Reputation: 26485
I'm trying to substitute an IndexedBase inside a summation in sympy. Outside the summation it works, but inside I'm getting back the expression without the substitution:
In [125]: (f, n) = sympy.symbols("f n")
In [126]: foo = sympy.IndexedBase(f)[n]
In [127]: foo.subs(foo, 1)
Out[127]: 1
In [128]: sympy.Sum(foo, (n, 0, 5)).subs(foo, 1)
Out[128]:
5
___
╲
╲ f[n]
╱
╱
‾‾‾
n = 0
Why does the last step not replace f[n]
by 1, and how do I need to change my code to ensure that it does?
Upvotes: 1
Views: 483
Reputation: 1957
It doesn't work because n is a dummy variable and it would change the value of the summation. That is, .subs( ) should give you the same value as when applied to the expanded summation:
In [7]: sympy.Sum(foo, (n, 0, 5)).doit()
Out[7]: f[0] + f[1] + f[2] + f[3] + f[4] + f[5]
In this expression there is no f[n] anymore, as it has been replaced by the respective numerical values. Substitution won't work:
In [8]: sympy.Sum(foo, (n, 0, 5)).doit().subs(foo, 1)
Out[8]: f[0] + f[1] + f[2] + f[3] + f[4] + f[5]
Therefore, .subs() will ignore matches on variables that are summed over (in this case n).
replace( ) on the other hand doesn't care about value consistency and replaces the matching expression anyway:
In [9]: sympy.Sum(foo, (n, 0, 5)).replace(foo, 1)
Out[9]:
5
___
╲
╲ 1
╱
╱
‾‾‾
n = 0
Of course, the resulting value is now different:
In [10]: sympy.Sum(foo, (n, 0, 5)).replace(foo, 1).doit()
Out[10]: 6
Upvotes: 2
Reputation: 26485
It works if you use the replace
method instead:
In [129]: sympy.Sum(foo, (n, 0, 5)).replace(foo, 1)
Out[129]:
5
___
╲
╲ 1
╱
╱
‾‾‾
n = 0
See also this answer.
Upvotes: 0