예제 #1
0
def FreeFermions(eigvec, subsystem, FermiVector):
	r=range(FermiVector)
	Cij=mp.matrix([[mp.fsum([eigvec[i,k]*eigvec[j,k] for k in r]) for i in subsystem] for j in subsystem])
	C_eigval=mp.eigsy(Cij, eigvals_only=True)
	EH_eigval=mp.matrix([mp.log(mp.fdiv(mp.fsub(mp.mpf(1.0),x),x)) for x in C_eigval])
	S=mp.re(mp.fsum([mp.log(mp.mpf(1.0)+mp.exp(-x))+mp.fdiv(x,mp.exp(x)+mp.mpf(1.0)) for x in EH_eigval]))
	return(S)
예제 #2
0
def mp_Lsolve(L, b):
    n = L.rows
    x = b.copy()
    for i in range(n):
        x[i] -= mp.fsum(L[i, j] * x[j] for j in range(i))
        x[i] /= L[i, i]
    return x
예제 #3
0
def _error_estimate1(
    h,
    sinh_t,
    cosh_t,
    cosh_sinh_t,
    y0,
    y1,
    fly,
    fry,
    f_left,
    f_right,
    alpha,
    last_estimate,
):
    """
    A pretty accurate error estimation is

      E(h) = h * (h/2/pi)**2 * sum_{-N}^{+N} F''(h*j)

    with

      F(t) = f(g(t)) * g'(t),
      g(t) = tanh(pi/2 sinh(t)).
    """
    alpha2 = alpha / mp.mpf(2)

    sinh_sinh_t = numpy.array(list(map(mp.sinh, sinh_t)))
    tanh_sinh_t = sinh_sinh_t / cosh_sinh_t

    # More derivatives of y = 1-g(t).
    y2 = -alpha2 * (sinh_t - 2 * cosh_t**2 * tanh_sinh_t) / cosh_sinh_t**2
    y3 = (-alpha2 * cosh_t *
          (+cosh_sinh_t - 4 * cosh_t**2 / cosh_sinh_t + 2 * cosh_t**2 *
           cosh_sinh_t + 2 * cosh_t**2 * tanh_sinh_t * sinh_sinh_t -
           6 * sinh_t * sinh_sinh_t) / cosh_sinh_t**3)

    fl1_y = numpy.array([f_left[1](yy) for yy in y0])
    fl2_y = numpy.array([f_left[2](yy) for yy in y0])

    fr1_y = numpy.array([f_right[1](yy) for yy in y0])
    fr2_y = numpy.array([f_right[2](yy) for yy in y0])

    # Second derivative of F(t) = f(g(t)) * g'(t).
    summands = numpy.concatenate([
        y3 * fly + 3 * y1 * y2 * fl1_y + y1**3 * fl2_y,
        y3 * fry + 3 * y1 * y2 * fr1_y + y1**3 * fr2_y,
    ])

    val = h * (h / 2 / mp.pi)**2 * mp.fsum(summands)
    if last_estimate is None:
        # Root level: The midpoint is counted twice in the above sum.
        out = val / 2
    else:
        out = last_estimate / 8 + val

    return out
예제 #4
0
def FreeFermions(subsystem, C):
    C = mp.matrix([[C[x, y] for x in subsystem] for y in subsystem])
    C_eigval = mp.eigh(C, eigvals_only=True)
    EH_eigval = mp.matrix(
        [mp.log(mp.fdiv(mp.fsub(mp.mpf(1.0), x), x)) for x in C_eigval])
    S = mp.re(
        mp.fsum([
            mp.log(mp.mpf(1.0) + mp.exp(-x)) + mp.fdiv(x,
                                                       mp.exp(x) + mp.mpf(1.0))
            for x in EH_eigval
        ]))
    return (S)
예제 #5
0
def FreeFermions(subsystem,
                 C_t):  #implements free fermion technique by peschel
    C = mp.matrix([[C_t[x, y] for x in subsystem] for y in subsystem])
    C_eigval = mp.eigh(C, eigvals_only=True)
    EH_eigval = mp.matrix(
        [mp.log(mp.fdiv(mp.fsub(mp.mpf(1.0), x), x)) for x in C_eigval])
    S = mp.re(
        mp.fsum([
            mp.log(mp.mpf(1.0) + mp.exp(-x)) + mp.fdiv(x,
                                                       mp.exp(x) + mp.mpf(1.0))
            for x in EH_eigval
        ]))
    return (S)
예제 #6
0
def rate_process_RMSE(rate_log_dic, correct_rate, size):
    l = []
    dic = {}
    correct_rate_mpf = mp.mpf(correct_rate)
    for i in rate_log_dic:
        if rate_log_dic[i] == None:
            continue
        else:
            element = mp.fsub(rate_log_dic[i], correct_rate_mpf)
            l.append(element)
    square = mp.fsum(l, squared=True)
    mean = mp.fdiv(square, size)
    root = mp.sqrt(mean)
    dic['rate_RMSE'] = root
    return dic
예제 #7
0
파일: quench.py 프로젝트: v-vitale/TopoSSH
def SvN(Dm, Dp, Kpart):

    dim = 2 * len(Kpart)
    gamma = mp.matrix(dim, dim)
    KpartH = Kpart.H
    for m in list(range(0, dim, 2)):
        for n in list(range(0, dim, 2)):
            row = int((m + 1) / 2)
            col = int((n + 1) / 2)
            gamma[m, n] = mp.j * Dp[row, col]
            gamma[m, n + 1] = mp.j * Kpart[row, col]
            gamma[m + 1, n] = -mp.j * KpartH[row, col]
            gamma[m + 1, n + 1] = mp.j * Dm[row, col]

    eigvalgamma = mp.eigh(gamma, eigvals_only=True)
    Spart = mp.fsum([
        -((mp.mpf(1.0) + x) / mp.mpf(2)) * mp.log(
            (mp.mpf(1.0) + x) / mp.mpf(2)) for x in eigvalgamma
    ])

    return (Spart)
예제 #8
0
def tanh_sinh_lr(f_left, f_right, alpha, eps, max_steps=10):
    '''Integrate a function `f` between `a` and `b` with accuracy `eps`. The
    function `f` is given in terms of two functions

        * `f_left(s) = f(a + s)`, i.e., `f` linearly scaled such that
          `f_left(0) = a`, `f_left(b-a) = b`,

        * `f_right(s) = f(b - s)`, i.e., `f` linearly scaled such that
          `f_right(0) = b`, `f_left(b-a) = a`.

    Implemented are Bailey's enhancements plus a few more tricks.

    David H. Bailey, Karthik Jeyabalan, and Xiaoye S. Li,
    Error function quadrature,
    Experiment. Math., Volume 14, Issue 3 (2005), 317-329,
    <https://projecteuclid.org/euclid.em/1128371757>.

    David H. Bailey,
    Tanh-Sinh High-Precision Quadrature,
    2006,
    <http://www.davidhbailey.com/dhbpapers/dhb-tanh-sinh.pdf>.
    '''
    num_digits = int(-mp.log10(eps) + 1)
    mp.dps = num_digits

    alpha2 = alpha / mp.mpf(2)

    # What's a good initial step size `h`?
    # The larger `h` is chosen, the fewer points will be part of the
    # evaluation. However, we don't want to choose the step size too large
    # since that means less accuracy for the quadrature overall. The idea would
    # then be too choose `h` such that it is just large enough for the first
    # tanh-sinh-step to contain only one point, the midpoint. The expression
    #
    #    j = mp.ln(-2/mp.pi * mp.lambertw(-tau/h/2, -1)) / h
    #
    # hence needs to just smaller than 1. (Ideally, one would actually like to
    # get `j` from the full tanh-sinh formula, but the above approximation is
    # good enough.) One gets
    #
    #    0 = pi/2 * exp(h) - h - ln(h) - ln(pi/tau)
    #
    # for which there is no analytic solution. One can, however, approximate
    # it. Since pi/2 * exp(h) >> h >> ln(h) (for `h` large enough), one can
    # either forget about both h and ln(h) to get
    #
    #     h0 = ln(2/pi * ln(pi/tau))
    #
    # or just scratch ln(h) to get
    #
    #     h1 = ln(tau/pi) - W_{-1}(-tau/2).
    #
    # Both of these suggestions underestimate and `j` will be too large. An
    # approximation that overestimates is obtained by replacing `ln(h)` by `h`,
    #
    #     h2 = 1/2 - log(sqrt(pi/tau)) - W_{-1}(-sqrt(exp(1)*pi*tau) / 4).
    #
    # Application of Newton's method will improve all of these approximations
    # and will also always overestimate such that `j` won't exceed 1 in the
    # first step. Nice!
    # TODO since we're doing Newton iterations anyways, use a more accurate
    #      representation for j, and consequently for h
    h = _solve_expx_x_logx(eps**2, tol=1.0e-10)

    last_error_estimate = None

    success = False
    for level in range(max_steps + 1):
        # We would like to calculate the weights until they are smaller than
        # tau, i.e.,
        #
        #     h * pi/2 * cosh(h*j) / cosh(pi/2 * sinh(h*j))**2 < tau.
        #
        # (TODO Newton on this expression to find tau?)
        #
        # To streamline the computation, j is estimated in advance. The only
        # assumption we're making is that h*j>>1 such that exp(-h*j) can be
        # neglected. With this, the above becomes
        #
        #     tau > h * pi/2 * exp(h*j)/2 / cosh(pi/2 * exp(h*j)/2)**2
        #
        # and further
        #
        #     tau > h * pi * exp(h*j) / exp(pi/2 * exp(h*j)).
        #
        # Calling z = - pi/2 * exp(h*j), one gets
        #
        #     tau > -2*h*z * exp(z)
        #
        # This inequality is fulfilled exactly if z = W(-tau/h/2) with W being
        # the (-1)-branch of the Lambert-W function IF exp(1)*tau < 2*h (which
        # we can assume since `tau` will generally be small). We finally get
        #
        #     j > ln(-2/pi * W(-tau/h/2)) / h.
        #
        # We do require j to be positive, so -2/pi * W(-tau/h/2) > 1. This
        # translates to the slightly stricter requirement
        #
        #     tau * exp(pi/2) < pi * h,
        #
        # i.e., h needs to be about 1.531 times larger than tau (not only 1.359
        # times as the previous bound suggested).
        #
        # Note further that h*j is ever decreasing as h decreases.
        assert eps**2 * mp.exp(mp.pi / 2) < mp.pi * h
        j = int(mp.ln(-2 / mp.pi * mp.lambertw(-eps**2 / h / 2, -1)) / h)

        # At level 0, one only takes the midpoint, for all greater levels every
        # other point. The value estimation is later completed with the
        # estimation from the previous level which.
        if level == 0:
            t = [0]
        else:
            t = h * numpy.arange(1, j + 1, 2)

        sinh_t = mp.pi / 2 * numpy.array(list(map(mp.sinh, t)))
        cosh_t = mp.pi / 2 * numpy.array(list(map(mp.cosh, t)))
        cosh_sinh_t = numpy.array(list(map(mp.cosh, sinh_t)))

        # y = alpha/2 * (1 - x)
        # x = [mp.tanh(v) for v in u2]
        exp_sinh_t = numpy.array(list(map(mp.exp, sinh_t)))

        y0 = alpha2 / exp_sinh_t / cosh_sinh_t
        y1 = -alpha2 * cosh_t / cosh_sinh_t**2

        weights = -h * y1

        fly = numpy.array([f_left[0](yy) for yy in y0])
        fry = numpy.array([f_right[0](yy) for yy in y0])

        lsummands = fly * weights
        rsummands = fry * weights

        # Perform the integration.
        if level == 0:
            # The root level only contains one node, the midpoint; function
            # values of f_left and f_right are equal here. Deliberately take
            # lsummands here.
            value_estimates = list(lsummands)
        else:
            value_estimates.append(
                # Take the estimation from the previous step and half the step
                # size. Fill the gaps with the sum of the values of the current
                # step.
                value_estimates[-1] / 2 + mp.fsum(lsummands) +
                mp.fsum(rsummands))

        # error estimation
        if 1 in f_left and 2 in f_left:
            assert 1 in f_right and 2 in f_right
            error_estimate = _error_estimate1(h, sinh_t, cosh_t, cosh_sinh_t,
                                              y0, y1, fly, fry, f_left,
                                              f_right, alpha,
                                              last_error_estimate)
            last_error_estimate = error_estimate
        else:
            error_estimate = _error_estimate2(eps, value_estimates, lsummands,
                                              rsummands)

        if abs(error_estimate) < eps:
            success = True
            break

        h /= 2

    assert success
    return value_estimates[-1], error_estimate
예제 #9
0
파일: ramp.py 프로젝트: labimage/openrave
def Sum(A):
    assert (len(A) > 0)
    return mp.fsum(A)
예제 #10
0
파일: ramp.py 프로젝트: Cescuder/openrave
def Sum(A):
    assert(len(A) > 0)
    return mp.fsum(A)
예제 #11
0
파일: ill_cond.py 프로젝트: vogdb/accupy
 def sum_exact(p):
     mp.dps = dps
     return mp.fsum(p)
def Entropy(sample):
    return -math.fsum(map(math.fmul, np.asarray(sample), map(math.log, map(math.fmul, np.asarray(sample), [len(sample)]*len(sample)))))
def kullbackLeiblerDivergence(sample,reference_sample):
	return -math.fsum(np.asarray(sample)*map(math.log,np.asarray(sample)/np.asarray(reference_sample)))
def ZPS(sample, beta=0.01):
	Z = math.fsum(map(math.exp, map(math.fmul, [-beta]*len(sample), np.asarray(sample))))
	P = map(math.fdiv, map(math.exp, map(math.fmul, [-beta]*len(sample), np.asarray(sample))), np.asarray([Z]*len(sample)))
	S = Entropy(P)
	return Z, P, S
예제 #15
0
def is_inverse_sum(numbers):
    """This function checks if the array of integers are an inverse sum of 0.5"""
    return mp.fsum([mp.fdiv(1, (n * n)) for n in numbers]) == 0.5