我有以下几个问题:
我正在尝试使用曲柄nicolson离散化解决一维Schrodinger方程,然后求反三对角矩阵。我的问题现在演变为周期性边界条件的问题,因此我修改了代码以使用Sherman Morrison算法。
假设v
当我希望反转三对角矩阵时,在每个时间步中都存在我的RHS。的大小v
是我在空间上拥有的网格点的数量。当我设定v[0]
并v[-1]
按照我的周期性情况的要求互相称呼时,我的方程式崩溃了。我不知道为什么会这样。我正在使用python2.7和scipy的内置solve_banded来求解方程。
这引出了我的第二个问题:我使用python是因为它是我最了解的语言,但是我发现它运行起来很慢(即使使用numpy和scipy提供的优化)。我已经尝试使用C ++,因为我对此相当熟悉。我以为我会使用经过BLAS优化的GSL,但没有找到任何文档来创建复杂向量或使用此类复杂值向量求解三对角矩阵。
我希望在程序中使用对象,因为我觉得这是以后进行泛化以包含波动函数之间的耦合的最简单方法,因此我坚持使用面向对象的语言。
我可以尝试手动编写三对角矩阵求解器,但是在python中编写时遇到了问题。随着时间的推移,随着时间的推移,我逐渐发展,错误不断累积,使我无聊。考虑到这一点,我决定使用内置方法。
任何建议深表感谢。
编辑:这是相关的代码段。该符号是从Wikipedia的页面上引用的三对角矩阵(TDM)公式。v是每个时间步长的crank nicolson算法的RHS。向量a,b和c是TDM的对角线。定期案例的校正算法来自CFD Wiki。我做了一些重命名。他们所说的u,v我称之为U,V(大写)。我称q为补数,y为临时解,而实际解为self.currentState。v [0]和v [-1]的分配是引起问题的原因,因此已被注释掉。您可能会忽略伽玛系数。它们是用于建模Bose Einstein冷凝物的非线性因子。
for T in np.arange(self.timeArraySize):
for i in np.arange(0,self.spaceArraySize-1):
v[i] = Y*self.currentState[i+1] + (1-2*Y)*self.currentState[i] + Y*self.currentState[i-1] - 1j*0.5*self.timeStep*potential[i]*self.currentState[i] - self.gamma*1j*0.5*self.timeStep*(abs(self.currentState[i])**2)*self.currentState[i]
b[i] = 1+2*Y + 1j*0.5*self.timeStep*potential[i] + self.gamma*self.timeStep*1j*0.5*(abs(self.currentState[i])**2)
#v[0] = Y*self.currentState[1] + (1-2*Y)*self.currentState[0] + Y*self.currentState[-1] - 1j*0.5*self.timeStep*potential[0]*self.currentState[0]# - self.gamma*1j*0.5*self.timeStep*(abs(self.currentState[0])**2)*self.currentState[0]
#v[-1] = Y*self.currentState[0] + (1-2*Y)*self.currentState[-1] + Y*self.currentState[-2] - 1j*0.5*self.timeStep*potential[-1]*self.currentState[-1]# - self.gamma*1j*0.5*self.timeStep*(abs(self.currentState[-1])**2)*self.currentState[-1]
b[0] = 1+2*Y + 1j*0.5*self.timeStep*potential[0] + self.gamma*self.timeStep*1j*0.5*(abs(self.currentState[0])**2)
b[-1] = 1+2*Y + 1j*0.5*self.timeStep*potential[-1] + self.gamma*self.timeStep*1j*0.5*(abs(self.currentState[-1])**2)
diagCorrection[0], diagCorrection[-1] = - b[0], - c[-1]*a[0]/b[0]
tridiag = np.matrix([
c,
b - diagCorrection,
a,
])
temp = solve_banded((1,1), tridiag, v)
U = np.zeros(self.spaceArraySize, dtype=np.complex64)
U[0], U[-1] = -b[0], c[-1]
V = np.zeros(self.spaceArraySize, dtype=np.complex64)
V[0], V[-1] = 1, -a[0]/b[0]
complement = solve_banded((1,1), tridiag, U)
num = np.dot(V, temp)
den = 1 + np.dot(V, complement)
self.currentState = temp - (num/den)*complement