如何在Sympy Sum中为Python列表编制索引



我想使用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求和进行计算。

最新更新