我想使用Sympy:在Python中计算以下和(代码的最后一行(
# Theta Functions, n = 0, 1, ... , x
theta_n = [0]*(x+1)
sig = sy.symbols('sigma^2', real=True)
j = sy.symbols('j', integer=True)
theta_n[0] = 1
theta_n[1] = 1
for n in range(2,x+1):
theta_n[n] = sy.Sum( sig**j * theta_n[n-2*j], (j,1,int(n/2))).doit()
但是我得到以下错误
类型错误:列表索引必须是整数或切片,而不是添加
我是一个完全的Sympy新手,想知道如何以正确的方式做到这一点。一种解决方法是使用for循环来计算和,这很好,但我认为这不是正确的方法。也许我需要一个其他的表示形式来表示,或者我可以以某种方式将j转换为和中的整数,以访问python列表的元素。
不要使用Sum,而是在j
上使用循环
for j in range(1, n//2 + 1):
theta_n[n] += theta_n[n-2*j]*sig**j
这两行将您的单行替换为Sum。
一旦你看到了你得到的结果,你可能会注意到这个模式,并将第n个术语重写为
>>> theta_n = lambda x: 2**max(0, x//2-1)*sig**(x//2)
>>> theta_n(100)
562949953421312*sigma^2**50
主要问题是试图使用符号(j
(对列表进行索引。列表索引仅适用于Python整数。在您的情况下,可以将j
用于普通Python整数,并使用常规Pythonsum
。这个正则和将首先转换为加法,然后在需要时转换为症状Add
。请注意,Python range命令需要比上一个索引高一个数字。
import sympy as sy
x = 12
theta_n = [0]*(x+1)
sig = sy.symbols('sigma^2', real=True)
theta_n[0] = 1
theta_n[1] = 1
for n in range(2, x+1):
theta_n[n] = sum(sig ** j * theta_n[n - 2 * j] for j in range(1, n//2+1) )
请注意,在sympy表达式中,sy.Sum( sig**j * theta_n[n-2*j], (j,1,int(n/2)))
、j
是一个完整的符号变量,而j
并不是像Python迭代那样一个接一个地获取所有值。
例如:
print(sy.Sum(j*j, (j, 1, 1_000_000_000)).doit())
Sympy通过将表达式转换为n**3/3 + n**2/2 + n/6
,立即给出正确的结果(333333333833333333500000000
(。这将需要很长时间才能使用常规Python求和进行计算。