Esempio n. 1
0
def get_initial_tensor_CDL_3d(pars):
    delta = np.eye(2, dtype=pars["dtype"])
    A = np.einsum(
        ("ae,fi,jm,nb,cq,rk,lu,vd,gs,to,pw,xh -> abcdefghijklmnopqrstuvwx"),
        *((delta,) * 12)
    )
    return Tensor.from_ndarray(A.reshape((16, 16, 16, 16, 16, 16)))
Esempio n. 2
0
def get_initial_tensor_CQL_3d(pars):
    delta = np.array([[[1, 0], [0, 0]], [[0, 0], [0, 1]]])
    A = np.einsum(
        ("aeu,fiv,gjq,hbr,mcw,nxk,ols,ptd " "-> abcdefghijklmnopqrstuvwx"),
        *((delta,) * 8)
    )
    return Tensor.from_ndarray(A.reshape((16, 16, 16, 16, 16, 16)))
Esempio n. 3
0
def get_KW_unitary(pars):
    """ The unitary that moves the Kramers-Wannier duality defect of the
    classical 2D square lattice Ising model.
    """
    CZ = Csigma_np("z")
    # fmt: off
    U = ncon((CZ,
              R(np.pi / 4, 'z'), R(np.pi / 4, 'x'),
              R(np.pi / 4, 'y')),
             ([-1, -2, 5, 6],
              [-3, 5], [3, 6],
              [-4, 3]))
    # fmt: on
    u = symmetry_bases["ising"]
    u_dg = u.T.conjugate()
    U = ncon(
        (U, u, u_dg, u_dg, u),
        ([1, 2, 3, 4], [-1, 1], [-2, 2], [3, -3], [4, -4]),
    )
    U *= -1j
    if pars["symmetry_tensors"]:
        U = TensorZ2.from_ndarray(
            U, shape=[[1, 1]] * 4, qhape=[[0, 1]] * 4, dirs=[1, 1, -1, -1]
        )
    else:
        U = Tensor.from_ndarray(U, dirs=[1, 1, 1, -1, -1, -1])
    return U
Esempio n. 4
0
def get_initial_sixvertex_tensor(pars):
    try:
        a = pars["sixvertex_a"]
        b = pars["sixvertex_b"]
        c = pars["sixvertex_c"]
    except KeyError:
        u = pars["sixvertex_u"]
        lmbd = pars["sixvertex_lambda"]
        rho = pars["sixvertex_rho"]
        a = rho * np.sin(lmbd - u)
        b = rho * np.sin(u)
        c = rho * np.sin(lmbd)
    A_0 = np.zeros((2, 2, 2, 2), dtype=pars["dtype"])
    A_0[1, 0, 0, 1] = a
    A_0[0, 1, 1, 0] = a
    A_0[0, 0, 1, 1] = b
    A_0[1, 1, 0, 0] = b
    A_0[0, 1, 0, 1] = c
    A_0[1, 0, 1, 0] = c
    if pars["symmetry_tensors"]:
        dim = [1, 1]
        qim = [-1, 1]
        A_0 = TensorU1.from_ndarray(
            A_0, shape=[dim] * 4, qhape=[qim] * 4, dirs=[1, 1, 1, 1]
        )
        A_0 = A_0.flip_dir(2)
        A_0 = A_0.flip_dir(3)
    else:
        A_0 = Tensor.from_ndarray(A_0)
    return A_0
Esempio n. 5
0
def convertAbe(A):
    """
    Convert A to class abeliantensors if it is not
    """
    if type(A).__module__.split(".")[0] != 'abeliantensors':
        A = Tensor.from_ndarray(A)
    return A
Esempio n. 6
0
def get_initial_impurity(pars, legs=(3,), factor=3, **kwargs):
    if kwargs:
        pars = pars.copy()
        pars.update(kwargs)
    A_pure = get_initial_tensor(pars)
    model = pars["model"]
    impurity = pars["impurity"]
    try:
        impurity_matrix = impurity_dict[model][impurity](pars)
    except KeyError:
        msg = "Unknown (model, impurity) combination: ({}, {})".format(
            model, impurity
        )
        raise ValueError(msg)
    # TODO The expectation that everything is in the symmetry basis
    # clashes with how 2D ising and potts initial tensors are generated.
    if not pars["symmetry_tensors"]:
        impurity_matrix = Tensor.from_ndarray(impurity_matrix.to_ndarray())
    # TODO This was commented in before 2019-09-06. Why? It's clearly wrong
    # for 3D Ising U-impurity and id-impurity.
    # impurity_matrix *= -1
    A_impure = 0
    if 0 in legs:
        A_impure += ncon(
            (A_pure, impurity_matrix), ([1, -2, -3, -4, -5, -6], [1, -1])
        )
    if 1 in legs:
        A_impure += ncon(
            (A_pure, impurity_matrix), ([-1, 2, -3, -4, -5, -6], [2, -2])
        )
    if 2 in legs:
        A_impure += ncon(
            (A_pure, impurity_matrix.transpose()),
            ([-1, -2, 3, -4, -5, -6], [3, -3]),
        )
    if 3 in legs:
        A_impure += ncon(
            (A_pure, impurity_matrix.transpose()),
            ([-1, -2, -3, 4, -5, -6], [4, -4]),
        )
    if 4 in legs:
        A_impure += ncon(
            (A_pure, impurity_matrix), ([-1, -2, -3, -4, 5, -6], [5, -5])
        )
    if 5 in legs:
        A_impure += ncon(
            (A_pure, impurity_matrix.transpose()),
            ([-1, -2, -3, -4, -5, 6], [6, -6]),
        )
    # TODO This was commented in before 2019-09-06. Why? It's clearly wrong
    # for 3D Ising U-impurity and id-impurity.
    # A_impure *= factor
    return A_impure
Esempio n. 7
0
def get_initial_tensor_CDL_3d_v2(pars):
    delta = np.eye(2, dtype=pars["dtype"])
    A = ncon(
        (delta,) * 12,
        # fmt: off
        (
            [-11, -21], [-12, -41], [-13, -51], [-14, -61],
            [-31, -22], [-32, -42], [-33, -52], [-34, -62],
            [-23, -63], [-64, -43], [-44, -53], [-54, -24],
        ),
        # fmt: on
    )
    return Tensor.from_ndarray(A.reshape((16, 16, 16, 16, 16, 16)))
Esempio n. 8
0
def get_initial_tensor_ising_3d(pars):
    beta = pars["beta"]
    ham = ising3d_ham(beta)
    A_0 = np.einsum(
        "ai,aj,ak,al,am,an -> ijklmn", ham, ham, ham, ham, ham, ham
    )
    if pars["symmetry_tensors"]:
        cls, dim, qim = TensorZ2, [1, 1], [0, 1]
        A_0 = cls.from_ndarray(
            A_0, shape=[dim] * 6, qhape=[qim] * 6, dirs=[1, 1, -1, -1, 1, -1]
        )
    else:
        A_0 = Tensor.from_ndarray(A_0)
    return A_0
Esempio n. 9
0
def get_initial_dilute_sixvertex_tensor(pars):
    # Copied and adapted from Roman
    #      1
    #      |
    # 4 -- A -- 2
    #      |
    #      3
    # "dilute six-vertex model",
    # states : 0:empty, 1:top arrow, 1:bot arrow. Time flows toward N-E

    w = np.exp(1j * np.pi / 8.0)
    z = 0.57  # Close to critical
    # z = 1.0  # XXZ universality class

    A = np.zeros((3, 3, 3, 3), dtype=np.complex)

    A[1, 1, 1, 1] = 1.0

    A[2, 1, 1, 2] = z * w
    A[1, 2, 2, 1] = z / w
    A[0, 1, 1, 0] = z / w
    A[1, 0, 0, 1] = z * w

    A[2, 0, 1, 1] = z / w
    A[0, 2, 1, 1] = z * w
    A[1, 1, 2, 0] = z * w
    A[1, 1, 0, 2] = z / w

    A[2, 2, 2, 2] = z ** 2
    A[0, 0, 0, 0] = z ** 2
    A[2, 0, 2, 0] = z ** 2
    A[0, 2, 0, 2] = z ** 2
    A[2, 0, 0, 2] = (z ** 2) * (w ** 2 + 1.0 / w ** 2)
    A[0, 2, 2, 0] = (z ** 2) * (w ** 2 + 1.0 / w ** 2)

    # U(1) charge : Q=(-1,0,+1) Q1+Q2=Q3+Q4
    if pars["symmetry_tensors"]:
        dim = [1, 1, 1]
        qim = [-1, 0, 1]
        A = TensorU1.from_ndarray(
            A, shape=[dim] * 4, qhape=[qim] * 4, dirs=[1, 1, -1, -1]
        )
    else:
        A = Tensor.from_ndarray(A)

    # To translate between Roman's convention and mine.
    A = A.transpose((3, 0, 1, 2))
    return A
Esempio n. 10
0
def get_initial_tensor(pars, **kwargs):
    if kwargs:
        pars = pars.copy()
        pars.update(kwargs)
    model_name = pars["model"].strip().lower()
    if model_name == "dilute_sixvertex":
        return get_initial_dilute_sixvertex_tensor(pars)
    elif model_name == "sixvertex":
        return get_initial_sixvertex_tensor(pars)
    elif model_name == "ising3d":
        return get_initial_tensor_ising_3d(pars)
    elif model_name == "potts33d":
        return get_initial_tensor_potts33d(pars)
    elif model_name == "complexion_qising":
        ham = get_ham(pars, model="qising")
        complexion = build_complexion(ham, pars)
        return complexion
    elif model_name == "complexion_qising_tricrit":
        ham = get_ham(pars, model="qising_tricrit")
        complexion = build_complexion(ham, pars)
        return complexion
    elif model_name == "complexion_sq_qising":
        ham = get_ham(pars, model="qising")
        complexion = build_complexion(ham, pars, square_hamiltonian=True)
        return complexion
    else:
        ham = hamiltonians[model_name](pars)
        boltz = np.exp(-pars["beta"] * ham)
        A_0 = np.einsum("ab,bc,cd,da->abcd", boltz, boltz, boltz, boltz)
        u = symmetry_bases[model_name]
        u_dg = u.T.conjugate()
        A_0 = ncon(
            (A_0, u, u, u_dg, u_dg),
            ([1, 2, 3, 4], [-1, 1], [-2, 2], [3, -3], [4, -4]),
        )
        if pars["symmetry_tensors"]:
            cls, dim, qim = symmetry_classes_dims_qims[model_name]
            A_0 = cls.from_ndarray(
                A_0, shape=[dim] * 4, qhape=[qim] * 4, dirs=[1, 1, -1, -1]
            )
        else:
            A_0 = Tensor.from_ndarray(A_0)
    return A_0
Esempio n. 11
0
def get_initial_tensor_potts33d(pars):
    beta = pars["beta"]
    Q = potts_Q(beta, 3)
    A = np.einsum(
        "ai,aj,ak,al,am,an -> ijklmn",
        Q,
        Q,
        Q.conjugate(),
        Q.conjugate(),
        Q,
        Q.conjugate(),
    )
    if np.linalg.norm(np.imag(A)) < 1e-12:
        A = np.real(A)
    if pars["symmetry_tensors"]:
        cls, dim, qim = symmetry_classes_dims_qims["potts3"]
        A = cls.from_ndarray(
            A, shape=[dim] * 6, qhape=[qim] * 6, dirs=[1, 1, -1, -1, 1, -1]
        )
    else:
        A = Tensor.from_ndarray(A)
    return A
Esempio n. 12
0
def get_KW_tensor(pars):
    """ The Kramers-Wannier duality defect of the classical 2D
    square lattice Ising model.
    """
    eye = np.eye(2, dtype=np.complex_)
    ham = hamiltonians["ising"](pars)
    B = np.exp(-pars["beta"] * ham)
    H = np.array([[1, 1], [1, -1]], dtype=np.complex_) / np.sqrt(2)
    y_trigged = np.ndarray((2, 2, 2), dtype=np.complex_)
    y_trigged[:, :, 0] = eye
    y_trigged[:, :, 1] = sigma("y")
    D_sigma = np.sqrt(2) * np.einsum(
        "ab,abi,ic,ad,adk,kc->abcd",
        B,
        y_trigged,
        H,
        B,
        y_trigged.conjugate(),
        H,
    )

    u = symmetry_bases["ising"]
    u_dg = u.T.conjugate()
    D_sigma = ncon(
        (D_sigma, u, u, u_dg, u_dg),
        ([1, 2, 3, 4], [-1, 1], [-2, 2], [3, -3], [4, -4]),
    )
    if pars["symmetry_tensors"]:
        D_sigma = TensorZ2.from_ndarray(
            D_sigma,
            shape=[[1, 1]] * 4,
            qhape=[[0, 1]] * 4,
            dirs=[1, 1, -1, -1],
        )
    else:
        D_sigma = Tensor.from_ndarray(D_sigma, dirs=[1, 1, -1, -1])
    return D_sigma