Search code examples
mathcurve-fittinggslleast-squares

Sine wave least squares curve fitting possible (using GSL)?


Is it possible to fit an A*sin(B*t+C) function with GSL or a similar library?

i want to get the A and C parameter of a sine wave present in 4096 samples (8bit) and can provide an good approximation of B.

A think that should be possible with GSLs non-linear multifit but I don’t understand the mathematical background with all that Jacobian matrix stuff...


Solution

  • Yes,

    You have probably read this: http://www.gnu.org/software/gsl/manual/html_node/Overview-of-Nonlinear-Least_002dSquares-Fitting.html#Overview-of-Nonlinear-Least_002dSquares-Fitting

    What is required from you is to provide two functions

    the objective:

    `

    int sine_f (const gsl_vector * x, void *data, 
            gsl_vector * f){
        ...
        for(...){
        ...
          double Yi = A * sin(B*t +C);
          gsl_vector_set (f, i, (Yi - y[i])/sigma[i]);
        }
        ...
        }
    

    and then the derivative of the objective with respect to the parameters

    int
    sine_df (const gsl_vector * x, void *data, 
             gsl_matrix * J)
    //the derivatives of Asin(Bt +C) wrt A,B,C for each t
    

    This is straight from http://www.gnu.org/software/gsl/manual/html_node/Example-programs-for-Nonlinear-Least_002dSquares-Fitting.html#Example-programs-for-Nonlinear-Least_002dSquares-Fitting

    So the Jacobian is just a 3xN matrix, where N is the number of data points For example J(0,3) = sin(B*t_3 + C)

    if A,B,C correspond to x[0],x[1],x[2]

    And J(1,5) = A*t_5*cos(B*t_5 + C) This is the derivative wrt. B