我尝试使用SymPy solve
来解决许多不同输入值的等式。到目前为止,这是我的代码:
E = np.linspace(Emin,Emax,((Emax-Emin)/Emesh)+1)
z1 = np.zeros(len(E))+0j
for i in xrange(len(E)):
z = Symbol('z')
z1[i] = solve( (d - E[i])/s - z - 1/z, z)
此处d
和s
是常量,E
是一维数组。代码工作正常,但速度很慢。由于E[i]
变化缓慢,z1[i]
几乎等于z1[i+1]
。我不是每次都为每个新的E[i]
从头开始解决方程式,而是希望使用结果z1[i]
作为求解z1[i+1]
的起点。另一种选择是根据z[i+1]
的值对z[i]
的允许值进行限制。基本上我希望尽可能加快这一部分的速度。
有什么建议吗?
答案 0 :(得分:2)
如果你看看你的等式,
(d - e) / s - z - 1/z == 0
乘以-z
。
z**2 + ((e - d) / 2) * z + 1 == 0
现在它是我们可以轻松解决的二次方,
b = (e - d) / s
z = (-b +/- (b*b - 4)**0.5) / 2
和numpy代码可以做到这一点,
import numpy as np
# some made-up numbers
e_min = 1.9
e_max = 2.6
e_mesh = 0.05
d = 2.1
s = 0.45
es = np.arange(e_min, e_max, e_mesh, dtype=np.complex)
bs = (es - d) / s
rts = np.sqrt(bs * bs - 4)
z1 = (-bs + rts) / 2
z2 = (-bs - rts) / 2
,当运行时,产生
z1
Out[118]:
array([ 0.22222222-0.97499604j, 0.16666667-0.9860133j ,
0.11111111-0.99380799j, 0.05555556-0.9984556j ,
0.00000000+1.j , -0.05555556+0.9984556j ,
-0.11111111+0.99380799j, -0.16666667+0.9860133j ,
-0.22222222+0.97499604j, -0.27777778+0.96064536j,
-0.33333333+0.94280904j, -0.38888889+0.92128466j,
-0.44444444+0.89580642j, -0.50000000+0.8660254j ,
-0.55555556+0.83147942j])
z2
Out[119]:
array([ 0.22222222+0.97499604j, 0.16666667+0.9860133j ,
0.11111111+0.99380799j, 0.05555556+0.9984556j ,
-0.00000000-1.j , -0.05555556-0.9984556j ,
-0.11111111-0.99380799j, -0.16666667-0.9860133j ,
-0.22222222-0.97499604j, -0.27777778-0.96064536j,
-0.33333333-0.94280904j, -0.38888889-0.92128466j,
-0.44444444-0.89580642j, -0.50000000-0.8660254j ,
-0.55555556-0.83147942j])
答案 1 :(得分:0)
在这种情况下,您甚至可能不需要使用求解! 你想要做的只是解决方程:
(d - E[i])/s - z - 1/z=0
表示z。在我们的朋友WolframAlpha的帮助下,我们得到:
z=-(-d+E[i]+sqrt(d**2-2*d*E[i]+E[i]**2-4*s**2))/(2*s)
和
z=(d-E[i]+sqrt(d**2-2*d*E[i]+E[i]**2-4*s**2))/(2*s)
我不确定您的域名,因此您可以选择其中一个或两个。
供参考,完整的功能:
E = np.linspace(Emin,Emax,((Emax-Emin)/Emesh)+1)
z1 = np.zeros(len(E))+0j
for i in xrange(len(E)):
z1[i] = z #Replace z with one/both of the expressions above