#define osborne_N 33
#define osborne_P 5
static double osborne_x0[osborne_P] = { 0.5, 1.5, -1.0, 0.01, 0.02 };
static double osborne_epsrel = 1.0e-8;
static double osborne_Y[osborne_N] = {
0.844, 0.908, 0.932, 0.936, 0.925, 0.908, 0.881,
0.850, 0.818, 0.784, 0.751, 0.718, 0.685, 0.658,
0.628, 0.603, 0.580, 0.558, 0.538, 0.522, 0.506,
0.490, 0.478, 0.467, 0.457, 0.448, 0.438, 0.431,
0.424, 0.420, 0.414, 0.411, 0.406
};
static void
osborne_checksol(const double x[], const double sumsq,
const double epsrel, const char *sname,
const char *pname)
{
const double sumsq_exact = 5.464894697482687e-05;
double osborne_x[osborne_P];
osborne_x[0] = 3.754100521058740e-01;
osborne_x[1] = GSL_NAN;
osborne_x[2] = GSL_NAN;
osborne_x[3] = GSL_NAN;
osborne_x[4] = GSL_NAN;
gsl_test_rel(sumsq, sumsq_exact, epsrel, "%s/%s sumsq",
sname, pname);
/* only the first model parameter is uniquely constrained */
gsl_test_rel(x[0], osborne_x[0], epsrel, "%s/%s i=0",
sname, pname);
}
static int
osborne_f (const gsl_vector * x, void *params, gsl_vector * f)
{
double x1 = gsl_vector_get(x, 0);
double x2 = gsl_vector_get(x, 1);
double x3 = gsl_vector_get(x, 2);
double x4 = gsl_vector_get(x, 3);
double x5 = gsl_vector_get(x, 4);
size_t i;
for (i = 0; i < osborne_N; ++i)
{
double ti = 10.0*i;
double yi = osborne_Y[i];
double fi = yi - (x1 + x2*exp(-x4*ti) + x3*exp(-x5*ti));
gsl_vector_set(f, i, fi);
}
(void)params; /* avoid unused parameter warning */
return GSL_SUCCESS;
}
static int
osborne_df (const gsl_vector * x, void *params, gsl_matrix * J)
{
double x2 = gsl_vector_get(x, 1);
double x3 = gsl_vector_get(x, 2);
double x4 = gsl_vector_get(x, 3);
double x5 = gsl_vector_get(x, 4);
size_t i;
for (i = 0; i < osborne_N; ++i)
{
double ti = 10.0*i;
double term1 = exp(-x4*ti);
double term2 = exp(-x5*ti);
gsl_matrix_set(J, i, 0, -1.0);
gsl_matrix_set(J, i, 1, -term1);
gsl_matrix_set(J, i, 2, -term2);
gsl_matrix_set(J, i, 3, ti*x2*term1);
gsl_matrix_set(J, i, 4, ti*x3*term2);
}
(void)params; /* avoid unused parameter warning */
return GSL_SUCCESS;
}
static int
osborne_fvv (const gsl_vector * x, const gsl_vector * v,
void *params, gsl_vector * fvv)
{
double x2 = gsl_vector_get(x, 1);
double x3 = gsl_vector_get(x, 2);
double x4 = gsl_vector_get(x, 3);
double x5 = gsl_vector_get(x, 4);
double v2 = gsl_vector_get(v, 1);
double v3 = gsl_vector_get(v, 2);
double v4 = gsl_vector_get(v, 3);
double v5 = gsl_vector_get(v, 4);
size_t i;
for (i = 0; i < osborne_N; ++i)
{
double ti = 10.0*i;
double term1 = exp(-x4*ti);
double term2 = exp(-x5*ti);
double term3 = -2*v2 + ti*v4*x2;
double term4 = -2*v3 + ti*v5*x3;
gsl_vector_set(fvv, i, -term1 * term2 * ti *
(v4 / term2 * term3 + v5 / term1 * term4));
}
(void)params; /* avoid unused parameter warning */
return GSL_SUCCESS;
}
static gsl_multifit_nlinear_fdf osborne_func =
{
osborne_f,
osborne_df,
osborne_fvv,
osborne_N,
osborne_P,
NULL,
0,
0,
0
};
static test_fdf_problem osborne_problem =
{
"osborne",
osborne_x0,
NULL,
NULL,
&osborne_epsrel,
&osborne_checksol,
&osborne_func
};