强制 SymPy 保持术语的顺序

Force SymPy to keep the order of terms

我有以下代码:

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

而当print(mainExpression)的输出为

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

问题是:我想要变量的原始顺序。

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

所有这些都在 IPython 笔记本中完成。 有什么办法可以维持秩序吗?

尝试阅读这篇文章http://docs.sympy.org/0.7.2/modules/utilities/misc.html,也许会对您有所帮助

注:

返回的密钥对于将项目放入跨平台相同的规范顺序很有用。它不能直接用于对表达式列表进行排序:

>>> a, b = x, 1/x

因为 a 只有 1 个项,它的值 sort_key 不受顺序影响:

>>> a.sort_key() == a.sort_key('rev-lex')
True

如果 ab 组合在一起,那么密钥将不同,因为有可以订购的条款:

>>> eq = a + b
>>> eq.sort_key() == eq.sort_key('rev-lex')
False
>>> eq.as_ordered_terms()
[x, 1/x]
>>> eq.as_ordered_terms('rev-lex')
[1/x, x]

但是由于这些术语中的每一个的键都独立于 order 的值,因此当它们单独出现在列表中时,它们的排序不会不同:

>>> sorted(eq.args, key=default_sort_key)
[1/x, x]
>>> sorted(eq.args, key=lambda i: default_sort_key(i, order='rev-lex'))
[1/x, x]

使用这些键时获得的项的顺序是如果这些项是产品中的因素将获得的顺序。

遗憾的是,SymPy 不跟踪输入顺序(请参阅我在对该问题的评论中链接的其他问题)。您可以定义自己的排序函数,按照您想要的方式对表达式进行排序,但无法完全按照输入的方式排序,因为该信息未保存。

如果您知道您的 arguments/terms 是什么,那么您可以使用 evaluate=False 手动创建添加以保持它们的顺序并使用初始化为不更改顺序的打印机打印它们:

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)

这输出

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

出于教学目的,我也不想过早地简化或改变术语的顺序。

我在 jupyter 笔记本上使用 pytexit: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)