我尝试使用IndexBase进行求和,但不了解如何进行序列替换:
A = sympy.IndexedBase('A')
i = sympy.Symbol('i', integer=True)
N = sympy.Symbol('N', integer=True)
S = sympy.Sum(A[i], (i, 0, N))
Trace = sympy.Sum(A[i, i], (i, 0, N))
S.subs([(A, range(3)), (N, 2)]).doit() # python3 range
# result: 3
S.subs([(A, [8, 16, 32]), (N, 2)]).doit()
# result: A[0] + A[1] + A[2]
S.subs([(A, numpy.arange(3)), (N, 2)]).doit()
# result: A[0] + A[1] + A[2]
Trace.subs([(A, numpy.diag([2, 4, 8])), (N, 2)]).doit()
# result: A[0, 0] + A[1, 1] + A[2, 2]
唯一可行的情况是替换range
。您能解释一下,在一般情况下如何将其归位吗?
答案 0 :(得分:0)
通常,一个代替索引对象A[i]
而不是IndexedBase A
。如果在替换之前用doit
明确写出了总和,这将起作用。
S.subs(N, 2).doit().subs([(A[i], i**2) for i in range(3)]) # 5
或
values = [8, 16, 32]
S.subs(N, 2).doit().subs([(A[i], values[i]) for i in range(3)]) # 56
类似地,Trace.subs(N, 2).doit().subs([(A[i, i], values[i]) for i in range(3)])
返回56。
使用Python范围进行替换是有效的,因为它由subs
表示为SymPy的Range
对象,该对象可以是SymPy表达式的一部分。
>>> S.subs([(A, range(3)), (N, 2)])
Sum(Range(0, 3, 1)[i], (i, 0, 2))
看起来应该可以用SymPy的SeqFormula
对象类似地替代:
>>> n = sympy.symbols('n')
>>> S.subs([(A, sympy.sequence(n**2, (n, 0, 3))), (N, 3)])
Sum(SeqFormula(n**2, (n, 0, 3))[i], (i, 0, 3))
但是随后的doit
在这里失败,并带有SympifyError: None
,看起来像个错误。