Предполагая, что вы знаете частоты заранее, проблема проста.Вы можете установить нижнюю границу на 0 и установить верхнюю границу на 2 * pi * freq для частоты.Для усилителей задайте любое число (или np.inf
, если вы не хотите границы).
Вы можете сформулировать функцию в виде lambda x, amp1, phase1, amp2, phase2... : y
, curve_fit
может принимать функцию неопределенного числа аргументов до тех пор, покапо мере того как вы вводите правильное начальное предположение.
Пример кода для пяти частот:
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
x = np.linspace(0,10,60)
w = [1,2,3,4,5]
a = [1,4,2,3,0.1]
x0 = [0,1,0,1,0.5]
y = np.sum(a_i * np.sin(w_i * x - x0_i) for w_i, a_i, x0_i in zip(w,a, x0)) #base_data
yr = y + np.random.normal(0,0.5, size=x.size) #noisy data
def func(x, *args):
""" function of the form lambda x, amp1, phase1, amp2, phase2...."""
return np.sum(a_i * np.sin(w_i * (x-x0)) for w_i, a_i, x0
in zip(w,args[::2], args[1::2]))
ubounds = np.zeros(len(w) * 2)
ubounds[::2] = 10 #setting amp max value to 10 (arbitrary)
ubounds[1::2] = np.asarray(w) * 2 * np.pi
p0 = [0] * 10 # note p0 size
popt, pcov = curve_fit(func, x, yr, p0, bounds=(0, ubounds))
amps, phases = popt[::2], popt[1::2]
plt.plot(x,func(x, *popt))
plt.plot(x,yr, 'go')