1# 2# test_linsolve.py 3# 4# Test the internal implementation of linsolve. 5# 6 7from sympy.testing.pytest import raises 8 9from sympy import S, Eq, I 10from sympy.abc import x, y, z 11 12from sympy.polys.matrices.linsolve import _linsolve 13from sympy.polys.solvers import PolyNonlinearError 14 15 16def test__linsolve(): 17 assert _linsolve([], [x]) == {x:x} 18 assert _linsolve([S.Zero], [x]) == {x:x} 19 assert _linsolve([x-1,x-2], [x]) is None 20 assert _linsolve([x-1], [x]) == {x:1} 21 assert _linsolve([x-1, y], [x, y]) == {x:1, y:S.Zero} 22 assert _linsolve([2*I], [x]) is None 23 raises(PolyNonlinearError, lambda: _linsolve([x*(1 + x)], [x])) 24 25 26def test__linsolve_float(): 27 28 # This should give the exact answer: 29 eqs = [ 30 y - x, 31 y - 0.0216 * x 32 ] 33 sol = {x:0.0, y:0.0} 34 assert _linsolve(eqs, (x, y)) == sol 35 36 # Other cases should be close to eps 37 38 def all_close(sol1, sol2, eps=1e-15): 39 close = lambda a, b: abs(a - b) < eps 40 assert sol1.keys() == sol2.keys() 41 return all(close(sol1[s], sol2[s]) for s in sol1) 42 43 eqs = [ 44 0.8*x + 0.8*z + 0.2, 45 0.9*x + 0.7*y + 0.2*z + 0.9, 46 0.7*x + 0.2*y + 0.2*z + 0.5 47 ] 48 sol_exact = {x:-29/42, y:-11/21, z:37/84} 49 sol_linsolve = _linsolve(eqs, [x,y,z]) 50 assert all_close(sol_exact, sol_linsolve) 51 52 eqs = [ 53 0.9*x + 0.3*y + 0.4*z + 0.6, 54 0.6*x + 0.9*y + 0.1*z + 0.7, 55 0.4*x + 0.6*y + 0.9*z + 0.5 56 ] 57 sol_exact = {x:-88/175, y:-46/105, z:-1/25} 58 sol_linsolve = _linsolve(eqs, [x,y,z]) 59 assert all_close(sol_exact, sol_linsolve) 60 61 eqs = [ 62 0.4*x + 0.3*y + 0.6*z + 0.7, 63 0.4*x + 0.3*y + 0.9*z + 0.9, 64 0.7*x + 0.9*y, 65 ] 66 sol_exact = {x:-9/5, y:7/5, z:-2/3} 67 sol_linsolve = _linsolve(eqs, [x,y,z]) 68 assert all_close(sol_exact, sol_linsolve) 69 70 eqs = [ 71 x*(0.7 + 0.6*I) + y*(0.4 + 0.7*I) + z*(0.9 + 0.1*I) + 0.5, 72 0.2*I*x + 0.2*I*y + z*(0.9 + 0.2*I) + 0.1, 73 x*(0.9 + 0.7*I) + y*(0.9 + 0.7*I) + z*(0.9 + 0.4*I) + 0.4, 74 ] 75 sol_exact = { 76 x:-6157/7995 - 411/5330*I, 77 y:8519/15990 + 1784/7995*I, 78 z:-34/533 + 107/1599*I, 79 } 80 sol_linsolve = _linsolve(eqs, [x,y,z]) 81 assert all_close(sol_exact, sol_linsolve) 82 83 # XXX: This system for x and y over RR(z) is problematic. 84 # 85 # eqs = [ 86 # x*(0.2*z + 0.9) + y*(0.5*z + 0.8) + 0.6, 87 # 0.1*x*z + y*(0.1*z + 0.6) + 0.9, 88 # ] 89 # 90 # linsolve(eqs, [x, y]) 91 # The solution for x comes out as 92 # 93 # -3.9e-5*z**2 - 3.6e-5*z - 8.67361737988404e-20 94 # x = ---------------------------------------------- 95 # 3.0e-6*z**3 - 1.3e-5*z**2 - 5.4e-5*z 96 # 97 # The 8e-20 in the numerator should be zero which would allow z to cancel 98 # from top and bottom. It should be possible to avoid this somehow because 99 # the inverse of the matrix only has a quadratic factor (the determinant) 100 # in the denominator. 101 102 103def test__linsolve_deprecated(): 104 assert _linsolve([Eq(x**2, x**2+y)], [x, y]) == {x:x, y:S.Zero} 105 assert _linsolve([(x+y)**2-x**2], [x]) == {x:-y/2} 106 assert _linsolve([Eq((x+y)**2, x**2)], [x]) == {x:-y/2} 107