/** 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; } }
static VALUE rb_gsl_spline_eval_deriv_e(VALUE obj, VALUE xx) { rb_gsl_spline *rgs = NULL; double val; int status; Data_Get_Struct(obj, rb_gsl_spline, rgs); Need_Float(xx); status = gsl_spline_eval_deriv_e(rgs->s, NUM2DBL(xx), rgs->a, &val); switch (status) { case GSL_EDOM: rb_gsl_error_handler("gsl_spline_eval_deriv_e error", __FILE__, __LINE__, status); break; default: return rb_float_new(val); break; } return Qnil; }
/** * Function which calculates the value of the waveform, plus its * first and second derivatives, for the points which will be required * in the hybrid comb attachment of the ringdown. */ static INT4 XLALGenerateHybridWaveDerivatives ( REAL8Vector *rwave, /**<< OUTPUT, values of the waveform at comb points */ REAL8Vector *dwave, /**<< OUTPUT, 1st deriv of the waveform at comb points */ REAL8Vector *ddwave, /**<< OUTPUT, 2nd deriv of the waveform at comb points */ REAL8Vector *timeVec, /**<< Vector containing the time */ REAL8Vector *wave, /**<< Last part of inspiral waveform */ REAL8Vector *matchrange, /**<< Times which determine the size of the comb */ REAL8 dt, /**<< Sample time step */ REAL8 mass1, /**<< First component mass (in Solar masses) */ REAL8 mass2 /**<< Second component mass (in Solar masses) */ ) { /* XLAL error handling */ INT4 errcode = XLAL_SUCCESS; /* For checking GSL return codes */ INT4 gslStatus; UINT4 j; UINT4 vecLength; REAL8 m; double *y; double ry, dy, dy2; double rt; double *tlist; gsl_interp_accel *acc; gsl_spline *spline; /* Total mass in geometric units */ m = (mass1 + mass2) * LAL_MTSUN_SI; tlist = (double *) LALMalloc(6 * sizeof(double)); rt = (matchrange->data[1] - matchrange->data[0]) / 5.; tlist[0] = matchrange->data[0]; tlist[1] = tlist[0] + rt; tlist[2] = tlist[1] + rt; tlist[3] = tlist[2] + rt; tlist[4] = tlist[3] + rt; tlist[5] = matchrange->data[1]; /* Set the length of the interpolation vectors */ vecLength = ( m * matchrange->data[2] / dt ) + 1; /* Getting interpolation and derivatives of the waveform using gsl spline routine */ /* Initiate arrays and supporting variables for gsl */ y = (double *) LALMalloc(vecLength * sizeof(double)); if ( !y ) { XLAL_ERROR( XLAL_ENOMEM ); } for (j = 0; j < vecLength; ++j) { y[j] = wave->data[j]; } XLAL_CALLGSL( acc = (gsl_interp_accel*) gsl_interp_accel_alloc() ); XLAL_CALLGSL( spline = (gsl_spline*) gsl_spline_alloc(gsl_interp_cspline, vecLength) ); if ( !acc || !spline ) { if ( acc ) gsl_interp_accel_free(acc); if ( spline ) gsl_spline_free(spline); LALFree( y ); XLAL_ERROR( XLAL_ENOMEM ); } /* Gall gsl spline interpolation */ gslStatus = gsl_spline_init(spline, timeVec->data, y, vecLength); if ( gslStatus != GSL_SUCCESS ) { gsl_spline_free(spline); gsl_interp_accel_free(acc); LALFree( y ); XLAL_ERROR( XLAL_EFUNC ); } /* Getting first and second order time derivatives from gsl interpolations */ for (j = 0; j < 6; ++j) { gslStatus = gsl_spline_eval_e( spline, tlist[j], acc, &ry ); if ( gslStatus == GSL_SUCCESS ) { gslStatus = gsl_spline_eval_deriv_e(spline, tlist[j], acc, &dy ); gslStatus = gsl_spline_eval_deriv2_e(spline, tlist[j], acc, &dy2 ); } if (gslStatus != GSL_SUCCESS ) { gsl_spline_free(spline); gsl_interp_accel_free(acc); LALFree( y ); XLAL_ERROR( XLAL_EFUNC ); } rwave->data[j] = (REAL8)(ry); dwave->data[j] = (REAL8)(dy/m); ddwave->data[j] = (REAL8)(dy2/m/m); } /* Free gsl variables */ gsl_spline_free(spline); gsl_interp_accel_free(acc); LALFree( tlist ); LALFree(y); return errcode; }