| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
#include |
|
2
|
|
|
|
|
|
|
#include |
|
3
|
|
|
|
|
|
|
#include |
|
4
|
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
#define FUNC_log2floor 1 |
|
6
|
|
|
|
|
|
|
#include "ptypes.h" |
|
7
|
|
|
|
|
|
|
#include "sieve.h" |
|
8
|
|
|
|
|
|
|
#include "util.h" |
|
9
|
|
|
|
|
|
|
#include "real.h" |
|
10
|
|
|
|
|
|
|
#include "mathl.h" |
|
11
|
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
/* 1) Naive FP summation |
|
13
|
|
|
|
|
|
|
* 2) Kahan summation |
|
14
|
|
|
|
|
|
|
* 3) Neumaier, also called KBN or "improved Kahan–Babuška algorithm" |
|
15
|
|
|
|
|
|
|
* 4) Klein, also called KB2 or second-order Kahan-Babuška |
|
16
|
|
|
|
|
|
|
*/ |
|
17
|
|
|
|
|
|
|
#define SUM_TYPE_NORMAL 0 |
|
18
|
|
|
|
|
|
|
#define SUM_TYPE_KAHAN 0 |
|
19
|
|
|
|
|
|
|
#define SUM_TYPE_NEUMAIER 1 |
|
20
|
|
|
|
|
|
|
#define SUM_TYPE_KLEIN 0 |
|
21
|
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
#if SUM_TYPE_NORMAL |
|
23
|
|
|
|
|
|
|
#define SUM_INIT(s) LNV s = 0.0; |
|
24
|
|
|
|
|
|
|
#define SUM_ADD(s, term) s = s + (term); |
|
25
|
|
|
|
|
|
|
#define SUM_FINAL(s) s |
|
26
|
|
|
|
|
|
|
#endif |
|
27
|
|
|
|
|
|
|
#if SUM_TYPE_KAHAN |
|
28
|
|
|
|
|
|
|
#define SUM_INIT(s) \ |
|
29
|
|
|
|
|
|
|
LNV s ## _y, s ## _t; \ |
|
30
|
|
|
|
|
|
|
LNV s ## _c = 0.0; \ |
|
31
|
|
|
|
|
|
|
LNV s = 0.0; |
|
32
|
|
|
|
|
|
|
#define SUM_ADD(s, term) \ |
|
33
|
|
|
|
|
|
|
do { \ |
|
34
|
|
|
|
|
|
|
s ## _y = (term) - s ## _c; \ |
|
35
|
|
|
|
|
|
|
s ## _t = s + s ## _y; \ |
|
36
|
|
|
|
|
|
|
s ## _c = (s ## _t - s) - s ## _y; \ |
|
37
|
|
|
|
|
|
|
s = s ## _t; \ |
|
38
|
|
|
|
|
|
|
} while (0) |
|
39
|
|
|
|
|
|
|
#define SUM_FINAL(s) s |
|
40
|
|
|
|
|
|
|
#endif |
|
41
|
|
|
|
|
|
|
#if SUM_TYPE_NEUMAIER |
|
42
|
|
|
|
|
|
|
#define SUM_INIT(s) \ |
|
43
|
|
|
|
|
|
|
LNV s ## _c = 0.0; \ |
|
44
|
|
|
|
|
|
|
LNV s = 0.0; |
|
45
|
|
|
|
|
|
|
#define SUM_ADD(s, term) \ |
|
46
|
|
|
|
|
|
|
do { \ |
|
47
|
|
|
|
|
|
|
LNV _term = term; \ |
|
48
|
|
|
|
|
|
|
LNV _t = s + _term; \ |
|
49
|
|
|
|
|
|
|
if ( fabslnv(s) >= fabslnv(_term) ) \ |
|
50
|
|
|
|
|
|
|
s ## _c += (s - _t) + _term; \ |
|
51
|
|
|
|
|
|
|
else \ |
|
52
|
|
|
|
|
|
|
s ## _c += (_term - _t) + s; \ |
|
53
|
|
|
|
|
|
|
s = _t; \ |
|
54
|
|
|
|
|
|
|
} while (0) |
|
55
|
|
|
|
|
|
|
#define SUM_FINAL(s) (s + s ## _c) |
|
56
|
|
|
|
|
|
|
#endif |
|
57
|
|
|
|
|
|
|
#if SUM_TYPE_KLEIN |
|
58
|
|
|
|
|
|
|
#define SUM_INIT(s) \ |
|
59
|
|
|
|
|
|
|
LNV s ## _cs = 0.0; \ |
|
60
|
|
|
|
|
|
|
LNV s ## _ccs = 0.0; \ |
|
61
|
|
|
|
|
|
|
LNV s = 0.0; |
|
62
|
|
|
|
|
|
|
#define SUM_ADD(s, term) \ |
|
63
|
|
|
|
|
|
|
do { \ |
|
64
|
|
|
|
|
|
|
LNV _term = term; \ |
|
65
|
|
|
|
|
|
|
LNV _c, _cc, _t = s + _term; \ |
|
66
|
|
|
|
|
|
|
if ( fabslnv(s) >= fabslnv(_term) ) \ |
|
67
|
|
|
|
|
|
|
_c = (s - _t) + _term; \ |
|
68
|
|
|
|
|
|
|
else \ |
|
69
|
|
|
|
|
|
|
_c = (_term - _t) + s; \ |
|
70
|
|
|
|
|
|
|
s = _t; \ |
|
71
|
|
|
|
|
|
|
_t = s ## _cs + _c; \ |
|
72
|
|
|
|
|
|
|
if ( fabslnv(s ## _cs) >= fabslnv(_c) ) \ |
|
73
|
|
|
|
|
|
|
_cc = (s ## _cs - _t) + _c; \ |
|
74
|
|
|
|
|
|
|
else \ |
|
75
|
|
|
|
|
|
|
_cc = (_c - _t) + s ## _cs; \ |
|
76
|
|
|
|
|
|
|
s ## _cs = _t; \ |
|
77
|
|
|
|
|
|
|
s ## _ccs += _cc; \ |
|
78
|
|
|
|
|
|
|
} while (0) |
|
79
|
|
|
|
|
|
|
#define SUM_FINAL(s) (s + s ## _cs + s ## _ccs) |
|
80
|
|
|
|
|
|
|
#endif |
|
81
|
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
static const unsigned short primes_tiny[] = |
|
84
|
|
|
|
|
|
|
{0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97, |
|
85
|
|
|
|
|
|
|
101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191, |
|
86
|
|
|
|
|
|
|
193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283, |
|
87
|
|
|
|
|
|
|
293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401, |
|
88
|
|
|
|
|
|
|
409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503}; |
|
89
|
|
|
|
|
|
|
#define NPRIMES_TINY (sizeof(primes_tiny)/sizeof(primes_tiny[0])) |
|
90
|
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
/******************************************************************************/ |
|
93
|
|
|
|
|
|
|
/* REAL FUNCTIONS (EI,LI,etc.) */ |
|
94
|
|
|
|
|
|
|
/******************************************************************************/ |
|
95
|
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
/* |
|
97
|
|
|
|
|
|
|
* See: |
|
98
|
|
|
|
|
|
|
* "Multiple-Precision Exponential Integral and Related Functions" |
|
99
|
|
|
|
|
|
|
* by David M. Smith |
|
100
|
|
|
|
|
|
|
* "On the Evaluation of the Complex-Valued Exponential Integral" |
|
101
|
|
|
|
|
|
|
* by Vincent Pegoraro and Philipp Slusallek |
|
102
|
|
|
|
|
|
|
* "Numerical Recipes" 3rd edition |
|
103
|
|
|
|
|
|
|
* by William H. Press et al. |
|
104
|
|
|
|
|
|
|
* "Rational Chevyshev Approximations for the Exponential Integral E_1(x)" |
|
105
|
|
|
|
|
|
|
* by W. J. Cody and Henry C. Thacher, Jr. |
|
106
|
|
|
|
|
|
|
* "High-precision Computation of Uniform Asymptotic Expansions for Special Functions" |
|
107
|
|
|
|
|
|
|
* by Guillermo Navas-Palencia (2019) |
|
108
|
|
|
|
|
|
|
* |
|
109
|
|
|
|
|
|
|
* Any mistakes here are mine. This code has not been rigorously verified. |
|
110
|
|
|
|
|
|
|
* Alternates: Navas-Palencia, Boost, MPFR, Pari/GP, Arb. |
|
111
|
|
|
|
|
|
|
* |
|
112
|
|
|
|
|
|
|
* We are trying to get close to maximum precision for all x with double, long |
|
113
|
|
|
|
|
|
|
* double, and quadmath. Hence the rational Chebyshev approximations should |
|
114
|
|
|
|
|
|
|
* not be used with quadmath (unless they are are modified). |
|
115
|
|
|
|
|
|
|
* |
|
116
|
|
|
|
|
|
|
* Performance, i7-6700HQ, 2.6GHz, 1e-9 to 1000 step 0.001 |
|
117
|
|
|
|
|
|
|
* range x > 0: |
|
118
|
|
|
|
|
|
|
* 0.22 microseconds, NV = double max rel error 1.4e-14 |
|
119
|
|
|
|
|
|
|
* 0.19 microseconds, NV = long double max rel error 4.3e-17 |
|
120
|
|
|
|
|
|
|
* 18.97 microseconds, NV = quad max rel error 4.4e-32 |
|
121
|
|
|
|
|
|
|
* range x < 0: |
|
122
|
|
|
|
|
|
|
* 0.18 microseconds, NV = double max rel error 1.4e-14 |
|
123
|
|
|
|
|
|
|
* 0.15 microseconds, NV = long double max rel error 1.2e-17 |
|
124
|
|
|
|
|
|
|
* 9.31 microseconds, NV = quad max rel error 1.7e-32 |
|
125
|
|
|
|
|
|
|
* |
|
126
|
|
|
|
|
|
|
* The maximum error is near the root 0.3725074... |
|
127
|
|
|
|
|
|
|
* The relative error profile for double precision is essentially identical |
|
128
|
|
|
|
|
|
|
* to the Navas-Palencia expintei(x) function. |
|
129
|
|
|
|
|
|
|
* Using long double on x86 improves the results with no time penalty. |
|
130
|
|
|
|
|
|
|
* Using quadmath gives improved results at a substantial time penalty. |
|
131
|
|
|
|
|
|
|
*/ |
|
132
|
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
static LNV const euler_mascheroni = LNVCONST(0.57721566490153286060651209008240243104215933593992); |
|
134
|
|
|
|
|
|
|
static LNV const li2 = LNVCONST(1.045163780117492784844588889194613136522615578151); |
|
135
|
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
/* Rational Chebyshev approximation (Cody, Thacher), good for -1 < x < 0 */ |
|
137
|
5
|
|
|
|
|
|
static LNV _ei_chebyshev_neg(const LNV x) { |
|
138
|
|
|
|
|
|
|
static const LNV C6p[7] = { LNVCONST(-148151.02102575750838086), |
|
139
|
|
|
|
|
|
|
LNVCONST( 150260.59476436982420737), |
|
140
|
|
|
|
|
|
|
LNVCONST( 89904.972007457256553251), |
|
141
|
|
|
|
|
|
|
LNVCONST( 15924.175980637303639884), |
|
142
|
|
|
|
|
|
|
LNVCONST( 2150.0672908092918123209), |
|
143
|
|
|
|
|
|
|
LNVCONST( 116.69552669734461083368), |
|
144
|
|
|
|
|
|
|
LNVCONST( 5.0196785185439843791020) }; |
|
145
|
|
|
|
|
|
|
static const LNV C6q[7] = { LNVCONST( 256664.93484897117319268), |
|
146
|
|
|
|
|
|
|
LNVCONST( 184340.70063353677359298), |
|
147
|
|
|
|
|
|
|
LNVCONST( 52440.529172056355429883), |
|
148
|
|
|
|
|
|
|
LNVCONST( 8125.8035174768735759866), |
|
149
|
|
|
|
|
|
|
LNVCONST( 750.43163907103936624165), |
|
150
|
|
|
|
|
|
|
LNVCONST( 40.205465640027706061433), |
|
151
|
|
|
|
|
|
|
LNVCONST( 1.0000000000000000000000) }; |
|
152
|
5
|
|
|
|
|
|
LNV sumn = C6p[0]-x*(C6p[1]-x*(C6p[2]-x*(C6p[3]-x*(C6p[4]-x*(C6p[5]-x*C6p[6]))))); |
|
153
|
5
|
|
|
|
|
|
LNV sumd = C6q[0]-x*(C6q[1]-x*(C6q[2]-x*(C6q[3]-x*(C6q[4]-x*(C6q[5]-x*C6q[6]))))); |
|
154
|
5
|
|
|
|
|
|
return loglnv(-x) - sumn/sumd; |
|
155
|
|
|
|
|
|
|
} |
|
156
|
|
|
|
|
|
|
/* Cody / Thacher rational Chebyshev for x > 24 */ |
|
157
|
1
|
|
|
|
|
|
static LNV _ei_chebyshev_pos24(const LNV x) { |
|
158
|
|
|
|
|
|
|
static const LNV P2[10] = { |
|
159
|
|
|
|
|
|
|
LNVCONST( 1.75338801265465972390E02), |
|
160
|
|
|
|
|
|
|
LNVCONST(-2.23127670777632409550E02), |
|
161
|
|
|
|
|
|
|
LNVCONST(-1.81949664929868906455E01), |
|
162
|
|
|
|
|
|
|
LNVCONST(-2.79798528624305389340E01), |
|
163
|
|
|
|
|
|
|
LNVCONST(-7.63147701620253630855E00), |
|
164
|
|
|
|
|
|
|
LNVCONST(-1.52856623636929636839E01), |
|
165
|
|
|
|
|
|
|
LNVCONST(-7.06810977895029358836E00), |
|
166
|
|
|
|
|
|
|
LNVCONST(-5.00006640413131002475E00), |
|
167
|
|
|
|
|
|
|
LNVCONST(-3.00000000320981265753E00), |
|
168
|
|
|
|
|
|
|
LNVCONST( 1.00000000000000485503E00) }; |
|
169
|
|
|
|
|
|
|
static const LNV Q2[9] = { |
|
170
|
|
|
|
|
|
|
LNVCONST( 3.97845977167414720840E04), |
|
171
|
|
|
|
|
|
|
LNVCONST( 3.97277109100414518365E00), |
|
172
|
|
|
|
|
|
|
LNVCONST( 1.37790390235747998793E02), |
|
173
|
|
|
|
|
|
|
LNVCONST( 1.17179220502086455287E02), |
|
174
|
|
|
|
|
|
|
LNVCONST( 7.04831847180424675988E01), |
|
175
|
|
|
|
|
|
|
LNVCONST(-1.20187763547154743238E01), |
|
176
|
|
|
|
|
|
|
LNVCONST(-7.99243595776339741065E00), |
|
177
|
|
|
|
|
|
|
LNVCONST(-2.99999894040324959612E00), |
|
178
|
|
|
|
|
|
|
LNVCONST( 1.99999999999048104167E00) }; |
|
179
|
1
|
|
|
|
|
|
LNV invx = LNV_ONE / x, frac = 0.0; |
|
180
|
|
|
|
|
|
|
uint32_t n; |
|
181
|
10
|
100
|
|
|
|
|
for (n = 0; n <= 8; n++) |
|
182
|
9
|
|
|
|
|
|
frac = Q2[n] / (P2[n] + x + frac); |
|
183
|
1
|
|
|
|
|
|
frac += P2[9]; |
|
184
|
1
|
|
|
|
|
|
return explnv(x) * (invx + invx*invx*frac); |
|
185
|
|
|
|
|
|
|
} |
|
186
|
|
|
|
|
|
|
#if 0 |
|
187
|
|
|
|
|
|
|
/* Continued fraction, good for x < -1 */ |
|
188
|
|
|
|
|
|
|
static LNV _ei_cfrac_neg(const LNV x) { |
|
189
|
|
|
|
|
|
|
LNV lc = 0, ld = LNV_ONE / (LNV_ONE - x); |
|
190
|
|
|
|
|
|
|
LNV val = ld * (-explnv(x)); |
|
191
|
|
|
|
|
|
|
uint32_t n; |
|
192
|
|
|
|
|
|
|
for (n = 1; n <= 20000; n++) { |
|
193
|
|
|
|
|
|
|
LNV old, t, n2 = n * n; |
|
194
|
|
|
|
|
|
|
t = (LNV)(2*n + 1) - x; |
|
195
|
|
|
|
|
|
|
lc = LNV_ONE / (t - n2 * lc); |
|
196
|
|
|
|
|
|
|
ld = LNV_ONE / (t - n2 * ld); |
|
197
|
|
|
|
|
|
|
old = val; |
|
198
|
|
|
|
|
|
|
val *= ld/lc; |
|
199
|
|
|
|
|
|
|
if ( fabslnv(val-old) <= LNV_EPSILON*fabslnv(val) ) |
|
200
|
|
|
|
|
|
|
break; |
|
201
|
|
|
|
|
|
|
} |
|
202
|
|
|
|
|
|
|
return val; |
|
203
|
|
|
|
|
|
|
} |
|
204
|
|
|
|
|
|
|
#endif |
|
205
|
|
|
|
|
|
|
/* eint_v using Laguerre series, Navas-Palencia (2019). */ |
|
206
|
1
|
|
|
|
|
|
static LNV _eintv_laguerre_series(const LNV v, const LNV x) { |
|
207
|
1
|
|
|
|
|
|
LNV L_k = 1.0, L_k1 = x + v; |
|
208
|
1
|
|
|
|
|
|
LNV q, r, u = LNV_ONE, d = LNV_ONE; |
|
209
|
|
|
|
|
|
|
uint32_t k; |
|
210
|
1
|
|
|
|
|
|
SUM_INIT(sum); |
|
211
|
1
|
50
|
|
|
|
|
SUM_ADD(sum, (LNV_ONE/L_k1)); |
|
212
|
20
|
50
|
|
|
|
|
for (k = 1; k < 500; k++) { |
|
213
|
20
|
|
|
|
|
|
u *= v + k - 1; |
|
214
|
20
|
|
|
|
|
|
d *= 1 + k; |
|
215
|
20
|
|
|
|
|
|
q = L_k1 * (x + 2*k + v) / (k + 1) - L_k * (k + v - 1) / (k + 1); |
|
216
|
20
|
|
|
|
|
|
r = u / (d * (q * L_k1)); |
|
217
|
20
|
50
|
|
|
|
|
SUM_ADD(sum, r); |
|
218
|
20
|
|
|
|
|
|
L_k = L_k1; |
|
219
|
20
|
|
|
|
|
|
L_k1 = q; |
|
220
|
20
|
100
|
|
|
|
|
if (fabslnv(r) < 0.1 * LNV_EPSILON) |
|
221
|
1
|
|
|
|
|
|
break; |
|
222
|
|
|
|
|
|
|
} |
|
223
|
1
|
|
|
|
|
|
return SUM_FINAL(sum) * explnv(-x); |
|
224
|
|
|
|
|
|
|
} |
|
225
|
|
|
|
|
|
|
/* Convergent series for small negative x through medium positive x */ |
|
226
|
131
|
|
|
|
|
|
static LNV _ei_series_convergent(LNV const x) { |
|
227
|
131
|
|
|
|
|
|
LNV term, fact_n = x; |
|
228
|
|
|
|
|
|
|
uint32_t n; |
|
229
|
131
|
|
|
|
|
|
SUM_INIT(sum); |
|
230
|
8704
|
50
|
|
|
|
|
for (n = 2; n <= 400; n++) { |
|
231
|
8704
|
|
|
|
|
|
LNV invn = LNV_ONE / n; |
|
232
|
8704
|
|
|
|
|
|
fact_n *= (LNV)x * invn; |
|
233
|
8704
|
|
|
|
|
|
term = fact_n * invn; |
|
234
|
8704
|
100
|
|
|
|
|
SUM_ADD(sum, term); |
|
235
|
|
|
|
|
|
|
/* printf("C after adding %.20Lf, val = %.20Lf\n", term, SUM_FINAL(sum)); */ |
|
236
|
8704
|
100
|
|
|
|
|
if (fabslnv(term) < LNV_EPSILON*fabslnv(SUM_FINAL(sum))) break; |
|
237
|
|
|
|
|
|
|
} |
|
238
|
131
|
100
|
|
|
|
|
SUM_ADD(sum, euler_mascheroni); |
|
239
|
131
|
50
|
|
|
|
|
SUM_ADD(sum, loglnv(fabslnv(x))); |
|
240
|
131
|
100
|
|
|
|
|
SUM_ADD(sum, x); |
|
241
|
131
|
|
|
|
|
|
return SUM_FINAL(sum); |
|
242
|
|
|
|
|
|
|
} |
|
243
|
|
|
|
|
|
|
/* Asymptotic divergent series, for large positive x */ |
|
244
|
0
|
|
|
|
|
|
static LNV _ei_series_divergent(LNV const x) { |
|
245
|
0
|
|
|
|
|
|
LNV invx = LNV_ONE / x, term = invx; |
|
246
|
|
|
|
|
|
|
unsigned int n; |
|
247
|
0
|
|
|
|
|
|
SUM_INIT(sum); |
|
248
|
0
|
0
|
|
|
|
|
for (n = 2; n <= 400; n++) { |
|
249
|
0
|
|
|
|
|
|
LNV last_term = term; |
|
250
|
0
|
|
|
|
|
|
term = term * ( (LNV)n * invx ); |
|
251
|
0
|
0
|
|
|
|
|
if (term < LNV_EPSILON*SUM_FINAL(sum)) break; |
|
252
|
0
|
0
|
|
|
|
|
if (term < last_term) { |
|
253
|
0
|
0
|
|
|
|
|
SUM_ADD(sum, term); |
|
254
|
|
|
|
|
|
|
/* printf("A after adding %.20llf, sum = %.20llf\n", term, SUM_FINAL(sum)); */ |
|
255
|
|
|
|
|
|
|
} else { |
|
256
|
0
|
0
|
|
|
|
|
SUM_ADD(sum, (-last_term/1.07) ); |
|
257
|
|
|
|
|
|
|
/* printf("A after adding %.20llf, sum = %.20llf\n", -last_term/1.07, SUM_FINAL(sum)); */ |
|
258
|
0
|
|
|
|
|
|
break; |
|
259
|
|
|
|
|
|
|
} |
|
260
|
|
|
|
|
|
|
} |
|
261
|
0
|
0
|
|
|
|
|
SUM_ADD(sum, invx); |
|
262
|
0
|
0
|
|
|
|
|
SUM_ADD(sum, LNV_ONE); |
|
263
|
0
|
|
|
|
|
|
return explnv(x) * SUM_FINAL(sum) * invx; |
|
264
|
|
|
|
|
|
|
} |
|
265
|
|
|
|
|
|
|
|
|
266
|
138
|
|
|
|
|
|
NV Ei(NV x) { |
|
267
|
138
|
|
|
|
|
|
bool nv_is_quad = LNV_IS_QUAD; /* make C2X happy */ |
|
268
|
138
|
50
|
|
|
|
|
if (x == 0) croak("Invalid input to ExponentialIntegral: x must be != 0"); |
|
269
|
|
|
|
|
|
|
/* Protect against messed up rounding modes */ |
|
270
|
138
|
50
|
|
|
|
|
if (x >= 12000) return INFINITY; |
|
271
|
138
|
50
|
|
|
|
|
if (x <= -12000) return 0; |
|
272
|
|
|
|
|
|
|
|
|
273
|
138
|
100
|
|
|
|
|
if (x < 0) { |
|
274
|
6
|
100
|
|
|
|
|
if (x >= -1.0 && !nv_is_quad) return _ei_chebyshev_neg(x); |
|
|
|
50
|
|
|
|
|
|
|
275
|
1
|
50
|
|
|
|
|
else if (x < -0.80) return -_eintv_laguerre_series(1, -x); |
|
276
|
0
|
|
|
|
|
|
else return _ei_series_convergent(x); |
|
277
|
|
|
|
|
|
|
} else { |
|
278
|
132
|
100
|
|
|
|
|
if (x < (-2 * loglnv(LNV_EPSILON))) return _ei_series_convergent(x); |
|
279
|
1
|
50
|
|
|
|
|
if (x >= 24 && (!nv_is_quad || x <= 43.2)) return _ei_chebyshev_pos24(x); |
|
|
|
50
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
280
|
0
|
|
|
|
|
|
else return _ei_series_divergent(x); |
|
281
|
|
|
|
|
|
|
} |
|
282
|
|
|
|
|
|
|
} |
|
283
|
|
|
|
|
|
|
|
|
284
|
886
|
|
|
|
|
|
NV Li(NV x) { |
|
285
|
886
|
50
|
|
|
|
|
if (x == 0) return 0; |
|
286
|
886
|
50
|
|
|
|
|
if (x == 1) return -INFINITY; |
|
287
|
886
|
50
|
|
|
|
|
if (x == 2) return li2; |
|
288
|
886
|
50
|
|
|
|
|
if (x < 0) croak("Invalid input to LogarithmicIntegral: x must be >= 0"); |
|
289
|
886
|
50
|
|
|
|
|
if (x >= NV_MAX) return INFINITY; |
|
290
|
|
|
|
|
|
|
|
|
291
|
|
|
|
|
|
|
/* Calculate directly using Ramanujan's series. */ |
|
292
|
886
|
50
|
|
|
|
|
if (x > 1) { |
|
293
|
886
|
|
|
|
|
|
const LNV logx = loglnv(x); |
|
294
|
886
|
|
|
|
|
|
LNV sum = 0, inner_sum = 0, old_sum, factorial = 1, power2 = 1; |
|
295
|
886
|
|
|
|
|
|
LNV q, p = -1; |
|
296
|
886
|
|
|
|
|
|
int k = 0, n = 0; |
|
297
|
|
|
|
|
|
|
|
|
298
|
34116
|
50
|
|
|
|
|
for (n = 1, k = 0; n < 200; n++) { |
|
299
|
34116
|
|
|
|
|
|
factorial *= n; |
|
300
|
34116
|
|
|
|
|
|
p *= -logx; |
|
301
|
34116
|
|
|
|
|
|
q = factorial * power2; |
|
302
|
34116
|
|
|
|
|
|
power2 *= 2; |
|
303
|
51403
|
100
|
|
|
|
|
for (; k <= (n - 1) / 2; k++) |
|
304
|
17287
|
|
|
|
|
|
inner_sum += LNV_ONE / (2 * k + 1); |
|
305
|
34116
|
|
|
|
|
|
old_sum = sum; |
|
306
|
34116
|
|
|
|
|
|
sum += (p / q) * inner_sum; |
|
307
|
34116
|
100
|
|
|
|
|
if (fabslnv(sum - old_sum) <= LNV_EPSILON) break; |
|
308
|
|
|
|
|
|
|
} |
|
309
|
886
|
|
|
|
|
|
return euler_mascheroni + loglnv(logx) + sqrtlnv(x) * sum; |
|
310
|
|
|
|
|
|
|
} |
|
311
|
|
|
|
|
|
|
|
|
312
|
0
|
|
|
|
|
|
return Ei(loglnv(x)); |
|
313
|
|
|
|
|
|
|
} |
|
314
|
|
|
|
|
|
|
|
|
315
|
88
|
|
|
|
|
|
long double ld_inverse_li(long double lx) { |
|
316
|
|
|
|
|
|
|
int i; |
|
317
|
88
|
|
|
|
|
|
long double t, term, old_term = 0; |
|
318
|
|
|
|
|
|
|
/* Iterate Halley's method until error grows. */ |
|
319
|
88
|
50
|
|
|
|
|
t = (lx <= 2) ? 2 : lx * logl(lx); |
|
320
|
400
|
100
|
|
|
|
|
for (i = 0; i < 4; i++) { |
|
321
|
352
|
|
|
|
|
|
long double dn = Li(t) - lx; |
|
322
|
352
|
|
|
|
|
|
term = dn*logl(t) / (1.0L + dn/(2*t)); |
|
323
|
352
|
100
|
|
|
|
|
if (i > 0 && fabsl(term) >= fabsl(old_term)) { t -= term/4; break; } |
|
|
|
100
|
|
|
|
|
|
|
324
|
312
|
|
|
|
|
|
old_term = term; |
|
325
|
312
|
|
|
|
|
|
t -= term; |
|
326
|
|
|
|
|
|
|
} |
|
327
|
88
|
|
|
|
|
|
return t; |
|
328
|
|
|
|
|
|
|
} |
|
329
|
|
|
|
|
|
|
|
|
330
|
87
|
|
|
|
|
|
UV inverse_li(UV x) { |
|
331
|
|
|
|
|
|
|
UV r, i; |
|
332
|
87
|
|
|
|
|
|
long double lx = (long double) x; |
|
333
|
|
|
|
|
|
|
|
|
334
|
87
|
100
|
|
|
|
|
if (x <= 2) return x + (x > 0); |
|
335
|
84
|
|
|
|
|
|
r = (UV) ceill( ld_inverse_li(lx) ); |
|
336
|
|
|
|
|
|
|
/* Meet our more stringent goal of an exact answer. */ |
|
337
|
84
|
50
|
|
|
|
|
i = (x > 4e16) ? 2048 : 128; |
|
338
|
84
|
50
|
|
|
|
|
if (Li(r-1) >= lx) { |
|
339
|
0
|
0
|
|
|
|
|
while (Li(r-i) >= lx) r -= i; |
|
340
|
0
|
0
|
|
|
|
|
for (i = i/2; i > 0; i /= 2) |
|
341
|
0
|
0
|
|
|
|
|
if (Li(r-i) >= lx) r -= i; |
|
342
|
84
|
50
|
|
|
|
|
} else if (Li(r) < lx) { |
|
343
|
0
|
0
|
|
|
|
|
while (Li(r+i-1) < lx) r += i; |
|
344
|
0
|
0
|
|
|
|
|
for (i = i/2; i > 0; i /= 2) |
|
345
|
0
|
0
|
|
|
|
|
if (Li(r+i-1) < lx) r += i; |
|
346
|
|
|
|
|
|
|
} |
|
347
|
84
|
|
|
|
|
|
return r; |
|
348
|
|
|
|
|
|
|
} |
|
349
|
|
|
|
|
|
|
|
|
350
|
23
|
|
|
|
|
|
static long double ld_inverse_R(long double lx) { |
|
351
|
|
|
|
|
|
|
int i; |
|
352
|
23
|
|
|
|
|
|
long double t, dn, term, old_term = 0; |
|
353
|
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
/* Rough estimate */ |
|
355
|
23
|
50
|
|
|
|
|
if (lx <= 3.5) { |
|
356
|
0
|
|
|
|
|
|
t = lx + 2.24*(lx-1)/2; |
|
357
|
|
|
|
|
|
|
} else { |
|
358
|
23
|
|
|
|
|
|
t = lx * logl(lx); |
|
359
|
23
|
50
|
|
|
|
|
if (lx < 50) { t *= 1.2; } |
|
360
|
23
|
100
|
|
|
|
|
else if (lx < 1000) { t *= 1.15; } |
|
361
|
|
|
|
|
|
|
else { /* use inverse Li (one iteration) for first inverse R approx */ |
|
362
|
22
|
|
|
|
|
|
dn = Li(t) - lx; |
|
363
|
22
|
|
|
|
|
|
term = dn * logl(t) / (1.0L + dn/(2*t)); |
|
364
|
22
|
|
|
|
|
|
t -= term; |
|
365
|
|
|
|
|
|
|
} |
|
366
|
|
|
|
|
|
|
} |
|
367
|
|
|
|
|
|
|
/* Iterate 1-n rounds of Halley, usually only 3 needed. */ |
|
368
|
143
|
50
|
|
|
|
|
for (i = 0; i < 100; i++) { |
|
369
|
143
|
|
|
|
|
|
dn = RiemannR(t, 1e-12) - lx; |
|
370
|
|
|
|
|
|
|
#if 1 /* Use f(t) = li(t) for derivatives */ |
|
371
|
143
|
|
|
|
|
|
term = dn * logl(t) / (1.0L + dn/(2*t)); |
|
372
|
|
|
|
|
|
|
#else /* Use f(t) = li(t) - li(sqrt(t))/2 for derivatives */ |
|
373
|
|
|
|
|
|
|
long double logt = logl(t); |
|
374
|
|
|
|
|
|
|
long double sqrtt = sqrtl(t); |
|
375
|
|
|
|
|
|
|
long double FA = 2 * sqrtt * logt; |
|
376
|
|
|
|
|
|
|
long double FB = 2 * sqrtt - 1; |
|
377
|
|
|
|
|
|
|
long double ifz = FA / FB; |
|
378
|
|
|
|
|
|
|
long double iffz = (logt - 2*FB) / (2 * sqrtt * FA * FA * FA * FA); |
|
379
|
|
|
|
|
|
|
term = dn * ifz * (1.0L - dn * iffz); |
|
380
|
|
|
|
|
|
|
#endif |
|
381
|
143
|
100
|
|
|
|
|
if (i > 0 && fabsl(term) >= fabsl(old_term)) { t -= term/4; break; } |
|
|
|
100
|
|
|
|
|
|
|
382
|
120
|
|
|
|
|
|
old_term = term; |
|
383
|
120
|
|
|
|
|
|
t -= term; |
|
384
|
|
|
|
|
|
|
} |
|
385
|
23
|
|
|
|
|
|
return t; |
|
386
|
|
|
|
|
|
|
} |
|
387
|
|
|
|
|
|
|
|
|
388
|
23
|
|
|
|
|
|
UV inverse_R(UV x) { |
|
389
|
23
|
50
|
|
|
|
|
if (x < 2) return x + (x > 0); |
|
390
|
23
|
|
|
|
|
|
return (UV) ceill( ld_inverse_R( (long double) x) ); |
|
391
|
|
|
|
|
|
|
} |
|
392
|
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
/* |
|
395
|
|
|
|
|
|
|
* Storing the first 10-20 Zeta values makes sense. Past that it is purely |
|
396
|
|
|
|
|
|
|
* to avoid making the call to generate them ourselves. We could cache the |
|
397
|
|
|
|
|
|
|
* calculated values. These all have 1 subtracted from them. */ |
|
398
|
|
|
|
|
|
|
static const long double riemann_zeta_table[] = { |
|
399
|
|
|
|
|
|
|
0.6449340668482264364724151666460251892L, /* zeta(2) */ |
|
400
|
|
|
|
|
|
|
0.2020569031595942853997381615114499908L, |
|
401
|
|
|
|
|
|
|
0.0823232337111381915160036965411679028L, |
|
402
|
|
|
|
|
|
|
0.0369277551433699263313654864570341681L, |
|
403
|
|
|
|
|
|
|
0.0173430619844491397145179297909205279L, |
|
404
|
|
|
|
|
|
|
0.0083492773819228268397975498497967596L, |
|
405
|
|
|
|
|
|
|
0.0040773561979443393786852385086524653L, |
|
406
|
|
|
|
|
|
|
0.0020083928260822144178527692324120605L, |
|
407
|
|
|
|
|
|
|
0.0009945751278180853371459589003190170L, |
|
408
|
|
|
|
|
|
|
0.0004941886041194645587022825264699365L, |
|
409
|
|
|
|
|
|
|
0.0002460865533080482986379980477396710L, |
|
410
|
|
|
|
|
|
|
0.0001227133475784891467518365263573957L, |
|
411
|
|
|
|
|
|
|
0.0000612481350587048292585451051353337L, |
|
412
|
|
|
|
|
|
|
0.0000305882363070204935517285106450626L, |
|
413
|
|
|
|
|
|
|
0.0000152822594086518717325714876367220L, |
|
414
|
|
|
|
|
|
|
0.0000076371976378997622736002935630292L, /* zeta(17) Past here all we're */ |
|
415
|
|
|
|
|
|
|
0.0000038172932649998398564616446219397L, /* zeta(18) getting is speed. */ |
|
416
|
|
|
|
|
|
|
0.0000019082127165539389256569577951013L, |
|
417
|
|
|
|
|
|
|
0.0000009539620338727961131520386834493L, |
|
418
|
|
|
|
|
|
|
0.0000004769329867878064631167196043730L, |
|
419
|
|
|
|
|
|
|
0.0000002384505027277329900036481867530L, |
|
420
|
|
|
|
|
|
|
0.0000001192199259653110730677887188823L, |
|
421
|
|
|
|
|
|
|
0.0000000596081890512594796124402079358L, |
|
422
|
|
|
|
|
|
|
0.0000000298035035146522801860637050694L, |
|
423
|
|
|
|
|
|
|
0.0000000149015548283650412346585066307L, |
|
424
|
|
|
|
|
|
|
0.0000000074507117898354294919810041706L, |
|
425
|
|
|
|
|
|
|
0.0000000037253340247884570548192040184L, |
|
426
|
|
|
|
|
|
|
0.0000000018626597235130490064039099454L, |
|
427
|
|
|
|
|
|
|
0.0000000009313274324196681828717647350L, |
|
428
|
|
|
|
|
|
|
0.0000000004656629065033784072989233251L, |
|
429
|
|
|
|
|
|
|
0.0000000002328311833676505492001455976L, |
|
430
|
|
|
|
|
|
|
0.0000000001164155017270051977592973835L, |
|
431
|
|
|
|
|
|
|
0.0000000000582077208790270088924368599L, |
|
432
|
|
|
|
|
|
|
0.0000000000291038504449709968692942523L, |
|
433
|
|
|
|
|
|
|
0.0000000000145519218910419842359296322L, |
|
434
|
|
|
|
|
|
|
0.0000000000072759598350574810145208690L, |
|
435
|
|
|
|
|
|
|
0.0000000000036379795473786511902372363L, |
|
436
|
|
|
|
|
|
|
0.0000000000018189896503070659475848321L, |
|
437
|
|
|
|
|
|
|
0.0000000000009094947840263889282533118L, |
|
438
|
|
|
|
|
|
|
0.0000000000004547473783042154026799112L, |
|
439
|
|
|
|
|
|
|
0.0000000000002273736845824652515226821L, |
|
440
|
|
|
|
|
|
|
0.0000000000001136868407680227849349105L, |
|
441
|
|
|
|
|
|
|
0.0000000000000568434198762758560927718L, |
|
442
|
|
|
|
|
|
|
0.0000000000000284217097688930185545507L, |
|
443
|
|
|
|
|
|
|
0.0000000000000142108548280316067698343L, |
|
444
|
|
|
|
|
|
|
0.00000000000000710542739521085271287735L, |
|
445
|
|
|
|
|
|
|
0.00000000000000355271369133711367329847L, |
|
446
|
|
|
|
|
|
|
0.00000000000000177635684357912032747335L, |
|
447
|
|
|
|
|
|
|
0.000000000000000888178421093081590309609L, |
|
448
|
|
|
|
|
|
|
0.000000000000000444089210314381336419777L, |
|
449
|
|
|
|
|
|
|
0.000000000000000222044605079804198399932L, |
|
450
|
|
|
|
|
|
|
0.000000000000000111022302514106613372055L, |
|
451
|
|
|
|
|
|
|
0.0000000000000000555111512484548124372374L, |
|
452
|
|
|
|
|
|
|
0.0000000000000000277555756213612417258163L, |
|
453
|
|
|
|
|
|
|
0.0000000000000000138777878097252327628391L, |
|
454
|
|
|
|
|
|
|
}; |
|
455
|
|
|
|
|
|
|
#define NPRECALC_ZETA (sizeof(riemann_zeta_table)/sizeof(riemann_zeta_table[0])) |
|
456
|
|
|
|
|
|
|
|
|
457
|
|
|
|
|
|
|
/* Riemann Zeta on the real line, with 1 subtracted. |
|
458
|
|
|
|
|
|
|
* Compare to Math::Cephes zetac. Also zeta with q=1 and subtracting 1. |
|
459
|
|
|
|
|
|
|
* |
|
460
|
|
|
|
|
|
|
* The Cephes zeta function uses a series (2k)!/B_2k which converges rapidly |
|
461
|
|
|
|
|
|
|
* and has a very wide range of values. We use it here for some values. |
|
462
|
|
|
|
|
|
|
* |
|
463
|
|
|
|
|
|
|
* Note: Calculations here are done on long doubles and we try to generate as |
|
464
|
|
|
|
|
|
|
* much accuracy as possible. They will get returned to Perl as an NV, |
|
465
|
|
|
|
|
|
|
* which is typically a 64-bit double with 15 digits. |
|
466
|
|
|
|
|
|
|
* |
|
467
|
|
|
|
|
|
|
* For values 0.5 to 5, this code uses the rational Chebyshev approximation |
|
468
|
|
|
|
|
|
|
* from Cody and Thacher. This method is extraordinarily fast and very |
|
469
|
|
|
|
|
|
|
* accurate over its range (slightly better than Cephes for most values). If |
|
470
|
|
|
|
|
|
|
* we had quad floats, we could use the 9-term polynomial. |
|
471
|
|
|
|
|
|
|
*/ |
|
472
|
3916
|
|
|
|
|
|
long double ld_riemann_zeta(long double x) { |
|
473
|
|
|
|
|
|
|
int i; |
|
474
|
|
|
|
|
|
|
|
|
475
|
3916
|
50
|
|
|
|
|
if (x < 0) croak("Invalid input to RiemannZeta: x must be >= 0"); |
|
476
|
3916
|
50
|
|
|
|
|
if (x == 1) return INFINITY; |
|
477
|
|
|
|
|
|
|
|
|
478
|
3916
|
100
|
|
|
|
|
if (x == (unsigned int)x) { |
|
479
|
3912
|
|
|
|
|
|
int k = x - 2; |
|
480
|
3912
|
50
|
|
|
|
|
if ((k >= 0) && (k < (int)NPRECALC_ZETA)) |
|
|
|
100
|
|
|
|
|
|
|
481
|
9
|
|
|
|
|
|
return riemann_zeta_table[k]; |
|
482
|
|
|
|
|
|
|
} |
|
483
|
|
|
|
|
|
|
|
|
484
|
|
|
|
|
|
|
/* Cody / Thacher rational Chebyshev approximation for small values */ |
|
485
|
3907
|
50
|
|
|
|
|
if (x >= 0.5 && x <= 5.0) { |
|
|
|
100
|
|
|
|
|
|
|
486
|
|
|
|
|
|
|
static const long double C8p[9] = { 1.287168121482446392809e10L, |
|
487
|
|
|
|
|
|
|
1.375396932037025111825e10L, |
|
488
|
|
|
|
|
|
|
5.106655918364406103683e09L, |
|
489
|
|
|
|
|
|
|
8.561471002433314862469e08L, |
|
490
|
|
|
|
|
|
|
7.483618124380232984824e07L, |
|
491
|
|
|
|
|
|
|
4.860106585461882511535e06L, |
|
492
|
|
|
|
|
|
|
2.739574990221406087728e05L, |
|
493
|
|
|
|
|
|
|
4.631710843183427123061e03L, |
|
494
|
|
|
|
|
|
|
5.787581004096660659109e01L }; |
|
495
|
|
|
|
|
|
|
static const long double C8q[9] = { 2.574336242964846244667e10L, |
|
496
|
|
|
|
|
|
|
5.938165648679590160003e09L, |
|
497
|
|
|
|
|
|
|
9.006330373261233439089e08L, |
|
498
|
|
|
|
|
|
|
8.042536634283289888587e07L, |
|
499
|
|
|
|
|
|
|
5.609711759541920062814e06L, |
|
500
|
|
|
|
|
|
|
2.247431202899137523543e05L, |
|
501
|
|
|
|
|
|
|
7.574578909341537560115e03L, |
|
502
|
|
|
|
|
|
|
-2.373835781373772623086e01L, |
|
503
|
|
|
|
|
|
|
1.000000000000000000000L }; |
|
504
|
2
|
|
|
|
|
|
long double sumn = C8p[0]+x*(C8p[1]+x*(C8p[2]+x*(C8p[3]+x*(C8p[4]+x*(C8p[5]+x*(C8p[6]+x*(C8p[7]+x*C8p[8]))))))); |
|
505
|
2
|
|
|
|
|
|
long double sumd = C8q[0]+x*(C8q[1]+x*(C8q[2]+x*(C8q[3]+x*(C8q[4]+x*(C8q[5]+x*(C8q[6]+x*(C8q[7]+x*C8q[8]))))))); |
|
506
|
2
|
|
|
|
|
|
long double sum = (sumn - (x-1)*sumd) / ((x-1)*sumd); |
|
507
|
2
|
|
|
|
|
|
return sum; |
|
508
|
|
|
|
|
|
|
} |
|
509
|
|
|
|
|
|
|
|
|
510
|
3905
|
50
|
|
|
|
|
if (x > 17000.0) |
|
511
|
0
|
|
|
|
|
|
return 0.0; |
|
512
|
|
|
|
|
|
|
|
|
513
|
|
|
|
|
|
|
#if 0 |
|
514
|
|
|
|
|
|
|
{ |
|
515
|
|
|
|
|
|
|
SUM_INIT(sum); |
|
516
|
|
|
|
|
|
|
/* Simple defining series, works well. */ |
|
517
|
|
|
|
|
|
|
for (i = 5; i <= 1000000; i++) { |
|
518
|
|
|
|
|
|
|
long double term = powl(i, -x); |
|
519
|
|
|
|
|
|
|
SUM_ADD(sum, term); |
|
520
|
|
|
|
|
|
|
if (term < LDBL_EPSILON*SUM_FINAL(sum)) break; |
|
521
|
|
|
|
|
|
|
} |
|
522
|
|
|
|
|
|
|
SUM_ADD(sum, powl(4, -x) ); |
|
523
|
|
|
|
|
|
|
SUM_ADD(sum, powl(3, -x) ); |
|
524
|
|
|
|
|
|
|
SUM_ADD(sum, powl(2, -x) ); |
|
525
|
|
|
|
|
|
|
return SUM_FINAL(sum); |
|
526
|
|
|
|
|
|
|
} |
|
527
|
|
|
|
|
|
|
#endif |
|
528
|
|
|
|
|
|
|
|
|
529
|
|
|
|
|
|
|
/* The 2n!/B_2k series used by the Cephes library. */ |
|
530
|
|
|
|
|
|
|
{ |
|
531
|
|
|
|
|
|
|
/* gp/pari: |
|
532
|
|
|
|
|
|
|
* for(i=1,13,printf("%.38g\n",(2*i)!/bernreal(2*i))) |
|
533
|
|
|
|
|
|
|
* MPU: |
|
534
|
|
|
|
|
|
|
* use bignum; |
|
535
|
|
|
|
|
|
|
* say +(factorial(2*$_)/bernreal(2*$_))->bround(38) for 1..13; |
|
536
|
|
|
|
|
|
|
*/ |
|
537
|
|
|
|
|
|
|
static const long double A[] = { |
|
538
|
|
|
|
|
|
|
12.0L, |
|
539
|
|
|
|
|
|
|
-720.0L, |
|
540
|
|
|
|
|
|
|
30240.0L, |
|
541
|
|
|
|
|
|
|
-1209600.0L, |
|
542
|
|
|
|
|
|
|
47900160.0L, |
|
543
|
|
|
|
|
|
|
-1892437580.3183791606367583212735166425L, |
|
544
|
|
|
|
|
|
|
74724249600.0L, |
|
545
|
|
|
|
|
|
|
-2950130727918.1642244954382084600497650L, |
|
546
|
|
|
|
|
|
|
116467828143500.67248729113000661089201L, |
|
547
|
|
|
|
|
|
|
-4597978722407472.6105457273596737891656L, |
|
548
|
|
|
|
|
|
|
181521054019435467.73425331153534235290L, |
|
549
|
|
|
|
|
|
|
-7166165256175667011.3346447367083352775L, |
|
550
|
|
|
|
|
|
|
282908877253042996618.18640556532523927L, |
|
551
|
|
|
|
|
|
|
}; |
|
552
|
|
|
|
|
|
|
long double a, b, s, t; |
|
553
|
3905
|
|
|
|
|
|
const long double w = 10.0; |
|
554
|
3905
|
|
|
|
|
|
s = 0.0; |
|
555
|
3905
|
|
|
|
|
|
b = 0.0; |
|
556
|
12909
|
100
|
|
|
|
|
for (i = 2; i < 11; i++) { |
|
557
|
12907
|
|
|
|
|
|
b = powl( i, -x ); |
|
558
|
12907
|
|
|
|
|
|
s += b; |
|
559
|
12907
|
100
|
|
|
|
|
if (fabsl(b) < fabsl(LDBL_EPSILON * s)) |
|
560
|
3903
|
|
|
|
|
|
return s; |
|
561
|
|
|
|
|
|
|
} |
|
562
|
2
|
|
|
|
|
|
s = s + b*w/(x-1.0) - 0.5 * b; |
|
563
|
2
|
|
|
|
|
|
a = 1.0; |
|
564
|
19
|
50
|
|
|
|
|
for (i = 0; i < 13; i++) { |
|
565
|
19
|
|
|
|
|
|
long double k = 2*i; |
|
566
|
19
|
|
|
|
|
|
a *= x + k; |
|
567
|
19
|
|
|
|
|
|
b /= w; |
|
568
|
19
|
|
|
|
|
|
t = a*b/A[i]; |
|
569
|
19
|
|
|
|
|
|
s = s + t; |
|
570
|
19
|
100
|
|
|
|
|
if (fabsl(t) < fabsl(LDBL_EPSILON * s)) |
|
571
|
2
|
|
|
|
|
|
break; |
|
572
|
17
|
|
|
|
|
|
a *= x + k + 1.0; |
|
573
|
17
|
|
|
|
|
|
b /= w; |
|
574
|
|
|
|
|
|
|
} |
|
575
|
2
|
|
|
|
|
|
return s; |
|
576
|
|
|
|
|
|
|
} |
|
577
|
|
|
|
|
|
|
} |
|
578
|
|
|
|
|
|
|
|
|
579
|
366
|
|
|
|
|
|
long double RiemannR(long double x, long double eps) { |
|
580
|
|
|
|
|
|
|
long double part_term, term, flogx, ki, old_sum; |
|
581
|
|
|
|
|
|
|
unsigned int k; |
|
582
|
366
|
|
|
|
|
|
SUM_INIT(sum); |
|
583
|
|
|
|
|
|
|
|
|
584
|
366
|
50
|
|
|
|
|
if (x <= 0) croak("Invalid input to RiemannR: x must be > 0"); |
|
585
|
366
|
100
|
|
|
|
|
if (eps < LDBL_EPSILON) eps = LDBL_EPSILON; |
|
586
|
|
|
|
|
|
|
|
|
587
|
366
|
100
|
|
|
|
|
if (x > 1e19) { |
|
588
|
2
|
|
|
|
|
|
const signed char* amob = range_moebius(0, 100); |
|
589
|
2
|
50
|
|
|
|
|
SUM_ADD(sum, Li(x)); |
|
590
|
132
|
50
|
|
|
|
|
for (k = 2; k <= 100; k++) { |
|
591
|
132
|
100
|
|
|
|
|
if (amob[k] == 0) continue; |
|
592
|
82
|
|
|
|
|
|
ki = 1.0L / (long double) k; |
|
593
|
82
|
|
|
|
|
|
part_term = powl(x,ki); |
|
594
|
82
|
50
|
|
|
|
|
if (part_term > LDBL_MAX) return INFINITY; |
|
595
|
82
|
|
|
|
|
|
term = amob[k] * ki * Li(part_term); |
|
596
|
82
|
|
|
|
|
|
old_sum = SUM_FINAL(sum); |
|
597
|
82
|
50
|
|
|
|
|
SUM_ADD(sum, term); |
|
598
|
82
|
100
|
|
|
|
|
if (fabslnv(SUM_FINAL(sum) - old_sum) <= eps) break; |
|
599
|
|
|
|
|
|
|
} |
|
600
|
2
|
|
|
|
|
|
Safefree(amob); |
|
601
|
2
|
|
|
|
|
|
return SUM_FINAL(sum); |
|
602
|
|
|
|
|
|
|
} |
|
603
|
|
|
|
|
|
|
|
|
604
|
364
|
50
|
|
|
|
|
SUM_ADD(sum, 1.0); |
|
605
|
364
|
|
|
|
|
|
flogx = logl(x); |
|
606
|
364
|
|
|
|
|
|
part_term = 1; |
|
607
|
|
|
|
|
|
|
|
|
608
|
23081
|
50
|
|
|
|
|
for (k = 1; k <= 10000; k++) { |
|
609
|
23081
|
100
|
|
|
|
|
ki = (k-1 < NPRECALC_ZETA) ? riemann_zeta_table[k-1] : ld_riemann_zeta(k+1); |
|
610
|
23081
|
|
|
|
|
|
part_term *= flogx / k; |
|
611
|
23081
|
|
|
|
|
|
term = part_term / (k + k * ki); |
|
612
|
23081
|
|
|
|
|
|
old_sum = SUM_FINAL(sum); |
|
613
|
23081
|
100
|
|
|
|
|
SUM_ADD(sum, term); |
|
614
|
|
|
|
|
|
|
/* printf("R %5d after adding %.18Lg, sum = %.19Lg (%Lg)\n", k, term, sum, fabsl(sum-old_sum)); */ |
|
615
|
23081
|
100
|
|
|
|
|
if (fabslnv(SUM_FINAL(sum) - old_sum) <= eps) break; |
|
616
|
|
|
|
|
|
|
} |
|
617
|
|
|
|
|
|
|
|
|
618
|
364
|
|
|
|
|
|
return SUM_FINAL(sum); |
|
619
|
|
|
|
|
|
|
} |
|
620
|
|
|
|
|
|
|
|
|
621
|
|
|
|
|
|
|
/* Options for LambertW initial approximation: |
|
622
|
|
|
|
|
|
|
* |
|
623
|
|
|
|
|
|
|
* - Four regions, we used before: |
|
624
|
|
|
|
|
|
|
* Pade(3,2), Winitzki 2003, Vargas 2013, Corless 1993 |
|
625
|
|
|
|
|
|
|
* Has issues near -1/e but ok around zero. |
|
626
|
|
|
|
|
|
|
* |
|
627
|
|
|
|
|
|
|
* - Iacono and Boyd (2017). Very simple function over whole range. |
|
628
|
|
|
|
|
|
|
* Doesn't work right very near -1/e and around zero. |
|
629
|
|
|
|
|
|
|
* |
|
630
|
|
|
|
|
|
|
* - Vazquez-Leal et al. (2019). Divides into four regions, power |
|
631
|
|
|
|
|
|
|
* series for each. Great results. Also has issues near -1/e and zero. |
|
632
|
|
|
|
|
|
|
* |
|
633
|
|
|
|
|
|
|
* We use known solutions for near -1/e and around zero. See Fukushima (2013) |
|
634
|
|
|
|
|
|
|
* and Johannson (2017,2020) for lots of discussion and solutions. |
|
635
|
|
|
|
|
|
|
* Use Vazquez-Leal (PSEM Approximations) for the rest. |
|
636
|
|
|
|
|
|
|
*/ |
|
637
|
8
|
|
|
|
|
|
static long double _lambertw_approx(long double x) { |
|
638
|
|
|
|
|
|
|
long double w, k1, k2, k3; |
|
639
|
|
|
|
|
|
|
|
|
640
|
8
|
100
|
|
|
|
|
if (x < -0.312) { |
|
641
|
|
|
|
|
|
|
/* Use Puiseux series, e.g. Verberic 2009, Boost, Johannson (2020). */ |
|
642
|
|
|
|
|
|
|
/* Near the branch point. See Fukushima (2013) section 2.5. */ |
|
643
|
1
|
|
|
|
|
|
k2 = 2.0L * (1.0L + 2.7182818284590452353603L * x); |
|
644
|
1
|
50
|
|
|
|
|
if (k2 <= 0) return -1.0L + 1*LDBL_EPSILON; |
|
645
|
1
|
|
|
|
|
|
k1 = sqrtl(k2); |
|
646
|
1
|
|
|
|
|
|
w = -1.0L + (1.0L + (-1.0L/3.0L + (11.0L/72.0L + (-43.0L/540.0L + (769.0L/17280.0L + (-221.0L/8505.0L + (680863.0L/43545600.0L + (-1963.0L/204120.0L + 226287557.0L/37623398400.0L |
|
647
|
1
|
|
|
|
|
|
* k1) * k1) * k1) * k1) * k1) * k1) * k1) * k1) * k1; |
|
648
|
|
|
|
|
|
|
|
|
649
|
7
|
50
|
|
|
|
|
} else if (x > -0.14 && x < 0.085) { |
|
|
|
100
|
|
|
|
|
|
|
650
|
|
|
|
|
|
|
/* Around zero. See Fukushima (2013) section 2.6. */ |
|
651
|
1
|
|
|
|
|
|
w = (1.0L + (-1.0L + (3.0L/2.0L + (-8.0L/3.0L + (125.0L/24.0L + (-54.0L/5.0L + (16807.0L/720.0L + (-16384.0L/315.0L + 531441.0L/4480.0L |
|
652
|
1
|
|
|
|
|
|
* x) * x) * x) * x) * x) * x) * x) * x) * x; |
|
653
|
|
|
|
|
|
|
|
|
654
|
6
|
100
|
|
|
|
|
} else if (x < 1) { |
|
655
|
|
|
|
|
|
|
/* This and the rest from Vazquez-Leal et al. (2019). */ |
|
656
|
1
|
|
|
|
|
|
k1 = sqrtl(1.0L + 2.7182818284590452353603L * x); |
|
657
|
1
|
|
|
|
|
|
k2 = 0.33333333333333333333333L + 0.70710678118654752440084L / k1 - 0.058925565098878960366737L * k1 + |
|
658
|
1
|
|
|
|
|
|
(x + 0.36787944117144L) * (0.050248489761611L + (0.11138904851051 + 0.040744556245195L * x) * x) |
|
659
|
1
|
|
|
|
|
|
/ |
|
660
|
1
|
|
|
|
|
|
(1.0L + (2.7090878606183L + (1.5510922597820L + 0.095477712183841L * x) * x) * x); |
|
661
|
1
|
|
|
|
|
|
w = -(k2-1)/k2; |
|
662
|
|
|
|
|
|
|
|
|
663
|
5
|
100
|
|
|
|
|
} else if (x < 40) { |
|
664
|
2
|
|
|
|
|
|
k1 = 1.0L + (5.950065500550155L + (13.96586471370701L + (10.52192021050505L + (3.065294254265870L + 0.1204576876518760L * x) * x) * x) * x) * x; |
|
665
|
2
|
|
|
|
|
|
w = 0.1600049638651493L * logl(k1); |
|
666
|
|
|
|
|
|
|
|
|
667
|
3
|
100
|
|
|
|
|
} else if (x < 20000) { |
|
668
|
1
|
|
|
|
|
|
k1 = 1.0L + (-3.16866642511229e11L + (3.420439800038598e10L + |
|
669
|
1
|
|
|
|
|
|
(-1.501433652432257e9L + (3.44887729947585e7L + (-4.453783741137856e5L + |
|
670
|
1
|
|
|
|
|
|
(3257.926478908996L + (-10.82545259305382L + (0.6898058947898353e-1L + |
|
671
|
1
|
|
|
|
|
|
0.4703653406071575e-4L * x) * x) * x) * x) * x) * x) * x) * x) * x; |
|
672
|
1
|
|
|
|
|
|
w = 0.9898045358731312e-1L * logl(k1); |
|
673
|
|
|
|
|
|
|
|
|
674
|
|
|
|
|
|
|
} else { |
|
675
|
2
|
|
|
|
|
|
k1 = 1.0L / (1.0L + logl(1.0L + x)); |
|
676
|
2
|
|
|
|
|
|
k2 = 1.0L / k1; |
|
677
|
2
|
|
|
|
|
|
k3 = logl(k2); |
|
678
|
2
|
|
|
|
|
|
w = k2-1-k3+(1+k3+(-1/2+(1/2)*k3*k3 +(-1/6+(-1+(-1/2+ |
|
679
|
2
|
|
|
|
|
|
(1/3) * k3) * k3) * k3) * k1) * k1) * k1; |
|
680
|
|
|
|
|
|
|
} |
|
681
|
8
|
|
|
|
|
|
return w; |
|
682
|
|
|
|
|
|
|
} |
|
683
|
|
|
|
|
|
|
|
|
684
|
9
|
|
|
|
|
|
NV lambertw(NV x) { |
|
685
|
|
|
|
|
|
|
long double w; |
|
686
|
|
|
|
|
|
|
int i; |
|
687
|
|
|
|
|
|
|
|
|
688
|
9
|
50
|
|
|
|
|
if (x < -0.36787944117145L) |
|
689
|
0
|
|
|
|
|
|
croak("Invalid input to LambertW: x must be >= -1/e"); |
|
690
|
9
|
100
|
|
|
|
|
if (x == 0.0L) return 0.0L; |
|
691
|
|
|
|
|
|
|
|
|
692
|
|
|
|
|
|
|
/* Estimate initial value */ |
|
693
|
8
|
|
|
|
|
|
w = _lambertw_approx(x); |
|
694
|
|
|
|
|
|
|
|
|
695
|
|
|
|
|
|
|
/* TODO: this section might not be best for quad precision */ |
|
696
|
|
|
|
|
|
|
/* If input is too small, return .99999.... */ |
|
697
|
|
|
|
|
|
|
/* if (w <= -1.0L) return -1.0L + LDBL_EPSILON; */ |
|
698
|
|
|
|
|
|
|
/* For very small inputs, don't iterate, return approx directly. */ |
|
699
|
8
|
100
|
|
|
|
|
if (x < -0.36768) return w; |
|
700
|
|
|
|
|
|
|
|
|
701
|
|
|
|
|
|
|
#if 0 /* Halley */ |
|
702
|
|
|
|
|
|
|
long double lastw = w; |
|
703
|
|
|
|
|
|
|
for (i = 0; i < 100; i++) { |
|
704
|
|
|
|
|
|
|
long double ew = expl(w); |
|
705
|
|
|
|
|
|
|
long double wew = w * ew; |
|
706
|
|
|
|
|
|
|
long double wewx = wew - x; |
|
707
|
|
|
|
|
|
|
long double w1 = w + 1; |
|
708
|
|
|
|
|
|
|
w = w - wewx / (ew * w1 - (w+2) * wewx/(2*w1)); |
|
709
|
|
|
|
|
|
|
if (w != 0.0L && fabsl((w-lastw)/w) <= 8*LDBL_EPSILON) break; |
|
710
|
|
|
|
|
|
|
lastw = w; |
|
711
|
|
|
|
|
|
|
} |
|
712
|
|
|
|
|
|
|
#else /* Fritsch, see Veberic 2009. 1-2 iterations are enough. */ |
|
713
|
15
|
50
|
|
|
|
|
for (i = 0; i < 6 && w != 0.0L; i++) { |
|
|
|
50
|
|
|
|
|
|
|
714
|
15
|
|
|
|
|
|
long double w1 = 1 + w; |
|
715
|
15
|
|
|
|
|
|
long double zn = logl((long double)x/w) - w; |
|
716
|
15
|
|
|
|
|
|
long double qn = 2 * w1 * (w1+(2.0L/3.0L)*zn); |
|
717
|
15
|
|
|
|
|
|
long double en = (zn/w1) * (qn-zn)/(qn-2.0L*zn); |
|
718
|
|
|
|
|
|
|
/* w *= 1.0L + en; if (fabsl(en) <= 16*LDBL_EPSILON) break; */ |
|
719
|
15
|
|
|
|
|
|
long double wen = w * en; |
|
720
|
15
|
50
|
|
|
|
|
if (isnan(wen)) return 0; |
|
721
|
15
|
|
|
|
|
|
w += wen; |
|
722
|
15
|
100
|
|
|
|
|
if (fabsl(wen) <= 64*LDBL_EPSILON) break; |
|
723
|
|
|
|
|
|
|
} |
|
724
|
|
|
|
|
|
|
#endif |
|
725
|
|
|
|
|
|
|
|
|
726
|
|
|
|
|
|
|
#if LNV_IS_QUAD /* For quadmath, one high precision correction */ |
|
727
|
|
|
|
|
|
|
if (w != LNV_ZERO) { |
|
728
|
|
|
|
|
|
|
LNV lw = w; |
|
729
|
|
|
|
|
|
|
LNV w1 = LNV_ONE + lw; |
|
730
|
|
|
|
|
|
|
LNV zn = loglnv((LNV)x/lw) - lw; |
|
731
|
|
|
|
|
|
|
LNV qn = LNVCONST(2.0) * w1 * (w1+(LNVCONST(2.0)/LNVCONST(3.0))*zn); |
|
732
|
|
|
|
|
|
|
LNV en = (zn/w1) * (qn-zn)/(qn-LNVCONST(2.0)*zn); |
|
733
|
|
|
|
|
|
|
return lw + lw * en; |
|
734
|
|
|
|
|
|
|
} |
|
735
|
|
|
|
|
|
|
#endif |
|
736
|
|
|
|
|
|
|
|
|
737
|
|
|
|
|
|
|
/* With long double = 64-bit double, we have 15 digits precision |
|
738
|
|
|
|
|
|
|
* near the branch point, and 16 over the rest of the range. |
|
739
|
|
|
|
|
|
|
* With long double = x86 extended precision, we have over 17 digits |
|
740
|
|
|
|
|
|
|
* over the entire range. |
|
741
|
|
|
|
|
|
|
* Correcting to the exact LDBL_EPSILON does not improve this. */ |
|
742
|
|
|
|
|
|
|
|
|
743
|
7
|
|
|
|
|
|
return w; |
|
744
|
|
|
|
|
|
|
} |
|
745
|
|
|
|
|
|
|
|
|
746
|
|
|
|
|
|
|
|
|
747
|
|
|
|
|
|
|
/******************************************************************************/ |
|
748
|
|
|
|
|
|
|
/* Chebyshev PSI / THETA */ |
|
749
|
|
|
|
|
|
|
/******************************************************************************/ |
|
750
|
|
|
|
|
|
|
|
|
751
|
9
|
|
|
|
|
|
NV chebyshev_psi(UV n) |
|
752
|
|
|
|
|
|
|
{ |
|
753
|
|
|
|
|
|
|
UV k; |
|
754
|
9
|
|
|
|
|
|
SUM_INIT(sum); |
|
755
|
|
|
|
|
|
|
|
|
756
|
58
|
100
|
|
|
|
|
for (k = log2floor(n); k > 0; k--) { |
|
|
|
100
|
|
|
|
|
|
|
757
|
49
|
100
|
|
|
|
|
SUM_ADD(sum, chebyshev_theta(rootint(n,k))); |
|
758
|
|
|
|
|
|
|
} |
|
759
|
9
|
|
|
|
|
|
return SUM_FINAL(sum); |
|
760
|
|
|
|
|
|
|
} |
|
761
|
|
|
|
|
|
|
|
|
762
|
|
|
|
|
|
|
#if BITS_PER_WORD == 64 |
|
763
|
|
|
|
|
|
|
typedef struct { |
|
764
|
|
|
|
|
|
|
UV n; |
|
765
|
|
|
|
|
|
|
LNV theta; |
|
766
|
|
|
|
|
|
|
} cheby_theta_t; |
|
767
|
|
|
|
|
|
|
static const cheby_theta_t _cheby_theta[] = { /* >= quad math precision */ |
|
768
|
|
|
|
|
|
|
{ UVCONST( 67108864),LNVCONST( 67100507.6357700963903836828562472350035880) }, |
|
769
|
|
|
|
|
|
|
{ UVCONST( 100000000),LNVCONST( 99987730.0180220043832124342600487053812729) }, |
|
770
|
|
|
|
|
|
|
{ UVCONST( 134217728),LNVCONST( 134204014.5735572091791081610859055728165544) }, |
|
771
|
|
|
|
|
|
|
{ UVCONST( 268435456),LNVCONST( 268419741.6134308193112682817754501071404173) }, |
|
772
|
|
|
|
|
|
|
{ UVCONST( 536870912),LNVCONST( 536842885.8045763840625719515011160692495056) }, |
|
773
|
|
|
|
|
|
|
{ UVCONST( 1000000000),LNVCONST( 999968978.5775661447991262386023331863364793) }, |
|
774
|
|
|
|
|
|
|
{ UVCONST( 1073741824),LNVCONST( 1073716064.8860663337617909073555831842945484) }, |
|
775
|
|
|
|
|
|
|
{ UVCONST( 2147483648),LNVCONST( 2147432200.2475857676814950053003448716360822) }, |
|
776
|
|
|
|
|
|
|
{ UVCONST( 4294967296),LNVCONST( 4294889489.1735446386752045191908417183337361) }, |
|
777
|
|
|
|
|
|
|
{ UVCONST( 8589934592),LNVCONST( 8589863179.5654263491545135406516173629373070) }, |
|
778
|
|
|
|
|
|
|
{ UVCONST( 10000000000),LNVCONST( 9999939830.6577573841592219954033850595228736) }, |
|
779
|
|
|
|
|
|
|
{ UVCONST( 12884901888),LNVCONST( 12884796620.4324254952601520445848183460347362) }, |
|
780
|
|
|
|
|
|
|
{ UVCONST( 17179869184),LNVCONST( 17179757715.9924077567777285147574707468995695) }, |
|
781
|
|
|
|
|
|
|
{ UVCONST( 21474836480),LNVCONST( 21474693322.0998273969188369449626287713082943) }, |
|
782
|
|
|
|
|
|
|
{ UVCONST( 25769803776),LNVCONST( 25769579799.3751535467593954636665656772211515) }, |
|
783
|
|
|
|
|
|
|
{ UVCONST( 30064771072),LNVCONST( 30064545001.2305211029215168703433831598544454) }, |
|
784
|
|
|
|
|
|
|
{ UVCONST( 34359738368),LNVCONST( 34359499180.0126643918259085362039638823175054) }, |
|
785
|
|
|
|
|
|
|
{ UVCONST( 51539607552),LNVCONST( 51539356394.9531019037592855639826469993402730) }, |
|
786
|
|
|
|
|
|
|
{ UVCONST( 68719476736),LNVCONST( 68719165213.6369838785284711480925219076501720) }, |
|
787
|
|
|
|
|
|
|
{ UVCONST( 85899345920),LNVCONST( 85899083852.3471545629838432726841470626910905) }, |
|
788
|
|
|
|
|
|
|
{ UVCONST( 100000000000),LNVCONST( 99999737653.1074446948519125729820679772770146) }, |
|
789
|
|
|
|
|
|
|
{ UVCONST( 103079215104),LNVCONST(103079022007.113299711630969211422868856259124) }, |
|
790
|
|
|
|
|
|
|
{ UVCONST( 120259084288),LNVCONST(120258614516.787336970535750737470005730125261) }, |
|
791
|
|
|
|
|
|
|
{ UVCONST( 137438953472),LNVCONST(137438579206.444595884982301543904849253294539) }, |
|
792
|
|
|
|
|
|
|
{ UVCONST( 171798691840),LNVCONST(171798276885.585945657918751085729734540334501) }, |
|
793
|
|
|
|
|
|
|
{ UVCONST( 206158430208),LNVCONST(206158003808.160276853604927822609009916573462) }, |
|
794
|
|
|
|
|
|
|
{ UVCONST( 240518168576),LNVCONST(240517893445.995868018331936763125264759516048) }, |
|
795
|
|
|
|
|
|
|
{ UVCONST( 274877906944),LNVCONST(274877354651.045354829956619821889825596300686) }, |
|
796
|
|
|
|
|
|
|
{ UVCONST( 309237645312),LNVCONST(309237050379.850690561796126460858271984023198) }, |
|
797
|
|
|
|
|
|
|
{ UVCONST( 343597383680),LNVCONST(343596855806.595496630500062749631211394707114) }, |
|
798
|
|
|
|
|
|
|
{ UVCONST( 377957122048),LNVCONST(377956498560.227794386327526022452943941537993) }, |
|
799
|
|
|
|
|
|
|
{ UVCONST( 412316860416),LNVCONST(412316008796.349553568121442261222464590518293) }, |
|
800
|
|
|
|
|
|
|
{ UVCONST( 446676598784),LNVCONST(446675972485.936512329625489223180824947531484) }, |
|
801
|
|
|
|
|
|
|
{ UVCONST( 481036337152),LNVCONST(481035608287.572961376833237046440177624505864) }, |
|
802
|
|
|
|
|
|
|
{ UVCONST( 515396075520),LNVCONST(515395302740.633513931333424447688399032397200) }, |
|
803
|
|
|
|
|
|
|
{ UVCONST( 549755813888),LNVCONST(549755185085.539613556787409928561107952681488) }, |
|
804
|
|
|
|
|
|
|
{ UVCONST( 584115552256),LNVCONST(584115015741.698143680148976236958207248900725) }, |
|
805
|
|
|
|
|
|
|
{ UVCONST( 618475290624),LNVCONST(618474400071.621528348965919774195984612254220) }, |
|
806
|
|
|
|
|
|
|
{ UVCONST( 652835028992),LNVCONST(652834230470.583317059774197550110194348469358) }, |
|
807
|
|
|
|
|
|
|
{ UVCONST( 687194767360),LNVCONST(687193697328.927006867624832386534836384752774) }, |
|
808
|
|
|
|
|
|
|
{ UVCONST( 721554505728),LNVCONST(721553211683.605313067593521060195071837766347) }, |
|
809
|
|
|
|
|
|
|
{ UVCONST( 755914244096),LNVCONST(755913502349.878525212441903698096011352015192) }, |
|
810
|
|
|
|
|
|
|
{ UVCONST( 790273982464),LNVCONST(790273042590.053075430445971969285969445183076) }, |
|
811
|
|
|
|
|
|
|
{ UVCONST( 824633720832),LNVCONST(824633080997.428352876758261549475609957696369) }, |
|
812
|
|
|
|
|
|
|
{ UVCONST( 858993459200),LNVCONST(858992716288.318498931165663742671579465316192) }, |
|
813
|
|
|
|
|
|
|
{ UVCONST( 893353197568),LNVCONST(893352235882.851072417721659027263613727927680) }, |
|
814
|
|
|
|
|
|
|
{ UVCONST( 927712935936),LNVCONST(927711881043.628817668337317445143018372892386) }, |
|
815
|
|
|
|
|
|
|
{ UVCONST( 962072674304),LNVCONST(962071726126.508938539006575212272731584070786) }, |
|
816
|
|
|
|
|
|
|
{ UVCONST( 996432412672),LNVCONST(996431411588.361462717402562171913706963939018) }, |
|
817
|
|
|
|
|
|
|
{ UVCONST( 1099511627776),LNVCONST(1099510565082.05800550569923209414874779035972) }, |
|
818
|
|
|
|
|
|
|
{ UVCONST( 1168231104512),LNVCONST(1168230478726.83399452743801182220790107593115) }, |
|
819
|
|
|
|
|
|
|
{ UVCONST( 1236950581248),LNVCONST(1236949680081.02610603189530371762093291521116) }, |
|
820
|
|
|
|
|
|
|
{ UVCONST( 1305670057984),LNVCONST(1305668780900.04255251887970870257110498423202) }, |
|
821
|
|
|
|
|
|
|
{ UVCONST( 1374389534720),LNVCONST(1374388383792.63751003694755359184583212193880) }, |
|
822
|
|
|
|
|
|
|
{ UVCONST( 1443109011456),LNVCONST(1443107961091.80955496949174183091839841371227) }, |
|
823
|
|
|
|
|
|
|
{ UVCONST( 1511828488192),LNVCONST(1511827317611.91227277802426032456922797572429) }, |
|
824
|
|
|
|
|
|
|
{ UVCONST( 1580547964928),LNVCONST(1580546753969.30607547506449941085747942395437) }, |
|
825
|
|
|
|
|
|
|
{ UVCONST( 1649267441664),LNVCONST(1649265973878.75361554498682516738256005501353) }, |
|
826
|
|
|
|
|
|
|
{ UVCONST( 1717986918400),LNVCONST(1717985403764.24562741452793071287954107946922) }, |
|
827
|
|
|
|
|
|
|
{ UVCONST( 1786706395136),LNVCONST(1786704769212.04241689416220650800274263053933) }, |
|
828
|
|
|
|
|
|
|
{ UVCONST( 1855425871872),LNVCONST(1855425013030.54920163513184322741954734357404) }, |
|
829
|
|
|
|
|
|
|
{ UVCONST( 1924145348608),LNVCONST(1924143701943.02957992419280264060220278182021) }, |
|
830
|
|
|
|
|
|
|
{ UVCONST( 1992864825344),LNVCONST(1992863373568.84039296068619447120308124302086) }, |
|
831
|
|
|
|
|
|
|
{ UVCONST( 2061584302080),LNVCONST(2061583632335.91985095534685076604018573279204) }, |
|
832
|
|
|
|
|
|
|
{ UVCONST( 2130303778816),LNVCONST(2113122935598.01727180199783433992649406589029) }, |
|
833
|
|
|
|
|
|
|
{ UVCONST( 2199023255552),LNVCONST(2199021399611.18488312543276191461914978761981) }, |
|
834
|
|
|
|
|
|
|
{ UVCONST( 2267742732288),LNVCONST(2267740947106.05038218811506263712808318234921) }, |
|
835
|
|
|
|
|
|
|
{ UVCONST( 2336462209024),LNVCONST(2336460081480.34962633829077377680844065198307) }, |
|
836
|
|
|
|
|
|
|
{ UVCONST( 2405181685760),LNVCONST(2405179969505.38642629423585641169740223940265) }, |
|
837
|
|
|
|
|
|
|
{ UVCONST( 2473901162496),LNVCONST(2473899311193.37872375168104562948639924654178) }, |
|
838
|
|
|
|
|
|
|
{ UVCONST( 2542620639232),LNVCONST(2542619362554.88893589220737167756411653816418) }, |
|
839
|
|
|
|
|
|
|
{ UVCONST( 2611340115968),LNVCONST(2611338370515.94936514022501267847930999670553) }, |
|
840
|
|
|
|
|
|
|
{ UVCONST( 2680059592704),LNVCONST(2680057722824.52981820001574883706268873541107) }, |
|
841
|
|
|
|
|
|
|
{ UVCONST( 2748779069440),LNVCONST(2748777610452.18903407570165081726781627254885) }, |
|
842
|
|
|
|
|
|
|
{ UVCONST( 2817498546176),LNVCONST(2817497017165.31924616507392971415494161401775) }, |
|
843
|
|
|
|
|
|
|
{ UVCONST( 2886218022912),LNVCONST(2886216579432.32232322707222172612181994322081) }, |
|
844
|
|
|
|
|
|
|
{ UVCONST( 2954937499648),LNVCONST(2954936100812.97301730406598982753121204977388) }, |
|
845
|
|
|
|
|
|
|
{ UVCONST( 3023656976384),LNVCONST(3023654789503.82041452274471455184651411931920) }, |
|
846
|
|
|
|
|
|
|
{ UVCONST( 3298534883328),LNVCONST(3298533215621.76606493931157388037915263658637) }, |
|
847
|
|
|
|
|
|
|
{ UVCONST( 3573412790272),LNVCONST(3573411344351.74163523704886736624674718378131) }, |
|
848
|
|
|
|
|
|
|
{ UVCONST( 3848290697216),LNVCONST(3848288415701.82534219216958446478503907262807) }, |
|
849
|
|
|
|
|
|
|
{ UVCONST( 4123168604160),LNVCONST(4123166102085.86116301709394219323327831487542) }, |
|
850
|
|
|
|
|
|
|
{ UVCONST( 4398046511104),LNVCONST(4398044965678.05143041707871320554940671182665) }, |
|
851
|
|
|
|
|
|
|
{ UVCONST( 4672924418048),LNVCONST(4672922414672.04998927945349278916525727295687) }, |
|
852
|
|
|
|
|
|
|
{ UVCONST( 4947802324992),LNVCONST(4947800056419.04384937181159608905993450182729) }, |
|
853
|
|
|
|
|
|
|
{ UVCONST( 5222680231936),LNVCONST(5222678728087.69487334278665824384732845008859) }, |
|
854
|
|
|
|
|
|
|
{ UVCONST( 5497558138880),LNVCONST(5497555766573.55159115560501595606332808978878) }, |
|
855
|
|
|
|
|
|
|
{ UVCONST( 5772436045824),LNVCONST(5772433560746.27053256770924553245647027548204) }, |
|
856
|
|
|
|
|
|
|
{ UVCONST( 6047313952768),LNVCONST(6047310750621.24497633828761530843255989494448) }, |
|
857
|
|
|
|
|
|
|
{ UVCONST( 6322191859712),LNVCONST(6322189275338.39747421237532473168802646234745) }, |
|
858
|
|
|
|
|
|
|
{ UVCONST( 6597069766656),LNVCONST(6579887620000.56226807898107616294821989189226) }, |
|
859
|
|
|
|
|
|
|
{ UVCONST( 6871947673600),LNVCONST(6871945430474.61791600096091374271286154432006) }, |
|
860
|
|
|
|
|
|
|
{ UVCONST( 7146825580544),LNVCONST(7146823258390.34361980709600216319269118247416) }, |
|
861
|
|
|
|
|
|
|
{ UVCONST( 7421703487488),LNVCONST(7421700443390.35536080251964387835425662360121) }, |
|
862
|
|
|
|
|
|
|
{ UVCONST( 7696581394432),LNVCONST(7696578975137.73249441643024336954233783264803) }, |
|
863
|
|
|
|
|
|
|
{ UVCONST( 7971459301376),LNVCONST(7971457197928.90863708984184849978605273042512) }, |
|
864
|
|
|
|
|
|
|
{ UVCONST( 8246337208320),LNVCONST(8246333982863.77146812177727648999195989358960) }, |
|
865
|
|
|
|
|
|
|
{ UVCONST( 8521215115264),LNVCONST(8529802085075.55635100929751669785228592926043) }, |
|
866
|
|
|
|
|
|
|
{ UVCONST( 8796093022208),LNVCONST(8796089836425.34909684634625258535266362465034) }, |
|
867
|
|
|
|
|
|
|
{ UVCONST( 9345848836096),LNVCONST(9345845828116.77456046925508587313) }, |
|
868
|
|
|
|
|
|
|
{ UVCONST( 9895604649984),LNVCONST(9895601077915.26821447819584407150) }, |
|
869
|
|
|
|
|
|
|
{ UVCONST(10000000000000),LNVCONST(9999996988293.03419965318214160284) }, |
|
870
|
|
|
|
|
|
|
{ UVCONST(15000000000000),LNVCONST(14999996482301.7098815115045166858) }, |
|
871
|
|
|
|
|
|
|
{ UVCONST(20000000000000),LNVCONST(19999995126082.2286880312461318496) }, |
|
872
|
|
|
|
|
|
|
{ UVCONST(25000000000000),LNVCONST(24999994219058.4086216020475916538) }, |
|
873
|
|
|
|
|
|
|
{ UVCONST(30000000000000),LNVCONST(29999995531389.8454274046657200568) }, |
|
874
|
|
|
|
|
|
|
{ UVCONST(35000000000000),LNVCONST(34999992921190.8049427456456479005) }, |
|
875
|
|
|
|
|
|
|
{ UVCONST(40000000000000),LNVCONST(39999993533724.3168289589273168844) }, |
|
876
|
|
|
|
|
|
|
{ UVCONST(45000000000000),LNVCONST(44999993567606.9795798378256194424) }, |
|
877
|
|
|
|
|
|
|
{ UVCONST(50000000000000),LNVCONST(49999992543194.2636545758235373677) }, |
|
878
|
|
|
|
|
|
|
{ UVCONST(55000000000000),LNVCONST(54999990847877.2435105757522625171) }, |
|
879
|
|
|
|
|
|
|
{ UVCONST(60000000000000),LNVCONST(59999990297033.6261976055811111726) }, |
|
880
|
|
|
|
|
|
|
{ UVCONST(65000000000000),LNVCONST(64999990861395.5522142429859245014) }, |
|
881
|
|
|
|
|
|
|
{ UVCONST(70000000000000),LNVCONST(69999994316409.8717306521862685981) }, |
|
882
|
|
|
|
|
|
|
{ UVCONST(75000000000000),LNVCONST(74999990126219.8344899338374090165) }, |
|
883
|
|
|
|
|
|
|
{ UVCONST(80000000000000),LNVCONST(79999990160858.3042387288372250950) }, |
|
884
|
|
|
|
|
|
|
{ UVCONST(85000000000000),LNVCONST(84999987096970.5915212896832780715) }, |
|
885
|
|
|
|
|
|
|
{ UVCONST(90000000000000),LNVCONST(89999989501395.0738966599857919767) }, |
|
886
|
|
|
|
|
|
|
{ UVCONST(95000000000000),LNVCONST(94999990785908.6672552042792168144) }, |
|
887
|
|
|
|
|
|
|
{ UVCONST(100000000000000),LNVCONST(99999990573246.9785384070303475639) }, |
|
888
|
|
|
|
|
|
|
}; |
|
889
|
|
|
|
|
|
|
#define NCHEBY_VALS (sizeof(_cheby_theta)/sizeof(_cheby_theta[0])) |
|
890
|
|
|
|
|
|
|
#endif |
|
891
|
|
|
|
|
|
|
|
|
892
|
59
|
|
|
|
|
|
NV chebyshev_theta(UV n) |
|
893
|
|
|
|
|
|
|
{ |
|
894
|
59
|
|
|
|
|
|
uint16_t i = 0; |
|
895
|
|
|
|
|
|
|
UV tp, startn, seg_base, seg_low, seg_high; |
|
896
|
|
|
|
|
|
|
unsigned char* segment; |
|
897
|
|
|
|
|
|
|
void* ctx; |
|
898
|
59
|
|
|
|
|
|
LNV initial_sum, prod = LNV_ONE; |
|
899
|
59
|
|
|
|
|
|
SUM_INIT(sum); |
|
900
|
|
|
|
|
|
|
|
|
901
|
59
|
100
|
|
|
|
|
if (n < 500) { |
|
902
|
379
|
100
|
|
|
|
|
for (i = 1; (tp = primes_tiny[i]) <= n; i++) { |
|
903
|
326
|
100
|
|
|
|
|
SUM_ADD(sum, loglnv(tp)); |
|
904
|
|
|
|
|
|
|
} |
|
905
|
53
|
|
|
|
|
|
return SUM_FINAL(sum); |
|
906
|
|
|
|
|
|
|
} |
|
907
|
|
|
|
|
|
|
|
|
908
|
|
|
|
|
|
|
#if defined NCHEBY_VALS |
|
909
|
6
|
100
|
|
|
|
|
if (n >= _cheby_theta[0].n) { |
|
910
|
1
|
50
|
|
|
|
|
for (i = 1; i < NCHEBY_VALS; i++) |
|
911
|
1
|
50
|
|
|
|
|
if (n < _cheby_theta[i].n) |
|
912
|
1
|
|
|
|
|
|
break; |
|
913
|
1
|
|
|
|
|
|
startn = _cheby_theta[i-1].n; |
|
914
|
1
|
|
|
|
|
|
initial_sum = _cheby_theta[i-1].theta; |
|
915
|
|
|
|
|
|
|
} else |
|
916
|
|
|
|
|
|
|
#endif |
|
917
|
|
|
|
|
|
|
{ |
|
918
|
5
|
50
|
|
|
|
|
SUM_ADD(sum, loglnv(2*3*5*7*11*13)); |
|
919
|
5
|
|
|
|
|
|
startn = 17; |
|
920
|
5
|
|
|
|
|
|
initial_sum = 0; |
|
921
|
|
|
|
|
|
|
} |
|
922
|
|
|
|
|
|
|
|
|
923
|
6
|
|
|
|
|
|
ctx = start_segment_primes(startn, n, &segment); |
|
924
|
|
|
|
|
|
|
#if 0 |
|
925
|
|
|
|
|
|
|
while (next_segment_primes(ctx, &seg_base, &seg_low, &seg_high)) { |
|
926
|
|
|
|
|
|
|
START_DO_FOR_EACH_SIEVE_PRIME( segment, seg_base, seg_low, seg_high ) { |
|
927
|
|
|
|
|
|
|
SUM_ADD(sum, loglnv(p)); |
|
928
|
|
|
|
|
|
|
} END_DO_FOR_EACH_SIEVE_PRIME |
|
929
|
|
|
|
|
|
|
} |
|
930
|
|
|
|
|
|
|
#else |
|
931
|
16
|
100
|
|
|
|
|
while (next_segment_primes(ctx, &seg_base, &seg_low, &seg_high)) { |
|
932
|
350117
|
50
|
|
|
|
|
START_DO_FOR_EACH_SIEVE_PRIME( segment, seg_base, seg_low, seg_high ) { |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
933
|
330048
|
|
|
|
|
|
prod *= (LNV) p; |
|
934
|
330048
|
100
|
|
|
|
|
if (++i >= (LNV_IS_QUAD ? 64 : 8)) { |
|
935
|
41254
|
100
|
|
|
|
|
SUM_ADD(sum, loglnv(prod)); |
|
936
|
41254
|
|
|
|
|
|
prod = LNV_ONE; |
|
937
|
41254
|
|
|
|
|
|
i = 0; |
|
938
|
|
|
|
|
|
|
} |
|
939
|
20044
|
|
|
|
|
|
} END_DO_FOR_EACH_SIEVE_PRIME |
|
940
|
|
|
|
|
|
|
} |
|
941
|
6
|
50
|
|
|
|
|
if (prod > 1.0) { SUM_ADD(sum, loglnv(prod)); prod = LNV_ONE; } |
|
|
|
50
|
|
|
|
|
|
|
942
|
|
|
|
|
|
|
#endif |
|
943
|
6
|
|
|
|
|
|
end_segment_primes(ctx); |
|
944
|
|
|
|
|
|
|
|
|
945
|
6
|
100
|
|
|
|
|
if (initial_sum > 0) SUM_ADD(sum, initial_sum); |
|
|
|
50
|
|
|
|
|
|
|
946
|
6
|
|
|
|
|
|
return SUM_FINAL(sum); |
|
947
|
|
|
|
|
|
|
} |
|
948
|
|
|
|
|
|
|
|
|
949
|
|
|
|
|
|
|
|
|
950
|
|
|
|
|
|
|
/******************************************************************************/ |
|
951
|
|
|
|
|
|
|
/* Other */ |
|
952
|
|
|
|
|
|
|
/******************************************************************************/ |
|
953
|
|
|
|
|
|
|
|
|
954
|
|
|
|
|
|
|
#if 0 |
|
955
|
|
|
|
|
|
|
/* This is the de Bruijn approximation, not exact! */ |
|
956
|
|
|
|
|
|
|
static long double dickman_rho(long double u) { |
|
957
|
|
|
|
|
|
|
int i; |
|
958
|
|
|
|
|
|
|
long double zeta; |
|
959
|
|
|
|
|
|
|
|
|
960
|
|
|
|
|
|
|
if (u <= 1) return 1; |
|
961
|
|
|
|
|
|
|
if (u <= 2) return 1-logl(u); |
|
962
|
|
|
|
|
|
|
|
|
963
|
|
|
|
|
|
|
/* Also see: |
|
964
|
|
|
|
|
|
|
* Granville 2008 https://dms.umontreal.ca/~andrew/PDF/msrire.pdf |
|
965
|
|
|
|
|
|
|
* Gorodetsky 2022 https://arxiv.org/pdf/2212.01949.pdf |
|
966
|
|
|
|
|
|
|
* van Hoek 2019 https://studenttheses.uu.nl/bitstream/handle/20.500.12932/32867/Masterscriptie%20Bart%20van%20Hoek.pdf |
|
967
|
|
|
|
|
|
|
*/ |
|
968
|
|
|
|
|
|
|
|
|
969
|
|
|
|
|
|
|
/* Calculate zeta. See Bach and Sorenson (2013) page 10 */ |
|
970
|
|
|
|
|
|
|
zeta = 2*(u-1); |
|
971
|
|
|
|
|
|
|
for (i = 0; i < 7; i++) { |
|
972
|
|
|
|
|
|
|
long double uz1 = 1 + u*zeta; |
|
973
|
|
|
|
|
|
|
zeta = zeta - ( (zeta-logl(uz1))*uz1 ) / (uz1-u); |
|
974
|
|
|
|
|
|
|
} |
|
975
|
|
|
|
|
|
|
/* Alternately: zeta = -1/u - LambertW1(-exp(-1/u)/u) */ |
|
976
|
|
|
|
|
|
|
|
|
977
|
|
|
|
|
|
|
return expl(-u*zeta+Ei(zeta)) / (zeta * sqrtl(2*3.1415926535*u)); |
|
978
|
|
|
|
|
|
|
} |
|
979
|
|
|
|
|
|
|
#endif |
|
980
|
|
|
|
|
|
|
|
|
981
|
|
|
|
|
|
|
|