Make all symbols commutative in a sympy expression
Asked Answered
S

2

2

Say you have a number of non commutative symbols within a sympy expression, something like

a, c = sympy.symbols('a c', commutative=False)
b = sympy.Symbol('b')
expr = a * c + b * c

What is the preferred way to make all symbols in the expression commutative, so that, for example, sympy.simplify(allcommutative(expr)) = c * (a + b)?

In this answer it is stated that there is no way to change the commutativity of a symbol after creation without replacing a symbol, but maybe there is an easy way to change in blocks all symbols of an expression like this?

Saucer answered 16/1, 2018 at 23:2 Comment(2)
Why were they created as noncommutative if they're supposed to be commutative?Esperanzaespial
@Esperanzaespial legit question of course. My reason is that I want to force a specific ordering in the printed expression, and setting the symbols as non commutative was the easiest way I found to achieve that.Saucer
E
5

If you want Eq(expr, c * (a + b)) to evaluate to True, you'll need to replace symbols by other symbols that commute. For example:

replacements = {s: sympy.Dummy(s.name) for s in expr.free_symbols}
sympy.Eq(expr, c * (a + b)).xreplace(replacements).simplify()

This returns True.

Eck answered 16/1, 2018 at 23:32 Comment(4)
this is the kind of this I was thinking of, yes. I guess there is no better way then. ThanksSaucer
@Saucer Yeah, I wish I could make x commutative by saying x.is_commutative=True, but I get AttributeError: can't set attribute.Siskind
Why doesn't calling a, c = sympy.symbols('a c', commutative=False) later work? It seems expressions involving those symbols are set in stone (as subs doesn't work on them).Siskind
@Siskind Sympy objects are immutable. Check out the "common pitfalls" section of the docs.Eck
D
3

Two comments:

  1. noncommutatives will factor (though they respect the side that the nc expr appears on)
  2. although you have a robust answer, a simple answer that will often be good enough is to just sympify the string version of the expression

Both are shown below:

>>> import sympy
>>> a, c = sympy.symbols('a c', commutative=False)
>>> b = sympy.Symbol('b')
>>> expr = a * c + b * c
>>> factor(expr)
(b + a)*c
>>> S(str(_))
c*(a + b)
Dramatics answered 18/1, 2018 at 4:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.