如何在SymPy中解决具有符号系数和非交换变量的方程?

4

我希望能够使用符号系数解决相当简单的方程:

from sympy import *

a, b = symbols('a b', commutative=False)
x = IndexedBase('x')
basis = [a, b, a * b - b * a]
el = b * a - a * b
coefs = [x[k] for k in range(len(basis))]
eq = el - sum([c * bel for c, bel in zip(coefs, basis)])
solve(eq.expand(), coefs)

方程为-x[0]*a - x[1]*b + x[2]*(-a*b + b*a) - a*b + b*a==0,解显然是x[0]=0, x[1]=0, x[2]=-1,但SymPy返回[(-x[1]*a**(-1)*b + x[2]*a**(-1)*b*a - x[2]*b + a**(-1)*b*a - b, x[1], x[2])]。如何解决这种类型的方程?我可以使用collect()来获取系数,提取它们,然后解决所有的结果方程。但目前collect()不适用于非交换符号。据我所知,问题在于SymPy认为a可以等于a*b(或者它们可以以某种其他方式相关)。我该如何告诉它这些符号和乘积肯定是不同的、线性独立的,并且不能通过一种手段表达另一种手段?

首先,你提出的解决方案似乎假定ab是可交换的。其次,根据commutative=Falte等因素判断,这几乎肯定不是你实际运行的内容。第三,即使我修复了Falte的问题,当我尝试运行它时仍然会出现TypeError错误。 - user2357112
你的修改更好了,但是当我尝试运行它时仍然出现TypeError。你使用的SymPy版本是多少? - user2357112
“master” 分支,因为某种程度上的非可交换性尚未发布而已经有些工作了。 - homocomputeris
你可以使用solve([eq1.diff(a), eq1.diff(b)], coefs)来解决一半的问题,它会返回{x[1]: 0, x[0]: 0}。但我无法解决剩下的任务,即求解-x[2]*a*b + x[2]*b*a - a*b + b*a中的x[2]。目前对于非交换符号的支持似乎还不够。 - user6655984
如果似乎没有办法使a,b线性无关:solve(x[0]*a + x[1]*b, [x[0],x[1]])将不会给出x[0]=x[1]=0。 - homocomputeris
1个回答

0

您可以通过自由符号(仅限于ab)将原始表达式的项分开,然后独立解决它们:

from sympy import ordered
byfree = sift(eq.args, lambda x: tuple(ordered(x.free_symbols&{a,b})))
solve([Add(*v) for v in byfree.values()], coefs)
{x[2]: -1, x[0]: 0, x[1]: 0}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接