4

I want to solve quite simple equations with symbolic coefficients:

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)

The equation is -x[0]*a - x[1]*b + x[2]*(-a*b + b*a) - a*b + b*a==0, and the solution is, obviously, x[0]=0, x[1]=0, x[2]=-1, but SymPy returns [(-x[1]*a**(-1)*b + x[2]*a**(-1)*b*a - x[2]*b + a**(-1)*b*a - b, x[1], x[2])].

How do I solve this type of equations?

I could use collect() to get coeffs, extract them, and then solve all the resulting equations. But at the moment collect() doesn't work for non-commutative symbols.

As far as I understand, the problem is that SymPy thinks that a can be equal to a*b (or that they can be related in some other way). How can I tell it that these symbols and products are definitely distinct, linearly independent, and cannot be expressed one by means of another?

homocomputeris
  • 509
  • 5
  • 18
  • First, your proposed solution seems to assume `a` and `b` are commutative. Second, this is almost certainly not what you actually ran, judging by things like `commutative=Falte`. Third, fixing the `Falte` bit, I still get a TypeError when I try to run this. – user2357112 Jun 20 '18 at 19:36
  • Your edit is better, but I still get a TypeError when I try to run this. What SymPy version are you on? – user2357112 Jun 20 '18 at 21:56
  • `master` branch because somewhat working non-commutativity hasn't been released yet. – homocomputeris Jun 20 '18 at 22:03
  • You can get halfway there with `solve([eq1.diff(a), eq1.diff(b)], coefs)` which returns `{x[1]: 0, x[0]: 0}`. I didn't manage the remaining task of solving `-x[2]*a*b + x[2]*b*a - a*b + b*a` for x[2]. It seems the current level of support for noncommutative symbols isn't enough for this. –  Jun 21 '18 at 10:18
  • @user6655984 If seems there is no way to make `a,b` linearly independent: `solve(x[0]*a + x[1]*b, [x[0],x[1]])` won't give you x[0]=x[1]=0 – homocomputeris Jun 21 '18 at 10:46

1 Answers1

0

You can separate the terms of the original expression by free symbols (limited to a and b) and then solve them independently:

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}
smichr
  • 16,948
  • 2
  • 27
  • 34