def test_CRZ() -> None: theta = 0.23 gate0 = qf.CRZ(theta, 0, 1) coords = qf.canonical_coords(gate0) assert np.isclose(coords[0], 0.5 * theta / np.pi) assert np.isclose(coords[1], 0.0) assert np.isclose(coords[2], 0.0) coords = qf.canonical_coords(gate0**3.3) assert np.isclose(coords[0], 3.3 * 0.5 * theta / np.pi) gate1 = qf.Circuit([qf.CRZ(theta, 0, 1), qf.CRZ(theta, 0, 1).H]).asgate() assert qf.almost_identity(gate1)
def test_PauliGate() -> None: pauli0 = 0.5 * np.pi * qf.sX(0) * qf.sX(1) alpha = 0.4 circ = qf.PauliGate(pauli0, alpha) coords = qf.canonical_coords(circ.asgate()) assert np.isclose(coords[0], 0.4) pauli1 = np.pi * qf.sX(0) * qf.sX(1) * qf.sY(2) * qf.sZ(3) _ = qf.PauliGate(pauli1, alpha) top2 = nx.star_graph(4) pauli2 = 0.5 * np.pi * qf.sX(1) * qf.sY(2) * qf.sZ(3) _ = qf.PauliGate(pauli2, alpha).decompose(top2) alpha = 0.2 top3 = nx.star_graph(4) pauli3 = 0.5 * np.pi * qf.sX(1) * qf.sX(2) circ3 = qf.Circuit(qf.PauliGate(pauli3, alpha).decompose(top3)) assert qf.circuits_close(circ3, qf.Circuit([qf.I(0), qf.XX(alpha, 1, 2)])) qf.PauliGate(qf.sI(0), alpha).decompose(top2) with pytest.raises(ValueError): pauli4 = 0.5j * np.pi * qf.sX(1) * qf.sX(2) _ = qf.Circuit(qf.PauliGate(pauli4, alpha).decompose(top3)) top4 = nx.DiGraph() nx.add_path(top4, [3, 2, 1, 0]) _ = qf.Circuit(qf.PauliGate(pauli3, alpha).decompose(top4))
def test_canonical_decomposition(): for tt1 in range(0, 10): for tt2 in range(tt1): for tt3 in range(tt2): t1, t2, t3 = tt1 / 20, tt2 / 20, tt3 / 20 if t3 == 0 and t1 > 0.5: continue coords = np.asarray((t1, t2, t3)) print('b') circ0 = qf.Circuit() circ0 += qf.ZYZ(0.2, 0.2, 0.2, q0=0) circ0 += qf.ZYZ(0.3, 0.3, 0.3, q0=1) circ0 += qf.CANONICAL(t1, t2, t3, 0, 1) circ0 += qf.ZYZ(0.15, 0.2, 0.3, q0=0) circ0 += qf.ZYZ(0.15, 0.22, 0.3, q0=1) gate0 = circ0.asgate() print('c') circ1 = qf.canonical_decomposition(gate0) assert qf.gates_close(gate0, circ1.asgate()) print('d') print(circ1) canon = circ1.elements[6] new_coords = np.asarray( [canon.params[n] for n in ['tx', 'ty', 'tz']]) assert np.allclose(coords, np.asarray(new_coords)) coords2 = qf.canonical_coords(gate0) assert np.allclose(coords, np.asarray(coords2)) print('>') print()
def test_canonical_decomposition() -> None: for tt1 in range(0, 6): for tt2 in range(tt1): for tt3 in range(tt2): t1, t2, t3 = tt1 / 12, tt2 / 12, tt3 / 12 if t3 == 0 and t1 > 0.5: continue coords = np.asarray((t1, t2, t3)) circ0 = qf.Circuit() circ0 += qf.RandomGate([0]) circ0 += qf.RandomGate([1]) circ0 += qf.Can(t1, t2, t3, 0, 1) circ0 += qf.RandomGate([0]) circ0 += qf.RandomGate([1]) gate0 = circ0.asgate() circ1 = qf.canonical_decomposition(gate0) assert qf.gates_close(gate0, circ1.asgate()) canon = circ1[1] new_coords = np.asarray( [canon.param(n) for n in ["tx", "ty", "tz"]]) assert np.allclose(coords, np.asarray(new_coords)) coords2 = qf.canonical_coords(gate0) assert np.allclose(coords, np.asarray(coords2))
def sandwich_decompositions(coords0, coords1, samples=SAMPLES): """Create composite gates, decompose, and return a list of canonical coordinates""" decomps = [] for _ in range(samples): circ = qf.Circuit() circ += qf.Can(*coords0, 0, 1) circ += qf.RandomGate([0]) circ += qf.RandomGate([1]) circ += qf.Can(*coords1, 0, 1) gate = circ.asgate() coords = qf.canonical_coords(gate) decomps.append(coords) return decomps