我遇到了一个问题,我在下面进行了简化。
所以,我有一个函数(矩阵),它返回矩阵的特征值。
第二个函数(deriv)找到相对于delta的特征值的导数。 SciPy自己的派生函数非常慢,所以我使用了复杂的差分方法。
然后我把积分的二重积分放在r和theta上。我不是采用双积分,而是在对θ进行一维积分后求解r的微分方程,这使得计算更快。
最后,整体工作。但是,如果我试图找到满足等式的特定delta,它会给出一个错误:无法将complex转换为float,我不明白虚数来自何处。
我是Python世界的新手,任何帮助都会非常感激。谢谢。
from scipy.integrate import quad
from numpy import linalg as LA
import numpy as np
from pylab import *
from scipy.integrate import odeint
from scipy.integrate import ode
from scipy.optimize import fsolve
#This routine is for the matrix and returns the eigenvalues
def matrix(r, theta, delta1, delta2):
mat = np.array([[r**2-1,r*np.cos(theta),0,delta1],r*np.cos(theta),r**2 - 1, -delta1,0],[0,-delta2,-r**2+1,-r*np.cos(theta)],[delta2,0,-r*np.cos(theta),-r**2+1]])
return np.sort(LA.eigvals(mat))[2:4]
#This routine takes the derivatives of eigenvalues with respect to the parameter delta. I set delta1 = delta2.
def deriv(r, theta, delta):
h = 0.00000000001
return np.imag(matrix(r, theta, delta, delta+h*1j))/h
#This is the integrand that we need to integrate over r and theta
def integrand(theta,r, beta, delta):
ee = matrix(r, theta, delta, delta)
dd = deriv(r, theta, delta)
return (np.tanh(0.5*beta*ee[0])*dd[0]+np.tanh(0.5*beta*ee[1])*dd[1])*r*r*np.sin(theta)
#Just integrate over theta
def polarint(y,r,beta,delta):
return quad(integrand,0,np.pi,args = (r,beta,delta))[0]
#Instead of integrating directly over r, solve the differential equation.
#Lambda is the range of r.
def givesclen(delta, beta, lam):
y0 = 0
t_out = np.linspace(0, lam, 2500);
rt = odeint(polarint,y0,t_out,args=(beta,delta))
temp = (rt[-1]/delta)/(4*np.pi**2)-t_out[-1]/(2*np.pi**2)
return temp[0]
#The goal is to find the delta; given sl, lam, beta
#Such that the result of the integration is equal to sl
def equationgap(delta, beta, lam,sl):
return givesclen(delta, beta, lam)*4*np.pi - sl
#Test if the equationgap works, the result should be close to zero!
print equationgap(.5,40,500,.1744)
#Now use the fsolve function should find the delta to be .5!
#beta = 40
#lam = 500
#sl = 0.174
#fsolve(equationgap,.6,args = (beta, lam, sl))
编辑:
错误消息是:
Traceback (most recent call last):
File "test.py", line 38, in polarint
return quad(integrand,0,np.pi,args = (r,beta,delta))[0]
File "/usr/local/anaconda/lib/python2.7/site-packages/scipy/integrate/quadpack.py", line 281, in quad
retval = _quad(func,a,b,args,full_output,epsabs,epsrel,limit,points)
File "/usr/local/anaconda/lib/python2.7/site-packages/scipy/integrate/quadpack.py", line 345, in _quad
return _quadpack._qagse(func,a,b,args,full_output,epsabs,epsrel,limit)
File "test.py", line 30, in integrand
dd = deriv(r, theta, delta)
File "test.py", line 22, in deriv
return np.imag(matrix(r, theta, delta, delta+h*1j))/h
File "test.py", line 14, in matrix
mat = np.array([[r**2-1,r*np.cos(theta),0,delta1],[r*np.cos(theta),r**2 - 1, -delta1,0],[0,-delta2,-r**2+1,-r*np.cos(theta)],[delta2,0,-r*np.cos(theta),-r**2+1]])
TypeError: can't convert complex to float
答案 0 :(得分:1)
这是失败的最小代码
from numpy import array
q = [[-1.0, 0.0, 0, array([ 0.6])], [0.0, -1.0, array([-0.6]), 0], [0, array([-0.6 -1.00000000e-11j]), 1.0, -0.0], [array([ 0.6 +1.00000000e-11j]), 0, -0.0, 1.0]]
array(q)
这有点奇怪。但是,请注意,有一个元素与一个元素混合在一起。只需在提供给array()
之前将对象打印出来就可以发现这一点。
要修复它,请在为fsolve提供的函数中将delta更改为delta [0]:
def equationgap(delta, beta, lam,sl):
return givesclen(delta[0], beta, lam)*4*np.pi - sl
因为代码的其余部分期望delta是单个数字,而不是数组。即使只有一个数字,fsolve也会给函数优化一个数组。
答案 1 :(得分:0)
我可以用以下内容生成错误消息:
x = np.ones((3,))
x[1] = 1 + 1j
x
是一个dtype=float
数组。尝试插入复杂值会产生错误。
如果在评估中产生错误:
mat = np.array([[r**2-1,r*np.cos(theta),0,delta1],
[r*np.cos(theta),r**2 - 1, -delta1,0],
[0,-delta2,-r**2+1,-r*np.cos(theta)],
[delta2,0,-r*np.cos(theta),-r**2+1]])
问题是 - r
,theta
,delta1
,delta2
的哪些值会产生此错误。第一个3是真正的标量,最后一个是复数,我得到一个(4,4)
复数数组。我怀疑这些变量中的一个是我们不能表达的。
我可以将pv
最小的例子缩短为:
np.array([1, np.array([1j])]) # error
np.array([[1],np.array([1j])]) # ok
切换术语的顺序,结果不同:
np.array([np.array([1j]),1])
# array([array([ 0.+1.j]), 1], dtype=object)
显然,错误是尝试从标量和数组的混合构建更大的数组的结果,其中一个是复杂的。错误消息不明确,可能是意外问题的结果。它可能值得一个错误报告。
解决方案是将所有0
转换为列表[0]
,或确保delta2
值是标量,而不是数组。