我是编码新手,仍处于学习阶段。我的目标是从下面的等式中找到参数(即 J0、Rs、A、Rsh),
J= -J0*[exp{q((V+Rs*J)/A*k*T)}-1]-(V-Rs*J)/Rsh
哪里
q = 1.60e-19
,k = 2.208e-42
,和T = 298.0
.
我一直在尝试使用 scipy.optimize 的 curve_fit 函数来拟合它,但它不接受其中的自变量和因变量。我试图在谷歌上找到其他可能的解决方案,但直到现在几乎都迷路了。任何帮助将不胜感激!
from scipy.optimize import curve_fit
import numpy as np
V = np.array([-0.5 , -0.48, -0.46, -0.44, -0.42, -0.4 , -0.38, -0.36, -0.34,
-0.32, -0.3 , -0.28, -0.26, -0.24, -0.22, -0.2 , -0.18, -0.16,
-0.14, -0.12, -0.1 , -0.08, -0.06, -0.04, -0.02, 0. , 0.02,
0.04, 0.06, 0.08, 0.1 , 0.12, 0.14, 0.16, 0.18, 0.2 ,
0.22, 0.24, 0.26, 0.28, 0.3 , 0.32, 0.34, 0.36, 0.38,
0.4 , 0.42, 0.44, 0.46, 0.48, 0.5 , 0.52, 0.54, 0.56,
0.58, 0.6 , 0.62, 0.64, 0.66, 0.68, 0.7 , 0.72, 0.74,
0.76, 0.78, 0.8 , 0.82, 0.84, 0.86, 0.88, 0.9 , 0.92,
0.94, 0.96, 0.98, 1.])
J = np.array([-4.516e-04, -4.282e-04, -4.044e-04, -3.824e-04, -3.598e-04,
-3.389e-04, -3.173e-04, -2.973e-04, -2.770e-04, -2.577e-04,
-2.388e-04, -2.202e-04, -2.028e-04, -1.849e-04, -1.684e-04,
-1.515e-04, -1.358e-04, -1.198e-04, -1.047e-04, -8.970e-05,
-7.477e-05, -6.028e-05, -4.567e-05, -3.078e-05, -1.582e-05,
1.346e-08, 1.658e-05, 3.469e-05, 5.357e-05, 7.427e-05,
9.664e-05, 1.207e-04, 1.459e-04, 1.737e-04, 2.031e-04,
2.342e-04, 2.679e-04, 3.022e-04, 3.406e-04, 3.788e-04,
4.220e-04, 4.662e-04, 5.162e-04, 5.714e-04, 6.347e-04,
7.134e-04, 8.095e-04, 9.477e-04, 1.132e-03, 1.415e-03,
1.837e-03, 2.524e-03, 3.517e-03, 5.171e-03, 7.452e-03,
1.091e-02, 1.564e-02, 2.241e-02, 3.047e-02, 4.127e-02,
5.331e-02, 6.810e-02, 8.428e-02, 1.026e-01, 1.228e-01,
1.444e-01, 1.675e-01, 1.926e-01, 2.179e-01, 2.460e-01,
2.732e-01, 3.037e-01, 3.097e-01, 3.098e-01, 3.097e-01,
3.097e-01])
q = 1.60e-19
k = 2.208e-42
T = 298.0
def func (V, J, J0, Rs, A, Rsh): #V and J are both variables
return -J0*(np.exp(q*(V+Rs*J)/A*k*T)-1) - (V-Rs*J)/Rsh
P0 = [1.0e-3, 1.0, 1.0, 1000.0]
c, cov = curve_fit(func, V, J, P0)
print('fitting parameters') #show optimal parameters
print(c)
这是对一些通用数据的尝试,这些数据是自一致产生的。 进一步解释如代码中的注释:
import numpy as np
from warnings import warn
from scipy.optimize import curve_fit
q = 1.60e-19 # electron charge in As
k = 1.38e-23 # in J/K
T = 298.0 #room temperature in K
qikT = q/k/T
# ~print qikT
# J= -J0*[exp{q((V+RsJ)/A kT)}-1]-(V-RsJ)/Rsh
# as Rsh is an independent variable we can set the constant term as variable Jl
def f( J, J0, Jl, V, Rs, n ):
exponent = qikT * ( (V + Rs * J ) / n )
out = np.exp( exponent )
out = -J0 * out
out += Jl
return out
def find_selfconsistent( J0, Jl, V, Rs, n ):
test = True
cnt = 0
jj = -1
while test:
jjj = f( jj, J0, Jl, V, Rs, n )
# ~print jjj
cnt += 1
if cnt > 150 or np.fabs( ( jjj - jj ) / jj ) < 1e-6 : # 0.1% change
if cnt > 150:
warn("not converged", UserWarning )
test = False
else:
jj = jjj
return jjj
"""
I don't know if these values make sense, but it converges
"""
vl = np.linspace( -.5, 1, 25 )
jl = np.fromiter( ( find_selfconsistent( 1e-2, 1.2e-4, v, 300.6, 90.0 ) for v in vl ), np.float )
# ~print jl
"""
now curve_fit wants a function that it calls as f( x, params )
and it optimizes params so
( y - f( x, params )^2 is minimum
We have, hence, to write a wrapper.
"""
def wrapper( jlist, J0, Jl, Rs, n ):
"""
jl will be passed as list
and we know that vl is of the same shape
"""
out = list()
if not isinstance( jlist, np.ndarray ):
raise( TypeError, "unexpected" )
for j, v in zip( jlist, vl): # vl is global!
out.append( j - f( j, J0, Jl, v, Rs, n ) )
return np.array( out )
# test
print wrapper( jl, 1e-2, 1.2e-4, 300.6, 90.0 ) ## is basically zero
sol, _ = curve_fit( wrapper, jl, np.zeros( len( jl ) ), p0 = [ 1e-2, 1.2e-4, 300.6, 90.0 ])
print sol
## works
## very likely one needs good starting values in p0
@mikuszefski,嗨。当我考虑需要考虑串联电阻的 MOSFET 的 I-V 曲线时,我遇到了类似的问题。我想知道如何用你的程序拟合赛义夫提供的数据(V-J),以及如何绘制实验V-J的图形和拟合参数的相应结果,可能会因为第一个参数(J)出现一些问题在函数中。谢谢!