用给定的方程拟合数据,在 Python 中方程的两边都有因变量

问题描述 投票:0回答:2

我是编码新手,仍处于学习阶段。我的目标是从下面的等式中找到参数(即 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)
python curve-fitting
2个回答
0
投票

这是对一些通用数据的尝试,这些数据是自一致产生的。 进一步解释如代码中的注释:

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

0
投票

@mikuszefski,嗨。当我考虑需要考虑串联电阻的 MOSFET 的 I-V 曲线时,我遇到了类似的问题。我想知道如何用你的程序拟合赛义夫提供的数据(V-J),以及如何绘制实验V-J的图形和拟合参数的相应结果,可能会因为第一个参数(J)出现一些问题在函数中。谢谢!

© www.soinside.com 2019 - 2024. All rights reserved.