Exemple #1
0
def rule_op(V, R, r, d, totalistic=False, hamiltonian=False):
    """
    Operator for rule R, activation V, and neighborhood radius r, and dimension d.
    hamiltonian flag for simultaion type (hamiltonian=analog, unitary=digital)
    """
    N = 2 * r * d
    OP = np.zeros((2 ** (N + 1), 2 ** (N + 1)), dtype=complex)
    if totalistic:
        R2 = mx.dec_to_bin(R, N + 1)[::-1]
    else:
        R2 = mx.dec_to_bin(R, 2 ** N)[::-1]
    for elnum, Rel in enumerate(R2):
        if totalistic:
            K = elnum * [1] + (N - elnum) * [0]
            hoods = list(set([perm for perm in permutations(K, N)]))
            hoods = map(list, hoods)
        else:
            hoods = [mx.dec_to_bin(elnum, N)]
        for hood in hoods:
            OP += rule_element(V, Rel, hood, hamiltonian=hamiltonian)
    if hamiltonian:
        assert mx.isherm(OP)
    else:  # unitaty
        assert mx.isU(OP)
    return OP
Exemple #2
0
def boundary_rule_ops(V, R, r, BC_conf, totalistic=False, hamiltonian=False):
    """
    Special operators for boundaries (of which there are 2r).
    BC_conf is a string "b0b1...br...b2r" where each bj is
    either 0 or 1. Visiually, BC_conf represents the fixed boundaries
    from left to right: |b0>|b1>...|br> |psi>|b2r-r>|b2r-r+1>...|b2r>.
    """
    # split BC configuration into left and reverse-right boundaries
    BC_conf = [BC_conf[:r], BC_conf[r::][::-1]]
    N = 2 * r
    OPs = []
    for j, BC in enumerate(BC_conf):
        for e in range(r):
            dim = r + 1 + e
            if j == 0:  # left boundary
                lslice = slice(r - e, r)
                rslice = slice(r, N)
                cslice = slice(0, r - e)
            elif j == 1:  # right boundary
                lslice = slice(0, r)
                rslice = slice(r, r + e)
                cslice = slice(r + e, N)
            OP = np.zeros((2**dim, 2**dim), dtype=complex)
            if totalistic:
                R2 = mx.dec_to_bin(R, N + 1)[::-1]
                for elnum, Rel in enumerate(R2):
                    K = elnum * [1] + (N - elnum) * [0]
                    hoods = list(set([perm for perm in permutations(K, N)]))
                    hoods = map(list, hoods)
                    for hood in hoods:
                        if BC[e:r] == hood[cslice]:
                            OP += rule_element(
                                V,
                                Rel,
                                hood,
                                lslice=lslice,
                                rslice=rslice,
                                hamiltonian=hamiltonian,
                            )

            else:  # non-totalistic
                R2 = mx.dec_to_bin(R, 2**N)[::-1]
                for elnum, Rel in enumerate(R2):
                    hood = mx.dec_to_bin(elnum, N)
                    if BC[e:r] == hood[cslice]:
                        OP += rule_element(
                            V,
                            Rel,
                            hood,
                            lslice=lslice,
                            rslice=rslice,
                            hamiltonian=hamiltonian,
                        )
            if hamiltonian:
                assert mx.isherm(OP)
            else:  # unitaty
                assert mx.isU(OP)
            OPs.append(OP)
    return OPs[:r], OPs[r:][::-1]
Exemple #3
0
def boundary_rule_ops(V, R, r, d, BC_conf, totalistic=False, hamiltonian=False):
    """
    Special operators for boundaries (of which there are 2r).
    BC_conf is a string "b0b1...br...b2r" where each bj is
    either 0 or 1. Visiually, BC_conf represents the fixed boundaries
    from left to right: |b0>|b1>...|br> |psi>|b2r-r>|b2r-r+1>...|b2r>.
    """
    BC_conf = np.array([int(s) for s in BC_conf])
    OPs = []
    N = 2 * r * d
    if totalistic:
        R2 = mx.dec_to_bin(R, N + 1)[::-1]
    else:
        R2 = mx.dec_to_bin(R, 2 ** N)[::-1]

    indsj = [np.arange(r), np.array([r]), np.arange(r+1, 2*r+1)]
    dj = 2*r + 1
    if d == 2:
        indsk = indsj
        dk = 2*r + 1
    elif d ==1:
        indsk = [[0]]
        dk =1
    OPs = []
    for J, js in enumerate(indsj):
        for K, ks in enumerate(indsk):
            OPs_region = []
            for j in js:
                OPs_row = []
                for k in ks:
                    mask = make_mask(j, k, dj, dk, r, d, BC_type="1")
                    clip = np.logical_not(mask)
                    if np.sum(clip) > 0:
                        dim = np.sum(mask)+1
                        OP = np.zeros((2 ** dim, 2 ** dim), dtype=complex)
                        for elnum, Rel in enumerate(R2):
                            if totalistic:
                                tot = elnum * [1] + (N - elnum) * [0]
                                hoods = list(set([perm for perm in permutations(tot, N)]))
                                hoods = map(np.array, hoods)
                            else:
                                hoods = np.array([mx.dec_to_bin(elnum, N)])
                            for hood in hoods:
                                if np.all(BC_conf[clip] == hood[clip]):
                                    OP += rule_element(
                                        V,
                                        Rel,
                                        hood[mask],
                                        hamiltonian=hamiltonian,
                                    )
                        if hamiltonian:
                            assert mx.isherm(OP)
                        else:  # unitaty
                            assert mx.isU(OP)
                        OPs_row.append(OP)
                OPs_region.append(OPs_row)
            if len(OPs_region[0]) > 0:
                OPs.append(OPs_region)
    return OPs
Exemple #4
0
def make_H(L, R, V):
    H = np.zeros((2**L, 2**L), dtype=np.complex128)
    if type(V) is not str:
        ops['V'] = V
        V = 'V'
    bulks = []
    lbs = []
    rbs = []
    for s, b in enumerate(mx.dec_to_bin(R, 4)[::-1]):
        if b:
            r = mx.dec_to_bin(s, 2)
            if r[1] == 0:
                rbs += [str(r[0]) + V]
            if r[0] == 0:
                lbs += [V + str(r[1])]
            bulks += [str(r[0]) + V + str(r[1])]

    #print('rule', R, mx.dec_to_bin(R, 4), lbs, bulks, rbs)
    for i in range(1, L - 1):
        l = i - 1
        r = L - 3 - l
        left = np.eye(2**l)
        right = np.eye(2**r)
        for bulk in bulks:
            bulk = mx.listkron([ops[o] for o in bulk])
            H += mx.listkron([left, bulk, right])

    # boundaries
    end = np.eye(2**(L - 2))
    for rb in rbs:
        rb = mx.listkron([ops[o] for o in rb])
        #H += mx.listkron([end, rb])

    for lb in lbs:
        lb = mx.listkron([ops[o] for o in lb])
        #H += mx.listkron([lb, end])

    assert mx.isherm(H)
    return H