sandbox/ecipriano/test/fsolve-gsl.c

    Test fsolve() using GSL

    This is one of the multiroot test cases provided with the gsl library. We want to solve the Rosenbrock system of equations: \displaystyle f_1(x,y) = a(1-x) \displaystyle f_2(x,y) = b(y-x^2) with a=1,b=10, knowing that the solution of this system is (x,y)=(1,1).

    We have to define the use of gsl before including fsolve.

    #define USE_GSL
    #include "run.h"
    #include "fsolve-gsl.h"

    We define a struct with data to be passed to the non-linear system function.

    typedef struct {
      double a, b;
    } UserDataNls;

    We define the function with the non-linear system of equations. For convience, when using different interfaces, it is useful to define a common function that uses just elementary C types.

    void function (const double * x, double * f, void * params) {
      UserDataNls * data = (UserDataNls *)params;
      double a = data->a;
      double b = data->b;
    
      f[0] = a*(1. - x[0]);
      f[1] = b*(x[1] - x[0]*x[0]);
    }

    The gsl interface requires the use of a specific function which can be implemented as follows.

    int function_gsl_interface (const gsl_vector * x, void * params, gsl_vector * f) {
      double * xdata = x->data;
      double * fdata = f->data;
    
      function (xdata, fdata, params);
      return GSL_SUCCESS;
    }
    
    int main (void) {

    We create an array with the first guess solution of the non-linear system.

      Array * arrUnk = array_new();
      {
        double val1 = 10., val2 = 5.;
        array_append (arrUnk, &val1, sizeof(double));
        array_append (arrUnk, &val2, sizeof(double));
    
        double * unks = (double *)arrUnk->p;
        for (int i=0; i<2; i++)
          fprintf (stderr, "firstguess[%d] = %f\n", i, unks[i]);
      }

    We create the parameters to be passed to the nls function.

      UserDataNls data;
      data.a = 1.;
      data.b = 10.;

    We solve the non-linear system, callig the function fsolve().

      fsolve (function_gsl_interface, arrUnk, &data);

    We recover the results of the system.

      {
        double * unks = (double *)arrUnk->p;
        for (int i=0; i<2; i++)
          fprintf (stderr, "results[%d] = %f\n", i, unks[i]);
      }

    Cleanup operations.

      array_free (arrUnk);
      run();
    }