我想在求和中使用次数符号并打印已计算的表达式,但是当我尝试这样做时我会收到错误。
正确的方法是什么?这有可能吗?
我用这种方式创建了一个求和表达式:
>>> 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
时,它给了我" TypeError:无法确定Relational"的真值。
>>> 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'
答案 0 :(得分:2)
似乎SymPy中存在一个错误。我已经开了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。