20 #ifndef _CUBICINTERPOLATION_INTERNAL_HPP_
21 #define _CUBICINTERPOLATION_INTERNAL_HPP_
23 #include "CubicInterpolation.hpp"
31 static double interpolateUsingXAndYTables(
const double xArr[],
const double yArr[],
const int offset,
const double x);
34 static double cubicInterpolate(
const double x0,
const double y0,
const double x1,
const double y1,
35 const double x2,
const double y2,
const double x3,
const double y3,
const double x);
38 static int findStraddle(
const double xArr[],
const int len,
const double x);
41 static int recursiveFindStraddle(
const double xArr[],
const int l,
const int r,
const double x);
44 static double interpolateUsingXArrAndYStride(
const double xArr[],
const double yStride,
45 const int offset,
const double x);
47 const int numEntries = 40;
50 const double xArrComputed[numEntries] = {
51 0.0, 1.0, 20.0, 400.0,
52 8000.0, 160000.0, 300000.0, 600000.0,
53 900000.0, 1200000.0, 1500000.0, 1800000.0,
54 2100000.0, 2400000.0, 2700000.0, 3000000.0,
55 3300000.0, 3600000.0, 3900000.0, 4200000.0,
56 4500000.0, 4800000.0, 5100000.0, 5400000.0,
57 5700000.0, 6000000.0, 6300000.0, 6600000.0,
58 6900000.0, 7200000.0, 7500000.0, 7800000.0,
59 8100000.0, 8400000.0, 8700000.0, 9000000.0,
60 9300000.0, 9600000.0, 9900000.0, 10200000.0
64 const double yArrComputed[numEntries] = {
65 0.0000000000000000, 1.0000000000000000, 20.0000009437402611, 400.0003963713384110,
66 8000.1589294602090376, 160063.6067763759638183, 300223.7071597663452849, 600895.5933856170158833,
67 902016.8065120954997838, 1203588.4983199508860707, 1505611.8245524743106216, 1808087.9449319066479802,
68 2111018.0231759352609515, 2414403.2270142501220107, 2718244.7282051891088486, 3022543.7025524540804327,
69 3327301.3299219091422856, 3632518.7942584538832307, 3938197.2836029687896371, 4244337.9901093561202288,
70 4550942.1100616492331028, 4858010.8438911894336343, 5165545.3961938973516226, 5473546.9757476449012756,
71 5782016.7955296505242586, 6090956.0727340159937739, 6400366.0287892958149314, 6710247.8893762007355690,
72 7020602.8844453142955899, 7331432.2482349723577499, 7642737.2192891482263803, 7954519.0404754765331745,
73 8266778.9590033423155546, 8579518.2264420464634895, 8892738.0987390466034412, 9206439.8362383283674717,
74 9520624.7036988288164139, 9835293.9703129194676876, 10150448.9097250290215015, 10466090.8000503256917000
78 double CubicInterpolation<A>::usingXAndYTables(
const double x) {
79 return usingXAndYTables(xArrComputed, yArrComputed, numEntries, x);
83 double CubicInterpolation<A>::usingXAndYTables(
const double xArr[],
const double yArr[],
84 const int len,
const double x) {
86 if (x < xArr[0] || x > xArr[len-1]) {
87 throw std::invalid_argument(
"x value out of range: " + std::to_string(x));
90 if (x == xArr[len-1]) {
94 offset = findStraddle<A>(xArr, len, x);
95 if (offset < 0 && offset > len-2) {
96 throw std::logic_error(
"offset must be >= 0 and <= " + std::to_string(len) +
"-2");
100 return (interpolateUsingXAndYTables<A>(xArr, yArr, (offset-0), x));
102 else if (offset == numEntries-2) {
103 return (interpolateUsingXAndYTables<A>(xArr, yArr, (offset-2), x));
106 return (interpolateUsingXAndYTables<A>(xArr, yArr, (offset-1), x));
111 static double interpolateUsingXAndYTables(
const double xArr[],
const double yArr[],
112 const int offset,
const double x) {
113 return (cubicInterpolate<A>(xArr[offset+0], yArr[offset+0],
114 xArr[offset+1], yArr[offset+1],
115 xArr[offset+2], yArr[offset+2],
116 xArr[offset+3], yArr[offset+3],
121 static inline double cubicInterpolate(
const double x0,
const double y0,
122 const double x1,
const double y1,
123 const double x2,
const double y2,
124 const double x3,
const double y3,
127 double l0_numer = (x - x1) * (x - x2) * (x - x3);
128 double l1_numer = (x - x0) * (x - x2) * (x - x3);
129 double l2_numer = (x - x0) * (x - x1) * (x - x3);
130 double l3_numer = (x - x0) * (x - x1) * (x - x2);
132 double l0_denom = (x0 - x1) * (x0 - x2) * (x0 - x3);
133 double l1_denom = (x1 - x0) * (x1 - x2) * (x1 - x3);
134 double l2_denom = (x2 - x0) * (x2 - x1) * (x2 - x3);
135 double l3_denom = (x3 - x0) * (x3 - x1) * (x3 - x2);
137 double term0 = y0 * l0_numer / l0_denom;
138 double term1 = y1 * l1_numer / l1_denom;
139 double term2 = y2 * l2_numer / l2_denom;
140 double term3 = y3 * l3_numer / l3_denom;
142 return (term0 + term1 + term2 + term3);
147 static int findStraddle(
const double xArr[],
const int len,
const double x)
149 if ((len < 2) || (x < xArr[0]) || (x > xArr[len-1])) {
150 throw std::logic_error(
"invariant violated during interpolation");
152 return(recursiveFindStraddle<A>(xArr, 0, len-1, x));
158 static int recursiveFindStraddle(
const double xArr[],
const int l,
const int r,
const double x)
162 throw std::logic_error(
"lower bound not less than upper bound in search");
164 if ((xArr[l] > x) || (x >= xArr[r])) {
165 throw std::logic_error(
"target value invariant violated in search");
168 if (l+1 == r)
return (l);
170 if (xArr[m] <= x)
return (recursiveFindStraddle<A>(xArr, m, r, x));
171 else return (recursiveFindStraddle<A>(xArr, l, m, x));
189 double CubicInterpolation<A>::usingXArrAndYStride(
const double xArr[],
const int xArrLen,
190 const double yStride,
const double x) {
191 const int xArrLenM1 = xArrLen - 1;
193 if ((xArrLen < 4) || (x < xArr[0]) || (x > xArr[xArrLenM1])) {
194 throw std::logic_error(
"impossible values during interpolaiton");
197 if (x == xArr[xArrLenM1]) {
198 return (yStride * (xArrLenM1));
201 const int offset = findStraddle<A>(xArr, xArrLen, x);
202 const int xArrLenM2 = xArrLen - 2;
203 if ((offset < 0) || (offset > xArrLenM2)) {
204 throw std::logic_error(
"invalid offset during interpolation");
208 return (interpolateUsingXArrAndYStride<A>(xArr, yStride, (offset - 0), x));
210 else if (offset == xArrLenM2) {
211 return (interpolateUsingXArrAndYStride<A>(xArr, yStride, (offset - 2), x));
214 return (interpolateUsingXArrAndYStride<A>(xArr, yStride, (offset - 1), x));
219 static double interpolateUsingXArrAndYStride(
const double xArr[],
const double yStride,
220 const int offset,
const double x) {
221 return cubicInterpolate<A>(
222 xArr[offset + 0], yStride * (offset + 0),
223 xArr[offset + 1], yStride * (offset + 1),
224 xArr[offset + 2], yStride * (offset + 2),
225 xArr[offset + 3], yStride * (offset + 3),
DataSketches namespace.
Definition: binomial_bounds.hpp:38