예제 #1
0
 void TransformationModelBSpline::computeLinear_(
   const double pos, double & slope, double & offset, double & sd_err)
 {
   gsl_bspline_deriv_workspace * deriv_workspace = gsl_bspline_deriv_alloc(4);
   gsl_matrix * deriv = gsl_matrix_alloc(ncoeffs_, 2);
   gsl_bspline_deriv_eval(pos, 1, deriv, workspace_, deriv_workspace);
   gsl_bspline_deriv_free(deriv_workspace);
   double results[2];
   for (size_t j = 0; j < 2; ++j)
   {
     for (size_t i = 0; i < ncoeffs_; ++i)
     {
       gsl_vector_set(bsplines_, i, gsl_matrix_get(deriv, i, j));
     }
     gsl_multifit_linear_est(bsplines_, coeffs_, cov_, &results[j], &sd_err);
     // TODO: find a good way to estimate the error
     // e.g. by reducing "num_breakpoints" and comparing to current?!
     if (sd_err >= 1)
     {
       // this SD seems on a much smaller scale than "yerr" in "evaluate"...
       // see GSL's "multilinear.c::gsl_multifit_linear_est" for details
       LOG_WARN << "Warning: B-spline extrapolation is unreliable. Consider reducing 'num_breakpoints' or using another model." << endl;
     }
   }
   gsl_matrix_free(deriv);
   offset = results[0];
   slope = results[1];
 }
예제 #2
0
int gsl_bspline_deriv(double *x,
                      int *n,
                      int *degree,
                      int *nbreak,
                      int *order,
											int *order_max, 
                      double *x_min,
                      double *x_max,
                      double *quantile_vector,
                      int *knots_int,
                      double *Bx)
{

  int k = *degree + 1; /* k in gsl */
  int ncoeffs;
  size_t i, j;

  gsl_bspline_workspace *bw = gsl_bspline_alloc(k, *nbreak);
  ncoeffs = (int)gsl_bspline_ncoeffs(bw);
  gsl_vector *dBorder = gsl_vector_alloc(ncoeffs);
  gsl_bspline_deriv_workspace *derivWS = gsl_bspline_deriv_alloc(k);
	gsl_matrix *dB = gsl_matrix_alloc(ncoeffs, *order_max+1);

	gsl_vector *quantile_vec = gsl_vector_alloc(*nbreak);

	/* 7/12/10 added support for quantile knots */

	if(*knots_int == 0) {
			gsl_bspline_knots_uniform(*x_min, *x_max, bw);
	} else {
			for(i = 0; i < *nbreak; i++) gsl_vector_set(quantile_vec, i, quantile_vector[i]);
			gsl_bspline_knots(quantile_vec, bw);
	}

	for (i = 0; i < *n; ++i)
	{

			/* compute B_j(xi) for all j */
			gsl_bspline_deriv_eval(x[i], order[i], dB, bw, derivWS);

			/* fill in row i of Bx */
			gsl_matrix_get_col(dBorder, dB, order[i]);

			for (j = 0; j < ncoeffs; ++j)
			{
					double Bj = gsl_vector_get(dBorder, j);
					Bx[i*ncoeffs+j] = Bj;
			}
	}

	gsl_bspline_free(bw);
	gsl_vector_free(dBorder);
	gsl_matrix_free(dB);
	/*  gsl_vector_free(quantile_vec);*/
	gsl_bspline_deriv_free(derivWS);

	return(0);

} /* main() */
예제 #3
0
파일: test.c 프로젝트: lemahdi/mglib
int
main(int argc, char **argv)
{
  size_t order, breakpoints, i;

  gsl_ieee_env_setup();

  argc = 0;                     /* prevent warnings about unused parameters */
  argv = 0;

  for (order = 1; order < 10; order++)
    {
      for (breakpoints = 2; breakpoints < 100; breakpoints++)
        {
          double a = -1.23 * order, b = 45.6 * order;
          gsl_bspline_workspace *bw = gsl_bspline_alloc(order, breakpoints);
          gsl_bspline_deriv_workspace *dbw = gsl_bspline_deriv_alloc(order);
          gsl_bspline_knots_uniform(a, b, bw);
          test_bspline(bw, dbw);
          gsl_bspline_deriv_free(dbw);
          gsl_bspline_free(bw);
        }
    }


  for (order = 1; order < 10; order++)
    {
      for (breakpoints = 2; breakpoints < 100; breakpoints++)
        {
          double a = -1.23 * order, b = 45.6 * order;
          gsl_bspline_workspace *bw = gsl_bspline_alloc(order, breakpoints);
          gsl_bspline_deriv_workspace *dbw = gsl_bspline_deriv_alloc(order);
          gsl_vector *k = gsl_vector_alloc(breakpoints);
          for (i = 0; i < breakpoints; i++)
            {
              double f, x;
              f = sqrt(i / (breakpoints - 1.0));
              x = (1 - f) * a + f * b;
              gsl_vector_set(k, i, x);
            };
          gsl_bspline_knots(k, bw);
          test_bspline(bw, dbw);
          gsl_vector_free(k);
          gsl_bspline_deriv_free(dbw);
          gsl_bspline_free(bw);
        }
    }

  /* Spot check known 0th, 1st, 2nd derivative
     evaluations for a particular k = 2 case.  */
  {
    size_t i, j; /* looping */

    const double xloc[4]     =  { 0.0,  1.0,  6.0,  7.0};
    const double deriv[4][3] =
    {
      { -1.0/2.0,  1.0/2.0, 0.0     },
      { -1.0/2.0,  1.0/2.0, 0.0     },
      {      0.0, -1.0/5.0, 1.0/5.0 },
      {      0.0, -1.0/5.0, 1.0/5.0 }
    };

    gsl_bspline_workspace *bw = gsl_bspline_alloc(2, 3);
    gsl_bspline_deriv_workspace *dbw = gsl_bspline_deriv_alloc(2);
    gsl_matrix *dB = gsl_matrix_alloc(gsl_bspline_ncoeffs(bw),
                                      gsl_bspline_order(bw) + 1);

    gsl_vector *breakpts = gsl_vector_alloc(3);
    gsl_vector_set(breakpts, 0, 0.0);
    gsl_vector_set(breakpts, 1, 2.0);
    gsl_vector_set(breakpts, 2, 7.0);
    gsl_bspline_knots(breakpts, bw);


    for (i = 0; i < 4; ++i)  /* at each location */
      {
        /* Initialize dB with poison to ensure we overwrite it */
        gsl_matrix_set_all(dB, GSL_NAN);

        gsl_bspline_deriv_eval(xloc[i], gsl_bspline_order(bw), dB, bw, dbw);
        for (j = 0; j < gsl_bspline_ncoeffs(bw) ; ++j)
          {
            /* check basis function 1st deriv */
            gsl_test_abs(gsl_matrix_get(dB, j, 1), deriv[i][j], GSL_DBL_EPSILON,
                         "b-spline k=%d basis #%d derivative %d at x = %f",
                         gsl_bspline_order(bw), j, 1, xloc[i]);
          }
        for (j = 0; j < gsl_bspline_ncoeffs(bw); ++j)
          {
            /* check k order basis function has k-th deriv equal to 0 */
            gsl_test_abs(gsl_matrix_get(dB, j, gsl_bspline_order(bw)), 0.0,
                         GSL_DBL_EPSILON,
                         "b-spline k=%d basis #%d derivative %d at x = %f",
                         gsl_bspline_order(bw), j, gsl_bspline_order(bw),
                         xloc[i]);
          }
      }

    gsl_matrix_free(dB);
    gsl_bspline_deriv_free(dbw);
    gsl_bspline_free(bw);
    gsl_vector_free(breakpts);
  }

  /* Spot check known 0th, 1st, 2nd derivative
     evaluations for a particular k = 3 case.  */
  {
    size_t i, j; /* looping */
    const double xloc[5]     =  { 0.0, 5.0, 9.0, 12.0, 15.0 };
    const double eval[5][6]  =
    {
      { 4./25.,  69./100.,   3./ 20. ,  0.    , 0.   , 0.    },
      { 0.     ,  4./21. , 143./210. ,  9./70., 0.   , 0.    },
      { 0.     ,  0.     ,   3./ 10. ,  7./10., 0.   , 0.    },
      { 0.     ,  0.     ,   0.      ,  3./4. , 1./4., 0.    },
      { 0.     ,  0.     ,   0.      ,  1./3. , 5./9., 1./9. }
    };
    const double deriv[5][6] =
    {
      { -4./25.,  3./50.,   1./ 10.,  0.    , 0.    , 0.      },
      {  0.    , -2./21.,   1./105.,  3./35., 0.    , 0.      },
      {  0.    ,  0.    ,  -1./5.  ,  1./ 5., 0.    , 0.      },
      {  0.    ,  0.    ,   0.     , -1./ 6., 1./6. , 0.      },
      {  0.    ,  0.    ,   0.     , -1./ 9., 1./27., 2./27. }
    };
    const double deriv2[5][6] =
    {
      { 2./25., -17./150.,   1.0/30.0 ,  0.0     ,  0.     , 0.     },
      { 0.    ,   1./ 42., -11.0/210.0,  1.0/35.0,  0.     , 0.     },
      { 0.    ,   0.     ,   1.0/15.0 ,-11.0/90.0,  1./18. , 0.     },
      { 0.    ,   0.     ,   0.0      ,  1.0/54.0, -7./162., 2./81. },
      { 0.    ,   0.     ,   0.0      ,  1.0/54.0, -7./162., 2./81. }
    };

    gsl_bspline_workspace *bw = gsl_bspline_alloc(3, 5);
    gsl_bspline_deriv_workspace *dbw = gsl_bspline_deriv_alloc(3);

    gsl_matrix *dB = gsl_matrix_alloc(gsl_bspline_ncoeffs(bw),
                                      gsl_bspline_order(bw) + 1);

    gsl_vector *breakpts = gsl_vector_alloc(5);
    gsl_vector_set(breakpts, 0, -3.0);
    gsl_vector_set(breakpts, 1,  2.0);
    gsl_vector_set(breakpts, 2,  9.0);
    gsl_vector_set(breakpts, 3, 12.0);
    gsl_vector_set(breakpts, 4, 21.0);
    gsl_bspline_knots(breakpts, bw);

    for (i = 0; i < 5; ++i)  /* at each location */
      {
        /* Initialize dB with poison to ensure we overwrite it */
        gsl_matrix_set_all(dB, GSL_NAN);
        gsl_bspline_deriv_eval(xloc[i], gsl_bspline_order(bw), dB, bw, dbw);

        /* check basis function evaluation */
        for (j = 0; j < gsl_bspline_ncoeffs(bw); ++j)
          {
            gsl_test_abs(gsl_matrix_get(dB, j, 0), eval[i][j], GSL_DBL_EPSILON,
                         "b-spline k=%d basis #%d derivative %d at x = %f",
                         gsl_bspline_order(bw), j, 0, xloc[i]);
          }
        /* check 1st derivative evaluation */
        for (j = 0; j < gsl_bspline_ncoeffs(bw); ++j)
          {
            gsl_test_abs(gsl_matrix_get(dB, j, 1), deriv[i][j], GSL_DBL_EPSILON,
                         "b-spline k=%d basis #%d derivative %d at x = %f",
                         gsl_bspline_order(bw), j, 1, xloc[i]);
          }
        /* check 2nd derivative evaluation */
        for (j = 0; j < gsl_bspline_ncoeffs(bw); ++j)
          {
            gsl_test_abs(gsl_matrix_get(dB, j, 2), deriv2[i][j], GSL_DBL_EPSILON,
                         "b-spline k=%d basis #%d derivative %d at x = %f",
                         gsl_bspline_order(bw), j, 2, xloc[i]);
          }
      }

    gsl_matrix_free(dB);
    gsl_bspline_deriv_free(dbw);
    gsl_bspline_free(bw);
    gsl_vector_free(breakpts);
  }

  /* Check Greville abscissae functionality on a non-uniform k=1 */
  {
    size_t i; /* looping */

    /* Test parameters */
    const size_t k = 1;
    const double bpoint_data[]    = { 0.0, 0.2, 0.5, 0.75, 1.0 };
    const size_t nbreak           = sizeof(bpoint_data)/sizeof(bpoint_data[0]);

    /* Expected results */
    const double abscissae_data[] = { 0.1, 0.35, 0.625, 0.875 };
    const size_t nabscissae       = sizeof(abscissae_data)/sizeof(abscissae_data[0]);

    gsl_vector_const_view bpoints = gsl_vector_const_view_array(bpoint_data, nbreak);
    gsl_bspline_workspace *w = gsl_bspline_alloc(k, nbreak);
    gsl_bspline_knots((const gsl_vector *) &bpoints, w);

    gsl_test_int(nabscissae, gsl_bspline_ncoeffs(w),
        "b-spline k=%d number of abscissae", k);
    for (i = 0; i < nabscissae; ++i)
      {
        gsl_test_abs(gsl_bspline_greville_abscissa(i, w), abscissae_data[i], 2*k*GSL_DBL_EPSILON,
            "b-spline k=%d Greville abscissa #%d at x = %f", k, i, abscissae_data[i]);
      }

    gsl_bspline_free(w);
  }

  /* Check Greville abscissae functionality on a non-uniform k=2 */
  {
    size_t i; /* looping */

    /* Test parameters */
    const size_t k = 2;
    const double bpoint_data[]    = { 0.0, 0.2, 0.5, 0.75, 1.0 };
    const size_t nbreak           = sizeof(bpoint_data)/sizeof(bpoint_data[0]);

    /* Expected results */
    const double abscissae_data[] = { 0.0, 0.2, 0.5, 0.75, 1.0 };
    const size_t nabscissae       = sizeof(abscissae_data)/sizeof(abscissae_data[0]);

    gsl_vector_const_view bpoints = gsl_vector_const_view_array(bpoint_data, nbreak);
    gsl_bspline_workspace *w = gsl_bspline_alloc(k, nbreak);
    gsl_bspline_knots((const gsl_vector *) &bpoints, w);

    gsl_test_int(nabscissae, gsl_bspline_ncoeffs(w),
        "b-spline k=%d number of abscissae", k);
    for (i = 0; i < nabscissae; ++i)
      {
        gsl_test_abs(gsl_bspline_greville_abscissa(i, w), abscissae_data[i], 2*k*GSL_DBL_EPSILON,
            "b-spline k=%d Greville abscissa #%d at x = %f", k, i, abscissae_data[i]);
      }

    gsl_bspline_free(w);
  }

  /* Check Greville abscissae functionality on non-uniform k=3 */
  {
    size_t i; /* looping */

    /* Test parameters */
    const size_t k = 3;
    const double bpoint_data[]    = { 0.0, 0.2, 0.5, 0.75, 1.0 };
    const size_t nbreak           = sizeof(bpoint_data)/sizeof(bpoint_data[0]);

    /* Expected results */
    const double abscissae_data[] = {      0.0, 1.0/10.0, 7.0/20.0,
                                      5.0/ 8.0, 7.0/ 8.0,      1.0 };
    const size_t nabscissae       = sizeof(abscissae_data)/sizeof(abscissae_data[0]);

    gsl_vector_const_view bpoints = gsl_vector_const_view_array(bpoint_data, nbreak);
    gsl_bspline_workspace *w = gsl_bspline_alloc(k, nbreak);
    gsl_bspline_knots((const gsl_vector *) &bpoints, w);

    gsl_test_int(nabscissae, gsl_bspline_ncoeffs(w),
        "b-spline k=%d number of abscissae", k);
    for (i = 0; i < nabscissae; ++i)
      {
        gsl_test_abs(gsl_bspline_greville_abscissa(i, w), abscissae_data[i], 2*k*GSL_DBL_EPSILON,
            "b-spline k=%d Greville abscissa #%d at x = %f", k, i, abscissae_data[i]);
      }

    gsl_bspline_free(w);
  }

  /* Check Greville abscissae functionality on non-uniform k=4 */
  {
    size_t i; /* looping */

    /* Test parameters */
    const size_t k = 4;
    const double bpoint_data[]    = { 0.0, 0.2, 0.5, 0.75, 1.0 };
    const size_t nbreak           = sizeof(bpoint_data)/sizeof(bpoint_data[0]);

    /* Expected results */
    const double abscissae_data[] = { 0.0,  1.0/15.0,  7.0/30.0,  29.0/60.0,
                                            3.0/ 4.0, 11.0/12.0,        1.0 };
    const size_t nabscissae       = sizeof(abscissae_data)/sizeof(abscissae_data[0]);

    gsl_vector_const_view bpoints = gsl_vector_const_view_array(bpoint_data, nbreak);
    gsl_bspline_workspace *w = gsl_bspline_alloc(k, nbreak);
    gsl_bspline_knots((const gsl_vector *) &bpoints, w);

    gsl_test_int(nabscissae, gsl_bspline_ncoeffs(w),
        "b-spline k=%d number of abscissae", k);
    for (i = 0; i < nabscissae; ++i)
      {
        gsl_test_abs(gsl_bspline_greville_abscissa(i, w), abscissae_data[i], 2*k*GSL_DBL_EPSILON,
            "b-spline k=%d Greville abscissa #%d at x = %f", k, i, abscissae_data[i]);
      }

    gsl_bspline_free(w);
  }

  exit(gsl_test_summary());
}