繁体   English   中英

Python scipy.optimize.curve_fit无法拟合函数

[英]Python scipy.optimize.curve_fit Failing to Fit Function

我正在尝试拟合LRC电路传递函数,但curve_fit似乎无法拟合。 我尝试了不同的初始值以及尝试实现scipy.optimize.differential_evolution。

下面是我的拟合尝试,在绘制后会产生这种情况

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

def f(freq, R, L, C):
    w = 2*np.pi*np.array(freq) # Convert frequency to angular frequency
    return R*w*C/np.sqrt((1-C*L*w**2)**2+(C*w*R)**2) # Series Transfer Function

name = ['R', 'L', 'C']
p0 = [1000,0.07,0.0000001] # Actual values of circuit components.

params, covariance = curve_fit(f, np.array(x), np.array(y), p0)
print(params)

我不太确定问题是否出在我的初始参数上,还是Levenberg-Marquardt算法做的事情完全不同。

当我尝试将拟合限制为函数的严格增加部分时,拟合似乎工作得很好,使我认为我的错误必定与函数的形状有关。

有谁暗示我为什么会变得如此奇怪?

这是一个使用背后的物理原理来猜测参数的解决方案:

有人知道最大值是“ U”。 此外,已知1/(L*C)= (2 * pi * fMax )**2 最终,对于小f ,我们可以使用U(f)约为2 * pi * f* R * C 从这个方程式中,您可以轻松计算出猜测

但是, LC只能相对于R进行拟合。 因此, R设置为1。 为了显示这种缩放行为,我绘制了第二张图,其中R设置为1000欧姆。 如果R > a * RL > a * L ,然后C > C / a 相应的图应相同。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import rc
rc('font',**{'family':'serif','serif':['Times']})
rc('text', usetex=True)
from scipy.optimize import curve_fit

def rlc_series( f, u , l, c, R=1):
    r = R
    w = 2 * np.pi * f
    return u * w * r * c / np.sqrt( ( 1 - w**2 * l * c )**2 + ( w * r * c )**2 )

fuData = np.loadtxt( "ohlVW.txt", delimiter=',' )
fuData = fuData[ fuData[:,0].argsort()]

### r=1
guessU = max( fuData[::,1] )
guessC = 1. / ( 2 * np.pi ) * ( fuData[ 1, 1 ] - fuData[ 0, 1 ] ) / (fuData[ 1, 0 ] - fuData[ 0, 0 ] ) / guessU
guessL = 1. / ( 2 * np.pi * fuData[ fuData[:,1].argmax() ,0 ] )**2 * 1./guessC
guess = [ guessU, guessL, guessC ]

sol, pcov = curve_fit(rlc_series, fuData[::,0], fuData[::,1], p0=guess )
print sol

fList = np.linspace( 0, 4000, 1000 )
uGList = np.fromiter( ( rlc_series( x, *guess ) for x in fList ), np.float )
uFList = np.fromiter( ( rlc_series( x, *sol ) for x in fList ), np.float )
uOtherList = np.fromiter( ( rlc_series( x, sol[0], sol[1]*1000, sol[2] / 1000., R=1000 ) for x in fList ), np.float )

fig = plt.figure()
ax = fig.add_subplot( 1, 1, 1 )
ax.plot( fuData[::,0], fuData[::,1] , marker ='o', ls='', label='Data' )
ax.plot( fList, uGList, label='Guess')
ax.plot( fList, uFList, label='Fit ($R=1\;\Omega$)')
ax.plot( fList, uOtherList, ls='--', label='scaled for $R=1000\;\Omega$')
ax.set_xlabel('$f\;\mathrm{(Hz)}$', fontsize=16)
ax.set_ylabel('$U\;\mathrm{(V)}$', fontsize=16)
ax.legend( loc=0 )
plt.show()

提供:

>> [3.85138538e-01 2.95465209e-04 3.49390461e-05]

适合

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM