/** Calculate the derivatives of each of the supplied points * * @param out :: The array to store the calculated derivatives * @param xValues :: The array of x values we wish to calculate derivatives at * @param nData :: The size of the arrays * @param order :: The order of derivatives to calculate too */ void CubicSpline::calculateDerivative(double* out, const double* xValues, const size_t nData, const size_t order) const { double xDeriv = 0; int errorCode = 0; bool outOfRange(false); //throw error if the order is not the 1st or 2nd derivative if(order < 1) throw std::invalid_argument( "CubicSpline: order of derivative must be 1 or greater"); for(size_t i = 0; i < nData; ++i) { if(checkXInRange(xValues[i])) { //choose the order of the derivative if(order == 1) { xDeriv = gsl_spline_eval_deriv(m_spline.get(),xValues[i],m_acc.get()); errorCode = gsl_spline_eval_deriv_e (m_spline.get(),xValues[i],m_acc.get(),&xDeriv); } else if (order == 2) { xDeriv = gsl_spline_eval_deriv2(m_spline.get(),xValues[i],m_acc.get()); errorCode = gsl_spline_eval_deriv2_e (m_spline.get(),xValues[i],m_acc.get(),&xDeriv); } } else { //if out of range, just set it to zero outOfRange = true; xDeriv = 0; } //check GSL functions didn't return an error checkGSLError(errorCode, GSL_EDOM); //record the value out[i] = xDeriv; } //warn user that some values weren't calculated if(outOfRange) { g_log.warning() << "Some x values where out of range and will not be calculated." << std::endl; } }
/* Performs the second derivative of a spline */ double FC_FUNC_(oct_spline_eval_der2, OCT_SPLINE_EVAL_DER2) (const double *x, const void **spl, void **acc) { /* the GSL headers specify double x */ return gsl_spline_eval_deriv2((gsl_spline *)(*spl), *x, (gsl_interp_accel *)(*acc)); }
double Interpolate::deriv2(double x) { return gsl_spline_eval_deriv2 (_spline, x, _acc); }