Reputation: 43
I try to use IndexBase for summation, but dont understand, how to do substitution of sequences:
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]
The only case which works is substitution of range
. Could you explain, how to substitude it in general case?
Upvotes: 4
Views: 1678
Reputation:
Usually one substitutes for Indexed objects A[i]
rather than for IndexedBase A
. This works if the sum is written out explicitly by doit
prior to substitution.
S.subs(N, 2).doit().subs([(A[i], i**2) for i in range(3)]) # 5
or
values = [8, 16, 32]
S.subs(N, 2).doit().subs([(A[i], values[i]) for i in range(3)]) # 56
Similarly, Trace.subs(N, 2).doit().subs([(A[i, i], values[i]) for i in range(3)])
returns 56.
The substitution by Python range works because it's sympified by subs
into SymPy's Range
object, which is something that can be a part of a SymPy expression.
>>> S.subs([(A, range(3)), (N, 2)])
Sum(Range(0, 3, 1)[i], (i, 0, 2))
It looks like one should be able to similarly substitute with SymPy's SeqFormula
objects:
>>> 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))
But subsequent doit
fails here with SympifyError: None
which looks like a bug.
Upvotes: 3