我在Sympy中有一个索引符号x
,表达式是x[1]*x[2] + x[3]**2 + x[4]*x[1]
等二度单项式的总和。我想将这样的表达式转换为x[1,2] + x[3,3] + x[4,1]
,即替换x[i]*x[j] -> x[i,j]
可能出现的索引有一个上限,所以我可以构造一个对每个替换进行硬编码的大表。还有更好的方法吗?
回应评论 - 创建x我写
from sympy.tensor import IndexedBase
x = IndexedBase('x')
答案 0 :(得分:1)
您可以将replace
与Wild
一起使用。
In [1]: i, j = symbols('i j', cls=Wild)
In [2]: x = IndexedBase('x')
In [3]: e = x[1]*x[3] + x[2]*x[1]
In [4]: e.replace(x[i]*x[j], x[i, j])
Out[4]: x[1, 2] + x[1, 3]
答案 1 :(得分:1)
您可以使用ordered来按顺序放置索引:
>>> from sympy import *
>>> i, j = symbols('i j', cls=Wild)
>>> x = IndexedBase('x')
>>> e = x[1]*x[3] + x[2]*x[1] + x[3]**2
>>> def new(o, x):
... if o.is_Mul:
... i,j=list(ordered([i.args[1] for i in o.args]))
... elif o.is_Pow:
... i = j = o.base.args[1]
... else:
... raise NotImplementedError
... return x[i, j]
...
>>> e.xreplace(dict([(o, new(o, x)) for o in e.find(x[i]*x[j])]))
x[1, 2] + x[1, 3] + x[3, 3]
但更简单的方法是在替换调用中使用Piecewise结果:
>>> e.replace(x[i]*x[j], Piecewise((x[i,j],i<j),(x[j,i],True)))
x[1, 2] + x[1, 3] + x[3, 3]