21using namespace CurveFitting;
24Kernel::Logger
g_log(
"CubicSpline");
27using namespace Kernel;
37 : m_min_points(3), m_acc(gsl_interp_accel_alloc(), m_gslFree),
38 m_spline(gsl_spline_alloc(gsl_interp_cspline, m_min_points), m_gslFree), m_recalculateSpline(true) {
40 declareAttribute(
"n",
Attribute(m_min_points));
47 declareParameter(
"y0", 0);
48 declareParameter(
"y1", 0);
49 declareParameter(
"y2", 0);
62 boost::scoped_array<double>
x(
new double[
n]);
63 boost::scoped_array<double>
y(
new double[
n]);
82 for (
int i = 0; i <
n; ++i) {
89 if (i > 1 && i <
n && (
x[i - 1] <
x[i - 2] ||
x[i - 1] >
x[i])) {
97 g_log.
warning() <<
"Spline x parameters are not in ascending order. Values "
100 using point = std::pair<double, double>;
101 std::vector<point> pairs;
103 for (
int i = 0; i <
n; ++i) {
104 pairs.emplace_back(
x[i],
y[i]);
107 std::sort(pairs.begin(), pairs.end(), [](
const point &xy1,
const point &xy2) { return xy1.first < xy2.first; });
109 for (
int i = 0; i <
n; ++i) {
110 x[i] = pairs[i].first;
111 y[i] = pairs[i].second;
130 boost::scoped_array<double>
x(
new double[
n]);
131 boost::scoped_array<double>
y(
new double[
n]);
154 bool outOfRange(
false);
155 for (
size_t i = 0; i < nData; ++i) {
162 if (xValues[i] <
m_spline->interp->xmin) {
172 g_log.
information() <<
"Some x values where out of range and will not be calculated.\n";
200 const size_t order)
const {
203 bool outOfRange(
false);
207 throw std::invalid_argument(
"CubicSpline: order of derivative must be 1 or greater");
209 for (
size_t i = 0; i < nData; ++i) {
213 xDeriv = gsl_spline_eval_deriv(
m_spline.get(), xValues[i],
m_acc.get());
214 errorCode = gsl_spline_eval_deriv_e(
m_spline.get(), xValues[i],
m_acc.get(), &xDeriv);
215 }
else if (order == 2) {
216 xDeriv = gsl_spline_eval_deriv2(
m_spline.get(), xValues[i],
m_acc.get());
217 errorCode = gsl_spline_eval_deriv2_e(
m_spline.get(), xValues[i],
m_acc.get(), &xDeriv);
234 g_log.
information() <<
"Some x values where out of range and will not be calculated.\n";
259 if (attName ==
"n") {
274 for (
int i = oldN; i <
n; ++i) {
277 std::string newXName =
"x" + num;
278 std::string newYName =
"y" + num;
286 }
else if (
n < oldN) {
287 throw std::invalid_argument(
"Cubic Spline: Can't decrease the number of attributes");
310 throw std::range_error(
"Cubic Spline: x index out of range.");
322 if (status == errorType) {
325 std::string message(
"CubicSpline: ");
326 message.append(gsl_strerror(errorType));
328 throw std::runtime_error(message);
339 int status = gsl_spline_init(
m_spline.get(),
x.get(),
y.get(),
n);
349 gsl_interp_accel_reset(
m_acc.get());
double value
The value of the point.
#define DECLARE_FUNCTION(classname)
Macro for declaring a new type of function to be used with the FunctionFactory.
Mantid::API::IFunction::Attribute Attribute
std::map< DeltaEMode::Type, std::string > index
Attribute is a non-fitting parameter.
int asInt() const
Returns int value if attribute is a int, throws exception otherwise.
double asDouble() const
Returns double value if attribute is a double, throws exception otherwise.
virtual Attribute getAttribute(const std::string &name) const
Return a value of attribute attName.
void declareAttribute(const std::string &name, const API::IFunction::Attribute &defaultValue)
Declare a single attribute.
void setAttributeValue(const std::string &attName, const T &value)
Set an attribute value.
void storeAttributeValue(const std::string &name, const API::IFunction::Attribute &value)
Store an attribute's value.
void setParameter(size_t, const double &value, bool explicitlySet=true) override
Set i-th parameter.
void declareParameter(const std::string &name, double initValue=0, const std::string &description="") override
Declare a new parameter.
double getParameter(size_t i) const override
Get i-th parameter.
A wrapper around GSL functions implementing cubic spline interpolation.
bool m_recalculateSpline
Flag for checking if the spline needs recalculating.
void setupInput(boost::scoped_array< double > &x, boost::scoped_array< double > &y, int n) const
Method to setup the gsl function.
void setParameter(size_t i, const double &value, bool explicitlySet=true) override
Set a parameter for the function and flags the spline for re-calculation.
bool checkXInRange(double x) const
Check if an x value falls within the range of the spline.
void setAttribute(const std::string &attName, const Attribute &) override
Set a value to attribute attName.
struct Mantid::CurveFitting::Functions::CubicSpline::GSLFree m_gslFree
void reallocGSLObjects(const int n)
Reallocate the spline object to use n data points.
double splineEval(const double x) const
Evaluate a point on the spline, with basic error handling.
std::shared_ptr< gsl_spline > m_spline
GSL data structure used to calculate spline.
void setXAttribute(const size_t index, double x)
Set the value of a data point location to x.
void function1D(double *out, const double *xValues, const size_t nData) const override
Execute the function.
void checkGSLError(const int status, const int errorType) const
Check if an error occurred and throw appropriate message.
void calculateSpline(double *out, const double *xValues, const size_t nData) const
Calculate the spline.
std::shared_ptr< gsl_interp_accel > m_acc
GSL interpolation accelerator object.
void calculateDerivative(double *out, const double *xValues, const size_t nData, const size_t order) const
Calculate the derivative.
void derivative1D(double *out, const double *xValues, size_t nData, const size_t order) const override
Calculate the derivatives for a set of points on the spline.
void initGSLObjects(boost::scoped_array< double > &x, boost::scoped_array< double > &y, int n) const
Initialise GSL objects if required.
void warning(const std::string &msg)
Logs at warning level.
void information(const std::string &msg)
Logs at information level.
Kernel::Logger g_log("ExperimentInfo")
static logger object
std::string to_string(const wide_integer< Bits, Signed > &n)