Imported Upstream version 1.71.0
[platform/upstream/boost.git] / libs / math / doc / interpolators / cubic_b_spline.qbk
1 [/
2 Copyright (c) 2017 Nick Thompson
3 Use, modification and distribution are subject to the
4 Boost Software License, Version 1.0. (See accompanying file
5 LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 ]
7
8 [section:cubic_b Cubic B-spline interpolation]
9
10 [heading Synopsis]
11 ``
12   #include <boost/math/interpolators/cubic_b_spline.hpp>
13 ``
14
15   namespace boost { namespace math {
16
17     template <class Real>
18     class cubic_b_spline
19     {
20     public:
21
22       template <class BidiIterator>
23         cubic_b_spline(BidiIterator a, BidiIterator b, Real left_endpoint, Real step_size,
24                        Real left_endpoint_derivative = std::numeric_limits<Real>::quiet_NaN(),
25                        Real right_endpoint_derivative = std::numeric_limits<Real>::quiet_NaN());
26         cubic_b_spline(const Real* const f, size_t length, Real left_endpoint, Real step_size,
27                        Real left_endpoint_derivative = std::numeric_limits<Real>::quiet_NaN(),
28                        Real right_endpoint_derivative = std::numeric_limits<Real>::quiet_NaN());
29
30         Real operator()(Real x) const;
31
32         Real prime(Real x) const;
33     };
34
35   }} // namespaces
36
37
38 [heading Cubic B-Spline Interpolation]
39
40 The cubic B-spline class provided by boost allows fast and accurate interpolation of a function which is known at equally spaced points.
41 The cubic B-spline interpolation is numerically stable as it uses compactly supported basis functions constructed via iterative convolution.
42 This is to be contrasted to traditional cubic spline interpolation which is ill-conditioned as the global support of cubic polynomials causes small changes far from the evaluation point to exert a large influence on the calculated value.
43
44 There are many use cases for interpolating a function at equally spaced points.
45 One particularly important example is solving ODEs whose coefficients depend on data determined from experiment or numerical simulation.
46 Since most ODE steppers are adaptive, they must be able to sample the coefficients at arbitrary points; not just at the points we know the values of our function.
47
48 The first two arguments to the constructor are either:
49
50 * A pair of bidirectional iterators into the data, or
51 * A pointer to the data, and a length of the data array.
52
53 These are then followed by:
54
55 * The start of the functions domain
56 * The step size
57
58 Optionally, you may provide two additional arguments to the constructor, namely the derivative of the function at the left endpoint, and the derivative at the right endpoint.
59 If you do not provide these arguments, they will be estimated using one-sided finite-difference formulas.
60 An example of a valid call to the constructor is
61
62     std::vector<double> f{0.01, -0.02, 0.3, 0.8, 1.9, -8.78, -22.6};
63     double t0 = 0;
64     double h = 0.01;
65     boost::math::cubic_b_spline<double> spline(f.begin(), f.end(), t0, h);
66
67 The endpoints are estimated using a one-sided finite-difference formula. If you know the derivative at the endpoint, you may pass it to the constructor via
68
69     boost::math::cubic_b_spline<double> spline(f.begin(), f.end(), t0, h, a_prime, b_prime);
70
71
72 To evaluate the interpolant at a point, we simply use
73
74     double y = spline(x);
75
76 and to evaluate the derivative of the interpolant we use
77
78     double yp = spline.prime(x);
79
80 Be aware that the accuracy guarantees on the derivative of the spline are an order lower than the guarantees on the original function, see [@http://www.springer.com/us/book/9780387984087 Numerical Analysis, Graduate Texts in Mathematics, 181, Rainer Kress] for details.
81
82 Finally, note that this is an interpolator, not an extrapolator.
83 Therefore, you should strenuously avoid evaluating the spline outside the endpoints.
84 However, it is not an error if you do, as often you cannot control where (say) an ODE stepper will evaluate your function.
85 As such the interpolant tries to do something reasonable when the passed a value outside the endpoints.
86 For evaluation within one stepsize of the interval, you can assume something somewhat reasonable was returned.
87 As you move further away from the endpoints, the interpolant decays to its average on the interval.
88
89
90 [heading Complexity and Performance]
91
92 The call to the constructor requires [bigo](/n/) operations, where /n/ is the number of points to interpolate.
93 Each call the the interpolant is [bigo](1) (constant time).
94 On the author's Intel Xeon E3-1230, this takes 21ns as long as the vector is small enough to fit in cache.
95
96 [heading Accuracy]
97
98 Let /h/ be the stepsize. If /f/ is four-times continuously differentiable, then the interpolant is ['[bigo](h[super 4])] accurate and the derivative is ['[bigo](h[super 3])] accurate.
99
100 [heading Testing]
101
102 Since the interpolant obeys ['s(x[sub j]) = f(x[sub j])] at all interpolation points,
103 the tests generate random data and evaluate the interpolant at the interpolation points,
104 validating that equality with the data holds.
105
106 In addition, constant, linear, and quadratic functions are interpolated to ensure that the interpolant behaves as expected.
107
108 [heading Example]
109
110 [import ../../example/cubic_b_spline_example.cpp]
111
112 [cubic_b_spline_example]
113
114 [cubic_b_spline_example_out]
115
116 [endsect] [/section:cubic_b Cubic B-spline interpolation]