AI Newsletter Digest improvements: fixed QP soft line break decoding, URL extraction, and content cleaning
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,179 @@
|
||||
"""
|
||||
If the arbitrary constant class from issue 4435 is ever implemented, this
|
||||
should serve as a set of test cases.
|
||||
"""
|
||||
|
||||
from sympy.core.function import Function
|
||||
from sympy.core.numbers import I
|
||||
from sympy.core.power import Pow
|
||||
from sympy.core.relational import Eq
|
||||
from sympy.core.singleton import S
|
||||
from sympy.core.symbol import Symbol
|
||||
from sympy.functions.elementary.exponential import (exp, log)
|
||||
from sympy.functions.elementary.hyperbolic import (cosh, sinh)
|
||||
from sympy.functions.elementary.miscellaneous import sqrt
|
||||
from sympy.functions.elementary.trigonometric import (acos, cos, sin)
|
||||
from sympy.integrals.integrals import Integral
|
||||
from sympy.solvers.ode.ode import constantsimp, constant_renumber
|
||||
from sympy.testing.pytest import XFAIL
|
||||
|
||||
|
||||
x = Symbol('x')
|
||||
y = Symbol('y')
|
||||
z = Symbol('z')
|
||||
u2 = Symbol('u2')
|
||||
_a = Symbol('_a')
|
||||
C1 = Symbol('C1')
|
||||
C2 = Symbol('C2')
|
||||
C3 = Symbol('C3')
|
||||
f = Function('f')
|
||||
|
||||
|
||||
def test_constant_mul():
|
||||
# We want C1 (Constant) below to absorb the y's, but not the x's
|
||||
assert constant_renumber(constantsimp(y*C1, [C1])) == C1*y
|
||||
assert constant_renumber(constantsimp(C1*y, [C1])) == C1*y
|
||||
assert constant_renumber(constantsimp(x*C1, [C1])) == x*C1
|
||||
assert constant_renumber(constantsimp(C1*x, [C1])) == x*C1
|
||||
assert constant_renumber(constantsimp(2*C1, [C1])) == C1
|
||||
assert constant_renumber(constantsimp(C1*2, [C1])) == C1
|
||||
assert constant_renumber(constantsimp(y*C1*x, [C1, y])) == C1*x
|
||||
assert constant_renumber(constantsimp(x*y*C1, [C1, y])) == x*C1
|
||||
assert constant_renumber(constantsimp(y*x*C1, [C1, y])) == x*C1
|
||||
assert constant_renumber(constantsimp(C1*x*y, [C1, y])) == C1*x
|
||||
assert constant_renumber(constantsimp(x*C1*y, [C1, y])) == x*C1
|
||||
assert constant_renumber(constantsimp(C1*y*(y + 1), [C1])) == C1*y*(y+1)
|
||||
assert constant_renumber(constantsimp(y*C1*(y + 1), [C1])) == C1*y*(y+1)
|
||||
assert constant_renumber(constantsimp(x*(y*C1), [C1])) == x*y*C1
|
||||
assert constant_renumber(constantsimp(x*(C1*y), [C1])) == x*y*C1
|
||||
assert constant_renumber(constantsimp(C1*(x*y), [C1, y])) == C1*x
|
||||
assert constant_renumber(constantsimp((x*y)*C1, [C1, y])) == x*C1
|
||||
assert constant_renumber(constantsimp((y*x)*C1, [C1, y])) == x*C1
|
||||
assert constant_renumber(constantsimp(y*(y + 1)*C1, [C1, y])) == C1
|
||||
assert constant_renumber(constantsimp((C1*x)*y, [C1, y])) == C1*x
|
||||
assert constant_renumber(constantsimp(y*(x*C1), [C1, y])) == x*C1
|
||||
assert constant_renumber(constantsimp((x*C1)*y, [C1, y])) == x*C1
|
||||
assert constant_renumber(constantsimp(C1*x*y*x*y*2, [C1, y])) == C1*x**2
|
||||
assert constant_renumber(constantsimp(C1*x*y*z, [C1, y, z])) == C1*x
|
||||
assert constant_renumber(constantsimp(C1*x*y**2*sin(z), [C1, y, z])) == C1*x
|
||||
assert constant_renumber(constantsimp(C1*C1, [C1])) == C1
|
||||
assert constant_renumber(constantsimp(C1*C2, [C1, C2])) == C1
|
||||
assert constant_renumber(constantsimp(C2*C2, [C1, C2])) == C1
|
||||
assert constant_renumber(constantsimp(C1*C1*C2, [C1, C2])) == C1
|
||||
assert constant_renumber(constantsimp(C1*x*2**x, [C1])) == C1*x*2**x
|
||||
|
||||
def test_constant_add():
|
||||
assert constant_renumber(constantsimp(C1 + C1, [C1])) == C1
|
||||
assert constant_renumber(constantsimp(C1 + 2, [C1])) == C1
|
||||
assert constant_renumber(constantsimp(2 + C1, [C1])) == C1
|
||||
assert constant_renumber(constantsimp(C1 + y, [C1, y])) == C1
|
||||
assert constant_renumber(constantsimp(C1 + x, [C1])) == C1 + x
|
||||
assert constant_renumber(constantsimp(C1 + C1, [C1])) == C1
|
||||
assert constant_renumber(constantsimp(C1 + C2, [C1, C2])) == C1
|
||||
assert constant_renumber(constantsimp(C2 + C1, [C1, C2])) == C1
|
||||
assert constant_renumber(constantsimp(C1 + C2 + C1, [C1, C2])) == C1
|
||||
|
||||
|
||||
def test_constant_power_as_base():
|
||||
assert constant_renumber(constantsimp(C1**C1, [C1])) == C1
|
||||
assert constant_renumber(constantsimp(Pow(C1, C1), [C1])) == C1
|
||||
assert constant_renumber(constantsimp(C1**C1, [C1])) == C1
|
||||
assert constant_renumber(constantsimp(C1**C2, [C1, C2])) == C1
|
||||
assert constant_renumber(constantsimp(C2**C1, [C1, C2])) == C1
|
||||
assert constant_renumber(constantsimp(C2**C2, [C1, C2])) == C1
|
||||
assert constant_renumber(constantsimp(C1**y, [C1, y])) == C1
|
||||
assert constant_renumber(constantsimp(C1**x, [C1])) == C1**x
|
||||
assert constant_renumber(constantsimp(C1**2, [C1])) == C1
|
||||
assert constant_renumber(
|
||||
constantsimp(C1**(x*y), [C1])) == C1**(x*y)
|
||||
|
||||
|
||||
def test_constant_power_as_exp():
|
||||
assert constant_renumber(constantsimp(x**C1, [C1])) == x**C1
|
||||
assert constant_renumber(constantsimp(y**C1, [C1, y])) == C1
|
||||
assert constant_renumber(constantsimp(x**y**C1, [C1, y])) == x**C1
|
||||
assert constant_renumber(
|
||||
constantsimp((x**y)**C1, [C1])) == (x**y)**C1
|
||||
assert constant_renumber(
|
||||
constantsimp(x**(y**C1), [C1, y])) == x**C1
|
||||
assert constant_renumber(constantsimp(x**C1**y, [C1, y])) == x**C1
|
||||
assert constant_renumber(
|
||||
constantsimp(x**(C1**y), [C1, y])) == x**C1
|
||||
assert constant_renumber(
|
||||
constantsimp((x**C1)**y, [C1])) == (x**C1)**y
|
||||
assert constant_renumber(constantsimp(2**C1, [C1])) == C1
|
||||
assert constant_renumber(constantsimp(S(2)**C1, [C1])) == C1
|
||||
assert constant_renumber(constantsimp(exp(C1), [C1])) == C1
|
||||
assert constant_renumber(
|
||||
constantsimp(exp(C1 + x), [C1])) == C1*exp(x)
|
||||
assert constant_renumber(constantsimp(Pow(2, C1), [C1])) == C1
|
||||
|
||||
|
||||
def test_constant_function():
|
||||
assert constant_renumber(constantsimp(sin(C1), [C1])) == C1
|
||||
assert constant_renumber(constantsimp(f(C1), [C1])) == C1
|
||||
assert constant_renumber(constantsimp(f(C1, C1), [C1])) == C1
|
||||
assert constant_renumber(constantsimp(f(C1, C2), [C1, C2])) == C1
|
||||
assert constant_renumber(constantsimp(f(C2, C1), [C1, C2])) == C1
|
||||
assert constant_renumber(constantsimp(f(C2, C2), [C1, C2])) == C1
|
||||
assert constant_renumber(
|
||||
constantsimp(f(C1, x), [C1])) == f(C1, x)
|
||||
assert constant_renumber(constantsimp(f(C1, y), [C1, y])) == C1
|
||||
assert constant_renumber(constantsimp(f(y, C1), [C1, y])) == C1
|
||||
assert constant_renumber(constantsimp(f(C1, y, C2), [C1, C2, y])) == C1
|
||||
|
||||
|
||||
def test_constant_function_multiple():
|
||||
# The rules to not renumber in this case would be too complicated, and
|
||||
# dsolve is not likely to ever encounter anything remotely like this.
|
||||
assert constant_renumber(
|
||||
constantsimp(f(C1, C1, x), [C1])) == f(C1, C1, x)
|
||||
|
||||
|
||||
def test_constant_multiple():
|
||||
assert constant_renumber(constantsimp(C1*2 + 2, [C1])) == C1
|
||||
assert constant_renumber(constantsimp(x*2/C1, [C1])) == C1*x
|
||||
assert constant_renumber(constantsimp(C1**2*2 + 2, [C1])) == C1
|
||||
assert constant_renumber(
|
||||
constantsimp(sin(2*C1) + x + sqrt(2), [C1])) == C1 + x
|
||||
assert constant_renumber(constantsimp(2*C1 + C2, [C1, C2])) == C1
|
||||
|
||||
def test_constant_repeated():
|
||||
assert C1 + C1*x == constant_renumber( C1 + C1*x)
|
||||
|
||||
def test_ode_solutions():
|
||||
# only a few examples here, the rest will be tested in the actual dsolve tests
|
||||
assert constant_renumber(constantsimp(C1*exp(2*x) + exp(x)*(C2 + C3), [C1, C2, C3])) == \
|
||||
constant_renumber(C1*exp(x) + C2*exp(2*x))
|
||||
assert constant_renumber(
|
||||
constantsimp(Eq(f(x), I*C1*sinh(x/3) + C2*cosh(x/3)), [C1, C2])
|
||||
) == constant_renumber(Eq(f(x), C1*sinh(x/3) + C2*cosh(x/3)))
|
||||
assert constant_renumber(constantsimp(Eq(f(x), acos((-C1)/cos(x))), [C1])) == \
|
||||
Eq(f(x), acos(C1/cos(x)))
|
||||
assert constant_renumber(
|
||||
constantsimp(Eq(log(f(x)/C1) + 2*exp(x/f(x)), 0), [C1])
|
||||
) == Eq(log(C1*f(x)) + 2*exp(x/f(x)), 0)
|
||||
assert constant_renumber(constantsimp(Eq(log(x*sqrt(2)*sqrt(1/x)*sqrt(f(x))
|
||||
/C1) + x**2/(2*f(x)**2), 0), [C1])) == \
|
||||
Eq(log(C1*sqrt(x)*sqrt(f(x))) + x**2/(2*f(x)**2), 0)
|
||||
assert constant_renumber(constantsimp(Eq(-exp(-f(x)/x)*sin(f(x)/x)/2 + log(x/C1) -
|
||||
cos(f(x)/x)*exp(-f(x)/x)/2, 0), [C1])) == \
|
||||
Eq(-exp(-f(x)/x)*sin(f(x)/x)/2 + log(C1*x) - cos(f(x)/x)*
|
||||
exp(-f(x)/x)/2, 0)
|
||||
assert constant_renumber(constantsimp(Eq(-Integral(-1/(sqrt(1 - u2**2)*u2),
|
||||
(u2, _a, x/f(x))) + log(f(x)/C1), 0), [C1])) == \
|
||||
Eq(-Integral(-1/(u2*sqrt(1 - u2**2)), (u2, _a, x/f(x))) +
|
||||
log(C1*f(x)), 0)
|
||||
assert [constantsimp(i, [C1]) for i in [Eq(f(x), sqrt(-C1*x + x**2)), Eq(f(x), -sqrt(-C1*x + x**2))]] == \
|
||||
[Eq(f(x), sqrt(x*(C1 + x))), Eq(f(x), -sqrt(x*(C1 + x)))]
|
||||
|
||||
|
||||
@XFAIL
|
||||
def test_nonlocal_simplification():
|
||||
assert constantsimp(C1 + C2+x*C2, [C1, C2]) == C1 + C2*x
|
||||
|
||||
|
||||
def test_constant_Eq():
|
||||
# C1 on the rhs is well-tested, but the lhs is only tested here
|
||||
assert constantsimp(Eq(C1, 3 + f(x)*x), [C1]) == Eq(x*f(x), C1)
|
||||
assert constantsimp(Eq(C1, 3 * f(x)*x), [C1]) == Eq(f(x)*x, C1)
|
||||
@@ -0,0 +1,59 @@
|
||||
from sympy.solvers.decompogen import decompogen, compogen
|
||||
from sympy.core.symbol import symbols
|
||||
from sympy.functions.elementary.complexes import Abs
|
||||
from sympy.functions.elementary.exponential import exp
|
||||
from sympy.functions.elementary.miscellaneous import sqrt, Max
|
||||
from sympy.functions.elementary.trigonometric import (cos, sin)
|
||||
from sympy.testing.pytest import XFAIL, raises
|
||||
|
||||
x, y = symbols('x y')
|
||||
|
||||
|
||||
def test_decompogen():
|
||||
assert decompogen(sin(cos(x)), x) == [sin(x), cos(x)]
|
||||
assert decompogen(sin(x)**2 + sin(x) + 1, x) == [x**2 + x + 1, sin(x)]
|
||||
assert decompogen(sqrt(6*x**2 - 5), x) == [sqrt(x), 6*x**2 - 5]
|
||||
assert decompogen(sin(sqrt(cos(x**2 + 1))), x) == [sin(x), sqrt(x), cos(x), x**2 + 1]
|
||||
assert decompogen(Abs(cos(x)**2 + 3*cos(x) - 4), x) == [Abs(x), x**2 + 3*x - 4, cos(x)]
|
||||
assert decompogen(sin(x)**2 + sin(x) - sqrt(3)/2, x) == [x**2 + x - sqrt(3)/2, sin(x)]
|
||||
assert decompogen(Abs(cos(y)**2 + 3*cos(x) - 4), x) == [Abs(x), 3*x + cos(y)**2 - 4, cos(x)]
|
||||
assert decompogen(x, y) == [x]
|
||||
assert decompogen(1, x) == [1]
|
||||
assert decompogen(Max(3, x), x) == [Max(3, x)]
|
||||
raises(TypeError, lambda: decompogen(x < 5, x))
|
||||
u = 2*x + 3
|
||||
assert decompogen(Max(sqrt(u),(u)**2), x) == [Max(sqrt(x), x**2), u]
|
||||
assert decompogen(Max(u, u**2, y), x) == [Max(x, x**2, y), u]
|
||||
assert decompogen(Max(sin(x), u), x) == [Max(2*x + 3, sin(x))]
|
||||
|
||||
|
||||
def test_decompogen_poly():
|
||||
assert decompogen(x**4 + 2*x**2 + 1, x) == [x**2 + 2*x + 1, x**2]
|
||||
assert decompogen(x**4 + 2*x**3 - x - 1, x) == [x**2 - x - 1, x**2 + x]
|
||||
|
||||
|
||||
@XFAIL
|
||||
def test_decompogen_fails():
|
||||
A = lambda x: x**2 + 2*x + 3
|
||||
B = lambda x: 4*x**2 + 5*x + 6
|
||||
assert decompogen(A(x*exp(x)), x) == [x**2 + 2*x + 3, x*exp(x)]
|
||||
assert decompogen(A(B(x)), x) == [x**2 + 2*x + 3, 4*x**2 + 5*x + 6]
|
||||
assert decompogen(A(1/x + 1/x**2), x) == [x**2 + 2*x + 3, 1/x + 1/x**2]
|
||||
assert decompogen(A(1/x + 2/(x + 1)), x) == [x**2 + 2*x + 3, 1/x + 2/(x + 1)]
|
||||
|
||||
|
||||
def test_compogen():
|
||||
assert compogen([sin(x), cos(x)], x) == sin(cos(x))
|
||||
assert compogen([x**2 + x + 1, sin(x)], x) == sin(x)**2 + sin(x) + 1
|
||||
assert compogen([sqrt(x), 6*x**2 - 5], x) == sqrt(6*x**2 - 5)
|
||||
assert compogen([sin(x), sqrt(x), cos(x), x**2 + 1], x) == sin(sqrt(
|
||||
cos(x**2 + 1)))
|
||||
assert compogen([Abs(x), x**2 + 3*x - 4, cos(x)], x) == Abs(cos(x)**2 +
|
||||
3*cos(x) - 4)
|
||||
assert compogen([x**2 + x - sqrt(3)/2, sin(x)], x) == (sin(x)**2 + sin(x) -
|
||||
sqrt(3)/2)
|
||||
assert compogen([Abs(x), 3*x + cos(y)**2 - 4, cos(x)], x) == \
|
||||
Abs(3*cos(x) + cos(y)**2 - 4)
|
||||
assert compogen([x**2 + 2*x + 1, x**2], x) == x**4 + 2*x**2 + 1
|
||||
# the result is in unsimplified form
|
||||
assert compogen([x**2 - x - 1, x**2 + x], x) == -x**2 - x + (x**2 + x)**2 - 1
|
||||
@@ -0,0 +1,500 @@
|
||||
"""Tests for tools for solving inequalities and systems of inequalities. """
|
||||
|
||||
from sympy.concrete.summations import Sum
|
||||
from sympy.core.function import Function
|
||||
from sympy.core.numbers import I, Rational, oo, pi
|
||||
from sympy.core.relational import Eq, Ge, Gt, Le, Lt, Ne
|
||||
from sympy.core.singleton import S
|
||||
from sympy.core.symbol import (Dummy, Symbol)
|
||||
from sympy.functions.elementary.complexes import Abs
|
||||
from sympy.functions.elementary.exponential import exp, log
|
||||
from sympy.functions.elementary.miscellaneous import root, sqrt
|
||||
from sympy.functions.elementary.piecewise import Piecewise
|
||||
from sympy.functions.elementary.trigonometric import cos, sin, tan
|
||||
from sympy.integrals.integrals import Integral
|
||||
from sympy.logic.boolalg import And, Or
|
||||
from sympy.polys.polytools import Poly, PurePoly
|
||||
from sympy.sets.sets import FiniteSet, Interval, Union
|
||||
from sympy.solvers.inequalities import (reduce_inequalities,
|
||||
solve_poly_inequality as psolve,
|
||||
reduce_rational_inequalities,
|
||||
solve_univariate_inequality as isolve,
|
||||
reduce_abs_inequality,
|
||||
_solve_inequality)
|
||||
from sympy.polys.rootoftools import rootof
|
||||
from sympy.solvers.solvers import solve
|
||||
from sympy.solvers.solveset import solveset
|
||||
from sympy.core.mod import Mod
|
||||
from sympy.abc import x, y
|
||||
|
||||
from sympy.testing.pytest import raises, XFAIL
|
||||
|
||||
|
||||
inf = oo.evalf()
|
||||
|
||||
|
||||
def test_solve_poly_inequality():
|
||||
assert psolve(Poly(0, x), '==') == [S.Reals]
|
||||
assert psolve(Poly(1, x), '==') == [S.EmptySet]
|
||||
assert psolve(PurePoly(x + 1, x), ">") == [Interval(-1, oo, True, False)]
|
||||
|
||||
|
||||
def test_reduce_poly_inequalities_real_interval():
|
||||
assert reduce_rational_inequalities(
|
||||
[[Eq(x**2, 0)]], x, relational=False) == FiniteSet(0)
|
||||
assert reduce_rational_inequalities(
|
||||
[[Le(x**2, 0)]], x, relational=False) == FiniteSet(0)
|
||||
assert reduce_rational_inequalities(
|
||||
[[Lt(x**2, 0)]], x, relational=False) == S.EmptySet
|
||||
assert reduce_rational_inequalities(
|
||||
[[Ge(x**2, 0)]], x, relational=False) == \
|
||||
S.Reals if x.is_real else Interval(-oo, oo)
|
||||
assert reduce_rational_inequalities(
|
||||
[[Gt(x**2, 0)]], x, relational=False) == \
|
||||
FiniteSet(0).complement(S.Reals)
|
||||
assert reduce_rational_inequalities(
|
||||
[[Ne(x**2, 0)]], x, relational=False) == \
|
||||
FiniteSet(0).complement(S.Reals)
|
||||
|
||||
assert reduce_rational_inequalities(
|
||||
[[Eq(x**2, 1)]], x, relational=False) == FiniteSet(-1, 1)
|
||||
assert reduce_rational_inequalities(
|
||||
[[Le(x**2, 1)]], x, relational=False) == Interval(-1, 1)
|
||||
assert reduce_rational_inequalities(
|
||||
[[Lt(x**2, 1)]], x, relational=False) == Interval(-1, 1, True, True)
|
||||
assert reduce_rational_inequalities(
|
||||
[[Ge(x**2, 1)]], x, relational=False) == \
|
||||
Union(Interval(-oo, -1), Interval(1, oo))
|
||||
assert reduce_rational_inequalities(
|
||||
[[Gt(x**2, 1)]], x, relational=False) == \
|
||||
Interval(-1, 1).complement(S.Reals)
|
||||
assert reduce_rational_inequalities(
|
||||
[[Ne(x**2, 1)]], x, relational=False) == \
|
||||
FiniteSet(-1, 1).complement(S.Reals)
|
||||
assert reduce_rational_inequalities([[Eq(
|
||||
x**2, 1.0)]], x, relational=False) == FiniteSet(-1.0, 1.0).evalf()
|
||||
assert reduce_rational_inequalities(
|
||||
[[Le(x**2, 1.0)]], x, relational=False) == Interval(-1.0, 1.0)
|
||||
assert reduce_rational_inequalities([[Lt(
|
||||
x**2, 1.0)]], x, relational=False) == Interval(-1.0, 1.0, True, True)
|
||||
assert reduce_rational_inequalities(
|
||||
[[Ge(x**2, 1.0)]], x, relational=False) == \
|
||||
Union(Interval(-inf, -1.0), Interval(1.0, inf))
|
||||
assert reduce_rational_inequalities(
|
||||
[[Gt(x**2, 1.0)]], x, relational=False) == \
|
||||
Union(Interval(-inf, -1.0, right_open=True),
|
||||
Interval(1.0, inf, left_open=True))
|
||||
assert reduce_rational_inequalities([[Ne(
|
||||
x**2, 1.0)]], x, relational=False) == \
|
||||
FiniteSet(-1.0, 1.0).complement(S.Reals)
|
||||
|
||||
s = sqrt(2)
|
||||
|
||||
assert reduce_rational_inequalities([[Lt(
|
||||
x**2 - 1, 0), Gt(x**2 - 1, 0)]], x, relational=False) == S.EmptySet
|
||||
assert reduce_rational_inequalities([[Le(x**2 - 1, 0), Ge(
|
||||
x**2 - 1, 0)]], x, relational=False) == FiniteSet(-1, 1)
|
||||
assert reduce_rational_inequalities(
|
||||
[[Le(x**2 - 2, 0), Ge(x**2 - 1, 0)]], x, relational=False
|
||||
) == Union(Interval(-s, -1, False, False), Interval(1, s, False, False))
|
||||
assert reduce_rational_inequalities(
|
||||
[[Le(x**2 - 2, 0), Gt(x**2 - 1, 0)]], x, relational=False
|
||||
) == Union(Interval(-s, -1, False, True), Interval(1, s, True, False))
|
||||
assert reduce_rational_inequalities(
|
||||
[[Lt(x**2 - 2, 0), Ge(x**2 - 1, 0)]], x, relational=False
|
||||
) == Union(Interval(-s, -1, True, False), Interval(1, s, False, True))
|
||||
assert reduce_rational_inequalities(
|
||||
[[Lt(x**2 - 2, 0), Gt(x**2 - 1, 0)]], x, relational=False
|
||||
) == Union(Interval(-s, -1, True, True), Interval(1, s, True, True))
|
||||
assert reduce_rational_inequalities(
|
||||
[[Lt(x**2 - 2, 0), Ne(x**2 - 1, 0)]], x, relational=False
|
||||
) == Union(Interval(-s, -1, True, True), Interval(-1, 1, True, True),
|
||||
Interval(1, s, True, True))
|
||||
|
||||
assert reduce_rational_inequalities([[Lt(x**2, -1.)]], x) is S.false
|
||||
|
||||
|
||||
def test_reduce_poly_inequalities_complex_relational():
|
||||
assert reduce_rational_inequalities(
|
||||
[[Eq(x**2, 0)]], x, relational=True) == Eq(x, 0)
|
||||
assert reduce_rational_inequalities(
|
||||
[[Le(x**2, 0)]], x, relational=True) == Eq(x, 0)
|
||||
assert reduce_rational_inequalities(
|
||||
[[Lt(x**2, 0)]], x, relational=True) == False
|
||||
assert reduce_rational_inequalities(
|
||||
[[Ge(x**2, 0)]], x, relational=True) == And(Lt(-oo, x), Lt(x, oo))
|
||||
assert reduce_rational_inequalities(
|
||||
[[Gt(x**2, 0)]], x, relational=True) == \
|
||||
And(Gt(x, -oo), Lt(x, oo), Ne(x, 0))
|
||||
assert reduce_rational_inequalities(
|
||||
[[Ne(x**2, 0)]], x, relational=True) == \
|
||||
And(Gt(x, -oo), Lt(x, oo), Ne(x, 0))
|
||||
|
||||
for one in (S.One, S(1.0)):
|
||||
inf = one*oo
|
||||
assert reduce_rational_inequalities(
|
||||
[[Eq(x**2, one)]], x, relational=True) == \
|
||||
Or(Eq(x, -one), Eq(x, one))
|
||||
assert reduce_rational_inequalities(
|
||||
[[Le(x**2, one)]], x, relational=True) == \
|
||||
And(And(Le(-one, x), Le(x, one)))
|
||||
assert reduce_rational_inequalities(
|
||||
[[Lt(x**2, one)]], x, relational=True) == \
|
||||
And(And(Lt(-one, x), Lt(x, one)))
|
||||
assert reduce_rational_inequalities(
|
||||
[[Ge(x**2, one)]], x, relational=True) == \
|
||||
And(Or(And(Le(one, x), Lt(x, inf)), And(Le(x, -one), Lt(-inf, x))))
|
||||
assert reduce_rational_inequalities(
|
||||
[[Gt(x**2, one)]], x, relational=True) == \
|
||||
And(Or(And(Lt(-inf, x), Lt(x, -one)), And(Lt(one, x), Lt(x, inf))))
|
||||
assert reduce_rational_inequalities(
|
||||
[[Ne(x**2, one)]], x, relational=True) == \
|
||||
Or(And(Lt(-inf, x), Lt(x, -one)),
|
||||
And(Lt(-one, x), Lt(x, one)),
|
||||
And(Lt(one, x), Lt(x, inf)))
|
||||
|
||||
|
||||
def test_reduce_rational_inequalities_real_relational():
|
||||
assert reduce_rational_inequalities([], x) == False
|
||||
assert reduce_rational_inequalities(
|
||||
[[(x**2 + 3*x + 2)/(x**2 - 16) >= 0]], x, relational=False) == \
|
||||
Union(Interval.open(-oo, -4), Interval(-2, -1), Interval.open(4, oo))
|
||||
|
||||
assert reduce_rational_inequalities(
|
||||
[[((-2*x - 10)*(3 - x))/((x**2 + 5)*(x - 2)**2) < 0]], x,
|
||||
relational=False) == \
|
||||
Union(Interval.open(-5, 2), Interval.open(2, 3))
|
||||
|
||||
assert reduce_rational_inequalities([[(x + 1)/(x - 5) <= 0]], x,
|
||||
relational=False) == \
|
||||
Interval.Ropen(-1, 5)
|
||||
|
||||
assert reduce_rational_inequalities([[(x**2 + 4*x + 3)/(x - 1) > 0]], x,
|
||||
relational=False) == \
|
||||
Union(Interval.open(-3, -1), Interval.open(1, oo))
|
||||
|
||||
assert reduce_rational_inequalities([[(x**2 - 16)/(x - 1)**2 < 0]], x,
|
||||
relational=False) == \
|
||||
Union(Interval.open(-4, 1), Interval.open(1, 4))
|
||||
|
||||
assert reduce_rational_inequalities([[(3*x + 1)/(x + 4) >= 1]], x,
|
||||
relational=False) == \
|
||||
Union(Interval.open(-oo, -4), Interval.Ropen(Rational(3, 2), oo))
|
||||
|
||||
assert reduce_rational_inequalities([[(x - 8)/x <= 3 - x]], x,
|
||||
relational=False) == \
|
||||
Union(Interval.Lopen(-oo, -2), Interval.Lopen(0, 4))
|
||||
|
||||
# issue sympy/sympy#10237
|
||||
assert reduce_rational_inequalities(
|
||||
[[x < oo, x >= 0, -oo < x]], x, relational=False) == Interval(0, oo)
|
||||
|
||||
|
||||
def test_reduce_abs_inequalities():
|
||||
e = abs(x - 5) < 3
|
||||
ans = And(Lt(2, x), Lt(x, 8))
|
||||
assert reduce_inequalities(e) == ans
|
||||
assert reduce_inequalities(e, x) == ans
|
||||
assert reduce_inequalities(abs(x - 5)) == Eq(x, 5)
|
||||
assert reduce_inequalities(
|
||||
abs(2*x + 3) >= 8) == Or(And(Le(Rational(5, 2), x), Lt(x, oo)),
|
||||
And(Le(x, Rational(-11, 2)), Lt(-oo, x)))
|
||||
assert reduce_inequalities(abs(x - 4) + abs(
|
||||
3*x - 5) < 7) == And(Lt(S.Half, x), Lt(x, 4))
|
||||
assert reduce_inequalities(abs(x - 4) + abs(3*abs(x) - 5) < 7) == \
|
||||
Or(And(S(-2) < x, x < -1), And(S.Half < x, x < 4))
|
||||
|
||||
nr = Symbol('nr', extended_real=False)
|
||||
raises(TypeError, lambda: reduce_inequalities(abs(nr - 5) < 3))
|
||||
assert reduce_inequalities(x < 3, symbols=[x, nr]) == And(-oo < x, x < 3)
|
||||
|
||||
|
||||
def test_reduce_inequalities_general():
|
||||
assert reduce_inequalities(Ge(sqrt(2)*x, 1)) == And(sqrt(2)/2 <= x, x < oo)
|
||||
assert reduce_inequalities(x + 1 > 0) == And(S.NegativeOne < x, x < oo)
|
||||
|
||||
|
||||
def test_reduce_inequalities_boolean():
|
||||
assert reduce_inequalities(
|
||||
[Eq(x**2, 0), True]) == Eq(x, 0)
|
||||
assert reduce_inequalities([Eq(x**2, 0), False]) == False
|
||||
assert reduce_inequalities(x**2 >= 0) is S.true # issue 10196
|
||||
|
||||
|
||||
def test_reduce_inequalities_multivariate():
|
||||
assert reduce_inequalities([Ge(x**2, 1), Ge(y**2, 1)]) == And(
|
||||
Or(And(Le(S.One, x), Lt(x, oo)), And(Le(x, -1), Lt(-oo, x))),
|
||||
Or(And(Le(S.One, y), Lt(y, oo)), And(Le(y, -1), Lt(-oo, y))))
|
||||
|
||||
|
||||
def test_reduce_inequalities_errors():
|
||||
raises(NotImplementedError, lambda: reduce_inequalities(Ge(sin(x) + x, 1)))
|
||||
raises(NotImplementedError, lambda: reduce_inequalities(Ge(x**2*y + y, 1)))
|
||||
|
||||
|
||||
def test__solve_inequalities():
|
||||
assert reduce_inequalities(x + y < 1, symbols=[x]) == (x < 1 - y)
|
||||
assert reduce_inequalities(x + y >= 1, symbols=[x]) == (x < oo) & (x >= -y + 1)
|
||||
assert reduce_inequalities(Eq(0, x - y), symbols=[x]) == Eq(x, y)
|
||||
assert reduce_inequalities(Ne(0, x - y), symbols=[x]) == Ne(x, y)
|
||||
|
||||
|
||||
def test_issue_6343():
|
||||
eq = -3*x**2/2 - x*Rational(45, 4) + Rational(33, 2) > 0
|
||||
assert reduce_inequalities(eq) == \
|
||||
And(x < Rational(-15, 4) + sqrt(401)/4, -sqrt(401)/4 - Rational(15, 4) < x)
|
||||
|
||||
|
||||
def test_issue_8235():
|
||||
assert reduce_inequalities(x**2 - 1 < 0) == \
|
||||
And(S.NegativeOne < x, x < 1)
|
||||
assert reduce_inequalities(x**2 - 1 <= 0) == \
|
||||
And(S.NegativeOne <= x, x <= 1)
|
||||
assert reduce_inequalities(x**2 - 1 > 0) == \
|
||||
Or(And(-oo < x, x < -1), And(x < oo, S.One < x))
|
||||
assert reduce_inequalities(x**2 - 1 >= 0) == \
|
||||
Or(And(-oo < x, x <= -1), And(S.One <= x, x < oo))
|
||||
|
||||
eq = x**8 + x - 9 # we want CRootOf solns here
|
||||
sol = solve(eq >= 0)
|
||||
tru = Or(And(rootof(eq, 1) <= x, x < oo), And(-oo < x, x <= rootof(eq, 0)))
|
||||
assert sol == tru
|
||||
|
||||
# recast vanilla as real
|
||||
assert solve(sqrt((-x + 1)**2) < 1) == And(S.Zero < x, x < 2)
|
||||
|
||||
|
||||
def test_issue_5526():
|
||||
assert reduce_inequalities(0 <=
|
||||
x + Integral(y**2, (y, 1, 3)) - 1, [x]) == \
|
||||
(x >= -Integral(y**2, (y, 1, 3)) + 1)
|
||||
f = Function('f')
|
||||
e = Sum(f(x), (x, 1, 3))
|
||||
assert reduce_inequalities(0 <= x + e + y**2, [x]) == \
|
||||
(x >= -y**2 - Sum(f(x), (x, 1, 3)))
|
||||
|
||||
|
||||
def test_solve_univariate_inequality():
|
||||
assert isolve(x**2 >= 4, x, relational=False) == Union(Interval(-oo, -2),
|
||||
Interval(2, oo))
|
||||
assert isolve(x**2 >= 4, x) == Or(And(Le(2, x), Lt(x, oo)), And(Le(x, -2),
|
||||
Lt(-oo, x)))
|
||||
assert isolve((x - 1)*(x - 2)*(x - 3) >= 0, x, relational=False) == \
|
||||
Union(Interval(1, 2), Interval(3, oo))
|
||||
assert isolve((x - 1)*(x - 2)*(x - 3) >= 0, x) == \
|
||||
Or(And(Le(1, x), Le(x, 2)), And(Le(3, x), Lt(x, oo)))
|
||||
assert isolve((x - 1)*(x - 2)*(x - 4) < 0, x, domain = FiniteSet(0, 3)) == \
|
||||
Or(Eq(x, 0), Eq(x, 3))
|
||||
# issue 2785:
|
||||
assert isolve(x**3 - 2*x - 1 > 0, x, relational=False) == \
|
||||
Union(Interval(-1, -sqrt(5)/2 + S.Half, True, True),
|
||||
Interval(S.Half + sqrt(5)/2, oo, True, True))
|
||||
# issue 2794:
|
||||
assert isolve(x**3 - x**2 + x - 1 > 0, x, relational=False) == \
|
||||
Interval(1, oo, True)
|
||||
#issue 13105
|
||||
assert isolve((x + I)*(x + 2*I) < 0, x) == Eq(x, 0)
|
||||
assert isolve(((x - 1)*(x - 2) + I)*((x - 1)*(x - 2) + 2*I) < 0, x) == Or(Eq(x, 1), Eq(x, 2))
|
||||
assert isolve((((x - 1)*(x - 2) + I)*((x - 1)*(x - 2) + 2*I))/(x - 2) > 0, x) == Eq(x, 1)
|
||||
raises (ValueError, lambda: isolve((x**2 - 3*x*I + 2)/x < 0, x))
|
||||
|
||||
# numerical testing in valid() is needed
|
||||
assert isolve(x**7 - x - 2 > 0, x) == \
|
||||
And(rootof(x**7 - x - 2, 0) < x, x < oo)
|
||||
|
||||
# handle numerator and denominator; although these would be handled as
|
||||
# rational inequalities, these test confirm that the right thing is done
|
||||
# when the domain is EX (e.g. when 2 is replaced with sqrt(2))
|
||||
assert isolve(1/(x - 2) > 0, x) == And(S(2) < x, x < oo)
|
||||
den = ((x - 1)*(x - 2)).expand()
|
||||
assert isolve((x - 1)/den <= 0, x) == \
|
||||
(x > -oo) & (x < 2) & Ne(x, 1)
|
||||
|
||||
n = Dummy('n')
|
||||
raises(NotImplementedError, lambda: isolve(Abs(x) <= n, x, relational=False))
|
||||
c1 = Dummy("c1", positive=True)
|
||||
raises(NotImplementedError, lambda: isolve(n/c1 < 0, c1))
|
||||
n = Dummy('n', negative=True)
|
||||
assert isolve(n/c1 > -2, c1) == (-n/2 < c1)
|
||||
assert isolve(n/c1 < 0, c1) == True
|
||||
assert isolve(n/c1 > 0, c1) == False
|
||||
|
||||
zero = cos(1)**2 + sin(1)**2 - 1
|
||||
raises(NotImplementedError, lambda: isolve(x**2 < zero, x))
|
||||
raises(NotImplementedError, lambda: isolve(
|
||||
x**2 < zero*I, x))
|
||||
raises(NotImplementedError, lambda: isolve(1/(x - y) < 2, x))
|
||||
raises(NotImplementedError, lambda: isolve(1/(x - y) < 0, x))
|
||||
raises(TypeError, lambda: isolve(x - I < 0, x))
|
||||
|
||||
zero = x**2 + x - x*(x + 1)
|
||||
assert isolve(zero < 0, x, relational=False) is S.EmptySet
|
||||
assert isolve(zero <= 0, x, relational=False) is S.Reals
|
||||
|
||||
# make sure iter_solutions gets a default value
|
||||
raises(NotImplementedError, lambda: isolve(
|
||||
Eq(cos(x)**2 + sin(x)**2, 1), x))
|
||||
|
||||
|
||||
def test_trig_inequalities():
|
||||
# all the inequalities are solved in a periodic interval.
|
||||
assert isolve(sin(x) < S.Half, x, relational=False) == \
|
||||
Union(Interval(0, pi/6, False, True), Interval.open(pi*Rational(5, 6), 2*pi))
|
||||
assert isolve(sin(x) > S.Half, x, relational=False) == \
|
||||
Interval(pi/6, pi*Rational(5, 6), True, True)
|
||||
assert isolve(cos(x) < S.Zero, x, relational=False) == \
|
||||
Interval(pi/2, pi*Rational(3, 2), True, True)
|
||||
assert isolve(cos(x) >= S.Zero, x, relational=False) == \
|
||||
Union(Interval(0, pi/2), Interval.Ropen(pi*Rational(3, 2), 2*pi))
|
||||
|
||||
assert isolve(tan(x) < S.One, x, relational=False) == \
|
||||
Union(Interval.Ropen(0, pi/4), Interval.open(pi/2, pi))
|
||||
|
||||
assert isolve(sin(x) <= S.Zero, x, relational=False) == \
|
||||
Union(FiniteSet(S.Zero), Interval.Ropen(pi, 2*pi))
|
||||
|
||||
assert isolve(sin(x) <= S.One, x, relational=False) == S.Reals
|
||||
assert isolve(cos(x) < S(-2), x, relational=False) == S.EmptySet
|
||||
assert isolve(sin(x) >= S.NegativeOne, x, relational=False) == S.Reals
|
||||
assert isolve(cos(x) > S.One, x, relational=False) == S.EmptySet
|
||||
|
||||
|
||||
def test_issue_9954():
|
||||
assert isolve(x**2 >= 0, x, relational=False) == S.Reals
|
||||
assert isolve(x**2 >= 0, x, relational=True) == S.Reals.as_relational(x)
|
||||
assert isolve(x**2 < 0, x, relational=False) == S.EmptySet
|
||||
assert isolve(x**2 < 0, x, relational=True) == S.EmptySet.as_relational(x)
|
||||
|
||||
|
||||
@XFAIL
|
||||
def test_slow_general_univariate():
|
||||
r = rootof(x**5 - x**2 + 1, 0)
|
||||
assert solve(sqrt(x) + 1/root(x, 3) > 1) == \
|
||||
Or(And(0 < x, x < r**6), And(r**6 < x, x < oo))
|
||||
|
||||
|
||||
def test_issue_8545():
|
||||
eq = 1 - x - abs(1 - x)
|
||||
ans = And(Lt(1, x), Lt(x, oo))
|
||||
assert reduce_abs_inequality(eq, '<', x) == ans
|
||||
eq = 1 - x - sqrt((1 - x)**2)
|
||||
assert reduce_inequalities(eq < 0) == ans
|
||||
|
||||
|
||||
def test_issue_8974():
|
||||
assert isolve(-oo < x, x) == And(-oo < x, x < oo)
|
||||
assert isolve(oo > x, x) == And(-oo < x, x < oo)
|
||||
|
||||
|
||||
def test_issue_10198():
|
||||
assert reduce_inequalities(
|
||||
-1 + 1/abs(1/x - 1) < 0) == (x > -oo) & (x < S(1)/2) & Ne(x, 0)
|
||||
|
||||
assert reduce_inequalities(abs(1/sqrt(x)) - 1, x) == Eq(x, 1)
|
||||
assert reduce_abs_inequality(-3 + 1/abs(1 - 1/x), '<', x) == \
|
||||
Or(And(-oo < x, x < 0),
|
||||
And(S.Zero < x, x < Rational(3, 4)), And(Rational(3, 2) < x, x < oo))
|
||||
raises(ValueError,lambda: reduce_abs_inequality(-3 + 1/abs(
|
||||
1 - 1/sqrt(x)), '<', x))
|
||||
|
||||
|
||||
def test_issue_10047():
|
||||
# issue 10047: this must remain an inequality, not True, since if x
|
||||
# is not real the inequality is invalid
|
||||
# assert solve(sin(x) < 2) == (x <= oo)
|
||||
|
||||
# with PR 16956, (x <= oo) autoevaluates when x is extended_real
|
||||
# which is assumed in the current implementation of inequality solvers
|
||||
assert solve(sin(x) < 2) == True
|
||||
assert solveset(sin(x) < 2, domain=S.Reals) == S.Reals
|
||||
|
||||
|
||||
def test_issue_10268():
|
||||
assert solve(log(x) < 1000) == And(S.Zero < x, x < exp(1000))
|
||||
|
||||
|
||||
@XFAIL
|
||||
def test_isolve_Sets():
|
||||
n = Dummy('n')
|
||||
assert isolve(Abs(x) <= n, x, relational=False) == \
|
||||
Piecewise((S.EmptySet, n < 0), (Interval(-n, n), True))
|
||||
|
||||
|
||||
def test_integer_domain_relational_isolve():
|
||||
|
||||
dom = FiniteSet(0, 3)
|
||||
x = Symbol('x',zero=False)
|
||||
assert isolve((x - 1)*(x - 2)*(x - 4) < 0, x, domain=dom) == Eq(x, 3)
|
||||
|
||||
x = Symbol('x')
|
||||
assert isolve(x + 2 < 0, x, domain=S.Integers) == \
|
||||
(x <= -3) & (x > -oo) & Eq(Mod(x, 1), 0)
|
||||
assert isolve(2 * x + 3 > 0, x, domain=S.Integers) == \
|
||||
(x >= -1) & (x < oo) & Eq(Mod(x, 1), 0)
|
||||
assert isolve((x ** 2 + 3 * x - 2) < 0, x, domain=S.Integers) == \
|
||||
(x >= -3) & (x <= 0) & Eq(Mod(x, 1), 0)
|
||||
assert isolve((x ** 2 + 3 * x - 2) > 0, x, domain=S.Integers) == \
|
||||
((x >= 1) & (x < oo) & Eq(Mod(x, 1), 0)) | (
|
||||
(x <= -4) & (x > -oo) & Eq(Mod(x, 1), 0))
|
||||
|
||||
|
||||
def test_issue_10671_12466():
|
||||
assert solveset(sin(y), y, Interval(0, pi)) == FiniteSet(0, pi)
|
||||
i = Interval(1, 10)
|
||||
assert solveset((1/x).diff(x) < 0, x, i) == i
|
||||
assert solveset((log(x - 6)/x) <= 0, x, S.Reals) == \
|
||||
Interval.Lopen(6, 7)
|
||||
|
||||
|
||||
def test__solve_inequality():
|
||||
for op in (Gt, Lt, Le, Ge, Eq, Ne):
|
||||
assert _solve_inequality(op(x, 1), x).lhs == x
|
||||
assert _solve_inequality(op(S.One, x), x).lhs == x
|
||||
# don't get tricked by symbol on right: solve it
|
||||
assert _solve_inequality(Eq(2*x - 1, x), x) == Eq(x, 1)
|
||||
ie = Eq(S.One, y)
|
||||
assert _solve_inequality(ie, x) == ie
|
||||
for fx in (x**2, exp(x), sin(x) + cos(x), x*(1 + x)):
|
||||
for c in (0, 1):
|
||||
e = 2*fx - c > 0
|
||||
assert _solve_inequality(e, x, linear=True) == (
|
||||
fx > c/S(2))
|
||||
assert _solve_inequality(2*x**2 + 2*x - 1 < 0, x, linear=True) == (
|
||||
x*(x + 1) < S.Half)
|
||||
assert _solve_inequality(Eq(x*y, 1), x) == Eq(x*y, 1)
|
||||
nz = Symbol('nz', nonzero=True)
|
||||
assert _solve_inequality(Eq(x*nz, 1), x) == Eq(x, 1/nz)
|
||||
assert _solve_inequality(x*nz < 1, x) == (x*nz < 1)
|
||||
a = Symbol('a', positive=True)
|
||||
assert _solve_inequality(a/x > 1, x) == (S.Zero < x) & (x < a)
|
||||
assert _solve_inequality(a/x > 1, x, linear=True) == (1/x > 1/a)
|
||||
# make sure to include conditions under which solution is valid
|
||||
e = Eq(1 - x, x*(1/x - 1))
|
||||
assert _solve_inequality(e, x) == Ne(x, 0)
|
||||
assert _solve_inequality(x < x*(1/x - 1), x) == (x < S.Half) & Ne(x, 0)
|
||||
|
||||
|
||||
def test__pt():
|
||||
from sympy.solvers.inequalities import _pt
|
||||
assert _pt(-oo, oo) == 0
|
||||
assert _pt(S.One, S(3)) == 2
|
||||
assert _pt(S.One, oo) == _pt(oo, S.One) == 2
|
||||
assert _pt(S.One, -oo) == _pt(-oo, S.One) == S.Half
|
||||
assert _pt(S.NegativeOne, oo) == _pt(oo, S.NegativeOne) == Rational(-1, 2)
|
||||
assert _pt(S.NegativeOne, -oo) == _pt(-oo, S.NegativeOne) == -2
|
||||
assert _pt(x, oo) == _pt(oo, x) == x + 1
|
||||
assert _pt(x, -oo) == _pt(-oo, x) == x - 1
|
||||
raises(ValueError, lambda: _pt(Dummy('i', infinite=True), S.One))
|
||||
|
||||
|
||||
def test_issue_25697():
|
||||
assert _solve_inequality(log(x, 3) <= 2, x) == (x <= 9) & (S.Zero < x)
|
||||
|
||||
|
||||
def test_issue_25738():
|
||||
assert reduce_inequalities(3 < abs(x)
|
||||
) == reduce_inequalities(pi < abs(x)).subs(pi, 3)
|
||||
|
||||
|
||||
def test_issue_25983():
|
||||
assert(reduce_inequalities(pi/Abs(x) <= 1) == ((pi <= x) & (x < oo)) | ((-oo < x) & (x <= -pi)))
|
||||
@@ -0,0 +1,139 @@
|
||||
from sympy.core.function import nfloat
|
||||
from sympy.core.numbers import (Float, I, Rational, pi)
|
||||
from sympy.core.relational import Eq
|
||||
from sympy.core.symbol import (Symbol, symbols)
|
||||
from sympy.functions.elementary.miscellaneous import sqrt
|
||||
from sympy.functions.elementary.piecewise import Piecewise
|
||||
from sympy.functions.elementary.trigonometric import sin
|
||||
from sympy.integrals.integrals import Integral
|
||||
from sympy.matrices.dense import Matrix
|
||||
from mpmath import mnorm, mpf
|
||||
from sympy.solvers import nsolve
|
||||
from sympy.utilities.lambdify import lambdify
|
||||
from sympy.testing.pytest import raises, XFAIL
|
||||
from sympy.utilities.decorator import conserve_mpmath_dps
|
||||
|
||||
@XFAIL
|
||||
def test_nsolve_fail():
|
||||
x = symbols('x')
|
||||
# Sometimes it is better to use the numerator (issue 4829)
|
||||
# but sometimes it is not (issue 11768) so leave this to
|
||||
# the discretion of the user
|
||||
ans = nsolve(x**2/(1 - x)/(1 - 2*x)**2 - 100, x, 0)
|
||||
assert ans > 0.46 and ans < 0.47
|
||||
|
||||
|
||||
def test_nsolve_denominator():
|
||||
x = symbols('x')
|
||||
# Test that nsolve uses the full expression (numerator and denominator).
|
||||
ans = nsolve((x**2 + 3*x + 2)/(x + 2), -2.1)
|
||||
# The root -2 was divided out, so make sure we don't find it.
|
||||
assert ans == -1.0
|
||||
|
||||
def test_nsolve():
|
||||
# onedimensional
|
||||
x = Symbol('x')
|
||||
assert nsolve(sin(x), 2) - pi.evalf() < 1e-15
|
||||
assert nsolve(Eq(2*x, 2), x, -10) == nsolve(2*x - 2, -10)
|
||||
# Testing checks on number of inputs
|
||||
raises(TypeError, lambda: nsolve(Eq(2*x, 2)))
|
||||
raises(TypeError, lambda: nsolve(Eq(2*x, 2), x, 1, 2))
|
||||
# multidimensional
|
||||
x1 = Symbol('x1')
|
||||
x2 = Symbol('x2')
|
||||
f1 = 3 * x1**2 - 2 * x2**2 - 1
|
||||
f2 = x1**2 - 2 * x1 + x2**2 + 2 * x2 - 8
|
||||
f = Matrix((f1, f2)).T
|
||||
F = lambdify((x1, x2), f.T, modules='mpmath')
|
||||
for x0 in [(-1, 1), (1, -2), (4, 4), (-4, -4)]:
|
||||
x = nsolve(f, (x1, x2), x0, tol=1.e-8)
|
||||
assert mnorm(F(*x), 1) <= 1.e-10
|
||||
# The Chinese mathematician Zhu Shijie was the very first to solve this
|
||||
# nonlinear system 700 years ago (z was added to make it 3-dimensional)
|
||||
x = Symbol('x')
|
||||
y = Symbol('y')
|
||||
z = Symbol('z')
|
||||
f1 = -x + 2*y
|
||||
f2 = (x**2 + x*(y**2 - 2) - 4*y) / (x + 4)
|
||||
f3 = sqrt(x**2 + y**2)*z
|
||||
f = Matrix((f1, f2, f3)).T
|
||||
F = lambdify((x, y, z), f.T, modules='mpmath')
|
||||
|
||||
def getroot(x0):
|
||||
root = nsolve(f, (x, y, z), x0)
|
||||
assert mnorm(F(*root), 1) <= 1.e-8
|
||||
return root
|
||||
assert list(map(round, getroot((1, 1, 1)))) == [2, 1, 0]
|
||||
assert nsolve([Eq(
|
||||
f1, 0), Eq(f2, 0), Eq(f3, 0)], [x, y, z], (1, 1, 1)) # just see that it works
|
||||
a = Symbol('a')
|
||||
assert abs(nsolve(1/(0.001 + a)**3 - 6/(0.9 - a)**3, a, 0.3) -
|
||||
mpf('0.31883011387318591')) < 1e-15
|
||||
|
||||
|
||||
def test_issue_6408():
|
||||
x = Symbol('x')
|
||||
assert nsolve(Piecewise((x, x < 1), (x**2, True)), x, 2) == 0
|
||||
|
||||
|
||||
def test_issue_6408_integral():
|
||||
x, y = symbols('x y')
|
||||
assert nsolve(Integral(x*y, (x, 0, 5)), y, 2) == 0
|
||||
|
||||
|
||||
@conserve_mpmath_dps
|
||||
def test_increased_dps():
|
||||
# Issue 8564
|
||||
import mpmath
|
||||
mpmath.mp.dps = 128
|
||||
x = Symbol('x')
|
||||
e1 = x**2 - pi
|
||||
q = nsolve(e1, x, 3.0)
|
||||
|
||||
assert abs(sqrt(pi).evalf(128) - q) < 1e-128
|
||||
|
||||
def test_nsolve_precision():
|
||||
x, y = symbols('x y')
|
||||
sol = nsolve(x**2 - pi, x, 3, prec=128)
|
||||
assert abs(sqrt(pi).evalf(128) - sol) < 1e-128
|
||||
assert isinstance(sol, Float)
|
||||
|
||||
sols = nsolve((y**2 - x, x**2 - pi), (x, y), (3, 3), prec=128)
|
||||
assert isinstance(sols, Matrix)
|
||||
assert sols.shape == (2, 1)
|
||||
assert abs(sqrt(pi).evalf(128) - sols[0]) < 1e-128
|
||||
assert abs(sqrt(sqrt(pi)).evalf(128) - sols[1]) < 1e-128
|
||||
assert all(isinstance(i, Float) for i in sols)
|
||||
|
||||
def test_nsolve_complex():
|
||||
x, y = symbols('x y')
|
||||
|
||||
assert nsolve(x**2 + 2, 1j) == sqrt(2.)*I
|
||||
assert nsolve(x**2 + 2, I) == sqrt(2.)*I
|
||||
|
||||
assert nsolve([x**2 + 2, y**2 + 2], [x, y], [I, I]) == Matrix([sqrt(2.)*I, sqrt(2.)*I])
|
||||
assert nsolve([x**2 + 2, y**2 + 2], [x, y], [I, I]) == Matrix([sqrt(2.)*I, sqrt(2.)*I])
|
||||
|
||||
def test_nsolve_dict_kwarg():
|
||||
x, y = symbols('x y')
|
||||
# one variable
|
||||
assert nsolve(x**2 - 2, 1, dict = True) == \
|
||||
[{x: sqrt(2.)}]
|
||||
# one variable with complex solution
|
||||
assert nsolve(x**2 + 2, I, dict = True) == \
|
||||
[{x: sqrt(2.)*I}]
|
||||
# two variables
|
||||
assert nsolve([x**2 + y**2 - 5, x**2 - y**2 + 1], [x, y], [1, 1], dict = True) == \
|
||||
[{x: sqrt(2.), y: sqrt(3.)}]
|
||||
|
||||
def test_nsolve_rational():
|
||||
x = symbols('x')
|
||||
assert nsolve(x - Rational(1, 3), 0, prec=100) == Rational(1, 3).evalf(100)
|
||||
|
||||
|
||||
def test_issue_14950():
|
||||
x = Matrix(symbols('t s'))
|
||||
x0 = Matrix([17, 23])
|
||||
eqn = x + x0
|
||||
assert nsolve(eqn, x, x0) == nfloat(-x0)
|
||||
assert nsolve(eqn.T, x.T, x0.T) == nfloat(-x0)
|
||||
@@ -0,0 +1,239 @@
|
||||
from sympy.core.function import (Derivative as D, Function)
|
||||
from sympy.core.relational import Eq
|
||||
from sympy.core.symbol import (Symbol, symbols)
|
||||
from sympy.functions.elementary.exponential import (exp, log)
|
||||
from sympy.functions.elementary.trigonometric import (cos, sin)
|
||||
from sympy.core import S
|
||||
from sympy.solvers.pde import (pde_separate, pde_separate_add, pde_separate_mul,
|
||||
pdsolve, classify_pde, checkpdesol)
|
||||
from sympy.testing.pytest import raises
|
||||
|
||||
|
||||
a, b, c, x, y = symbols('a b c x y')
|
||||
|
||||
def test_pde_separate_add():
|
||||
x, y, z, t = symbols("x,y,z,t")
|
||||
F, T, X, Y, Z, u = map(Function, 'FTXYZu')
|
||||
|
||||
eq = Eq(D(u(x, t), x), D(u(x, t), t)*exp(u(x, t)))
|
||||
res = pde_separate_add(eq, u(x, t), [X(x), T(t)])
|
||||
assert res == [D(X(x), x)*exp(-X(x)), D(T(t), t)*exp(T(t))]
|
||||
|
||||
|
||||
def test_pde_separate():
|
||||
x, y, z, t = symbols("x,y,z,t")
|
||||
F, T, X, Y, Z, u = map(Function, 'FTXYZu')
|
||||
|
||||
eq = Eq(D(u(x, t), x), D(u(x, t), t)*exp(u(x, t)))
|
||||
raises(ValueError, lambda: pde_separate(eq, u(x, t), [X(x), T(t)], 'div'))
|
||||
|
||||
|
||||
def test_pde_separate_mul():
|
||||
x, y, z, t = symbols("x,y,z,t")
|
||||
c = Symbol("C", real=True)
|
||||
Phi = Function('Phi')
|
||||
F, R, T, X, Y, Z, u = map(Function, 'FRTXYZu')
|
||||
r, theta, z = symbols('r,theta,z')
|
||||
|
||||
# Something simple :)
|
||||
eq = Eq(D(F(x, y, z), x) + D(F(x, y, z), y) + D(F(x, y, z), z), 0)
|
||||
|
||||
# Duplicate arguments in functions
|
||||
raises(
|
||||
ValueError, lambda: pde_separate_mul(eq, F(x, y, z), [X(x), u(z, z)]))
|
||||
# Wrong number of arguments
|
||||
raises(ValueError, lambda: pde_separate_mul(eq, F(x, y, z), [X(x), Y(y)]))
|
||||
# Wrong variables: [x, y] -> [x, z]
|
||||
raises(
|
||||
ValueError, lambda: pde_separate_mul(eq, F(x, y, z), [X(t), Y(x, y)]))
|
||||
|
||||
assert pde_separate_mul(eq, F(x, y, z), [Y(y), u(x, z)]) == \
|
||||
[D(Y(y), y)/Y(y), -D(u(x, z), x)/u(x, z) - D(u(x, z), z)/u(x, z)]
|
||||
assert pde_separate_mul(eq, F(x, y, z), [X(x), Y(y), Z(z)]) == \
|
||||
[D(X(x), x)/X(x), -D(Z(z), z)/Z(z) - D(Y(y), y)/Y(y)]
|
||||
|
||||
# wave equation
|
||||
wave = Eq(D(u(x, t), t, t), c**2*D(u(x, t), x, x))
|
||||
res = pde_separate_mul(wave, u(x, t), [X(x), T(t)])
|
||||
assert res == [D(X(x), x, x)/X(x), D(T(t), t, t)/(c**2*T(t))]
|
||||
|
||||
# Laplace equation in cylindrical coords
|
||||
eq = Eq(1/r * D(Phi(r, theta, z), r) + D(Phi(r, theta, z), r, 2) +
|
||||
1/r**2 * D(Phi(r, theta, z), theta, 2) + D(Phi(r, theta, z), z, 2), 0)
|
||||
# Separate z
|
||||
res = pde_separate_mul(eq, Phi(r, theta, z), [Z(z), u(theta, r)])
|
||||
assert res == [D(Z(z), z, z)/Z(z),
|
||||
-D(u(theta, r), r, r)/u(theta, r) -
|
||||
D(u(theta, r), r)/(r*u(theta, r)) -
|
||||
D(u(theta, r), theta, theta)/(r**2*u(theta, r))]
|
||||
# Lets use the result to create a new equation...
|
||||
eq = Eq(res[1], c)
|
||||
# ...and separate theta...
|
||||
res = pde_separate_mul(eq, u(theta, r), [T(theta), R(r)])
|
||||
assert res == [D(T(theta), theta, theta)/T(theta),
|
||||
-r*D(R(r), r)/R(r) - r**2*D(R(r), r, r)/R(r) - c*r**2]
|
||||
# ...or r...
|
||||
res = pde_separate_mul(eq, u(theta, r), [R(r), T(theta)])
|
||||
assert res == [r*D(R(r), r)/R(r) + r**2*D(R(r), r, r)/R(r) + c*r**2,
|
||||
-D(T(theta), theta, theta)/T(theta)]
|
||||
|
||||
|
||||
def test_issue_11726():
|
||||
x, t = symbols("x t")
|
||||
f = symbols("f", cls=Function)
|
||||
X, T = symbols("X T", cls=Function)
|
||||
|
||||
u = f(x, t)
|
||||
eq = u.diff(x, 2) - u.diff(t, 2)
|
||||
res = pde_separate(eq, u, [T(x), X(t)])
|
||||
assert res == [D(T(x), x, x)/T(x),D(X(t), t, t)/X(t)]
|
||||
|
||||
|
||||
def test_pde_classify():
|
||||
# When more number of hints are added, add tests for classifying here.
|
||||
f = Function('f')
|
||||
eq1 = a*f(x,y) + b*f(x,y).diff(x) + c*f(x,y).diff(y)
|
||||
eq2 = 3*f(x,y) + 2*f(x,y).diff(x) + f(x,y).diff(y)
|
||||
eq3 = a*f(x,y) + b*f(x,y).diff(x) + 2*f(x,y).diff(y)
|
||||
eq4 = x*f(x,y) + f(x,y).diff(x) + 3*f(x,y).diff(y)
|
||||
eq5 = x**2*f(x,y) + x*f(x,y).diff(x) + x*y*f(x,y).diff(y)
|
||||
eq6 = y*x**2*f(x,y) + y*f(x,y).diff(x) + f(x,y).diff(y)
|
||||
for eq in [eq1, eq2, eq3]:
|
||||
assert classify_pde(eq) == ('1st_linear_constant_coeff_homogeneous',)
|
||||
for eq in [eq4, eq5, eq6]:
|
||||
assert classify_pde(eq) == ('1st_linear_variable_coeff',)
|
||||
|
||||
|
||||
def test_checkpdesol():
|
||||
f, F = map(Function, ['f', 'F'])
|
||||
eq1 = a*f(x,y) + b*f(x,y).diff(x) + c*f(x,y).diff(y)
|
||||
eq2 = 3*f(x,y) + 2*f(x,y).diff(x) + f(x,y).diff(y)
|
||||
eq3 = a*f(x,y) + b*f(x,y).diff(x) + 2*f(x,y).diff(y)
|
||||
for eq in [eq1, eq2, eq3]:
|
||||
assert checkpdesol(eq, pdsolve(eq))[0]
|
||||
eq4 = x*f(x,y) + f(x,y).diff(x) + 3*f(x,y).diff(y)
|
||||
eq5 = 2*f(x,y) + 1*f(x,y).diff(x) + 3*f(x,y).diff(y)
|
||||
eq6 = f(x,y) + 1*f(x,y).diff(x) + 3*f(x,y).diff(y)
|
||||
assert checkpdesol(eq4, [pdsolve(eq5), pdsolve(eq6)]) == [
|
||||
(False, (x - 2)*F(3*x - y)*exp(-x/S(5) - 3*y/S(5))),
|
||||
(False, (x - 1)*F(3*x - y)*exp(-x/S(10) - 3*y/S(10)))]
|
||||
for eq in [eq4, eq5, eq6]:
|
||||
assert checkpdesol(eq, pdsolve(eq))[0]
|
||||
sol = pdsolve(eq4)
|
||||
sol4 = Eq(sol.lhs - sol.rhs, 0)
|
||||
raises(NotImplementedError, lambda:
|
||||
checkpdesol(eq4, sol4, solve_for_func=False))
|
||||
|
||||
|
||||
def test_solvefun():
|
||||
f, F, G, H = map(Function, ['f', 'F', 'G', 'H'])
|
||||
eq1 = f(x,y) + f(x,y).diff(x) + f(x,y).diff(y)
|
||||
assert pdsolve(eq1) == Eq(f(x, y), F(x - y)*exp(-x/2 - y/2))
|
||||
assert pdsolve(eq1, solvefun=G) == Eq(f(x, y), G(x - y)*exp(-x/2 - y/2))
|
||||
assert pdsolve(eq1, solvefun=H) == Eq(f(x, y), H(x - y)*exp(-x/2 - y/2))
|
||||
|
||||
|
||||
def test_pde_1st_linear_constant_coeff_homogeneous():
|
||||
f, F = map(Function, ['f', 'F'])
|
||||
u = f(x, y)
|
||||
eq = 2*u + u.diff(x) + u.diff(y)
|
||||
assert classify_pde(eq) == ('1st_linear_constant_coeff_homogeneous',)
|
||||
sol = pdsolve(eq)
|
||||
assert sol == Eq(u, F(x - y)*exp(-x - y))
|
||||
assert checkpdesol(eq, sol)[0]
|
||||
|
||||
eq = 4 + (3*u.diff(x)/u) + (2*u.diff(y)/u)
|
||||
assert classify_pde(eq) == ('1st_linear_constant_coeff_homogeneous',)
|
||||
sol = pdsolve(eq)
|
||||
assert sol == Eq(u, F(2*x - 3*y)*exp(-S(12)*x/13 - S(8)*y/13))
|
||||
assert checkpdesol(eq, sol)[0]
|
||||
|
||||
eq = u + (6*u.diff(x)) + (7*u.diff(y))
|
||||
assert classify_pde(eq) == ('1st_linear_constant_coeff_homogeneous',)
|
||||
sol = pdsolve(eq)
|
||||
assert sol == Eq(u, F(7*x - 6*y)*exp(-6*x/S(85) - 7*y/S(85)))
|
||||
assert checkpdesol(eq, sol)[0]
|
||||
|
||||
eq = a*u + b*u.diff(x) + c*u.diff(y)
|
||||
sol = pdsolve(eq)
|
||||
assert checkpdesol(eq, sol)[0]
|
||||
|
||||
|
||||
def test_pde_1st_linear_constant_coeff():
|
||||
f, F = map(Function, ['f', 'F'])
|
||||
u = f(x,y)
|
||||
eq = -2*u.diff(x) + 4*u.diff(y) + 5*u - exp(x + 3*y)
|
||||
sol = pdsolve(eq)
|
||||
assert sol == Eq(f(x,y),
|
||||
(F(4*x + 2*y)*exp(x/2) + exp(x + 4*y)/15)*exp(-y))
|
||||
assert classify_pde(eq) == ('1st_linear_constant_coeff',
|
||||
'1st_linear_constant_coeff_Integral')
|
||||
assert checkpdesol(eq, sol)[0]
|
||||
|
||||
eq = (u.diff(x)/u) + (u.diff(y)/u) + 1 - (exp(x + y)/u)
|
||||
sol = pdsolve(eq)
|
||||
assert sol == Eq(f(x, y), F(x - y)*exp(-x/2 - y/2) + exp(x + y)/3)
|
||||
assert classify_pde(eq) == ('1st_linear_constant_coeff',
|
||||
'1st_linear_constant_coeff_Integral')
|
||||
assert checkpdesol(eq, sol)[0]
|
||||
|
||||
eq = 2*u + -u.diff(x) + 3*u.diff(y) + sin(x)
|
||||
sol = pdsolve(eq)
|
||||
assert sol == Eq(f(x, y),
|
||||
F(3*x + y)*exp(x/5 - 3*y/5) - 2*sin(x)/5 - cos(x)/5)
|
||||
assert classify_pde(eq) == ('1st_linear_constant_coeff',
|
||||
'1st_linear_constant_coeff_Integral')
|
||||
assert checkpdesol(eq, sol)[0]
|
||||
|
||||
eq = u + u.diff(x) + u.diff(y) + x*y
|
||||
sol = pdsolve(eq)
|
||||
assert sol.expand() == Eq(f(x, y),
|
||||
x + y + (x - y)**2/4 - (x + y)**2/4 + F(x - y)*exp(-x/2 - y/2) - 2).expand()
|
||||
assert classify_pde(eq) == ('1st_linear_constant_coeff',
|
||||
'1st_linear_constant_coeff_Integral')
|
||||
assert checkpdesol(eq, sol)[0]
|
||||
eq = u + u.diff(x) + u.diff(y) + log(x)
|
||||
assert classify_pde(eq) == ('1st_linear_constant_coeff',
|
||||
'1st_linear_constant_coeff_Integral')
|
||||
|
||||
|
||||
def test_pdsolve_all():
|
||||
f, F = map(Function, ['f', 'F'])
|
||||
u = f(x,y)
|
||||
eq = u + u.diff(x) + u.diff(y) + x**2*y
|
||||
sol = pdsolve(eq, hint = 'all')
|
||||
keys = ['1st_linear_constant_coeff',
|
||||
'1st_linear_constant_coeff_Integral', 'default', 'order']
|
||||
assert sorted(sol.keys()) == keys
|
||||
assert sol['order'] == 1
|
||||
assert sol['default'] == '1st_linear_constant_coeff'
|
||||
assert sol['1st_linear_constant_coeff'].expand() == Eq(f(x, y),
|
||||
-x**2*y + x**2 + 2*x*y - 4*x - 2*y + F(x - y)*exp(-x/2 - y/2) + 6).expand()
|
||||
|
||||
|
||||
def test_pdsolve_variable_coeff():
|
||||
f, F = map(Function, ['f', 'F'])
|
||||
u = f(x, y)
|
||||
eq = x*(u.diff(x)) - y*(u.diff(y)) + y**2*u - y**2
|
||||
sol = pdsolve(eq, hint="1st_linear_variable_coeff")
|
||||
assert sol == Eq(u, F(x*y)*exp(y**2/2) + 1)
|
||||
assert checkpdesol(eq, sol)[0]
|
||||
|
||||
eq = x**2*u + x*u.diff(x) + x*y*u.diff(y)
|
||||
sol = pdsolve(eq, hint='1st_linear_variable_coeff')
|
||||
assert sol == Eq(u, F(y*exp(-x))*exp(-x**2/2))
|
||||
assert checkpdesol(eq, sol)[0]
|
||||
|
||||
eq = y*x**2*u + y*u.diff(x) + u.diff(y)
|
||||
sol = pdsolve(eq, hint='1st_linear_variable_coeff')
|
||||
assert sol == Eq(u, F(-2*x + y**2)*exp(-x**3/3))
|
||||
assert checkpdesol(eq, sol)[0]
|
||||
|
||||
eq = exp(x)**2*(u.diff(x)) + y
|
||||
sol = pdsolve(eq, hint='1st_linear_variable_coeff')
|
||||
assert sol == Eq(u, y*exp(-2*x)/2 + F(y))
|
||||
assert checkpdesol(eq, sol)[0]
|
||||
|
||||
eq = exp(2*x)*(u.diff(y)) + y*u - u
|
||||
sol = pdsolve(eq, hint='1st_linear_variable_coeff')
|
||||
assert sol == Eq(u, F(x)*exp(-y*(y - 2)*exp(-2*x)/2))
|
||||
@@ -0,0 +1,462 @@
|
||||
"""Tests for solvers of systems of polynomial equations. """
|
||||
from sympy.polys.domains import ZZ, QQ_I
|
||||
from sympy.core.numbers import (I, Integer, Rational)
|
||||
from sympy.core.singleton import S
|
||||
from sympy.core.symbol import symbols
|
||||
from sympy.functions.elementary.miscellaneous import sqrt
|
||||
from sympy.polys.domains.rationalfield import QQ
|
||||
from sympy.polys.polyerrors import UnsolvableFactorError
|
||||
from sympy.polys.polyoptions import Options
|
||||
from sympy.polys.polytools import Poly
|
||||
from sympy.polys.rootoftools import CRootOf
|
||||
from sympy.solvers.solvers import solve
|
||||
from sympy.utilities.iterables import flatten
|
||||
from sympy.abc import a, b, c, x, y, z
|
||||
from sympy.polys import PolynomialError
|
||||
from sympy.solvers.polysys import (solve_poly_system,
|
||||
solve_triangulated,
|
||||
solve_biquadratic, SolveFailed,
|
||||
solve_generic, factor_system_bool,
|
||||
factor_system_cond, factor_system_poly,
|
||||
factor_system, _factor_sets, _factor_sets_slow)
|
||||
from sympy.polys.polytools import parallel_poly_from_expr
|
||||
from sympy.testing.pytest import raises
|
||||
from sympy.core.relational import Eq
|
||||
from sympy.functions.elementary.trigonometric import sin, cos
|
||||
|
||||
from sympy.functions.elementary.exponential import exp
|
||||
|
||||
|
||||
def test_solve_poly_system():
|
||||
assert solve_poly_system([x - 1], x) == [(S.One,)]
|
||||
|
||||
assert solve_poly_system([y - x, y - x - 1], x, y) is None
|
||||
|
||||
assert solve_poly_system([y - x**2, y + x**2], x, y) == [(S.Zero, S.Zero)]
|
||||
|
||||
assert solve_poly_system([2*x - 3, y*Rational(3, 2) - 2*x, z - 5*y], x, y, z) == \
|
||||
[(Rational(3, 2), Integer(2), Integer(10))]
|
||||
|
||||
assert solve_poly_system([x*y - 2*y, 2*y**2 - x**2], x, y) == \
|
||||
[(0, 0), (2, -sqrt(2)), (2, sqrt(2))]
|
||||
|
||||
assert solve_poly_system([y - x**2, y + x**2 + 1], x, y) == \
|
||||
[(-I*sqrt(S.Half), Rational(-1, 2)), (I*sqrt(S.Half), Rational(-1, 2))]
|
||||
|
||||
f_1 = x**2 + y + z - 1
|
||||
f_2 = x + y**2 + z - 1
|
||||
f_3 = x + y + z**2 - 1
|
||||
|
||||
a, b = sqrt(2) - 1, -sqrt(2) - 1
|
||||
|
||||
assert solve_poly_system([f_1, f_2, f_3], x, y, z) == \
|
||||
[(0, 0, 1), (0, 1, 0), (1, 0, 0), (a, a, a), (b, b, b)]
|
||||
|
||||
solution = [(1, -1), (1, 1)]
|
||||
|
||||
assert solve_poly_system([Poly(x**2 - y**2), Poly(x - 1)]) == solution
|
||||
assert solve_poly_system([x**2 - y**2, x - 1], x, y) == solution
|
||||
assert solve_poly_system([x**2 - y**2, x - 1]) == solution
|
||||
|
||||
assert solve_poly_system(
|
||||
[x + x*y - 3, y + x*y - 4], x, y) == [(-3, -2), (1, 2)]
|
||||
|
||||
raises(NotImplementedError, lambda: solve_poly_system([x**3 - y**3], x, y))
|
||||
raises(NotImplementedError, lambda: solve_poly_system(
|
||||
[z, -2*x*y**2 + x + y**2*z, y**2*(-z - 4) + 2]))
|
||||
raises(PolynomialError, lambda: solve_poly_system([1/x], x))
|
||||
|
||||
raises(NotImplementedError, lambda: solve_poly_system(
|
||||
[x-1,], (x, y)))
|
||||
raises(NotImplementedError, lambda: solve_poly_system(
|
||||
[y-1,], (x, y)))
|
||||
|
||||
# solve_poly_system should ideally construct solutions using
|
||||
# CRootOf for the following four tests
|
||||
assert solve_poly_system([x**5 - x + 1], [x], strict=False) == []
|
||||
raises(UnsolvableFactorError, lambda: solve_poly_system(
|
||||
[x**5 - x + 1], [x], strict=True))
|
||||
|
||||
assert solve_poly_system([(x - 1)*(x**5 - x + 1), y**2 - 1], [x, y],
|
||||
strict=False) == [(1, -1), (1, 1)]
|
||||
raises(UnsolvableFactorError,
|
||||
lambda: solve_poly_system([(x - 1)*(x**5 - x + 1), y**2-1],
|
||||
[x, y], strict=True))
|
||||
|
||||
|
||||
def test_solve_generic():
|
||||
NewOption = Options((x, y), {'domain': 'ZZ'})
|
||||
assert solve_generic([x**2 - 2*y**2, y**2 - y + 1], NewOption) == \
|
||||
[(-sqrt(-1 - sqrt(3)*I), Rational(1, 2) - sqrt(3)*I/2),
|
||||
(sqrt(-1 - sqrt(3)*I), Rational(1, 2) - sqrt(3)*I/2),
|
||||
(-sqrt(-1 + sqrt(3)*I), Rational(1, 2) + sqrt(3)*I/2),
|
||||
(sqrt(-1 + sqrt(3)*I), Rational(1, 2) + sqrt(3)*I/2)]
|
||||
|
||||
# solve_generic should ideally construct solutions using
|
||||
# CRootOf for the following two tests
|
||||
assert solve_generic(
|
||||
[2*x - y, (y - 1)*(y**5 - y + 1)], NewOption, strict=False) == \
|
||||
[(Rational(1, 2), 1)]
|
||||
raises(UnsolvableFactorError, lambda: solve_generic(
|
||||
[2*x - y, (y - 1)*(y**5 - y + 1)], NewOption, strict=True))
|
||||
|
||||
|
||||
def test_solve_biquadratic():
|
||||
x0, y0, x1, y1, r = symbols('x0 y0 x1 y1 r')
|
||||
|
||||
f_1 = (x - 1)**2 + (y - 1)**2 - r**2
|
||||
f_2 = (x - 2)**2 + (y - 2)**2 - r**2
|
||||
s = sqrt(2*r**2 - 1)
|
||||
a = (3 - s)/2
|
||||
b = (3 + s)/2
|
||||
assert solve_poly_system([f_1, f_2], x, y) == [(a, b), (b, a)]
|
||||
|
||||
f_1 = (x - 1)**2 + (y - 2)**2 - r**2
|
||||
f_2 = (x - 1)**2 + (y - 1)**2 - r**2
|
||||
|
||||
assert solve_poly_system([f_1, f_2], x, y) == \
|
||||
[(1 - sqrt((2*r - 1)*(2*r + 1))/2, Rational(3, 2)),
|
||||
(1 + sqrt((2*r - 1)*(2*r + 1))/2, Rational(3, 2))]
|
||||
|
||||
query = lambda expr: expr.is_Pow and expr.exp is S.Half
|
||||
|
||||
f_1 = (x - 1 )**2 + (y - 2)**2 - r**2
|
||||
f_2 = (x - x1)**2 + (y - 1)**2 - r**2
|
||||
|
||||
result = solve_poly_system([f_1, f_2], x, y)
|
||||
|
||||
assert len(result) == 2 and all(len(r) == 2 for r in result)
|
||||
assert all(r.count(query) == 1 for r in flatten(result))
|
||||
|
||||
f_1 = (x - x0)**2 + (y - y0)**2 - r**2
|
||||
f_2 = (x - x1)**2 + (y - y1)**2 - r**2
|
||||
|
||||
result = solve_poly_system([f_1, f_2], x, y)
|
||||
|
||||
assert len(result) == 2 and all(len(r) == 2 for r in result)
|
||||
assert all(len(r.find(query)) == 1 for r in flatten(result))
|
||||
|
||||
s1 = (x*y - y, x**2 - x)
|
||||
assert solve(s1) == [{x: 1}, {x: 0, y: 0}]
|
||||
s2 = (x*y - x, y**2 - y)
|
||||
assert solve(s2) == [{y: 1}, {x: 0, y: 0}]
|
||||
gens = (x, y)
|
||||
for seq in (s1, s2):
|
||||
(f, g), opt = parallel_poly_from_expr(seq, *gens)
|
||||
raises(SolveFailed, lambda: solve_biquadratic(f, g, opt))
|
||||
seq = (x**2 + y**2 - 2, y**2 - 1)
|
||||
(f, g), opt = parallel_poly_from_expr(seq, *gens)
|
||||
assert solve_biquadratic(f, g, opt) == [
|
||||
(-1, -1), (-1, 1), (1, -1), (1, 1)]
|
||||
ans = [(0, -1), (0, 1)]
|
||||
seq = (x**2 + y**2 - 1, y**2 - 1)
|
||||
(f, g), opt = parallel_poly_from_expr(seq, *gens)
|
||||
assert solve_biquadratic(f, g, opt) == ans
|
||||
seq = (x**2 + y**2 - 1, x**2 - x + y**2 - 1)
|
||||
(f, g), opt = parallel_poly_from_expr(seq, *gens)
|
||||
assert solve_biquadratic(f, g, opt) == ans
|
||||
|
||||
|
||||
def test_solve_triangulated():
|
||||
f_1 = x**2 + y + z - 1
|
||||
f_2 = x + y**2 + z - 1
|
||||
f_3 = x + y + z**2 - 1
|
||||
|
||||
a, b = sqrt(2) - 1, -sqrt(2) - 1
|
||||
|
||||
assert solve_triangulated([f_1, f_2, f_3], x, y, z) == \
|
||||
[(0, 0, 1), (0, 1, 0), (1, 0, 0)]
|
||||
|
||||
dom = QQ.algebraic_field(sqrt(2))
|
||||
|
||||
assert solve_triangulated([f_1, f_2, f_3], x, y, z, domain=dom) == \
|
||||
[(0, 0, 1), (0, 1, 0), (1, 0, 0), (a, a, a), (b, b, b)]
|
||||
|
||||
a, b = CRootOf(z**2 + 2*z - 1, 0), CRootOf(z**2 + 2*z - 1, 1)
|
||||
assert solve_triangulated([f_1, f_2, f_3], x, y, z, extension=True) == \
|
||||
[(0, 0, 1), (0, 1, 0), (1, 0, 0), (a, a, a), (b, b, b)]
|
||||
|
||||
|
||||
def test_solve_issue_3686():
|
||||
roots = solve_poly_system([((x - 5)**2/250000 + (y - Rational(5, 10))**2/250000) - 1, x], x, y)
|
||||
assert roots == [(0, S.Half - 15*sqrt(1111)), (0, S.Half + 15*sqrt(1111))]
|
||||
|
||||
roots = solve_poly_system([((x - 5)**2/250000 + (y - 5.0/10)**2/250000) - 1, x], x, y)
|
||||
# TODO: does this really have to be so complicated?!
|
||||
assert len(roots) == 2
|
||||
assert roots[0][0] == 0
|
||||
assert roots[0][1].epsilon_eq(-499.474999374969, 1e12)
|
||||
assert roots[1][0] == 0
|
||||
assert roots[1][1].epsilon_eq(500.474999374969, 1e12)
|
||||
|
||||
|
||||
def test_factor_system():
|
||||
|
||||
assert factor_system([x**2 + 2*x + 1]) == [[x + 1]]
|
||||
assert factor_system([x**2 + 2*x + 1, y**2 + 2*y + 1]) == [[x + 1, y + 1]]
|
||||
assert factor_system([x**2 + 1]) == [[x**2 + 1]]
|
||||
assert factor_system([]) == [[]]
|
||||
|
||||
assert factor_system([x**2 + y**2 + 2*x*y, x**2 - 2], extension=sqrt(2)) == [
|
||||
[x + y, x + sqrt(2)],
|
||||
[x + y, x - sqrt(2)],
|
||||
]
|
||||
|
||||
assert factor_system([x**2 + 1, y**2 + 1], gaussian=True) == [
|
||||
[x + I, y + I],
|
||||
[x + I, y - I],
|
||||
[x - I, y + I],
|
||||
[x - I, y - I],
|
||||
]
|
||||
|
||||
assert factor_system([x**2 + 1, y**2 + 1], domain=QQ_I) == [
|
||||
[x + I, y + I],
|
||||
[x + I, y - I],
|
||||
[x - I, y + I],
|
||||
[x - I, y - I],
|
||||
]
|
||||
|
||||
assert factor_system([0]) == [[]]
|
||||
assert factor_system([1]) == []
|
||||
assert factor_system([0 , x]) == [[x]]
|
||||
assert factor_system([1, 0, x]) == []
|
||||
|
||||
assert factor_system([x**4 - 1, y**6 - 1]) == [
|
||||
[x**2 + 1, y**2 + y + 1],
|
||||
[x**2 + 1, y**2 - y + 1],
|
||||
[x**2 + 1, y + 1],
|
||||
[x**2 + 1, y - 1],
|
||||
[x + 1, y**2 + y + 1],
|
||||
[x + 1, y**2 - y + 1],
|
||||
[x - 1, y**2 + y + 1],
|
||||
[x - 1, y**2 - y + 1],
|
||||
[x + 1, y + 1],
|
||||
[x + 1, y - 1],
|
||||
[x - 1, y + 1],
|
||||
[x - 1, y - 1],
|
||||
]
|
||||
|
||||
assert factor_system([(x - 1)*(y - 2), (y - 2)*(z - 3)]) == [
|
||||
[x - 1, z - 3],
|
||||
[y - 2]
|
||||
]
|
||||
|
||||
assert factor_system([sin(x)**2 + cos(x)**2 - 1, x]) == [
|
||||
[x, sin(x)**2 + cos(x)**2 - 1],
|
||||
]
|
||||
|
||||
assert factor_system([sin(x)**2 + cos(x)**2 - 1]) == [
|
||||
[sin(x)**2 + cos(x)**2 - 1]
|
||||
]
|
||||
|
||||
assert factor_system([sin(x)**2 + cos(x)**2]) == [
|
||||
[sin(x)**2 + cos(x)**2]
|
||||
]
|
||||
|
||||
assert factor_system([a*x, y, a]) == [[y, a]]
|
||||
|
||||
assert factor_system([a*x, y, a], [x, y]) == []
|
||||
|
||||
assert factor_system([a ** 2 * x, y], [x, y]) == [[x, y]]
|
||||
|
||||
assert factor_system([a*x*(x - 1), b*y, c], [x, y]) == []
|
||||
|
||||
assert factor_system([a*x*(x - 1), b*y, c], [x, y, c]) == [
|
||||
[x - 1, y, c],
|
||||
[x, y, c],
|
||||
]
|
||||
|
||||
assert factor_system([a*x*(x - 1), b*y, c]) == [
|
||||
[x - 1, y, c],
|
||||
[x, y, c],
|
||||
[x - 1, b, c],
|
||||
[x, b, c],
|
||||
[y, a, c],
|
||||
[a, b, c],
|
||||
]
|
||||
|
||||
assert factor_system([x**2 - 2], [y]) == []
|
||||
|
||||
assert factor_system([x**2 - 2], [x]) == [[x**2 - 2]]
|
||||
|
||||
assert factor_system([cos(x)**2 - sin(x)**2, cos(x)**2 + sin(x)**2 - 1]) == [
|
||||
[sin(x)**2 + cos(x)**2 - 1, sin(x) + cos(x)],
|
||||
[sin(x)**2 + cos(x)**2 - 1, -sin(x) + cos(x)],
|
||||
]
|
||||
|
||||
assert factor_system([(cos(x) + sin(x))**2 - 1, cos(x)**2 - sin(x)**2 - cos(2*x)]) == [
|
||||
[sin(x)**2 - cos(x)**2 + cos(2*x), sin(x) + cos(x) + 1],
|
||||
[sin(x)**2 - cos(x)**2 + cos(2*x), sin(x) + cos(x) - 1],
|
||||
]
|
||||
|
||||
assert factor_system([(cos(x) + sin(x))*exp(y) - 1, (cos(x) - sin(x))*exp(y) - 1]) == [
|
||||
[exp(y)*sin(x) + exp(y)*cos(x) - 1, -exp(y)*sin(x) + exp(y)*cos(x) - 1]
|
||||
]
|
||||
|
||||
|
||||
def test_factor_system_poly():
|
||||
|
||||
px = lambda e: Poly(e, x)
|
||||
pxab = lambda e: Poly(e, x, domain=ZZ[a, b])
|
||||
pxI = lambda e: Poly(e, x, domain=QQ_I)
|
||||
pxyz = lambda e: Poly(e, (x, y, z))
|
||||
|
||||
assert factor_system_poly([px(x**2 - 1), px(x**2 - 4)]) == [
|
||||
[px(x + 2), px(x + 1)],
|
||||
[px(x + 2), px(x - 1)],
|
||||
[px(x + 1), px(x - 2)],
|
||||
[px(x - 1), px(x - 2)],
|
||||
]
|
||||
|
||||
assert factor_system_poly([px(x**2 - 1)]) == [[px(x + 1)], [px(x - 1)]]
|
||||
|
||||
assert factor_system_poly([pxyz(x**2*y - y), pxyz(x**2*z - z)]) == [
|
||||
[pxyz(x + 1)],
|
||||
[pxyz(x - 1)],
|
||||
[pxyz(y), pxyz(z)],
|
||||
]
|
||||
|
||||
assert factor_system_poly([px(x**2*(x - 1)**2), px(x*(x - 1))]) == [
|
||||
[px(x)],
|
||||
[px(x - 1)],
|
||||
]
|
||||
|
||||
assert factor_system_poly([pxyz(x**2 + y*x), pxyz(x**2 + z*x)]) == [
|
||||
[pxyz(x + y), pxyz(x + z)],
|
||||
[pxyz(x)],
|
||||
]
|
||||
|
||||
assert factor_system_poly([pxab((a - 1)*(x - 2)), pxab((b - 3)*(x - 2))]) == [
|
||||
[pxab(x - 2)],
|
||||
[pxab(a - 1), pxab(b - 3)],
|
||||
]
|
||||
|
||||
assert factor_system_poly([pxI(x**2 + 1)]) == [[pxI(x + I)], [pxI(x - I)]]
|
||||
|
||||
assert factor_system_poly([]) == [[]]
|
||||
|
||||
assert factor_system_poly([px(1)]) == []
|
||||
assert factor_system_poly([px(0), px(x)]) == [[px(x)]]
|
||||
|
||||
|
||||
def test_factor_system_cond():
|
||||
|
||||
assert factor_system_cond([x ** 2 - 1, x ** 2 - 4]) == [
|
||||
[x + 2, x + 1],
|
||||
[x + 2, x - 1],
|
||||
[x + 1, x - 2],
|
||||
[x - 1, x - 2],
|
||||
]
|
||||
|
||||
assert factor_system_cond([1]) == []
|
||||
assert factor_system_cond([0]) == [[]]
|
||||
assert factor_system_cond([1, x]) == []
|
||||
assert factor_system_cond([0, x]) == [[x]]
|
||||
assert factor_system_cond([]) == [[]]
|
||||
|
||||
assert factor_system_cond([x**2 + y*x]) == [[x + y], [x]]
|
||||
|
||||
assert factor_system_cond([(a - 1)*(x - 2), (b - 3)*(x - 2)], [x]) == [
|
||||
[x - 2],
|
||||
[a - 1, b - 3],
|
||||
]
|
||||
|
||||
assert factor_system_cond([a * (x - 1), b], [x]) == [[x - 1, b], [a, b]]
|
||||
|
||||
assert factor_system_cond([a*x*(x-1), b*y, c], [x, y]) == [
|
||||
[x - 1, y, c],
|
||||
[x, y, c],
|
||||
[x - 1, b, c],
|
||||
[x, b, c],
|
||||
[y, a, c],
|
||||
[a, b, c],
|
||||
]
|
||||
|
||||
assert factor_system_cond([x*(x-1), y], [x, y]) == [[x - 1, y], [x, y]]
|
||||
|
||||
assert factor_system_cond([a*x, y, a], [x, y]) == [[y, a]]
|
||||
|
||||
assert factor_system_cond([a*x, b*x], [x, y]) == [[x], [a, b]]
|
||||
|
||||
assert factor_system_cond([a*b*x, y], [x, y]) == [[x, y], [y, a*b]]
|
||||
|
||||
assert factor_system_cond([a*b*x, y]) == [[x, y], [y, a], [y, b]]
|
||||
|
||||
assert factor_system_cond([a**2*x, y], [x, y]) == [[x, y], [y, a]]
|
||||
|
||||
def test_factor_system_bool():
|
||||
|
||||
eqs = [a*(x - 1)*(y - 1), b*(x - 2)*(y - 1)*(y - 2)]
|
||||
assert factor_system_bool(eqs, [x, y]) == (
|
||||
Eq(y - 1, 0)
|
||||
| (Eq(a, 0) & Eq(b, 0))
|
||||
| (Eq(a, 0) & Eq(x - 2, 0))
|
||||
| (Eq(a, 0) & Eq(y - 2, 0))
|
||||
| (Eq(b, 0) & Eq(x - 1, 0))
|
||||
| (Eq(x - 2, 0) & Eq(x - 1, 0))
|
||||
| (Eq(x - 1, 0) & Eq(y - 2, 0))
|
||||
)
|
||||
|
||||
assert factor_system_bool([x - 1], [x]) == Eq(x - 1, 0)
|
||||
|
||||
assert factor_system_bool([(x - 1)*(x - 2)], [x]) == Eq(x - 2, 0) | Eq(x - 1, 0)
|
||||
|
||||
assert factor_system_bool([], [x]) == True
|
||||
assert factor_system_bool([0], [x]) == True
|
||||
assert factor_system_bool([1], [x]) == False
|
||||
assert factor_system_bool([a], [x]) == Eq(a, 0)
|
||||
|
||||
assert factor_system_bool([a * x, y, a], [x, y]) == Eq(a, 0) & Eq(y, 0)
|
||||
|
||||
assert (factor_system_bool([a*x, b*y*x, a], [x, y]) == (
|
||||
Eq(a, 0) & Eq(b, 0))
|
||||
| (Eq(a, 0) & Eq(x, 0))
|
||||
| (Eq(a, 0) & Eq(y, 0)))
|
||||
|
||||
assert (factor_system_bool([a*x, b*x], [x, y]) == Eq(x, 0) |
|
||||
(Eq(a, 0) & Eq(b, 0)))
|
||||
|
||||
assert (factor_system_bool([a*b*x, y], [x, y]) == (
|
||||
Eq(x, 0) & Eq(y, 0)) |
|
||||
(Eq(y, 0) & Eq(a*b, 0)))
|
||||
|
||||
assert (factor_system_bool([a**2*x, y], [x, y]) == (
|
||||
Eq(a, 0) & Eq(y, 0)) |
|
||||
(Eq(x, 0) & Eq(y, 0)))
|
||||
|
||||
assert factor_system_bool([a*x*y, b*y*z], [x, y, z]) == (
|
||||
Eq(y, 0)
|
||||
| (Eq(a, 0) & Eq(b, 0))
|
||||
| (Eq(a, 0) & Eq(z, 0))
|
||||
| (Eq(b, 0) & Eq(x, 0))
|
||||
| (Eq(x, 0) & Eq(z, 0))
|
||||
)
|
||||
|
||||
assert factor_system_bool([a*(x - 1), b], [x]) == (
|
||||
(Eq(a, 0) & Eq(b, 0))
|
||||
| (Eq(x - 1, 0) & Eq(b, 0))
|
||||
)
|
||||
|
||||
|
||||
def test_factor_sets():
|
||||
#
|
||||
from random import randint
|
||||
|
||||
def generate_random_system(n_eqs=3, n_factors=2, max_val=10):
|
||||
return [
|
||||
[randint(0, max_val) for _ in range(randint(1, n_factors))]
|
||||
for _ in range(n_eqs)
|
||||
]
|
||||
|
||||
test_cases = [
|
||||
[[1, 2], [1, 3]],
|
||||
[[1, 2], [3, 4]],
|
||||
[[1], [1, 2], [2]],
|
||||
]
|
||||
|
||||
for case in test_cases:
|
||||
assert _factor_sets(case) == _factor_sets_slow(case)
|
||||
|
||||
for _ in range(100):
|
||||
system = generate_random_system()
|
||||
assert _factor_sets(system) == _factor_sets_slow(system)
|
||||
@@ -0,0 +1,295 @@
|
||||
from sympy.core.function import (Function, Lambda, expand)
|
||||
from sympy.core.numbers import (I, Rational)
|
||||
from sympy.core.relational import Eq
|
||||
from sympy.core.singleton import S
|
||||
from sympy.core.symbol import (Symbol, symbols)
|
||||
from sympy.functions.combinatorial.factorials import (rf, binomial, factorial)
|
||||
from sympy.functions.elementary.complexes import Abs
|
||||
from sympy.functions.elementary.miscellaneous import sqrt
|
||||
from sympy.functions.elementary.trigonometric import (cos, sin)
|
||||
from sympy.polys.polytools import factor
|
||||
from sympy.solvers.recurr import rsolve, rsolve_hyper, rsolve_poly, rsolve_ratio
|
||||
from sympy.testing.pytest import raises, slow, XFAIL
|
||||
from sympy.abc import a, b
|
||||
|
||||
y = Function('y')
|
||||
n, k = symbols('n,k', integer=True)
|
||||
C0, C1, C2 = symbols('C0,C1,C2')
|
||||
|
||||
|
||||
def test_rsolve_poly():
|
||||
assert rsolve_poly([-1, -1, 1], 0, n) == 0
|
||||
assert rsolve_poly([-1, -1, 1], 1, n) == -1
|
||||
|
||||
assert rsolve_poly([-1, n + 1], n, n) == 1
|
||||
assert rsolve_poly([-1, 1], n, n) == C0 + (n**2 - n)/2
|
||||
assert rsolve_poly([-n - 1, n], 1, n) == C0*n - 1
|
||||
assert rsolve_poly([-4*n - 2, 1], 4*n + 1, n) == -1
|
||||
|
||||
assert rsolve_poly([-1, 1], n**5 + n**3, n) == \
|
||||
C0 - n**3 / 2 - n**5 / 2 + n**2 / 6 + n**6 / 6 + 2*n**4 / 3
|
||||
|
||||
|
||||
def test_rsolve_ratio():
|
||||
solution = rsolve_ratio([-2*n**3 + n**2 + 2*n - 1, 2*n**3 + n**2 - 6*n,
|
||||
-2*n**3 - 11*n**2 - 18*n - 9, 2*n**3 + 13*n**2 + 22*n + 8], 0, n)
|
||||
assert solution == C0*(2*n - 3)/(n**2 - 1)/2
|
||||
|
||||
|
||||
def test_rsolve_hyper():
|
||||
assert rsolve_hyper([-1, -1, 1], 0, n) in [
|
||||
C0*(S.Half - S.Half*sqrt(5))**n + C1*(S.Half + S.Half*sqrt(5))**n,
|
||||
C1*(S.Half - S.Half*sqrt(5))**n + C0*(S.Half + S.Half*sqrt(5))**n,
|
||||
]
|
||||
|
||||
assert rsolve_hyper([n**2 - 2, -2*n - 1, 1], 0, n) in [
|
||||
C0*rf(sqrt(2), n) + C1*rf(-sqrt(2), n),
|
||||
C1*rf(sqrt(2), n) + C0*rf(-sqrt(2), n),
|
||||
]
|
||||
|
||||
assert rsolve_hyper([n**2 - k, -2*n - 1, 1], 0, n) in [
|
||||
C0*rf(sqrt(k), n) + C1*rf(-sqrt(k), n),
|
||||
C1*rf(sqrt(k), n) + C0*rf(-sqrt(k), n),
|
||||
]
|
||||
|
||||
assert rsolve_hyper(
|
||||
[2*n*(n + 1), -n**2 - 3*n + 2, n - 1], 0, n) == C1*factorial(n) + C0*2**n
|
||||
|
||||
assert rsolve_hyper(
|
||||
[n + 2, -(2*n + 3)*(17*n**2 + 51*n + 39), n + 1], 0, n) == 0
|
||||
|
||||
assert rsolve_hyper([-n - 1, -1, 1], 0, n) == 0
|
||||
|
||||
assert rsolve_hyper([-1, 1], n, n).expand() == C0 + n**2/2 - n/2
|
||||
|
||||
assert rsolve_hyper([-1, 1], 1 + n, n).expand() == C0 + n**2/2 + n/2
|
||||
|
||||
assert rsolve_hyper([-1, 1], 3*(n + n**2), n).expand() == C0 + n**3 - n
|
||||
|
||||
assert rsolve_hyper([-a, 1],0,n).expand() == C0*a**n
|
||||
|
||||
assert rsolve_hyper([-a, 0, 1], 0, n).expand() == (-1)**n*C1*a**(n/2) + C0*a**(n/2)
|
||||
|
||||
assert rsolve_hyper([1, 1, 1], 0, n).expand() == \
|
||||
C0*(Rational(-1, 2) - sqrt(3)*I/2)**n + C1*(Rational(-1, 2) + sqrt(3)*I/2)**n
|
||||
|
||||
assert rsolve_hyper([1, -2*n/a - 2/a, 1], 0, n) == 0
|
||||
|
||||
|
||||
@XFAIL
|
||||
def test_rsolve_ratio_missed():
|
||||
# this arises during computation
|
||||
# assert rsolve_hyper([-1, 1], 3*(n + n**2), n).expand() == C0 + n**3 - n
|
||||
assert rsolve_ratio([-n, n + 2], n, n) is not None
|
||||
|
||||
|
||||
def recurrence_term(c, f):
|
||||
"""Compute RHS of recurrence in f(n) with coefficients in c."""
|
||||
return sum(c[i]*f.subs(n, n + i) for i in range(len(c)))
|
||||
|
||||
|
||||
def test_rsolve_bulk():
|
||||
"""Some bulk-generated tests."""
|
||||
funcs = [ n, n + 1, n**2, n**3, n**4, n + n**2, 27*n + 52*n**2 - 3*
|
||||
n**3 + 12*n**4 - 52*n**5 ]
|
||||
coeffs = [ [-2, 1], [-2, -1, 1], [-1, 1, 1, -1, 1], [-n, 1], [n**2 -
|
||||
n + 12, 1] ]
|
||||
for p in funcs:
|
||||
# compute difference
|
||||
for c in coeffs:
|
||||
q = recurrence_term(c, p)
|
||||
if p.is_polynomial(n):
|
||||
assert rsolve_poly(c, q, n) == p
|
||||
# See issue 3956:
|
||||
if p.is_hypergeometric(n) and len(c) <= 3:
|
||||
assert rsolve_hyper(c, q, n).subs(zip(symbols('C:3'), [0, 0, 0])).expand() == p
|
||||
|
||||
|
||||
def test_rsolve_0_sol_homogeneous():
|
||||
# fixed by cherry-pick from
|
||||
# https://github.com/diofant/diofant/commit/e1d2e52125199eb3df59f12e8944f8a5f24b00a5
|
||||
assert rsolve_hyper([n**2 - n + 12, 1], n*(n**2 - n + 12) + n + 1, n) == n
|
||||
|
||||
|
||||
def test_rsolve():
|
||||
f = y(n + 2) - y(n + 1) - y(n)
|
||||
h = sqrt(5)*(S.Half + S.Half*sqrt(5))**n \
|
||||
- sqrt(5)*(S.Half - S.Half*sqrt(5))**n
|
||||
|
||||
assert rsolve(f, y(n)) in [
|
||||
C0*(S.Half - S.Half*sqrt(5))**n + C1*(S.Half + S.Half*sqrt(5))**n,
|
||||
C1*(S.Half - S.Half*sqrt(5))**n + C0*(S.Half + S.Half*sqrt(5))**n,
|
||||
]
|
||||
|
||||
assert rsolve(f, y(n), [0, 5]) == h
|
||||
assert rsolve(f, y(n), {0: 0, 1: 5}) == h
|
||||
assert rsolve(f, y(n), {y(0): 0, y(1): 5}) == h
|
||||
assert rsolve(y(n) - y(n - 1) - y(n - 2), y(n), [0, 5]) == h
|
||||
assert rsolve(Eq(y(n), y(n - 1) + y(n - 2)), y(n), [0, 5]) == h
|
||||
|
||||
assert f.subs(y, Lambda(k, rsolve(f, y(n)).subs(n, k))).simplify() == 0
|
||||
|
||||
f = (n - 1)*y(n + 2) - (n**2 + 3*n - 2)*y(n + 1) + 2*n*(n + 1)*y(n)
|
||||
g = C1*factorial(n) + C0*2**n
|
||||
h = -3*factorial(n) + 3*2**n
|
||||
|
||||
assert rsolve(f, y(n)) == g
|
||||
assert rsolve(f, y(n), []) == g
|
||||
assert rsolve(f, y(n), {}) == g
|
||||
|
||||
assert rsolve(f, y(n), [0, 3]) == h
|
||||
assert rsolve(f, y(n), {0: 0, 1: 3}) == h
|
||||
assert rsolve(f, y(n), {y(0): 0, y(1): 3}) == h
|
||||
|
||||
assert f.subs(y, Lambda(k, rsolve(f, y(n)).subs(n, k))).simplify() == 0
|
||||
|
||||
f = y(n) - y(n - 1) - 2
|
||||
|
||||
assert rsolve(f, y(n), {y(0): 0}) == 2*n
|
||||
assert rsolve(f, y(n), {y(0): 1}) == 2*n + 1
|
||||
assert rsolve(f, y(n), {y(0): 0, y(1): 1}) is None
|
||||
|
||||
assert f.subs(y, Lambda(k, rsolve(f, y(n)).subs(n, k))).simplify() == 0
|
||||
|
||||
f = 3*y(n - 1) - y(n) - 1
|
||||
|
||||
assert rsolve(f, y(n), {y(0): 0}) == -3**n/2 + S.Half
|
||||
assert rsolve(f, y(n), {y(0): 1}) == 3**n/2 + S.Half
|
||||
assert rsolve(f, y(n), {y(0): 2}) == 3*3**n/2 + S.Half
|
||||
|
||||
assert f.subs(y, Lambda(k, rsolve(f, y(n)).subs(n, k))).simplify() == 0
|
||||
|
||||
f = y(n) - 1/n*y(n - 1)
|
||||
assert rsolve(f, y(n)) == C0/factorial(n)
|
||||
assert f.subs(y, Lambda(k, rsolve(f, y(n)).subs(n, k))).simplify() == 0
|
||||
|
||||
f = y(n) - 1/n*y(n - 1) - 1
|
||||
assert rsolve(f, y(n)) is None
|
||||
|
||||
f = 2*y(n - 1) + (1 - n)*y(n)/n
|
||||
|
||||
assert rsolve(f, y(n), {y(1): 1}) == 2**(n - 1)*n
|
||||
assert rsolve(f, y(n), {y(1): 2}) == 2**(n - 1)*n*2
|
||||
assert rsolve(f, y(n), {y(1): 3}) == 2**(n - 1)*n*3
|
||||
|
||||
assert f.subs(y, Lambda(k, rsolve(f, y(n)).subs(n, k))).simplify() == 0
|
||||
|
||||
f = (n - 1)*(n - 2)*y(n + 2) - (n + 1)*(n + 2)*y(n)
|
||||
|
||||
assert rsolve(f, y(n), {y(3): 6, y(4): 24}) == n*(n - 1)*(n - 2)
|
||||
assert rsolve(
|
||||
f, y(n), {y(3): 6, y(4): -24}) == -n*(n - 1)*(n - 2)*(-1)**(n)
|
||||
|
||||
assert f.subs(y, Lambda(k, rsolve(f, y(n)).subs(n, k))).simplify() == 0
|
||||
|
||||
assert rsolve(Eq(y(n + 1), a*y(n)), y(n), {y(1): a}).simplify() == a**n
|
||||
|
||||
assert rsolve(y(n) - a*y(n-2),y(n), \
|
||||
{y(1): sqrt(a)*(a + b), y(2): a*(a - b)}).simplify() == \
|
||||
a**(n/2 + 1) - b*(-sqrt(a))**n
|
||||
|
||||
f = (-16*n**2 + 32*n - 12)*y(n - 1) + (4*n**2 - 12*n + 9)*y(n)
|
||||
|
||||
yn = rsolve(f, y(n), {y(1): binomial(2*n + 1, 3)})
|
||||
sol = 2**(2*n)*n*(2*n - 1)**2*(2*n + 1)/12
|
||||
assert factor(expand(yn, func=True)) == sol
|
||||
|
||||
sol = rsolve(y(n) + a*(y(n + 1) + y(n - 1))/2, y(n))
|
||||
assert str(sol) == 'C0*((-sqrt(1 - a**2) - 1)/a)**n + C1*((sqrt(1 - a**2) - 1)/a)**n'
|
||||
|
||||
assert rsolve((k + 1)*y(k), y(k)) is None
|
||||
assert (rsolve((k + 1)*y(k) + (k + 3)*y(k + 1) + (k + 5)*y(k + 2), y(k))
|
||||
is None)
|
||||
|
||||
assert rsolve(y(n) + y(n + 1) + 2**n + 3**n, y(n)) == (-1)**n*C0 - 2**n/3 - 3**n/4
|
||||
|
||||
|
||||
def test_rsolve_raises():
|
||||
x = Function('x')
|
||||
raises(ValueError, lambda: rsolve(y(n) - y(k + 1), y(n)))
|
||||
raises(ValueError, lambda: rsolve(y(n) - y(n + 1), x(n)))
|
||||
raises(ValueError, lambda: rsolve(y(n) - x(n + 1), y(n)))
|
||||
raises(ValueError, lambda: rsolve(y(n) - sqrt(n)*y(n + 1), y(n)))
|
||||
raises(ValueError, lambda: rsolve(y(n) - y(n + 1), y(n), {x(0): 0}))
|
||||
raises(ValueError, lambda: rsolve(y(n) + y(n + 1) + 2**n + cos(n), y(n)))
|
||||
|
||||
|
||||
def test_issue_6844():
|
||||
f = y(n + 2) - y(n + 1) + y(n)/4
|
||||
assert rsolve(f, y(n)) == 2**(-n + 1)*C1*n + 2**(-n)*C0
|
||||
assert rsolve(f, y(n), {y(0): 0, y(1): 1}) == 2**(1 - n)*n
|
||||
|
||||
|
||||
def test_issue_18751():
|
||||
r = Symbol('r', positive=True)
|
||||
theta = Symbol('theta', real=True)
|
||||
f = y(n) - 2 * r * cos(theta) * y(n - 1) + r**2 * y(n - 2)
|
||||
assert rsolve(f, y(n)) == \
|
||||
C0*(r*(cos(theta) - I*Abs(sin(theta))))**n + C1*(r*(cos(theta) + I*Abs(sin(theta))))**n
|
||||
|
||||
|
||||
def test_constant_naming():
|
||||
#issue 8697
|
||||
assert rsolve(y(n+3) - y(n+2) - y(n+1) + y(n), y(n)) == (-1)**n*C1 + C0 + C2*n
|
||||
assert rsolve(y(n+3)+3*y(n+2)+3*y(n+1)+y(n), y(n)).expand() == (-1)**n*C0 - (-1)**n*C1*n - (-1)**n*C2*n**2
|
||||
assert rsolve(y(n) - 2*y(n - 3) + 5*y(n - 2) - 4*y(n - 1),y(n),[1,3,8]) == 3*2**n - n - 2
|
||||
|
||||
#issue 19630
|
||||
assert rsolve(y(n+3) - 3*y(n+1) + 2*y(n), y(n), {y(1):0, y(2):8, y(3):-2}) == (-2)**n + 2*n
|
||||
|
||||
|
||||
@slow
|
||||
def test_issue_15751():
|
||||
f = y(n) + 21*y(n + 1) - 273*y(n + 2) - 1092*y(n + 3) + 1820*y(n + 4) + 1092*y(n + 5) - 273*y(n + 6) - 21*y(n + 7) + y(n + 8)
|
||||
assert rsolve(f, y(n)) is not None
|
||||
|
||||
|
||||
def test_issue_17990():
|
||||
f = -10*y(n) + 4*y(n + 1) + 6*y(n + 2) + 46*y(n + 3)
|
||||
sol = rsolve(f, y(n))
|
||||
expected = C0*((86*18**(S(1)/3)/69 + (-12 + (-1 + sqrt(3)*I)*(290412 +
|
||||
3036*sqrt(9165))**(S(1)/3))*(1 - sqrt(3)*I)*(24201 + 253*sqrt(9165))**
|
||||
(S(1)/3)/276)/((1 - sqrt(3)*I)*(24201 + 253*sqrt(9165))**(S(1)/3))
|
||||
)**n + C1*((86*18**(S(1)/3)/69 + (-12 + (-1 - sqrt(3)*I)*(290412 + 3036
|
||||
*sqrt(9165))**(S(1)/3))*(1 + sqrt(3)*I)*(24201 + 253*sqrt(9165))**
|
||||
(S(1)/3)/276)/((1 + sqrt(3)*I)*(24201 + 253*sqrt(9165))**(S(1)/3))
|
||||
)**n + C2*(-43*18**(S(1)/3)/(69*(24201 + 253*sqrt(9165))**(S(1)/3)) -
|
||||
S(1)/23 + (290412 + 3036*sqrt(9165))**(S(1)/3)/138)**n
|
||||
assert sol == expected
|
||||
e = sol.subs({C0: 1, C1: 1, C2: 1, n: 1}).evalf()
|
||||
assert abs(e + 0.130434782608696) < 1e-13
|
||||
|
||||
|
||||
def test_issue_8697():
|
||||
a = Function('a')
|
||||
eq = a(n + 3) - a(n + 2) - a(n + 1) + a(n)
|
||||
assert rsolve(eq, a(n)) == (-1)**n*C1 + C0 + C2*n
|
||||
eq2 = a(n + 3) + 3*a(n + 2) + 3*a(n + 1) + a(n)
|
||||
assert (rsolve(eq2, a(n)) ==
|
||||
(-1)**n*C0 + (-1)**(n + 1)*C1*n + (-1)**(n + 1)*C2*n**2)
|
||||
|
||||
assert rsolve(a(n) - 2*a(n - 3) + 5*a(n - 2) - 4*a(n - 1),
|
||||
a(n), {a(0): 1, a(1): 3, a(2): 8}) == 3*2**n - n - 2
|
||||
|
||||
# From issue thread (but fixed by https://github.com/diofant/diofant/commit/da9789c6cd7d0c2ceeea19fbf59645987125b289):
|
||||
assert rsolve(a(n) - 2*a(n - 1) - n, a(n), {a(0): 1}) == 3*2**n - n - 2
|
||||
|
||||
|
||||
def test_diofantissue_294():
|
||||
f = y(n) - y(n - 1) - 2*y(n - 2) - 2*n
|
||||
assert rsolve(f, y(n)) == (-1)**n*C0 + 2**n*C1 - n - Rational(5, 2)
|
||||
# issue sympy/sympy#11261
|
||||
assert rsolve(f, y(n), {y(0): -1, y(1): 1}) == (-(-1)**n/2 + 2*2**n -
|
||||
n - Rational(5, 2))
|
||||
# issue sympy/sympy#7055
|
||||
assert rsolve(-2*y(n) + y(n + 1) + n - 1, y(n)) == 2**n*C0 + n
|
||||
|
||||
|
||||
def test_issue_15553():
|
||||
f = Function("f")
|
||||
assert rsolve(Eq(f(n), 2*f(n - 1) + n), f(n)) == 2**n*C0 - n - 2
|
||||
assert rsolve(Eq(f(n + 1), 2*f(n) + n**2 + 1), f(n)) == 2**n*C0 - n**2 - 2*n - 4
|
||||
assert rsolve(Eq(f(n + 1), 2*f(n) + n**2 + 1), f(n), {f(1): 0}) == 7*2**n/2 - n**2 - 2*n - 4
|
||||
assert rsolve(Eq(f(n), 2*f(n - 1) + 3*n**2), f(n)) == 2**n*C0 - 3*n**2 - 12*n - 18
|
||||
assert rsolve(Eq(f(n), 2*f(n - 1) + n**2), f(n)) == 2**n*C0 - n**2 - 4*n - 6
|
||||
assert rsolve(Eq(f(n), 2*f(n - 1) + n), f(n), {f(0): 1}) == 3*2**n - n - 2
|
||||
@@ -0,0 +1,254 @@
|
||||
from sympy.core.numbers import Rational
|
||||
from sympy.core.relational import Eq, Ne
|
||||
from sympy.core.symbol import symbols
|
||||
from sympy.core.sympify import sympify
|
||||
from sympy.core.singleton import S
|
||||
from sympy.core.random import random, choice
|
||||
from sympy.functions.elementary.miscellaneous import sqrt
|
||||
from sympy.ntheory.generate import randprime
|
||||
from sympy.matrices.dense import Matrix
|
||||
from sympy.solvers.solveset import linear_eq_to_matrix
|
||||
from sympy.solvers.simplex import (_lp as lp, _primal_dual,
|
||||
UnboundedLPError, InfeasibleLPError, lpmin, lpmax,
|
||||
_m, _abcd, _simplex, linprog)
|
||||
|
||||
from sympy.external.importtools import import_module
|
||||
|
||||
from sympy.testing.pytest import raises
|
||||
|
||||
from sympy.abc import x, y, z
|
||||
|
||||
|
||||
np = import_module("numpy")
|
||||
scipy = import_module("scipy")
|
||||
|
||||
|
||||
def test_lp():
|
||||
r1 = y + 2*z <= 3
|
||||
r2 = -x - 3*z <= -2
|
||||
r3 = 2*x + y + 7*z <= 5
|
||||
constraints = [r1, r2, r3, x >= 0, y >= 0, z >= 0]
|
||||
objective = -x - y - 5 * z
|
||||
ans = optimum, argmax = lp(max, objective, constraints)
|
||||
assert ans == lpmax(objective, constraints)
|
||||
assert objective.subs(argmax) == optimum
|
||||
for constr in constraints:
|
||||
assert constr.subs(argmax) == True
|
||||
|
||||
r1 = x - y + 2*z <= 3
|
||||
r2 = -x + 2*y - 3*z <= -2
|
||||
r3 = 2*x + y - 7*z <= -5
|
||||
constraints = [r1, r2, r3, x >= 0, y >= 0, z >= 0]
|
||||
objective = -x - y - 5*z
|
||||
ans = optimum, argmax = lp(max, objective, constraints)
|
||||
assert ans == lpmax(objective, constraints)
|
||||
assert objective.subs(argmax) == optimum
|
||||
for constr in constraints:
|
||||
assert constr.subs(argmax) == True
|
||||
|
||||
r1 = x - y + 2*z <= -4
|
||||
r2 = -x + 2*y - 3*z <= 8
|
||||
r3 = 2*x + y - 7*z <= 10
|
||||
constraints = [r1, r2, r3, x >= 0, y >= 0, z >= 0]
|
||||
const = 2
|
||||
objective = -x-y-5*z+const # has constant term
|
||||
ans = optimum, argmax = lp(max, objective, constraints)
|
||||
assert ans == lpmax(objective, constraints)
|
||||
assert objective.subs(argmax) == optimum
|
||||
for constr in constraints:
|
||||
assert constr.subs(argmax) == True
|
||||
|
||||
# Section 4 Problem 1 from
|
||||
# http://web.tecnico.ulisboa.pt/mcasquilho/acad/or/ftp/FergusonUCLA_LP.pdf
|
||||
# answer on page 55
|
||||
v = x1, x2, x3, x4 = symbols('x1 x2 x3 x4')
|
||||
r1 = x1 - x2 - 2*x3 - x4 <= 4
|
||||
r2 = 2*x1 + x3 -4*x4 <= 2
|
||||
r3 = -2*x1 + x2 + x4 <= 1
|
||||
objective, constraints = x1 - 2*x2 - 3*x3 - x4, [r1, r2, r3] + [
|
||||
i >= 0 for i in v]
|
||||
ans = optimum, argmax = lp(max, objective, constraints)
|
||||
assert ans == lpmax(objective, constraints)
|
||||
assert ans == (4, {x1: 7, x2: 0, x3: 0, x4: 3})
|
||||
|
||||
# input contains Floats
|
||||
r1 = x - y + 2.0*z <= -4
|
||||
r2 = -x + 2*y - 3.0*z <= 8
|
||||
r3 = 2*x + y - 7*z <= 10
|
||||
constraints = [r1, r2, r3] + [i >= 0 for i in (x, y, z)]
|
||||
objective = -x-y-5*z
|
||||
optimum, argmax = lp(max, objective, constraints)
|
||||
assert objective.subs(argmax) == optimum
|
||||
for constr in constraints:
|
||||
assert constr.subs(argmax) == True
|
||||
|
||||
# input contains non-float or non-Rational
|
||||
r1 = x - y + sqrt(2) * z <= -4
|
||||
r2 = -x + 2*y - 3*z <= 8
|
||||
r3 = 2*x + y - 7*z <= 10
|
||||
raises(TypeError, lambda: lp(max, -x-y-5*z, [r1, r2, r3]))
|
||||
|
||||
r1 = x >= 0
|
||||
raises(UnboundedLPError, lambda: lp(max, x, [r1]))
|
||||
r2 = x <= -1
|
||||
raises(InfeasibleLPError, lambda: lp(max, x, [r1, r2]))
|
||||
|
||||
# strict inequalities are not allowed
|
||||
r1 = x > 0
|
||||
raises(TypeError, lambda: lp(max, x, [r1]))
|
||||
|
||||
# not equals not allowed
|
||||
r1 = Ne(x, 0)
|
||||
raises(TypeError, lambda: lp(max, x, [r1]))
|
||||
|
||||
def make_random_problem(nvar=2, num_constraints=2, sparsity=.1):
|
||||
def rand():
|
||||
if random() < sparsity:
|
||||
return sympify(0)
|
||||
int1, int2 = [randprime(0, 200) for _ in range(2)]
|
||||
return Rational(int1, int2)*choice([-1, 1])
|
||||
variables = symbols('x1:%s' % (nvar + 1))
|
||||
constraints = [(sum(rand()*x for x in variables) <= rand())
|
||||
for _ in range(num_constraints)]
|
||||
objective = sum(rand() * x for x in variables)
|
||||
return objective, constraints, variables
|
||||
|
||||
# equality
|
||||
r1 = Eq(x, y)
|
||||
r2 = Eq(y, z)
|
||||
r3 = z <= 3
|
||||
constraints = [r1, r2, r3]
|
||||
objective = x
|
||||
ans = optimum, argmax = lp(max, objective, constraints)
|
||||
assert ans == lpmax(objective, constraints)
|
||||
assert objective.subs(argmax) == optimum
|
||||
for constr in constraints:
|
||||
assert constr.subs(argmax) == True
|
||||
|
||||
|
||||
def test_simplex():
|
||||
L = [
|
||||
[[1, 1], [-1, 1], [0, 1], [-1, 0]],
|
||||
[5, 1, 2, -1],
|
||||
[[1, 1]],
|
||||
[-1]]
|
||||
A, B, C, D = _abcd(_m(*L), list=False)
|
||||
assert _simplex(A, B, -C, -D) == (-6, [3, 2], [1, 0, 0, 0])
|
||||
assert _simplex(A, B, -C, -D, dual=True) == (-6,
|
||||
[1, 0, 0, 0], [5, 0])
|
||||
|
||||
assert _simplex([[]],[],[[1]],[0]) == (0, [0], [])
|
||||
|
||||
# handling of Eq (or Eq-like x<=y, x>=y conditions)
|
||||
assert lpmax(x - y, [x <= y + 2, x >= y + 2, x >= 0, y >= 0]
|
||||
) == (2, {x: 2, y: 0})
|
||||
assert lpmax(x - y, [x <= y + 2, Eq(x, y + 2), x >= 0, y >= 0]
|
||||
) == (2, {x: 2, y: 0})
|
||||
assert lpmax(x - y, [x <= y + 2, Eq(x, 2)]) == (2, {x: 2, y: 0})
|
||||
assert lpmax(y, [Eq(y, 2)]) == (2, {y: 2})
|
||||
|
||||
# the conditions are equivalent to Eq(x, y + 2)
|
||||
assert lpmin(y, [x <= y + 2, x >= y + 2, y >= 0]
|
||||
) == (0, {x: 2, y: 0})
|
||||
# equivalent to Eq(y, -2)
|
||||
assert lpmax(y, [0 <= y + 2, 0 >= y + 2]) == (-2, {y: -2})
|
||||
assert lpmax(y, [0 <= y + 2, 0 >= y + 2, y <= 0]
|
||||
) == (-2, {y: -2})
|
||||
|
||||
# extra symbols symbols
|
||||
assert lpmin(x, [y >= 1, x >= y]) == (1, {x: 1, y: 1})
|
||||
assert lpmin(x, [y >= 1, x >= y + z, x >= 0, z >= 0]
|
||||
) == (1, {x: 1, y: 1, z: 0})
|
||||
|
||||
# detect oscillation
|
||||
# o1
|
||||
v = x1, x2, x3, x4 = symbols('x1 x2 x3 x4')
|
||||
raises(InfeasibleLPError, lambda: lpmin(
|
||||
9*x2 - 8*x3 + 3*x4 + 6,
|
||||
[5*x2 - 2*x3 <= 0,
|
||||
-x1 - 8*x2 + 9*x3 <= -3,
|
||||
10*x1 - x2+ 9*x4 <= -4] + [i >= 0 for i in v]))
|
||||
# o2 - equations fed to lpmin are changed into a matrix
|
||||
# system that doesn't oscillate and has the same solution
|
||||
# as below
|
||||
M = linear_eq_to_matrix
|
||||
f = 5*x2 + x3 + 4*x4 - x1
|
||||
L = 5*x2 + 2*x3 + 5*x4 - (x1 + 5)
|
||||
cond = [L <= 0] + [Eq(3*x2 + x4, 2), Eq(-x1 + x3 + 2*x4, 1)]
|
||||
c, d = M(f, v)
|
||||
a, b = M(L, v)
|
||||
aeq, beq = M(cond[1:], v)
|
||||
ans = (S(9)/2, [0, S(1)/2, 0, S(1)/2])
|
||||
assert linprog(c, a, b, aeq, beq, bounds=(0, 1)) == ans
|
||||
lpans = lpmin(f, cond + [x1 >= 0, x1 <= 1,
|
||||
x2 >= 0, x2 <= 1, x3 >= 0, x3 <= 1, x4 >= 0, x4 <= 1])
|
||||
assert (lpans[0], list(lpans[1].values())) == ans
|
||||
|
||||
|
||||
def test_lpmin_lpmax():
|
||||
v = x1, x2, y1, y2 = symbols('x1 x2 y1 y2')
|
||||
L = [[1, -1]], [1], [[1, 1]], [2]
|
||||
a, b, c, d = [Matrix(i) for i in L]
|
||||
m = Matrix([[a, b], [c, d]])
|
||||
f, constr = _primal_dual(m)[0]
|
||||
ans = lpmin(f, constr + [i >= 0 for i in v[:2]])
|
||||
assert ans == (-1, {x1: 1, x2: 0}),ans
|
||||
|
||||
L = [[1, -1], [1, 1]], [1, 1], [[1, 1]], [2]
|
||||
a, b, c, d = [Matrix(i) for i in L]
|
||||
m = Matrix([[a, b], [c, d]])
|
||||
f, constr = _primal_dual(m)[1]
|
||||
ans = lpmax(f, constr + [i >= 0 for i in v[-2:]])
|
||||
assert ans == (-1, {y1: 1, y2: 0})
|
||||
|
||||
|
||||
def test_linprog():
|
||||
for do in range(2):
|
||||
if not do:
|
||||
M = lambda a, b: linear_eq_to_matrix(a, b)
|
||||
else:
|
||||
# check matrices as list
|
||||
M = lambda a, b: tuple([
|
||||
i.tolist() for i in linear_eq_to_matrix(a, b)])
|
||||
|
||||
v = x, y, z = symbols('x1:4')
|
||||
f = x + y - 2*z
|
||||
c = M(f, v)[0]
|
||||
ineq = [7*x + 4*y - 7*z <= 3,
|
||||
3*x - y + 10*z <= 6,
|
||||
x >= 0, y >= 0, z >= 0]
|
||||
ab = M([i.lts - i.gts for i in ineq], v)
|
||||
ans = (-S(6)/5, [0, 0, S(3)/5])
|
||||
assert lpmin(f, ineq) == (ans[0], dict(zip(v, ans[1])))
|
||||
assert linprog(c, *ab) == ans
|
||||
|
||||
f += 1
|
||||
c = M(f, v)[0]
|
||||
eq = [Eq(y - 9*x, 1)]
|
||||
abeq = M([i.lhs - i.rhs for i in eq], v)
|
||||
ans = (1 - S(2)/5, [0, 1, S(7)/10])
|
||||
assert lpmin(f, ineq + eq) == (ans[0], dict(zip(v, ans[1])))
|
||||
assert linprog(c, *ab, *abeq) == (ans[0] - 1, ans[1])
|
||||
|
||||
eq = [z - y <= S.Half]
|
||||
abeq = M([i.lhs - i.rhs for i in eq], v)
|
||||
ans = (1 - S(10)/9, [0, S(1)/9, S(11)/18])
|
||||
assert lpmin(f, ineq + eq) == (ans[0], dict(zip(v, ans[1])))
|
||||
assert linprog(c, *ab, *abeq) == (ans[0] - 1, ans[1])
|
||||
|
||||
bounds = [(0, None), (0, None), (None, S.Half)]
|
||||
ans = (0, [0, 0, S.Half])
|
||||
assert lpmin(f, ineq + [z <= S.Half]) == (
|
||||
ans[0], dict(zip(v, ans[1])))
|
||||
assert linprog(c, *ab, bounds=bounds) == (ans[0] - 1, ans[1])
|
||||
assert linprog(c, *ab, bounds={v.index(z): bounds[-1]}
|
||||
) == (ans[0] - 1, ans[1])
|
||||
eq = [z - y <= S.Half]
|
||||
|
||||
assert linprog([[1]], [], [], bounds=(2, 3)) == (2, [2])
|
||||
assert linprog([1], [], [], bounds=(2, 3)) == (2, [2])
|
||||
assert linprog([1], bounds=(2, 3)) == (2, [2])
|
||||
assert linprog([1, -1], [[1, 1]], [2], bounds={1:(None, None)}
|
||||
) == (-2, [0, 2])
|
||||
assert linprog([1, -1], [[1, 1]], [5], bounds={1:(3, None)}
|
||||
) == (-5, [0, 5])
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user