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?

推荐答案

你依赖于solve的隐含行为,即给定一个方程,而不是在所有未知数中都是线性的列表中,它将假设你正在寻找一个在语义上与普通解完全不同的待定系数解.

它们之间的区别如下所示:

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     ⎠⎭⎠

在这里,第一种情况返回值ab,这可以使表达式对于所有可能的值xy相同地为零.第二种情况是将xy视为固定但未指定的参数,并将ab的可能值集作为符号参数xy的函数返回,从而可以使表达式为零.

从概念上讲,这是两件非常不同的事情,如果Solve没有在单个最终用户函数中将它们混为一谈就更好了.你看到的不同之处在于,你的方程式被视为第二种情况,而不是第一种情况.也就是说,我不能用最新版本的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)})

如果我在列表中超过eq,那么我确实看到了它:

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         ⎠⎭⎠

在任何情况下,最好不要以这种方式使用solve.我建议仅将solve用于其主要目的,即上面的情况2,为此,应始终使用列表来调用它(即使对于单个方程).

取而代之的是函数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

Python相关问答推荐

即使在可见的情况下也不相互作用

我从带有langchain的mongoDB中的vector serch获得一个空数组

如何过滤包含2个指定子字符串的收件箱列名?

Python+线程\TrocessPoolExecutor

什么是最好的方法来切割一个相框到一个面具的第一个实例?

如何在turtle中不使用write()来绘制填充字母(例如OEG)

如何更新pandas DataFrame上列标题的de值?

未调用自定义JSON编码器

剪切间隔以添加特定日期

用SymPy在Python中求解指数函数

将一个双框爆炸到另一个双框的范围内

根据Pandas中带条件的两个列的值创建新列

如何为需要初始化的具体类实现依赖反转和接口分离?

如何在Django模板中显示串行化器错误

如何根据一定条件生成段id

有了Gekko,可以创建子模型或将模型合并在一起吗?

将相应的值从第2列合并到第1列(Pandas )

如何将列表从a迭代到z-以抓取数据并将其转换为DataFrame?

对当前的鼹鼠进行编码,并且我的按键获得了注册

如何使用Polars从AWS S3读取镶木地板文件