SymPy解决容易方程的零空间时出现问题。

huangapple go评论61阅读模式
英文:

Sympy solve fails to find nullspace of easy equation

问题

You may be using solve correctly, but it's possible that the equations you provided are more complex than what sympy can handle easily. The complexity of equations and their solutions can vary, and sympy may not always find simplified solutions as you expect. You might consider manually simplifying or manipulating the equations to get the specific solution you desire.

英文:

I am trying to find the nullspace of various function-sets with pythons module sympy. It managed to find the solution to some sets like
{(x - 1)!, x * (x - 2)!, (x - 2)!}
My code is

from sympy import solve, factorial
from sympy.abc import a, b, c, x
eq = a * factorial(x - 1) + b * x * factorial(x - 2) + c * factorial(x - 2)
print(solve(eq, a, b, c, set=True))  #  output: ([a, b, c], {((-b*x + b - c)/x, b, c)})
eq = -b * x + b - c - a * x
print(solve(eq, a, b, c, set=True)) #  output: ([a, b], {(-c, c)})

However, it struggled with the set
{upper_gamma(x, -1), upper_gamma(x - 1, -1), x * upper_gamma(x - 1, -1), (-1) ^ x}
Which is fair enough, even wolfram-alpha cannot find the solution. However, I was surprised when it also failed on the simplified problem
{(x - 1) * y - z, y, x * y, z}
My code was again the same

eq = a * (x-1) * y - a * z + b * y + c * x * y + d * z
print(solve(eq, a, b, c, d, set=True))  # output: ([a, b, c, d], {((b*y + c*x*y + d*z)/(-x*y + y + z), b, c, d)})

I expected the solution ([a, b, c], {d, d, -d}).
Am I using solve wrongly or is the equation to hard for this solver?

答案1

得分: 4

You are depending on an implicit behaviour of solve that given a single equation not in a list that is linear in all unknowns it will assume that you are looking for an undetermined coefficients solution which is semantically something quite different from an ordinary solution.

这里涉及到您依赖 solve 的一种隐式行为,即对于一个不在列表中的单一方程,只要它在所有未知数上是线性的,solve 会假定您正在寻找一个待定系数的解决方案,这在语义上与普通解决方案有很大不同。

The difference between these can be seen like:

这两者之间的区别可以如下所示:

Here the first case is returning values of a and b that can make the expression identically zero for all possible values of x and y. The second case is treating x and y as being fixed but unspecified parameters and returning the set of possible values for a and b as functions of the symbolic parameters x and y that could make the expression zero.

在这里,第一个情况返回了可以使表达式在所有可能的 xy 值上恒等于零的 ab 的值。而第二种情况将 xy 视为已固定但未指定的参数,并返回 ab 的可能值集合,这些值是符号参数 xy 的函数,可以使表达式为零。

Conceptually these are two very different things and it would be better if solve did not mix them up in a single end-user function. The difference that you see is because your equation is being treated like the second case rather than the first. That being said I cannot reproduce the output you report with the most recent version of SymPy (1.11.1):

从概念上讲,这两者是非常不同的,如果 solve 不在单个最终用户函数中混合它们,那将更好。您看到的差异是因为您的方程被视为第二种情况,而不是第一种情况。话虽如此,我无法在最新版本的 SymPy(1.11.1)中复现您报告的输出:

If I pass eq in a list then I do see it:

如果我将 eq 放在列表中,我会看到它:

In any case it is best not to depend on using solve this way. I suggest to use solve only for its primary purpose which is case 2 above and for that it should always be called with a list (even for a single equation).

无论如何,最好不要依赖于以这种方式使用 solve。我建议仅将 solve 用于其主要目的,即上述的第2种情况,而对于这种情况,它应始终使用列表调用(即使是单个方程也要如此)。

There is instead a function solve_undetermined_coeffs which is the explicit function for doing what you want to do here:

相反,有一个名为 solve_undetermined_coeffs 的函数,它是执行您在此处想要执行的操作的显式函数:

In [9]: solve_undetermined_coeffs(eq, [a, b, c, d], [x, y, z])
Out[9]: {a: d, b: d, c: -d}

https://docs.sympy.org/latest/modules/solvers/solvers.html#sympy.solvers.solvers.solve_undetermined_coeffs

英文:

You are depending on an implicit behaviour of solve that given a single equation not in a list that is linear in all unknowns it will assume that you are looking for an undetermined coefficients solution which is semantically something quite different from an ordinary solution.

The difference between these can be seen like:

In [5]: solve(a*x + b*y, a, b, set=True)
Out[5]: ([a, b], {(0, 0)})

In [6]: solve([a*x + b*y], a, b, set=True)
Out[6]: 
⎛        ⎧⎛-b⋅y    ⎞⎫⎞
⎜[a, b], ⎨⎜─────, b⎟⎬⎟
⎝        ⎩⎝  x     ⎠⎭⎠

Here the first case is returning values of a and b that can make the expression identically zero for all possible values of x and y. The second case is treating x and y as being fixed but unspecified parameters and returning the set of possible values for a and b as functions of the symbolic parameters x and y that could make the expression zero.

Conceptually these are two very different things and it would be better if solve did not mix them up in a single end-user function. The difference that you see is because your equation is being treated like the second case rather than the first. That being said I cannot reproduce the output you report with the most recent version of SymPy (1.11.1):

In [1]: a, b, c, d = symbols('a, b, c, d')

In [2]: eq = a * (x-1) * y - a * z + b * y + c * x * y + d * z
   ...: print(solve(eq, a, b, c, d, set=True))  # output: ([a, b, c, d], {((b*y + c*x*y + d*z)/(-x*y + y 
   ...: + z), b, c, d)})
([a, b, c, d], {(d, d, -d, d)})

If I pass eq in a list then I do see it:

In [7]: solve([eq], a, b, c, d, set=True)
Out[7]: 
⎛              ⎧⎛      b⋅y          c⋅x⋅y          d⋅z             ⎞⎫⎞
⎜[a, b, c, d], ⎨⎜- ─────────── - ─────────── - ───────────, b, c, d⎟⎬⎟
⎝              ⎩⎝  x⋅y - y - z   x⋅y - y - z   x⋅y - y - z         ⎠⎭⎠

In any case it is best not to depend on using solve this way. I suggest to use solve only for its primary purpose which is case 2 above and for that it should always be called with a list (even for a single equation).

There is instead a function solve_undetermined_coeffs which is the explicit function for doing what you want to do here:

In [9]: solve_undetermined_coeffs(eq, [a, b, c, d], [x, y, z])
Out[9]: {a: d, b: d, c: -d}

https://docs.sympy.org/latest/modules/solvers/solvers.html#sympy.solvers.solvers.solve_undetermined_coeffs

huangapple
  • 本文由 发表于 2023年5月10日 16:04:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/76216186.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定