示例#1
0
def calc_x_tp(Kp1, C_tp, Cm1_tp, rp1, lm2, Am1, A, Ap1, lm1_s, lm1_si, r_s, r_si, Vsh):
    D = A.shape[2]
    Dm1 = A.shape[1]
    q = A.shape[0]
    
    x = np.zeros((Dm1, q * D - Dm1), dtype=A.dtype)

    V = sp.transpose(Vsh, axes=(0, 2, 1)).conj().copy()
    Vri = V.copy()
    try:
        for Vris in Vri:
            Vris[:] = r_si.dot_left(Vris)
    except AttributeError:
        for Vris in Vri:
            Vris[:] = Vris.dot(r_si)
    
    if not C_tp is None:
        x += lm1_s.dot(eps_r_op_2s_C12_tp(rp1, C_tp, Vri, Ap1)) #1
        
    if not Cm1_tp is None:
        for al in xrange(len(Cm1_tp)):
            x += lm1_si.dot(eps_l_noop(lm2, Am1, Cm1_tp[al][0]).dot(eps_r_noop(r_s, Cm1_tp[al][1], V))) #2
            
    if not Kp1 is None:
        x += lm1_s.dot(eps_r_noop(Kp1, A, Vri))

    return x
示例#2
0
def calc_Vsh_l(A, lm1_sqrt, sanity_checks=False):
    D = A.shape[2]
    Dm1 = A.shape[1]
    q = A.shape[0]

    if q * Dm1 - D <= 0:
        return None

    L = sp.zeros((D, q, Dm1), dtype=A.dtype, order='C')

    for s in xrange(q):
        L[:, s, :] = lm1_sqrt.dot(A[s]).conj().T

    L = L.reshape((D, q * Dm1))
    V = ns.nullspace_qr(L)

    if sanity_checks:
        if not sp.allclose(L.dot(V), 0):
            log.warning("Sanity Fail in calc_Vsh_l!: LV != 0")
        if not sp.allclose(V.conj().T.dot(V), sp.eye(V.shape[1])):
            log.warning("Sanity Fail in calc_Vsh_l!: V H(V) != eye")

    V = V.reshape((q, Dm1, q * Dm1 - D))

    Vsh = sp.transpose(V.conj(), axes=(0, 2, 1))
    Vsh = sp.asarray(Vsh, order='C')

    if sanity_checks:
        M = eps_l_noop(lm1_sqrt, A, V)
        if not sp.allclose(M, 0):
            log.warning("Sanity Fail in calc_Vsh_l!: Bad Vsh")

    return Vsh
示例#3
0
def calc_x_tp(Kp1, C_tp, Cm1_tp, rp1, lm2, Am1, A, Ap1, lm1_s, lm1_si, r_s,
              r_si, Vsh):
    D = A.shape[2]
    Dm1 = A.shape[1]
    q = A.shape[0]

    x = np.zeros((Dm1, q * D - Dm1), dtype=A.dtype)

    V = sp.transpose(Vsh, axes=(0, 2, 1)).conj().copy()
    Vri = V.copy()
    try:
        for Vris in Vri:
            Vris[:] = r_si.dot_left(Vris)
    except AttributeError:
        for Vris in Vri:
            Vris[:] = Vris.dot(r_si)

    if not C_tp is None:
        x += lm1_s.dot(eps_r_op_2s_C12_tp(rp1, C_tp, Vri, Ap1))  #1

    if not Cm1_tp is None:
        for al in xrange(len(Cm1_tp)):
            x += lm1_si.dot(
                eps_l_noop(lm2, Am1, Cm1_tp[al][0]).dot(
                    eps_r_noop(r_s, Cm1_tp[al][1], V)))  #2

    if not Kp1 is None:
        x += lm1_s.dot(eps_r_noop(Kp1, A, Vri))

    return x
示例#4
0
def calc_Vsh_l(A, lm1_sqrt, sanity_checks=False):    
    D = A.shape[2]
    Dm1 = A.shape[1]
    q = A.shape[0]
    
    if q * Dm1 - D <= 0:
        return None
    
    L = sp.zeros((D, q, Dm1), dtype=A.dtype, order='C')

    for s in xrange(q):
        L[:,s,:] = lm1_sqrt.dot(A[s]).conj().T

    L = L.reshape((D, q * Dm1))
    V = ns.nullspace_qr(L)

    if sanity_checks:
        if not sp.allclose(L.dot(V), 0):
            log.warning("Sanity Fail in calc_Vsh_l!: LV != 0")
        if not sp.allclose(V.conj().T.dot(V), sp.eye(V.shape[1])):
            log.warning("Sanity Fail in calc_Vsh_l!: V H(V) != eye")
        
    V = V.reshape((q, Dm1, q * Dm1 - D))

    Vsh = sp.transpose(V.conj(), axes=(0, 2, 1))
    Vsh = sp.asarray(Vsh, order='C')

    if sanity_checks:
        M = eps_l_noop(lm1_sqrt, A, V)
        if not sp.allclose(M, 0):
            log.warning("Sanity Fail in calc_Vsh_l!: Bad Vsh")

    return Vsh
示例#5
0
def restore_LCF_l(A, lm1, Gm1, sanity_checks=False, zero_tol=1E-15):
    if Gm1 is None:
        GhGm1 = lm1
    else:
        GhGm1 = Gm1.conj().T.dot(lm1.dot(Gm1))

    M = eps_l_noop(GhGm1, A, A)

    G, Gi, new_D = herm_fac_with_inv(M,
                                     zero_tol=zero_tol,
                                     return_rank=True,
                                     sanity_checks=sanity_checks)

    if Gm1 is None:
        Gm1 = G

    if sanity_checks:
        if new_D == A.shape[2]:
            eye = sp.eye(A.shape[2])
        else:
            eye = mm.simple_diag_matrix(np.append(np.zeros(A.shape[2] - new_D),
                                                  np.ones(new_D)),
                                        dtype=A.dtype)
        if not sp.allclose(G.dot(Gi), eye, atol=1E-13, rtol=1E-13):
            log.warning("Sanity Fail in restore_LCF_l!: Bad GT!")

    for s in xrange(A.shape[0]):
        A[s] = Gm1.dot(A[s]).dot(Gi)

    if new_D == A.shape[2]:
        l = mm.eyemat(A.shape[2], A.dtype)
    else:
        l = mm.simple_diag_matrix(np.append(np.zeros(A.shape[2] - new_D),
                                            np.ones(new_D)),
                                  dtype=A.dtype)

    if sanity_checks:
        lm1_ = mm.eyemat(A.shape[1], A.dtype)

        l_ = eps_l_noop(lm1_, A, A)
        if not sp.allclose(l_, l.A, atol=1E-13, rtol=1E-13):
            log.warning("Sanity Fail in restore_LCF_l!: l is bad")
            log.warning(la.norm(l_ - l))

    return l, G, Gi
示例#6
0
def calc_K_3s_l(Km1, Cm2, lm3, r, A, Am2Am1A):
    K = eps_l_noop(Km1, A, A)

    Hl = eps_l_op_3s_AAA123_C456(lm3, Am2Am1A, Cm2)

    op_expect = mm.adot_noconj(Hl, r)

    K += Hl

    return K, op_expect
示例#7
0
def calc_K_3s_l(Km1, Cm2, lm3, r, A, Am2Am1A):
    K = eps_l_noop(Km1, A, A)
    
    Hl = eps_l_op_3s_AAA123_C456(lm3, Am2Am1A, Cm2)  
    
    op_expect = mm.adot_noconj(Hl, r)
        
    K += Hl
    
    return K, op_expect
示例#8
0
def calc_K_l_tp(Km1, lm2, r, Am1, A, Cm1_tp):
    K = eps_l_noop(Km1, A, A)
    
    Hl = eps_l_op_2s_C34_tp(lm2, Am1, A, Cm1_tp)

    op_expect = mm.adot_noconj(Hl, r)
        
    K += Hl
    
    return K, op_expect
示例#9
0
def calc_K_l_tp(Km1, lm2, r, Am1, A, Cm1_tp):
    K = eps_l_noop(Km1, A, A)

    Hl = eps_l_op_2s_C34_tp(lm2, Am1, A, Cm1_tp)

    op_expect = mm.adot_noconj(Hl, r)

    K += Hl

    return K, op_expect
示例#10
0
def calc_BB_Y_2s_tp(C_tp, Vlh, Vrh_p1, l_s_m1, r_s_p1):
    Vl = sp.transpose(Vlh, axes=(0, 2, 1)).conj().copy()
    Vr_p1 = sp.transpose(Vrh_p1, axes=(0, 2, 1)).conj().copy()

    Y = 0
    for al in xrange(len(C_tp)):
        Y += eps_l_noop(l_s_m1, Vl, C_tp[al][0]).dot(eps_r_noop(r_s_p1, C_tp[al][1], Vr_p1))

    etaBB_sq = mm.adot(Y, Y)
    
    return Y, etaBB_sq
示例#11
0
def calc_BB_Y_2s_tp(C_tp, Vlh, Vrh_p1, l_s_m1, r_s_p1):
    Vl = sp.transpose(Vlh, axes=(0, 2, 1)).conj().copy()
    Vr_p1 = sp.transpose(Vrh_p1, axes=(0, 2, 1)).conj().copy()

    Y = 0
    for al in range(len(C_tp)):
        Y += eps_l_noop(l_s_m1, Vl, C_tp[al][0]).dot(eps_r_noop(r_s_p1, C_tp[al][1], Vr_p1))

    etaBB_sq = mm.adot(Y, Y)
    
    return Y, etaBB_sq
示例#12
0
def restore_LCF_l(A, lm1, Gm1, sanity_checks=False, zero_tol=1E-15):
    if Gm1 is None:
        GhGm1 = lm1
    else:
        GhGm1 = Gm1.conj().T.dot(lm1.dot(Gm1))

    M = eps_l_noop(GhGm1, A, A)
    
    G, Gi, new_D = herm_fac_with_inv(M, zero_tol=zero_tol, return_rank=True, 
                                     sanity_checks=sanity_checks)

    if Gm1 is None:
        Gm1 = G

    if sanity_checks:
        if new_D == A.shape[2]:
            eye = sp.eye(A.shape[2])
        else:
            eye = mm.simple_diag_matrix(np.append(np.zeros(A.shape[2] - new_D),
                                                   np.ones(new_D)), dtype=A.dtype)
        if not sp.allclose(G.dot(Gi), eye, atol=1E-13, rtol=1E-13):
            log.warning("Sanity Fail in restore_LCF_l!: Bad GT!")

    for s in xrange(A.shape[0]):
        A[s] = Gm1.dot(A[s]).dot(Gi)

    if new_D == A.shape[2]:
        l = mm.eyemat(A.shape[2], A.dtype)
    else:
        l = mm.simple_diag_matrix(np.append(np.zeros(A.shape[2] - new_D),
                                                np.ones(new_D)), dtype=A.dtype)

    if sanity_checks:
        lm1_ = mm.eyemat(A.shape[1], A.dtype)

        l_ = eps_l_noop(lm1_, A, A)
        if not sp.allclose(l_, l.A, atol=1E-13, rtol=1E-13):
            log.warning("Sanity Fail in restore_LCF_l!: l is bad")
            log.warning(la.norm(l_ - l))

    return l, G, Gi
示例#13
0
def calc_K_l(Km1, Cm1, lm2, r, A, Am1A):
    """Calculates the K_left using the recursive definition.
    
    This is the "bra-vector" K_left, which means (K_left.dot(r)).trace() = <K_left|r>.
    In other words, K_left ~ <K_left| and K_left.conj().T ~ |K_left>.
    """
    K = eps_l_noop(Km1, A, A)

    Hl = eps_l_op_2s_AA12_C34(lm2, Am1A, Cm1)

    op_expect = mm.adot_noconj(Hl, r)

    K += Hl

    return K, op_expect
示例#14
0
def calc_K_l(Km1, Cm1, lm2, r, A, Am1A):
    """Calculates the K_left using the recursive definition.
    
    This is the "bra-vector" K_left, which means (K_left.dot(r)).trace() = <K_left|r>.
    In other words, K_left ~ <K_left| and K_left.conj().T ~ |K_left>.
    """    
    K = eps_l_noop(Km1, A, A)
    
    Hl = eps_l_op_2s_AA12_C34(lm2, Am1A, Cm1)

    op_expect = mm.adot_noconj(Hl, r)
        
    K += Hl
    
    return K, op_expect
示例#15
0
def restore_LCF_l_seq(A, l, G0=None, sanity_checks=False, sc_data=''):
    """Transforms a sequence of A[n]'s to obtain l[n] = eye(D).
    
    Implements the condition for left-orthonormalization.
    
    Uses a reduced QR (RQ) decomposition to avoid inverting anything explicity.
    
    Parameters
    ----------
    A : sequence of ndarray
        The parameter tensors for a sequence of sites [None, A1, A2,..., AN].
        The first entry is ignored so that the indices match up with l.
    l : sequence of ndarray or objects with array interface
        The matrices [l0, l1, l2,..., lN], where l0 will not be changed, but is 
        used for sanity checks.
    G0 : ndarray or scalar
        Initial left gauge transformation matrix for site 0. Only needed when used
        as part of a larger transformation.
    sanity_checks : bool (False)
        Whether to perform additional sanity checks.
    sc_data : string
        A string to be appended to sanity check log messages.
    """
    if G0 is None:
        G = mm.eyemat(A[1].shape[1], dtype=A[1].dtype)
    else:
        G = G0

    for n in xrange(1, len(A)):
        q, Dm1, D = A[n].shape
        GA = sp.array([G.dot(As) for As in A[n]])
        GA = GA.reshape((q * Dm1, D))
        Q, G = la.qr(GA, mode='economic')
        A[n] = Q.reshape((q, Dm1, D))

        l[n] = mm.eyemat(D, dtype=A[n].dtype)

        if sanity_checks:
            l_ = eps_l_noop(l[n - 1], A[n], A[n])
            if not sp.allclose(l_, l[n].A, atol=1E-13, rtol=1E-13):
                log.warning("Sanity Fail in restore_LCF_l_seq!: l is bad")
                log.warning(la.norm(l_ - l[n].A))

    return G
示例#16
0
def restore_LCF_l_seq(A, l, G0=None, sanity_checks=False, sc_data=''):
    """Transforms a sequence of A[n]'s to obtain l[n] = eye(D).
    
    Implements the condition for left-orthonormalization.
    
    Uses a reduced QR (RQ) decomposition to avoid inverting anything explicity.
    
    Parameters
    ----------
    A : sequence of ndarray
        The parameter tensors for a sequence of sites [None, A1, A2,..., AN].
        The first entry is ignored so that the indices match up with l.
    l : sequence of ndarray or objects with array interface
        The matrices [l0, l1, l2,..., lN], where l0 will not be changed, but is 
        used for sanity checks.
    G0 : ndarray or scalar
        Initial left gauge transformation matrix for site 0. Only needed when used
        as part of a larger transformation.
    sanity_checks : bool (False)
        Whether to perform additional sanity checks.
    sc_data : string
        A string to be appended to sanity check log messages.
    """
    if G0 is None:
        G = mm.eyemat(A[1].shape[1], dtype=A[1].dtype)
    else:
        G = G0

    for n in xrange(1, len(A)):
        q, Dm1, D = A[n].shape
        GA = sp.array([G.dot(As) for As in A[n]])
        GA = GA.reshape((q * Dm1, D))
        Q, G = la.qr(GA, mode='economic')
        A[n] = Q.reshape((q, Dm1, D))
        
        l[n] = mm.eyemat(D, dtype=A[n].dtype)
        
        if sanity_checks:
            l_ = eps_l_noop(l[n - 1], A[n], A[n])
            if not sp.allclose(l_, l[n].A, atol=1E-13, rtol=1E-13):
                log.warning("Sanity Fail in restore_LCF_l_seq!: l is bad")
                log.warning(la.norm(l_ - l[n].A))
        
    return G
示例#17
0
def restore_RCF_l(A, lm1, Gm1, sanity_checks=False):
    """Transforms a single A[n] to obtain diagonal l[n].

    Applied after restore_RCF_r(), this completes the full canonical form
    of sub-section 3.1, theorem 1 of arXiv:quant-ph/0608197v2.

    This function must be called for each n in turn, starting at 1,
    passing the gauge transformation matrix from the previous step
    as an argument.

    Finds a G[n] such that orthonormalization is fulfilled for n.

    The diagonal entries of l[n] are sorted in
    ascending order (for example l[n] = diag([0, 0, 0.1, 0.2, ...])).

    Parameters
    ----------
    A : ndarray
        The parameter tensor for the nth site A[n].
    lm1 : ndarray or object with array interface
        The matrix l[n - 1].
    Gm1 : ndarray
        The gauge transform matrix for site n obtained in the previous step (for n - 1).
    sanity_checks : bool (False)
        Whether to perform additional sanity checks.
        
    Returns
    -------
    l : ndarray or simple_diag_matrix
        The new, diagonal matrix l[n]. 
    G : ndarray
        The gauge transformation matrix for site n.
    G_i : ndarray
        Inverse of G.
    """
    if Gm1 is None:
        x = lm1
    else:
        x = Gm1.conj().T.dot(lm1.dot(Gm1))

    M = eps_l_noop(x, A, A)
    ev, EV = la.eigh(
        M)  #wraps lapack routines, which return eigenvalues in ascending order

    if sanity_checks:
        assert np.all(ev == np.sort(ev)), "unexpected eigenvalue ordering"

    l = mm.simple_diag_matrix(ev, dtype=A.dtype)
    G_i = EV

    if Gm1 is None:
        Gm1 = EV.conj().T  #for left uniform case
        lm1 = l  #for sanity check

    for s in xrange(A.shape[0]):
        A[s] = Gm1.dot(A[s].dot(G_i))

    if sanity_checks:
        l_ = eps_l_noop(lm1, A, A)
        if not sp.allclose(l_, l, atol=1E-12, rtol=1E-12):
            log.warning("Sanity Fail in restore_RCF_l!: l is bad!")
            log.warning(la.norm(l_ - l))

    G = EV.conj().T

    return l, G, G_i
示例#18
0
def eps_l_op_2s_AA12_C34(x, AA12, C34):
    d = AA12.shape[0] * AA12.shape[1]
    S1 = (d, AA12.shape[2], AA12.shape[3])
    S2 = (d, C34.shape[2], C34.shape[3])
    return eps_l_noop(x, AA12.reshape(S1), C34.reshape(S2))
示例#19
0
def eps_l_op_3s_AAA123_C456(x, AAA123, C456):
    d = C456.shape[0] * C456.shape[1] * C456.shape[2]
    S1 = (d, AAA123.shape[3], AAA123.shape[4])
    S2 = (d, C456.shape[3], C456.shape[4])
    return eps_l_noop(x, AAA123.reshape(S1), C456.reshape(S2))
示例#20
0
def eps_l_op_2s_C34_tp(x, A1, A2, C34_tp):
    res = 0
    for al in xrange(len(C34_tp)):
        res += eps_l_noop(eps_l_noop(x, A1, C34_tp[al][0]), A2, C34_tp[al][1])
    return res
示例#21
0
def eps_l_op_2s_AA12_C34(x, AA12, C34):
    d = AA12.shape[0] * AA12.shape[1]
    S1 = (d, AA12.shape[2], AA12.shape[3])
    S2 = (d, C34.shape[2], C34.shape[3])
    return eps_l_noop(x, AA12.reshape(S1), C34.reshape(S2))
示例#22
0
def eps_l_op_3s_AAA123_C456(x, AAA123, C456):
    d = C456.shape[0] * C456.shape[1] * C456.shape[2]
    S1 = (d, AAA123.shape[3], AAA123.shape[4])
    S2 = (d, C456.shape[3], C456.shape[4])
    return eps_l_noop(x, AAA123.reshape(S1), C456.reshape(S2))
示例#23
0
def restore_RCF_l(A, lm1, Gm1, sanity_checks=False):
    """Transforms a single A[n] to obtain diagonal l[n].

    Applied after restore_RCF_r(), this completes the full canonical form
    of sub-section 3.1, theorem 1 of arXiv:quant-ph/0608197v2.

    This function must be called for each n in turn, starting at 1,
    passing the gauge transformation matrix from the previous step
    as an argument.

    Finds a G[n] such that orthonormalization is fulfilled for n.

    The diagonal entries of l[n] are sorted in
    ascending order (for example l[n] = diag([0, 0, 0.1, 0.2, ...])).

    Parameters
    ----------
    A : ndarray
        The parameter tensor for the nth site A[n].
    lm1 : ndarray or object with array interface
        The matrix l[n - 1].
    Gm1 : ndarray
        The gauge transform matrix for site n obtained in the previous step (for n - 1).
    sanity_checks : bool (False)
        Whether to perform additional sanity checks.
        
    Returns
    -------
    l : ndarray or simple_diag_matrix
        The new, diagonal matrix l[n]. 
    G : ndarray
        The gauge transformation matrix for site n.
    G_i : ndarray
        Inverse of G.
    """
    if Gm1 is None:
        x = lm1
    else:
        x = Gm1.conj().T.dot(lm1.dot(Gm1))

    M = eps_l_noop(x, A, A)
    ev, EV = la.eigh(M) #wraps lapack routines, which return eigenvalues in ascending order
    
    if sanity_checks:
        assert np.all(ev == np.sort(ev)), "unexpected eigenvalue ordering"
    
    l = mm.simple_diag_matrix(ev, dtype=A.dtype)
    G_i = EV

    if Gm1 is None:
        Gm1 = EV.conj().T #for left uniform case
        lm1 = l #for sanity check

    for s in xrange(A.shape[0]):
        A[s] = Gm1.dot(A[s].dot(G_i))

    if sanity_checks:
        l_ = eps_l_noop(lm1, A, A)
        if not sp.allclose(l_, l, atol=1E-12, rtol=1E-12):
            log.warning("Sanity Fail in restore_RCF_l!: l is bad!")
            log.warning(la.norm(l_ - l))

    G = EV.conj().T

    return l, G, G_i
示例#24
0
def eps_l_op_2s_C34_tp(x, A1, A2, C34_tp):
    res = 0
    for al in xrange(len(C34_tp)):
        res += eps_l_noop(eps_l_noop(x, A1, C34_tp[al][0]), A2, C34_tp[al][1])
    return res