Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Force SymPy to keep the order of terms

Tags:

python

sympy

I have the following code:

from sympy import *
init_printing()

x,y = symbols('x y')
u = Function('u')(x,y)
ux,uy,uxx,uxy,uyy = symbols("u_x u_y u_xx u_xy u_yy")

mainEvaluation = uxx - 2*sin(x)*uxy - (cos(x) ** 2) * uyy - 2*ux + (2 - cos(x) + 2*sin(x) )*uy

And when the output of print(mainExpression) is

-2*u_x + u_xx - 2*u_xy*sin(x) + u_y*(2*sin(x) - cos(x) + 2) - u_yy*cos(x)**2

The problem is: I want the original order of variables.

u_xx - 2*u_xy*sin(x)  - u_yy*cos(x)**2  - 2*u_x + u_y*(2*sin(x) - cos(x) + 2)

All this is done in IPython notebook. Is there any way to keep order?

like image 785
UpmostScarab Avatar asked Mar 30 '16 15:03

UpmostScarab


2 Answers

For the teaching purpose, I also don't want to simpilify or change the order of terms too early.

I'm using pytexit with jupyter notebook: https://pytexit.readthedocs.io/en/latest/

from pytexit import py2tex

def showeq(str):
    py2tex(str, print_formula=False);

eq1 = "angle = acos((side_A**2 + side_B**2 - side_C**2)/(2*side_A*side_B))"
show(eq1)

side_A = 14.8
side_B = 16.3
side_C = 13.2
exec(eq1)
like image 81
Jeremy Chen Avatar answered Oct 21 '22 18:10

Jeremy Chen


If you know what your arguments/terms are then you can manually create the Add with evaluate=False to keep them in order and print them with a printer initialized to not change the order:

x,y = symbols('x y')
u = Function('u')(x,y)
ux,uy,uxx,uxy,uyy = symbols("u_x u_y u_xx u_xy u_yy")
args = uxx , -2*sin(x)*uxy, -cos(x)**2*uyy, -2*ux, +(2-cos(x)+2*sin(x))*uy

expr = Add(*args, evaluate=False)
from sympy.printing.str import StrPrinter # or LatexPrinter from .latex)
StrPrinter(dict(order='none'))._print_Add(expr)

This outputs

u_xx - 2*u_xy*sin(x) - u_yy*cos(x)**2 - 2*u_x + u_y*(2 - cos(x) + 2*sin(x))
like image 26
smichr Avatar answered Oct 21 '22 19:10

smichr