用x [i,j]代替x [i] * x [j]的Sympy替换

时间:2014-12-04 19:50:04

标签: sympy

我在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')

2 个答案:

答案 0 :(得分:1)

您可以将replaceWild一起使用。

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]