Ejemplo n.º 1
0
def run_eigsy(A, verbose=False):
    if verbose:
        print("original matrix:\n", str(A))

    D, Q = mp.eigsy(A)
    B = Q * mp.diag(D) * Q.transpose()
    C = A - B
    E = Q * Q.transpose() - mp.eye(A.rows)

    if verbose:
        print("eigenvalues:\n", D)
        print("eigenvectors:\n", Q)

    NC = mp.mnorm(C)
    NE = mp.mnorm(E)

    if verbose:
        print("difference:", NC, "\n", C, "\n")
        print("difference:", NE, "\n", E, "\n")

    eps = mp.exp(0.8 * mp.log(mp.eps))

    assert NC < eps
    assert NE < eps

    return NC
Ejemplo n.º 2
0
def run_eigsy(A, verbose = False):
    if verbose:
        print("original matrix:\n", str(A))

    D, Q = mp.eigsy(A)
    B = Q * mp.diag(D) * Q.transpose()
    C = A - B
    E = Q * Q.transpose() - mp.eye(A.rows)

    if verbose:
        print("eigenvalues:\n", D)
        print("eigenvectors:\n", Q)

    NC = mp.mnorm(C)
    NE = mp.mnorm(E)

    if verbose:
        print("difference:", NC, "\n", C, "\n")
        print("difference:", NE, "\n", E, "\n")

    eps = mp.exp( 0.8 * mp.log(mp.eps))

    assert NC < eps
    assert NE < eps

    return NC
Ejemplo n.º 3
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)
Ejemplo n.º 4
0
def convert_chain_to_star(c0,
                          omega,
                          t,
                          get_trafo=False,
                          force_sp=False,
                          mp_dps=30,
                          sort_by=None):
    """
        Converts chain coefficients in the form c0, omega, t (system to bath coupling, bath energies,
        bath-bath couplings) into the equivalent star geometry coefficients gamma, xi (star system to bath coupling,
        star bath energies) by using diagonalization with either arbitrary precision mpmath if the library is installed
        or scipy eigh_tridiagonal in float precision
    :param c0: System to bath coupling float
    :param omega: Bath energies (numpy array)
    :param t: Bath-bath couplings (numpy array)
    :param get_trafo: If the transformation between the chain and the star should be returned or not
                      This matrix is only for the omega/t coefficients
    :param force_sp: Force the use of the scipy method eigh_tridiagonal, even if mpmath is installed
    :param mp_dps: Decimals, which mpmath uses for the computation
    :return: gamma (star system to bath coupling), xi (star bath energies),
             info dict with the keys: 'trafo': Contains the transformation Matrix between the geometries
    """
    assert len(omega) - 1 == len(t)
    info = dict()
    info['trafo'] = None
    if mp is None or force_sp:
        w, v = eigh_tridiagonal(omega, t)
        gamma = c0 * np.abs(v[0, :])
        xi = w
        if get_trafo:
            info['trafo'] = v
    else:
        mp.set_dps = mp_dps
        nof_coefficients = len(omega)
        A = np.zeros((nof_coefficients, nof_coefficients))
        drows, dcols = np.diag_indices_from(A)
        A[drows[:nof_coefficients], dcols[:nof_coefficients]] = omega
        rng = np.arange(nof_coefficients - 1)
        A[rng + 1, rng] = t
        A[rng, rng + 1] = t
        E, Q = mp.eigsy(mp.matrix(A.tolist()))
        xi = np.empty(nof_coefficients)
        gamma = np.empty(nof_coefficients)
        for i in range(A.shape[1]):
            xi[i] = float(E[i])
            gamma[i] = c0 * np.abs(float(Q[0, i]))
        if get_trafo:
            Q = np.array(Q.tolist(), dtype=np.float64)
            info['trafo'] = Q
    gamma, xi = sort_star_coefficients(gamma, xi, sort_by)
    return gamma, xi, info
Ejemplo n.º 5
0
def symmetric_svd(a):
    # Here we implicitly assume a is symmetric.
    A = mp.matrix(a)

    reA = A.apply(mp.re)
    imA = A.apply(mp.im)
    n = len(a)

    Bmat = [[0 for _ in range(2 * n)] for _ in range(2 * n)]
    for i in range(n):
        for j in range(n):
            Bmat[i][j] = reA[i, j]
            Bmat[i + n][j] = imA[i, j]
            Bmat[i][j + n] = imA[i, j]
            Bmat[i + n][j + n] = -reA[i, j]

    B = mp.matrix(Bmat)
    # Q.T * mp.diag(ev) * Q == B
    ev, Q = mp.eigsy(B)

    Qmat = [[Q[j, i] for j in range(2 * n)] for i in range(2 * n)]
    Umat = [[0 for _ in range(n)] for _ in range(n)]
    vs = [Qmat[i] for i, v in enumerate(ev) if v > 0]

    assert (len(vs) == n)

    for i in range(n):
        for j in range(n):
            Umat[i][j] = vs[j][i] - 1j * vs[j][i + n]

    Q = mp.matrix(Umat)

    # Accordingly, Q.T * A * Q is a diagonal matrix
    sing_mat = Q.T * A * Q
    sing_vs = [sing_mat[i, i] for i in range(len(sing_mat))]

    return sing_vs, Q
Ejemplo n.º 6
0
        print("Currently working on...")
        print("L=" + str(L))
        print(v)
        print("................................")
        #the following cicle takes care of the staggered hopping
        for i in range(END):
            j = (i + 1) % L
            if i % 2 == 0:
                H[i, j] = -v
                H[j, i] = H[i, j]
            elif j % 2 == 0:
                H[i, j] = -1
                H[j, i] = H[i, j]

        #find its eigenvalues and vectors
        eigval, eigvec = mp.eigsy(H)
        eigval, eigvec = mp.eig_sort(eigval, eigvec)

        Cij = Cij_0(eigvec, Np)

        #From now on I will use the Free Fermions technique to calculate the entanglement entropies of the subsistems in units of log2

        SB = FreeFermions(B, Cij) / mp.log(mp.mpf(2.0))

        SAB = FreeFermions(A + B, Cij) / mp.log(mp.mpf(2.0))

        SBC = FreeFermions(B + C, Cij) / mp.log(mp.mpf(2.0))

        SABC = FreeFermions(D, Cij) / mp.log(mp.mpf(2.0))

        #In the end I calculate Sqtopo ad proposed by Wen