def test_levin_2(): # [2] A. Sidi - "Pratical Extrapolation Methods" p.373 mp.dps = 17 z = mp.mpf(10) eps = mp.mpf(mp.eps) with mp.extraprec(2 * mp.prec): L = mp.levin(method="sidi", variant="t") n = 0 while 1: s = (-1)**n * mp.fac(n) * z**(-n) v, e = L.step(s) n += 1 if e < eps: break if n > 1000: raise RuntimeError("iteration limit exceeded") eps = mp.exp(0.9 * mp.log(eps)) exact = mp.quad(lambda x: mp.exp(-x) / (1 + x / z), [0, mp.inf]) # there is also a symbolic expression for the integral: # exact = z * mp.exp(z) * mp.expint(1,z) err = abs(v - exact) assert err < eps w = mp.nsum(lambda n: (-1)**n * mp.fac(n) * z**(-n), [0, mp.inf], method="sidi", levin_variant="t") assert err < eps
def _gwr_no_memo(fn: Callable[[float], Any], time: float, M: int = 32, precin: int = 0) -> float: """ GWR alorithm without memoization. This is a near 1:1 translation from Mathematica. """ tau = mp.log(2.0) / mp.mpf(time) fni: List[float] = [0.0] * M for i, n in enumerate(fni): if i == 0: continue fni[i] = fn(n * tau) G0: List[float] = [0.0] * M Gp: List[float] = [0.0] * M M1 = M for n in range(1, M + 1): try: n_fac = mp.fac(n - 1) G0[n - 1] = tau * mp.fac(2 * n) / (n * n_fac * n_fac) s = 0.0 for i in range(n + 1): s += mp.binomial(n, i) * (-1) ** i * fni[n + i] G0[n - 1] *= s except: M1 = n - 1 break best = G0[M1 - 1] Gm: List[float] = [0.0] * M1 broken = False for k in range(M1 - 1): for n in range(M1 - 1 - k)[::-1]: try: expr = G0[n + 1] - G0[n] except: expr = 0.0 broken = True break expr = Gm[n + 1] + (k + 1) / expr Gp[n] = expr if k % 2 == 1 and n == M1 - 2 - k: best = expr if broken: break for n in range(M1 - k): Gm[n] = G0[n] G0[n] = Gp[n] return best
def test_levin_3(): mp.dps = 17 z = mp.mpf(2) eps = mp.mpf(mp.eps) with mp.extraprec( 7 * mp.prec ): # we need copious amount of precision to sum this highly divergent series L = mp.levin(method="levin", variant="t") n, s = 0, 0 while 1: s += (-z)**n * mp.fac(4 * n) / (mp.fac(n) * mp.fac(2 * n) * (4**n)) n += 1 v, e = L.step_psum(s) if e < eps: break if n > 1000: raise RuntimeError("iteration limit exceeded") eps = mp.exp(0.8 * mp.log(eps)) exact = mp.quad(lambda x: mp.exp(-x * x / 2 - z * x**4), [0, mp.inf]) * 2 / mp.sqrt(2 * mp.pi) # there is also a symbolic expression for the integral: # exact = mp.exp(mp.one / (32 * z)) * mp.besselk(mp.one / 4, mp.one / (32 * z)) / (4 * mp.sqrt(z * mp.pi)) err = abs(v - exact) assert err < eps 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)]) err = abs(v - w) assert err < eps
def test_levin_2(): # [2] A. Sidi - "Pratical Extrapolation Methods" p.373 mp.dps = 17 z=mp.mpf(10) eps = mp.mpf(mp.eps) with mp.extraprec(2 * mp.prec): L = mp.levin(method = "sidi", variant = "t") n = 0 while 1: s = (-1)**n * mp.fac(n) * z ** (-n) v, e = L.step(s) n += 1 if e < eps: break if n > 1000: raise RuntimeError("iteration limit exceeded") eps = mp.exp(0.9 * mp.log(eps)) exact = mp.quad(lambda x: mp.exp(-x)/(1+x/z),[0,mp.inf]) # there is also a symbolic expression for the integral: # exact = z * mp.exp(z) * mp.expint(1,z) err = abs(v - exact) assert err < eps w = mp.nsum(lambda n: (-1) ** n * mp.fac(n) * z ** (-n), [0, mp.inf], method = "sidi", levin_variant = "t") assert err < eps
def test_levin_nsum(): mp.dps = 17 with mp.extraprec(mp.prec): z = mp.mpf(10)**(-10) a = mp.nsum(lambda n: n**(-(1 + z)), [1, mp.inf], method="l") - 1 / z assert abs(a - mp.euler) < 1e-10 eps = mp.exp(0.8 * mp.log(mp.eps)) a = mp.nsum(lambda n: (-1)**(n - 1) / n, [1, mp.inf], method="sidi") assert abs(a - mp.log(2)) < eps z = 2 + 1j 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)) v = mp.nsum(f, [0, mp.inf], method="levin", steps=[10 for x in xrange(1000)]) exact = mp.hyp2f1(2 / mp.mpf(3), 4 / mp.mpf(3), 1 / mp.mpf(3), z) assert abs(exact - v) < eps
def test_levin_3(): mp.dps = 17 z=mp.mpf(2) eps = mp.mpf(mp.eps) with mp.extraprec(7*mp.prec): # we need copious amount of precision to sum this highly divergent series L = mp.levin(method = "levin", variant = "t") n, s = 0, 0 while 1: s += (-z)**n * mp.fac(4 * n) / (mp.fac(n) * mp.fac(2 * n) * (4 ** n)) n += 1 v, e = L.step_psum(s) if e < eps: break if n > 1000: raise RuntimeError("iteration limit exceeded") eps = mp.exp(0.8 * mp.log(eps)) exact = mp.quad(lambda x: mp.exp( -x * x / 2 - z * x ** 4), [0,mp.inf]) * 2 / mp.sqrt(2 * mp.pi) # there is also a symbolic expression for the integral: # exact = mp.exp(mp.one / (32 * z)) * mp.besselk(mp.one / 4, mp.one / (32 * z)) / (4 * mp.sqrt(z * mp.pi)) err = abs(v - exact) assert err < eps 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)]) err = abs(v - w) assert err < eps
def fac(n: int, precin: int) -> float: return mp.fac(n)
def test_levin_nsum(): mp.dps = 17 with mp.extraprec(mp.prec): z = mp.mpf(10) ** (-10) a = mp.nsum(lambda n: n**(-(1+z)), [1, mp.inf], method = "l") - 1 / z assert abs(a - mp.euler) < 1e-10 eps = mp.exp(0.8 * mp.log(mp.eps)) a = mp.nsum(lambda n: (-1)**(n-1) / n, [1, mp.inf], method = "sidi") assert abs(a - mp.log(2)) < eps z = 2 + 1j 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)) v = mp.nsum(f, [0, mp.inf], method = "levin", steps = [10 for x in xrange(1000)]) exact = mp.hyp2f1(2 / mp.mpf(3), 4 / mp.mpf(3), 1 / mp.mpf(3), z) assert abs(exact - v) < eps
def place_children(dim, c, use_sp, sp, sample_from, sb, precision): """ Algorithm to place a set of points uniformly on the n-dimensional unit sphere. The idea is to try to tile the surface of the sphere with hypercubes. What was done was to build it once with a large number of points and then sample for this set of points. Input: * dim: Integer. Embedding dimensions * c: Integer. Number of children * use_sp: Boolean. Condition to rotate points or not. * sp: the grandparent node * sample_from: Boolean. Condition to sample from sb * sb: array of coordinates in the embedding * precision: precision used in mpmath library Output: * points: array of coordinates on the hypershpere for each child node """ mp.prec = precision N = dim K = c if sample_from: _, K_large = sb.shape points = [mp.mpf(0) for i in range(0, N * K)] points = np.array(points) points = points.reshape((N, K)) for i in range(0, K - 2 + 1): points[:, i] = sb[:, int(np.floor(K_large / (K - 1))) * i] points[:, K - 1] = sb[:, K_large - 1] min_d_ds = 2 for i in range(0, K): for j in range(i + 1, K): dist = np.linalg.norm(points[:, i] - points[:, j]) if dist < min_d_ds: min_d_ds = dist else: if N % 2 == 1: AN = N * (2**N) * mp.power(mp.mpf(np.pi), (N - 1) / 2) * mp.mpf( mp.fac((N - 1) // 2) / (mp.fac(N))) else: AN = N * mp.power(mp.mpf(np.pi), mp.mpf(N / 2)) / (mp.fac( (N // 2))) delta = mp.power(mp.mpf(AN / K), (mp.mpf(1 / (N - 1)))) true_k = 0 while true_k < K: points, true_k = place_on_sphere(delta, N, K, False, precision) delta = delta * mp.power(mp.mpf(true_k / K), mp.mpf(1 / (N - 1))) points, true_k = place_on_sphere(delta, N, K, True, precision) if use_sp: points = rotate_points(points, sp, N, K) return np.array(points)