Я пишу программное обеспечение, которое использует SymPy для символической записи кода, и я столкнулся с умноженными суммами, которые мне нужно упростить.Алгоритм, который я использую, требует использования продукта Коши для преобразования двух сумм, умноженных друг на друга, в двойную сумму.Ниже приведен пример того, что я пытаюсь выполнить:
from sympy import Sum, Function, Symbol, oo
# Define variables
n = Symbol('n')
x = Symbol('x')
t = Symbol('t')
# Define functions
theta = Function('theta')(t)
p = Function('p')(n,x)
q = Function('q')(n,x)
# Create Summations
pSum = Sum(p*theta**n, (n,0,oo))
qSum = Sum(q*theta**n, (n,0,oo))
# Multiply
out = pSum * qSum
print(out)
>>> Sum(p(n, x)*theta(t)**n, (n, 0, oo))*Sum(q(n, x)*theta(t)**n, (n, 0, oo))
Мне нужно преобразовать это в
print(out)
>>> Sum(Sum((p(i, x)*q(n-i, x))*theta**n, (i, 0, n)), (n, 0, oo))
Мой подход при этом заключался в импорте Sum
и определении классакоторый наследуется от Sum
.Затем я определяю оператор __mul__
, чтобы делать то, что я хочу.Это работает для простых случаев, но в более сложных случаях это не будет работать.В этом примере первый случай работает, но следующий не умножается, потому что * не вызывает __mul__
, когда он уже находится в SymPy.
import sympy
from sympy import expand, Function, Symbol, oo, diff, Sum, Derivative
class Sum2(Sum):
# Overriding the __mul__ method.
def __mul__(self, other):
if isinstance(other, Sum2):
i = Symbol('i')
n = Symbol('n')
return Sum2(Sum(self.args[0].subs(n, i)*other.args[0].subs(n, n-i), (i,0,n)), (n,0,oo))
else:
super().__mul__(other)
x = Symbol('x')
t = Symbol('t')
n = Symbol('n')
f = Function('f')(n, x)
a = Sum2(f*t**n, (n,0,oo))
# Works
print(a*a)
# Doesn't work.
c = (Derivative(a,x)*a).doit()
print(c)
print(c.doit())
print(expand(c))
Я пробовал аналогичный подход, наследуявместо Function
.Та же проблема.Возможно, __mul__
не была правильной функцией для переопределения?Как я могу позволить таким образом умножать бесконечные суммы?