test.c

来自「math library from gnu」· C语言 代码 · 共 272 行

C
272
字号
/* bspline/test.c * * Copyright (C) 2006, 2007 Brian Gough * Copyright (C) 2008 Rhys Ulerich * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */#include <config.h>#include <gsl/gsl_test.h>#include <gsl/gsl_errno.h>#include <gsl/gsl_bspline.h>#include <gsl/gsl_ieee_utils.h>#include <gsl/gsl_nan.h>voidtest_bspline(gsl_bspline_workspace * bw, gsl_bspline_deriv_workspace * dbw){  gsl_vector *B;  gsl_matrix *dB;  size_t i, j;  size_t n = 100;  size_t ncoeffs = gsl_bspline_ncoeffs(bw);  size_t order = gsl_bspline_order(bw);  size_t nbreak = gsl_bspline_nbreak(bw);  double a = gsl_bspline_breakpoint(0, bw);  double b = gsl_bspline_breakpoint(nbreak - 1, bw);  B  = gsl_vector_alloc(ncoeffs);  dB = gsl_matrix_alloc(ncoeffs, 1);  /* Ensure B-splines form a partition of unity */  for (i = 0; i < n; i++)    {      double xi = a + (b - a) * (i / (n - 1.0));      double sum = 0;      gsl_bspline_eval(xi, B, bw);      for (j = 0; j < ncoeffs; j++)        {          double Bj = gsl_vector_get(B, j);          int s = (Bj < 0 || Bj > 1);          gsl_test(s,                   "basis-spline coefficient %u is in range [0,1] for x=%g",                   j, xi);          sum += Bj;        }      gsl_test_rel(sum, 1.0, order * GSL_DBL_EPSILON,                   "basis-spline order %u is normalized for x=%g", order,                   xi);    }  /* Ensure B-splines 0th derivatives agree with regular evaluation */  for (i = 0; i < n; i++)    {      double xi = a + (b - a) * (i / (n - 1.0));      gsl_bspline_eval(xi, B, bw);      gsl_bspline_deriv_eval(xi, 0, dB, bw, dbw);      for (j = 0; j < ncoeffs; j++)        {          gsl_test_abs(gsl_matrix_get(dB, j, 0), gsl_vector_get(B, j),                       GSL_DBL_EPSILON,                       "b-spline order %d basis #%d evaluation and 0th derivative consistent for x=%g",                       order, j, xi);        }    }  gsl_vector_free(B);  gsl_matrix_free(dB);}intmain(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);  }  exit(gsl_test_summary());}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?