Я застреваю в проблеме, которую я упростил ниже.SciPy не может преобразовать комплекс в float
Итак, у меня есть функция (матрица), которая возвращает собственные значения матрицы.
Вторая функция (производная) находит производные собственных значений по дельта. Собственная производная функция SciPy очень медленная, поэтому я использовал метод сложных разностей.
Затем я беру двойной интеграл подынтегрального выражения по r и theta. Вместо того, чтобы брать двойной интеграл, я решаю дифференциальное уравнение г, взяв одномерный интеграл по тете, что делает вычисления более быстрыми.
И, наконец, интегральные работы. Однако, если я попытаюсь найти конкретную дельту, которая удовлетворяет уравнению, она дает ошибку: невозможно преобразовать комплекс в 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))
Edit:
Сообщение об ошибке:
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
Ваш вызов 'np.imag' преобразуется в сложный. Почему это там? –
Это для взятия производной, взятой отсюда: http://blogs.mathworks.com/cleve/2013/10/14/complex-step-differentiation/ – gurluk
В python существует множество производных подпрограмм. Вы смешиваете код MATLAB? В любом случае, np.imag означает взять воображаемую сторону. Если вы вызовете эту функцию, она преобразует свой аргумент в сложную функцию. Я не знаю, какая производная она должна быть. –