test_levin.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. from mpmath import mp
  4. from mpmath import libmp
  5. xrange = libmp.backend.xrange
  6. # Attention:
  7. # These tests run with 15-20 decimal digits precision. For higher precision the
  8. # working precision must be raised.
  9. def test_levin_0():
  10. mp.dps = 17
  11. eps = mp.mpf(mp.eps)
  12. with mp.extraprec(2 * mp.prec):
  13. L = mp.levin(method = "levin", variant = "u")
  14. S, s, n = [], 0, 1
  15. while 1:
  16. s += mp.one / (n * n)
  17. n += 1
  18. S.append(s)
  19. v, e = L.update_psum(S)
  20. if e < eps:
  21. break
  22. if n > 1000: raise RuntimeError("iteration limit exceeded")
  23. eps = mp.exp(0.9 * mp.log(eps))
  24. err = abs(v - mp.pi ** 2 / 6)
  25. assert err < eps
  26. w = mp.nsum(lambda n: 1/(n * n), [1, mp.inf], method = "levin", levin_variant = "u")
  27. err = abs(v - w)
  28. assert err < eps
  29. def test_levin_1():
  30. mp.dps = 17
  31. eps = mp.mpf(mp.eps)
  32. with mp.extraprec(2 * mp.prec):
  33. L = mp.levin(method = "levin", variant = "v")
  34. A, n = [], 1
  35. while 1:
  36. s = mp.mpf(n) ** (2 + 3j)
  37. n += 1
  38. A.append(s)
  39. v, e = L.update(A)
  40. if e < eps:
  41. break
  42. if n > 1000: raise RuntimeError("iteration limit exceeded")
  43. eps = mp.exp(0.9 * mp.log(eps))
  44. err = abs(v - mp.zeta(-2-3j))
  45. assert err < eps
  46. w = mp.nsum(lambda n: n ** (2 + 3j), [1, mp.inf], method = "levin", levin_variant = "v")
  47. err = abs(v - w)
  48. assert err < eps
  49. def test_levin_2():
  50. # [2] A. Sidi - "Pratical Extrapolation Methods" p.373
  51. mp.dps = 17
  52. z=mp.mpf(10)
  53. eps = mp.mpf(mp.eps)
  54. with mp.extraprec(2 * mp.prec):
  55. L = mp.levin(method = "sidi", variant = "t")
  56. n = 0
  57. while 1:
  58. s = (-1)**n * mp.fac(n) * z ** (-n)
  59. v, e = L.step(s)
  60. n += 1
  61. if e < eps:
  62. break
  63. if n > 1000: raise RuntimeError("iteration limit exceeded")
  64. eps = mp.exp(0.9 * mp.log(eps))
  65. exact = mp.quad(lambda x: mp.exp(-x)/(1+x/z),[0,mp.inf])
  66. # there is also a symbolic expression for the integral:
  67. # exact = z * mp.exp(z) * mp.expint(1,z)
  68. err = abs(v - exact)
  69. assert err < eps
  70. w = mp.nsum(lambda n: (-1) ** n * mp.fac(n) * z ** (-n), [0, mp.inf], method = "sidi", levin_variant = "t")
  71. assert err < eps
  72. def test_levin_3():
  73. mp.dps = 17
  74. z=mp.mpf(2)
  75. eps = mp.mpf(mp.eps)
  76. with mp.extraprec(7*mp.prec): # we need copious amount of precision to sum this highly divergent series
  77. L = mp.levin(method = "levin", variant = "t")
  78. n, s = 0, 0
  79. while 1:
  80. s += (-z)**n * mp.fac(4 * n) / (mp.fac(n) * mp.fac(2 * n) * (4 ** n))
  81. n += 1
  82. v, e = L.step_psum(s)
  83. if e < eps:
  84. break
  85. if n > 1000: raise RuntimeError("iteration limit exceeded")
  86. eps = mp.exp(0.8 * mp.log(eps))
  87. exact = mp.quad(lambda x: mp.exp( -x * x / 2 - z * x ** 4), [0,mp.inf]) * 2 / mp.sqrt(2 * mp.pi)
  88. # there is also a symbolic expression for the integral:
  89. # exact = mp.exp(mp.one / (32 * z)) * mp.besselk(mp.one / 4, mp.one / (32 * z)) / (4 * mp.sqrt(z * mp.pi))
  90. err = abs(v - exact)
  91. assert err < eps
  92. w = mp.nsum(lambda n: (-z)**n * mp.fac(4 * n) / (mp.fac(n) * mp.fac(2 * n) * (4 ** n)), [0, mp.inf], method = "levin", levin_variant = "t", workprec = 8*mp.prec, steps = [2] + [1 for x in xrange(1000)])
  93. err = abs(v - w)
  94. assert err < eps
  95. def test_levin_nsum():
  96. mp.dps = 17
  97. with mp.extraprec(mp.prec):
  98. z = mp.mpf(10) ** (-10)
  99. a = mp.nsum(lambda n: n**(-(1+z)), [1, mp.inf], method = "l") - 1 / z
  100. assert abs(a - mp.euler) < 1e-10
  101. eps = mp.exp(0.8 * mp.log(mp.eps))
  102. a = mp.nsum(lambda n: (-1)**(n-1) / n, [1, mp.inf], method = "sidi")
  103. assert abs(a - mp.log(2)) < eps
  104. z = 2 + 1j
  105. f = lambda n: mp.rf(2 / mp.mpf(3), n) * mp.rf(4 / mp.mpf(3), n) * z**n / (mp.rf(1 / mp.mpf(3), n) * mp.fac(n))
  106. v = mp.nsum(f, [0, mp.inf], method = "levin", steps = [10 for x in xrange(1000)])
  107. exact = mp.hyp2f1(2 / mp.mpf(3), 4 / mp.mpf(3), 1 / mp.mpf(3), z)
  108. assert abs(exact - v) < eps
  109. def test_cohen_alt_0():
  110. mp.dps = 17
  111. AC = mp.cohen_alt()
  112. S, s, n = [], 0, 1
  113. while 1:
  114. s += -((-1) ** n) * mp.one / (n * n)
  115. n += 1
  116. S.append(s)
  117. v, e = AC.update_psum(S)
  118. if e < mp.eps:
  119. break
  120. if n > 1000: raise RuntimeError("iteration limit exceeded")
  121. eps = mp.exp(0.9 * mp.log(mp.eps))
  122. err = abs(v - mp.pi ** 2 / 12)
  123. assert err < eps
  124. def test_cohen_alt_1():
  125. mp.dps = 17
  126. A = []
  127. AC = mp.cohen_alt()
  128. n = 1
  129. while 1:
  130. A.append( mp.loggamma(1 + mp.one / (2 * n - 1)))
  131. A.append(-mp.loggamma(1 + mp.one / (2 * n)))
  132. n += 1
  133. v, e = AC.update(A)
  134. if e < mp.eps:
  135. break
  136. if n > 1000: raise RuntimeError("iteration limit exceeded")
  137. v = mp.exp(v)
  138. err = abs(v - 1.06215090557106)
  139. assert err < 1e-12