### 39.6 Providing the Function to be Minimized

The user must provide n functions of p variables for the minimization algorithm to operate on. In order to allow for arbitrary parameters the functions are defined by the following data types:

Data Type: gsl_multifit_nlinear_fdf

  This data type defines a general system of functions with arbitrary parameters, the corresponding Jacobian matrix of derivatives, and optionally the second directional derivative of the functions for geodesic acceleration.

  `int (* f) (const gsl_vector * x, void * params, gsl_vector * f)`

    This function should store the n components of the vector f(x) in f for argument x and arbitrary parameters params, returning an appropriate error code if the function cannot be computed.

  `int (* df) (const gsl_vector * x, void * params, gsl_matrix * J)`

    This function should store the n-by-p matrix result J_ij = d f_i(x) / d x_j in J for argument x and arbitrary parameters params, returning an appropriate error code if the matrix cannot be computed. If an analytic Jacobian is unavailable, or too expensive to compute, this function pointer may be set to NULL, in which case the Jacobian will be internally computed using finite difference approximations of the function f.

  `int (* fvv) (const gsl_vector * x, const gsl_vector * v, void * params, gsl_vector * fvv)`

    When geodesic acceleration is enabled, this function should store the n components of the vector f_{vv}(x) = \sum_{\alpha\beta} v_{\alpha} v_{\beta} {\partial \over \partial x_{\alpha}} {\partial \over \partial x_{\beta}} f(x), representing second directional derivatives of the function to be minimized, into the output fvv. The parameter vector is provided in x and the velocity vector is provided in v, both of which have p components. The arbitrary parameters are given in params. If analytic expressions for f_{vv}(x) are unavailable or too difficult to compute, this function pointer may be set to NULL, in which case f_{vv}(x) will be computed internally using a finite difference approximation.

  `size_t n`

    the number of functions, i.e. the number of components of the vector f.

  `size_t p`

    the number of independent variables, i.e. the number of components of the vector x.

  `void * params`

    a pointer to the arbitrary parameters of the function.

  `size_t nevalf`

    This does not need to be set by the user. It counts the number of function evaluations and is initialized by the `_init` function.

  `size_t nevaldf`

    This does not need to be set by the user. It counts the number of Jacobian evaluations and is initialized by the `_init` function.

  `size_t nevalfvv`

    This does not need to be set by the user. It counts the number of f_{vv}(x) evaluations and is initialized by the `_init` function.

Data Type: gsl_multilarge_nlinear_fdf

  This data type defines a general system of functions with arbitrary parameters, a function to compute J u or J^T u for a given vector u, the normal equations matrix J^T J, and optionally the second directional derivative of the functions for geodesic acceleration.

  `int (* f) (const gsl_vector * x, void * params, gsl_vector * f)`

    This function should store the n components of the vector f(x) in f for argument x and arbitrary parameters params, returning an appropriate error code if the function cannot be computed.

  `int (* df) (CBLAS_TRANSPOSE_t TransJ, const gsl_vector * x, const gsl_vector * u, void * params, gsl_vector * v, gsl_matrix * JTJ)`

    If TransJ is equal to `CblasNoTrans`, then this function should compute the matrix-vector product J u and store the result in v. If TransJ is equal to `CblasTrans`, then this function should compute the matrix-vector product J^T u and store the result in v. Additionally, the normal equations matrix J^T J should be stored in the lower half of JTJ. The input matrix JTJ could be set to NULL, for example by iterative methods which do not require this matrix, so the user should check for this prior to constructing the matrix. The input params contains the arbitrary parameters.

  `int (* fvv) (const gsl_vector * x, const gsl_vector * v, void * params, gsl_vector * fvv)`

    When geodesic acceleration is enabled, this function should store the n components of the vector f_{vv}(x) = \sum_{\alpha\beta} v_{\alpha} v_{\beta} {\partial \over \partial x_{\alpha}} {\partial \over \partial x_{\beta}} f(x), representing second directional derivatives of the function to be minimized, into the output fvv. The parameter vector is provided in x and the velocity vector is provided in v, both of which have p components. The arbitrary parameters are given in params. If analytic expressions for f_{vv}(x) are unavailable or too difficult to compute, this function pointer may be set to NULL, in which case f_{vv}(x) will be computed internally using a finite difference approximation.

  `size_t n`

    the number of functions, i.e. the number of components of the vector f.

  `size_t p`

    the number of independent variables, i.e. the number of components of the vector x.

  `void * params`

    a pointer to the arbitrary parameters of the function.

  `size_t nevalf`

    This does not need to be set by the user. It counts the number of function evaluations and is initialized by the `_init` function.

  `size_t nevaldfu`

    This does not need to be set by the user. It counts the number of Jacobian matrix-vector evaluations (J u or J^T u) and is initialized by the `_init` function.

  `size_t nevaldf2`

    This does not need to be set by the user. It counts the number of J^T J evaluations and is initialized by the `_init` function.

  `size_t nevalfvv`

    This does not need to be set by the user. It counts the number of f_{vv}(x) evaluations and is initialized by the `_init` function.

Note that when fitting a non-linear model against experimental data, the data is passed to the functions above using the params argument and the trial best-fit parameters through the x argument.