2017-04-11 146 views
1

我希望求和中的求和符號並打印求值的表達式,但是當我嘗試這樣做時出現錯誤。用SymPy中的求和表達式中的符號替換

什麼是正確的方法?這可能嗎?

我創建了一個求和表達式是這樣的:

>>> from sympy import * 
>>> from sympy.interactive import printing 
>>> printing.init_printing() 
>>> n = symbols('n', integer=True, positive=True) 
>>> i = Idx('i', (1, n)) 
>>> d = IndexedBase('d') 
>>> s = Sum(d[i], i) 
>>> s 
    n  
___  
╲   
    ╲ d[i] 
    ╱  
╱   
‾‾‾  
i = 1 

當我嘗試分別代替n它給了我「類型錯誤:無法確定關係的真值」。

>>> s.subs(n, 5) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/home/artem/prog/dev/my_slot/env/local/lib/python2.7/site-packages/sympy/core/basic.py", line 902, in subs 
    rv = rv._subs(old, new, **kwargs) 
    File "/home/artem/prog/dev/my_slot/env/local/lib/python2.7/site-packages/sympy/core/cache.py", line 95, in wrapper 
    retval = func(*args, **kwargs) 
    File "/home/artem/prog/dev/my_slot/env/local/lib/python2.7/site-packages/sympy/core/basic.py", line 1014, in _subs 
    rv = self._eval_subs(old, new) 
    File "/home/artem/prog/dev/my_slot/env/local/lib/python2.7/site-packages/sympy/concrete/expr_with_limits.py", line 341, in _eval_subs 
    return self.func(func, *limits) 
    File "/home/artem/prog/dev/my_slot/env/local/lib/python2.7/site-packages/sympy/concrete/summations.py", line 155, in __new__ 
    obj = AddWithLimits.__new__(cls, function, *symbols, **assumptions) 
    File "/home/artem/prog/dev/my_slot/env/local/lib/python2.7/site-packages/sympy/concrete/expr_with_limits.py", line 368, in __new__ 
    limits, orientation = _process_limits(*symbols) 
    File "/home/artem/prog/dev/my_slot/env/local/lib/python2.7/site-packages/sympy/concrete/expr_with_limits.py", line 59, in _process_limits 
    if V[0].upper is not None and not bool(nlim[1] <= V[0].upper): 
    File "/home/artem/prog/dev/my_slot/env/local/lib/python2.7/site-packages/sympy/core/relational.py", line 195, in __nonzero__ 
    raise TypeError("cannot determine truth value of Relational") 
TypeError: cannot determine truth value of Relational 

當我嘗試替換d時,它會產生另一個錯誤。

>>> i = Idx('i', (1, 5)) 
>>> s = Sum(d[i], i)      
>>> s 
    5  
___  
╲   
    ╲ d[i] 
    ╱  
╱   
‾‾‾  
i = 1 
>>> s.subs(d, range(1, 6)) 
    5      
___      
╲      
    ╲ [1, 2, 3, 4, 5][i] 
    ╱      
╱      
‾‾‾      
i = 1 
>>> s.subs(d, range(1, 6)).doit() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/home/artem/prog/dev/my_slot/env/local/lib/python2.7/site-packages/sympy/concrete/summations.py", line 189, in doit 
    newf = eval_sum(f, (i, a, b)) 
    File "/home/artem/prog/dev/my_slot/env/local/lib/python2.7/site-packages/sympy/concrete/summations.py", line 824, in eval_sum 
    if i not in f.free_symbols: 
    File "/home/artem/prog/dev/my_slot/env/local/lib/python2.7/site-packages/sympy/core/basic.py", line 494, in free_symbols 
    return set().union(*[a.free_symbols for a in self.args]) 
AttributeError: 'list' object has no attribute 'free_symbols' 

回答

2

看來SymPy中有一個bug。我爲此打開了an issue

一種解決方法是,以指定的限度的Sum代替Idx

>>> i = Idx('i') 
>>> s = Sum(d[i], (i, 1, n)) 
>>> s.subs(n, 5) 
Sum(d[i], (i, 1, 5)) 
>>> s.subs(n, 5).doit() 
d[1] + d[2] + d[3] + d[4] + d[5] 

代入IndexedBase爲列表是另一個issue。這裏是一個解決辦法,使這項工作:

>>> l = range(6) 
>>> s.subs(n, 5).doit().replace(Indexed, lambda i, j: Indexed(i, j) if i != d else l[j]) 
15 
>>> 

注意,因爲它使用的範圍從1索引你原來是不行的,但是Python使用基於0的索引,所以您可能需要增加範圍,如我一樣,或修改您的總和從0到n - 1。

+0

非常感謝。有沒有一種解決方法來替代'IndexedBase'列表? – raacer

+0

@raacer看我的編輯。 – asmeurer

相關問題