我正在尝试使用curve_fit从scipy适合一个函数。优化模块。我一直得到错误信息:
"TypeError:只有size-1的数组可以转换为Python标量。
frequency = []
for i in driven_period:
frequency.append(2*math.pi*i**-1)
amplitude = []
for i in driven_height:
amplitude.append(i-41.3)
def amplitude_func(omega, p, omega0, gamma):
x=((p*omega0**2)/(math.sqrt((omega0**2-omega**2)**2+gamma**2*omega**2)))
return x
parameters = sp.curve_fit(amplitude_func, frequency, amplitude)
p_fit = parameters[0][0]
omega0_fit = parameters[0][1]
gamma_fit = parameters[0][2]
fit=[]
for i in frequency:
fit.append(amplitude_func(i, p_fit, w_fit, y_fit))
plt.scatter(frequency, amplitude)
plt.plot(frequency, fit)
我用一个基本的线性函数尝试了同样的代码,它起作用了,所以我认为问题一定是与函数amplitude_func有关,但我不知道它是什么。我试着在每个阶段打印,但我找不到我有错误的地方。对不起,如果这是一个愚蠢的问题,我是新的编程。帮助感激。
编辑:更多信息。错误信息:---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Input In [151], in <cell line: 27>()
24 return (p*(omega)**2)/(math.sqrt((omega0)**2-(omega)**2)**2+(gamma)**2*(omega**2))
26 # lorenzian least-squares fit
---> 27 amplitude_fit, amplitude_covariance = sp.curve_fit(amplitude_func, frequency, amplitude)
28 p_fit = amplitude_fit[0]
29 omega0_fit = amplitude_fit[1]
File ~/opt/anaconda3/lib/python3.9/site-packages/scipy/optimize/minpack.py:789, in curve_fit(f, xdata, ydata, p0, sigma, absolute_sigma, check_finite, bounds, method, jac, **kwargs)
787 # Remove full_output from kwargs, otherwise we're passing it in twice.
788 return_full = kwargs.pop('full_output', False)
--> 789 res = leastsq(func, p0, Dfun=jac, full_output=1, **kwargs)
790 popt, pcov, infodict, errmsg, ier = res
791 ysize = len(infodict['fvec'])
File ~/opt/anaconda3/lib/python3.9/site-packages/scipy/optimize/minpack.py:410, in leastsq(func, x0, args, Dfun, full_output, col_deriv, ftol, xtol, gtol, maxfev, epsfcn, factor, diag)
408 if not isinstance(args, tuple):
409 args = (args,)
--> 410 shape, dtype = _check_func('leastsq', 'func', func, x0, args, n)
411 m = shape[0]
413 if n > m:
File ~/opt/anaconda3/lib/python3.9/site-packages/scipy/optimize/minpack.py:24, in _check_func(checker, argname, thefunc, x0, args, numinputs, output_shape)
22 def _check_func(checker, argname, thefunc, x0, args, numinputs,
23 output_shape=None):
---> 24 res = atleast_1d(thefunc(*((x0[:numinputs],) + args)))
25 if (output_shape is not None) and (shape(res) != output_shape):
26 if (output_shape[0] != 1):
File ~/opt/anaconda3/lib/python3.9/site-packages/scipy/optimize/minpack.py:485, in _wrap_func.<locals>.func_wrapped(params)
484 def func_wrapped(params):
--> 485 return func(xdata, *params) - ydata
Input In [151], in amplitude_func(omega, p, omega0, gamma)
23 def amplitude_func(omega, p, omega0, gamma):
---> 24 return (p*(omega)**2)/(math.sqrt((omega0)**2-(omega)**2)**2+(gamma)**2*(omega**2))
TypeError: only size-1 arrays can be converted to Python scalars
数组:driven_period = [1.027, 0.949, 0.866, 0.806, 0.648, 0.917, 0.935, 1.404, 1.113, 0.887, 0.983]
driven_height = [43.1, 45.35, 43.7, 42.25, 41.3, 45.9, 45.7, 41.5, 42.25, 44.75, 44.0]
我想我弄明白了:
Python似乎在数组乘法(**运算符和数学库)方面有问题。切换到np进行计算是有效的。遗憾的是,我无法深入解释原因:/
import math
import numpy as np
driven_period = [1.027, 0.949, 0.866, 0.806, 0.648, 0.917, 0.935, 1.404, 1.113, 0.887, 0.983]
driven_height = [43.1, 45.35, 43.7, 42.25, 41.3, 45.9, 45.7, 41.5, 42.25, 44.75, 44.0]
frequency = []
for i in driven_period:
frequency.append(2*math.pi*i**-1)
amplitude = []
for i in driven_height:
amplitude.append(i-41.3)
def amplitude_func(omega, p, omega0, gamma):
#x=((p*omega0**2)/(math.sqrt((omega0**2-omega**2)**2+gamma**2*omega**2)))
p1 = np.power(omega0,2)-np.power(omega,2)
p2 = np.power(gamma*omega,2)
return p*np.power(omega0,2) / (np.sqrt(p1+p2))
parameters = sp.curve_fit(amplitude_func, frequency, amplitude)
p_fit = parameters[0][0]
omega0_fit = parameters[0][1]
gamma_fit = parameters[0][2]
print(parameters)
fit=[]
for i in frequency:
fit.append(amplitude_func(i, p_fit, omega0_fit, gamma_fit))
现在我只能通过ssh访问Python解释器。所以我不能保证情节和契合是否有意义。将函数拆分为变量p1
和p2
只是为了调试目的。可以重新合并。