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
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]
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
def make_U(V, r, S): N = 2 * r Sb = mx.dec_to_bin(S, 2**N)[::-1] U = np.zeros((2**(N + 1), 2**(N + 1)), dtype=complex) for sig, s in enumerate(Sb): sigb = mx.dec_to_bin(sig, N) Vmat = get_V(V, s) ops = ([mx.ops[str(op)] for op in sigb[0:r]] + [Vmat] + [mx.ops[str(op)] for op in sigb[r:2 * r + 1]]) U += mx.listkron(ops) if not mx.isU(U): raise AssertionError return U
def cluster_all(L, config): state = np.zeros(2**L, dtype=np.complex128) for k in range(2**L): b = dec_to_bin(k, L) c = 1.0 for j in range(L - 1): c *= (-1)**(b[j] * b[j + 1]) state += c * listkron([bvecs[str(bj)] for bj in b]) return state / 2**(L / 2)
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
def make_boundary_Us(V, r, S, BC_conf): BC_conf = list(map(int, BC_conf)) N = 2 * r Sb = mx.dec_to_bin(S, 2**N)[::-1] bUs = [] for w in (0, 1): fixed_o = list(BC_conf[w * r:r + w * r]) for c in range(r): U = np.zeros((2**(r + 1 + c), 2**(r + 1 + c)), dtype=complex) for i in range(2**(r + c)): if w == 0: var = mx.dec_to_bin(i, r + c) var1 = var[:c] var2 = var[c:] fixed = fixed_o[c:r] n = fixed + var1 + var2 s = Sb[mx.bin_to_dec(n)] Vmat = get_V(V, s) ops = ([mx.ops[str(op)] for op in var1] + [Vmat] + [mx.ops[str(op)] for op in var2]) elif w == 1: var = mx.dec_to_bin(i, r + c) var1 = var[c:] var2 = var[:c] fixed = fixed_o[0:r - c] n = var1 + var2 + fixed s = Sb[mx.bin_to_dec(n)] Vmat = get_V(V, s) ops = ([mx.ops[str(op)] for op in var1] + [Vmat] + [mx.ops[str(op)] for op in var2]) U += mx.listkron(ops) bUs.append(U) return bUs
plt.plot(th, sz(const_th)) plt.legend() #plt.show() # update op # --------- for R in range(256): T = sweep.local_update_op(R) I = np.eye(8) Tdag = mx.dagger(T) TdT = Tdag.dot(T) TTd = T.dot(Tdag) unitaryQ = np.array_equal(TdT, I) and np.array_equal(TTd, I) if unitaryQ is True: print(R, mx.dec_to_bin(R ^ 204, 8)) #print(T) fixed_params_dict = { 'output_name': ['sweep_block_4'], 'mode': ['sweep', 'block'], 'R': [150, 102], 'IC': ['s18'], 'L': [19], 'tmax': [1000] } var_params_dict = {'center_op': [['H'], ['H', 'T'], ['H', 'X', 'T']]} def concat_dicts(d1, d2):