5 #ifndef LODESTAR_BACKWARDDIFFERENCE_HPP
6 #define LODESTAR_BACKWARDDIFFERENCE_HPP
11 namespace primitives {
12 template<
typename TType,
size_t TSamples,
size_t TOrder,
typename TScalarType =
double>
14 static_assert(TSamples > 1,
"Number of samples must be greater than one.");
16 static_assert(TOrder > 1,
"Differentiation order must be greater than one.");
18 static_assert(TSamples > TOrder,
"Number of samples must be greater than order.");
22 (TSamples == 2 && TOrder == 1) ||
23 (TSamples == 3 && TOrder == 1) ||
24 (TSamples == 4 && TOrder == 1) ||
25 (TSamples == 5 && TOrder == 1) ||
26 (TSamples == 6 && TOrder == 1) ||
27 (TSamples == 7 && TOrder == 1) ||
29 (TSamples == 3 && TOrder == 2) ||
30 (TSamples == 4 && TOrder == 2) ||
31 (TSamples == 5 && TOrder == 2) ||
32 (TSamples == 6 && TOrder == 2) ||
33 (TSamples == 7 && TOrder == 2) ||
35 (TSamples == 4 && TOrder == 3) ||
36 (TSamples == 5 && TOrder == 3) ||
37 (TSamples == 6 && TOrder == 3) ||
38 (TSamples == 7 && TOrder == 3),
"Combination of samples and order is not supported.");
49 template<
typename TType,
typename TScalarType>
52 static TType compute(
const TType &xNeg1,
const TType &x0)
58 static TType compute(
const TType &xNeg1,
const TType &x0, TScalarType h)
60 return compute(xNeg1, x0) / h;
63 static const int kOrder = 1;
64 static const int kErrorOrder = 1;
73 template<
typename TType,
typename TScalarType>
76 static TType compute(
const TType &xNeg2,
const TType &xNeg1,
const TType &x0)
78 return (3.0 / 2.0) * x0 - 2.0 * xNeg1 + (1.0 / 2.0) * xNeg2;
82 static TType compute(
const TType &xNeg2,
const TType &xNeg1,
const TType &x0, TScalarType h)
84 return compute(xNeg2, xNeg1, x0) / h;
87 static const int kOrder = 1;
88 static const int kErrorOrder = 2;
97 template<
typename TType,
typename TScalarType>
100 static TType compute(
const TType &xNeg3,
const TType &xNeg2,
const TType &xNeg1,
const TType &x0)
102 return (11.0 / 6.0) * x0 - 3.0 * xNeg1 + (3.0 / 2.0) * xNeg2 - (1.0 / 3.0) * xNeg3;
107 compute(
const TType &xNeg3,
const TType &xNeg2,
const TType &xNeg1,
const TType &x0, TScalarType h)
109 return compute(xNeg3, xNeg2, xNeg1, x0) / h;
112 static const int kOrder = 1;
113 static const int kErrorOrder = 3;
122 template<
typename TType,
typename TScalarType>
126 compute(
const TType &xNeg4,
const TType &xNeg3,
const TType &xNeg2,
const TType &xNeg1,
const TType &x0)
128 return (25.0 / 12.0) * x0 - 4.0 * xNeg1 + 3.0 * xNeg2 - (4.0 / 3.0) * xNeg3 + (1.0 / 4.0) * xNeg4;
133 compute(
const TType &xNeg4,
const TType &xNeg3,
const TType &xNeg2,
const TType &xNeg1,
const TType &x0,
136 return compute(xNeg4, xNeg3, xNeg2, xNeg1, x0) / h;
139 static const int kOrder = 1;
140 static const int kErrorOrder = 4;
149 template<
typename TType,
typename TScalarType>
153 compute(
const TType &xNeg5,
const TType &xNeg4,
const TType &xNeg3,
const TType &xNeg2,
const TType &xNeg1,
156 return (137.0 / 60.0) * x0 - 5.0 * xNeg1 + 5.0 * xNeg2 - (10.0 / 3.0) * xNeg3 + (5.0 / 4.0) * xNeg4 -
162 compute(
const TType &xNeg5,
const TType &xNeg4,
const TType &xNeg3,
const TType &xNeg2,
const TType &xNeg1,
163 const TType &x0, TScalarType h)
165 return compute(xNeg5, xNeg4, xNeg3, xNeg2, xNeg1, x0) / h;
168 static const int kOrder = 1;
169 static const int kErrorOrder = 5;
178 template<
typename TType,
typename TScalarType>
182 compute(
const TType &xNeg6,
const TType &xNeg5,
const TType &xNeg4,
const TType &xNeg3,
const TType &xNeg2,
183 const TType &xNeg1,
const TType &x0)
185 return (49.0 / 20.0) * x0 - 6.0 * xNeg1 + (15.0 / 2.0) * xNeg2 - (20.0 / 3.0) * xNeg3 +
186 (15.0 / 4.0) * xNeg4 - (6.0 / 5.0) * xNeg5 + (1.0 / 6.0) * xNeg6;
191 compute(
const TType &xNeg6,
const TType &xNeg5,
const TType &xNeg4,
const TType &xNeg3,
const TType &xNeg2,
192 const TType &xNeg1,
const TType &x0, TScalarType h)
194 return compute(xNeg6, xNeg5, xNeg4, xNeg3, xNeg2, xNeg1, x0) / h;
197 static const int kOrder = 1;
198 static const int kErrorOrder = 6;
209 template<
typename TType,
typename TScalarType>
212 static TType compute(
const TType &xNeg2,
const TType &xNeg1,
const TType &x0)
214 return x0 - 2 * xNeg1 + xNeg2;
218 static TType compute(
const TType &xNeg2,
const TType &xNeg1,
const TType &x0, TScalarType h)
220 return compute(xNeg2, xNeg1, x0) / (h * h);
223 static const int kOrder = 2;
224 static const int kErrorOrder = 1;
233 template<
typename TType,
typename TScalarType>
236 static TType compute(
const TType &xNeg3,
const TType &xNeg2,
const TType &xNeg1,
const TType &x0)
238 return 2 * x0 - 5 * xNeg1 + 4 * xNeg2 - 1 * xNeg3;
243 compute(
const TType &xNeg3,
const TType &xNeg2,
const TType &xNeg1,
const TType &x0, TScalarType h)
245 return compute(xNeg3, xNeg2, xNeg1, x0) / (h * h);
248 static const int kOrder = 2;
249 static const int kErrorOrder = 2;
258 template<
typename TType,
typename TScalarType>
262 compute(
const TType &xNeg4,
const TType &xNeg3,
const TType &xNeg2,
const TType &xNeg1,
const TType &x0)
264 return (35.0 / 12.0) * x0 - (26.0 / 3.0) * xNeg1 + (19.0 / 2.0) * xNeg2 - (14.0 / 3.0) * xNeg3 +
265 (11.0 / 12.0) * xNeg4;
270 compute(
const TType &xNeg4,
const TType &xNeg3,
const TType &xNeg2,
const TType &xNeg1,
const TType &x0,
273 return compute(xNeg4, xNeg3, xNeg2, xNeg1, x0) / (h * h);
276 static const int kOrder = 2;
277 static const int kErrorOrder = 3;
286 template<
typename TType,
typename TScalarType>
290 compute(
const TType &xNeg5,
const TType &xNeg4,
const TType &xNeg3,
const TType &xNeg2,
const TType &xNeg1,
293 return (15.0 / 4.0) * x0 - (77.0 / 6.0) * xNeg1 + (107.0 / 6.0) * xNeg2 - 13.0 * xNeg3 +
294 (61.0 / 12.0) * xNeg4 - (5.0 / 6.0) * xNeg5;
299 compute(
const TType &xNeg5,
const TType &xNeg4,
const TType &xNeg3,
const TType &xNeg2,
const TType &xNeg1,
300 const TType &x0, TScalarType h)
302 return compute(xNeg5, xNeg4, xNeg3, xNeg2, xNeg1, x0) / (h * h);
305 static const int kOrder = 2;
306 static const int kErrorOrder = 4;
315 template<
typename TType,
typename TScalarType>
319 compute(
const TType &xNeg6,
const TType &xNeg5,
const TType &xNeg4,
const TType &xNeg3,
const TType &xNeg2,
320 const TType &xNeg1,
const TType &x0)
322 return (203.0 / 45.0) * x0 - (87.0 / 5.0) * xNeg1 + (117.0 / 4.0) * xNeg2 - (254.0 / 9.0) * xNeg3 +
323 (33.0 / 2.0) * xNeg4 - (27.0 / 5.0) * xNeg5 + (137.0 / 180.0) * xNeg6;
328 compute(
const TType &xNeg6,
const TType &xNeg5,
const TType &xNeg4,
const TType &xNeg3,
const TType &xNeg2,
329 const TType &xNeg1,
const TType &x0, TScalarType h)
331 return compute(xNeg6, xNeg5, xNeg4, xNeg3, xNeg2, xNeg1, x0) / (h * h);
334 static const int kOrder = 2;
335 static const int kErrorOrder = 5;
346 template<
typename TType,
typename TScalarType>
349 static TType compute(
const TType &xNeg3,
const TType &xNeg2,
const TType &xNeg1,
const TType &x0)
351 return 1.0 * x0 - 3.0 * xNeg1 + 3.0 * xNeg2 - 1.0 * xNeg3;
356 compute(
const TType &xNeg3,
const TType &xNeg2,
const TType &xNeg1,
const TType &x0, TScalarType h)
358 return compute(xNeg3, xNeg2, xNeg1, x0) / (h * h * h);
361 static const int kOrder = 3;
362 static const int kErrorOrder = 1;
371 template<
typename TType,
typename TScalarType>
375 compute(
const TType &xNeg4,
const TType &xNeg3,
const TType &xNeg2,
const TType &xNeg1,
const TType &x0)
377 return (5.0 / 2.0) * x0 - 9.0 * xNeg1 + 12.0 * xNeg2 - 7.0 * xNeg3 + (3.0 / 2.0) * xNeg4;
382 compute(
const TType &xNeg4,
const TType &xNeg3,
const TType &xNeg2,
const TType &xNeg1,
const TType &x0,
385 return compute(xNeg4, xNeg3, xNeg2, xNeg1, x0) / (h * h * h);
388 static const int kOrder = 3;
389 static const int kErrorOrder = 2;
398 template<
typename TType,
typename TScalarType>
402 compute(
const TType &xNeg5,
const TType &xNeg4,
const TType &xNeg3,
const TType &xNeg2,
const TType &xNeg1,
405 return (17.0 / 4.0) * x0 - (71.0 / 4.0) * xNeg1 + (59.0 / 2.0) * xNeg2 - (49.0 / 2.0) * xNeg3 +
406 (41.0 / 4.0) * xNeg4 - (7.0 / 4.0) * xNeg5;
411 compute(
const TType &xNeg5,
const TType &xNeg4,
const TType &xNeg3,
const TType &xNeg2,
const TType &xNeg1,
412 const TType &x0, TScalarType h)
414 return compute(xNeg5, xNeg4, xNeg3, xNeg2, xNeg1, x0) / (h * h * h);
417 static const int kOrder = 3;
418 static const int kErrorOrder = 3;
427 template<
typename TType,
typename TScalarType>
431 compute(
const TType &xNeg6,
const TType &xNeg5,
const TType &xNeg4,
const TType &xNeg3,
const TType &xNeg2,
432 const TType &xNeg1,
const TType &x0)
434 return (49.0 / 8.0) * x0 - 29.0 * xNeg1 + (461.0 / 8.0) * xNeg2 - 62.0 * xNeg3 + (307.0 / 8.0) * xNeg4 -
435 13.0 * xNeg5 + (15.0 / 8.0) * xNeg6;
440 compute(
const TType &xNeg6,
const TType &xNeg5,
const TType &xNeg4,
const TType &xNeg3,
const TType &xNeg2,
441 const TType &xNeg1,
const TType &x0, TScalarType h)
443 return compute(xNeg6, xNeg5, xNeg4, xNeg3, xNeg2, xNeg1, x0) / (h * h * h);
446 static const int kOrder = 3;
447 static const int kErrorOrder = 4;
453 #endif //LODESTAR_BACKWARDDIFFERENCE_HPP