mathpf 0.7.2__tar.gz → 0.7.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mathpf-0.7.2/src/mathpf.egg-info → mathpf-0.7.3}/PKG-INFO +1 -1
- {mathpf-0.7.2 → mathpf-0.7.3}/src/mathpf/_kernels/mills.cpp +41 -23
- {mathpf-0.7.2 → mathpf-0.7.3}/src/mathpf/_kernels/mills_dd.cpp +5 -5
- {mathpf-0.7.2 → mathpf-0.7.3}/src/mathpf/_mills_coef.h +44 -5
- {mathpf-0.7.2 → mathpf-0.7.3}/src/mathpf/_pyref/mills_cheby.py +79 -32
- {mathpf-0.7.2 → mathpf-0.7.3}/src/mathpf/_pyref/mills_dd.py +5 -5
- {mathpf-0.7.2 → mathpf-0.7.3}/src/mathpf/avg_funcs.c +152 -152
- {mathpf-0.7.2 → mathpf-0.7.3}/src/mathpf/mills.cpp +152 -152
- {mathpf-0.7.2 → mathpf-0.7.3}/src/mathpf/mills_dd.cpp +152 -152
- {mathpf-0.7.2 → mathpf-0.7.3/src/mathpf.egg-info}/PKG-INFO +1 -1
- {mathpf-0.7.2 → mathpf-0.7.3}/src/mathpf.egg-info/SOURCES.txt +7 -1
- mathpf-0.7.3/tests/_ref_table.py +276 -0
- {mathpf-0.7.2 → mathpf-0.7.3}/tests/test_mills.py +7 -45
- mathpf-0.7.3/tests/test_mills_dd_high_prec.py +139 -0
- mathpf-0.7.3/tests/test_mills_high_prec.py +85 -0
- mathpf-0.7.3/tools/_mrdd_cf_probe.py +52 -0
- mathpf-0.7.3/tools/_rrel_seg_explore.py +98 -0
- mathpf-0.7.3/tools/gen_mills_ref.py +212 -0
- {mathpf-0.7.2 → mathpf-0.7.3}/.github/workflows/build_wheels.yml +0 -0
- {mathpf-0.7.2 → mathpf-0.7.3}/.gitignore +0 -0
- {mathpf-0.7.2 → mathpf-0.7.3}/MANIFEST.in +0 -0
- {mathpf-0.7.2 → mathpf-0.7.3}/pyproject.toml +0 -0
- {mathpf-0.7.2 → mathpf-0.7.3}/setup.cfg +0 -0
- {mathpf-0.7.2 → mathpf-0.7.3}/setup.py +0 -0
- {mathpf-0.7.2 → mathpf-0.7.3}/src/mathpf/__init__.py +0 -0
- {mathpf-0.7.2 → mathpf-0.7.3}/src/mathpf/_kernels/CommonMacro.h +0 -0
- {mathpf-0.7.2 → mathpf-0.7.3}/src/mathpf/_kernels/mills.h +0 -0
- {mathpf-0.7.2 → mathpf-0.7.3}/src/mathpf/_kernels/mills_dd.h +0 -0
- {mathpf-0.7.2 → mathpf-0.7.3}/src/mathpf/_pyref/__init__.py +0 -0
- {mathpf-0.7.2 → mathpf-0.7.3}/src/mathpf/avg_funcs.pxd +0 -0
- {mathpf-0.7.2 → mathpf-0.7.3}/src/mathpf/avg_funcs.pyx +0 -0
- {mathpf-0.7.2 → mathpf-0.7.3}/src/mathpf/mills.pxd +0 -0
- {mathpf-0.7.2 → mathpf-0.7.3}/src/mathpf/mills.pyx +0 -0
- {mathpf-0.7.2 → mathpf-0.7.3}/src/mathpf/mills_dd.pxd +0 -0
- {mathpf-0.7.2 → mathpf-0.7.3}/src/mathpf/mills_dd.pyx +0 -0
- {mathpf-0.7.2 → mathpf-0.7.3}/src/mathpf.egg-info/dependency_links.txt +0 -0
- {mathpf-0.7.2 → mathpf-0.7.3}/src/mathpf.egg-info/requires.txt +0 -0
- {mathpf-0.7.2 → mathpf-0.7.3}/src/mathpf.egg-info/top_level.txt +0 -0
- {mathpf-0.7.2 → mathpf-0.7.3}/tests/test_mills_dd.py +0 -0
- {mathpf-0.7.2 → mathpf-0.7.3}/tests/test_pyref_consistency.py +0 -0
- {mathpf-0.7.2 → mathpf-0.7.3}/tools/README.md +0 -0
- {mathpf-0.7.2 → mathpf-0.7.3}/tools/_cancel.py +0 -0
- {mathpf-0.7.2 → mathpf-0.7.3}/tools/_oddcf.py +0 -0
- {mathpf-0.7.2 → mathpf-0.7.3}/tools/_tiers.py +0 -0
- {mathpf-0.7.2 → mathpf-0.7.3}/tools/_wlin.py +0 -0
- {mathpf-0.7.2 → mathpf-0.7.3}/tools/cheby_fit.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mathpf
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.3
|
|
4
4
|
Summary: Numerically stable special functions and primitives (Mills ratio, normalised moment averages, etc.)
|
|
5
5
|
Project-URL: Homepage, https://github.com/quants-net/MathPF
|
|
6
6
|
Requires-Python: >=3.10
|
|
@@ -20,14 +20,22 @@ QNSPACE
|
|
|
20
20
|
using std::exp;
|
|
21
21
|
|
|
22
22
|
/* ----------------------------------------------------------------------
|
|
23
|
-
* MillsRatioRel_below1(x) = (sqrt(pi/2) - R(x))/x on [0, 1].
|
|
24
|
-
*
|
|
23
|
+
* MillsRatioRel_below1(x) = (sqrt(pi/2) - R(x))/x on [0, 1]. 12 uniform
|
|
24
|
+
* segments of degree 7 in C_Rrel; same per-call cost as MillsRatioDeriv1.
|
|
25
|
+
* The two other [0, 1] consumers (MillsRatio, MillsRatioDeriv1) inline the
|
|
26
|
+
* same lookup+Horner pattern, then apply their respective identities:
|
|
27
|
+
* R = sqrt(pi/2) - x * Rrel
|
|
28
|
+
* R1 = 1 - x * R = 1 - x*(sqrt(pi/2) - x*Rrel)
|
|
25
29
|
* ---------------------------------------------------------------------- */
|
|
26
30
|
template<typename T>
|
|
27
31
|
T MillsRatioRel_below1(T x)
|
|
28
32
|
{
|
|
33
|
+
int i = static_cast<int>(T(NSEG_RREL) * x);
|
|
34
|
+
if (i >= NSEG_RREL) i = NSEG_RREL - 1;
|
|
35
|
+
const T s = T(NSEG_RREL) * x - T(i);
|
|
36
|
+
const int o = i * 8;
|
|
29
37
|
const double* c = C_Rrel;
|
|
30
|
-
return (((((((
|
|
38
|
+
return (((((((T(c[o+7]))*s + T(c[o+6]))*s + T(c[o+5]))*s + T(c[o+4]))*s + T(c[o+3]))*s + T(c[o+2]))*s + T(c[o+1]))*s + T(c[o]);
|
|
31
39
|
}
|
|
32
40
|
|
|
33
41
|
/* ----------------------------------------------------------------------
|
|
@@ -94,17 +102,22 @@ QNSPACE
|
|
|
94
102
|
return T(M_SQRT2PI) * exp(T(0.5) * x * x) - MillsRatio(-x);
|
|
95
103
|
}
|
|
96
104
|
if (x <= T(1.0)) {
|
|
105
|
+
i = static_cast<int>(T(NSEG_RREL) * x);
|
|
106
|
+
if (i >= NSEG_RREL) i = NSEG_RREL - 1;
|
|
107
|
+
s = T(NSEG_RREL) * x - T(i);
|
|
108
|
+
o = i * 8;
|
|
97
109
|
c = C_Rrel;
|
|
98
|
-
|
|
110
|
+
const T rrel = (((((((T(c[o+7]))*s + T(c[o+6]))*s + T(c[o+5]))*s + T(c[o+4]))*s + T(c[o+3]))*s + T(c[o+2]))*s + T(c[o+1]))*s + T(c[o]);
|
|
111
|
+
return T(M_SQRT2PI_2) - x * rrel;
|
|
99
112
|
}
|
|
100
113
|
if (x >= T(XCF_R[0])) { /* tiered CF via shared MillsRatio_CF */
|
|
101
|
-
if (x >= T(XCF_R[6])) return T(1.0) / x;
|
|
102
|
-
if (x >= T(XCF_R[5])) return MillsRatio_CF(x,
|
|
103
|
-
if (x >= T(XCF_R[4])) return MillsRatio_CF(x, 4,
|
|
104
|
-
if (x >= T(XCF_R[3])) return MillsRatio_CF(x,
|
|
105
|
-
if (x >= T(XCF_R[2])) return MillsRatio_CF(x,
|
|
106
|
-
if (x >= T(XCF_R[1])) return MillsRatio_CF(x,
|
|
107
|
-
return MillsRatio_CF(x,
|
|
114
|
+
if (x >= T(XCF_R[6])) return T(1.0) / x; /* x >= 67000000: n=0 degenerate */
|
|
115
|
+
if (x >= T(XCF_R[5])) return MillsRatio_CF(x, NCF_R[5], 0); /* x in [548, 67e6): CF n=2 */
|
|
116
|
+
if (x >= T(XCF_R[4])) return MillsRatio_CF(x, NCF_R[4], 0); /* x in [59.3, 548): CF n=4 */
|
|
117
|
+
if (x >= T(XCF_R[3])) return MillsRatio_CF(x, NCF_R[3], 0); /* x in [24.1, 59.3): CF n=6 */
|
|
118
|
+
if (x >= T(XCF_R[2])) return MillsRatio_CF(x, NCF_R[2], 0); /* x in [15.1, 24.1): CF n=8 */
|
|
119
|
+
if (x >= T(XCF_R[1])) return MillsRatio_CF(x, NCF_R[1], 0); /* x in [11.4, 15.1): CF n=10 */
|
|
120
|
+
return MillsRatio_CF(x, NCF_R[0], 0); /* x in [9.5, 11.4): CF n=12 bridge */
|
|
108
121
|
}
|
|
109
122
|
d = T(N_FRAC_R1) + x;
|
|
110
123
|
i = static_cast<int>(T(NSEG_R1) * (x - T(1.0)) / d);
|
|
@@ -130,18 +143,23 @@ QNSPACE
|
|
|
130
143
|
return T(M_SQRT2PI) * (-x) * exp(T(0.5) * x * x) + MillsRatioDeriv1(-x);
|
|
131
144
|
}
|
|
132
145
|
if (x <= T(1.0)) {
|
|
146
|
+
i = static_cast<int>(T(NSEG_RREL) * x);
|
|
147
|
+
if (i >= NSEG_RREL) i = NSEG_RREL - 1;
|
|
148
|
+
s = T(NSEG_RREL) * x - T(i);
|
|
149
|
+
o = i * 8;
|
|
133
150
|
c = C_Rrel;
|
|
134
|
-
|
|
151
|
+
const T rrel = (((((((T(c[o+7]))*s + T(c[o+6]))*s + T(c[o+5]))*s + T(c[o+4]))*s + T(c[o+3]))*s + T(c[o+2]))*s + T(c[o+1]))*s + T(c[o]);
|
|
152
|
+
return T(1.0) - x * (T(M_SQRT2PI_2) - x * rrel);
|
|
135
153
|
}
|
|
136
154
|
if (x >= T(XCF_R1[0])) {
|
|
137
155
|
u = x * x + T(3.0); /* shared with U_MAX guard and MillsRatio_CF */
|
|
138
156
|
if (u > T(U_MAX)) return T(0.0); /* +3 shift invisible at the saturation threshold */
|
|
139
|
-
if (x >= T(XCF_R1[5])) return MillsRatio_CF(u,
|
|
140
|
-
if (x >= T(XCF_R1[4])) return MillsRatio_CF(u, 4,
|
|
141
|
-
if (x >= T(XCF_R1[3])) return MillsRatio_CF(u,
|
|
142
|
-
if (x >= T(XCF_R1[2])) return MillsRatio_CF(u,
|
|
143
|
-
if (x >= T(XCF_R1[1])) return MillsRatio_CF(u,
|
|
144
|
-
return MillsRatio_CF(u,
|
|
157
|
+
if (x >= T(XCF_R1[5])) return MillsRatio_CF(u, NCF_R1[5], 1); /* x >= 12800: CF n=2 */
|
|
158
|
+
if (x >= T(XCF_R1[4])) return MillsRatio_CF(u, NCF_R1[4], 1); /* x in [165, 12800): CF n=4 */
|
|
159
|
+
if (x >= T(XCF_R1[3])) return MillsRatio_CF(u, NCF_R1[3], 1); /* x in [41, 165): CF n=6 */
|
|
160
|
+
if (x >= T(XCF_R1[2])) return MillsRatio_CF(u, NCF_R1[2], 1); /* x in [21.2, 41): CF n=8 */
|
|
161
|
+
if (x >= T(XCF_R1[1])) return MillsRatio_CF(u, NCF_R1[1], 1); /* x in [14.5, 21.2): CF n=10 */
|
|
162
|
+
return MillsRatio_CF(u, NCF_R1[0], 1); /* x in [11.5, 14.5): CF n=12 bridge */
|
|
145
163
|
}
|
|
146
164
|
d = T(N_FRAC_R1) + x;
|
|
147
165
|
i = static_cast<int>(T(NSEG_R1) * (x - T(1.0)) / d);
|
|
@@ -169,11 +187,11 @@ QNSPACE
|
|
|
169
187
|
if (x >= T(XCF_R3[0])) {
|
|
170
188
|
u = x * x + T(3.0);
|
|
171
189
|
if (u > T(U_MAX)) return T(0.0);
|
|
172
|
-
if (x >= T(XCF_R3[4])) return MillsRatio_CF(u, 4,
|
|
173
|
-
if (x >= T(XCF_R3[3])) return MillsRatio_CF(u,
|
|
174
|
-
if (x >= T(XCF_R3[2])) return MillsRatio_CF(u,
|
|
175
|
-
if (x >= T(XCF_R3[1])) return MillsRatio_CF(u,
|
|
176
|
-
return MillsRatio_CF(u,
|
|
190
|
+
if (x >= T(XCF_R3[4])) return MillsRatio_CF(u, NCF_R3[4], 3); /* x >= 17300: CF n=4 */
|
|
191
|
+
if (x >= T(XCF_R3[3])) return MillsRatio_CF(u, NCF_R3[3], 3); /* x in [210, 17300): CF n=6 */
|
|
192
|
+
if (x >= T(XCF_R3[2])) return MillsRatio_CF(u, NCF_R3[2], 3); /* x in [50.5, 210): CF n=8 */
|
|
193
|
+
if (x >= T(XCF_R3[1])) return MillsRatio_CF(u, NCF_R3[1], 3); /* x in [25.4, 50.5): CF n=10 */
|
|
194
|
+
return MillsRatio_CF(u, NCF_R3[0], 3); /* x in [17.1, 25.4): CF n=12 bridge */
|
|
177
195
|
}
|
|
178
196
|
d = T(N_FRAC_R3) + x;
|
|
179
197
|
i = static_cast<int>(x / d * T(NSEG_R3));
|
|
@@ -79,16 +79,16 @@ QNSPACE
|
|
|
79
79
|
/* Asymp CF DD ladder, even-only n aligned with R_hat_1's CF cutoffs
|
|
80
80
|
* XCF_R1[5..2] = 12800, 165, 41, 21.2. Falls through to Taylor when
|
|
81
81
|
* a < XCF_R1[2] = 21.2. */
|
|
82
|
-
if (a >= T(XCF_R1[5])) return MillsRatioDiff_CF<T>(x, dx,
|
|
83
|
-
else if (a >= T(XCF_R1[4])) return MillsRatioDiff_CF<T>(x, dx, 4); /* a
|
|
84
|
-
else if (a >= T(XCF_R1[3])) return MillsRatioDiff_CF<T>(x, dx,
|
|
85
|
-
else if (a >= T(XCF_R1[2])) return MillsRatioDiff_CF<T>(x, dx,
|
|
82
|
+
if (a >= T(XCF_R1[5])) return MillsRatioDiff_CF<T>(x, dx, NCF_R1[5]); /* a >= 12800: CF n=2 */
|
|
83
|
+
else if (a >= T(XCF_R1[4])) return MillsRatioDiff_CF<T>(x, dx, NCF_R1[4]); /* a in [165, 12800): CF n=4 */
|
|
84
|
+
else if (a >= T(XCF_R1[3])) return MillsRatioDiff_CF<T>(x, dx, NCF_R1[3]); /* a in [41, 165): CF n=6 */
|
|
85
|
+
else if (a >= T(XCF_R1[2])) return MillsRatioDiff_CF<T>(x, dx, NCF_R1[2]); /* a in [21.2, 41): CF n=8 */
|
|
86
86
|
|
|
87
87
|
/* a < 21.2: 5-term Taylor seeded by R''' (N=5 balance, ~38 eps at gate) */
|
|
88
88
|
T u = x * x + T(3.0); /* shared shifted variable */
|
|
89
89
|
T r_d3;
|
|
90
90
|
if (x >= T(XCF_R3[0])) /* x in [17.1, ~22): CF n=12 directly */
|
|
91
|
-
r_d3 = MillsRatio_CF<T>(u,
|
|
91
|
+
r_d3 = MillsRatio_CF<T>(u, NCF_R3[0], 3);
|
|
92
92
|
else /* x < 17.1: segmented Chebyshev path */
|
|
93
93
|
r_d3 = MillsRatioDeriv3<T>(x);
|
|
94
94
|
T r_d1 = (r_d3 + T(1.0)) / u; /* descend: -R'(x), cancellation-free */
|
|
@@ -9,9 +9,19 @@ inline constexpr double M_SQRT2PI_2 = 1.2533141373155001; /* R(0) = sqrt(pi/2)
|
|
|
9
9
|
inline constexpr double U_MAX = 1.3407807929942596e+154; /* sqrt(DBL_MAX); R1/R3 -> 0 beyond */
|
|
10
10
|
inline constexpr double X_NEG_MAX = -37.5; /* x < this: R/R1/R3 reflection's exp(x^2/2) overflows; saturate to +inf */
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
/* XCF_R* ladders: lower-edge cutoffs for each CF tier. XCF_R*[0] is the
|
|
13
|
+
* bridge entry (smallest x in CF region); subsequent entries are tier
|
|
14
|
+
* boundaries. NCF_R* are parallel arrays giving the CF order n_terms to
|
|
15
|
+
* use at each tier (NCF_R*[k] applies when x >= XCF_R*[k] and x < XCF_R*[k+1];
|
|
16
|
+
* the last entry of NCF_R covers x above the last XCF_R cutoff). */
|
|
17
|
+
inline constexpr double XCF_R[7] = {9.5, 11.4, 15.1, 24.1, 59.3, 548.0, 67000000.0};
|
|
18
|
+
inline constexpr int NCF_R[7] = { 12, 10, 8, 6, 4, 2, 0};
|
|
19
|
+
|
|
20
|
+
inline constexpr double XCF_R1[6] = {11.5, 14.5, 21.2, 41.0, 165.0, 12800.0};
|
|
21
|
+
inline constexpr int NCF_R1[6] = { 12, 10, 8, 6, 4, 2};
|
|
22
|
+
|
|
23
|
+
inline constexpr double XCF_R3[5] = {17.1, 25.4, 50.5, 210.0, 17300.0};
|
|
24
|
+
inline constexpr int NCF_R3[5] = { 12, 10, 8, 6, 4};
|
|
15
25
|
|
|
16
26
|
inline constexpr double N_FRAC_R1 = 2.5;
|
|
17
27
|
inline constexpr int NSEG_R1 = 32;
|
|
@@ -20,8 +30,37 @@ inline constexpr double N_FRAC_R3 = 3.5;
|
|
|
20
30
|
inline constexpr int NSEG_R3 = 50;
|
|
21
31
|
inline constexpr int TMAX_R3 = 45;
|
|
22
32
|
|
|
23
|
-
/* Rrel_below1: deg-
|
|
24
|
-
|
|
33
|
+
/* Rrel_below1: deg-7, 12 uniform segments on [0, 1]; max per-seg rel-err = 7.13e-17.
|
|
34
|
+
* Per-call cost matches R1 (8 Horner mults + 1 segment lookup), down from the
|
|
35
|
+
* previous deg-14 single-segment form (14 mults). Also speeds up R(x) and
|
|
36
|
+
* R1(x) at small x since both use the identity R = sqrt(pi/2) - x * Rrel_below1. */
|
|
37
|
+
inline constexpr int NSEG_RREL = 12;
|
|
38
|
+
inline constexpr double C_Rrel[96] = {
|
|
39
|
+
0.99999999999999989, -0.052221422388137158, 0.002314814814632304, -9.066219018308359e-05,
|
|
40
|
+
3.2150148093635393e-06, -1.049207214667232e-07, 3.1747412868461658e-09, -8.1818321557437068e-11,
|
|
41
|
+
0.95000584342332284, -0.04785142539805684, 0.0020611150286913332, -7.8790704394343048e-05,
|
|
42
|
+
2.7351696394277882e-06, -8.7568840012488809e-08, 2.6040490377601506e-09, -6.6128211226567048e-11,
|
|
43
|
+
0.90413939248828323, -0.043955049458090562, 0.0018403159170131999, -6.8675945685293206e-05,
|
|
44
|
+
2.3340724416270501e-06, -7.3316002324167622e-08, 2.1427519540086741e-09, -5.3618158471580657e-11,
|
|
45
|
+
0.86195824584709368, -0.040471463270170725, 0.001647590369901791, -6.0031835892380922e-05,
|
|
46
|
+
1.9977576684326855e-06, -6.1571686018192153e-08, 1.7686869030624921e-09, -4.3611606027074922e-11,
|
|
47
|
+
0.8230762790219901, -0.037348684558952627, 0.0014788913058506813, -5.2622673426225258e-05,
|
|
48
|
+
1.7149036061140052e-06, -5.1864346992849886e-08, 1.464404082345293e-09, -3.558226982637687e-11,
|
|
49
|
+
0.7871555275635429, -0.03454216113748549, 0.0013308152825848647, -4.6253658706491024e-05,
|
|
50
|
+
1.4763029262718868e-06, -4.381624734045847e-08, 1.2161205298368843e-09, -2.9119444573423483e-11,
|
|
51
|
+
0.75389936172361582, -0.032013598325074694, 0.0012004915918592111, -4.0763305386601887e-05,
|
|
52
|
+
1.2744446141417648e-06, -3.7123845055879282e-08, 1.0129151506068687e-09, -2.3901605254302183e-11,
|
|
53
|
+
0.72304672999479636, -0.029729986988100948, 0.0010854917967352113, -3.6017342938875408e-05,
|
|
54
|
+
1.1031827972270407e-06, -3.1542467834696725e-08, 8.461075312198616e-10, -1.96762563556725e-11,
|
|
55
|
+
0.69436728992725238, -0.027662795465682701, 0.00098375571844156904, -3.1903802382321565e-05,
|
|
56
|
+
9.5747359208258599e-07, -2.6874297328552898e-08, 7.0877706144625224e-10, -1.6244501366989223e-11,
|
|
57
|
+
0.66765727766945626, -0.025787295774111246, 0.00089353070040033291, -2.832904354394483e-05,
|
|
58
|
+
8.331653564502964e-07, -2.2958919563475081e-08, 5.9538950878966358e-10, -1.3449189871286501e-11,
|
|
59
|
+
0.6427359943405786, -0.024082000158919439, 0.0008133216211253367, -2.5214533869796095e-05,
|
|
60
|
+
7.2683100257424873e-07, -1.9665870750764083e-08, 5.0150614189839877e-10, -1.1165784642725488e-11,
|
|
61
|
+
0.61944280892438686, -0.022528188592743449, 0.00074184963493787457, -2.249422893909321e-05,
|
|
62
|
+
6.3563353781433684e-07, -1.6888739426799828e-08, 4.2355646646197732e-10, -9.2953031295141281e-12,
|
|
63
|
+
};
|
|
25
64
|
/* R1 = -R': flat 26 x 8 (deg-7); bucket i = C_R1[i*8+k] */
|
|
26
65
|
inline constexpr double C_R1[208] = {0.34432045758120156, -0.03405489990411223, 0.001192475013485524, -1.3635915460280841e-05, -1.3251365677088036e-07, 2.4578598186034305e-09, 4.7259798016565235e-11, -2.1299291732726891e-13, 0.3114442667663644, -0.031711375106782305, 0.0011507974681864693, -1.4140453769849712e-05, -1.1952291224066734e-07, 2.7367623481353177e-09, 4.577568410470565e-11, -3.4644867471321874e-13, 0.28086943193327807, -0.029452665667327314, 0.0011076870163868847, -1.4590274431017942e-05, -1.051645883314536e-07, 3.00394263963843e-09, 4.3356088452077136e-11, -4.908348064347212e-13, 0.25250976089012617, -0.02728146783978619, 0.001063315885024093, -1.4980043440399068e-05, -8.9511711273763e-08, 3.2535620231815327e-09, 3.9923965131252817e-11, -6.434215671525449e-13, 0.22627654267305497, -0.025200117744054493, 0.0010178718054031299, -1.5304778731445228e-05, -7.266756081693456e-08, 3.4793782218609222e-09, 3.542133108597344e-11, -8.005004273636312e-13, 0.2020789228021104, -0.023210561535870394, 0.0009715567721355419, -1.555997480906793e-05, -5.476736805112463e-08, 3.6748803621119108e-09, 2.981614382368417e-11, -9.573261822764798e-13, 0.1798243069999376, -0.021314328438901478, 0.0009245854194418766, -1.574173268587291e-05, -3.597923298071676e-08, 3.833466388717661e-09, 2.3109595935902425e-11, -1.108115098551026e-12, 0.15941879012402702, -0.019512507416774686, 0.0008771830040236347, -1.5846891568595946e-05, -1.650404553414359e-08, 3.948664179564567e-09, 1.5343435068724515e-11, -1.2461203413548787e-12, 0.14076760627842333, -0.01780572827295679, 0.0008295829956692178, -1.587315787368715e-05, 3.4258061653874034e-09, 4.014394860143601e-09, 6.6067680330346175e-12, -1.3638064663876794e-12, 0.12377559528870606, -0.01619414794994658, 0.0007820242912950428, -1.5819226312877644e-05, 2.3549140060769075e-08, 4.025273115508551e-09, -2.958346618579145e-12, -1.4531425859246267e-12, 0.10834767997374334, -0.014677442751291432, 0.0007347480850363722, -1.568488705701397e-05, 4.3580259611923756e-08, 3.976934719948031e-09, -1.3153353021684132e-11, -1.5060277702761603e-12, 0.0943893479629662, -0.013254807126140003, 0.0006879944458428944, -1.547111245079173e-05, 6.321490918831119e-08, 3.8663762221956915e-09, -2.3722632943972796e-11, -1.5148512230532907e-12, 0.08180713122626623, -0.011924959533228441, 0.0006419986740560224, -1.5180116517391639e-05, 8.213791675062653e-08, 3.6922860926877568e-09, -3.4356875881364274e-11, -1.4731730171396532e-12, 0.07050907604494921, -0.010686155738024478, 0.0005969875285749982, -1.48153806721575e-05, 1.0003241787830908e-07, 3.4553412408264596e-09, -4.4701242481255216e-11, -1.3764887281773427e-12, 0.06040519589650897, -0.009536209694355962, 0.0005531754350527934, -1.438163976502519e-05, 1.1659041314902527e-07, 3.158438467770723e-09, -5.436892460793421e-11, -1.2230145032238319e-12, 0.051407899690700455, -0.008472521924474962, 0.0005107608014036381, -1.3884823877572707e-05, 1.3152425187566604e-07, 2.806828171228694e-09, -6.296026047136019e-11, -1.014401164890225e-12, 0.04343238801085694, -0.007492115047014164, 0.0004699225778571462, -1.3331953255339888e-05, 1.4457847261351243e-07, 2.408118619722417e-09, -7.008691905435431e-11, -7.562622998141824e-13, 0.03639701050419264, -0.006591675822397399, 0.00043081720292740893, -1.273098633749718e-05, 1.5554128375514165e-07, 1.972124460314804e-09, -7.539985358319632e-11, -4.583894179026021e-13, 0.03022357833593512, -0.0057676028054052825, 0.00039357607223790807, -1.2090623945587052e-05, 1.6425485980300317e-07, 1.510543578358e-09, -7.861882135731254e-11, -1.3453580375042955e-13, 0.024837626665472186, -0.005016058433263478, 0.0003583036528881787, -1.1420076101325395e-05, 1.706235866941693e-07, 1.036462079424263e-09, -7.95604210426085e-11, 1.9831276835300475e-13, 0.020168623389682224, -0.004333024155107946, 0.00032507634148359177, -1.072880134841987e-05, 1.746194370082991e-07, 5.637070820781498e-10, -7.816100808861748e-11, 5.211942931994726e-13, 0.016150121880213728, -0.0037143570452199816, 0.0002939421296615079, -1.002623145989574e-05, 1.7628380941330315e-07, 1.0608900697596745e-10, -7.449073982704427e-11, 8.148726397980141e-13, 0.01271985704941791, -0.003155846255834055, 0.0002649210987800892, -9.321496586034821e-06, 1.7572542851795311e-07, -3.234043106873131e-10, -6.875556935207283e-11, 1.061797613056228e-12, 0.009819785730108346, -0.002653267668440114, 0.00023800671851479017, -8.62316683305915e-06, 1.7311425406524061e-07, -7.133843445508475e-10, -6.12853392609736e-11, 1.2480422998988533e-12, 0.007396073954182386, -0.0022024352007907985, 0.00021316787662600472, -7.93902566639996e-06, 1.6867175299844368e-07, -1.0547269597103247e-09, -5.250812569094551e-11, 1.364889655169418e-12, 0.005399035170233996, -0.0017992474166552762, 0.00019035152391663708, -7.275888307985233e-06, 1.626582865548259e-07, -1.3410511347824749e-09, -4.2913325720609484e-11, 1.409765189350702e-12};
|
|
27
66
|
/* R3 = -R''': flat 45 x 9 (deg-8); bucket i = C_R3[i*9+k] */
|
|
@@ -18,20 +18,49 @@ from array import array
|
|
|
18
18
|
|
|
19
19
|
M_SQRT2PI = 2.5066282746310002
|
|
20
20
|
M_SQRT2PI_2 = 1.2533141373155001 # R(0) = sqrt(pi/2) = M_SQRT2PI/2
|
|
21
|
-
XCF_R = (9.5, 11.4, 15.1, 24.1, 59.3, 548.0, 67000000.0)
|
|
21
|
+
XCF_R = (9.5, 11.4, 15.1, 24.1, 59.3, 548.0, 67000000.0)
|
|
22
|
+
NCF_R = (12, 10, 8, 6, 4, 2, 0) # CF order paired with each XCF_R tier
|
|
22
23
|
# _U_MAX = sqrt(DBL_MAX) ~ 1.34e154. Past it x*x overflows the quadratic CF
|
|
23
24
|
# denominators of R1/R3; there the functions are ~0, so the guard returns 0.
|
|
24
25
|
_U_MAX = math.sqrt(sys.float_info.max)
|
|
25
26
|
|
|
26
|
-
# --- Rrel_below1: the [0,1] primitive shared by R and R1
|
|
27
|
-
#
|
|
28
|
-
#
|
|
29
|
-
|
|
27
|
+
# --- Rrel_below1: the [0,1] primitive shared by R and R1 ---
|
|
28
|
+
# Deg-7 in 12 uniform segments on [0, 1]; bucket i = C_Rrel[i*8 + k], lookup by
|
|
29
|
+
# i = floor(x * NSEG_RREL), local coord s = x*NSEG_RREL - i. Same per-call cost
|
|
30
|
+
# as R1 (8 Horner mults + 1 lookup); was deg-14 single segment (14 mults).
|
|
31
|
+
NSEG_RREL = 12
|
|
32
|
+
C_Rrel = array('d', (
|
|
33
|
+
0.99999999999999989, -0.052221422388137158, 0.002314814814632304, -9.066219018308359e-05,
|
|
34
|
+
3.2150148093635393e-06, -1.049207214667232e-07, 3.1747412868461658e-09, -8.1818321557437068e-11,
|
|
35
|
+
0.95000584342332284, -0.04785142539805684, 0.0020611150286913332, -7.8790704394343048e-05,
|
|
36
|
+
2.7351696394277882e-06, -8.7568840012488809e-08, 2.6040490377601506e-09, -6.6128211226567048e-11,
|
|
37
|
+
0.90413939248828323, -0.043955049458090562, 0.0018403159170131999, -6.8675945685293206e-05,
|
|
38
|
+
2.3340724416270501e-06, -7.3316002324167622e-08, 2.1427519540086741e-09, -5.3618158471580657e-11,
|
|
39
|
+
0.86195824584709368, -0.040471463270170725, 0.001647590369901791, -6.0031835892380922e-05,
|
|
40
|
+
1.9977576684326855e-06, -6.1571686018192153e-08, 1.7686869030624921e-09, -4.3611606027074922e-11,
|
|
41
|
+
0.8230762790219901, -0.037348684558952627, 0.0014788913058506813, -5.2622673426225258e-05,
|
|
42
|
+
1.7149036061140052e-06, -5.1864346992849886e-08, 1.464404082345293e-09, -3.558226982637687e-11,
|
|
43
|
+
0.7871555275635429, -0.03454216113748549, 0.0013308152825848647, -4.6253658706491024e-05,
|
|
44
|
+
1.4763029262718868e-06, -4.381624734045847e-08, 1.2161205298368843e-09, -2.9119444573423483e-11,
|
|
45
|
+
0.75389936172361582, -0.032013598325074694, 0.0012004915918592111, -4.0763305386601887e-05,
|
|
46
|
+
1.2744446141417648e-06, -3.7123845055879282e-08, 1.0129151506068687e-09, -2.3901605254302183e-11,
|
|
47
|
+
0.72304672999479636, -0.029729986988100948, 0.0010854917967352113, -3.6017342938875408e-05,
|
|
48
|
+
1.1031827972270407e-06, -3.1542467834696725e-08, 8.461075312198616e-10, -1.96762563556725e-11,
|
|
49
|
+
0.69436728992725238, -0.027662795465682701, 0.00098375571844156904, -3.1903802382321565e-05,
|
|
50
|
+
9.5747359208258599e-07, -2.6874297328552898e-08, 7.0877706144625224e-10, -1.6244501366989223e-11,
|
|
51
|
+
0.66765727766945626, -0.025787295774111246, 0.00089353070040033291, -2.832904354394483e-05,
|
|
52
|
+
8.331653564502964e-07, -2.2958919563475081e-08, 5.9538950878966358e-10, -1.3449189871286501e-11,
|
|
53
|
+
0.6427359943405786, -0.024082000158919439, 0.0008133216211253367, -2.5214533869796095e-05,
|
|
54
|
+
7.2683100257424873e-07, -1.9665870750764083e-08, 5.0150614189839877e-10, -1.1165784642725488e-11,
|
|
55
|
+
0.61944280892438686, -0.022528188592743449, 0.00074184963493787457, -2.249422893909321e-05,
|
|
56
|
+
6.3563353781433684e-07, -1.6888739426799828e-08, 4.2355646646197732e-10, -9.2953031295141281e-12,
|
|
57
|
+
))
|
|
30
58
|
|
|
31
59
|
# --- R / R1: hybrid split at x=1 (memory-minimal; see emit_R_R1_Rrel) ---
|
|
32
60
|
# x<=1: use C_Rrel above. x>1: R1 has a deg-7 table (C_R1) in t=(x-1)/(N_FRAC_R1+x),
|
|
33
61
|
# R = (1-R1)/x. Beyond x_cf each uses its own tiered CF (XCF_R at top, XCF_R1 below).
|
|
34
|
-
XCF_R1 = (11.5, 14.5, 21.2, 41.0, 165.0, 12800.0)
|
|
62
|
+
XCF_R1 = (11.5, 14.5, 21.2, 41.0, 165.0, 12800.0)
|
|
63
|
+
NCF_R1 = (12, 10, 8, 6, 4, 2) # CF order paired with each XCF_R1 tier
|
|
35
64
|
N_FRAC_R1 = 2.5 # shifted-t scale: t = (x-1)/(N_FRAC_R1 + x), t=0 at x=1
|
|
36
65
|
NSEG_R1 = 32 # equal t-buckets over [0,1] (XCF-independent partition)
|
|
37
66
|
TMAX_R1 = 26 # stored buckets 0..TMAX_R1-1 of C_R1; cover x in [1, XMAX_R1]
|
|
@@ -71,7 +100,8 @@ C_R1 = array('d', (
|
|
|
71
100
|
# equal buckets (FIXED partition). i = int(x/(N_FRAC_R3+x)*NSEG_R3); local coordinate
|
|
72
101
|
# s = ((NSEG_R3-i)*x - i*N_FRAC_R3)/(N_FRAC_R3+x) (not NSEG*w-i) keeps precision at large x.
|
|
73
102
|
N_FRAC_R3 = 3.5 # w-bucket scale: w = x/(N_FRAC_R3 + x)
|
|
74
|
-
XCF_R3 = (17.1, 25.4, 50.5, 210.0, 17300.0)
|
|
103
|
+
XCF_R3 = (17.1, 25.4, 50.5, 210.0, 17300.0) # XCF_R3[0] in bucket ~37
|
|
104
|
+
NCF_R3 = (12, 10, 8, 6, 4) # CF order paired with each XCF_R3 tier
|
|
75
105
|
NSEG_R3 = 50 # total equal-width buckets of w=x/(N_FRAC_R3+x) over [0,1] (XCF-independent)
|
|
76
106
|
TMAX_R3 = 45 # coefficients cover buckets 0..TMAX_R3-1, i.e. t in [0, TMAX_R3)
|
|
77
107
|
XMAX_R3 = 31.5 # max x covered by C_R3 (~1.24x bridge); XCF_R3[0] may rise to XMAX_R3 w/o refit
|
|
@@ -127,10 +157,15 @@ C_R3 = array('d', (
|
|
|
127
157
|
|
|
128
158
|
|
|
129
159
|
def Rrel_below1(x):
|
|
130
|
-
"""Rrel_below1(x) = (sqrt(pi/2) - R(x))/x for x in [0,1] (
|
|
131
|
-
R(x) = M_SQRT2PI_2 - x*Rrel_below1(x).
|
|
160
|
+
"""Rrel_below1(x) = (sqrt(pi/2) - R(x))/x for x in [0,1] (12 segments,
|
|
161
|
+
deg-7 each, >0); R(x) = M_SQRT2PI_2 - x*Rrel_below1(x). Rrel_below1(0) = 1."""
|
|
162
|
+
i = int(NSEG_RREL * x)
|
|
163
|
+
if i >= NSEG_RREL:
|
|
164
|
+
i = NSEG_RREL - 1
|
|
165
|
+
s = NSEG_RREL * x - i
|
|
166
|
+
o = i * 8
|
|
132
167
|
c = C_Rrel
|
|
133
|
-
return (((((((
|
|
168
|
+
return (((((((c[o+7])*s + c[o+6])*s + c[o+5])*s + c[o+4])*s + c[o+3])*s + c[o+2])*s + c[o+1])*s + c[o]
|
|
134
169
|
|
|
135
170
|
|
|
136
171
|
def R013_CF(x_or_u, n, d):
|
|
@@ -198,17 +233,23 @@ def R(x):
|
|
|
198
233
|
"""Mills ratio R(x) = N(-x)/n(x), scalar float (any sign)."""
|
|
199
234
|
if x < 0.0:
|
|
200
235
|
return M_SQRT2PI * math.exp(0.5 * x * x) - R(-x)
|
|
201
|
-
if x <= 1.0: # R = sqrt(pi/2) - x*Rrel_below1(x) (inlined)
|
|
236
|
+
if x <= 1.0: # R = sqrt(pi/2) - x*Rrel_below1(x) (inlined segmented)
|
|
237
|
+
i = int(NSEG_RREL * x)
|
|
238
|
+
if i >= NSEG_RREL:
|
|
239
|
+
i = NSEG_RREL - 1
|
|
240
|
+
s = NSEG_RREL * x - i
|
|
241
|
+
o = i * 8
|
|
202
242
|
c = C_Rrel
|
|
203
|
-
|
|
243
|
+
rrel = (((((((c[o+7])*s + c[o+6])*s + c[o+5])*s + c[o+4])*s + c[o+3])*s + c[o+2])*s + c[o+1])*s + c[o]
|
|
244
|
+
return M_SQRT2PI_2 - x * rrel
|
|
204
245
|
if x >= XCF_R[0]: # tiered CF convergents (shared with R1, R3 via R013_CF)
|
|
205
|
-
if x >= XCF_R[6]: return 1.0 / x
|
|
206
|
-
if x >= XCF_R[5]: return R013_CF(x,
|
|
207
|
-
if x >= XCF_R[4]: return R013_CF(x,
|
|
208
|
-
if x >= XCF_R[3]: return R013_CF(x,
|
|
209
|
-
if x >= XCF_R[2]: return R013_CF(x,
|
|
210
|
-
if x >= XCF_R[1]: return R013_CF(x,
|
|
211
|
-
return R013_CF(x,
|
|
246
|
+
if x >= XCF_R[6]: return 1.0 / x # x >= 67000000: n=0 degenerate
|
|
247
|
+
if x >= XCF_R[5]: return R013_CF(x, NCF_R[5], 0) # x in [548, 67e6): CF n=2
|
|
248
|
+
if x >= XCF_R[4]: return R013_CF(x, NCF_R[4], 0) # x in [59.3, 548): CF n=4
|
|
249
|
+
if x >= XCF_R[3]: return R013_CF(x, NCF_R[3], 0) # x in [24.1, 59.3): CF n=6
|
|
250
|
+
if x >= XCF_R[2]: return R013_CF(x, NCF_R[2], 0) # x in [15.1, 24.1): CF n=8
|
|
251
|
+
if x >= XCF_R[1]: return R013_CF(x, NCF_R[1], 0) # x in [11.4, 15.1): CF n=10
|
|
252
|
+
return R013_CF(x, NCF_R[0], 0) # x in [9.5, 11.4): CF n=12 bridge
|
|
212
253
|
d = N_FRAC_R1 + x # 1 < x < XCF_R[0]: R = (1 - R1)/x, R1 from C_R1
|
|
213
254
|
i = int(NSEG_R1 * (x - 1.0) / d)
|
|
214
255
|
if i >= TMAX_R1:
|
|
@@ -223,18 +264,24 @@ def R1(x):
|
|
|
223
264
|
"""R1(x) = 1 - x R(x) = -R'(x), scalar float (any sign)."""
|
|
224
265
|
if x < 0.0: # reflection: R1(x) = R1(-x) - M_SQRT2PI*x*exp(x^2/2)
|
|
225
266
|
return M_SQRT2PI * (-x) * math.exp(0.5 * x * x) + R1(-x)
|
|
226
|
-
if x <= 1.0: # R1 = 1 - x*R, R = sqrt(pi/2)-x*Rrel_below1 (inlined)
|
|
267
|
+
if x <= 1.0: # R1 = 1 - x*R, R = sqrt(pi/2)-x*Rrel_below1 (inlined segmented)
|
|
268
|
+
i = int(NSEG_RREL * x)
|
|
269
|
+
if i >= NSEG_RREL:
|
|
270
|
+
i = NSEG_RREL - 1
|
|
271
|
+
s = NSEG_RREL * x - i
|
|
272
|
+
o = i * 8
|
|
227
273
|
c = C_Rrel
|
|
228
|
-
|
|
274
|
+
rrel = (((((((c[o+7])*s + c[o+6])*s + c[o+5])*s + c[o+4])*s + c[o+3])*s + c[o+2])*s + c[o+1])*s + c[o]
|
|
275
|
+
return 1.0 - x * (M_SQRT2PI_2 - x * rrel)
|
|
229
276
|
if x >= XCF_R1[0]:
|
|
230
277
|
u = x*x + 3.0 # kernel's shifted variable; shared with _U_MAX guard and R013_CF
|
|
231
278
|
if u > _U_MAX: return 0.0 # +3 shift in threshold is invisible (_U_MAX >> 3 at saturation)
|
|
232
|
-
if x >= XCF_R1[5]: return R013_CF(u,
|
|
233
|
-
if x >= XCF_R1[4]: return R013_CF(u,
|
|
234
|
-
if x >= XCF_R1[3]: return R013_CF(u,
|
|
235
|
-
if x >= XCF_R1[2]: return R013_CF(u,
|
|
236
|
-
if x >= XCF_R1[1]: return R013_CF(u,
|
|
237
|
-
return R013_CF(u,
|
|
279
|
+
if x >= XCF_R1[5]: return R013_CF(u, NCF_R1[5], 1) # x >= 12800: CF n=2
|
|
280
|
+
if x >= XCF_R1[4]: return R013_CF(u, NCF_R1[4], 1) # x in [165, 12800): CF n=4
|
|
281
|
+
if x >= XCF_R1[3]: return R013_CF(u, NCF_R1[3], 1) # x in [41, 165): CF n=6
|
|
282
|
+
if x >= XCF_R1[2]: return R013_CF(u, NCF_R1[2], 1) # x in [21.2, 41): CF n=8
|
|
283
|
+
if x >= XCF_R1[1]: return R013_CF(u, NCF_R1[1], 1) # x in [14.5, 21.2): CF n=10
|
|
284
|
+
return R013_CF(u, NCF_R1[0], 1) # x in [11.5, 14.5): CF n=12 bridge
|
|
238
285
|
d = N_FRAC_R1 + x # 1 < x < XCF_R1[0]: deg-7 t-bucket
|
|
239
286
|
i = int(NSEG_R1 * (x - 1.0) / d)
|
|
240
287
|
if i >= TMAX_R1:
|
|
@@ -252,11 +299,11 @@ def R3(x):
|
|
|
252
299
|
if x >= XCF_R3[0]:
|
|
253
300
|
u = x*x + 3.0 # kernel's shifted variable; shared with _U_MAX guard and R013_CF
|
|
254
301
|
if u > _U_MAX: return 0.0 # +3 shift in threshold is invisible (_U_MAX >> 3 at saturation)
|
|
255
|
-
if x >= XCF_R3[4]: return R013_CF(u,
|
|
256
|
-
if x >= XCF_R3[3]: return R013_CF(u,
|
|
257
|
-
if x >= XCF_R3[2]: return R013_CF(u,
|
|
258
|
-
if x >= XCF_R3[1]: return R013_CF(u,
|
|
259
|
-
return R013_CF(u,
|
|
302
|
+
if x >= XCF_R3[4]: return R013_CF(u, NCF_R3[4], 3) # x >= 17300: CF n=4
|
|
303
|
+
if x >= XCF_R3[3]: return R013_CF(u, NCF_R3[3], 3) # x in [210, 17300): CF n=6
|
|
304
|
+
if x >= XCF_R3[2]: return R013_CF(u, NCF_R3[2], 3) # x in [50.5, 210): CF n=8
|
|
305
|
+
if x >= XCF_R3[1]: return R013_CF(u, NCF_R3[1], 3) # x in [25.4, 50.5): CF n=10
|
|
306
|
+
return R013_CF(u, NCF_R3[0], 3) # x in [17.1, 25.4): CF n=12 bridge
|
|
260
307
|
d = N_FRAC_R3 + x
|
|
261
308
|
i = int(x / d * NSEG_R3)
|
|
262
309
|
s = ((NSEG_R3 - i) * x - i * N_FRAC_R3) / d
|
|
@@ -68,14 +68,14 @@ def R_DD(x, dx, theta=1):
|
|
|
68
68
|
# Asymp CF DD ladder, even-only n aligned with R_hat_1's CF convergent rate (n+1)!/a^(2n) ~ eps:
|
|
69
69
|
# thresholds are exactly R_hat_1's CF cutoffs at n = 2, 4, 6, 8 (mc.XCF_R1[5..2]). Falls
|
|
70
70
|
# through to Taylor when a < mc.XCF_R1[2] (= 21.2).
|
|
71
|
-
if a >= mc.XCF_R1[5]: return R_DD_CF(x, dx,
|
|
72
|
-
elif a >= mc.XCF_R1[4]: return R_DD_CF(x, dx, 4) # a
|
|
73
|
-
elif a >= mc.XCF_R1[3]: return R_DD_CF(x, dx,
|
|
74
|
-
elif a >= mc.XCF_R1[2]: return R_DD_CF(x, dx,
|
|
71
|
+
if a >= mc.XCF_R1[5]: return R_DD_CF(x, dx, mc.NCF_R1[5]) # a >= 12800: CF n=2
|
|
72
|
+
elif a >= mc.XCF_R1[4]: return R_DD_CF(x, dx, mc.NCF_R1[4]) # a in [165, 12800): CF n=4
|
|
73
|
+
elif a >= mc.XCF_R1[3]: return R_DD_CF(x, dx, mc.NCF_R1[3]) # a in [41, 165): CF n=6
|
|
74
|
+
elif a >= mc.XCF_R1[2]: return R_DD_CF(x, dx, mc.NCF_R1[2]) # a in [21.2, 41): CF n=8 bottom row
|
|
75
75
|
# a < mc.XCF_R1[2] (21.2): 5-term Taylor seeded by R''' (N=5 balance, ~38 eps at gate)
|
|
76
76
|
u = x*x + 3.0 # kernel's shifted variable; shared with R013_CF, descent, and ascent
|
|
77
77
|
if x >= _R3_XCF: # x in [17.1, ~22): mc.R3's CF n=12 path; call directly with our u
|
|
78
|
-
r_d3 = mc.R013_CF(u,
|
|
78
|
+
r_d3 = mc.R013_CF(u, mc.NCF_R3[0], 3) # skips mc.R3's sign/U_MAX/ladder dispatch + redundant x*x + 3
|
|
79
79
|
else: # x < 17.1: segmented Chebyshev path inside mc.R3
|
|
80
80
|
r_d3 = mc.R3(x) # = -R'''(x)
|
|
81
81
|
r_d1 = (r_d3 + 1.0) / u # descend: -R'(x), cancellation-free (odd -> odd); u = x^2 + 3
|