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