00001 #include "basis_spline1d.h"
00002 #include <cmath>
00003
00004 #define BSPLINE_EPSILON 1e-12
00005
00006 using namespace std;
00007 using namespace TNT;
00008
00009
00010 bool CBasisSpline1d::Read(const parameterMap& m){
00011 bool success = CGenericSpline1d::Read(m);
00012 Array1D<double> new_splco(ndata,0.);
00013 _splco = new_splco;
00014 return success;
00015 }
00016
00021 double CBasisSpline1d::getValue(double x) const{
00022 if ( (x<knots[0]) || (x>knots[knots.dim()-1]) ) return 0.0;
00023 if (std::abs(x-knots[0])<BSPLINE_EPSILON) x+=BSPLINE_EPSILON;
00024 if (std::abs(x-knots[knots.dim()-1])<BSPLINE_EPSILON) x-=BSPLINE_EPSILON;
00025 return get_bvalue(data,x,0);
00026 }
00027
00034 double CBasisSpline1d::basisFunction(double x, int i, int jderiv) const{
00035
00036 if ((i<0) || (i>=ndata)) return 0.0;
00037
00038 if ((x < knots[i]) || (x > knots[i+spline_degree+1])) return 0.0;
00039
00040 const_cast<CBasisSpline1d*>(this)->_splco[i]=1.0;
00041
00042 if (std::abs(x-knots[0])<BSPLINE_EPSILON) x+=BSPLINE_EPSILON;
00043 if (std::abs(x-knots[spline_degree-1])<BSPLINE_EPSILON) x-=BSPLINE_EPSILON;
00044 double ans=get_bvalue(_splco,x,jderiv);
00045
00046 const_cast<CBasisSpline1d*>(this)->_splco[i]=0.0;
00047 return ans;
00048 }
00049
00050
00051
00095 double CBasisSpline1d::get_bvalue(const Array1D<double>& bcoef, double x, int jderiv) const
00096 {
00097 int i,ilo,imk,j,jc,jcmin,jcmax,jj,kmj,km1,nmi,jdrvp1;
00098 const int kmax = 20;
00099 int n = ndata;
00100 int k = spline_degree+1;
00101 Array1D<double> aj(kmax,0.0),dl(kmax,0.0),dr(kmax,0.0);
00102 double fkmj;
00103 double bvalue = 0.;
00104 if (jderiv >= k) return bvalue;
00105
00106
00107
00108
00109
00110
00111 i=getKnotToLeft(x)+1;
00112 if ( (i < 0)||(i > n+k) ) return bvalue;
00113 if ( (knots[i-1]>x)||(x>=knots[i]) ) return bvalue;
00114
00115
00116 km1 = spline_degree;
00117 if (spline_degree < 0) {bvalue = bcoef[i-1]; return bvalue;}
00118
00119
00120
00121
00122
00123
00124
00125
00126 jcmin = 1;
00127 imk = i - k;
00128 if (imk >= 0) {
00129 for(j=1;j<=km1;j++){dl[j-1] = x - knots[i-j];}
00130 } else {
00131 jcmin = 1 - imk;
00132 for(j=1;j<=i;j++){dl[j-1] = x - knots[i-j];}
00133 for (j=i;j<=km1;j++){
00134 aj[k-j-1] = 0.;
00135 dl[j-1] = dl[i-1];
00136 }
00137 }
00138
00139 jcmax = k;
00140 nmi = n - i;
00141 if (nmi >= 0){
00142 for (j=1;j<=km1;j++){dr[j-1] = knots[i+j-1] - x;}
00143 } else {
00144 jcmax = k + nmi;
00145 for (j=1;j<=jcmax;j++){dr[j-1] = knots[i+j-1] - x;}
00146 for (j=jcmax;j<=km1;j++){
00147 aj[j] = 0.;
00148 dr[j-1] = dr[jcmax-1];
00149 }
00150 }
00151
00152 for( jc=jcmin;jc<=jcmax;jc++){aj[jc-1] = bcoef[imk + jc-1];}
00153
00154
00155 if (jderiv != 0) {
00156 for (j=1;j<=jderiv;j++){
00157 kmj = k-j;
00158 fkmj = static_cast<double>(kmj);
00159 ilo = kmj;
00160 for(jj=1;jj<=kmj;jj++) {
00161 aj[jj-1] = ((aj[jj] - aj[jj-1])/(dl[ilo-1] + dr[jj-1]))*fkmj;
00162 ilo = ilo - 1;
00163 }
00164 }
00165 }
00166
00167
00168
00169
00170 if (jderiv != km1) {
00171 jdrvp1 = jderiv + 1;
00172 for (j=jdrvp1;j<=km1;j++){
00173 kmj = k-j;
00174 ilo = kmj;
00175 for (jj=1;jj<=kmj;jj++){
00176 aj[jj-1]=(aj[jj]*dl[ilo-1]+aj[jj-1]*dr[jj-1])/
00177 (dl[ilo-1]+dr[jj-1]);
00178 ilo = ilo - 1;
00179 }
00180 }
00181 }
00182 bvalue = aj[0];
00183
00184 return bvalue;
00185 }
00186
00188 bool CBasisSpline1d::setDim(int ncoeffs){
00189 Array1D<double> new_splco(ncoeffs,0.);
00190 _splco = new_splco;
00191 return CGenericSpline1d::setDim(ncoeffs);
00192 }