1 #include "NumericalApproximation.h" 
   16   NumericalApproximation::FunctorList NumericalApproximation::p_interpFunctors;
 
   39       p_dataValidated = 
false;
 
   43                        "NumericalApproximation() - Unable to construct NumericalApproximation object",
 
   81   NumericalApproximation::NumericalApproximation(
unsigned int n, 
double *x, 
double *y,
 
   90                        "NumericalApproximation() - Unable to construct object using the given arrays, size and interpolation type",
 
  125   NumericalApproximation::NumericalApproximation(
const vector <double> &x, 
const vector <double> &y,
 
  134                        "NumericalApproximation() - Unable to construct an object using the given vectors and interpolation type",
 
  185                        "NumericalApproximation() - Unable to copy the given object",
 
  216       if(&oldObject != 
this) {
 
  217         if(GslInterpType(p_itype)) GslDeallocation();
 
  218         SetInterpType(oldObject.
p_itype);
 
  234                        "operator=() - Unable to copy the given object",
 
  250   NumericalApproximation::~NumericalApproximation() {
 
  251     if(GslInterpType(p_itype)) GslDeallocation();
 
  276   string NumericalApproximation::Name()
 const {
 
  277     if(p_itype == NumericalApproximation::CubicNeighborhood) {
 
  278       return "cspline-neighborhood";
 
  280     else if(p_itype == NumericalApproximation::CubicClamped) {
 
  281       return "cspline-clamped";
 
  283     else if(p_itype == NumericalApproximation::PolynomialNeville) {
 
  284       return "polynomial-Neville's";
 
  286     else if(p_itype == NumericalApproximation::CubicHermite) {
 
  287       return "cspline-Hermite";
 
  290       string name = (string(GslFunctor(p_itype)->name));
 
  291       if(p_itype == NumericalApproximation::CubicNatural) {
 
  292         return name + 
"-natural";
 
  299                        "Name() - GSL interpolation type not found",
 
  327   int NumericalApproximation::MinPoints() {
 
  328     if(p_itype == NumericalApproximation::CubicNeighborhood) {
 
  331     else if(p_itype == NumericalApproximation::CubicClamped) {
 
  334     else if(p_itype == NumericalApproximation::PolynomialNeville) {
 
  337     else if(p_itype == NumericalApproximation::CubicHermite) {
 
  341       return (GslFunctor(p_itype)->min_size);
 
  346                        "MinPoints() - GSL interpolation not found",
 
  380     if(GslInterpType(itype)) {
 
  389                          "MinPoints() - GSL interpolation type not found",
 
  393     else if(itype == NumericalApproximation::CubicNeighborhood) {
 
  396     else if(itype == NumericalApproximation::CubicClamped) {
 
  399     else if(itype == NumericalApproximation::PolynomialNeville) {
 
  402     else if(itype == NumericalApproximation::CubicHermite) {
 
  406                      "MinPoints() - Invalid argument. Unknown interpolation type: " 
  434   void NumericalApproximation::AddData(
const double x, 
const double y) {
 
  437     p_clampedComputed = 
false;
 
  438     p_clampedEndptsSet = 
false;
 
  439     p_dataValidated = 
false;
 
  440     p_clampedSecondDerivs.clear();
 
  441     p_clampedDerivFirstPt = 0;
 
  442     p_clampedDerivLastPt = 0;
 
  443     p_polyNevError.clear();
 
  467   void NumericalApproximation::AddData(
unsigned int n, 
double *x, 
double *y) {
 
  468     for(
unsigned int i = 0; i < n; i++) {
 
  472     p_clampedComputed = 
false;
 
  473     p_clampedEndptsSet = 
false;
 
  474     p_dataValidated = 
false;
 
  475     p_clampedSecondDerivs.clear();
 
  476     p_clampedDerivFirstPt = 0;
 
  477     p_clampedDerivLastPt = 0;
 
  478     p_polyNevError.clear();
 
  506   void NumericalApproximation::AddData(
const vector <double> &x,
 
  507                                        const vector <double> &y)
 
  512       ReportException(IException::Programmer, 
"AddData()",
 
  513                       "Invalid arguments. The sizes of the input vectors do " 
  520     if(!p_x.empty() || !p_y.empty()) {
 
  521       for(
int i = 0; i < n; i++) {
 
  531     p_clampedComputed = 
false;
 
  532     p_clampedEndptsSet = 
false;
 
  533     p_dataValidated = 
false;
 
  534     p_clampedSecondDerivs.clear();
 
  535     p_clampedDerivFirstPt = 0;
 
  536     p_clampedDerivLastPt = 0;
 
  537     p_polyNevError.clear();
 
  559   void NumericalApproximation::SetCubicClampedEndptDeriv(
double yp1, 
double ypn) {
 
  560     if(p_itype != NumericalApproximation::CubicClamped) {
 
  561       ReportException(IException::Programmer, 
"SetCubicClampedEndptDeriv()",
 
  562                       "This method is only valid for cspline-clamped interpolation, may not be used for " 
  563                       + Name() + 
" interpolation",
 
  566     p_clampedDerivFirstPt = yp1;
 
  567     p_clampedDerivLastPt = ypn;
 
  568     p_clampedEndptsSet = 
true;
 
  586   void NumericalApproximation::AddCubicHermiteDeriv(
unsigned int n, 
double *fprimeOfx) {
 
  587     if(p_itype != NumericalApproximation::CubicHermite) {
 
  588       ReportException(IException::Programmer, 
"SetCubicHermiteDeriv()",
 
  589                       "This method is only valid for cspline-Hermite interpolation, may not be used for " 
  590                       + Name() + 
" interpolation",
 
  593     for(
unsigned int i = 0; i < n; i++) {
 
  594       p_fprimeOfx.push_back(fprimeOfx[i]);
 
  611   void NumericalApproximation::AddCubicHermiteDeriv(
 
  612       const vector <double> &fprimeOfx) {
 
  613     if(p_itype != NumericalApproximation::CubicHermite) {
 
  614       ReportException(IException::Programmer, 
"SetCubicHermiteDeriv()",
 
  615                       "This method is only valid for cspline-Hermite interpolation, may not be used for " 
  616                       + Name() + 
" interpolation",
 
  621     if(!p_fprimeOfx.empty()) {
 
  622       for(
unsigned int i = 0; i < fprimeOfx.size(); i++) {
 
  623         p_fprimeOfx.push_back(fprimeOfx[i]);
 
  627       p_fprimeOfx = fprimeOfx;
 
  645   void NumericalApproximation::AddCubicHermiteDeriv(
 
  647     if(p_itype != NumericalApproximation::CubicHermite) {
 
  648       ReportException(IException::Programmer, 
"SetCubicHermiteDeriv()",
 
  649                       "This method is only valid for cspline-Hermite interpolation, may not be used for " 
  650                       + Name() + 
" interpolation",
 
  653     p_fprimeOfx.push_back(fprimeOfx);
 
  681   vector <double> NumericalApproximation::CubicClampedSecondDerivatives() {
 
  683       if(p_itype != NumericalApproximation::CubicClamped)
 
  684         ReportException(IException::Programmer, 
"CubicClampedSecondDerivatives()",
 
  685                         "This method is only valid for cspline-clamped interpolation type may not be used for " 
  686                         + Name() + 
" interpolation",
 
  688       if(!p_clampedComputed) ComputeCubicClamped();
 
  689       return p_clampedSecondDerivs;
 
  694                        "CubicClampedSecondDerivatives() - Unable to compute clamped cubic spline interpolation",
 
  717   double NumericalApproximation::DomainMinimum() {
 
  719       if(GslInterpType(p_itype)) {
 
  721         if(!GslComputed()) ComputeGsl();
 
  722         return (p_interp->interp->xmin);
 
  725         if(!p_dataValidated) ValidateDataSet();
 
  726         return *min_element(p_x.begin(), p_x.end());
 
  732                        "DomainMinimum() - Unable to calculate the domain minimum for the data set",
 
  754   double NumericalApproximation::DomainMaximum() {
 
  756       if(GslInterpType(p_itype)) {
 
  758         if(!GslComputed()) ComputeGsl();
 
  759         return (p_interp->interp->xmax);
 
  762         if(!p_dataValidated) ValidateDataSet();
 
  763         return *max_element(p_x.begin(), p_x.end());
 
  769                        "DomainMaximum() - Unable to calculate the domain maximum for the data set",
 
  787   bool NumericalApproximation::Contains(
double x) {
 
  788     return binary_search(p_x.begin(), p_x.end(), x);
 
  830   double NumericalApproximation::Evaluate(
const double a, 
const ExtrapType &etype) {
 
  836       else a0 = ValueToExtrapolate(a, etype);
 
  838       if(p_itype == NumericalApproximation::CubicNeighborhood) {
 
  839         return EvaluateCubicNeighborhood(a0);
 
  841       else if(p_itype == NumericalApproximation::PolynomialNeville) {
 
  842         p_polyNevError.clear();
 
  843         return EvaluatePolynomialNeville(a0);
 
  845       else if(p_itype == NumericalApproximation::CubicClamped) {
 
  847         if(!p_clampedComputed) ComputeCubicClamped();
 
  848         return EvaluateCubicClamped(a0);
 
  850       else if(p_itype == NumericalApproximation::CubicHermite) {
 
  851         return EvaluateCubicHermite(a0);
 
  854       if(!GslComputed()) ComputeGsl();
 
  856       GslIntegrityCheck(gsl_spline_eval_e(p_interp, a0, p_acc, &result), 
_FILEINFO_);
 
  862                        "Evaluate() - Unable to evaluate the function at the point a = " 
  906   vector <double> NumericalApproximation::Evaluate(
const vector <double> &a, 
const ExtrapType &etype) {
 
  908       if(p_itype == NumericalApproximation::CubicNeighborhood) {
 
  912         return EvaluateCubicNeighborhood(a, etype);
 
  914       vector <double> result(a.size());
 
  915       if(p_itype == NumericalApproximation::PolynomialNeville) {
 
  918         p_polyNevError.clear();
 
  919         for(
unsigned int i = 0; i < result.size(); i++) {
 
  921           if(InsideDomain(a[i]))
 
  923           else a0 = ValueToExtrapolate(a[i], etype);
 
  924           result[i] = EvaluatePolynomialNeville(a0);
 
  930       for(
unsigned int i = 0; i < result.size(); i++) {
 
  931         result[i] = Evaluate(a[i], etype);
 
  938                        "Evaluate() - Unable to evaluate the function at the given vector of points",
 
  964   vector <double> NumericalApproximation::PolynomialNevilleErrorEstimate() {
 
  965     if(p_itype != NumericalApproximation::PolynomialNeville) {
 
  966       ReportException(IException::Programmer, 
"PolynomialNevilleErrorEstimate()",
 
  967                       "This method is only valid for polynomial-Neville's, may not be used for " 
  968                       + Name() + 
" interpolation",
 
  971     if(p_polyNevError.empty()) {
 
  972       ReportException(IException::Programmer, 
"PolynomialNevilleErrorEstimate()",
 
  973                       "Error not calculated. This method only valid after Evaluate() has been called",
 
  976     return p_polyNevError;
 
 1014   double NumericalApproximation::GslFirstDerivative(
const double a) {
 
 1016       if(!GslComputed()) ComputeGsl();
 
 1021                        "GslFirstDerivative() - Unable to compute the first derivative at a = " 
 1022                        + 
IString(a) + 
" using the GSL interpolation",
 
 1025     if(!InsideDomain(a)) {
 
 1026       ReportException(IException::Programmer, 
"GslFirstDerivative()",
 
 1027                       "Invalid argument. Value entered, a = " 
 1028                       + 
IString(a) + 
", is outside of domain = [" 
 1029                       + 
IString(DomainMinimum()) + 
", " 
 1030                       + 
IString(DomainMaximum()) + 
"]",
 
 1033     if(!GslInterpType(p_itype)) {
 
 1034       ReportException(IException::Programmer, 
"GslFirstDerivative()",
 
 1035                       "Method only valid for GSL interpolation types, may not be used for " 
 1036                       + Name() + 
" interpolation",
 
 1041       GslIntegrityCheck(gsl_spline_eval_deriv_e(p_interp, a, p_acc, &value), 
_FILEINFO_);
 
 1047                        "GslFirstDerivative() - Unable to compute the first derivative at a = " 
 1048                        + 
IString(a) + 
". GSL integrity check failed",
 
 1065   double NumericalApproximation::EvaluateCubicHermiteFirstDeriv(
const double a) {
 
 1066     if(p_itype != NumericalApproximation::CubicHermite) { 
 
 1067       ReportException(IException::User, 
"EvaluateCubicHermiteFirstDeriv()",
 
 1068                       "This method is only valid for cspline-Hermite interpolation, may not be used for " 
 1069                       + Name() + 
" interpolation",
 
 1072     if(p_fprimeOfx.size() != Size()) {
 
 1073       ReportException(IException::User, 
"EvaluateCubicHermiteFirstDeriv()",
 
 1074                       "Invalid arguments. The size of the first derivative vector does not match the number of (x,y) data points.",
 
 1078     int lowerIndex = FindIntervalLowerIndex(a);
 
 1082     if(a == p_x[lowerIndex]) {
 
 1083       return p_fprimeOfx[lowerIndex];
 
 1085     if(a == p_x[lowerIndex+1]) {
 
 1086       return p_fprimeOfx[lowerIndex+1];
 
 1089     double x0, x1, y0, y1, m0, m1;
 
 1091     x0 = p_x[lowerIndex];
 
 1092     x1 = p_x[lowerIndex+1];
 
 1094     y0 = p_y[lowerIndex];
 
 1095     y1 = p_y[lowerIndex+1];
 
 1097     m0 = p_fprimeOfx[lowerIndex];
 
 1098     m1 = p_fprimeOfx[lowerIndex+1];
 
 1104       return ((6 * t * t - 6 * t) * y0 + (3 * t * t - 4 * t + 1) * h * m0 + (-6 * t * t + 6 * t) * y1 + (3 * t * t - 2 * t) * h * m1) / h;
 
 1153   double NumericalApproximation::BackwardFirstDifference(
const double a, 
const unsigned int n, 
const double h) {
 
 1154     if(!InsideDomain(a)) {
 
 1155       ReportException(IException::Programmer, 
"BackwardFirstDifference()",
 
 1156                       "Invalid argument. Value entered, a = " 
 1157                       + 
IString(a) + 
", is outside of domain = [" 
 1158                       + 
IString(DomainMinimum()) + 
", " 
 1159                       + 
IString(DomainMaximum()) + 
"]",
 
 1162     if(!InsideDomain(a - (n - 1)*h)) {
 
 1163       ReportException(IException::Programmer, 
"BackwardFirstDifference()",
 
 1164                       "Formula steps outside of domain. For " 
 1165                       + 
IString((
int) n) + 
"-point backward difference, a-(n-1)h = " 
 1166                       + 
IString(a - (n - 1)*h) + 
" is smaller than domain min = " 
 1168                       + 
".  Try forward difference or use smaller value for h or n",
 
 1171     if(!p_dataValidated) ValidateDataSet();
 
 1175       for(
double i = 0; i < n; i++) {
 
 1176         xi = a + h * (i - (n - 1));
 
 1177         f.push_back(Evaluate(xi)); 
 
 1183                        "BackwardFirstDifference() - Unable to calculate backward first difference for (a, n, h) = (" 
 1189         return (-f[0] + f[1]) / h;              
 
 1191         return (3 * f[2] - 4 * f[1] + f[0]) / (2 * h); 
 
 1194                          "BackwardFirstDifference() - Invalid argument. There is no " 
 1195                          + 
IString((
int) n) + 
"-point backward difference formula in use",
 
 1242   double NumericalApproximation::ForwardFirstDifference(
const double a, 
const unsigned int n, 
const double h) {
 
 1243     if(!InsideDomain(a)) {
 
 1244       ReportException(IException::Programmer, 
"ForwardFirstDifference()",
 
 1245                       "Invalid argument. Value entered, a = " 
 1246                       + 
IString(a) + 
", is outside of domain = [" 
 1247                       + 
IString(DomainMinimum()) + 
", " 
 1248                       + 
IString(DomainMaximum()) + 
"]",
 
 1251     if(!InsideDomain(a + (n - 1)*h)) {
 
 1252       ReportException(IException::Programmer, 
"ForwardFirstDifference()",
 
 1253                       "Formula steps outside of domain. For " 
 1254                       + 
IString((
int) n) + 
"-point forward difference, a+(n-1)h = " 
 1255                       + 
IString(a + (n - 1)*h) + 
" is greater than domain max = " 
 1257                       + 
".  Try backward difference or use smaller value for h or n",
 
 1260     if(!p_dataValidated) ValidateDataSet();
 
 1264       for(
double i = 0; i < n; i++) {
 
 1266         f.push_back(Evaluate(xi));
 
 1272                        "ForwardFirstDifference() - Unable to calculate forward first difference for (a, n, h) = (" 
 1278         return (-f[0] + f[1]) / h;              
 
 1280         return (-3 * f[0] + 4 * f[1] - f[2]) / (2 * h); 
 
 1283                          "ForwardFirstDifference() - Invalid argument. There is no " 
 1284                          + 
IString((
int) n) + 
"-point forward difference formula in use",
 
 1332   double NumericalApproximation::CenterFirstDifference(
const double a, 
const unsigned int n, 
const double h) {
 
 1333     if(!InsideDomain(a)) {
 
 1334       ReportException(IException::Programmer, 
"CenterFirstDifference()",
 
 1335                       "Invalid argument. Value entered, a = " 
 1336                       + 
IString(a) + 
", is outside of domain = [" 
 1337                       + 
IString(DomainMinimum()) + 
", " 
 1338                       + 
IString(DomainMaximum()) + 
"]",
 
 1341     if(!InsideDomain(a + (n - 1)*h) || !InsideDomain(a - (n - 1)*h)) {
 
 1342       ReportException(IException::Programmer, 
"CenterFirstDifference()",
 
 1343                       "Formula steps outside of domain. For " 
 1344                       + 
IString((
int) n) + 
"-point center difference, a-(n-1)h = " 
 1345                       + 
IString(a - (n - 1)*h) + 
" or a+(n-1)h = " 
 1346                       + 
IString(a + (n - 1)*h) + 
" is out of domain = [" 
 1348                       + 
"].  Use smaller value for h or n",
 
 1351     if(!p_dataValidated) ValidateDataSet();
 
 1355       for(
double i = 0; i < n; i++) {
 
 1356         xi = a + h * (i - (n - 1) / 2);
 
 1357         f.push_back(Evaluate(xi));
 
 1363                        "CenterFirstDifference() - Unable to calculate center first difference for (a, n, h) = (" 
 1369         return (-f[0] + f[2]) / (2 * h);              
 
 1371         return (f[0] - 8 * f[1] + 8 * f[3] - f[4]) / (12 * h); 
 
 1374                          "CenterFirstDifference() - Invalid argument. There is no " 
 1375                          + 
IString((
int) n) + 
"-point center difference formula in use",
 
 1416   double NumericalApproximation::GslSecondDerivative(
const double a) {
 
 1418       if(!GslComputed()) ComputeGsl();
 
 1423                        "GslSecondDerivative() - Unable to compute the second derivative at a = " 
 1424                        + 
IString(a) + 
" using the GSL interpolation",
 
 1427     if(!InsideDomain(a))
 
 1428       ReportException(IException::Programmer, 
"GslSecondDerivative()",
 
 1429                       "Invalid argument. Value entered, a = " 
 1430                       + 
IString(a) + 
", is outside of domain = [" 
 1431                       + 
IString(DomainMinimum()) + 
", " 
 1432                       + 
IString(DomainMaximum()) + 
"]",
 
 1434     if(!GslInterpType(p_itype))
 
 1435       ReportException(IException::Programmer, 
"GslSecondDerivative()",
 
 1436                       "Method only valid for GSL interpolation types, may not be used for " 
 1437                       + Name() + 
" interpolation",
 
 1441       if(!GslComputed()) ComputeGsl();
 
 1443       GslIntegrityCheck(gsl_spline_eval_deriv2_e(p_interp, a, p_acc, &value), 
_FILEINFO_);
 
 1449                        "GslSecondDerivative() - Unable to compute the second derivative at a = " 
 1450                        + 
IString(a) + 
". GSL integrity check failed",
 
 1468   double NumericalApproximation::EvaluateCubicHermiteSecDeriv(
const double a) {
 
 1469     if(p_itype != NumericalApproximation::CubicHermite) {
 
 1470       ReportException(IException::User, 
"EvaluateCubicHermiteSecDeriv()",
 
 1471                       "This method is only valid for cspline-Hermite interpolation, may not be used for " 
 1472                       + Name() + 
" interpolation",
 
 1475     if(p_fprimeOfx.size() != Size()) {
 
 1476       ReportException(IException::User, 
"EvaluateCubicHermiteSecDeriv()",
 
 1477                       "Invalid arguments. The size of the first derivative vector does not match the number of (x,y) data points.",
 
 1481     int lowerIndex = FindIntervalLowerIndex(a);
 
 1482     double x0, x1, y0, y1, m0, m1;
 
 1484     x0 = p_x[lowerIndex];
 
 1485     x1 = p_x[lowerIndex+1];
 
 1487     y0 = p_y[lowerIndex];
 
 1488     y1 = p_y[lowerIndex+1];
 
 1490     m0 = p_fprimeOfx[lowerIndex];
 
 1491     m1 = p_fprimeOfx[lowerIndex+1];
 
 1497       return ((12 * t - 6) * y0 + (6 * t - 4) * h * m0 + (-12 * t + 6) * y1 + (6 * t - 2) * h * m1) / h;
 
 1540   double NumericalApproximation::BackwardSecondDifference(
const double a, 
const unsigned int n, 
const double h) {
 
 1541     if(!InsideDomain(a)) {
 
 1542       ReportException(IException::Programmer, 
"BackwardSecondDifference()",
 
 1543                       "Invalid argument. Value entered, a = " 
 1544                       + 
IString(a) + 
", is outside of domain = [" 
 1545                       + 
IString(DomainMinimum()) + 
", " 
 1546                       + 
IString(DomainMaximum()) + 
"]",
 
 1549     if(!InsideDomain(a - (n - 1)*h)) {
 
 1550       ReportException(IException::Programmer, 
"BackwardSecondDifference()",
 
 1551                       "Formula steps outside of domain. For " 
 1552                       + 
IString((
int) n) + 
"-point backward difference, a-(n-1)h = " 
 1553                       + 
IString(a - (n - 1)*h) + 
" is smaller than domain min = " 
 1555                       + 
".  Try forward difference or use smaller value for h or n",
 
 1558     if(!p_dataValidated) ValidateDataSet();
 
 1562       for(
double i = 0; i < n; i++) {
 
 1563         xi = a + h * (i - (n - 1));
 
 1564         f.push_back(Evaluate(xi));
 
 1570                        "BackwardSecondDifference() - Unable to calculate backward second difference for (a, n, h) = (" 
 1576         return (f[0] - 2 * f[1] + f[2]) / (h * h);                   
 
 1579                          "BackwardSecondDifference() - Invalid argument. There is no " 
 1580                          + 
IString((
int) n) + 
"-point backward second difference formula in use",
 
 1622   double NumericalApproximation::ForwardSecondDifference(
const double a, 
const unsigned int n, 
const double h) {
 
 1623     if(!InsideDomain(a)) {
 
 1624       ReportException(IException::Programmer, 
"ForwardSecondDifference()",
 
 1625                       "Invalid argument. Value entered, a = " 
 1626                       + 
IString(a) + 
", is outside of domain = [" 
 1627                       + 
IString(DomainMinimum()) + 
", " 
 1628                       + 
IString(DomainMaximum()) + 
"]",
 
 1631     if(!InsideDomain(a + (n - 1)*h)) {
 
 1632       ReportException(IException::Programmer, 
"ForwardSecondDifference()",
 
 1633                       "Formula steps outside of domain. For " 
 1634                       + 
IString((
int) n) + 
"-point forward difference, a+(n-1)h = " 
 1635                       + 
IString(a + (n - 1)*h) + 
" is greater than domain max = " 
 1637                       + 
".  Try backward difference or use smaller value for h or n",
 
 1640     if(!p_dataValidated) ValidateDataSet();
 
 1644       for(
double i = 0; i < n; i++) {
 
 1646         f.push_back(Evaluate(xi));
 
 1652                        "ForwardSecondDifference() - Unable to calculate forward second difference for (a, n, h) = (" 
 1658         return (f[0] - 2 * f[1] + f[2]) / (h * h);                   
 
 1661                          "ForwardSecondDifference() - Invalid argument. There is no " 
 1662                          + 
IString((
int) n) + 
"-point forward second difference formula in use",
 
 1710   double NumericalApproximation::CenterSecondDifference(
const double a, 
const unsigned int n, 
const double h) {
 
 1711     if(!InsideDomain(a)) {
 
 1712       ReportException(IException::Programmer, 
"CenterSecondDifference()",
 
 1713                       "Invalid argument. Value entered, a = " 
 1714                       + 
IString(a) + 
", is outside of domain = [" 
 1715                       + 
IString(DomainMinimum()) + 
", " 
 1716                       + 
IString(DomainMaximum()) + 
"]",
 
 1719     if(!InsideDomain(a + (n - 1)*h) || !InsideDomain(a - (n - 1)*h)) {
 
 1720       ReportException(IException::Programmer, 
"CenterSecondDifference()",
 
 1721                       "Formula steps outside of domain. For " 
 1722                       + 
IString((
int) n) + 
"-point center difference, a-(n-1)h = " 
 1723                       + 
IString(a - (n - 1)*h) + 
" or a+(n-1)h = " 
 1724                       + 
IString(a + (n - 1)*h) + 
" is out of domain = [" 
 1726                       + 
"].  Use smaller value for h or n",
 
 1729     if(!p_dataValidated) ValidateDataSet();
 
 1733       for(
double i = 0; i < n; i++) {
 
 1734         xi = a + h * (i - (n - 1) / 2);
 
 1735         f.push_back(Evaluate(xi));
 
 1741                        "CenterSecondDifference() - Unable to calculate center second difference for (a, n, h) = (" 
 1747         return (f[0] - 2 * f[1] + f[2]) / (h * h);                   
 
 1749         return (-f[0] + 16 * f[1] - 30 * f[2] + 16 * f[3] - f[4]) / (12 * h * h); 
 
 1752                          "CenterSecondDifference() - Invalid argument. There is no " 
 1753                          + 
IString((
int) n) + 
"-point center second difference formula in use",
 
 1791   double NumericalApproximation::GslIntegral(
const double a, 
const double b) {
 
 1793       if(!GslComputed()) ComputeGsl();
 
 1798                        "GslIntegral() - Unable to compute the integral on the interval (a,b) = (" 
 1800                        + 
") using the GSL interpolation",
 
 1804       ReportException(IException::Programmer, 
"GslIntegral()",
 
 1805                       "Invalid interval entered: [a,b] = [" 
 1809     if(!InsideDomain(a) || !InsideDomain(b)) {
 
 1810       ReportException(IException::Programmer, 
"GslIntegral()",
 
 1811                       "Invalid arguments. Interval entered [" 
 1813                       + 
"] is not contained within domain [" 
 1814                       + 
IString(DomainMinimum()) + 
", " 
 1815                       + 
IString(DomainMaximum()) + 
"]",
 
 1818     if(!GslInterpType(p_itype)) {
 
 1819       ReportException(IException::Programmer, 
"GslIntegral()",
 
 1820                       "Method only valid for GSL interpolation types, may not be used for " 
 1821                       + Name() + 
" interpolation",
 
 1826       GslIntegrityCheck(gsl_spline_eval_integ_e(p_interp, a, b, p_acc, &value), 
_FILEINFO_);
 
 1832                        "GslIntegral() - Unable to compute the integral on the interval (a,b) = (" 
 1834                        + 
"). GSL integrity check failed",
 
 1862   double NumericalApproximation::TrapezoidalRule(
const double a, 
const double b) {
 
 1867       vector <double> f = EvaluateForIntegration(a, b, n);
 
 1868       double h = f.back();
 
 1872       for(
unsigned int i = 0; i < (f.size() - 1) / (n - 1); i++) {
 
 1873         ii = (i + 1) * (n - 1);
 
 1874         result += (f[ii-1] + f[ii]) * h / 2;
 
 1881                        "TrapezoidalRule() - Unable to calculate the integral on the interval (a,b) = (" 
 1883                        + 
") using the trapeziodal rule",
 
 1914   double NumericalApproximation::Simpsons3PointRule(
const double a, 
const double b) {
 
 1919       vector <double> f = EvaluateForIntegration(a, b, n);
 
 1920       double h = f.back();
 
 1923       for(
unsigned int i = 0; i < (f.size() - 1) / (n - 1); i++) {
 
 1924         ii = (i + 1) * (n - 1);
 
 1925         result += (f[ii-2] + 4 * f[ii-1] + f[ii]) * h / 3;
 
 1932                        "Simpsons3PointRule() - Unable to calculate the integral on the interval (a,b) = (" 
 1934                        + 
") using Simpson's 3 point rule",
 
 1966   double NumericalApproximation::Simpsons4PointRule(
const double a, 
const double b) {
 
 1971       vector <double> f = EvaluateForIntegration(a, b, n);
 
 1972       double h = f.back();
 
 1975       for(
unsigned int i = 0; i < (f.size() - 1) / (n - 1); i++) {
 
 1976         ii = (i + 1) * (n - 1);
 
 1977         result += (f[ii-3] + 3 * f[ii-2] + 3 * f[ii-1] + f[ii]) * h * 3 / 8;
 
 1984                        "Simpsons4PointRule() - Unable to calculate the integral on the interval (a,b) = (" 
 1986                        + 
") using Simpson's 4 point rule",
 
 2021   double NumericalApproximation::BoolesRule(
const double a, 
const double b) {
 
 2026       vector <double> f = EvaluateForIntegration(a, b, n);
 
 2027       double h = f.back();
 
 2030       for(
unsigned int i = 0; i < (f.size() - 1) / (n - 1); i++) {
 
 2031         ii = (i + 1) * (n - 1);
 
 2032         result += (7 * f[ii-4] + 32 * f[ii-3] + 12 * f[ii-2] + 32 * f[ii-1] + 7 * f[ii]) * h * 2 / 45;
 
 2039                        "BoolesRule() - Unable to calculate the integral on the interval (a,b) = (" 
 2041                        + 
") using Boole's rule",
 
 2090   double NumericalApproximation::RefineExtendedTrap(
double a, 
double b, 
double s, 
unsigned int n) {
 
 2097         if(GslInterpType(p_itype) || p_itype == NumericalApproximation::CubicNeighborhood) {
 
 2099           begin = Evaluate(a, NumericalApproximation::NearestEndpoint);
 
 2100           end = Evaluate(b, NumericalApproximation::NearestEndpoint);
 
 2104           begin = Evaluate(a, NumericalApproximation::Extrapolate);
 
 2105           end = Evaluate(b, NumericalApproximation::Extrapolate);
 
 2107         return (0.5 * (b - a) * (begin + end));
 
 2111         double delta, tnm, x, sum;
 
 2112         it = (int)(pow(2.0, (
double)(n - 2)));
 
 2114         delta = (b - a) / tnm; 
 
 2115         x = a + 0.5 * delta;
 
 2117         for(
int i = 0; i < it; i++) {
 
 2118           if(GslInterpType(p_itype) || p_itype == NumericalApproximation::CubicNeighborhood) {
 
 2119             sum = sum + Evaluate(x, NumericalApproximation::NearestEndpoint);
 
 2122             sum = sum + Evaluate(x, NumericalApproximation::Extrapolate);
 
 2126         return (0.5 * (s + (b - a) * sum / tnm));
 
 2132                        "RefineExtendedTrap() - Unable to calculate the integral on the interval (a,b) = (" 
 2134                        + 
") using the extended trapeziodal rule",
 
 2173   double NumericalApproximation::RombergsMethod(
double a, 
double b) {
 
 2180     double trap[maxits+1]; 
 
 2191       for(
int i = 0; i < maxits; i++) {
 
 2194         trap[i] = RefineExtendedTrap(a, b, trap[i], i + 1); 
 
 2196           interp.
AddData(5, &h[i-4], &trap[i-4]);
 
 2198           ss = interp.
Evaluate(0.0, NumericalApproximation::Extrapolate);
 
 2202           if(fabs(dss) <= epsilon * fabs(ss)) 
return ss;
 
 2203           if(fabs(dss) <= epsilon2) 
return ss;
 
 2205         trap[i+1] = trap[i];
 
 2206         h[i+1] = 0.25 * h[i];
 
 2217                        "RombergsMethod() - Unable to calculate the integral on the interval (a,b) = (" 
 2219                        + 
") using Romberg's method",
 
 2223                      "RombergsMethod() - Unable to calculate the integral using RombergsMethod() - Failed to converge in " 
 2224                      + 
IString(maxits) + 
" iterations",
 
 2245   void NumericalApproximation::Reset() {
 
 2246     if(GslInterpType(p_itype)) GslDeallocation();
 
 2247     p_clampedComputed = 
false;
 
 2248     p_clampedEndptsSet = 
false;
 
 2249     p_dataValidated = 
false;
 
 2252     p_clampedSecondDerivs.clear();
 
 2253     p_clampedDerivFirstPt = 0;
 
 2254     p_clampedDerivLastPt = 0;
 
 2255     p_polyNevError.clear();
 
 2256     p_fprimeOfx.clear();
 
 2280       SetInterpType(itype);
 
 2286                        "Reset() - Unable to reset interpolation type",
 
 2315     if(GslInterpType(itype)) {
 
 2322                          "SetInterpType() - Unable to set interpolation type",
 
 2326     else if(itype > 9) {    
 
 2327       ReportException(IException::Programmer, 
"SetInterpType()",
 
 2328                       "Invalid argument. Unknown interpolation type: " 
 2335     p_dataValidated = 
false;
 
 2336     p_clampedComputed = 
false;
 
 2337     p_clampedEndptsSet = 
false;
 
 2338     p_clampedSecondDerivs.clear();
 
 2339     p_clampedDerivFirstPt = 0;
 
 2340     p_clampedDerivLastPt = 0;
 
 2341     p_polyNevError.clear();
 
 2342     p_fprimeOfx.clear();
 
 2370     if(p_interpFunctors.empty()) {
 
 2371       p_interpFunctors.insert(make_pair(Linear, gsl_interp_linear));
 
 2372       p_interpFunctors.insert(make_pair(Polynomial, gsl_interp_polynomial));
 
 2373       p_interpFunctors.insert(make_pair(CubicNatural, gsl_interp_cspline));
 
 2374       p_interpFunctors.insert(make_pair(CubicNatPeriodic, gsl_interp_cspline_periodic));
 
 2375       p_interpFunctors.insert(make_pair(Akima, gsl_interp_akima));
 
 2376       p_interpFunctors.insert(make_pair(AkimaPeriodic, gsl_interp_akima_periodic));
 
 2382       SetInterpType(itype);
 
 2387                        "Init() - Unable to initialize NumericalApproximation object",
 
 2392     gsl_set_error_handler_off();
 
 2413     if(itype == NumericalApproximation::Linear)        
return true;
 
 2414     if(itype == NumericalApproximation::Polynomial)    
return true;
 
 2415     if(itype == NumericalApproximation::CubicNatural)  
return true;
 
 2416     if(itype == NumericalApproximation::CubicNatPeriodic) 
return true;
 
 2417     if(itype == NumericalApproximation::Akima)         
return true;
 
 2418     if(itype == NumericalApproximation::AkimaPeriodic) 
return true;
 
 2438   void NumericalApproximation::GslAllocation(
unsigned int npoints) {
 
 2441     p_acc = gsl_interp_accel_alloc();
 
 2443     p_interp = gsl_spline_alloc(GslFunctor(p_itype), npoints);
 
 2460   void NumericalApproximation::GslDeallocation() {
 
 2461     if(p_interp) gsl_spline_free(p_interp);
 
 2462     if(p_acc) gsl_interp_accel_free(p_acc);
 
 2489     if(fItr == p_interpFunctors.end()) {
 
 2490       ReportException(IException::Programmer, 
"GslFunctor()",
 
 2491                       "Invalid argument. Unable to find GSL interpolator with id = " 
 2495     return (fItr->second);
 
 2517   void NumericalApproximation::GslIntegrityCheck(
int gsl_status, 
const char *src, 
int line)
 
 2519     if(gsl_status != GSL_SUCCESS) {
 
 2520       if(gsl_status != GSL_EDOM) {
 
 2521         ReportException(IException::Programmer, 
"GslIntegrityCheck(int,char,int)",
 
 2522                         "GslIntegrityCheck(): GSL error occured: " 
 2523                         + 
string(gsl_strerror(gsl_status)), src, line);
 
 2557   void NumericalApproximation::ValidateDataSet() {
 
 2558     if((
int) Size() < MinPoints()) {
 
 2559       ReportException(IException::Programmer, 
"ValidateDataSet()",
 
 2560                       Name() + 
" interpolation requires a minimum of " 
 2561                       + 
IString(MinPoints()) + 
" data points - currently have " 
 2565     for(
unsigned int i = 1; i < Size(); i++) {
 
 2567       if(p_x[i-1] == p_x[i]) {
 
 2568         ReportException(IException::Programmer, 
"ValidateDataSet()",
 
 2569                         "Invalid data set, x-values must be unique: \n\t\tp_x[" 
 2571                         + 
" = p_x[" + 
IString((
int) i) + 
"]",
 
 2574       if(p_x[i-1] > p_x[i]) {
 
 2577         if(p_itype != NumericalApproximation::PolynomialNeville) {
 
 2578           ReportException(IException::Programmer, 
"ValidateDataSet()",
 
 2579                           "Invalid data set, x-values must be in ascending order for " 
 2580                           + Name() + 
" interpolation: \n\t\tx[" 
 2587     if(p_itype == NumericalApproximation::CubicNatPeriodic) {
 
 2588       if(p_y[0] != p_y[Size()-1]) {
 
 2589         ReportException(IException::Programmer, 
"ValidateDataSet()",
 
 2590                         "First and last points of the data set must have the same y-value for " 
 2591                         + Name() + 
"interpolation to prevent discontinuity at the boundary",
 
 2595     p_dataValidated = 
true;
 
 2613   bool NumericalApproximation::InsideDomain(
const double a) {
 
 2615       if(a + DBL_EPSILON < DomainMinimum()) {
 
 2618       if(a - DBL_EPSILON > DomainMaximum()) {
 
 2625                        "InsideDomain() - Unable to compute domain boundaries",
 
 2647   bool NumericalApproximation::GslComputed()
 const {
 
 2648     if(GslInterpType(p_itype)) 
return ((p_interp) && (p_acc));
 
 2651                        "GslComputed() - Method only valid for GSL interpolation types, may not be used for " 
 2652                        + Name() + 
" interpolation",
 
 2677   void NumericalApproximation::ComputeGsl() {
 
 2679       if(GslComputed()) 
return;
 
 2680       if(!p_dataValidated) ValidateDataSet();
 
 2681       GslAllocation(Size());
 
 2682       GslIntegrityCheck(gsl_spline_init(p_interp, &p_x[0], &p_y[0], Size()), 
_FILEINFO_);
 
 2688                        "ComputeGsl() - Unable to compute GSL interpolation",
 
 2729   void NumericalApproximation::ComputeCubicClamped() {
 
 2734     if(!p_dataValidated) {
 
 2741                          "ComputeCubicClamped() - Unable to compute cubic clamped interpolation",
 
 2745     if(!p_clampedEndptsSet) {
 
 2746       ReportException(IException::Programmer, 
"ComputeCubicClamped()",
 
 2747                       "Must set endpoint derivative values after adding data in order to compute cubic spline with clamped boundary conditions",
 
 2751     p_clampedSecondDerivs.resize(n);
 
 2753     double p, sig, qn, un;
 
 2755     if(p_clampedDerivFirstPt > 0.99e30) {
 
 2756       p_clampedSecondDerivs[0] = 0.0;
 
 2760       p_clampedSecondDerivs[0] = -0.5;
 
 2761       u[0] = (3.0 / (p_x[1] - p_x[0])) * ((p_y[1] - p_y[0]) / (p_x[1] - p_x[0]) - p_clampedDerivFirstPt);
 
 2763     for(
int i = 1; i < n - 1; i++) { 
 
 2764       sig = (p_x[i] - p_x[i-1]) / (p_x[i+1] - p_x[i-1]);
 
 2765       p = sig * p_clampedSecondDerivs[i-1] + 2.0;
 
 2766       p_clampedSecondDerivs[i] = (sig - 1.0) / p;
 
 2767       u[i] = (6.0 * ((p_y[i+1] - p_y[i]) / (p_x[i+1] - p_x[i]) - (p_y[i] - p_y[i-1]) /
 
 2768                      (p_x[i] - p_x[i-1])) / (p_x[i+1] - p_x[i-1]) - sig * u[i-1]) / p;
 
 2770     if(p_clampedDerivLastPt > 0.99e30) { 
 
 2776       un = (3.0 / (p_x[n-1] - p_x[n-2])) * (p_clampedDerivLastPt - (p_y[n-1] - p_y[n-2]) /
 
 2777                                             (p_x[n-1] - p_x[n-2]));
 
 2779     p_clampedSecondDerivs[n-1] = (un - qn * u[n-2]) / (qn * p_clampedSecondDerivs[n-2] + 1.0);
 
 2780     for(
int i = n - 2; i >= 0; i--) { 
 
 2781       p_clampedSecondDerivs[i] = p_clampedSecondDerivs[i] * p_clampedSecondDerivs[i+1] + u[i];
 
 2783     p_clampedComputed = 
true;
 
 2824   double NumericalApproximation::ValueToExtrapolate(
const double a, 
const ExtrapType &etype) {
 
 2825     if(etype == NumericalApproximation::ThrowError) {
 
 2826       ReportException(IException::Programmer, 
"Evaluate()",
 
 2827                       "Invalid argument. Value entered, a = " 
 2828                       + 
IString(a) + 
", is outside of domain = [" 
 2829                       + 
IString(DomainMinimum()) + 
", " 
 2830                       + 
IString(DomainMaximum()) + 
"]",
 
 2833     if(etype == NumericalApproximation::NearestEndpoint) {
 
 2834       if(a + DBL_EPSILON < DomainMinimum()) {
 
 2835         return DomainMinimum();
 
 2838         return DomainMaximum(); 
 
 2842       if(GslInterpType(p_itype)
 
 2843           || p_itype == NumericalApproximation::CubicNeighborhood) {
 
 2844         ReportException(IException::Programmer, 
"Evaluate()",
 
 2845                         "Invalid argument. Cannot extrapolate for type " 
 2846                         + Name() + 
", must choose to throw error or return nearest neighbor",
 
 2887   double NumericalApproximation::EvaluateCubicNeighborhood(
const double a) {
 
 2889       int s = 0, s_old, s0;
 
 2890       vector <double> x0(4), y0(4);
 
 2892       for(
unsigned int n = 0; n < Size(); n++) {
 
 2893         if(p_x[n] < a) s = n;
 
 2897       else if(s > (
int) Size() - 3) s = Size() - 3;
 
 2901         for(
int n = 0; n < 4; n++) {
 
 2910       return spline.
Evaluate(a, NumericalApproximation::NearestEndpoint);
 
 2915                        "EvaluateCubicNeighborhood() - Unable to evaluate cubic neighborhood interpolation at a = " 
 2967   vector <double> NumericalApproximation::EvaluateCubicNeighborhood(
const vector <double> &a,
 
 2969     vector <double> result(a.size());
 
 2971     vector <double> x0(4), y0(4);
 
 2975     for(
unsigned int i = 0; i < a.size(); i++) {
 
 2976       for(
unsigned int n = 0; n < Size(); n++) {
 
 2984       if(s[i] > ((
int) Size()) - 3) {
 
 2991       for(
unsigned int i = 0; i < a.size(); i++) {
 
 2995           for(
int n = 0; n < 4; n++) {
 
 3004         if(InsideDomain(a[i]))
 
 3006         else a0 = ValueToExtrapolate(a[i], etype);
 
 3008         result[i] = spline.
Evaluate(a0, NumericalApproximation::NearestEndpoint);
 
 3015                        "EvaluateCubicNeighborhood() - Unable to evaluate the function at the given vector of points using cubic neighborhood interpolation",
 
 3054   double NumericalApproximation::EvaluateCubicClamped(
double a) {
 
 3070     while(k_Hi - k_Lo > 1) {
 
 3071       k = (k_Hi + k_Lo) / 2;
 
 3080     h = p_x[k_Hi] - p_x[k_Lo];
 
 3081     A = (p_x[k_Hi] - a) / h;
 
 3082     B = (a - p_x[k_Lo]) / h;
 
 3083     result = A * p_y[k_Lo] + B * p_y[k_Hi] + ((pow(A, 3.0) - A) *
 
 3084              p_clampedSecondDerivs[k_Lo] + (pow(B, 3.0) - B) * p_clampedSecondDerivs[k_Hi]) * pow(h, 2.0) / 6.0;
 
 3115   double NumericalApproximation::EvaluateCubicHermite(
const double a) {
 
 3119     if(p_fprimeOfx.size() != Size()) {
 
 3120       ReportException(IException::User, 
"EvaluateCubicHermite()",
 
 3121                       "Invalid arguments. The size of the first derivative vector does not match the number of (x,y) data points.",
 
 3125     int lowerIndex = FindIntervalLowerIndex(a);
 
 3129     if(a == p_x[lowerIndex]) {
 
 3130       return p_y[lowerIndex];
 
 3132     if(a == p_x[lowerIndex+1]) {
 
 3133       return p_y[lowerIndex+1];
 
 3136     double x0, x1, y0, y1, m0, m1;
 
 3138     x0 = p_x[lowerIndex];
 
 3139     x1 = p_x[lowerIndex+1];
 
 3141     y0 = p_y[lowerIndex];
 
 3142     y1 = p_y[lowerIndex+1];
 
 3144     m0 = p_fprimeOfx[lowerIndex];
 
 3145     m1 = p_fprimeOfx[lowerIndex+1];
 
 3154     return (2 * t * t * t - 3 * t * t + 1) * y0 + (t * t * t - 2 * t * t + t) * h * m0 + (-2 * t * t * t + 3 * t * t) * y1 + (t * t * t - t * t) * h * m1;
 
 3177   int NumericalApproximation::FindIntervalLowerIndex(
const double a) {
 
 3178     if(InsideDomain(a)) {
 
 3180       std::vector<double>::iterator pos;
 
 3182       pos = upper_bound(p_x.begin(), p_x.end(), a);
 
 3184       if(pos != p_x.end()) {
 
 3185         upperIndex = distance(p_x.begin(), pos);
 
 3188         upperIndex = Size() - 1;
 
 3190       return upperIndex - 1;
 
 3192     else if((a + DBL_EPSILON) < DomainMinimum()) {
 
 3236   double NumericalApproximation::EvaluatePolynomialNeville(
const double a) {
 
 3244     double den, dif, dift, c[n], d[n], ho, hp, w;
 
 3247     dif = fabs(a - p_x[0]);
 
 3248     for(
int i = 0; i < n; i++) { 
 
 3249       dift = fabs(a - p_x[i]);
 
 3259     for(
int m = 1; m < n; m++) {
 
 3260       for(
int i = 1; i <= n - m; i++) { 
 
 3262         hp = p_x[i+m-1] - a;
 
 3269       if(2 * ns < n - m) { 
 
 3278     p_polyNevError.push_back(*err);
 
 3300   vector <double> NumericalApproximation::EvaluateForIntegration(
const double a, 
const double b, 
const unsigned int n) {
 
 3302       ReportException(IException::Programmer, 
"EvaluatedForIntegration()",
 
 3303                       "Invalid interval entered: [a,b] = [" 
 3307     if(!InsideDomain(a) || !InsideDomain(b)) {
 
 3308       ReportException(IException::Programmer, 
"EvaluateForIntegration()",
 
 3309                       "Invalid arguments. Interval entered [" 
 3311                       + 
"] is not contained within domain [" 
 3312                       + 
IString(DomainMinimum()) + 
", " 
 3313                       + 
IString(DomainMaximum()) + 
"]",
 
 3320     int xSegments = Size() - 1;
 
 3321     while(xSegments % (n - 1) != 0) {
 
 3328     double h = (xMax - xMin) / xSegments;
 
 3331       for(
double i = 0; i < (xSegments + 1); i++) {
 
 3332         double xi = h * i + xMin;
 
 3333         f.push_back(Evaluate(xi));  
 
 3341                        "EvaluateForIntegration() - Unable to evaluate the data set for integration",
 
 3366   void NumericalApproximation::ReportException(
IException::ErrorType type, 
const string &methodName, 
const string &message,
 
 3367       const char *filesrc, 
int lineno)
 
 3369     string msg = methodName + 
" - " + message;
 
 3370     throw IException(type, msg.c_str(), filesrc, lineno);
 
bool p_clampedEndptsSet
Flag variable to determine whether SetCubicClampedEndptDeriv() has been called after all data was add...
 
vector< double > p_x
List of X values. 
 
InterpType
This enum defines the types of interpolation supported in this class. 
 
vector< double > p_fprimeOfx
List of first derivatives corresponding to each x value in the data set (i.e. each value in p_x) ...
 
double p_clampedDerivFirstPt
First derivative of first x-value, p_x[0]. This is only used for the CubicClamped interpolation type...
 
InterpFunctor GslFunctor(NumericalApproximation::InterpType itype) const 
Search for a GSL interpolation function. 
 
ErrorType errorType() const 
Returns the source of the error for this exception. 
 
NumericalApproximation provides various numerical analysis methods of interpolation, extrapolation and approximation of a tabulated set of x, y data. 
 
vector< double > p_clampedSecondDerivs
List of second derivatives evaluated at p_x values. This is only used for the CubicClamped interpolat...
 
double Evaluate(const double a, const ExtrapType &etype=ThrowError)
Calculates interpolated or extrapolated value of tabulated data set for given domain value...
 
void Reset()
Resets the state of the object. 
 
vector< double > PolynomialNevilleErrorEstimate()
Retrieves the error estimate for the Neville's polynomial interpolation type. 
 
ExtrapType
This enum defines the manner in which a value outside of the domain should be handled if passed to th...
 
#define _FILEINFO_
Macro for the filename and line number. 
 
double p_clampedDerivLastPt
First derivative of last x-value, p_x[n-1]. This is only used for the CubicClamped interpolation type...
 
const gsl_interp_type * InterpFunctor
GSL Interpolation specs. 
 
ErrorType
Contains a set of exception error types. 
 
void AddData(const double x, const double y)
Add a datapoint to the set. 
 
bool p_dataValidated
Flag variable to determine whether ValidateDataSet() has been called. 
 
Adds specific functionality to C++ strings. 
 
vector< double > p_y
List of Y values. 
 
vector< double > p_polyNevError
Estimate of error for interpolation evaluated at x. This is only used for the PolynomialNeville inter...
 
InterpType p_itype
Interpolation type. 
 
FunctorList::const_iterator FunctorConstIter
GSL Iterator. 
 
bool p_clampedComputed
Flag variable to determine whether ComputeCubicClamped() has been called.