Sympy;对索引变量进行求和和积分。

时间:2018-10-02 09:51:35

标签: python-3.x sympy

我尝试重新创建的练习是这些lattice notes中的第一个练习。 question part 1 question part 2

我正在与python3一起尝试此操作。我的尝试是这样;

import sympy
from sympy.abc import a, m
from sympy import IndexedBase, Idx, oo, symbols
# from ipdb import set_trace as st

integrated_path = sympy.Symbol('I')

def V(sym_a, sym_x):
    return (sym_x**2)/sym_a

N, j, j_primed = symbols('N j, j_primed', integer=True)
x = IndexedBase('x')
j_idx = Idx(j)
S = sympy.summation(((m/(2*a)) * (x[j_idx+1] - x[j_idx]**2) + a*V(a, x[j_idx])),
                    (j_idx, 0, N-1))
print("The action ", S)

integrand = sympy.exp(-S)
j_primed_idx = Idx(j_primed, (0, N))
integrated_path = sympy.integrate(integrand, (x[j_primed_idx], -oo, oo))
print("The integrated path is ", integrated_path)

subbed_path = integrated_path.subs({a: 0.5, N: 8, m: 1})
print("The subbed path is ", subbed_path)

但是,集成并未将x[j+1]识别为x[j]之一,因此它没有在其上进行集成。我得到的输出是;

The action  Sum(x[j]**2 + m*(x[j + 1] - x[j]**2)/(2*a), (j, 0, N - 1))
The integrated path is  oo*sign(exp(-Sum(x[j]**2, (j, 0, N - 1)) - m*Sum(x[j + 1], (j, 0, N - 1))/(2*a) + m*Sum(x[j]**2, (j, 0, N - 1))/(2*a)))
The subbed path is  oo*sign(exp(-1.0*Sum(x[j + 1], (j, 0, 7))))

所有x值都应该已经集成,但是其中一个仍然存在。所以我认为我使用的索引变量不正确。缺少硬编码N的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

SymPy对索引对象的处理还不够复杂,无法像人类那样处理此计算。特别是,它不会理解集成  (x[j_primed_idx], -oo, oo)上为“对所有索引x进行积分”。这看起来像是对SymPy的单个集成,并且覆盖了与任何x[j]不同的变量,因为索引看起来并不相同。简而言之,SymPy并不真正理解索引在数学中的工作方式。

您需要预先声明N的值才能完成所有操作。要修正(x[j_idx+1] - x[j_idx]**2)中的错字-应该是(x[j_idx+1] - x[j_idx])**2。而且,如果N很大并且am是符号,那将永远是永远的。问题在于,有一些案例基于am的相对大小。这是N, a, m都已预先指定的工作版本-这对集成商有很大帮助 。请注意,顺便使用Rational(1, 2)而不是浮点数0.5-这对SymPy很重要。

import sympy
from sympy import oo, symbols
N = 8
a = sympy.Rational(1, 2)
m = 1

def V(sym_a, sym_x):
    return (sym_x**2)/sym_a

x = symbols('x0:{}'.format(N))
S = sympy.Add(*[((m/(2*a)) * (x[j_idx+1] - x[j_idx])**2 + a*V(a, x[j_idx])) for j_idx in range(N-1)])
print("The action ", S)

integrand = sympy.exp(-S)
integrated_path = sympy.integrate(integrand, *[(x[j_primed_idx], -oo, oo) for j_primed_idx in range(N)], conds='none')
print("The integrated and subbed path is ", integrated_path)

输出:

The action  x0**2 + x1**2 + x2**2 + x3**2 + x4**2 + x5**2 + x6**2 + (-x0 + x1)**2 + (-x1 + x2)**2 + (-x2 + x3)**2 + (-x3 + x4)**2 + (-x4 + x5)**2 + (-x5 + x6)**2 + (-x6 + x7)**2
The integrated and subbed path is  sqrt(377)*pi**4/377

这就是我可以用符号a和m推多远的距离:N = 2。

import sympy
from sympy import IndexedBase, Idx, oo, symbols
a, m = symbols('a m', positive=True)
N = 2

def V(sym_a, sym_x):
    return (sym_x**2)/sym_a

j, j_primed = symbols('j, j_primed', integer=True)
x = symbols('x0:{}'.format(N))
S = sympy.Add(*[((m/(2*a)) * (x[j_idx+1] - x[j_idx])**2 + a*V(a, x[j_idx])) for j_idx in range(N-1)])
print("The action ", S)

integrand = sympy.exp(-S)
integrated_path = sympy.integrate(integrand, *[(x[j_primed_idx], -oo, oo) for j_primed_idx in range(N)], conds='none')
print("The integrated path is ", integrated_path)

subbed_path = integrated_path.subs({a: sympy.Rational(1, 2), m: 1})
print("The subbed path is ", subbed_path)

输出:

The action  x0**2 + m*(-x0 + x1)**2/(2*a)
The integrated path is  -I*pi*sqrt(a)*sqrt(4*a**2 + 2*a*m)*Piecewise((I/sqrt(-1 + (4*a**2 + 2*a*m)/(2*a*m)), (4*a**2 + 2*a*m)/(2*a*m) > 1), (1/sqrt(1 - (4*a**2 + 2*a*m)/(2*a*m)), True))/(m*sqrt(a + m/2))
The subbed path is  pi