gerrit
gerrit

Reputation: 26485

Substitution of IndexedBase inside a summation

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

Answers (2)

Francesco Bonazzi
Francesco Bonazzi

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

gerrit
gerrit

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

Related Questions