Is there an a method to fit a wave created from two wave? I need to get the frequency and amplitude for a wave that consists of multiple function.
for example, if I have a sine curve (created from two sine waves), How can I extract the parameters for this complex wave.
I used the curve fitting code provided in this answer, as illustrated below. A simple sinusoidal function is used in the provided code. so I obtain a fitted curve with a single amplitude and frequency.
Data example:
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline

x = np.arange(0, 50, 0.01)
x2 = np.arange(0, 100, 0.02)
x3 = np.arange(0, 150, 0.03)
sin1 = np.sin(x)
sin2 = np.sin(x2)
sin3= np.sin(x3/2)

sin4 = sin1 + sin2+sin3
plt.plot(x, sin4)
plt.show()


import numpy, scipy.optimize

def fit_sin(tt, yy):
    '''Fit sin to the input time sequence, and return fitting parameters &quot;amp&quot;, &quot;omega&quot;, &quot;phase&quot;, &quot;offset&quot;, &quot;freq&quot;, &quot;period&quot; and &quot;fitfunc&quot;'''
    tt = numpy.array(tt)
    yy = numpy.array(yy)
    ff = numpy.fft.fftfreq(len(tt), (tt[1]-tt[0]))   # assume uniform spacing
    Fyy = abs(numpy.fft.fft(yy))
    guess_freq = abs(ff[numpy.argmax(Fyy[1:])+1])   # excluding the zero frequency &quot;peak&quot;, which is related to offset
    guess_amp = numpy.std(yy) * 2.**0.5
    guess_offset = numpy.mean(yy)
    guess = numpy.array([guess_amp, 2.*numpy.pi*guess_freq, 0., guess_offset])

    def sinfunc(t, A, w, p, c):  return A * numpy.sin(w*t + p) + c
    popt, pcov = scipy.optimize.curve_fit(sinfunc, tt, yy, p0=guess)
    A, w, p, c = popt
    f = w/(2.*numpy.pi)
    fitfunc = lambda t: A * numpy.sin(w*t + p) + c
    return {&quot;amp&quot;: A, &quot;omega&quot;: w, &quot;phase&quot;: p, &quot;offset&quot;: c, &quot;freq&quot;: f, &quot;period&quot;: 1./f, &quot;fitfunc&quot;: fitfunc, &quot;maxcov&quot;: numpy.max(pcov), &quot;rawres&quot;: (guess,popt,pcov)}

yy = sin4
tt = x
res = fit_sin(tt, yy)
print(str(i), &quot;Amplitude=%(amp)s, Angular freq.=%(omega)s, phase=%(phase)s, offset=%(offset)s, Max. Cov.=%(maxcov)s&quot; % res )
fit_values=res[&quot;fitfunc&quot;](tt)
Frequenc_fit= res['freq']
print(i, Frequenc_fit)
Frequenc_fit=Frequenc_fit
Amp_fit=res['amp']
Omega_fit=res['omega']
Phase_fit=res['phase']
Offset_fit=res['offset']
maxcov_fit=res['maxcov']
plt.plot(tt, yy, &quot;-k&quot;, label=&quot;y&quot;, linewidth=2)
plt.plot(tt,fit_values, &quot;r-&quot;, label=&quot;y fit curve&quot;, linewidth=2)
plt.legend(loc=&quot;best&quot;)
plt.show()

I got a fitted sine curve with a single frequency and amplitude as follows:

Is there a method to obtain fitted curve matches with the original one? or open software can be used to get the parameters for the best-fitted wave from the original one?
PLEASE, my understanding of FFT is VERY limited! So PLEASE forgive me for my lack of knowledge.
As a precautionary statement, the FFT will give you coefficients of the frequency components closest to the integer multiples of $1/T$ in Hz where $T$ is the length of the sequence in seconds being used for the FFT. If the components are not on these integer boundaries, then you will get several results (called spectral leakage) where the actual components (if information is known such as in the OP’s case of having just two tones) can be estimated as being in between two large adjacent results.
Further when combining the waveform you must pay attention to the phase as well as amplitude of the result in order for it to match the time domain waveform shown. The FFT will provide both a scaled magnitude and phase. The FFT results are the coefficients for complex frequencies (of the form $e^{j\omega t}$ but if it is known that the waveform is real then you can use the first half of the FFT as representing the coefficients of real frequencies in the form of $\cos(\omega t)$, scaled by $N/2$ where $N$ is the number of samples in the sequence used for the FFT.