def test_ising_model_with_field(self, cyclic): p = qtn.MPS_computational_state('0000100000', cyclic=cyclic) pd = p.to_dense() H_nni = qtn.NNI_ham_ising(10, j=4, bx=1, cyclic=cyclic) H_mpo = qtn.MPO_ham_ising(10, j=4, bx=1, cyclic=cyclic) H = qu.ham_ising(10, jz=4, bx=1, cyclic=cyclic) tebd = qtn.TEBD(p, H_nni, tol=1e-6) tebd.split_opts['cutoff'] = 1e-9 tebd.split_opts['cutoff_mode'] = 'rel' evo = qu.Evolution(pd, H) e0 = qu.expec(pd, H) e0_mpo = qtn.expec_TN_1D(p.H, H_mpo, p) assert e0_mpo == pytest.approx(e0) tf = 2 ts = np.linspace(0, tf, 21) evo.update_to(tf) for pt in tebd.at_times(ts): assert isinstance(pt, qtn.MatrixProductState) assert (pt.H @ pt) == pytest.approx(1.0, rel=1e-5) assert (qu.expec(tebd.pt.to_dense(), evo.pt) == pytest.approx(1.0, rel=1e-5)) ef_mpo = qtn.expec_TN_1D(tebd.pt.H, H_mpo, tebd.pt) assert ef_mpo == pytest.approx(e0, 1e-5)
def test_OTOC_local(): L = 10 psi0 = qtn.MPS_computational_state('0' * L, cyclic=True) H1 = qtn.NNI_ham_ising(L, j=4, bx=0, cyclic=True) H_back1 = qtn.NNI_ham_ising(L, j=-4, bx=0, cyclic=True) H2 = qtn.NNI_ham_ising(L, j=4, bx=1, cyclic=True) H_back2 = qtn.NNI_ham_ising(L, j=-4, bx=-1, cyclic=True) A = qu.pauli('z') ts = np.linspace(1, 2, 2) OTOC_t = [] for OTOC in OTOC_local(psi0, H1, H_back1, ts, 5, A, tol=1e-5, split_opts={ 'cutoff': 1e-5, 'cutoff_mode': 'rel' }, initial_eigenstate='check'): OTOC_t += [OTOC] assert OTOC_t[0] == pytest.approx(1.0) assert OTOC_t[1] == pytest.approx(1.0) x_t = [] for x in OTOC_local(psi0, H2, H_back2, ts, 5, A, tol=1e-5, split_opts={ 'cutoff': 1e-5, 'cutoff_mode': 'rel' }, initial_eigenstate='check'): x_t += [x] assert x_t[0] == pytest.approx(0.52745, 1e-5) assert x_t[1] == pytest.approx(0.70440, 1e-5)
def CLTNRepHWQC(nq, nr, p): px = 0.004 kappa2 = 10**7 alpha2 = 8 pi1 = [1 - 10 * p, 10 * p] pi2 = [1 - 0.299 * (p**0.5), 0.299 * (p**0.5)] p3 = p * kappa2 * alpha2 * (350 * (10**(-9)) + (10 / (kappa2 * alpha2))) pi3 = [1 - p3, p3] pz1 = 0.845 * (p**0.5) pz2 = 0.133 * (p**0.5) pz1z2 = 0.133 * (p**0.5) pm = [1 - px, px] pp = [1 - 15 * p / 2, 15 * p / 2] perf = [1, 0] ptq = [1 - pz1 - pz2 - pz1z2, pz1, pz2, pz1z2] #print(psq) #print(ptq) #print(pm) #print(pp) gh0 = format(0, 'b').zfill(nq + 1) gh1 = format(2**(nq + 1) - 1, 'b').zfill(nq + 1) ghz = (qtn.MPS_computational_state(gh0) + qtn.MPS_computational_state(gh1)) ghz = ghz.contract(all) ghzd = ghz.data for r in range(0, nr): if r == 0: tagsD = ('D{:d}T0'.format(nq - 1)) indsD = ('d{:d}g0'.format(nq - 1), ) TN = qtn.Tensor(DTermWait(pi1), indsD, tagsD) for dq in range(0, nq - 1): tagsD = ('D{:d}T0'.format(dq)) indsD = ('d{:d}g0'.format(dq), ) TN = TN & qtn.Tensor(DTermWait(pi1), indsD, tagsD) else: for dq in range(0, nq): tagsD = ('D{:d}T{:d}'.format(dq, 4 * r)) indsD = ('d{:d}g{:d}'.format(dq, 4 * r - 1), 'd{:d}g{:d}'.format(dq, 4 * r)) TN = TN & qtn.Tensor(IdTensor(perf), indsD, tagsD) for aq in range(0, nq - 1): tagsA = ('A{:d}T{:d}'.format(aq, 4 * r)) indsA = ('sf{:d}r{:d}'.format(aq, r), 'a{:d}g{:d}'.format(aq, 4 * r)) TN = TN & qtn.Tensor(APrepTensor1(pp), indsA, tagsA) #first round of CNOTs for aq in range(0, nq - 1): tagsD = ('D{:d}A{:d}T{:d}'.format(aq, aq, 4 * r + 1)) indsD = ('d{:d}g{:d}'.format(aq, 4 * r), 'a{:d}g{:d}'.format( aq, 4 * r), 'd{:d}g{:d}'.format(aq, 4 * r + 1), 'a{:d}g{:d}'.format(aq, 4 * r + 1)) TN = TN & qtn.Tensor(RepCNOTTensorHW(ptq), indsD, tagsD) tagsD = ('D{:d}T{:d}'.format(nq - 1, 4 * r + 1)) indsD = ('d{:d}g{:d}'.format(nq - 1, 4 * r), 'd{:d}g{:d}'.format(nq - 1, 4 * r + 1)) TN = TN & qtn.Tensor(IdTensor(pi2), indsD, tagsD) #second round of CNOTs for aq in range(0, nq - 1): tagsD = ('D{:d}A{:d}T{:d}'.format(aq + 1, aq, 4 * r + 2)) indsD = ('d{:d}g{:d}'.format(aq + 1, 4 * r + 1), 'a{:d}g{:d}'.format(aq, 4 * r + 1), 'd{:d}g{:d}'.format( aq + 1, 4 * r + 2), 'a{:d}g{:d}'.format(aq, 4 * r + 2)) TN = TN & qtn.Tensor(RepCNOTTensorHW(ptq), indsD, tagsD) tagsD = ('D{:d}T{:d}'.format(0, 4 * r + 2)) indsD = ('d{:d}g{:d}'.format(0, 4 * r + 1), 'd{:d}g{:d}'.format(0, 4 * r + 2)) TN = TN & qtn.Tensor(IdTensor(pi2), indsD, tagsD) #measurement round/wait locations #first do the terminal data wait locations if r == nr - 1: for dq in range(0, nq): tagsD = ('D{:d}T{:d}'.format(dq, 4 * r + 3)) indsD = ('d{:d}g{:d}'.format(dq, 4 * r + 2), 'd{:d}g{:d}'.format(dq, 4 * r + 3)) TN = TN & qtn.Tensor(IdTensor(pm), indsD, tagsD) for dq in range(0, (nq - 1) // 2): tagsD = ('D{:d}T{:d}'.format(dq, 4 * r + 4)) indsD = ('d{:d}g{:d}'.format(dq, 4 * r + 3), 'd{:d}lz'.format(dq), 'd{:d}p'.format(dq)) TN = TN & qtn.Tensor(DatTermTensor(pi3), indsD, tagsD) tagsD = ('D{:d}T{:d}'.format((nq - 1) // 2, 4 * r + 4)) indsD = ('d{:d}g{:d}'.format( (nq - 1) // 2, 4 * r + 3), 'd{:d}lz'.format((nq - 1) // 2)) TN = TN & qtn.Tensor(IdTensor(pi3), indsD, tagsD) for dq in range(((nq - 1) // 2) + 1, nq): tagsD = ('D{:d}T{:d}'.format(dq, 4 * r + 4)) indsD = ('d{:d}g{:d}'.format(dq, 4 * r + 3), 'd{:d}lz'.format(dq), 'd{:d}p'.format(dq - 1)) TN = TN & qtn.Tensor(DatTermTensor(pi3), indsD, tagsD) else: for dq in range(0, (nq - 1) // 2): tagsD = ('D{:d}T{:d}'.format(dq, 4 * r + 3)) indsD = ('d{:d}g{:d}'.format(dq, 4 * r + 2), 'd{:d}g{:d}'.format(dq, 4 * r + 3)) TN = TN & qtn.Tensor(IdTensor(pi3), indsD, tagsD) tagsD = ('D{:d}T{:d}'.format((nq - 1) // 2, 4 * r + 3)) indsD = ('d{:d}g{:d}'.format( (nq - 1) // 2, 4 * r + 2), 'd{:d}g{:d}'.format((nq - 1) // 2, 4 * r + 3)) TN = TN & qtn.Tensor(IdTensor(pi3), indsD, tagsD) for dq in range(((nq - 1) // 2) + 1, nq): tagsD = ('D{:d}T{:d}'.format(dq, 4 * r + 3)) indsD = ('d{:d}g{:d}'.format(dq, 4 * r + 2), 'd{:d}g{:d}'.format(dq, 4 * r + 3)) TN = TN & qtn.Tensor(IdTensor(pi3), indsD, tagsD) #now do the ancilla measurement failure locations for aq in range(0, nq - 1): tagsA = ('A{:d}T{:d}'.format(aq, 4 * r + 3)) indsA = ('a{:d}g{:d}'.format(aq, 4 * r + 2), ) TN = TN & qtn.Tensor(AMeasTensor1(pm), indsA, tagsA) #finally, put in the logical control tensor tagsL = ('LZ') indsL = ('lz', ) for dq in range(0, nq): indsL = indsL + ('d{:d}lz'.format(dq), ) TN = TN & qtn.Tensor(ghzd, indsL, tagsL) return TN
def CLTNRepHWTraceMeas(nq, nr, p): #First initialize all HW noise parameters. Note that p=k1/k2 pxm = 0.004 #X readout failure probability kappa2 = 10**7 alpha2 = 8 #photon number p1 = 10 * p #fail prob for data qubit wait location during very first ancilla initialization p2 = 0.299 * ( p**0.5 ) #fail prob for data qubit wait location during execution of a CNOT on other qubits p3 = p * kappa2 * alpha2 * ( 350 * (10**(-9)) + (10 / (kappa2 * alpha2)) ) #fail prob for data qubit wait location during readout of ancilla pz1 = 0.845 * ( p**0.5 ) #prob of z1 otimes I failure after CNOT (qubit 1 is control, 2 is target) pz2 = 0.133 * ( p**0.5 ) #prob of I otimes z2 failure after CNOT (qubit 1 is control, 2 is target) pz1z2 = 0.133 * (p**0.5) #prob of z1 otimes z2 failure after CNOT #create probability distributions to be passed to local tensor constructors which model different locations pi1 = [1 - p1, p1] #data qubit wait during first ancilla init pi2 = [1 - p2, p2] #data qubit wait during CNOT pi3 = [1 - p3, p3] #data qubit wait during ancilla measurement and re-init pm = [1 - pxm, pxm] #X measurement location pp = [1 - 15 * p / 2, 15 * p / 2] #ancilla initialization perf = [1, 0] #perfect wait location ptq = [1 - pz1 - pz2 - pz1z2, pz1, pz2, pz1z2] #CNOT location gh0 = format(0, 'b').zfill(nq + 1) gh1 = format(2**(nq + 1) - 1, 'b').zfill(nq + 1) ghz = (qtn.MPS_computational_state(gh0) + qtn.MPS_computational_state(gh1)) ghz = ghz.contract(all) ghzd = ghz.data for r in range(0, nr): if r == 0: tagsD = ('D{:d}T0'.format(nq - 1)) indsD = ('d{:d}g0'.format(nq - 1), ) TN = qtn.Tensor(DTermWait(pi1), indsD, tagsD) for dq in range(0, nq - 1): tagsD = ('D{:d}T0'.format(dq)) indsD = ('d{:d}g0'.format(dq), ) TN = TN & qtn.Tensor(DTermWait(pi1), indsD, tagsD) else: for dq in range(0, nq): tagsD = ('D{:d}T{:d}'.format(dq, 4 * r)) indsD = ('d{:d}g{:d}'.format(dq, 4 * r - 1), 'd{:d}g{:d}'.format(dq, 4 * r)) TN = TN & qtn.Tensor(IdTensor(perf), indsD, tagsD) for aq in range(0, nq - 1): tagsA = ('A{:d}T{:d}'.format(aq, 4 * r)) indsA = ('sf{:d}r{:d}'.format(aq, r), 'a{:d}g{:d}'.format(aq, 4 * r)) TN = TN & qtn.Tensor(APrepTensor1(pp), indsA, tagsA) tagsST = ('A{:d}T{:d}TR'.format(aq, 4 * r)) indsST = ('sf{:d}r{:d}'.format(aq, r), ) TN = TN & qtn.Tensor(np.ones(2), indsST, tagsST) #first round of CNOTs for aq in range(0, nq - 1): tagsD = ('D{:d}A{:d}T{:d}'.format(aq, aq, 4 * r + 1)) indsD = ('d{:d}g{:d}'.format(aq, 4 * r), 'a{:d}g{:d}'.format( aq, 4 * r), 'd{:d}g{:d}'.format(aq, 4 * r + 1), 'a{:d}g{:d}'.format(aq, 4 * r + 1)) TN = TN & qtn.Tensor(RepCNOTTensorHW(ptq), indsD, tagsD) tagsD = ('D{:d}T{:d}'.format(nq - 1, 4 * r + 1)) indsD = ('d{:d}g{:d}'.format(nq - 1, 4 * r), 'd{:d}g{:d}'.format(nq - 1, 4 * r + 1)) TN = TN & qtn.Tensor(IdTensor(pi2), indsD, tagsD) #second round of CNOTs for aq in range(0, nq - 1): tagsD = ('D{:d}A{:d}T{:d}'.format(aq + 1, aq, 4 * r + 2)) indsD = ('d{:d}g{:d}'.format(aq + 1, 4 * r + 1), 'a{:d}g{:d}'.format(aq, 4 * r + 1), 'd{:d}g{:d}'.format( aq + 1, 4 * r + 2), 'a{:d}g{:d}'.format(aq, 4 * r + 2)) TN = TN & qtn.Tensor(RepCNOTTensorHW(ptq), indsD, tagsD) tagsD = ('D{:d}T{:d}'.format(0, 4 * r + 2)) indsD = ('d{:d}g{:d}'.format(0, 4 * r + 1), 'd{:d}g{:d}'.format(0, 4 * r + 2)) TN = TN & qtn.Tensor(IdTensor(pi2), indsD, tagsD) #measurement round/wait locations #first do the terminal data wait locations if r == nr - 1: for dq in range(0, (nq - 1) // 2): tagsD = ('D{:d}T{:d}'.format(dq, 4 * r + 3)) indsD = ('d{:d}g{:d}'.format(dq, 4 * r + 2), 'd{:d}lz'.format(dq), 'd{:d}p'.format(dq)) TN = TN & qtn.Tensor(DatTermTensor(pi3), indsD, tagsD) tagsD = ('D{:d}T{:d}'.format((nq - 1) // 2, 4 * r + 3)) indsD = ('d{:d}g{:d}'.format( (nq - 1) // 2, 4 * r + 2), 'd{:d}lz'.format((nq - 1) // 2)) TN = TN & qtn.Tensor(IdTensor(pi3), indsD, tagsD) for dq in range(((nq - 1) // 2) + 1, nq): tagsD = ('D{:d}T{:d}'.format(dq, 4 * r + 3)) indsD = ('d{:d}g{:d}'.format(dq, 4 * r + 2), 'd{:d}lz'.format(dq), 'd{:d}p'.format(dq - 1)) TN = TN & qtn.Tensor(DatTermTensor(pi3), indsD, tagsD) else: for dq in range(0, (nq - 1) // 2): tagsD = ('D{:d}T{:d}'.format(dq, 4 * r + 3)) indsD = ('d{:d}g{:d}'.format(dq, 4 * r + 2), 'd{:d}g{:d}'.format(dq, 4 * r + 3)) TN = TN & qtn.Tensor(IdTensor(pi3), indsD, tagsD) tagsD = ('D{:d}T{:d}'.format((nq - 1) // 2, 4 * r + 3)) indsD = ('d{:d}g{:d}'.format( (nq - 1) // 2, 4 * r + 2), 'd{:d}g{:d}'.format((nq - 1) // 2, 4 * r + 3)) TN = TN & qtn.Tensor(IdTensor(pi3), indsD, tagsD) for dq in range(((nq - 1) // 2) + 1, nq): tagsD = ('D{:d}T{:d}'.format(dq, 4 * r + 3)) indsD = ('d{:d}g{:d}'.format(dq, 4 * r + 2), 'd{:d}g{:d}'.format(dq, 4 * r + 3)) TN = TN & qtn.Tensor(IdTensor(pi3), indsD, tagsD) #now do the ancilla measurement failure locations for aq in range(0, nq - 1): tagsA = ('A{:d}T{:d}'.format(aq, 4 * r + 3)) indsA = ('a{:d}g{:d}'.format(aq, 4 * r + 2), ) TN = TN & qtn.Tensor(AMeasTensor1(pm), indsA, tagsA) #finally, put in the logical control tensor tagsL = ('LZ') indsL = ('lz', ) for dq in range(0, nq): indsL = indsL + ('d{:d}lz'.format(dq), ) TN = TN & qtn.Tensor(ghzd, indsL, tagsL) return TN
sequence='ABCDCDAB', swap_trick=False ): file = f'circuit_n{n}_m{depth}_s{seed}_e{elided}_p{sequence}.qsim' if swap_trick: gate_opts={'contract': 'swap-split-gate', 'max_bond': 2} else: gate_opts={} # instantiate the `Circuit` object that # constructs the initial tensor network: return qtn.Circuit.from_qasm_file(file, gate_opts=gate_opts) circ = load_circuit(depth=10) psi_f = qtn.MPS_computational_state('0' * (circ.N)) tn = circ.psi & psi_f output_inds = [] # inplace full simplify and cast to single precision tn.full_simplify_(output_inds=output_inds) tn.astype_('complex64') opt = ctg.HyperOptimizer( # methods=['kahypar', 'greedy', 'walktrap'], methods = ['greedy','kahypar'], max_repeats=128, progbar=True, minimize='flops', score_compression=0.5, # deliberately make the optimizer try many methods