gtsam/gtsam/3rdparty/cephes/cephes/spence.c

126 lines
2.2 KiB
C
Raw Blame History

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

/* spence.c
*
* Dilogarithm
*
*
*
* SYNOPSIS:
*
* double x, y, spence();
*
* y = spence( x );
*
*
*
* DESCRIPTION:
*
* Computes the integral
*
* x
* -
* | | log t
* spence(x) = - | ----- dt
* | | t - 1
* -
* 1
*
* for x >= 0. A rational approximation gives the integral in
* the interval (0.5, 1.5). Transformation formulas for 1/x
* and 1-x are employed outside the basic expansion range.
*
*
*
* ACCURACY:
*
* Relative error:
* arithmetic domain # trials peak rms
* IEEE 0,4 30000 3.9e-15 5.4e-16
*
*
*/
/* spence.c */
/*
* Cephes Math Library Release 2.1: January, 1989
* Copyright 1985, 1987, 1989 by Stephen L. Moshier
* Direct inquiries to 30 Frost Street, Cambridge, MA 02140
*/
#include "mconf.h"
static double A[8] = {
4.65128586073990045278E-5,
7.31589045238094711071E-3,
1.33847639578309018650E-1,
8.79691311754530315341E-1,
2.71149851196553469920E0,
4.25697156008121755724E0,
3.29771340985225106936E0,
1.00000000000000000126E0,
};
static double B[8] = {
6.90990488912553276999E-4,
2.54043763932544379113E-2,
2.82974860602568089943E-1,
1.41172597751831069617E0,
3.63800533345137075418E0,
5.03278880143316990390E0,
3.54771340985225096217E0,
9.99999999999999998740E-1,
};
extern double MACHEP;
double spence(double x)
{
double w, y, z;
int flag;
if (x < 0.0) {
sf_error("spence", SF_ERROR_DOMAIN, NULL);
return (NAN);
}
if (x == 1.0)
return (0.0);
if (x == 0.0)
return (M_PI * M_PI / 6.0);
flag = 0;
if (x > 2.0) {
x = 1.0 / x;
flag |= 2;
}
if (x > 1.5) {
w = (1.0 / x) - 1.0;
flag |= 2;
}
else if (x < 0.5) {
w = -x;
flag |= 1;
}
else
w = x - 1.0;
y = -w * polevl(w, A, 7) / polevl(w, B, 7);
if (flag & 1)
y = (M_PI * M_PI) / 6.0 - log(x) * log(1.0 - x) - y;
if (flag & 2) {
z = log(x);
y = -0.5 * z * z - y;
}
return (y);
}