Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I fit a cosine function?

I wrote a python function to get the parameters of the following cosine function: enter image description here

param = Parameters()    
param.add( 'amp', value = amp_guess, min = 0.1 * amp_guess, max = amp_guess )

param.add( 'off', value = off_guess, min = -10, max = 10 )

param.add( 'shift', value = shift_guess[0], min = 0, max = 2 * np.pi, )

fit_values = minimize( self.residual, param, args = ( azi_unique, los_unique ) )

def residual( self, param, azi, data ):
        """
        Parameters
        ----------

        Returns
        -------
        """
        amp = param['amp'].value
        off = param['off'].value
        shift = param['shift'].value
        model = off + amp * np.cos( azi - shift )
        return model - data

In Matlab how can get the amplitude, offset and shift of the cosine function?

like image 494
OHLÁLÁ Avatar asked Jan 21 '26 00:01

OHLÁLÁ


1 Answers

My experience tells me that it's always good to depend as little as possible on toolboxes. For your particular case, the model is simple and doing it manually is pretty straightforward.

Assuming that you have the following model:

y = B + A*cos(w*x + phi)

and that your data is equally-spaced, then:

%// Create some bogus data

A   = 8;
B   = -4;
w   = 0.2;
phi = 1.8;

x = 0 : 0.1 : 8.4*pi;
y = B + A*cos(w*x + phi) + 0.5*randn(size(x));

%// Find kick-ass initial estimates
L = length(y);
N = 2^nextpow2(L);

B0 = (max(y(:))+min(y(:)))/2;

Y = fft(y-B0, N)/L;
f = 5/(x(2)-x(1)) * linspace(0,1,N/2+1);

[A0,I] = max( 2*abs(Y(1:N/2+1)) );
w0   = f(I);
phi0 = 2*imag(Y(I));

%// Refine the fit
sol = fminsearch(@(t) sum( (y(:)-t(1)-t(2)*cos(t(3)*x(:)+t(4))).^2 ), [B0 A0 w0 phi0])

Results:
 

sol = %// B was -4      A was 8       w was 0.2     phi was 1.8                
         -4.0097e+000   7.9913e+000   1.9998e-001   1.7961e+000    
like image 106
Rody Oldenhuis Avatar answered Jan 22 '26 23:01

Rody Oldenhuis



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!