Closed certik closed 12 years ago
bc.. The point of failure here ist the attempt of multivariate factorization.
Multivariate factorization is not at all robust, because it just tries to solve the problem by factorization of a new univariate polynomial (of high degree, depending on the number of variables). This is probably, were the overflow is generated.
Factorization is called from simplify in the solver. I guess that the solving wouldn't pose any great problems though. Ideally, the solver would recognize this as linear equations and call the appropriate matrix algorithm, right?
p. Original comment: "http://code.google.com/p/sympy/issues/detail?id=458#c1":http://code.google.com/p/sympy/issues/detail?id=458#c1
p. Original author: "https://code.google.com/u/116277859734487035258/":https://code.google.com/u/116277859734487035258/
bc.. Yes, in this case it should be converted to matrix algorithm automatically by the solver. So it should be actually pretty easy to fix this bug.
The only problem is how to easily automatically recognize that we deal with a linear system.
p. Original comment: "http://code.google.com/p/sympy/issues/detail?id=458#c2":http://code.google.com/p/sympy/issues/detail?id=458#c2
p. Original author: "https://code.google.com/u/104039945248245758823/":https://code.google.com/u/104039945248245758823/
bc.. Labels: -Priority-Medium Priority-High
p. Original comment: "http://code.google.com/p/sympy/issues/detail?id=458#c3":http://code.google.com/p/sympy/issues/detail?id=458#c3
p. Original author: "https://code.google.com/u/104039945248245758823/":https://code.google.com/u/104039945248245758823/
bc.. You can apply the following patch:
$ hg di diff -r 48db9d4aaf29 sympy/solvers/solvers.py --- a/sympy/solvers/solvers.py Fri Dec 14 09:14:00 2007 +0300 +++ b/sympy/solvers/solvers.py Fri Dec 14 22:19:10 2007 +0100 @@ -202,7 +202,7 @@ def solve_linear_system(system, symbols, content -= matrix[k, j]*solutions[syms[j]]
if simplified == True:
That doesn't use "simplify", but just expand() and then it works, even though the result is complicated:
$ bin/isympy Python 2.4.4 console for SymPy 0.5.8-hg. These commands were executed:
from future import division from sympy import * x, y, z = symbols('xyz') k, m, n = symbols('kmn', integer=True) f = Function("f") Basic.set_repr_level(2) # pretty print output; Use "1" for python output pprint_try_use_unicode() # use unicode pretty print when available
In [1]: a,b,c,d,e,f,g,h,i,x,y,z = symbols('abcdefghixyz')
In [2]: eq1 = x_a + y_b + z*c == 1
In [3]: eq2 = x_d + y_e + z*f == 1
In [4]: eq3 = x_g + y_h + z*i == 1
In [5]: print solve([eq1,eq2,eq3],[x,y,z])
{y:
1 d f
─────── - ─────────── - ──────────────────────────────────────────────────────
b_d ⎛ b_d⎞ ⎛ b_d⎞ ⎛ c_g f_h b_f_g c_dh
e - ─── a⎜e - ───⎟ ⎜e - ───⎟_⎜i - ─── - ─────── + ─────────── + ─────────
a ⎝ a ⎠ ⎝ a ⎠ ⎜ a b_d ⎛ bd⎞ ⎛ b
⎜ e - ─── a⎜e - ───⎟ a⎜e - ──
⎝ a ⎝ a ⎠ ⎝ a
[...]
(and many more lines like that)
Status: Started
p. Original comment: "http://code.google.com/p/sympy/issues/detail?id=458#c4":http://code.google.com/p/sympy/issues/detail?id=458#c4
p. Original author: "https://code.google.com/u/104039945248245758823/":https://code.google.com/u/104039945248245758823/
bc.. It's a bad idea to call simplify() in the solver. Imho. But it's clear, that it needs to try to simplify things, compare the result from sympy and from maxima.
p. Original comment: "http://code.google.com/p/sympy/issues/detail?id=458#c5":http://code.google.com/p/sympy/issues/detail?id=458#c5
p. Original author: "https://code.google.com/u/104039945248245758823/":https://code.google.com/u/104039945248245758823/
bc.. With some effort sympy can compute the system in finite time:
In [1]: var('a b c d e f g h i') Out[1]: (a, b, c, d, e, f, g, h, i)
In [2]: f_1 = x_a + y_b + z*c - 1
In [3]: f_2 = x_d + y_e + z*f - 1
In [4]: f_3 = x_g + y_h + z*i - 1
In [5]: s = solve([f_1,f_2,f_3], x,y,z, simplified=False)
In [6]: s_x = Poly.cancel(s[x])
In [7]: s_y = Poly.cancel(s[y])
In [8]: s_z = Poly.cancel(s[z])
In [9]: s_x
Out[9]:
b_f + c_h + e_i - b_i - c_e - f_h
─────────────────────────────────────────────
a_e_i + b_f_g + c_d_h - a_f_h - b_d_i - c_e_g
In [10]: s_y
Out[10]:
a_f + c_g + d_i - a_i - c_d - f_g
─────────────────────────────────────────────
a_f_h + b_d_i + c_e_g - a_e_i - b_f_g - c_d_h
In [11]: s_z
Out[11]:
a_e + b_g + d_h - a_h - b_d - e_g
─────────────────────────────────────────────
a_e_i + b_f_g + c_d_h - a_f_h - b_d_i - c_e_g
It's a bad idea to call simplify() in the solver.
It's bad to use radsimp() (if fact match()) anywhere:
In [12]: s_x.count_ops(False) Out[12]: 36
In [13]: s[x].count_ops(False) Out[13]: 137
In [14]: powsimp(s[x]).count_ops(False) Out[14]: 137
In [15]: radsimp(s[x]).count_ops(False) Out[15]: 1152
For now a solution is to remove radsimp() from simplify(). If fact functionality of radsimp() was reimplemented in Poly.cancel() for Symbol-less case (where radsimp() gives any reasonable results), so we won't loose anything with this change.
Summary: radsimp() makes expressions more complex.
p. Original comment: "http://code.google.com/p/sympy/issues/detail?id=458#c6":http://code.google.com/p/sympy/issues/detail?id=458#c6
p. Original author: "https://code.google.com/u/101069955704897915480/":https://code.google.com/u/101069955704897915480/
bc.. So it's radsimp redundant? Let's remove it then, or call Poly.cancel() from it.
p. Original comment: "http://code.google.com/p/sympy/issues/detail?id=458#c7":http://code.google.com/p/sympy/issues/detail?id=458#c7
p. Original author: "https://code.google.com/u/104039945248245758823/":https://code.google.com/u/104039945248245758823/
bc.. The original problem was fixed and a test written.
In [1]: var('a b c d e f g h i') Out[1]: (a, b, c, d, e, f, g, h, i)
In [2]: f_1 = x_a + y_b + z*c - 1
In [3]: f_2 = x_d + y_e + z*f - 1
In [4]: f_3 = x_g + y_h + z*i - 1
In [5]: solve([f_1,f_2,f_3], x,y,z) Out[5]: ⎧ a_e + b_g + d_h - a_h - b_d - e_g a_f + c_g + d_i - ⎨z: ─────────────────────────────────────────────, y: ──────────────────────── ⎩ a_e_i + b_f_g + c_d_h - a_f_h - b_d_i - c_e_g a_f_h + b_d_i + c_e*g -
a_i - c_d - f_g b_f + c_h + e_i - b_i - c_e - f_h ⎫ ─────────────────────, x: ─────────────────────────────────────────────⎬ a_e_i - b_f_g - c_d_h a_e_i + b_f_g + c_d_h - a_f_h - b_d_i - c_e*g⎭
p. Original comment: "http://code.google.com/p/sympy/issues/detail?id=458#c8":http://code.google.com/p/sympy/issues/detail?id=458#c8
p. Original author: "https://code.google.com/u/104039945248245758823/":https://code.google.com/u/104039945248245758823/
bc.. So I think this is not a high priority anymore.
Labels: -Priority-High Priority-Medium
p. Original comment: "http://code.google.com/p/sympy/issues/detail?id=458#c9":http://code.google.com/p/sympy/issues/detail?id=458#c9
p. Original author: "https://code.google.com/u/104039945248245758823/":https://code.google.com/u/104039945248245758823/
bc.. > So it's radsimp redundant?
radsimp() is needed, but:
[1] Basic.match must be fixed, there are many other issues concerning it [2] radsimp() must know about sqrtdenest(), to handle trivial cases fast and also non-trivial input [3] it can't be applied blindly as it was in simplify()
p. Original comment: "http://code.google.com/p/sympy/issues/detail?id=458#c10":http://code.google.com/p/sympy/issues/detail?id=458#c10
p. Original author: "https://code.google.com/u/101069955704897915480/":https://code.google.com/u/101069955704897915480/
Chris, do your radsimp() changes in t (commit from issue 4924 ) fix any of this? Or is that issue a duplicate of this one?
**Cc:** smichr
Referenced issues: #4924 Original comment: http://code.google.com/p/sympy/issues/detail?id=458#c12 Original author: https://code.google.com/u/asmeurer@gmail.com/
c8 pointed out the the OP issue was fixed. 1825 fixes the explosion-in-size issue and a pull is forthcoming.
>>> ok = var('a:z')
>>> eq1 = x*a + y*b + z*c - 1
>>> eq2 = x*d + y*e + z*f - 1
>>> eq3 = x*g + y*h + z*i - 1
>>> s = solve([eq1,eq2,eq3],[x,y,z])
>>> for k,v in s.items():
... print k
... pprint(v)
... print
...
x
b*f - b*i - c*e + c*h + e*i - f*h
---------------------------------------------
a*e*i - a*f*h - b*d*i + b*f*g + c*d*h - c*e*g
y
-a*f + a*i + c*d - c*g - d*i + f*g
---------------------------------------------
a*e*i - a*f*h - b*d*i + b*f*g + c*d*h - c*e*g
z
a*e - a*h - b*d + b*g + d*h - e*g
---------------------------------------------
a*e*i - a*f*h - b*d*i + b*f*g + c*d*h - c*e*g
>>> s[x].count_ops()
29
>>> radsimp(s[x]).count_ops()
29
Original comment: http://code.google.com/p/sympy/issues/detail?id=458#c13 Original author: https://code.google.com/u/117933771799683895267/
https://github.com/sympy/sympy/pull/660
**Labels:** NeedsReview smichr
Original comment: http://code.google.com/p/sympy/issues/detail?id=458#c14 Original author: https://code.google.com/u/117933771799683895267/
Actually, the explosion of size was already fixed in master, but the other issues (which I will enumerate in the commit message) are addressed by the pull request.
Original comment: http://code.google.com/p/sympy/issues/detail?id=458#c15 Original author: https://code.google.com/u/117933771799683895267/
**Status:** Fixed
Original comment: http://code.google.com/p/sympy/issues/detail?id=458#c16 Original author: https://code.google.com/u/117933771799683895267/
bc.. a,b,c,d,e,f,g,h,i,x,y,z = symbols('abcdefghixyz')
Maxima:
eq1 : x_a + y_b + z_c = 1; eq2 : x_d + y_e + z_f = 1; eq3 : x_g + y_h + z*i = 1;
(%i18) solve([eq1,eq2,eq3],[x,y,z]);
(%o18) [[x = ---------------------------------------------, a (f h - e i) + b (d i - f g) + c (e g - d h) a (i - f) - d i + f g + c (d - g) y = - ---------------------------------------------, a (f h - e i) + b (d i - f g) + c (e g - d h) a (h - e) - d h + e g + b (d - g) z = ---------------------------------------------]] a (f h - e i) + b (d i - f g) + c (e g - d h)
p. Original issue for "#3557":https://github.com/sympy/sympy/issues/3557: "http://code.google.com/p/sympy/issues/detail?id=458":http://code.google.com/p/sympy/issues/detail?id=458
p. Original author: "https://code.google.com/u/104039945248245758823/":https://code.google.com/u/104039945248245758823/