Avoid sorting args in Python module Sympy
Asked Answered
A

1

3

I am currently developing a differential operator for sympy that can be placed in matricial form. In this case the order of the args list when creating a Mul object is very important to guarantee that the differentiation is performed where it is required only.

The issue is that, when the following is done:

input = (t,z,x)
Mul(*input).args

It returns (t, x, z) because some rearrangement in args took place. How to avoid args to be sorted?

Amok answered 26/4, 2013 at 15:30 Comment(2)
in the real case the differential operator is applied such that r*D(z)*z will return a Mulobject, but currently it returns in the following order (r, z, D(z)), which makes it difficult to apply the operator correctly. See here for more details.Amok
This is very similar to https://mcmap.net/q/49770/-prevent-sympy-from-rearranging-the-equation/161801Abstemious
A
3

Why is the arg ordering important for it to be correct?

The only way to prevent this is to set your symbols to be non-commutative (x = Symbol('x', commutative=False)). SymPy objects compare by comparing the args, so for x*y*z == y*x*z to work, the args have to be sorted canonically. There have been some attempts to get this working without explicit sorting (mainly for performance reasons), but note that even if we did that, there would be no guarantee at all about the arg order, especially if you perform any kind of operation on the expression. It is very common for functions to rebuild expressions in SymPy, which would in general use some other unrelated order from the original.

Abstemious answered 26/4, 2013 at 22:12 Comment(4)
The args order is important to avoid Mul(*(r,D(z),z), which is to be evaluated later, to become r*z*D(z), because in the latter the differential operator D(z) will not be applied properly.Amok
I see. This is the fundamental issue I was referring to at https://mcmap.net/q/49131/-differential-operator-usable-in-matrix-form-in-python-module-sympy (first paragraph). Right now, there is no way to control what happens inside of Mul regarding custom multiplication rules. The best you can get is your operator doing the right thing when multiplied with *, and to write a custom function that "finishes the job" on multiplications applied otherwise. Given the associativity issue I noted in that same answer, you will probably need to just use the latter solution.Abstemious
That's it! I used sympy.var('t, x, z', commutative=False) to do the x = Symbol('x', commutative=False) for everybody and now args is not being rearranged! Thank you!Amok
What does Sage/Pynac do different?Floatstone

© 2022 - 2024 — McMap. All rights reserved.