Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python scipy.optimize.curve_fit未能拟合函数_Python_Scipy_Physics_Curve Fitting - Fatal编程技术网

Python scipy.optimize.curve_fit未能拟合函数

Python scipy.optimize.curve_fit未能拟合函数,python,scipy,physics,curve-fitting,Python,Scipy,Physics,Curve Fitting,我试图拟合LRC电路传递函数,但曲线拟合似乎无法拟合。我尝试了不同的初始值,也尝试了实现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

我试图拟合LRC电路传递函数,但曲线拟合似乎无法拟合。我尝试了不同的初始值,也尝试了实现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
。最后,我们可以使用
U(f)
大约是
2*pi*f*R*C
来表示较小的
f
。从这个方程式可以很容易地计算出猜测

但是,
L
C
只能相对于
R
进行安装。因此,
R
被设置为unity。为了显示这种缩放行为,我绘制了第二个图,其中
R
设置为1000欧姆。如果
R
->
a*R
L
->
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]

注意:您的
f
是一个LCR系列,用于测量R上的电压。如果
w**2=1/(L*C)
f
返回
1
,即谐振时,电压仅下降到R上。由于您的最大值为
0.4
,我认为您得到了错误的模型。我看到您导入了微分进化来估计曲线拟合的初始参数值,但尚未在代码中使用它。我想我可以让你走,但我需要你的数据。请链接到数据,或者如果数据不大,请将其添加到您的问题中?您的图像表明您有一个RLC并行电路。您是否将此与R0串联?您可能需要拟合
w*r*l/np.sqrt((r*r0*(1-w**2*l*c))**2+(w*l*(r+r0))**2)
您可以从最大值猜测r0/r,从其位置猜测l*c。从小频率的斜率可以得到L/R0等。看起来你的模型函数太尖锐,无法匹配你的数据。似乎模型要求最大值为1,而不是~0.4。这可能是因为响应函数需要加宽或用其他术语衰减。顺便说一句,数据是OP数据的子集。这是一个非常有趣的解决方案。非常感谢。