40 #ifndef _cubicspline_h
41 #define _cubicspline_h
55 template <
typename X,
typename Y>
83 : x(_x), a(_a), b(_b), c(_c), d(_d)
91 return a + b * xix + c * (xix * xix) + d * (xix * xix * xix);
108 template <
typename TimeSeriesType,
typename DataSeriesType>
131 std::vector<TimeSeriesType> x;
134 CalculateElements(x,y);
138 CubicSpline(
const std::vector<TimeSeriesType>& x,
const std::vector<DataSeriesType>& y)
139 { CalculateElements(x,y); }
143 DataSeriesType operator[](
const TimeSeriesType& x)
const
144 {
return interpolate(x); }
146 DataSeriesType interpolate(
const TimeSeriesType&x)
const
148 if (DataElements.size() == 0)
149 {
return DataSeriesType(); }
150 typename std::vector<element_type>::const_iterator it;
151 it = std::lower_bound(DataElements.begin(), DataElements.end(),
element_type(x));
152 if (it != DataElements.begin())
157 std::vector<DataSeriesType> operator[](
const std::vector<TimeSeriesType>& xx)
const
158 {
return interpolate(xx); }
161 {
return DataElements.begin(); }
163 {
return DataElements.end(); }
165 const_iterator begin()
const
166 {
return DataElements.begin(); }
167 const_iterator end()
const
168 {
return DataElements.end(); }
176 std::vector<TimeSeriesType> x;
177 std::vector<DataSeriesType> y;
180 CalculateElements(x,y);
184 std::vector<DataSeriesType> interpolate(
const std::vector<TimeSeriesType>& xx)
const
186 if (DataElements.size() == 0)
187 {
return std::vector<DataSeriesType>(xx.size()); }
189 typename std::vector<TimeSeriesType>::const_iterator it;
190 typename std::vector<element_type>::const_iterator it2;
191 it2 = DataElements.begin();
192 std::vector<DataSeriesType> ys;
193 for (it = xx.begin(); it != xx.end(); it++)
195 it2 = std::lower_bound(it2, DataElements.end(),
element_type(*it));
196 if (it2 != DataElements.begin())
199 ys.push_back(it2->eval(*it));
206 void CalculateElements(
const std::vector<TimeSeriesType>& x,
const std::vector<DataSeriesType>& y)
208 if (x.size() != y.size())
214 DataElements.clear();
216 typedef typename std::vector<TimeSeriesType>::difference_type size_type;
218 size_type n = y.size() - 1;
220 std::vector<DataSeriesType> b(n), d(n), a(n), c(n+1), l(n+1), u(n+1), z(n+1);
221 std::vector<TimeSeriesType> h(n+1);
223 l[0] = DataSeriesType(1);
224 u[0] = DataSeriesType(0);
225 z[0] = DataSeriesType(0);
228 for (size_type i = 1; i < n; i++)
230 h[i] = x[i+1] - x[i];
231 l[i] = DataSeriesType(2 * (x[i+1] - x[i-1])) - DataSeriesType(h[i-1]) * u[i-1];
232 u[i] = DataSeriesType(h[i]) / l[i];
233 a[i] = (DataSeriesType(3) / DataSeriesType(h[i])) * (y[i+1] - y[i]) - (DataSeriesType(3) / DataSeriesType(h[i-1])) * (y[i] - y[i-1]);
234 z[i] = (a[i] - DataSeriesType(h[i-1]) * z[i-1]) / l[i];
237 l[n] = DataSeriesType(1);
238 z[n] = c[n] = DataSeriesType(0);
240 for (size_type j = n-1; j >= 0; j--)
242 c[j] = z[j] - u[j] * c[j+1];
243 b[j] = (y[j+1] - y[j]) / DataSeriesType(h[j]) - (DataSeriesType(h[j]) * (c[j+1] + DataSeriesType(2) * c[j])) / DataSeriesType(3);
244 d[j] = (c[j+1] - c[j]) / DataSeriesType(3 * h[j]);
247 for (size_type i = 0; i < n; i++)
249 DataElements.push_back(
element_type(x[i], y[i], b[i], c[i], d[i]));
256 #endif // Include guard
bool Boole
Generally acts a single bit, true or false.
Y c
Meta-data corresponding to "c" on wikipedia description of a cubic splines.
ContainerType::const_iterator const_iterator
An iterator suitable for the metadata this spline uses that will not allow changes to the underlying ...
#define MEZZ_EXCEPTION(num, desc)
An easy way to throw exceptions with rich information.
All the definitions for datatypes as well as some basic conversion functions are defined here...
Y a
Meta-data corresponding to "a" on wikipedia description of a cubic splines.
CubicSpline(const std::vector< DataSeriesType > &y)
Create a Spline with a time series spread evenly between 0 and 1.
Y eval(const X &xx) const
The actual interpolation of the meta-data into a result.
Boole operator<(const X &xx) const
Sort Meta-data elements by time series locations.
X x
Time series meta-data.
CubicSplineElement(X _x)
Simple constructor.
CubicSplineElement< TimeSeriesType, DataSeriesType > element_type
The meta data type stored by this container.
Meta data nodes required to generate a cubic spline.
std::vector< element_type > ContainerType
The underlying type of the container that actually stores the instances of ContainerType.
Thrown when a passed parameter is checked at runtime and not in the expected range.
Y b
Meta-data corresponding to "b" on wikipedia description of a cubic splines.
ContainerType::iterator iterator
An iterator suitable for the metadata this spline uses.
CubicSpline(const std::vector< TimeSeriesType > &x, const std::vector< DataSeriesType > &y)
A spline with custom time and data series values.
CubicSplineElement(X _x, Y _a, Y _b, Y _c, Y _d)
Complete meta-data constructor _x Time series location _a Meta-data corresponding to "a" on wikipedia...
The bulk of the engine components go in this namspace.
Boole operator<(const CubicSplineElement &e) const
Sort Meta-data elements by time series locations in other Meta-Data.
A class for interpolating data with arbitrary.
void push_back(const DataSeriesType &DataToAdd)
Add another entry to the spline.
CubicSpline()
Create an empty, invalid spline.
ContainerType DataElements
The actual container of Metadata.
Y d
Meta-data corresponding to "d" on wikipedia description of a cubic splines.