New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
nonlinsolve() and linsolve() fail on a under-determined system #19859
Comments
I just tested with sympy 1.6.1 (the latest available version for now) and the result is the same -- no solution found. |
In your example you substitute values for In [27]: A, b = linear_eq_to_matrix(sy, [x1, x2, x3, x4])
In [28]: Matrix.hstack(A, b).echelon_form().expand()
Out[28]:
Matrix([
[1, 1, 1, 1, 1],
[0, -1, 0, -1, i - 1],
[0, 0, 1 - a, -a, 0],
[0, 0, 0, -a - b + 1, 0],
[0, 0, 0, 0, -i - j + 1]]) From the lower-right of the echelon form of the augmented matrix we can see that a solution only exists if A simpler example to demonstrate what you are showing is this: In [45]: x, y = symbols('x, y')
In [46]: solve(eqs, [x])
Out[46]: []
In [47]: linsolve(eqs, [x])
Out[47]: ∅
In [48]: nonlinsolve(eqs, [x])
Out[48]: {(-1,)} I said that sympy usually gives the generic solution because this is not uniformly applied and we can see e.g. that If instead one of the conditional parameters is given as an unknown then all solvers can find the value of that unknown: In [50]: solve(eqs, [x, y])
Out[50]: {x: -1, y: 1}
In [51]: linsolve(eqs, [x, y])
Out[51]: {(-1, 1)}
In [52]: nonlinsolve(eqs, [x, y])
Out[52]: {(-1, 1)} That will also work in the original example: In [53]: linsolve(sy, [x1,x2,x3,x4,i])
Out[53]: {(1 - j, j, 0, 0, 1 - j)}
In [54]: linsolve(sy, [x1,x2,x3,x4,i,j])
Out[54]: {(1 - j, j, 0, 0, 1 - j, j)} I don't think the example you have showed is incorrect. Rather I think that We should support conditionally existent solutions as described in #16861. The solver from there fails for this example though... |
To be clear the system with only |
In fact,
It could also make sense to add an optional parameter to |
You can include the equation In [12]: linsolve(sy + [i + j - 1], [x1, x2, x3, x4, i])
Out[12]: {(1 - j, j, 0, 0, 1 - j)}
In [13]: linsolve(sy + [i + j - 1], [x1, x2, x3, x4, i, j])
Out[13]: {(1 - j, j, 0, 0, 1 - j, j)}
In [14]: linsolve(sy + [i + j - 1], [x1, x2, x3, x4, j])
Out[14]: {(i, 1 - i, 0, 0, 1 - i)} If you want In [7]: linsolve(sy, [x1,x2,x3,x4,i])
Out[7]: {(1 - j, j, 0, 0, 1 - j)}
It wouldn't be hard for sympy to do this automatically but the implication would be that linsolve returns solution sets that are not generically correct. If i and j are parameters of the system rather than unknowns then for almost all possible values of i and j the system has no solution. That is why linsolve returns the empty set. That might not be the ideal behaviour in your usecase but it is a consistent definition. |
This workaround is not as generic as suggested
looks close to the searched solution. |
Rather than psubs it would probably make more sense to have a parameter called something like linsolve(..., conditions=Eq(i + j, 1) & Eq(a + b, 1)) On the other hand at some point we probably want to be able to support an assumptions argument here so maybe that could be used as the mechanism like linsolve(..., assumptions=Q(Eq(i + j, 1) & Eq(a + b, 1))) For now you don't need to use nonlinsolve if you eliminate the redundant symbols: In [6]: conditions = [Eq(i + j, 1), Eq(a + b, 1)]
In [7]: rep = solve(conditions, [j, b])
In [8]: rep
Out[8]: {b: 1 - a, j: 1 - i}
In [9]: linsolve([s.subs(rep) for s in sy], [x1,x2,x3,x4])
Out[9]:
⎧⎛ a⋅x₄ -a⋅x₄ ⎞⎫
⎨⎜───── + i, -i - x₄ + 1, ──────, x₄⎟⎬
⎩⎝a - 1 a - 1 ⎠⎭ |
Hi,
I am new to SymPy and trying to solve a parametric linear system with 4 variables x1, x2, x3, x4 and 4 parameters a, b, i, and j. The system is under-determined, it has 1 free variable despite the fact that there are 5 equations. However,
nonlinsolve()
andlinsolve()
does not detect that the system is under-determined and provided meaningless result. Here is a minimal reproducible example:And here is an example of a solution:
I am using Python 3.7.6 and sympy 1.3 on a rpm based Linux.
The text was updated successfully, but these errors were encountered: