Skip to content

Commit a6ea863

Browse files
authored
Bugfix: imprecision of complex li2 for small arguments (#39)
Note: This change leads to a performance decrease due to the use of `std::log(const std::complex<T>&)`, which is more precise than `std::log(|z|) + I*std::arg(z)` for values of z close to unity.
1 parent d47291c commit a6ea863

34 files changed

+656
-665
lines changed

src/c/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ add_library(polylogarithm_c
99
Li4.c
1010
Li5.c
1111
Li6.c
12+
log.c
1213
)
1314

1415
target_include_directories(polylogarithm_c PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

src/c/Li2.c

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#include <complex.h>
88
#include <float.h>
99
#include <math.h>
10-
#include "fast_clog.h"
10+
#include "log.h"
1111

1212

1313
static long double hornerl(long double x, const long double* c, int len)
@@ -331,23 +331,23 @@ float _Complex cli2f(float _Complex z)
331331
/* transformation to |z|<1, Re(z)<=0.5f */
332332
if (rz <= 0.5f) {
333333
if (nz > 1.0f) {
334-
const float _Complex lz = fast_clogf(-z);
335-
u = -fast_clogf(1.0f - 1.0f / z);
334+
const float _Complex lz = clogf(-z);
335+
u = -clogf(1.0f - 1.0f / z);
336336
rest = -0.5f*lz*lz - PI*PI/6;
337337
sgn = -1;
338338
} else { /* nz <= 1 */
339-
u = -fast_clogf(1.0f - z);
339+
u = -clogf(1.0f - z);
340340
rest = 0;
341341
sgn = 1;
342342
}
343343
} else { /* rz > 0.5f */
344344
if (nz <= 2*rz) {
345-
u = -fast_clogf(z);
346-
rest = u*fast_clogf(1.0f - z) + PI*PI/6;
345+
u = -clogf(z);
346+
rest = u*clogf(1.0f - z) + PI*PI/6;
347347
sgn = -1;
348348
} else { /* nz > 2*rz */
349-
const float _Complex lz = fast_clogf(-z);
350-
u = -fast_clogf(1.0f - 1.0f / z);
349+
const float _Complex lz = clogf(-z);
350+
u = -clogf(1.0f - 1.0f / z);
351351
rest = -0.5f*lz*lz - PI*PI/6;
352352
sgn = -1;
353353
}
@@ -412,23 +412,23 @@ double _Complex cli2(double _Complex z)
412412
/* transformation to |z|<1, Re(z)<=0.5 */
413413
if (rz <= 0.5) {
414414
if (nz > 1.0) {
415-
const double _Complex lz = fast_clog(-z);
416-
u = -fast_clog(1.0 - 1.0 / z);
415+
const double _Complex lz = clog(-z);
416+
u = -clog1p(-1.0/z);
417417
rest = -0.5*lz*lz - PI*PI/6;
418418
sgn = -1;
419419
} else { /* nz <= 1 */
420-
u = -fast_clog(1.0 - z);
420+
u = -clog1p(-z);
421421
rest = 0;
422422
sgn = 1;
423423
}
424424
} else { /* rz > 0.5 */
425425
if (nz <= 2*rz) {
426-
u = -fast_clog(z);
427-
rest = u*fast_clog(1.0 - z) + PI*PI/6;
426+
u = -clog(z);
427+
rest = u*clog1p(-z) + PI*PI/6;
428428
sgn = -1;
429429
} else { /* nz > 2*rz */
430-
const double _Complex lz = fast_clog(-z);
431-
u = -fast_clog(1.0 - 1.0 / z);
430+
const double _Complex lz = clog(-z);
431+
u = -clog1p(-1.0/z);
432432
rest = -0.5*lz*lz - PI*PI/6;
433433
sgn = -1;
434434
}
@@ -517,23 +517,23 @@ long double _Complex cli2l(long double _Complex z)
517517
/* transformation to |z|<1, Re(z)<=0.5 */
518518
if (rz <= 0.5L) {
519519
if (nz > 1.0L) {
520-
const long double _Complex lz = fast_clogl(-z);
521-
u = -fast_clogl(1.0L - 1.0L/z);
520+
const long double _Complex lz = clogl(-z);
521+
u = -clog1pl(-1.0L/z);
522522
rest = -0.5L*lz*lz - PI*PI/6;
523523
sgn = -1;
524524
} else { /* nz <= 1 */
525-
u = -fast_clogl(1.0L - z);
525+
u = -clog1pl(-z);
526526
rest = 0;
527527
sgn = 1;
528528
}
529529
} else { /* rz > 0.5L */
530530
if (nz <= 2*rz) {
531-
u = -fast_clogl(z);
532-
rest = u * fast_clogl(1.0L - z) + PI*PI/6;
531+
u = -clogl(z);
532+
rest = u * clog1pl(-z) + PI*PI/6;
533533
sgn = -1;
534534
} else { /* nz > 2*rz */
535-
const long double _Complex lz = fast_clogl(-z);
536-
u = -fast_clogl(1.0L - 1.0L/z);
535+
const long double _Complex lz = clogl(-z);
536+
u = -clog1pl(-1.0L/z);
537537
rest = -0.5L*lz*lz - PI*PI/6;
538538
sgn = -1;
539539
}

src/c/Li3.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#include <complex.h>
88
#include <float.h>
99
#include <math.h>
10-
#include "fast_clog.h"
10+
#include "log.h"
1111

1212
/// Li_3(x) for x in [-1,0]
1313
static double li3_neg(double x)
@@ -145,7 +145,7 @@ double _Complex cli3(double _Complex z)
145145
const double _Complex u4 = u2*u2;
146146
const double _Complex u8 = u4*u4;
147147
const double _Complex c0 = zeta3 + u*(zeta2 - u2/12.0);
148-
const double _Complex c1 = 0.25 * (3.0 - 2.0*fast_pos_clog(-u));
148+
const double _Complex c1 = 0.25 * (3.0 - 2.0*pos_clog(-u));
149149

150150
const double cs[7] = {
151151
-3.4722222222222222e-03, 1.1574074074074074e-05,
@@ -165,11 +165,11 @@ double _Complex cli3(double _Complex z)
165165
double _Complex u = 0.0, rest = 0.0;
166166

167167
if (nz <= 1.0) {
168-
u = -fast_pos_clog(1.0 - z);
168+
u = -pos_clog(1.0 - z);
169169
} else { // nz > 1
170170
const double arg = pz > 0.0 ? pz - PI : pz + PI;
171171
const double _Complex lmz = lnz + arg*I; // clog(-z)
172-
u = -fast_pos_clog(1.0 - 1.0/z);
172+
u = -pos_clog(1.0 - 1.0/z);
173173
rest = -lmz*(lmz*lmz/6.0 + zeta2);
174174
}
175175

@@ -275,7 +275,7 @@ long double _Complex cli3l(long double _Complex z)
275275
const long double _Complex u = lnz + pz*I; // clog(z)
276276
const long double _Complex u2 = u*u;
277277
const long double _Complex c0 = zeta3 + u*(zeta2 - u2/12.0L);
278-
const long double _Complex c1 = 0.25L * (3.0L - 2.0L*fast_pos_clogl(-u));
278+
const long double _Complex c1 = 0.25L * (3.0L - 2.0L*pos_clogl(-u));
279279

280280
const long double cs[] = {
281281
-3.47222222222222222222222222222222222e-03L,
@@ -317,11 +317,11 @@ long double _Complex cli3l(long double _Complex z)
317317
long double _Complex u = 0.0L, rest = 0.0L;
318318

319319
if (nz <= 1.0L) {
320-
u = -fast_pos_clogl(1.0L - z);
320+
u = -pos_clogl(1.0L - z);
321321
} else { // nz > 1
322322
const long double arg = pz > 0.0L ? pz - PI : pz + PI;
323323
const long double _Complex lmz = lnz + arg*I; // clog(-z)
324-
u = -fast_pos_clogl(1.0L - 1.0L/z);
324+
u = -pos_clogl(1.0L - 1.0L/z);
325325
rest = -lmz*(lmz*lmz/6.0L + zeta2);
326326
}
327327

src/c/Li4.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#include <complex.h>
88
#include <float.h>
99
#include <math.h>
10-
#include "fast_clog.h"
10+
#include "log.h"
1111

1212
/// Li_4(x) for x in [-1,0]
1313
static double li4_neg(double x)
@@ -200,7 +200,7 @@ double _Complex cli4(double _Complex z)
200200
const double _Complex u8 = u4*u4;
201201
const double c1 = 1.2020569031595943; // zeta(3)
202202
const double c2 = 0.82246703342411322;
203-
const double _Complex c3 = (11.0/6.0 - fast_pos_clog(-u))/6.0;
203+
const double _Complex c3 = (11.0/6.0 - pos_clog(-u))/6.0;
204204
const double c4 = -1.0/48.0;
205205

206206
const double cs[7] = {
@@ -224,12 +224,12 @@ double _Complex cli4(double _Complex z)
224224
double sgn = 1;
225225

226226
if (nz <= 1.0) {
227-
u = -fast_pos_clog(1.0 - z);
227+
u = -pos_clog(1.0 - z);
228228
} else { // nz > 1
229229
const double arg = pz > 0.0 ? pz - PI : pz + PI;
230230
const double _Complex lmz = lnz + arg*I; // clog(-z)
231231
const double _Complex lmz2 = lmz*lmz;
232-
u = -fast_pos_clog(1.0 - 1.0/z);
232+
u = -pos_clog(1.0 - 1.0/z);
233233
r = 1.0/360.0*(-7*PI4 + lmz2*(-30.0*PI2 - 15.0*lmz2));
234234
sgn = -1;
235235
}
@@ -336,7 +336,7 @@ long double _Complex cli4l(long double _Complex z)
336336
const long double _Complex u2 = u*u;
337337
const long double c1 = 1.20205690315959428539973816151144999L; // zeta(3)
338338
const long double c2 = 0.822467033424113218236207583323012595L;
339-
const long double _Complex c3 = (11.0L/6.0L - fast_pos_clogl(-u))/6.0L;
339+
const long double _Complex c3 = (11.0L/6.0L - pos_clogl(-u))/6.0L;
340340
const long double c4 = -1.0L/48.0L;
341341

342342
const long double cs[] = {
@@ -377,12 +377,12 @@ long double _Complex cli4l(long double _Complex z)
377377
long double sgn = 1;
378378

379379
if (nz <= 1.0L) {
380-
u = -fast_pos_clogl(1.0L - z);
380+
u = -pos_clogl(1.0L - z);
381381
} else { // nz > 1
382382
const long double arg = pz > 0.0 ? pz - PI : pz + PI;
383383
const long double _Complex lmz = lnz + arg*I; // clog(-z)
384384
const long double _Complex lmz2 = lmz*lmz;
385-
u = -fast_pos_clogl(1.0L - 1.0L/z);
385+
u = -pos_clogl(1.0L - 1.0L/z);
386386
r = 1.0L/360.0L*(-7*PI4 + lmz2*(-30.0L*PI2 - 15.0L*lmz2));
387387
sgn = -1;
388388
}

src/c/Li5.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#include <complex.h>
88
#include <float.h>
99
#include <math.h>
10-
#include "fast_clog.h"
10+
#include "log.h"
1111

1212

1313
/**
@@ -61,7 +61,7 @@ double _Complex cli5(double _Complex z)
6161
const double c1 = 1.0823232337111382; // zeta(4)
6262
const double c2 = 0.60102845157979714; // zeta(3)/2
6363
const double c3 = 0.27415567780803774;
64-
const double _Complex c4 = (25.0/12.0 - fast_pos_clog(-u))/24.0;
64+
const double _Complex c4 = (25.0/12.0 - pos_clog(-u))/24.0;
6565
const double c5 = -1.0/240.0;
6666

6767
const double cs[6] = {
@@ -84,12 +84,12 @@ double _Complex cli5(double _Complex z)
8484
double _Complex u = 0.0, rest = 0.0;
8585

8686
if (nz <= 1.0) {
87-
u = -fast_pos_clog(1.0 - z);
87+
u = -pos_clog(1.0 - z);
8888
} else { // nz > 1
8989
const double arg = pz > 0.0 ? pz - PI : pz + PI;
9090
const double _Complex lmz = lnz + arg*I; // clog(-z)
9191
const double _Complex lmz2 = lmz*lmz;
92-
u = -fast_pos_clog(1.0 - 1.0/z);
92+
u = -pos_clog(1.0 - 1.0/z);
9393
rest = -1.0/360.0*lmz*(7*PI4 + lmz2*(10.0*PI2 + 3.0*lmz2));
9494
}
9595

@@ -196,7 +196,7 @@ long double _Complex cli5l(long double _Complex z)
196196
const long double c1 = 1.08232323371113819151600369654116790L; // zeta(4)
197197
const long double c2 = 0.601028451579797142699869080755724995L; // zeta(3)/2
198198
const long double c3 = 0.274155677808037739412069194441004198L;
199-
const long double _Complex c4 = (25.0L/12.0L - fast_pos_clogl(-u))/24.0L;
199+
const long double _Complex c4 = (25.0L/12.0L - pos_clogl(-u))/24.0L;
200200
const long double c5 = -1.0L/240.0L;
201201

202202
const long double cs[] = {
@@ -236,12 +236,12 @@ long double _Complex cli5l(long double _Complex z)
236236
long double _Complex u = 0.0L, rest = 0.0L;
237237

238238
if (nz <= 1.0L) {
239-
u = -fast_pos_clogl(1.0L - z);
239+
u = -pos_clogl(1.0L - z);
240240
} else { // nz > 1
241241
const long double arg = pz > 0.0 ? pz - PI : pz + PI;
242242
const long double _Complex lmz = lnz + arg*I; // clog(-z)
243243
const long double _Complex lmz2 = lmz*lmz;
244-
u = -fast_pos_clogl(1.0L - 1.0L/z);
244+
u = -pos_clogl(1.0L - 1.0L/z);
245245
rest = -1.0L/360.0L*lmz*(7*PI4 + lmz2*(10.0L*PI2 + 3.0L*lmz2));
246246
}
247247

src/c/Li6.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#include <complex.h>
88
#include <float.h>
99
#include <math.h>
10-
#include "fast_clog.h"
10+
#include "log.h"
1111

1212

1313
/**
@@ -62,7 +62,7 @@ double _Complex cli6(double _Complex z)
6262
const double c2 = 0.54116161685556910;
6363
const double c3 = 0.20034281719326571;
6464
const double c4 = 0.068538919452009435;
65-
const double _Complex c5 = (137.0/60.0 - fast_pos_clog(-u))/120.0;
65+
const double _Complex c5 = (137.0/60.0 - pos_clog(-u))/120.0;
6666
const double c6 = -1.0/1440.0;
6767

6868
const double cs[5] = {
@@ -86,12 +86,12 @@ double _Complex cli6(double _Complex z)
8686
double sgn = 1;
8787

8888
if (nz <= 1.0) {
89-
u = -fast_pos_clog(1.0 - z);
89+
u = -pos_clog(1.0 - z);
9090
} else { // nz > 1
9191
const double arg = pz > 0.0 ? pz - PI : pz + PI;
9292
const double _Complex lmz = lnz + arg*I; // clog(-z)
9393
const double _Complex lmz2 = lmz*lmz;
94-
u = -fast_pos_clog(1.0 - 1.0/z);
94+
u = -pos_clog(1.0 - 1.0/z);
9595
r = -31.0*PI6/15120.0 + lmz2*(-7.0/720.0*PI4 + lmz2*(-1.0/144.0*PI2 - 1.0/720.0*lmz2));
9696
sgn = -1;
9797
}
@@ -202,7 +202,7 @@ long double _Complex cli6l(long double _Complex z)
202202
const long double c2 = 0.541161616855569095758001848270583951L;
203203
const long double c3 = 0.200342817193265714233289693585241665L;
204204
const long double c4 = 0.0685389194520094348530172986102510496L;
205-
const long double _Complex c5 = (137.0L/60.0L - fast_pos_clogl(-u))/120.0L;
205+
const long double _Complex c5 = (137.0L/60.0L - pos_clogl(-u))/120.0L;
206206
const long double c6 = -1.0L/1440.0L;
207207

208208
const long double cs[] = {
@@ -247,12 +247,12 @@ long double _Complex cli6l(long double _Complex z)
247247
long double sgn = 1;
248248

249249
if (nz <= 1.0L) {
250-
u = -fast_pos_clogl(1.0L - z);
250+
u = -pos_clogl(1.0L - z);
251251
} else { // nz > 1
252252
const long double arg = pz > 0.0 ? pz - PI : pz + PI;
253253
const long double _Complex lmz = lnz + arg*I; // clog(-z)
254254
const long double _Complex lmz2 = lmz*lmz;
255-
u = -fast_pos_clogl(1.0L - 1.0L/z);
255+
u = -pos_clogl(1.0L - 1.0L/z);
256256
r = -31.0L*PI6/15120.0L
257257
+ lmz2*(-7.0L/720.0L*PI4 +
258258
lmz2*(-1.0L/144.0L*PI2 - 1.0L/720.0L*lmz2));

0 commit comments

Comments
 (0)