def test_separate_measures(self): prog = Program() qreg = prog.qalloc(3) creg = prog.calloc(3) prog.apply(H, qreg[0]) prog.apply(H, qreg[1]) prog.apply(H, qreg[2]) expected = prog.to_circ() result = Prg() cbs = result.declare("ro", "BIT", 3) result += pg.H(0) result += pg.H(1) result += pg.H(2) result += pg.MEASURE(0, cbs[0]) result += pg.MEASURE(1, cbs[1]) result += pg.MEASURE(2, cbs[2]) result, to_measure = pyquil_to_qlm(result, True) exp_str = print_aq(expected) res_str = print_aq(result) self.assertEqual(res_str, exp_str) self.assertEqual(to_measure, [0, 1, 2])
def test_load_program_via_entry_point(self): """Test that a pyquil Program instance can be loaded via the load entrypoint.""" program = pyquil.Program() program += g.H(0) program += g.RZ(0.34, 1) program += g.CNOT(0, 3) program += g.H(2) program += g.H(7) program += g.X(7) program += g.Y(1) program += g.RZ(0.34, 1) with OperationRecorder() as rec: qml.load(program, format="pyquil_program")(wires=range(5)) # The wires should be assigned as # 0 1 2 3 7 # 0 1 2 3 4 expected_queue = [ qml.Hadamard(0), qml.RZ(0.34, wires=[1]), qml.CNOT(wires=[0, 3]), qml.Hadamard(2), qml.Hadamard(4), qml.PauliX(4), qml.PauliY(1), qml.RZ(0.34, wires=[1]), ] for converted, expected in zip(rec.queue, expected_queue): assert converted.name == expected.name assert converted.wires == expected.wires assert converted.params == expected.params
def test_convert_simple_program(self): """Test that a simple program is properly converted.""" program = pyquil.Program() program += g.H(0) program += g.RZ(0.34, 1) program += g.CNOT(0, 3) program += g.H(2) program += g.H(7) program += g.X(7) program += g.Y(1) program += g.RZ(0.34, 1) with OperationRecorder() as rec: load_program(program)(wires=range(5)) # The wires should be assigned as # 0 1 2 3 7 # 0 1 2 3 4 expected_queue = [ qml.Hadamard(0), qml.RZ(0.34, wires=[1]), qml.CNOT(wires=[0, 3]), qml.Hadamard(2), qml.Hadamard(4), qml.PauliX(4), qml.PauliY(1), qml.RZ(0.34, wires=[1]), ] for converted, expected in zip(rec.queue, expected_queue): assert converted.name == expected.name assert converted.wires == expected.wires assert converted.params == expected.params
def test_convert_simple_program_wire_assignment(self): """Test that the assignment of qubits to wires works as expected.""" program = pyquil.Program() program += g.H(0) program += g.RZ(0.34, 1) program += g.CNOT(0, 3) program += g.H(2) program += g.H(7) program += g.X(7) program += g.Y(1) program += g.RZ(0.34, 1) with OperationRecorder() as rec: load_program(program)(wires=[3, 6, 4, 9, 1]) # The wires should be assigned as # 0 1 2 3 7 # 3 6 4 9 1 expected_queue = [ qml.Hadamard(3), qml.RZ(0.34, wires=[6]), qml.CNOT(wires=[3, 9]), qml.Hadamard(4), qml.Hadamard(1), qml.PauliX(1), qml.PauliY(6), qml.RZ(0.34, wires=[6]), ] for converted, expected in zip(rec.queue, expected_queue): assert converted.name == expected.name assert converted.wires == expected.wires assert converted.params == expected.params
def superdense_coding_program(self, bit0: int, bit1: int): raw_prog = Program() ro = raw_prog.declare('ro', 'BIT', 2) # Prepare Bell pair raw_prog += gates.H(0) raw_prog += gates.CNOT(0, 1) # Alice controls qubit 0 and Bob controls 1 if bit0 == 0 and bit1 == 0: pass if bit0 == 0 and bit1 == 1: raw_prog += gates.X(0) if bit0 == 1 and bit1 == 0: raw_prog += gates.Z(0) if bit0 == 1 and bit1 == 1: raw_prog += gates.X(0) raw_prog += gates.Z(0) # Now Alice sends qubit 0 to Bob # Bob rotates from Bell basis to standard basis raw_prog += gates.CNOT(0, 1) raw_prog += gates.H(0) # Measure qubits into Bob's registers raw_prog += gates.MEASURE(0, ro[0]) raw_prog += gates.MEASURE(1, ro[1]) new_prog = ftqc.rewrite_program(raw_prog, self.steane_7bit) results = self.run_program(new_prog) for result in results: self.assertEqual(result[0], bit0) self.assertEqual(result[1], bit1)
def test_convert_program_with_inverses(self): """Test that a program with inverses is properly converted.""" program = pyquil.Program() program += g.H(0) program += g.RZ(0.34, 1).dagger() program += g.CNOT(0, 3).dagger() program += g.H(2) program += g.H(7).dagger().dagger() program += g.X(7).dagger() program += g.X(7) program += g.Y(1) program += g.RZ(0.34, 1) with OperationRecorder() as rec: load_program(program)(wires=range(5)) expected_queue = [ qml.Hadamard(0), qml.RZ(0.34, wires=[1]).inv(), qml.CNOT(wires=[0, 3]).inv(), qml.Hadamard(2), qml.Hadamard(4), qml.PauliX(4).inv(), qml.PauliX(4), qml.PauliY(1), qml.RZ(0.34, wires=[1]), ] for converted, expected in zip(rec.queue, expected_queue): assert converted.name == expected.name assert converted.wires == expected.wires assert converted.params == expected.params
def tiny_ansatz_2(current_params): "Previously used for Helium VQE in Rigetti implementation" return pyquil.quil.Program(g.X(0), g.X(1), g.RX(np.pi / 2, 0), g.H(1), g.CNOT(0, 1), g.RZ(current_params[0], 1), g.CNOT(0, 1), g.RX(-np.pi / 2, 0), g.H(1), g.H(0), g.RX(np.pi / 2, 1), g.CNOT(0, 1), g.RZ(current_params[1], 1), g.CNOT(0, 1), g.H(0), g.RX(-np.pi / 2, 1))
def test_HZH_program(self): raw_prog = Program() ro = raw_prog.declare('ro', 'BIT', 1) raw_prog += gates.H(0) raw_prog += gates.Z(0) raw_prog += gates.H(0) raw_prog += gates.MEASURE(0, ro[0]) new_prog = ftqc.rewrite_program(raw_prog, self.steane_7bit) results = self.run_program(new_prog) for result in results: self.assertEqual(result[0], 1)
def noisy_encode_plus(self, qubits: List[Union[QubitPlaceholder, int]]) -> Program: """ Construct a program preparing a new logical qubit in the |+> state (+1 eigenstate of \hat X). The qubits must all be reset to the physical |0> state at the beginning of this program. The preparation is not fault tolerant and any physical errors that occur during preparation may create many correlated errors in the code block. """ # See implementation of noisy_encode_zero for more detailed comments. n, r_1, r_2 = self.n, self.r_1, self.r_2 # The idea is that we want to transform the parity check matrix from # # [[ 0 0 0 | I1 0 0 ], [[ I1 A1 A2 | 0 0 0 ], # [ 0 0 0 | 0 I2 0 ], => [ 0 0 0 | D I2 E ], # [ 0 0 0 | 0 0 I3 ]] [ 0 ET I3 | 0 0 0 ]] # The program accumulates the actual operations on the qubits. prog = Program() # Step 1: Apply Hadamards to move I1 and I3 to the X side. Post-state: # # [[ I1 0 0 | 0 0 0 ], # [ 0 0 0 | 0 I2 0 ], # [ 0 0 I3 | 0 0 0 ]] for i in range(r_1): prog += gates.H(qubits[i]) for i in range(r_1 + r_2, n): prog += gates.H(qubits[i]) # Step 2: Copy Z's from I2 to E. This has the side effect of constructing ET. Post-state: # # [[ I1 0 0 | 0 0 0 ], # [ 0 0 0 | 0 I2 E ], # [ 0 ET I3 | 0 0 0 ]] for i in range(r_1, r_1 + r_2): for j in range(r_1 + r_2, n): if self.parity_check_c2[i - r_1, j] == 1: prog += gates.CNOT(qubits[j], qubits[i]) # Step 3: Copy X's from I1 to A1 and A2. This has the side effect of constructing D. # Post-state: # # [[ I1 A1 A2 | 0 0 0 ], # [ 0 0 0 | D I2 E ], # [ 0 ET I3 | 0 0 0 ]] for i in range(r_1): for j in range(r_1, n): if self.parity_check_c1[i, j] == 1: prog += gates.CNOT(qubits[i], qubits[j]) return prog
def test_convert_wire_error(self, wires): """Test that the conversion raises an error if the given number of wires doesn't match the number of qubits in the Program.""" program = pyquil.Program() program += g.H(0) program += g.H(1) program += g.H(2) with pytest.raises( qml.DeviceError, match= "The number of given wires does not match the number of qubits in the PyQuil Program", ): load_program(program)(wires=wires)
def test_convert_simple_program_with_parameters_mixed_keys(self): """Test that a parametrized program is properly converted when the variable map contains mixed key types.""" program = pyquil.Program() alpha = program.declare("alpha", "REAL") beta = program.declare("beta", "REAL") gamma = program.declare("gamma", "REAL") delta = program.declare("delta", "REAL") program += g.H(0) program += g.CNOT(0, 1) program += g.RX(alpha, 1) program += g.RZ(beta, 1) program += g.RX(gamma, 1) program += g.CNOT(0, 1) program += g.RZ(delta, 0) program += g.H(0) a, b, c, d = 0.1, 0.2, 0.3, 0.4 parameter_map = { "alpha": a, beta: b, gamma: c, "delta": d, } with OperationRecorder() as rec: load_program(program)(wires=range(2), parameter_map=parameter_map) expected_queue = [ qml.Hadamard(0), qml.CNOT(wires=[0, 1]), qml.RX(0.1, wires=[1]), qml.RZ(0.2, wires=[1]), qml.RX(0.3, wires=[1]), qml.CNOT(wires=[0, 1]), qml.RZ(0.4, wires=[0]), qml.Hadamard(0), ] for converted, expected in zip(rec.queue, expected_queue): assert converted.name == expected.name assert converted.wires == expected.wires assert converted.params == expected.params
def noisy_encode_zero(self, qubits: List[Union[QubitPlaceholder, int]]) -> Program: """ Construct a program preparing a new logical qubit in the |0> state (+1 eigenstate of \hat Z). The qubits must all be reset to the physical |0> state at the beginning of this program. The preparation is not fault tolerant and any physical errors that occur during preparation may create many correlated errors in the code block. """ n, r_1, r_2 = self.n, self.r_1, self.r_2 # We are starting with all qubits in the |0> state, meaning they are stabilised by # Z_1, Z_2, ..., Z_n. We want to do a unitary transformation to a state stabilised by the # code stabilisers along with the stabilisers for the logical 0 state. In general, if a # state |ᴪ> is stabilised by S, then U|ᴪ> is stabilised by USU†. We can perform Clifford # gate operations to transform the stabiliser set. For details see Nielsen & Chuang # section 10.5.2 and Problem 10.3. Also, see Appendix A of "Fault-tolerant Preparation of # Stabilizer States for Quantum CSS Codes by ClassicalError-Correcting Codes." # # The idea is that we want to transform the parity check matrix from # # [[ 0 0 0 | I1 0 0 ], [[ I1 A1 A2 | 0 0 0 ], # [ 0 0 0 | 0 I2 0 ], => [ 0 0 0 | D I2 E ], # [ 0 0 0 | 0 0 I3 ]] [ 0 0 0 | A2T 0 I3 ]] # # Transformations to manipulate the parity check are derived from Figure 10.7 in # Nielsen & Chuang which shows how Pauli operators behave under conjugation by Clifford # operators. # The program accumulates the actual operations on the qubits. prog = Program() # Step 0: Copy Z's from I3 to E. Post-state: # # [[ I1 0 0 | 0 0 0 ], # [ 0 0 0 | 0 I2 E ], # [ 0 0 0 | 0 0 I3 ]] # # This is just a multiplication of stabilisers and does not require any instructions. # Step 1: Apply Hadamards to move I1 to the X side. Post-state: # # [[ I1 0 0 | 0 0 0 ], # [ 0 0 0 | 0 I2 E ], # [ 0 0 0 | 0 0 I3 ]] for i in range(r_1): prog += gates.H(qubits[i]) # Step 2: Copy X's from I1 to A1 and A2. This has the side effect of constructing D and A2T. # Post-state: # # [[ I1 A1 A2 | 0 0 0 ], # [ 0 0 0 | D I2 E ], # [ 0 0 0 | A2T 0 I3 ]] for i in range(r_1): for j in range(r_1, n): if self.parity_check_c1[i, j] == 1: prog += gates.CNOT(qubits[i], qubits[j]) return prog
def test_convert_simple_program_with_parameters(self): """Test that a simple program with parameters is properly converted.""" program = pyquil.Program() alpha = program.declare("alpha", "REAL") beta = program.declare("beta", "REAL") gamma = program.declare("gamma", "REAL") program += g.H(0) program += g.CNOT(0, 1) program += g.RX(alpha, 1) program += g.RZ(beta, 1) program += g.RX(gamma, 1) program += g.CNOT(0, 1) program += g.H(0) a, b, c = 0.1, 0.2, 0.3 parameter_map = { "alpha": a, "beta": b, "gamma": c, } with OperationRecorder() as rec: load_program(program)(wires=range(2), parameter_map=parameter_map) expected_queue = [ qml.Hadamard(0), qml.CNOT(wires=[0, 1]), qml.RX(0.1, wires=[1]), qml.RZ(0.2, wires=[1]), qml.RX(0.3, wires=[1]), qml.CNOT(wires=[0, 1]), qml.Hadamard(0), ] for converted, expected in zip(rec.queue, expected_queue): assert converted.name == expected.name assert converted.wires == expected.wires assert converted.params == expected.params
def test_measures(self): # Create qlm program prog = Program() qreg = prog.qalloc(3) prog.apply(H, qreg[0]) prog.apply(H, qreg[1]) prog.apply(H, qreg[2]) result = qlm_to_pyquil(prog.to_circ()) # Create pyquil program expected = Prg() cbs = expected.declare("ro", "BIT", 3) expected += pg.H(0) expected += pg.H(1) expected += pg.H(2) expected += pg.MEASURE(0, cbs[0]) expected += pg.MEASURE(1, cbs[1]) expected += pg.MEASURE(2, cbs[2]) self.assertEqual(str(result), str(expected))
def test_multiple_measurements_program(self): raw_prog = Program() ro = raw_prog.declare('ro', 'BIT', 2) raw_prog += gates.H(0) raw_prog += gates.MEASURE(0, ro[0]) raw_prog.if_then(ro[0], gates.X(0), Program()) raw_prog += gates.MEASURE(0, ro[1]) new_prog = ftqc.rewrite_program(raw_prog, self.steane_7bit) results = self.run_program(new_prog) for result in results: self.assertEqual(result[1], 0)
def test_parameter_not_given_error(self): """Test that the correct error is raised if a parameter is not given.""" program = pyquil.Program() alpha = program.declare("alpha", "REAL") beta = program.declare("beta", "REAL") program += g.H(0) program += g.CNOT(0, 1) program += g.RX(alpha, 1) program += g.RZ(beta, 1) a = 0.1 parameter_map = {"alpha": a} with pytest.raises( qml.DeviceError, match= "The PyQuil program defines a variable .* that is not present in the given variable map", ): load_program(program)(wires=range(2), parameter_map=parameter_map)
class TestProgramConverter: """Test that PyQuil Program instances are properly converted.""" @pytest.mark.parametrize( "pyquil_operation,expected_pl_operation", [ (g.I(0), qml.Identity(wires=[0])), (g.H(0), qml.Hadamard(0)), (g.H(0).dagger(), qml.Hadamard(0).inv()), (g.H(0).dagger().dagger(), qml.Hadamard(0).inv().inv()), (g.S(0), qml.S(wires=[0])), (g.S(0).dagger(), qml.S(wires=[0]).inv()), (g.S(0).dagger().dagger(), qml.S(wires=[0]).inv().inv()), (g.T(0), qml.T(wires=[0])), (g.T(0).dagger(), qml.T(wires=[0]).inv()), (g.T(0).dagger().dagger(), qml.T(wires=[0]).inv().inv()), (g.X(0), qml.PauliX(0)), (g.X(0).dagger(), qml.PauliX(0).inv()), (g.X(0).dagger().dagger(), qml.PauliX(0).inv().inv()), (g.X(0).controlled(1), qml.CNOT(wires=[1, 0])), (g.X(0).controlled(1).dagger(), qml.CNOT(wires=[1, 0]).inv()), (g.X(0).controlled(1).dagger().dagger(), qml.CNOT(wires=[1, 0]).inv().inv()), (g.X(0).controlled(1).controlled(2), plf.ops.CCNOT(wires=[2, 1, 0])), (g.X(0).controlled(1).controlled(2).dagger(), plf.ops.CCNOT(wires=[2, 1, 0]).inv()), ( g.X(0).controlled(1).controlled(2).dagger().dagger(), plf.ops.CCNOT(wires=[2, 1, 0]).inv().inv(), ), (g.Y(0), qml.PauliY(0)), (g.Y(0).dagger(), qml.PauliY(0).inv()), (g.Y(0).dagger().dagger(), qml.PauliY(0).inv().inv()), (g.Z(0), qml.PauliZ(0)), (g.Z(0).dagger(), qml.PauliZ(0).inv()), (g.Z(0).dagger().dagger(), qml.PauliZ(0).inv().inv()), (g.Z(0).controlled(1), qml.CZ(wires=[1, 0])), (g.Z(0).controlled(1).dagger(), qml.CZ(wires=[1, 0]).inv()), (g.Z(0).controlled(1).dagger().dagger(), qml.CZ(wires=[1, 0]).inv().inv()), (g.CNOT(0, 1), qml.CNOT(wires=[0, 1])), (g.CNOT(0, 1).dagger(), qml.CNOT(wires=[0, 1]).inv()), (g.CNOT(0, 1).dagger().dagger(), qml.CNOT(wires=[0, 1]).inv().inv()), (g.CNOT(0, 1).controlled(2), plf.ops.CCNOT(wires=[2, 0, 1])), (g.CNOT(0, 1).controlled(2).dagger(), plf.ops.CCNOT(wires=[2, 0, 1]).inv()), ( g.CNOT(0, 1).controlled(2).dagger().dagger(), plf.ops.CCNOT(wires=[2, 0, 1]).inv().inv(), ), (g.SWAP(0, 1), qml.SWAP(wires=[0, 1])), (g.SWAP(0, 1).dagger(), qml.SWAP(wires=[0, 1]).inv()), (g.SWAP(0, 1).dagger().dagger(), qml.SWAP(wires=[0, 1]).inv().inv()), (g.SWAP(0, 1).controlled(2), qml.CSWAP(wires=[2, 0, 1])), (g.SWAP(0, 1).controlled(2).dagger(), qml.CSWAP(wires=[2, 0, 1]).inv()), (g.SWAP(0, 1).controlled(2).dagger().dagger(), qml.CSWAP(wires=[2, 0, 1]).inv().inv()), (g.ISWAP(0, 1), plf.ops.ISWAP(wires=[0, 1])), (g.ISWAP(0, 1).dagger(), plf.ops.ISWAP(wires=[0, 1]).inv()), (g.ISWAP(0, 1).dagger().dagger(), plf.ops.ISWAP(wires=[0, 1]).inv().inv()), (g.PSWAP(0.3, 0, 1), plf.ops.PSWAP(0.3, wires=[0, 1])), (g.PSWAP(0.3, 0, 1).dagger(), plf.ops.PSWAP(0.3, wires=[0, 1 ]).inv()), (g.PSWAP(0.3, 0, 1).dagger().dagger(), plf.ops.PSWAP(0.3, wires=[0, 1]).inv().inv()), (g.CZ(0, 1), qml.CZ(wires=[0, 1])), (g.CZ(0, 1).dagger(), qml.CZ(wires=[0, 1]).inv()), (g.CZ(0, 1).dagger().dagger(), qml.CZ(wires=[0, 1]).inv().inv()), (g.PHASE(0.3, 0), qml.PhaseShift(0.3, wires=[0])), (g.PHASE(0.3, 0).dagger(), qml.PhaseShift(0.3, wires=[0]).inv()), (g.PHASE(0.3, 0).dagger().dagger(), qml.PhaseShift( 0.3, wires=[0]).inv().inv()), (g.PHASE(0.3, 0).controlled(1), plf.ops.CPHASE( 0.3, 3, wires=[1, 0])), (g.PHASE(0.3, 0).controlled(1).dagger(), plf.ops.CPHASE(0.3, 3, wires=[1, 0]).inv()), ( g.PHASE(0.3, 0).controlled(1).dagger().dagger(), plf.ops.CPHASE(0.3, 3, wires=[1, 0]).inv().inv(), ), (g.RX(0.3, 0), qml.RX(0.3, wires=[0])), (g.RX(0.3, 0).dagger(), qml.RX(0.3, wires=[0]).inv()), (g.RX(0.3, 0).dagger().dagger(), qml.RX(0.3, wires=[0]).inv().inv()), (g.RX(0.3, 0).controlled(1), qml.CRX(0.3, wires=[1, 0])), (g.RX(0.3, 0).controlled(1).dagger(), qml.CRX(0.3, wires=[1, 0]).inv()), (g.RX(0.3, 0).controlled(1).dagger().dagger(), qml.CRX(0.3, wires=[1, 0]).inv().inv()), (g.RY(0.3, 0), qml.RY(0.3, wires=[0])), (g.RY(0.3, 0).dagger(), qml.RY(0.3, wires=[0]).inv()), (g.RY(0.3, 0).dagger().dagger(), qml.RY(0.3, wires=[0]).inv().inv()), (g.RY(0.3, 0).controlled(1), qml.CRY(0.3, wires=[1, 0])), (g.RY(0.3, 0).controlled(1).dagger(), qml.CRY(0.3, wires=[1, 0]).inv()), (g.RY(0.3, 0).controlled(1).dagger().dagger(), qml.CRY(0.3, wires=[1, 0]).inv().inv()), (g.RZ(0.3, 0), qml.RZ(0.3, wires=[0])), (g.RZ(0.3, 0).dagger(), qml.RZ(0.3, wires=[0]).inv()), (g.RZ(0.3, 0).dagger().dagger(), qml.RZ(0.3, wires=[0]).inv().inv()), (g.RZ(0.3, 0).controlled(1), qml.CRZ(0.3, wires=[1, 0])), (g.RZ(0.3, 0).controlled(1).dagger(), qml.CRZ(0.3, wires=[1, 0]).inv()), (g.RZ(0.3, 0).controlled(1).dagger().dagger(), qml.CRZ(0.3, wires=[1, 0]).inv().inv()), (g.CPHASE(0.3, 0, 1), plf.ops.CPHASE(0.3, 3, wires=[0, 1])), (g.CPHASE(0.3, 0, 1).dagger(), plf.ops.CPHASE(0.3, 3, wires=[0, 1]).inv()), ( g.CPHASE(0.3, 0, 1).dagger().dagger(), plf.ops.CPHASE(0.3, 3, wires=[0, 1]).inv().inv(), ), (g.CPHASE00(0.3, 0, 1), plf.ops.CPHASE(0.3, 0, wires=[0, 1])), (g.CPHASE00(0.3, 0, 1).dagger(), plf.ops.CPHASE(0.3, 0, wires=[0, 1]).inv()), ( g.CPHASE00(0.3, 0, 1).dagger().dagger(), plf.ops.CPHASE(0.3, 0, wires=[0, 1]).inv().inv(), ), (g.CPHASE01(0.3, 0, 1), plf.ops.CPHASE(0.3, 1, wires=[0, 1])), (g.CPHASE01(0.3, 0, 1).dagger(), plf.ops.CPHASE(0.3, 1, wires=[0, 1]).inv()), ( g.CPHASE01(0.3, 0, 1).dagger().dagger(), plf.ops.CPHASE(0.3, 1, wires=[0, 1]).inv().inv(), ), (g.CPHASE10(0.3, 0, 1), plf.ops.CPHASE(0.3, 2, wires=[0, 1])), (g.CPHASE10(0.3, 0, 1).dagger(), plf.ops.CPHASE(0.3, 2, wires=[0, 1]).inv()), ( g.CPHASE10(0.3, 0, 1).dagger().dagger(), plf.ops.CPHASE(0.3, 2, wires=[0, 1]).inv().inv(), ), (g.CSWAP(0, 1, 2), qml.CSWAP(wires=[0, 1, 2])), (g.CSWAP(0, 1, 2).dagger(), qml.CSWAP(wires=[0, 1, 2]).inv()), (g.CSWAP(0, 1, 2).dagger().dagger(), qml.CSWAP(wires=[0, 1, 2]).inv().inv()), (g.CCNOT(0, 1, 2), plf.ops.CCNOT(wires=[0, 1, 2])), (g.CCNOT(0, 1, 2).dagger(), plf.ops.CCNOT(wires=[0, 1, 2]).inv()), (g.CCNOT(0, 1, 2).dagger().dagger(), plf.ops.CCNOT(wires=[0, 1, 2]).inv().inv()), ], ) def test_convert_operation(self, pyquil_operation, expected_pl_operation): """Test that single pyquil gates are properly converted.""" program = pyquil.Program() program += pyquil_operation with OperationRecorder() as rec: loader = load_program(program) loader(wires=range(len(loader.defined_qubits))) assert rec.queue[0].name == expected_pl_operation.name assert rec.queue[0].wires == expected_pl_operation.wires assert rec.queue[0].params == expected_pl_operation.params def test_convert_simple_program(self): """Test that a simple program is properly converted.""" program = pyquil.Program() program += g.H(0) program += g.RZ(0.34, 1) program += g.CNOT(0, 3) program += g.H(2) program += g.H(7) program += g.X(7) program += g.Y(1) program += g.RZ(0.34, 1) with OperationRecorder() as rec: load_program(program)(wires=range(5)) # The wires should be assigned as # 0 1 2 3 7 # 0 1 2 3 4 expected_queue = [ qml.Hadamard(0), qml.RZ(0.34, wires=[1]), qml.CNOT(wires=[0, 3]), qml.Hadamard(2), qml.Hadamard(4), qml.PauliX(4), qml.PauliY(1), qml.RZ(0.34, wires=[1]), ] for converted, expected in zip(rec.queue, expected_queue): assert converted.name == expected.name assert converted.wires == expected.wires assert converted.params == expected.params def test_convert_simple_program_with_parameters(self): """Test that a simple program with parameters is properly converted.""" program = pyquil.Program() alpha = program.declare("alpha", "REAL") beta = program.declare("beta", "REAL") gamma = program.declare("gamma", "REAL") program += g.H(0) program += g.CNOT(0, 1) program += g.RX(alpha, 1) program += g.RZ(beta, 1) program += g.RX(gamma, 1) program += g.CNOT(0, 1) program += g.H(0) a, b, c = 0.1, 0.2, 0.3 parameter_map = {"alpha": a, "beta": b, "gamma": c} with OperationRecorder() as rec: load_program(program)(wires=range(2), parameter_map=parameter_map) expected_queue = [ qml.Hadamard(0), qml.CNOT(wires=[0, 1]), qml.RX(0.1, wires=[1]), qml.RZ(0.2, wires=[1]), qml.RX(0.3, wires=[1]), qml.CNOT(wires=[0, 1]), qml.Hadamard(0), ] for converted, expected in zip(rec.queue, expected_queue): assert converted.name == expected.name assert converted.wires == expected.wires assert converted.params == expected.params def test_parameter_not_given_error(self): """Test that the correct error is raised if a parameter is not given.""" program = pyquil.Program() alpha = program.declare("alpha", "REAL") beta = program.declare("beta", "REAL") program += g.H(0) program += g.CNOT(0, 1) program += g.RX(alpha, 1) program += g.RZ(beta, 1) a = 0.1 parameter_map = {"alpha": a} with pytest.raises( qml.DeviceError, match= "The PyQuil program defines a variable .* that is not present in the given variable map", ): load_program(program)(wires=range(2), parameter_map=parameter_map) def test_convert_simple_program_with_parameters_mixed_keys(self): """Test that a parametrized program is properly converted when the variable map contains mixed key types.""" program = pyquil.Program() alpha = program.declare("alpha", "REAL") beta = program.declare("beta", "REAL") gamma = program.declare("gamma", "REAL") delta = program.declare("delta", "REAL") program += g.H(0) program += g.CNOT(0, 1) program += g.RX(alpha, 1) program += g.RZ(beta, 1) program += g.RX(gamma, 1) program += g.CNOT(0, 1) program += g.RZ(delta, 0) program += g.H(0) a, b, c, d = 0.1, 0.2, 0.3, 0.4 parameter_map = {"alpha": a, beta: b, gamma: c, "delta": d} with OperationRecorder() as rec: load_program(program)(wires=range(2), parameter_map=parameter_map) expected_queue = [ qml.Hadamard(0), qml.CNOT(wires=[0, 1]), qml.RX(0.1, wires=[1]), qml.RZ(0.2, wires=[1]), qml.RX(0.3, wires=[1]), qml.CNOT(wires=[0, 1]), qml.RZ(0.4, wires=[0]), qml.Hadamard(0), ] for converted, expected in zip(rec.queue, expected_queue): assert converted.name == expected.name assert converted.wires == expected.wires assert converted.params == expected.params def test_convert_simple_program_wire_assignment(self): """Test that the assignment of qubits to wires works as expected.""" program = pyquil.Program() program += g.H(0) program += g.RZ(0.34, 1) program += g.CNOT(0, 3) program += g.H(2) program += g.H(7) program += g.X(7) program += g.Y(1) program += g.RZ(0.34, 1) with OperationRecorder() as rec: load_program(program)(wires=[3, 6, 4, 9, 1]) # The wires should be assigned as # 0 1 2 3 7 # 3 6 4 9 1 expected_queue = [ qml.Hadamard(3), qml.RZ(0.34, wires=[6]), qml.CNOT(wires=[3, 9]), qml.Hadamard(4), qml.Hadamard(1), qml.PauliX(1), qml.PauliY(6), qml.RZ(0.34, wires=[6]), ] for converted, expected in zip(rec.queue, expected_queue): assert converted.name == expected.name assert converted.wires == expected.wires assert converted.params == expected.params @pytest.mark.parametrize("wires", [[0, 1, 2, 3], [4, 5]]) def test_convert_wire_error(self, wires): """Test that the conversion raises an error if the given number of wires doesn't match the number of qubits in the Program.""" program = pyquil.Program() program += g.H(0) program += g.H(1) program += g.H(2) with pytest.raises( qml.DeviceError, match= "The number of given wires does not match the number of qubits in the PyQuil Program", ): load_program(program)(wires=wires) def test_convert_program_with_inverses(self): """Test that a program with inverses is properly converted.""" program = pyquil.Program() program += g.H(0) program += g.RZ(0.34, 1).dagger() program += g.CNOT(0, 3).dagger() program += g.H(2) program += g.H(7).dagger().dagger() program += g.X(7).dagger() program += g.X(7) program += g.Y(1) program += g.RZ(0.34, 1) with OperationRecorder() as rec: load_program(program)(wires=range(5)) expected_queue = [ qml.Hadamard(0), qml.RZ(0.34, wires=[1]).inv(), qml.CNOT(wires=[0, 3]).inv(), qml.Hadamard(2), qml.Hadamard(4), qml.PauliX(4).inv(), qml.PauliX(4), qml.PauliY(1), qml.RZ(0.34, wires=[1]), ] for converted, expected in zip(rec.queue, expected_queue): assert converted.name == expected.name assert converted.wires == expected.wires assert converted.params == expected.params def test_convert_program_with_controlled_operations(self): """Test that a program with controlled operations is properly converted.""" program = pyquil.Program() program += g.RZ(0.34, 1) program += g.RY(0.2, 3).controlled(2) program += g.RX(0.4, 2).controlled(0) program += g.CNOT(1, 4) program += g.CNOT(1, 6).controlled(3) program += g.X(3).controlled(4).controlled(1) with OperationRecorder() as rec: load_program(program)(wires=range(6)) expected_queue = [ qml.RZ(0.34, wires=[1]), qml.CRY(0.2, wires=[2, 3]), qml.CRX(0.4, wires=[0, 2]), qml.CNOT(wires=[1, 4]), plf.ops.CCNOT(wires=[3, 1, 5]), plf.ops.CCNOT(wires=[1, 4, 3]), ] for converted, expected in zip(rec.queue, expected_queue): assert converted.name == expected.name assert converted.wires == expected.wires assert converted.params == expected.params def test_convert_program_with_controlled_operations_not_in_pl_core( self, tol): """Test that a program with controlled operations out of scope of PL core/PLF is properly converted, i.e. the operations are replaced with controlled operations.""" program = pyquil.Program() CS_matrix = np.eye(4, dtype=complex) CS_matrix[3, 3] = 1j CCT_matrix = np.eye(8, dtype=complex) CCT_matrix[7, 7] = np.exp(1j * np.pi / 4) program += g.CNOT(0, 1) program += g.S(0).controlled(1) program += g.S(1).controlled(0) program += g.T(0).controlled(1).controlled(2) program += g.T(1).controlled(0).controlled(2) program += g.T(2).controlled(1).controlled(0) with OperationRecorder() as rec: load_program(program)(wires=range(3)) expected_queue = [ qml.CNOT(wires=[0, 1]), qml.QubitUnitary(CS_matrix, wires=[1, 0]), qml.QubitUnitary(CS_matrix, wires=[0, 1]), qml.QubitUnitary(CCT_matrix, wires=[2, 1, 0]), qml.QubitUnitary(CCT_matrix, wires=[2, 0, 1]), qml.QubitUnitary(CCT_matrix, wires=[0, 1, 2]), ] for converted, expected in zip(rec.queue, expected_queue): assert converted.name == expected.name assert converted.wires == expected.wires assert np.allclose(converted.params, expected.params, atol=tol, rtol=0) def test_convert_program_with_controlled_dagger_operations(self): """Test that a program that combines controlled and daggered operations is properly converted.""" program = pyquil.Program() program += g.CNOT(0, 1).controlled(2) program += g.CNOT(0, 1).dagger().controlled(2) program += g.CNOT(0, 1).controlled(2).dagger() program += g.CNOT(0, 1).dagger().controlled(2).dagger() program += g.RX(0.3, 3).controlled(4) program += g.RX(0.2, 3).controlled(4).dagger() program += g.RX(0.3, 3).dagger().controlled(4) program += g.RX(0.2, 3).dagger().controlled(4).dagger() program += g.X(2).dagger().controlled(4).controlled(1).dagger() program += g.X(0).dagger().controlled(4).controlled(1) program += g.X(0).dagger().controlled(4).dagger().dagger().controlled( 1).dagger() with OperationRecorder() as rec: load_program(program)(wires=range(5)) expected_queue = [ plf.ops.CCNOT(wires=[2, 0, 1]), plf.ops.CCNOT(wires=[2, 0, 1]).inv(), plf.ops.CCNOT(wires=[2, 0, 1]).inv(), plf.ops.CCNOT(wires=[2, 0, 1]), qml.CRX(0.3, wires=[4, 3]), qml.CRX(0.2, wires=[4, 3]).inv(), qml.CRX(0.3, wires=[4, 3]).inv(), qml.CRX(0.2, wires=[4, 3]), plf.ops.CCNOT(wires=[1, 4, 2]), plf.ops.CCNOT(wires=[1, 4, 0]).inv(), plf.ops.CCNOT(wires=[1, 4, 0]), ] for converted, expected in zip(rec.queue, expected_queue): assert converted.name == expected.name assert converted.wires == expected.wires assert converted.params == expected.params def test_convert_program_with_defgates(self): """Test that a program that defines its own gates is properly converted.""" program = pyquil.Program() sqrt_x = np.array([[0.5 + 0.5j, 0.5 - 0.5j], [0.5 - 0.5j, 0.5 + 0.5j]]) sqrt_x_t2 = np.kron(sqrt_x, sqrt_x) sqrt_x_t3 = np.kron(sqrt_x, sqrt_x_t2) sqrt_x_definition = pyquil.quil.DefGate("SQRT-X", sqrt_x) SQRT_X = sqrt_x_definition.get_constructor() sqrt_x_t2_definition = pyquil.quil.DefGate("SQRT-X-T2", sqrt_x_t2) SQRT_X_T2 = sqrt_x_t2_definition.get_constructor() sqrt_x_t3_definition = pyquil.quil.DefGate("SQRT-X-T3", sqrt_x_t3) SQRT_X_T3 = sqrt_x_t3_definition.get_constructor() program += sqrt_x_definition program += sqrt_x_t2_definition program += sqrt_x_t3_definition program += g.CNOT(0, 1) program += SQRT_X(0) program += SQRT_X_T2(1, 2) program += SQRT_X_T3(1, 0, 2) program += g.CNOT(0, 1) program += g.CNOT(1, 2) program += g.CNOT(2, 0) with OperationRecorder() as rec: load_program(program)(wires=range(3)) expected_queue = [ qml.CNOT(wires=[0, 1]), qml.QubitUnitary(sqrt_x, wires=[0]), qml.QubitUnitary(sqrt_x_t2, wires=[1, 2]), qml.QubitUnitary(sqrt_x_t3, wires=[1, 0, 2]), qml.CNOT(wires=[0, 1]), qml.CNOT(wires=[1, 2]), qml.CNOT(wires=[2, 0]), ] for converted, expected in zip(rec.queue, expected_queue): assert converted.name == expected.name assert converted.wires == expected.wires assert converted.params == expected.params def test_convert_program_with_controlled_defgates(self, tol): """Test that a program with controlled defined gates is properly converted.""" program = pyquil.Program() sqrt_x = np.array([[0.5 + 0.5j, 0.5 - 0.5j], [0.5 - 0.5j, 0.5 + 0.5j]]) sqrt_x_t2 = np.kron(sqrt_x, sqrt_x) c_sqrt_x = np.eye(4, dtype=complex) c_sqrt_x[2:, 2:] = sqrt_x c_sqrt_x_t2 = np.eye(8, dtype=complex) c_sqrt_x_t2[4:, 4:] = sqrt_x_t2 sqrt_x_definition = pyquil.quil.DefGate("SQRT-X", sqrt_x) SQRT_X = sqrt_x_definition.get_constructor() sqrt_x_t2_definition = pyquil.quil.DefGate("SQRT-X-T2", sqrt_x_t2) SQRT_X_T2 = sqrt_x_t2_definition.get_constructor() program += sqrt_x_definition program += sqrt_x_t2_definition program += g.CNOT(0, 1) program += SQRT_X(0).controlled(1) program += SQRT_X_T2(1, 2).controlled(0) program += g.X(0).controlled(1) program += g.RX(0.4, 0) with OperationRecorder() as rec: load_program(program)(wires=range(3)) expected_queue = [ qml.CNOT(wires=[0, 1]), qml.QubitUnitary(c_sqrt_x, wires=[1, 0]), qml.QubitUnitary(c_sqrt_x_t2, wires=[0, 1, 2]), qml.CNOT(wires=[1, 0]), qml.RX(0.4, wires=[0]), ] for converted, expected in zip(rec.queue, expected_queue): assert converted.name == expected.name assert converted.wires == expected.wires assert np.allclose(converted.params, expected.params, atol=tol, rtol=0) def test_convert_program_with_defpermutationgates(self): """Test that a program with gates defined via DefPermutationGate is properly converted.""" program = pyquil.Program() expected_matrix = np.eye(4) expected_matrix = expected_matrix[:, [1, 0, 3, 2]] x_plus_x_definition = pyquil.quil.DefPermutationGate( "X+X", [1, 0, 3, 2]) X_plus_X = x_plus_x_definition.get_constructor() program += x_plus_x_definition program += g.CNOT(0, 1) program += X_plus_X(0, 1) program += g.CNOT(0, 1) with OperationRecorder() as rec: load_program(program)(wires=range(2)) expected_queue = [ qml.CNOT(wires=[0, 1]), qml.QubitUnitary(expected_matrix, wires=[0, 1]), qml.CNOT(wires=[0, 1]), ] for converted, expected in zip(rec.queue, expected_queue): assert converted.name == expected.name assert converted.wires == expected.wires assert np.array_equal(converted.params, expected.params) def test_convert_program_with_controlled_defpermutationgates(self): """Test that a program that uses controlled permutation gates is properly converted.""" program = pyquil.Program() expected_matrix = np.eye(4) expected_matrix = expected_matrix[:, [1, 0, 3, 2]] expected_controlled_matrix = np.eye(8) expected_controlled_matrix[4:, 4:] = expected_matrix x_plus_x_definition = pyquil.quil.DefPermutationGate( "X+X", [1, 0, 3, 2]) X_plus_X = x_plus_x_definition.get_constructor() program += x_plus_x_definition program += g.CNOT(0, 1) program += X_plus_X(0, 1).controlled(2) program += X_plus_X(1, 2).controlled(0) program += g.CNOT(0, 1) with OperationRecorder() as rec: load_program(program)(wires=range(3)) expected_queue = [ qml.CNOT(wires=[0, 1]), qml.QubitUnitary(expected_controlled_matrix, wires=[2, 0, 1]), qml.QubitUnitary(expected_controlled_matrix, wires=[0, 1, 2]), qml.CNOT(wires=[0, 1]), ] for converted, expected in zip(rec.queue, expected_queue): assert converted.name == expected.name assert converted.wires == expected.wires assert np.array_equal(converted.params, expected.params) def test_forked_gate_error(self): """Test that an error is raised if conversion of a forked gate is attempted.""" program = pyquil.Program() program += g.CNOT(0, 1) program += g.RX(0.3, 1).forked(2, [0.5]) program += g.CNOT(0, 1) with pytest.raises( qml.DeviceError, match= "Forked gates can not be imported into PennyLane, as this functionality is not supported", ): load_program(program)(wires=range(3))
def calculate(self): '''Processes the quantum circuit and returns the results''' p = Program() # Gets definitions for quarter & eighth turn gates p = self.define_extra_gates(p) # length of circuit = number of columns col_length = len(self.circuit) num_qubits = 0 # max length of any number of operations per column = number of qubits / rows used for i in self.circuit: if len(i) > num_qubits: num_qubits = len(i) # loops over each gate in circuit and applies the gate for i in range(col_length): # Keeps track of where special components are (i.e. SWAP) special_loc = [] # Obtains any controls in the column i; if present, each gate is made into a controlled gate, else the gate is normal control_qubits, anticontrol_qubits = self.get_controls_in_column(i) # To apply anticontrols, X gate needs to be applied to the corresponding qubit wire and applied again after column is processed for qubit in anticontrol_qubits: p += pqg.X(qubit) for j in range(len(self.circuit[i])): current_gate = str(self.circuit[i][j]).upper() # If the gate is X, Y, Z or H, apply the gate to qubit #j if current_gate in "H": p += pqg.H(j).controlled(control_qubits) elif current_gate in "X": p += pqg.X(j).controlled(control_qubits) elif current_gate in "Y": p += pqg.Y(j).controlled(control_qubits) elif current_gate in "Z": p += pqg.Z(j).controlled(control_qubits) # If the gate is a quarter turn (+/- 90 deg or pi/2) for X, Y or Z, apply the respective gate elif current_gate in ("X^1/2", "X^½"): p += POS_SQRT_X(j).controlled(control_qubits) elif current_gate in ('X^-1/2', 'X^-½'): p += NEG_SQRT_X(j).controlled(control_qubits) elif current_gate in ("Y^1/2", "Y^½"): p += POS_SQRT_Y(j).controlled(control_qubits) elif current_gate in ("Y^-1/2", "Y^-½"): p += NEG_SQRT_Y(j).controlled(control_qubits) elif current_gate in ("Z^1/2", "Z^½", "S"): p += POS_SQRT_Z(j).controlled(control_qubits) elif current_gate in ("Z^-1/2", "Z^-½", "S^-1"): p += NEG_SQRT_Z(j).controlled(control_qubits) # If the gate is an eighth turn (+/- 45 deg or pi/4) for X, Y or Z, apply the respective gate elif current_gate in ("X^1/4", "X^¼"): p += POS_FTRT_X(j).controlled(control_qubits) elif current_gate in ("X^-1/4", "X^-¼"): p += NEG_FTRT_X(j).controlled(control_qubits) elif current_gate in ("Y^1/4", "Y^¼"): p += POS_FTRT_Y(j).controlled(control_qubits) elif current_gate in ("Y^-1/4", "Y^-¼"): p += NEG_FTRT_Y(j).controlled(control_qubits) elif current_gate in ("Z^1/4", "Z^¼", "T"): p += POS_FTRT_Z(j).controlled(control_qubits) elif current_gate in ("Z^-1/4", "Z^-¼", "T^-1"): p += NEG_FTRT_Z(j).controlled(control_qubits) # If the gate is a SWAP gate, check if another one has been found before and perform the SWAP operation # If not, keep track of its location until we find the other SWAP gate elif current_gate in "SWAP": if len(special_loc) == 1: p += pqg.SWAP(special_loc[0], j).controlled(control_qubits) special_loc = [] else: special_loc.append(j) else: p += pqg.I(j) # Reverses the process used to make anticontrols possible for qubit in anticontrol_qubits: p += pqg.X(qubit) self.construct_results_dict(p) return self.results
) from mitiq.utils import _equal # Cirq Bell circuit. cirq_qreg = cirq.LineQubit.range(2) cirq_circuit = cirq.Circuit(cirq.ops.H.on(cirq_qreg[0]), cirq.ops.CNOT.on(*cirq_qreg)) # Qiskit Bell circuit. qiskit_qreg = qiskit.QuantumRegister(2) qiskit_circuit = qiskit.QuantumCircuit(qiskit_qreg) qiskit_circuit.h(qiskit_qreg[0]) qiskit_circuit.cnot(*qiskit_qreg) # pyQuil Bell circuit. pyquil_circuit = Program(gates.H(0), gates.CNOT(0, 1)) # Braket Bell circuit. braket_circuit = BKCircuit([ Instruction(braket_gates.H(), 0), Instruction(braket_gates.CNot(), [0, 1]), ]) circuit_types = { "qiskit": qiskit.QuantumCircuit, "pyquil": Program, "braket": BKCircuit, } @noise_scaling_converter
def expectation(angles: List[float], coeff: complex, pauli: str, ansatz: pyquil.Program, creg: pyquil.quilatom.MemoryReference, computer: pyquil.api.QuantumComputer, shots: int = 10000, verbose: bool = False) -> float: """Returns coeff * <\theta| paulii |\theta>. Args: angles: List of angles at which to evaluate coeff * <theta| pauli |theta>. coeff: Coefficient of Pauli term. pauli: Pauli string. ansatz: pyQuil program representing the ansatz state. creg: Classical register of ansatz to measure into. computer: QuantumComputer to execute the circuit on. shots: Number of times to execute the circuit (sampling statistics). verbose: Option for visualization/debugging. """ if np.isclose(np.imag(coeff), 0.0): coeff = np.real(coeff) if set(pauli) == {"I"}: return coeff angles = list(angles) angles = deepcopy(angles) if verbose: print("DEBUG holy f**k") print(f"type(angles) = {type(angles)}") print("angles =", angles) # Set up the circuit circuit = ansatz.copy() qubits = computer.qubits() measured = [] for (q, p) in enumerate(pauli): if p in ("X", "Y", "Z"): measured.append(qubits[q]) if p == "X": circuit += [gates.H(qubits[q]), gates.MEASURE(qubits[q], creg[q])] elif p == "Y": circuit += [ gates.S(qubits[q]), gates.H(qubits[q]), gates.MEASURE(qubits[q], creg[q]) ] elif p == "Z": circuit += [gates.MEASURE(qubits[q], creg[q])] if verbose: print(f"Computing {coeff} x <theta|{pauli}|theta>...") print("\nCircuit to be executed:") print(circuit) print(f"type(angles) = {type(angles)}") # Execute the circuit circuit.wrap_in_numshots_loop(shots) executable = computer.compile(circuit) res = computer.run(executable, memory_map={"theta": angles}) if verbose: print("\nResults:") print(f"{len(res)} total measured bit strings.") print(res) # Do the postprocessing tot = 0.0 for vals in res: tot += (-1)**sum(vals) return coeff * tot / shots
"""Random bit generator circuit in PyQuil 2.1.1.""" # imports from pyquil.quil import Program import pyquil.gates as gates from pyquil import api # get a program and classical memory register qprog = Program() creg = qprog.declare(name="ro", memory_size=1) # REQUIRES: api key, qvm running in background ("qvm -S" in a linux terminal # after it is installed. See Rigetti website for download instructions # https://www.rigetti.com/forest) qvm = api.QVMConnection() # add instructions to the program qprog += [gates.H(0), gates.MEASURE(0, creg[0])] print(qprog) print(qvm.run(qprog, trials=1))
#!/usr/bin/env python3 # -*- coding: utf-8 -*- # =========================================== # wavelet.py # # Doing the wavelet transform in PyQuil. # # written by Ryan LaRose <*****@*****.**> # at Michigan State University 05-17-18 # =========================================== from pyquil.quil import Program import pyquil.gates as gates from pyquil import api devices = api.get_devices(as_dict=True) acorn = devices['8Q-Agave'] compiler = api.CompilerConnection(acorn) qprog = Program() qprog.inst(gates.H(0), gates.H(1), gates.H(2), gates.CNOT(0, 2), gates.CNOT(1, 2)) job_id = compiler.compile_async(qprog) job = compiler.wait_for_job(job_id) print(job.compiled_quil()) qvm = api.QVMConnection()
creg = qprog.declare("ro", memory_size=3) # REQUIRES: api key, qvm running in background ("qvm -S" in a linux terminal # after it is installed. See Rigetti website for download instructions # https://www.rigetti.com/forest) qvm = api.QVMConnection() # ============================================================================= # teleportation circuit # ============================================================================= # Alice wants to send |1> to Bob qprog += gates.X(0) # main circuit qprog += [ gates.H(1), gates.CNOT(1, 2), gates.CNOT(0, 1), gates.H(0), gates.MEASURE(0, creg[0]), gates.MEASURE(1, creg[1]) ] # conditional operations qprog.if_then(creg[0], gates.Z(2)) qprog.if_then(creg[1], gates.X(2)) # measure qubit three qprog.measure(2, creg[2]) # =============================================================================
if not is_sim_meas_group(paulis): raise ValueError("Input group is not simultaneously measurable.") # Squash the group into one Pauli string to determine the correct measurements # Note this is only possible by assumption that the group is simultaneously measurable squashed = squash(paulis) # Add the right rotation + measurement operators to the ansatz circuit = ansatz.copy() qubits = computer.qubits() to_measure = [] for (q, p) in enumerate(squashed): if p in ("X", "Y", "Z"): to_measure.append(q) if p == "X": circuit += [gates.H(qubits[q])] elif p == "Y": circuit += [gates.S(qubits[q]), gates.H(qubits[q])] # Add the terminal measurements # Note we do it this way since all measurements *must* be at the end of the circuit on hardware for q in to_measure: circuit += [gates.MEASURE(qubits[q], creg[q])] # Execute the circuit circuit.wrap_in_numshots_loop(shots) executable = computer.compile(circuit) res = computer.run(executable, memory_map={"theta": angles}) # Do the postprocessing supports = [support(pauli) for pauli in paulis]
def H(qubit) -> None: program_context().inst(gates.H(qubit))
if len(sys.argv) > 1: depth = int(sys.argv[2]) else: depth = 10 # allocate classical memory creg = qprog.declare("ro", memory_size=n) # ============================================================================= # circuit to test simulator # ============================================================================= # main (arbitrary) circuit for level in range(depth): for ii in range(n): qprog.inst(gates.H(ii), gates.X(ii)) if ii != 0: qprog.inst(gates.CNOT(ii, 0)) # measurements for ii in range(n): qprog.inst(gates.MEASURE(ii, creg[ii])) # ============================================================================= # run the circuit and print the results # ============================================================================= # timing -- get the start time start = time.time()