/* cspline Cubic spline fitting and interpolation Tim Behrens, FMRIB Image Analysis Group Copyright (C) 1999-2000 University of Oxford */ /* CCOPYRIGHT */ #include #include #include #include "newmatap.h" #include "newmatio.h" #include "miscmaths.h" #include "cspline.h" #define WANT_STREAM #define WANT_MATH using namespace NEWMAT; using namespace std; /////////////////////////////////////////////////////// namespace MISCMATHS{ // void Cspline::Cspline(){} void Cspline::set(ColumnVector& pnodes,ColumnVector& pvals){ nodes=pnodes;vals=pvals; fitted=false; n=vals.Nrows(); } void Cspline::set(ColumnVector& pnodes, Matrix& pcoefs){ nodes=pnodes;coefs=pcoefs; fitted=false; n=vals.Nrows(); } void Cspline::diff(const ColumnVector& x, ColumnVector& dx ){ // dx should be of length length(x)-1 dx.ReSize(x.Nrows()-1); for(int i=2;i<=x.Nrows();i++){ dx(i-1)=x(i)-x(i-1); } } void Cspline::fit(){ if(vals.Nrows()<4){ cerr<<"Cspline::fit - You have less than 4 data pts for spline fitting."<nodes(nodes.Nrows())){ ind=nodes.Nrows()-1; } else{ for(int i=1;ixx) ){ ind=i; stop=true; } } } } float a=coefs(ind,1); float b=coefs(ind,2); float c=coefs(ind,3); float d=coefs(ind,4); float t=xx-nodes(ind); ret=a+b*t+c*t*t+d*t*t*t; } return ret; } float Cspline::interpolate(float xx, int ind) const{ float ret; if(!fitted){ cerr<<"Cspline::interpolate - Cspline has not been fitted"<n-1){ cerr<<"Cspline::interpolate - segment index is greater than number of segments - exiting"<=nodes(nodes.Nrows())){ ind=nodes.Nrows()-1; } else{ for(int i=1;ixx) ){ ind=i; stop=true; } } } } float a=coefs(ind,1); float b=coefs(ind,2); float c=coefs(ind,3); float d=coefs(ind,4); float t=xx-nodes(ind); ret(xnum)=a+b*t+c*t*t+d*t*t*t; } } return ret; } ColumnVector Cspline::interpolate(const ColumnVector& x,const ColumnVector& indvec) const{ // nodes must be monotonically increasing. I don't check this. // On your head be it if you don't. if(nodes.Nrows()!=vals.Nrows()){ cerr<<"Cspline::interpolate - Nodes and Vals should be the same length"<