我有几个相关的功能,因为它们非常复杂和庞大,我不想用精确的数学代码为你烦恼。我尽力缩短计算时间来证明这一点。您可以在第一个函数中选择任何5x5 Hermitian矩阵。以下是代码摘要:
from numpy import linalg as LA
import numpy as np
import scipy as sp
def matrix(x, alpha, beta):
mat = #Some 5x5 matrix which depend on the parameters x, alpha, beta.
return np.sort(LA.eigvals(mat)) #it returns an array with 5 elements.
def integrand(x, alpha, beta):
#Some mathematical calculation which uses the function above, it returns a scalar.
h = 0.0000000001;
#The routine below is for taking the derivative with respect to beta
mm = np.imag(matrix(x,alpha,beta + 1j*h))/h
return (mm[0]**2 + mm[2]**2)
def integrate(alpha, beta):
return quad(integrand,0,600, args = (alpha,beta))[0]-1
y0 = 1.5
beta = 2
fsolve(integrate,y0,args = (beta))
fsolve给了我很多错误,它们都是一样的:
TypeError: ufunc 'isfinite' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''
错误是由于某些功能给出了NaN。
/usr/local/anaconda/lib/python2.7/site-packages/numpy/linalg/linalg.pyc in _assertFinite(*arrays)
214 def _assertFinite(*arrays):
215 for a in arrays:
--> 216 if not (isfinite(a).all()):
217 raise LinAlgError("Array must not contain infs or NaNs")
218
TypeError: ufunc 'isfinite' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''
我猜这是由于数据类型的数量不够。我怀疑这是由于集成功能的最后一行:
quad(...)[0]-1
我是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 the routine 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!
equationgap(.5,40,500,.1744)
#Now use the fsolve function should find the delta to be .5!
beta = 50
lam = 600
sl = 0.174
mu = 1
fsolve(equationgap,.6,args = (beta, lam, sl))