|
Packit |
67cb25 |
#define wnlin_N 40
|
|
Packit |
67cb25 |
#define wnlin_P 3
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* initial guess should be chosen so that Jacobian has full rank,
|
|
Packit |
67cb25 |
* or some solvers will fail */
|
|
Packit |
67cb25 |
static double wnlin_x0[wnlin_P] = { 1.0, 0.9, 0.0 };
|
|
Packit |
67cb25 |
static double wnlin_epsrel = 1.0e-7;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
static int wnlin_internal_weight = 1;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* data */
|
|
Packit |
67cb25 |
static double wnlin_Y[wnlin_N] = {
|
|
Packit |
67cb25 |
6.08035e+00, 5.47552e+00, 5.94654e+00, 5.04920e+00, 4.78568e+00,
|
|
Packit |
67cb25 |
3.51748e+00, 2.84671e+00, 3.24634e+00, 3.23395e+00, 3.30385e+00,
|
|
Packit |
67cb25 |
2.83439e+00, 2.31891e+00, 2.33858e+00, 2.40559e+00, 2.41856e+00,
|
|
Packit |
67cb25 |
1.99966e+00, 1.88127e+00, 1.91477e+00, 1.70415e+00, 1.60316e+00,
|
|
Packit |
67cb25 |
1.77937e+00, 1.55302e+00, 1.50903e+00, 1.36364e+00, 1.36873e+00,
|
|
Packit |
67cb25 |
1.41954e+00, 1.37778e+00, 1.23573e+00, 1.28524e+00, 1.46327e+00,
|
|
Packit |
67cb25 |
1.22315e+00, 1.19330e+00, 1.18717e+00, 8.83172e-01, 1.23424e+00,
|
|
Packit |
67cb25 |
1.14683e+00, 1.11091e+00, 1.20396e+00, 1.28722e+00, 1.05801e+00
|
|
Packit |
67cb25 |
};
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* weights */
|
|
Packit |
67cb25 |
static double wnlin_W[wnlin_N] = {
|
|
Packit |
67cb25 |
2.77778e+00, 3.27690e+00, 3.85426e+00, 4.51906e+00, 5.28083e+00,
|
|
Packit |
67cb25 |
6.14919e+00, 7.13370e+00, 8.24349e+00, 9.48703e+00, 1.08717e+01,
|
|
Packit |
67cb25 |
1.24036e+01, 1.40869e+01, 1.59238e+01, 1.79142e+01, 2.00553e+01,
|
|
Packit |
67cb25 |
2.23415e+01, 2.47646e+01, 2.73137e+01, 2.99753e+01, 3.27337e+01,
|
|
Packit |
67cb25 |
3.55714e+01, 3.84696e+01, 4.14085e+01, 4.43678e+01, 4.73278e+01,
|
|
Packit |
67cb25 |
5.02690e+01, 5.31731e+01, 5.60234e+01, 5.88046e+01, 6.15036e+01,
|
|
Packit |
67cb25 |
6.41092e+01, 6.66121e+01, 6.90054e+01, 7.12839e+01, 7.34442e+01,
|
|
Packit |
67cb25 |
7.54848e+01, 7.74053e+01, 7.92069e+01, 8.08918e+01, 8.24632e+01
|
|
Packit |
67cb25 |
};
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
static void
|
|
Packit |
67cb25 |
wnlin_checksol(const double x[], const double sumsq,
|
|
Packit |
67cb25 |
const double epsrel, const char *sname,
|
|
Packit |
67cb25 |
const char *pname)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
size_t i;
|
|
Packit |
67cb25 |
const double sumsq_exact = 29.7481259665713758;
|
|
Packit |
67cb25 |
const double wnlin_x[wnlin_P] = { 5.17378551196259195,
|
|
Packit |
67cb25 |
0.111041758006851149,
|
|
Packit |
67cb25 |
1.05282724070446099 };
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_test_rel(sumsq, sumsq_exact, epsrel, "%s/%s sumsq",
|
|
Packit |
67cb25 |
sname, pname);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
for (i = 0; i < wnlin_P; ++i)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
gsl_test_rel(x[i], wnlin_x[i], epsrel, "%s/%s i=%zu",
|
|
Packit |
67cb25 |
sname, pname, i);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
static int
|
|
Packit |
67cb25 |
wnlin_f (const gsl_vector *x, void *params, gsl_vector *f)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
int *iptr = (int *) params;
|
|
Packit |
67cb25 |
int doweight = iptr ? *iptr : 0;
|
|
Packit |
67cb25 |
double A = gsl_vector_get (x, 0);
|
|
Packit |
67cb25 |
double lambda = gsl_vector_get (x, 1);
|
|
Packit |
67cb25 |
double b = gsl_vector_get (x, 2);
|
|
Packit |
67cb25 |
size_t i;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* model Yi = A * exp(-lambda * i) + b */
|
|
Packit |
67cb25 |
for (i = 0; i < wnlin_N; i++)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
double ti = i;
|
|
Packit |
67cb25 |
double yi = wnlin_Y[i];
|
|
Packit |
67cb25 |
double swi = sqrt(wnlin_W[i]);
|
|
Packit |
67cb25 |
double Mi = A * exp (-lambda * ti) + b;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (doweight)
|
|
Packit |
67cb25 |
gsl_vector_set (f, i, swi * (Mi - yi));
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
gsl_vector_set (f, i, Mi - yi);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
return GSL_SUCCESS;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
static int
|
|
Packit |
67cb25 |
wnlin_df (const gsl_vector *x, void *params, gsl_matrix *df)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
int *iptr = (int *) params;
|
|
Packit |
67cb25 |
int doweight = iptr ? *iptr : 0;
|
|
Packit |
67cb25 |
double A = gsl_vector_get (x, 0);
|
|
Packit |
67cb25 |
double lambda = gsl_vector_get (x, 1);
|
|
Packit |
67cb25 |
size_t i;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
for (i = 0; i < wnlin_N; i++)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
gsl_vector_view v = gsl_matrix_row(df, i);
|
|
Packit |
67cb25 |
double ti = i;
|
|
Packit |
67cb25 |
double swi = sqrt(wnlin_W[i]);
|
|
Packit |
67cb25 |
double e = exp(-lambda * ti);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_vector_set(&v.vector, 0, e);
|
|
Packit |
67cb25 |
gsl_vector_set(&v.vector, 1, -ti * A * e);
|
|
Packit |
67cb25 |
gsl_vector_set(&v.vector, 2, 1.0);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (doweight)
|
|
Packit |
67cb25 |
gsl_vector_scale(&v.vector, swi);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
return GSL_SUCCESS;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
static int
|
|
Packit |
67cb25 |
wnlin_fvv (const gsl_vector * x, const gsl_vector * v,
|
|
Packit |
67cb25 |
void *params, gsl_vector * fvv)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
int *iptr = (int *) params;
|
|
Packit |
67cb25 |
int doweight = iptr ? *iptr : 0;
|
|
Packit |
67cb25 |
double A = gsl_vector_get (x, 0);
|
|
Packit |
67cb25 |
double lambda = gsl_vector_get (x, 1);
|
|
Packit |
67cb25 |
double v1 = gsl_vector_get(v, 0);
|
|
Packit |
67cb25 |
double v2 = gsl_vector_get(v, 1);
|
|
Packit |
67cb25 |
size_t i;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
for (i = 0; i < wnlin_N; i++)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
double ti = i;
|
|
Packit |
67cb25 |
double swi = sqrt(wnlin_W[i]);
|
|
Packit |
67cb25 |
double fvvi;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
fvvi = exp(-ti*lambda)*ti*v2 * (-2*v1 + ti*v2*A);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (doweight)
|
|
Packit |
67cb25 |
gsl_vector_set(fvv, i, swi * fvvi);
|
|
Packit |
67cb25 |
else
|
|
Packit |
67cb25 |
gsl_vector_set(fvv, i, fvvi);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
return GSL_SUCCESS;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
static gsl_multifit_nlinear_fdf wnlin_func1 =
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
wnlin_f,
|
|
Packit |
67cb25 |
wnlin_df,
|
|
Packit |
67cb25 |
wnlin_fvv,
|
|
Packit |
67cb25 |
wnlin_N,
|
|
Packit |
67cb25 |
wnlin_P,
|
|
Packit |
67cb25 |
(void *) &wnlin_internal_weight,
|
|
Packit |
67cb25 |
0,
|
|
Packit |
67cb25 |
0,
|
|
Packit |
67cb25 |
0
|
|
Packit |
67cb25 |
};
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
static gsl_multifit_nlinear_fdf wnlin_func2 =
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
wnlin_f,
|
|
Packit |
67cb25 |
wnlin_df,
|
|
Packit |
67cb25 |
wnlin_fvv,
|
|
Packit |
67cb25 |
wnlin_N,
|
|
Packit |
67cb25 |
wnlin_P,
|
|
Packit |
67cb25 |
NULL,
|
|
Packit |
67cb25 |
0,
|
|
Packit |
67cb25 |
0,
|
|
Packit |
67cb25 |
0
|
|
Packit |
67cb25 |
};
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
static test_fdf_problem wnlin_problem1 =
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
"wnlin_internal_weights",
|
|
Packit |
67cb25 |
wnlin_x0,
|
|
Packit |
67cb25 |
NULL,
|
|
Packit |
67cb25 |
NULL,
|
|
Packit |
67cb25 |
&wnlin_epsrel,
|
|
Packit |
67cb25 |
&wnlin_checksol,
|
|
Packit |
67cb25 |
&wnlin_func1
|
|
Packit |
67cb25 |
};
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
static test_fdf_problem wnlin_problem2 =
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
"wnlin_external_weights",
|
|
Packit |
67cb25 |
wnlin_x0,
|
|
Packit |
67cb25 |
wnlin_W,
|
|
Packit |
67cb25 |
NULL,
|
|
Packit |
67cb25 |
&wnlin_epsrel,
|
|
Packit |
67cb25 |
&wnlin_checksol,
|
|
Packit |
67cb25 |
&wnlin_func2
|
|
Packit |
67cb25 |
};
|