Upload math2.py with huggingface_hub
Browse files
math2.py
ADDED
|
@@ -0,0 +1,672 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
This module complements the math and cmath builtin modules by providing
|
| 3 |
+
fast machine precision versions of some additional functions (gamma, ...)
|
| 4 |
+
and wrapping math/cmath functions so that they can be called with either
|
| 5 |
+
real or complex arguments.
|
| 6 |
+
"""
|
| 7 |
+
|
| 8 |
+
import operator
|
| 9 |
+
import math
|
| 10 |
+
import cmath
|
| 11 |
+
|
| 12 |
+
# Irrational (?) constants
|
| 13 |
+
pi = 3.1415926535897932385
|
| 14 |
+
e = 2.7182818284590452354
|
| 15 |
+
sqrt2 = 1.4142135623730950488
|
| 16 |
+
sqrt5 = 2.2360679774997896964
|
| 17 |
+
phi = 1.6180339887498948482
|
| 18 |
+
ln2 = 0.69314718055994530942
|
| 19 |
+
ln10 = 2.302585092994045684
|
| 20 |
+
euler = 0.57721566490153286061
|
| 21 |
+
catalan = 0.91596559417721901505
|
| 22 |
+
khinchin = 2.6854520010653064453
|
| 23 |
+
apery = 1.2020569031595942854
|
| 24 |
+
|
| 25 |
+
logpi = 1.1447298858494001741
|
| 26 |
+
|
| 27 |
+
def _mathfun_real(f_real, f_complex):
|
| 28 |
+
def f(x, **kwargs):
|
| 29 |
+
if type(x) is float:
|
| 30 |
+
return f_real(x)
|
| 31 |
+
if type(x) is complex:
|
| 32 |
+
return f_complex(x)
|
| 33 |
+
try:
|
| 34 |
+
x = float(x)
|
| 35 |
+
return f_real(x)
|
| 36 |
+
except (TypeError, ValueError):
|
| 37 |
+
x = complex(x)
|
| 38 |
+
return f_complex(x)
|
| 39 |
+
f.__name__ = f_real.__name__
|
| 40 |
+
return f
|
| 41 |
+
|
| 42 |
+
def _mathfun(f_real, f_complex):
|
| 43 |
+
def f(x, **kwargs):
|
| 44 |
+
if type(x) is complex:
|
| 45 |
+
return f_complex(x)
|
| 46 |
+
try:
|
| 47 |
+
return f_real(float(x))
|
| 48 |
+
except (TypeError, ValueError):
|
| 49 |
+
return f_complex(complex(x))
|
| 50 |
+
f.__name__ = f_real.__name__
|
| 51 |
+
return f
|
| 52 |
+
|
| 53 |
+
def _mathfun_n(f_real, f_complex):
|
| 54 |
+
def f(*args, **kwargs):
|
| 55 |
+
try:
|
| 56 |
+
return f_real(*(float(x) for x in args))
|
| 57 |
+
except (TypeError, ValueError):
|
| 58 |
+
return f_complex(*(complex(x) for x in args))
|
| 59 |
+
f.__name__ = f_real.__name__
|
| 60 |
+
return f
|
| 61 |
+
|
| 62 |
+
# Workaround for non-raising log and sqrt in Python 2.5 and 2.4
|
| 63 |
+
# on Unix system
|
| 64 |
+
try:
|
| 65 |
+
math.log(-2.0)
|
| 66 |
+
def math_log(x):
|
| 67 |
+
if x <= 0.0:
|
| 68 |
+
raise ValueError("math domain error")
|
| 69 |
+
return math.log(x)
|
| 70 |
+
def math_sqrt(x):
|
| 71 |
+
if x < 0.0:
|
| 72 |
+
raise ValueError("math domain error")
|
| 73 |
+
return math.sqrt(x)
|
| 74 |
+
except (ValueError, TypeError):
|
| 75 |
+
math_log = math.log
|
| 76 |
+
math_sqrt = math.sqrt
|
| 77 |
+
|
| 78 |
+
pow = _mathfun_n(operator.pow, lambda x, y: complex(x)**y)
|
| 79 |
+
log = _mathfun_n(math_log, cmath.log)
|
| 80 |
+
sqrt = _mathfun(math_sqrt, cmath.sqrt)
|
| 81 |
+
exp = _mathfun_real(math.exp, cmath.exp)
|
| 82 |
+
|
| 83 |
+
cos = _mathfun_real(math.cos, cmath.cos)
|
| 84 |
+
sin = _mathfun_real(math.sin, cmath.sin)
|
| 85 |
+
tan = _mathfun_real(math.tan, cmath.tan)
|
| 86 |
+
|
| 87 |
+
acos = _mathfun(math.acos, cmath.acos)
|
| 88 |
+
asin = _mathfun(math.asin, cmath.asin)
|
| 89 |
+
atan = _mathfun_real(math.atan, cmath.atan)
|
| 90 |
+
|
| 91 |
+
cosh = _mathfun_real(math.cosh, cmath.cosh)
|
| 92 |
+
sinh = _mathfun_real(math.sinh, cmath.sinh)
|
| 93 |
+
tanh = _mathfun_real(math.tanh, cmath.tanh)
|
| 94 |
+
|
| 95 |
+
floor = _mathfun_real(math.floor,
|
| 96 |
+
lambda z: complex(math.floor(z.real), math.floor(z.imag)))
|
| 97 |
+
ceil = _mathfun_real(math.ceil,
|
| 98 |
+
lambda z: complex(math.ceil(z.real), math.ceil(z.imag)))
|
| 99 |
+
|
| 100 |
+
|
| 101 |
+
cos_sin = _mathfun_real(lambda x: (math.cos(x), math.sin(x)),
|
| 102 |
+
lambda z: (cmath.cos(z), cmath.sin(z)))
|
| 103 |
+
|
| 104 |
+
cbrt = _mathfun(lambda x: x**(1./3), lambda z: z**(1./3))
|
| 105 |
+
|
| 106 |
+
def nthroot(x, n):
|
| 107 |
+
r = 1./n
|
| 108 |
+
try:
|
| 109 |
+
return float(x) ** r
|
| 110 |
+
except (ValueError, TypeError):
|
| 111 |
+
return complex(x) ** r
|
| 112 |
+
|
| 113 |
+
def _sinpi_real(x):
|
| 114 |
+
if x < 0:
|
| 115 |
+
return -_sinpi_real(-x)
|
| 116 |
+
n, r = divmod(x, 0.5)
|
| 117 |
+
r *= pi
|
| 118 |
+
n %= 4
|
| 119 |
+
if n == 0: return math.sin(r)
|
| 120 |
+
if n == 1: return math.cos(r)
|
| 121 |
+
if n == 2: return -math.sin(r)
|
| 122 |
+
if n == 3: return -math.cos(r)
|
| 123 |
+
|
| 124 |
+
def _cospi_real(x):
|
| 125 |
+
if x < 0:
|
| 126 |
+
x = -x
|
| 127 |
+
n, r = divmod(x, 0.5)
|
| 128 |
+
r *= pi
|
| 129 |
+
n %= 4
|
| 130 |
+
if n == 0: return math.cos(r)
|
| 131 |
+
if n == 1: return -math.sin(r)
|
| 132 |
+
if n == 2: return -math.cos(r)
|
| 133 |
+
if n == 3: return math.sin(r)
|
| 134 |
+
|
| 135 |
+
def _sinpi_complex(z):
|
| 136 |
+
if z.real < 0:
|
| 137 |
+
return -_sinpi_complex(-z)
|
| 138 |
+
n, r = divmod(z.real, 0.5)
|
| 139 |
+
z = pi*complex(r, z.imag)
|
| 140 |
+
n %= 4
|
| 141 |
+
if n == 0: return cmath.sin(z)
|
| 142 |
+
if n == 1: return cmath.cos(z)
|
| 143 |
+
if n == 2: return -cmath.sin(z)
|
| 144 |
+
if n == 3: return -cmath.cos(z)
|
| 145 |
+
|
| 146 |
+
def _cospi_complex(z):
|
| 147 |
+
if z.real < 0:
|
| 148 |
+
z = -z
|
| 149 |
+
n, r = divmod(z.real, 0.5)
|
| 150 |
+
z = pi*complex(r, z.imag)
|
| 151 |
+
n %= 4
|
| 152 |
+
if n == 0: return cmath.cos(z)
|
| 153 |
+
if n == 1: return -cmath.sin(z)
|
| 154 |
+
if n == 2: return -cmath.cos(z)
|
| 155 |
+
if n == 3: return cmath.sin(z)
|
| 156 |
+
|
| 157 |
+
cospi = _mathfun_real(_cospi_real, _cospi_complex)
|
| 158 |
+
sinpi = _mathfun_real(_sinpi_real, _sinpi_complex)
|
| 159 |
+
|
| 160 |
+
def tanpi(x):
|
| 161 |
+
try:
|
| 162 |
+
return sinpi(x) / cospi(x)
|
| 163 |
+
except OverflowError:
|
| 164 |
+
if complex(x).imag > 10:
|
| 165 |
+
return 1j
|
| 166 |
+
if complex(x).imag < 10:
|
| 167 |
+
return -1j
|
| 168 |
+
raise
|
| 169 |
+
|
| 170 |
+
def cotpi(x):
|
| 171 |
+
try:
|
| 172 |
+
return cospi(x) / sinpi(x)
|
| 173 |
+
except OverflowError:
|
| 174 |
+
if complex(x).imag > 10:
|
| 175 |
+
return -1j
|
| 176 |
+
if complex(x).imag < 10:
|
| 177 |
+
return 1j
|
| 178 |
+
raise
|
| 179 |
+
|
| 180 |
+
INF = 1e300*1e300
|
| 181 |
+
NINF = -INF
|
| 182 |
+
NAN = INF-INF
|
| 183 |
+
EPS = 2.2204460492503131e-16
|
| 184 |
+
|
| 185 |
+
_exact_gamma = (INF, 1.0, 1.0, 2.0, 6.0, 24.0, 120.0, 720.0, 5040.0, 40320.0,
|
| 186 |
+
362880.0, 3628800.0, 39916800.0, 479001600.0, 6227020800.0, 87178291200.0,
|
| 187 |
+
1307674368000.0, 20922789888000.0, 355687428096000.0, 6402373705728000.0,
|
| 188 |
+
121645100408832000.0, 2432902008176640000.0)
|
| 189 |
+
|
| 190 |
+
_max_exact_gamma = len(_exact_gamma)-1
|
| 191 |
+
|
| 192 |
+
# Lanczos coefficients used by the GNU Scientific Library
|
| 193 |
+
_lanczos_g = 7
|
| 194 |
+
_lanczos_p = (0.99999999999980993, 676.5203681218851, -1259.1392167224028,
|
| 195 |
+
771.32342877765313, -176.61502916214059, 12.507343278686905,
|
| 196 |
+
-0.13857109526572012, 9.9843695780195716e-6, 1.5056327351493116e-7)
|
| 197 |
+
|
| 198 |
+
def _gamma_real(x):
|
| 199 |
+
_intx = int(x)
|
| 200 |
+
if _intx == x:
|
| 201 |
+
if _intx <= 0:
|
| 202 |
+
#return (-1)**_intx * INF
|
| 203 |
+
raise ZeroDivisionError("gamma function pole")
|
| 204 |
+
if _intx <= _max_exact_gamma:
|
| 205 |
+
return _exact_gamma[_intx]
|
| 206 |
+
if x < 0.5:
|
| 207 |
+
# TODO: sinpi
|
| 208 |
+
return pi / (_sinpi_real(x)*_gamma_real(1-x))
|
| 209 |
+
else:
|
| 210 |
+
x -= 1.0
|
| 211 |
+
r = _lanczos_p[0]
|
| 212 |
+
for i in range(1, _lanczos_g+2):
|
| 213 |
+
r += _lanczos_p[i]/(x+i)
|
| 214 |
+
t = x + _lanczos_g + 0.5
|
| 215 |
+
return 2.506628274631000502417 * t**(x+0.5) * math.exp(-t) * r
|
| 216 |
+
|
| 217 |
+
def _gamma_complex(x):
|
| 218 |
+
if not x.imag:
|
| 219 |
+
return complex(_gamma_real(x.real))
|
| 220 |
+
if x.real < 0.5:
|
| 221 |
+
# TODO: sinpi
|
| 222 |
+
return pi / (_sinpi_complex(x)*_gamma_complex(1-x))
|
| 223 |
+
else:
|
| 224 |
+
x -= 1.0
|
| 225 |
+
r = _lanczos_p[0]
|
| 226 |
+
for i in range(1, _lanczos_g+2):
|
| 227 |
+
r += _lanczos_p[i]/(x+i)
|
| 228 |
+
t = x + _lanczos_g + 0.5
|
| 229 |
+
return 2.506628274631000502417 * t**(x+0.5) * cmath.exp(-t) * r
|
| 230 |
+
|
| 231 |
+
gamma = _mathfun_real(_gamma_real, _gamma_complex)
|
| 232 |
+
|
| 233 |
+
def rgamma(x):
|
| 234 |
+
try:
|
| 235 |
+
return 1./gamma(x)
|
| 236 |
+
except ZeroDivisionError:
|
| 237 |
+
return x*0.0
|
| 238 |
+
|
| 239 |
+
def factorial(x):
|
| 240 |
+
return gamma(x+1.0)
|
| 241 |
+
|
| 242 |
+
def arg(x):
|
| 243 |
+
if type(x) is float:
|
| 244 |
+
return math.atan2(0.0,x)
|
| 245 |
+
return math.atan2(x.imag,x.real)
|
| 246 |
+
|
| 247 |
+
# XXX: broken for negatives
|
| 248 |
+
def loggamma(x):
|
| 249 |
+
if type(x) not in (float, complex):
|
| 250 |
+
try:
|
| 251 |
+
x = float(x)
|
| 252 |
+
except (ValueError, TypeError):
|
| 253 |
+
x = complex(x)
|
| 254 |
+
try:
|
| 255 |
+
xreal = x.real
|
| 256 |
+
ximag = x.imag
|
| 257 |
+
except AttributeError: # py2.5
|
| 258 |
+
xreal = x
|
| 259 |
+
ximag = 0.0
|
| 260 |
+
# Reflection formula
|
| 261 |
+
# http://functions.wolfram.com/GammaBetaErf/LogGamma/16/01/01/0003/
|
| 262 |
+
if xreal < 0.0:
|
| 263 |
+
if abs(x) < 0.5:
|
| 264 |
+
v = log(gamma(x))
|
| 265 |
+
if ximag == 0:
|
| 266 |
+
v = v.conjugate()
|
| 267 |
+
return v
|
| 268 |
+
z = 1-x
|
| 269 |
+
try:
|
| 270 |
+
re = z.real
|
| 271 |
+
im = z.imag
|
| 272 |
+
except AttributeError: # py2.5
|
| 273 |
+
re = z
|
| 274 |
+
im = 0.0
|
| 275 |
+
refloor = floor(re)
|
| 276 |
+
if im == 0.0:
|
| 277 |
+
imsign = 0
|
| 278 |
+
elif im < 0.0:
|
| 279 |
+
imsign = -1
|
| 280 |
+
else:
|
| 281 |
+
imsign = 1
|
| 282 |
+
return (-pi*1j)*abs(refloor)*(1-abs(imsign)) + logpi - \
|
| 283 |
+
log(sinpi(z-refloor)) - loggamma(z) + 1j*pi*refloor*imsign
|
| 284 |
+
if x == 1.0 or x == 2.0:
|
| 285 |
+
return x*0
|
| 286 |
+
p = 0.
|
| 287 |
+
while abs(x) < 11:
|
| 288 |
+
p -= log(x)
|
| 289 |
+
x += 1.0
|
| 290 |
+
s = 0.918938533204672742 + (x-0.5)*log(x) - x
|
| 291 |
+
r = 1./x
|
| 292 |
+
r2 = r*r
|
| 293 |
+
s += 0.083333333333333333333*r; r *= r2
|
| 294 |
+
s += -0.0027777777777777777778*r; r *= r2
|
| 295 |
+
s += 0.00079365079365079365079*r; r *= r2
|
| 296 |
+
s += -0.0005952380952380952381*r; r *= r2
|
| 297 |
+
s += 0.00084175084175084175084*r; r *= r2
|
| 298 |
+
s += -0.0019175269175269175269*r; r *= r2
|
| 299 |
+
s += 0.0064102564102564102564*r; r *= r2
|
| 300 |
+
s += -0.02955065359477124183*r
|
| 301 |
+
return s + p
|
| 302 |
+
|
| 303 |
+
_psi_coeff = [
|
| 304 |
+
0.083333333333333333333,
|
| 305 |
+
-0.0083333333333333333333,
|
| 306 |
+
0.003968253968253968254,
|
| 307 |
+
-0.0041666666666666666667,
|
| 308 |
+
0.0075757575757575757576,
|
| 309 |
+
-0.021092796092796092796,
|
| 310 |
+
0.083333333333333333333,
|
| 311 |
+
-0.44325980392156862745,
|
| 312 |
+
3.0539543302701197438,
|
| 313 |
+
-26.456212121212121212]
|
| 314 |
+
|
| 315 |
+
def _digamma_real(x):
|
| 316 |
+
_intx = int(x)
|
| 317 |
+
if _intx == x:
|
| 318 |
+
if _intx <= 0:
|
| 319 |
+
raise ZeroDivisionError("polygamma pole")
|
| 320 |
+
if x < 0.5:
|
| 321 |
+
x = 1.0-x
|
| 322 |
+
s = pi*cotpi(x)
|
| 323 |
+
else:
|
| 324 |
+
s = 0.0
|
| 325 |
+
while x < 10.0:
|
| 326 |
+
s -= 1.0/x
|
| 327 |
+
x += 1.0
|
| 328 |
+
x2 = x**-2
|
| 329 |
+
t = x2
|
| 330 |
+
for c in _psi_coeff:
|
| 331 |
+
s -= c*t
|
| 332 |
+
if t < 1e-20:
|
| 333 |
+
break
|
| 334 |
+
t *= x2
|
| 335 |
+
return s + math_log(x) - 0.5/x
|
| 336 |
+
|
| 337 |
+
def _digamma_complex(x):
|
| 338 |
+
if not x.imag:
|
| 339 |
+
return complex(_digamma_real(x.real))
|
| 340 |
+
if x.real < 0.5:
|
| 341 |
+
x = 1.0-x
|
| 342 |
+
s = pi*cotpi(x)
|
| 343 |
+
else:
|
| 344 |
+
s = 0.0
|
| 345 |
+
while abs(x) < 10.0:
|
| 346 |
+
s -= 1.0/x
|
| 347 |
+
x += 1.0
|
| 348 |
+
x2 = x**-2
|
| 349 |
+
t = x2
|
| 350 |
+
for c in _psi_coeff:
|
| 351 |
+
s -= c*t
|
| 352 |
+
if abs(t) < 1e-20:
|
| 353 |
+
break
|
| 354 |
+
t *= x2
|
| 355 |
+
return s + cmath.log(x) - 0.5/x
|
| 356 |
+
|
| 357 |
+
digamma = _mathfun_real(_digamma_real, _digamma_complex)
|
| 358 |
+
|
| 359 |
+
# TODO: could implement complex erf and erfc here. Need
|
| 360 |
+
# to find an accurate method (avoiding cancellation)
|
| 361 |
+
# for approx. 1 < abs(x) < 9.
|
| 362 |
+
|
| 363 |
+
_erfc_coeff_P = [
|
| 364 |
+
1.0000000161203922312,
|
| 365 |
+
2.1275306946297962644,
|
| 366 |
+
2.2280433377390253297,
|
| 367 |
+
1.4695509105618423961,
|
| 368 |
+
0.66275911699770787537,
|
| 369 |
+
0.20924776504163751585,
|
| 370 |
+
0.045459713768411264339,
|
| 371 |
+
0.0063065951710717791934,
|
| 372 |
+
0.00044560259661560421715][::-1]
|
| 373 |
+
|
| 374 |
+
_erfc_coeff_Q = [
|
| 375 |
+
1.0000000000000000000,
|
| 376 |
+
3.2559100272784894318,
|
| 377 |
+
4.9019435608903239131,
|
| 378 |
+
4.4971472894498014205,
|
| 379 |
+
2.7845640601891186528,
|
| 380 |
+
1.2146026030046904138,
|
| 381 |
+
0.37647108453729465912,
|
| 382 |
+
0.080970149639040548613,
|
| 383 |
+
0.011178148899483545902,
|
| 384 |
+
0.00078981003831980423513][::-1]
|
| 385 |
+
|
| 386 |
+
def _polyval(coeffs, x):
|
| 387 |
+
p = coeffs[0]
|
| 388 |
+
for c in coeffs[1:]:
|
| 389 |
+
p = c + x*p
|
| 390 |
+
return p
|
| 391 |
+
|
| 392 |
+
def _erf_taylor(x):
|
| 393 |
+
# Taylor series assuming 0 <= x <= 1
|
| 394 |
+
x2 = x*x
|
| 395 |
+
s = t = x
|
| 396 |
+
n = 1
|
| 397 |
+
while abs(t) > 1e-17:
|
| 398 |
+
t *= x2/n
|
| 399 |
+
s -= t/(n+n+1)
|
| 400 |
+
n += 1
|
| 401 |
+
t *= x2/n
|
| 402 |
+
s += t/(n+n+1)
|
| 403 |
+
n += 1
|
| 404 |
+
return 1.1283791670955125739*s
|
| 405 |
+
|
| 406 |
+
def _erfc_mid(x):
|
| 407 |
+
# Rational approximation assuming 0 <= x <= 9
|
| 408 |
+
return exp(-x*x)*_polyval(_erfc_coeff_P,x)/_polyval(_erfc_coeff_Q,x)
|
| 409 |
+
|
| 410 |
+
def _erfc_asymp(x):
|
| 411 |
+
# Asymptotic expansion assuming x >= 9
|
| 412 |
+
x2 = x*x
|
| 413 |
+
v = exp(-x2)/x*0.56418958354775628695
|
| 414 |
+
r = t = 0.5 / x2
|
| 415 |
+
s = 1.0
|
| 416 |
+
for n in range(1,22,4):
|
| 417 |
+
s -= t
|
| 418 |
+
t *= r * (n+2)
|
| 419 |
+
s += t
|
| 420 |
+
t *= r * (n+4)
|
| 421 |
+
if abs(t) < 1e-17:
|
| 422 |
+
break
|
| 423 |
+
return s * v
|
| 424 |
+
|
| 425 |
+
def erf(x):
|
| 426 |
+
"""
|
| 427 |
+
erf of a real number.
|
| 428 |
+
"""
|
| 429 |
+
x = float(x)
|
| 430 |
+
if x != x:
|
| 431 |
+
return x
|
| 432 |
+
if x < 0.0:
|
| 433 |
+
return -erf(-x)
|
| 434 |
+
if x >= 1.0:
|
| 435 |
+
if x >= 6.0:
|
| 436 |
+
return 1.0
|
| 437 |
+
return 1.0 - _erfc_mid(x)
|
| 438 |
+
return _erf_taylor(x)
|
| 439 |
+
|
| 440 |
+
def erfc(x):
|
| 441 |
+
"""
|
| 442 |
+
erfc of a real number.
|
| 443 |
+
"""
|
| 444 |
+
x = float(x)
|
| 445 |
+
if x != x:
|
| 446 |
+
return x
|
| 447 |
+
if x < 0.0:
|
| 448 |
+
if x < -6.0:
|
| 449 |
+
return 2.0
|
| 450 |
+
return 2.0-erfc(-x)
|
| 451 |
+
if x > 9.0:
|
| 452 |
+
return _erfc_asymp(x)
|
| 453 |
+
if x >= 1.0:
|
| 454 |
+
return _erfc_mid(x)
|
| 455 |
+
return 1.0 - _erf_taylor(x)
|
| 456 |
+
|
| 457 |
+
gauss42 = [\
|
| 458 |
+
(0.99839961899006235, 0.0041059986046490839),
|
| 459 |
+
(-0.99839961899006235, 0.0041059986046490839),
|
| 460 |
+
(0.9915772883408609, 0.009536220301748501),
|
| 461 |
+
(-0.9915772883408609,0.009536220301748501),
|
| 462 |
+
(0.97934250806374812, 0.014922443697357493),
|
| 463 |
+
(-0.97934250806374812, 0.014922443697357493),
|
| 464 |
+
(0.96175936533820439,0.020227869569052644),
|
| 465 |
+
(-0.96175936533820439, 0.020227869569052644),
|
| 466 |
+
(0.93892355735498811, 0.025422959526113047),
|
| 467 |
+
(-0.93892355735498811,0.025422959526113047),
|
| 468 |
+
(0.91095972490412735, 0.030479240699603467),
|
| 469 |
+
(-0.91095972490412735, 0.030479240699603467),
|
| 470 |
+
(0.87802056981217269,0.03536907109759211),
|
| 471 |
+
(-0.87802056981217269, 0.03536907109759211),
|
| 472 |
+
(0.8402859832618168, 0.040065735180692258),
|
| 473 |
+
(-0.8402859832618168,0.040065735180692258),
|
| 474 |
+
(0.7979620532554873, 0.044543577771965874),
|
| 475 |
+
(-0.7979620532554873, 0.044543577771965874),
|
| 476 |
+
(0.75127993568948048,0.048778140792803244),
|
| 477 |
+
(-0.75127993568948048, 0.048778140792803244),
|
| 478 |
+
(0.70049459055617114, 0.052746295699174064),
|
| 479 |
+
(-0.70049459055617114,0.052746295699174064),
|
| 480 |
+
(0.64588338886924779, 0.056426369358018376),
|
| 481 |
+
(-0.64588338886924779, 0.056426369358018376),
|
| 482 |
+
(0.58774459748510932, 0.059798262227586649),
|
| 483 |
+
(-0.58774459748510932, 0.059798262227586649),
|
| 484 |
+
(0.5263957499311922, 0.062843558045002565),
|
| 485 |
+
(-0.5263957499311922, 0.062843558045002565),
|
| 486 |
+
(0.46217191207042191, 0.065545624364908975),
|
| 487 |
+
(-0.46217191207042191, 0.065545624364908975),
|
| 488 |
+
(0.39542385204297503, 0.067889703376521934),
|
| 489 |
+
(-0.39542385204297503, 0.067889703376521934),
|
| 490 |
+
(0.32651612446541151, 0.069862992492594159),
|
| 491 |
+
(-0.32651612446541151, 0.069862992492594159),
|
| 492 |
+
(0.25582507934287907, 0.071454714265170971),
|
| 493 |
+
(-0.25582507934287907, 0.071454714265170971),
|
| 494 |
+
(0.18373680656485453, 0.072656175243804091),
|
| 495 |
+
(-0.18373680656485453, 0.072656175243804091),
|
| 496 |
+
(0.11064502720851986, 0.073460813453467527),
|
| 497 |
+
(-0.11064502720851986, 0.073460813453467527),
|
| 498 |
+
(0.036948943165351772, 0.073864234232172879),
|
| 499 |
+
(-0.036948943165351772, 0.073864234232172879)]
|
| 500 |
+
|
| 501 |
+
EI_ASYMP_CONVERGENCE_RADIUS = 40.0
|
| 502 |
+
|
| 503 |
+
def ei_asymp(z, _e1=False):
|
| 504 |
+
r = 1./z
|
| 505 |
+
s = t = 1.0
|
| 506 |
+
k = 1
|
| 507 |
+
while 1:
|
| 508 |
+
t *= k*r
|
| 509 |
+
s += t
|
| 510 |
+
if abs(t) < 1e-16:
|
| 511 |
+
break
|
| 512 |
+
k += 1
|
| 513 |
+
v = s*exp(z)/z
|
| 514 |
+
if _e1:
|
| 515 |
+
if type(z) is complex:
|
| 516 |
+
zreal = z.real
|
| 517 |
+
zimag = z.imag
|
| 518 |
+
else:
|
| 519 |
+
zreal = z
|
| 520 |
+
zimag = 0.0
|
| 521 |
+
if zimag == 0.0 and zreal > 0.0:
|
| 522 |
+
v += pi*1j
|
| 523 |
+
else:
|
| 524 |
+
if type(z) is complex:
|
| 525 |
+
if z.imag > 0:
|
| 526 |
+
v += pi*1j
|
| 527 |
+
if z.imag < 0:
|
| 528 |
+
v -= pi*1j
|
| 529 |
+
return v
|
| 530 |
+
|
| 531 |
+
def ei_taylor(z, _e1=False):
|
| 532 |
+
s = t = z
|
| 533 |
+
k = 2
|
| 534 |
+
while 1:
|
| 535 |
+
t = t*z/k
|
| 536 |
+
term = t/k
|
| 537 |
+
if abs(term) < 1e-17:
|
| 538 |
+
break
|
| 539 |
+
s += term
|
| 540 |
+
k += 1
|
| 541 |
+
s += euler
|
| 542 |
+
if _e1:
|
| 543 |
+
s += log(-z)
|
| 544 |
+
else:
|
| 545 |
+
if type(z) is float or z.imag == 0.0:
|
| 546 |
+
s += math_log(abs(z))
|
| 547 |
+
else:
|
| 548 |
+
s += cmath.log(z)
|
| 549 |
+
return s
|
| 550 |
+
|
| 551 |
+
def ei(z, _e1=False):
|
| 552 |
+
typez = type(z)
|
| 553 |
+
if typez not in (float, complex):
|
| 554 |
+
try:
|
| 555 |
+
z = float(z)
|
| 556 |
+
typez = float
|
| 557 |
+
except (TypeError, ValueError):
|
| 558 |
+
z = complex(z)
|
| 559 |
+
typez = complex
|
| 560 |
+
if not z:
|
| 561 |
+
return -INF
|
| 562 |
+
absz = abs(z)
|
| 563 |
+
if absz > EI_ASYMP_CONVERGENCE_RADIUS:
|
| 564 |
+
return ei_asymp(z, _e1)
|
| 565 |
+
elif absz <= 2.0 or (typez is float and z > 0.0):
|
| 566 |
+
return ei_taylor(z, _e1)
|
| 567 |
+
# Integrate, starting from whichever is smaller of a Taylor
|
| 568 |
+
# series value or an asymptotic series value
|
| 569 |
+
if typez is complex and z.real > 0.0:
|
| 570 |
+
zref = z / absz
|
| 571 |
+
ref = ei_taylor(zref, _e1)
|
| 572 |
+
else:
|
| 573 |
+
zref = EI_ASYMP_CONVERGENCE_RADIUS * z / absz
|
| 574 |
+
ref = ei_asymp(zref, _e1)
|
| 575 |
+
C = (zref-z)*0.5
|
| 576 |
+
D = (zref+z)*0.5
|
| 577 |
+
s = 0.0
|
| 578 |
+
if type(z) is complex:
|
| 579 |
+
_exp = cmath.exp
|
| 580 |
+
else:
|
| 581 |
+
_exp = math.exp
|
| 582 |
+
for x,w in gauss42:
|
| 583 |
+
t = C*x+D
|
| 584 |
+
s += w*_exp(t)/t
|
| 585 |
+
ref -= C*s
|
| 586 |
+
return ref
|
| 587 |
+
|
| 588 |
+
def e1(z):
|
| 589 |
+
# hack to get consistent signs if the imaginary part if 0
|
| 590 |
+
# and signed
|
| 591 |
+
typez = type(z)
|
| 592 |
+
if type(z) not in (float, complex):
|
| 593 |
+
try:
|
| 594 |
+
z = float(z)
|
| 595 |
+
typez = float
|
| 596 |
+
except (TypeError, ValueError):
|
| 597 |
+
z = complex(z)
|
| 598 |
+
typez = complex
|
| 599 |
+
if typez is complex and not z.imag:
|
| 600 |
+
z = complex(z.real, 0.0)
|
| 601 |
+
# end hack
|
| 602 |
+
return -ei(-z, _e1=True)
|
| 603 |
+
|
| 604 |
+
_zeta_int = [\
|
| 605 |
+
-0.5,
|
| 606 |
+
0.0,
|
| 607 |
+
1.6449340668482264365,1.2020569031595942854,1.0823232337111381915,
|
| 608 |
+
1.0369277551433699263,1.0173430619844491397,1.0083492773819228268,
|
| 609 |
+
1.0040773561979443394,1.0020083928260822144,1.0009945751278180853,
|
| 610 |
+
1.0004941886041194646,1.0002460865533080483,1.0001227133475784891,
|
| 611 |
+
1.0000612481350587048,1.0000305882363070205,1.0000152822594086519,
|
| 612 |
+
1.0000076371976378998,1.0000038172932649998,1.0000019082127165539,
|
| 613 |
+
1.0000009539620338728,1.0000004769329867878,1.0000002384505027277,
|
| 614 |
+
1.0000001192199259653,1.0000000596081890513,1.0000000298035035147,
|
| 615 |
+
1.0000000149015548284]
|
| 616 |
+
|
| 617 |
+
_zeta_P = [-3.50000000087575873, -0.701274355654678147,
|
| 618 |
+
-0.0672313458590012612, -0.00398731457954257841,
|
| 619 |
+
-0.000160948723019303141, -4.67633010038383371e-6,
|
| 620 |
+
-1.02078104417700585e-7, -1.68030037095896287e-9,
|
| 621 |
+
-1.85231868742346722e-11][::-1]
|
| 622 |
+
|
| 623 |
+
_zeta_Q = [1.00000000000000000, -0.936552848762465319,
|
| 624 |
+
-0.0588835413263763741, -0.00441498861482948666,
|
| 625 |
+
-0.000143416758067432622, -5.10691659585090782e-6,
|
| 626 |
+
-9.58813053268913799e-8, -1.72963791443181972e-9,
|
| 627 |
+
-1.83527919681474132e-11][::-1]
|
| 628 |
+
|
| 629 |
+
_zeta_1 = [3.03768838606128127e-10, -1.21924525236601262e-8,
|
| 630 |
+
2.01201845887608893e-7, -1.53917240683468381e-6,
|
| 631 |
+
-5.09890411005967954e-7, 0.000122464707271619326,
|
| 632 |
+
-0.000905721539353130232, -0.00239315326074843037,
|
| 633 |
+
0.084239750013159168, 0.418938517907442414, 0.500000001921884009]
|
| 634 |
+
|
| 635 |
+
_zeta_0 = [-3.46092485016748794e-10, -6.42610089468292485e-9,
|
| 636 |
+
1.76409071536679773e-7, -1.47141263991560698e-6, -6.38880222546167613e-7,
|
| 637 |
+
0.000122641099800668209, -0.000905894913516772796, -0.00239303348507992713,
|
| 638 |
+
0.0842396947501199816, 0.418938533204660256, 0.500000000000000052]
|
| 639 |
+
|
| 640 |
+
def zeta(s):
|
| 641 |
+
"""
|
| 642 |
+
Riemann zeta function, real argument
|
| 643 |
+
"""
|
| 644 |
+
if not isinstance(s, (float, int)):
|
| 645 |
+
try:
|
| 646 |
+
s = float(s)
|
| 647 |
+
except (ValueError, TypeError):
|
| 648 |
+
try:
|
| 649 |
+
s = complex(s)
|
| 650 |
+
if not s.imag:
|
| 651 |
+
return complex(zeta(s.real))
|
| 652 |
+
except (ValueError, TypeError):
|
| 653 |
+
pass
|
| 654 |
+
raise NotImplementedError
|
| 655 |
+
if s == 1:
|
| 656 |
+
raise ValueError("zeta(1) pole")
|
| 657 |
+
if s >= 27:
|
| 658 |
+
return 1.0 + 2.0**(-s) + 3.0**(-s)
|
| 659 |
+
n = int(s)
|
| 660 |
+
if n == s:
|
| 661 |
+
if n >= 0:
|
| 662 |
+
return _zeta_int[n]
|
| 663 |
+
if not (n % 2):
|
| 664 |
+
return 0.0
|
| 665 |
+
if s <= 0.0:
|
| 666 |
+
return 2.**s*pi**(s-1)*_sinpi_real(0.5*s)*_gamma_real(1-s)*zeta(1-s)
|
| 667 |
+
if s <= 2.0:
|
| 668 |
+
if s <= 1.0:
|
| 669 |
+
return _polyval(_zeta_0,s)/(s-1)
|
| 670 |
+
return _polyval(_zeta_1,s)/(s-1)
|
| 671 |
+
z = _polyval(_zeta_P,s) / _polyval(_zeta_Q,s)
|
| 672 |
+
return 1.0 + 2.0**(-s) + 3.0**(-s) + 4.0**(-s)*z
|