static void SplineData_Destroy(SplineData *splinedata) { if(!splinedata) return; if(splinedata->bwx) gsl_bspline_free(splinedata->bwx); if(splinedata->bwy) gsl_bspline_free(splinedata->bwy); XLALFree(splinedata); }
gsl_bspline_workspace * gsl_bspline_alloc(const size_t k, const size_t nbreak) { if (k == 0) { GSL_ERROR_NULL("k must be at least 1", GSL_EINVAL); } else if (nbreak < 2) { GSL_ERROR_NULL("nbreak must be at least 2", GSL_EINVAL); } else { gsl_bspline_workspace *w; w = (gsl_bspline_workspace *) calloc(1, sizeof(gsl_bspline_workspace)); if (w == 0) { GSL_ERROR_NULL("failed to allocate space for workspace", GSL_ENOMEM); } w->k = k; w->km1 = k - 1; w->nbreak = nbreak; w->l = nbreak - 1; w->n = w->l + k - 1; w->knots = gsl_vector_alloc(w->n + k); if (w->knots == 0) { gsl_bspline_free(w); GSL_ERROR_NULL("failed to allocate space for knots vector", GSL_ENOMEM); } w->deltal = gsl_vector_alloc(k); w->deltar = gsl_vector_alloc(k); if (!w->deltal || !w->deltar) { gsl_bspline_free(w); GSL_ERROR_NULL("failed to allocate space for delta vectors", GSL_ENOMEM); } w->B = gsl_vector_alloc(k); if (w->B == 0) { gsl_bspline_free(w); GSL_ERROR_NULL("failed to allocate space for temporary spline vector", GSL_ENOMEM); } return (w); } } /* gsl_bspline_alloc() */
int main (int argc, char **argv) { int status = 0; 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_knots_uniform (a, b, bw); test_bspline (bw); 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_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); gsl_vector_free (k); gsl_bspline_free (bw); } } exit (gsl_test_summary ()); }
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() */
TransformationModelBSpline::~TransformationModelBSpline() { gsl_bspline_free(workspace_); gsl_vector_free(bsplines_); gsl_vector_free(coeffs_); gsl_matrix_free(cov_); gsl_vector_free(x_); gsl_vector_free(y_); gsl_vector_free(w_); }
int gsl_bspline(double *x, int *n, int *degree, int *nbreak, double *x_min, double *x_max, double *quantile_vector, int *knots_int, double *Bx) { int k = *degree + 1; /* k in gsl */ int ncoeffs; int i, j; gsl_bspline_workspace *bw = gsl_bspline_alloc(k, *nbreak); ncoeffs = (int)gsl_bspline_ncoeffs(bw); /* *nbreak+k-2 */ gsl_vector *B = gsl_vector_alloc(ncoeffs); 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_eval(x[i], B, bw); /* fill in row i of Bx */ for (j = 0; j < ncoeffs; ++j) { double Bj = gsl_vector_get(B, j); Bx[i*ncoeffs+j] = Bj; /* Bx:*n-by-(*nbreak+*degree-1) */ } } gsl_bspline_free(bw); gsl_vector_free(B); gsl_vector_free(quantile_vec); return(0); } /* main() */
int main (void) { const size_t n = N; const size_t ncoeffs = NCOEFFS; const size_t nbreak = NBREAK; size_t i, j; gsl_bspline_workspace *bw; gsl_vector *B; double dy; gsl_rng *r; gsl_vector *c, *w; gsl_vector *x, *y; gsl_matrix *X, *cov; gsl_multifit_linear_workspace *mw; double chisq; double Rsq; double dof; gsl_rng_env_setup(); r = gsl_rng_alloc(gsl_rng_default); /* allocate a cubic bspline workspace (k = 4) */ bw = gsl_bspline_alloc(4, nbreak); B = gsl_vector_alloc(ncoeffs); x = gsl_vector_alloc(n); y = gsl_vector_alloc(n); X = gsl_matrix_alloc(n, ncoeffs); c = gsl_vector_alloc(ncoeffs); w = gsl_vector_alloc(n); cov = gsl_matrix_alloc(ncoeffs, ncoeffs); mw = gsl_multifit_linear_alloc(n, ncoeffs); printf("#m=0,S=0\n"); /* this is the data to be fitted */ for (i = 0; i < n; ++i) { double sigma; double xi = (15.0 / (N - 1)) * i; double yi = cos(xi) * exp(-0.1 * xi); sigma = 0.1 * yi; dy = gsl_ran_gaussian(r, sigma); yi += dy; gsl_vector_set(x, i, xi); gsl_vector_set(y, i, yi); gsl_vector_set(w, i, 1.0 / (sigma * sigma)); printf("%f %f\n", xi, yi); } /* use uniform breakpoints on [0, 15] */ gsl_bspline_knots_uniform(0.0, 15.0, bw); /* construct the fit matrix X */ for (i = 0; i < n; ++i) { double xi = gsl_vector_get(x, i); /* compute B_j(xi) for all j */ gsl_bspline_eval(xi, B, bw); /* fill in row i of X */ for (j = 0; j < ncoeffs; ++j) { double Bj = gsl_vector_get(B, j); gsl_matrix_set(X, i, j, Bj); } } /* do the fit */ gsl_multifit_wlinear(X, w, y, c, cov, &chisq, mw); dof = n - ncoeffs; Rsq = 1.0 - chisq / gsl_stats_wtss(w->data, 1, y->data, 1, y->size); fprintf(stderr, "chisq/dof = %e, Rsq = %f\n", chisq / dof, Rsq); /* output the smoothed curve */ { double xi, yi, yerr; printf("#m=1,S=0\n"); for (xi = 0.0; xi < 15.0; xi += 0.1) { gsl_bspline_eval(xi, B, bw); gsl_multifit_linear_est(B, c, cov, &yi, &yerr); printf("%f %f\n", xi, yi); } } gsl_rng_free(r); gsl_bspline_free(bw); gsl_vector_free(B); gsl_vector_free(x); gsl_vector_free(y); gsl_matrix_free(X); gsl_vector_free(c); gsl_vector_free(w); gsl_matrix_free(cov); gsl_multifit_linear_free(mw); return 0; } /* main() */
/** Executes the algorithm * */ void SplineBackground::exec() { API::MatrixWorkspace_sptr inWS = getProperty("InputWorkspace"); int spec = getProperty("WorkspaceIndex"); if (spec > static_cast<int>(inWS->getNumberHistograms())) throw std::out_of_range("WorkspaceIndex is out of range."); const MantidVec& X = inWS->readX(spec); const MantidVec& Y = inWS->readY(spec); const MantidVec& E = inWS->readE(spec); const bool isHistogram = inWS->isHistogramData(); const int ncoeffs = getProperty("NCoeff"); const int k = 4; // order of the spline + 1 (cubic) const int nbreak = ncoeffs - (k - 2); if (nbreak <= 0) throw std::out_of_range("Too low NCoeff"); gsl_bspline_workspace *bw; gsl_vector *B; gsl_vector *c, *w, *x, *y; gsl_matrix *Z, *cov; gsl_multifit_linear_workspace *mw; double chisq; int n = static_cast<int>(Y.size()); bool isMasked = inWS->hasMaskedBins(spec); std::vector<int> masked(Y.size()); if (isMasked) { for(API::MatrixWorkspace::MaskList::const_iterator it=inWS->maskedBins(spec).begin();it!=inWS->maskedBins(spec).end();++it) masked[it->first] = 1; n -= static_cast<int>(inWS->maskedBins(spec).size()); } if (n < ncoeffs) { g_log.error("Too many basis functions (NCoeff)"); throw std::out_of_range("Too many basis functions (NCoeff)"); } /* allocate a cubic bspline workspace (k = 4) */ bw = gsl_bspline_alloc(k, nbreak); B = gsl_vector_alloc(ncoeffs); x = gsl_vector_alloc(n); y = gsl_vector_alloc(n); Z = gsl_matrix_alloc(n, ncoeffs); c = gsl_vector_alloc(ncoeffs); w = gsl_vector_alloc(n); cov = gsl_matrix_alloc(ncoeffs, ncoeffs); mw = gsl_multifit_linear_alloc(n, ncoeffs); /* this is the data to be fitted */ int j = 0; for (MantidVec::size_type i = 0; i < Y.size(); ++i) { if (isMasked && masked[i]) continue; gsl_vector_set(x, j, (isHistogram ? (0.5*(X[i]+X[i+1])) : X[i])); // Middle of the bins, if a histogram gsl_vector_set(y, j, Y[i]); gsl_vector_set(w, j, E[i]>0.?1./(E[i]*E[i]):0.); ++j; } if (n != j) { gsl_bspline_free(bw); gsl_vector_free(B); gsl_vector_free(x); gsl_vector_free(y); gsl_matrix_free(Z); gsl_vector_free(c); gsl_vector_free(w); gsl_matrix_free(cov); gsl_multifit_linear_free(mw); throw std::runtime_error("Assertion failed: n != j"); } double xStart = X.front(); double xEnd = X.back(); /* use uniform breakpoints */ gsl_bspline_knots_uniform(xStart, xEnd, bw); /* construct the fit matrix X */ for (int i = 0; i < n; ++i) { double xi=gsl_vector_get(x, i); /* compute B_j(xi) for all j */ gsl_bspline_eval(xi, B, bw); /* fill in row i of X */ for (j = 0; j < ncoeffs; ++j) { double Bj = gsl_vector_get(B, j); gsl_matrix_set(Z, i, j, Bj); } } /* do the fit */ gsl_multifit_wlinear(Z, w, y, c, cov, &chisq, mw); /* output the smoothed curve */ API::MatrixWorkspace_sptr outWS = WorkspaceFactory::Instance().create(inWS,1,X.size(),Y.size()); { outWS->getAxis(1)->setValue(0, inWS->getAxis(1)->spectraNo(spec)); double xi, yi, yerr; for (MantidVec::size_type i=0;i<Y.size();i++) { xi = X[i]; gsl_bspline_eval(xi, B, bw); gsl_multifit_linear_est(B, c, cov, &yi, &yerr); outWS->dataY(0)[i] = yi; outWS->dataE(0)[i] = yerr; } outWS->dataX(0) = X; } gsl_bspline_free(bw); gsl_vector_free(B); gsl_vector_free(x); gsl_vector_free(y); gsl_matrix_free(Z); gsl_vector_free(c); gsl_vector_free(w); gsl_matrix_free(cov); gsl_multifit_linear_free(mw); setProperty("OutputWorkspace",outWS); }
// [[Rcpp::export]] Rcpp::List fitData(Rcpp::DataFrame ds) { const size_t ncoeffs = NCOEFFS; const size_t nbreak = NBREAK; const size_t n = N; size_t i, j; Rcpp::DataFrame D(ds); // construct the data.frame object RcppGSL::vector<double> y = D["y"]; // access columns by name, RcppGSL::vector<double> x = D["x"]; // assigning to GSL vectors RcppGSL::vector<double> w = D["w"]; gsl_bspline_workspace *bw; gsl_vector *B; gsl_vector *c; gsl_matrix *X, *cov; gsl_multifit_linear_workspace *mw; double chisq, Rsq, dof, tss; bw = gsl_bspline_alloc(4, nbreak); // allocate a cubic bspline workspace (k = 4) B = gsl_vector_alloc(ncoeffs); X = gsl_matrix_alloc(n, ncoeffs); c = gsl_vector_alloc(ncoeffs); cov = gsl_matrix_alloc(ncoeffs, ncoeffs); mw = gsl_multifit_linear_alloc(n, ncoeffs); gsl_bspline_knots_uniform(0.0, 15.0, bw); // use uniform breakpoints on [0, 15] for (i = 0; i < n; ++i) { // construct the fit matrix X double xi = gsl_vector_get(x, i); gsl_bspline_eval(xi, B, bw); // compute B_j(xi) for all j for (j = 0; j < ncoeffs; ++j) { // fill in row i of X double Bj = gsl_vector_get(B, j); gsl_matrix_set(X, i, j, Bj); } } gsl_multifit_wlinear(X, w, y, c, cov, &chisq, mw); // do the fit dof = n - ncoeffs; tss = gsl_stats_wtss(w->data, 1, y->data, 1, y->size); Rsq = 1.0 - chisq / tss; Rcpp::NumericVector FX(151), FY(151); // output the smoothed curve double xi, yi, yerr; for (xi = 0.0, i=0; xi < 15.0; xi += 0.1, i++) { gsl_bspline_eval(xi, B, bw); gsl_multifit_linear_est(B, c, cov, &yi, &yerr); FX[i] = xi; FY[i] = yi; } Rcpp::List res = Rcpp::List::create(Rcpp::Named("X")=FX, Rcpp::Named("Y")=FY, Rcpp::Named("chisqdof")=Rcpp::wrap(chisq/dof), Rcpp::Named("rsq")=Rcpp::wrap(Rsq)); gsl_bspline_free(bw); gsl_vector_free(B); gsl_matrix_free(X); gsl_vector_free(c); gsl_matrix_free(cov); gsl_multifit_linear_free(mw); y.free(); x.free(); w.free(); return(res); }
void bSplineGSLOriginalDemo () { const size_t n = N; const size_t ncoeffs = NCOEFFS; const size_t nbreak = NBREAK; size_t i, j; gsl_bspline_workspace *bw; gsl_vector *B; double dy; gsl_rng *r; gsl_vector *c, *w; gsl_vector *x, *y; gsl_matrix *X, *cov; gsl_multifit_linear_workspace *mw; double chisq, Rsq, dof, tss; vector<double> xControl, yControl, xFit, yFit; gsl_rng_env_setup(); r = gsl_rng_alloc(gsl_rng_default); /* allocate a cubic bspline workspace (k = 4) */ bw = gsl_bspline_alloc(4, nbreak); B = gsl_vector_alloc(ncoeffs); x = gsl_vector_alloc(n); y = gsl_vector_alloc(n); X = gsl_matrix_alloc(n, ncoeffs); c = gsl_vector_alloc(ncoeffs); w = gsl_vector_alloc(n); cov = gsl_matrix_alloc(ncoeffs, ncoeffs); mw = gsl_multifit_linear_alloc(n, ncoeffs); printf("#m=0,S=0\n"); /* this is the data to be fitted */ for (i = 0; i < n; ++i) { double sigma; double xi = (15.0 / (N - 1)) * i; double yi = cos(xi) * exp(-0.1 * xi); sigma = 0.1 * yi; dy = gsl_ran_gaussian(r, sigma); yi += dy; gsl_vector_set(x, i, xi); xControl.push_back(xi); gsl_vector_set(y, i, yi); yControl.push_back(yi); gsl_vector_set(w, i, 1.0 / (sigma * sigma)); printf("%f %f\n", xi, yi); } /* use uniform breakpoints on [0, 15] */ gsl_bspline_knots_uniform(0.0, 15.0, bw); /* construct the fit matrix X */ for (i = 0; i < n; ++i) { double xi = gsl_vector_get(x, i); /* compute B_j(xi) for all j */ gsl_bspline_eval(xi, B, bw); /* fill in row i of X */ for (j = 0; j < ncoeffs; ++j) { double Bj = gsl_vector_get(B, j); gsl_matrix_set(X, i, j, Bj); } } /* do the fit */ gsl_multifit_wlinear(X, w, y, c, cov, &chisq, mw); dof = n - ncoeffs; tss = gsl_stats_wtss(w->data, 1, y->data, 1, y->size); Rsq = 1.0 - chisq / tss; fprintf(stderr, "chisq/dof = %e, Rsq = %f\n", chisq / dof, Rsq); /* output the smoothed curve */ { double xi, yi, yerr; printf("#m=1,S=0\n"); for (xi = 0.0; xi < 15.0; xi += 0.1) { gsl_bspline_eval(xi, B, bw); gsl_multifit_linear_est(B, c, cov, &yi, &yerr); xFit.push_back(xi); yFit.push_back(yi); printf("%f %f\n", xi, yi); } } gsl_rng_free(r); gsl_bspline_free(bw); gsl_vector_free(B); gsl_vector_free(x); gsl_vector_free(y); gsl_matrix_free(X); gsl_vector_free(c); gsl_vector_free(w); gsl_matrix_free(cov); gsl_multifit_linear_free(mw); TGraph *gr = LoadGraphFromVectors(xControl, yControl); TGraph *grFit = LoadGraphFromVectors(xFit, yFit); gr->SetMarkerColor(kRed); TCanvas *c1 = new TCanvas("c1", "Graph", 200, 10, 700, 500); gr->Draw("apz"); grFit->Draw("SAME"); c1->Update(); }
//spline locations held fixed in Mpc^-1; CMB basically fixed P(k) in these units void dopksmoothbspline_(double *kvals, double *lnpklinear, double *lnpksmooth, int *npts) { double kmaxsuppress = 0.01*0.7; size_t n, ncoeffs, nbreak; gsl_bspline_workspace *bw; gsl_vector *B; gsl_vector *c, *w, *x, *y; gsl_matrix *X, *cov; gsl_multifit_linear_workspace *mw; double deltak,lastk; int i,j,countkeep; nbreak = 9; gsl_vector *mybreaks = gsl_vector_alloc(nbreak); gsl_vector_set(mybreaks,0,(0.001*0.7)); gsl_vector_set(mybreaks,1,(0.025*0.7)); gsl_vector_set(mybreaks,2,(0.075*0.7)); gsl_vector_set(mybreaks,3,(0.125*0.7)); gsl_vector_set(mybreaks,4,(0.175*0.7)); gsl_vector_set(mybreaks,5,(0.225*0.7)); gsl_vector_set(mybreaks,6,(0.275*0.7)); gsl_vector_set(mybreaks,7,(0.325*0.7)); gsl_vector_set(mybreaks,8,(0.375*0.7)); countkeep = 0; for(i=0;i<(*npts);i++) { if((kvals[i]) >= gsl_vector_get(mybreaks,0) && (kvals[i]) <= gsl_vector_get(mybreaks,nbreak-1)) { countkeep += 1; } } n = countkeep; ncoeffs = nbreak + 2; /* allocate a cubic bspline workspace (k = 4) */ bw = gsl_bspline_alloc(4, nbreak); B = gsl_vector_alloc(ncoeffs); x = gsl_vector_alloc(n); y = gsl_vector_alloc(n); X = gsl_matrix_alloc(n, ncoeffs); c = gsl_vector_alloc(ncoeffs); w = gsl_vector_alloc(n); cov = gsl_matrix_alloc(ncoeffs, ncoeffs); mw = gsl_multifit_linear_alloc(n, ncoeffs); i=0; for(j=0;j<(*npts);j++) { if((kvals[j]) >= gsl_vector_get(mybreaks,0) && (kvals[j]) <= gsl_vector_get(mybreaks,nbreak-1)) { gsl_vector_set(x,i,(kvals[j])); gsl_vector_set(y,i,exp(lnpklinear[j])*pow(kvals[j],1.5)); if(j>0) { deltak = kvals[j] - kvals[j-1]; } else { deltak = kvals[0]; if(kvals[1] - kvals[0] < deltak) { deltak = kvals[1]-kvals[0]; } } gsl_vector_set(w,i,deltak); i+=1; } } gsl_bspline_knots(mybreaks,bw); for(i=0;i<n;i++) { double xi = gsl_vector_get(x,i); gsl_bspline_eval(xi,B,bw); for(j=0;j<ncoeffs;j++) { double Bj = gsl_vector_get(B,j); gsl_matrix_set(X,i,j,Bj); } } //do fit double yi,yierr,chisq; gsl_multifit_wlinear(X,w,y,c,cov,&chisq,mw); i = 0; for(j=0;j<(*npts);j++) { if((kvals[j]) >= gsl_vector_get(mybreaks,0) && (kvals[j]) <= gsl_vector_get(mybreaks,nbreak-1)) { gsl_bspline_eval(gsl_vector_get(x,i),B,bw); gsl_multifit_linear_est(B,c,cov,&yi,&yierr); lnpksmooth[j] = log(yi*pow(kvals[j],-1.5)); i += 1; } else { lnpksmooth[j] = lnpklinear[j]; } //spline is wacky at small k -- suppress difference at k < 0.01 if(kvals[j] < kmaxsuppress) { lnpksmooth[j] = lnpklinear[j]; } } assert(i==n); gsl_bspline_free(bw); gsl_vector_free(B); gsl_vector_free(x); gsl_vector_free(y); gsl_vector_free(mybreaks); gsl_matrix_free(X); gsl_vector_free(c); gsl_vector_free(w); gsl_matrix_free(cov); gsl_multifit_linear_free(mw); }
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()); }