Python: curve_fit не работает для функции с тремя подгоночными параметрами и неправильным интегралом - PullRequest
0 голосов
/ 01 декабря 2018

Я пытаюсь согласовать набор данных с этим монстром уравнения.Я знаю, что об этом уже спрашивали, но я не думаю, что первоначальные предположения являются моей проблемой, и при этом я не могу добавить больше терминов к своему уравнению подбора.

Мое уравнение подбора.Обратите внимание, что «u» в интеграле НЕ совпадает с u, как определено сверху.enter image description here

Кстати, мой набор данных в мА / гм.

Я реализовал это в функции F , которая принимает входные параметры Vd, T, r и Vt. T, r и Vt как параметры подгонки.T и r колеблются от 0

Мои первые несколько программ были ужасно подходят (если бы он мог даже выполнить интеграл), поэтому я решил посмотреть, работает ли алгоритм.Реализация функции выглядит следующим образом:

from scipy import integrate
from scipy.optimize import curve_fit
import numpy as np
import matplotlib.pyplot as plt

#Constants
eSiO2 = 3.9 #Relative dielectric constant of SiO2
tox = 2e-9  #Gate oxide thickness in m
evac = 8.854e-12    #Vacuum permittivity, F/m
em = 0.2*9.11e-31   #Effective electron mass in kg
KT = 4.11e-21 #Thermal energy in joules
Mv = 2.5 #Degeneracy factor
q = 1.6e-19 #Electron charge, coulombs
hbar = 1.054e-34    #Reduced plancks constant
Vg = 1

def F(Vd,T,r,Vt):
    #Derived constants required for computation
    Ci = (eSiO2*evac)/tox #Oxide capacitance per area
    ved = (q*r*Vd)/(KT) #little Vd
    I0 = (np.sqrt(2)*q*(KT**1.5)*Mv*np.sqrt(em))/(np.pi*hbar)**2 #Leakage Current

    #Rho
    rho1 = 2*np.pi*hbar**2*Ci
    rho2 = q*KT*em*Mv
    rhoV = Vg-Vt
    rho = (rho1*rhoV)/rho2

    #u
    UA = 1 + np.exp(ved)
    UB = np.exp(ved)*(np.exp(rho)-1)
    Usq = np.sqrt(UA**2+4*UB)
    u = np.log(Usq-UA)-np.log(2)

    #Integrand of F(u)
    def integrand1(A,x):
        return (np.sqrt(A))/(1+np.exp(A-x))

    #Integrand of F(u-v)
    def integrand2(A,x):
        return (np.sqrt(A))/(1+np.exp(A-x))
    sum1 = 0
    sum2 = 0
    tempy1=[]
    tempy2=[]
    tempx2=[]

    #Tempx2 = dummy variable domain
    tempx2 = np.linspace(0,100,num=10000)

    #Fitting parameters are determined
    if Ready is True:
        #Evaluate the integrands for all the Vd values
        tempy1 = integrand1(tempx2,u)
        tempy2 = integrand2(tempx2,u-ved)

    #Fitting parameters are NOT determined
    else:
        print ("Calculating")
        #Evaluate the integrands for all the Vd values
        for i in range (0,len(u)):
            tempy1 = integrand1(tempx2,u[i])
            tempy2 = integrand2(tempx2,u[i]-ved[i]) 

    #Perform integration over dummy domain
    sum1 = integrate.simps(tempy1,tempx2,0.1)
    sum2 = integrate.simps(tempy2,tempx2,0.1)

    if Ready is False:
        print ("u=%s" %u,"ved=%s" %ved)
        print ("Sum1 is %s" %sum1)
    return I0*T*1e-3*(sum1-sum2)

Функция будет вычислять F (x, T, r, Vt), если указаны T, r и Vt.Поэтому я решил создать «примерный» набор данных, чтобы посмотреть, будет ли он почти идеально соответствовать самому себе:

#Create domain for reference curve
Ready = True
x = np.linspace(0,1.2,50)

y=[]
#Evaluate the reference curve domain
for j in range (0,50):
    y.append(F(x[j],0.2,0.147,0.45))

Теперь, когда эталонная кривая создана, кривая будет пытаться соответствовать.Обратите внимание, что мои значения p0 очень близки к реальным значениям.

#Guesses for the curve fit
initial = [0.21,0.15,0.46]
Ready = False
#Attempt to fit the reference curve
popt, popc = curve_fit(F,x,y,initial,bounds=(0,1))

#Create the fit curve
fitdata=[]
Ready = True
for i in range (0,50):
    fitdata.append(F(x[i],popt[0],popt[1],popt[2]))

А затем построите и контрольную, и кривую соответствия.Тем не менее, кривая соответствия является плохой, хотя значения p0 действительно близки к фактическим.Я видел, что у людей были проблемы с этим в предыдущих постах StackOverflow.

plt.plot(x,y,label='Reference')
plt.plot(x,fitdata,label='Fit')
plt.legend()
plt.show()

Вот сюжет:

Plot with reference and fit curve

Я обнаружил, что это по крайней мереполезно выбрать некоторые параметры, чтобы затем угадать их вручную и проверить для окончательной подгонки.Это просто так странно, что он не может даже соответствовать самому себе, даже если свойство curve_fit в основном соответствует расстоянию касания для наилучших параметров подгонки.

Из-за сложности этого уравнения подбора мне придется это делать?Я сделал почти то же самое вычисление с квадратичной подгонкой (для другого проекта) к реальным данным, и получить соответствующую кривую было тривиально.

1 Ответ

0 голосов
/ 01 декабря 2018

Вы отбрасываете все результаты для tempy1 и tempy2, кроме последнего.Я думаю, что вы хотите добавить в список.

Изменение

for i in range (0,len(u)):
        tempy1 = integrand1(tempx2,u[i])
        tempy2 = integrand2(tempx2,u[i]-ved[i])

на

for i in range (0,len(u)):
        tempy1.append(integrand1(tempx2,u[i]))
        tempy2.append(integrand2(tempx2,u[i]-ved[i]))

приводит к перекрытию двух графиков.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...