math2.py 18 KB

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