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
Exemple #2
0
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
Exemple #7
0
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)