def circuit(): """A combination of two and three qubit gates with the one_qubit_block and a simple PauliZ measurement applied to an input basis state""" qml.BasisState(np.array(basis_state), wires=[0, 1, 2]) qml.RX(0.5, wires=0) qml.Hadamard(wires=1) qml.RY(0.9, wires=2) qml.CNOT(wires=[0, 1]) qml.CNOT(wires=[2, 0]) qml.CZ(wires=[1, 0]) one_qubit_block(wires=0) qml.Toffoli(wires=[1, 0, 2]) one_qubit_block(wires=2) qml.SWAP(wires=[0, 1]) qml.SWAP(wires=[0, 2]) qml.CRX(0.5, wires=[1, 0]) qml.CSWAP(wires=[2, 1, 0]) qml.CRY(0.9, wires=[2, 1]) one_qubit_block(wires=1) qml.CRZ(0.02, wires=[0, 1]) qml.CRot(0.2, 0.3, 0.7, wires=[2, 1]) qml.RZ(0.4, wires=0) qml.Toffoli(wires=[2, 1, 0]) return qml.expval(qml.PauliZ(0))
class TestDrawableLayers: """Tests for `drawable_layers`""" def test_single_wires_no_blocking(self): """Test simple case where nothing blocks each other""" ops = [qml.PauliX(0), qml.PauliX(1), qml.PauliX(2)] layers = drawable_layers(ops) assert layers == [set(ops)] def test_single_wires_blocking(self): """Test single wire gates blocking each other""" ops = [qml.PauliX(0), qml.PauliX(0), qml.PauliX(0)] layers = drawable_layers(ops) assert layers == [{ops[0]}, {ops[1]}, {ops[2]}] @pytest.mark.parametrize( "multiwire_gate", ( qml.CNOT(wires=(0, 2)), qml.CNOT(wires=(2, 0)), qml.Toffoli(wires=(0, 2, 3)), qml.Toffoli(wires=(2, 3, 0)), qml.Toffoli(wires=(3, 0, 2)), qml.Toffoli(wires=(0, 3, 2)), qml.Toffoli(wires=(3, 2, 0)), qml.Toffoli(wires=(2, 0, 3)), ), ) def test_multiwire_blocking(self, multiwire_gate): """Test multi-wire gate blocks on unused wire""" wire_map = {0: 0, 1: 1, 2: 2, 3: 3} ops = [qml.PauliZ(1), multiwire_gate, qml.PauliX(1)] layers = drawable_layers(ops, wire_map=wire_map) assert layers == [{ops[0]}, {ops[1]}, {ops[2]}] @pytest.mark.parametrize("measurement", (qml.state(), qml.sample())) def test_all_wires_measurement(self, measurement): """Test measurements that act on all wires also block on all available wires.""" ops = [qml.PauliX(0), measurement, qml.PauliY(1)] layers = drawable_layers(ops) assert layers == [{ops[0]}, {ops[1]}, {ops[2]}]
def test_four_qubit_random_circuit(self, shots): """Test a four-qubit random circuit with the whole set of possible gates, the test is analog to a failing device test and is used to check the try/except expval function from the mixed_simulator device.""" dev = qml.device("cirq.mixedsimulator", wires=4) gates = [ qml.PauliX(wires=0), qml.PauliY(wires=1), qml.PauliZ(wires=2), qml.S(wires=3), qml.T(wires=0), qml.RX(2.3, wires=1), qml.RY(1.3, wires=2), qml.RZ(3.3, wires=3), qml.Hadamard(wires=0), qml.Rot(0.1, 0.2, 0.3, wires=1), qml.CRot(0.1, 0.2, 0.3, wires=[2, 3]), qml.Toffoli(wires=[0, 1, 2]), qml.SWAP(wires=[1, 2]), qml.CSWAP(wires=[1, 2, 3]), qml.U1(1.0, wires=0), qml.U2(1.0, 2.0, wires=2), qml.U3(1.0, 2.0, 3.0, wires=3), qml.CRX(0.1, wires=[1, 2]), qml.CRY(0.2, wires=[2, 3]), qml.CRZ(0.3, wires=[3, 1]), ] layers = 3 np.random.seed(1967) gates_per_layers = [pnp.random.permutation(gates).numpy() for _ in range(layers)] def circuit(): """4-qubit circuit with layers of randomly selected gates and random connections for multi-qubit gates.""" np.random.seed(1967) for gates in gates_per_layers: for gate in gates: qml.apply(gate) return qml.expval(qml.PauliZ(0)) qnode = qml.QNode(circuit, dev) assert np.allclose(qnode(), 0.0)
def parameterized_qubit_tape(): """A parametrized qubit ciruit.""" a, b, c = 0.1, 0.2, 0.3 angles = np.array([0.4, 0.5, 0.6]) with qml.tape.QuantumTape() as tape: qml.RX(a, wires=0) qml.RX(b, wires=1) qml.PauliZ(1) qml.CNOT(wires=[0, 1]).inv() qml.CRY(b, wires=[3, 1]) qml.RX(angles[0], wires=0) qml.RX(4 * angles[1], wires=1) qml.PhaseShift(17 / 9 * c, wires=2) qml.RZ(b, wires=3) qml.RX(angles[2], wires=2).inv() qml.CRY(0.3589, wires=[3, 1]).inv() qml.CSWAP(wires=[4, 2, 1]).inv() qml.QubitUnitary(np.eye(2), wires=[2]) qml.ControlledQubitUnitary(np.eye(2), control_wires=[0, 1], wires=[2]) qml.MultiControlledX(control_wires=[0, 1, 2], wires=[3]) qml.Toffoli(wires=[0, 2, 1]) qml.CNOT(wires=[0, 2]) qml.PauliZ(wires=[1]) qml.PauliZ(wires=[1]).inv() qml.CZ(wires=[0, 1]) qml.CZ(wires=[0, 2]).inv() qml.CY(wires=[1, 2]) qml.CY(wires=[2, 0]).inv() qml.CNOT(wires=[2, 1]) qml.CNOT(wires=[0, 2]) qml.SWAP(wires=[0, 2]).inv() qml.CNOT(wires=[1, 3]) qml.RZ(b, wires=3) qml.CSWAP(wires=[4, 0, 1]) qml.expval(qml.PauliY(0)), qml.var(qml.Hadamard(wires=1)), qml.sample(qml.PauliX(2)), qml.expval(qml.Hermitian(np.eye(4), wires=[3, 4])), return tape
def test_Toffoli(self): """Test Toffoli gets a special call.""" with QuantumTape() as tape: qml.Toffoli(wires=(0, 1, 2)) _, ax = tape_mpl(tape) layer = 0 assert len(ax.patches) == 3 assert ax.patches[0].center == (layer, 0) assert ax.patches[1].center == (layer, 1) assert ax.patches[2].center == (layer, 2) # three wires, one control line, two target lines assert len(ax.lines) == 6 control_line = ax.lines[3] assert control_line.get_data() == ((layer, layer), (0, 2)) plt.close()
def circuit(self, a, b): aBasis = i_to_basis(a, pad=self.reg_a_size) bBasis = i_to_basis(b, pad=self.reg_a_size) zeros = [0] * (self.reg_b_size - self.reg_a_size) ancilla = [0] * (self.ancilla_size) qml.BasisState(np.array(aBasis + zeros + bBasis + ancilla), wires=range(self.reg_a_size + self.reg_b_size + self.ancilla_size)) for g in self.gateSet: if len(g) == 1: qml.PauliX(g[0]) if len(g) == 2: qml.CNOT(wires=list(g)) if len(g) == 3: qml.Toffoli(wires=list(g)) return [ qml.expval(qml.PauliZ(i)) for i in range(self.reg_a_size + self.reg_b_size) ]
def test_unitary_to_rot_too_big_unitary(self): """Test that the transform ignores QubitUnitary instances that are too big to decompose.""" tof = qml.Toffoli(wires=[0, 1, 2]).matrix def qfunc(): qml.QubitUnitary(H, wires="a") qml.QubitUnitary(tof, wires=["a", "b", "c"]) transformed_qfunc = unitary_to_rot(qfunc) ops = qml.transforms.make_tape(transformed_qfunc)().operations assert len(ops) == 2 assert ops[0].name == "Rot" assert ops[0].wires == Wires("a") assert ops[1].name == "QubitUnitary" assert ops[1].wires == Wires(["a", "b", "c"])
def test_ctrl_within_ctrl(): """Test using ctrl on a method that uses ctrl.""" def ansatz(params): qml.RX(params[0], wires=0) ctrl(qml.PauliX, control=0)(wires=1) qml.RX(params[1], wires=0) controlled_ansatz = ctrl(ansatz, 2) with QuantumTape() as tape: controlled_ansatz([0.123, 0.456]) tape = expand_tape( tape, 2, stop_at=lambda op: not isinstance(op, ControlledOperation)) expected = [ qml.CRX(0.123, wires=[2, 0]), qml.Toffoli(wires=[0, 2, 1]), qml.CRX(0.456, wires=[2, 0]) ] assert_equal_operations(tape.operations, expected)
def test_integration(): gates = [ qml.PauliX(wires=0), qml.PauliY(wires=0), qml.PauliZ(wires=0), qml.S(wires=0), qml.T(wires=0), qml.RX(0.4, wires=0), qml.RY(0.4, wires=0), qml.RZ(0.4, wires=0), qml.Hadamard(wires=0), qml.Rot(0.4, 0.5, 0.6, wires=1), qml.CRot(0.4, 0.5, 0.6, wires=(0, 1)), qml.Toffoli(wires=(0, 1, 2)), qml.SWAP(wires=(0, 1)), qml.CSWAP(wires=(0, 1, 2)), qml.U1(0.4, wires=0), qml.U2(0.4, 0.5, wires=0), qml.U3(0.4, 0.5, 0.6, wires=0), qml.CRX(0.4, wires=(0, 1)), qml.CRY(0.4, wires=(0, 1)), qml.CRZ(0.4, wires=(0, 1)), ] layers = 3 np.random.seed(1967) gates_per_layers = [np.random.permutation(gates) for _ in range(layers)] with qml.tape.QuantumTape() as tape: np.random.seed(1967) for gates in gates_per_layers: for gate in gates: qml.apply(gate) base_circ = from_pennylane(tape) tape_recovered = to_pennylane(base_circ) circ_recovered = from_pennylane(tape_recovered) u_1 = cirq.unitary(base_circ) u_2 = cirq.unitary(circ_recovered) cirq.testing.assert_allclose_up_to_global_phase(u_1, u_2, atol=0)
def test_toffoli_decomposition(self, tol): """Tests that the decomposition of the Toffoli gate is correct""" op = qml.Toffoli(wires=[0, 1, 2]) res = op.decompose() assert len(res) == 15 mats = [] for i in reversed(res): if i.wires == Wires([2]): mats.append(np.kron(np.eye(4), i.matrix)) elif i.wires == Wires([1]): mats.append(np.kron(np.eye(2), np.kron(i.matrix, np.eye(2)))) elif i.wires == Wires([0]): mats.append(np.kron(i.matrix, np.eye(4))) elif i.wires == Wires([0, 1]) and i.name == "CNOT": mats.append(np.kron(i.matrix, np.eye(2))) elif i.wires == Wires([1, 2]) and i.name == "CNOT": mats.append(np.kron(np.eye(2), i.matrix)) elif i.wires == Wires([0, 2]) and i.name == "CNOT": mats.append( np.array( [ [1, 0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 0, 1, 0], ] ) ) decomposed_matrix = np.linalg.multi_dot(mats) assert np.allclose(decomposed_matrix, op.matrix, atol=tol, rtol=0)
def decomposition(self, *args, **kwargs): if len(self.control_wires) > 2 and len(self._work_wires) == 0: raise ValueError( f"At least one work wire is required to decompose operation: {self}" ) flips1 = [ qml.PauliX(self.control_wires[i]) for i, val in enumerate(self.control_values) if val == "0" ] if len(self.control_wires) == 1: decomp = [ qml.CNOT(wires=[self.control_wires[0], self._target_wire]) ] elif len(self.control_wires) == 2: decomp = [ qml.Toffoli(wires=[*self.control_wires, self._target_wire]) ] else: num_work_wires_needed = len(self.control_wires) - 2 if len(self._work_wires) >= num_work_wires_needed: decomp = self._decomposition_with_many_workers( self.control_wires, self._target_wire, self._work_wires) else: work_wire = self._work_wires[0] decomp = self._decomposition_with_one_worker( self.control_wires, self._target_wire, work_wire) flips2 = [ qml.PauliX(self.control_wires[i]) for i, val in enumerate(self.control_values) if val == "0" ] return flips1 + decomp + flips2
def _decomposition_with_many_workers(control_wires, target_wire, work_wires): """Decomposes the multi-controlled PauliX gate using the approach in Lemma 7.2 of https://arxiv.org/pdf/quant-ph/9503016.pdf, which requires a suitably large register of work wires""" num_work_wires_needed = len(control_wires) - 2 work_wires = work_wires[:num_work_wires_needed] work_wires_reversed = list(reversed(work_wires)) control_wires_reversed = list(reversed(control_wires)) gates = [] for i in range(len(work_wires)): ctrl1 = control_wires_reversed[i] ctrl2 = work_wires_reversed[i] t = target_wire if i == 0 else work_wires_reversed[i - 1] gates.append(qml.Toffoli(wires=[ctrl1, ctrl2, t])) gates.append(qml.Toffoli(wires=[*control_wires[:2], work_wires[0]])) for i in reversed(range(len(work_wires))): ctrl1 = control_wires_reversed[i] ctrl2 = work_wires_reversed[i] t = target_wire if i == 0 else work_wires_reversed[i - 1] gates.append(qml.Toffoli(wires=[ctrl1, ctrl2, t])) for i in range(len(work_wires) - 1): ctrl1 = control_wires_reversed[i + 1] ctrl2 = work_wires_reversed[i + 1] t = work_wires_reversed[i] gates.append(qml.Toffoli(wires=[ctrl1, ctrl2, t])) gates.append(qml.Toffoli(wires=[*control_wires[:2], work_wires[0]])) for i in reversed(range(len(work_wires) - 1)): ctrl1 = control_wires_reversed[i + 1] ctrl2 = work_wires_reversed[i + 1] t = work_wires_reversed[i] gates.append(qml.Toffoli(wires=[ctrl1, ctrl2, t])) return gates
class TestCircuitDrawer: """Test the CircuitDrawer class.""" def test_resolve_representation(self, dummy_circuit_drawer): """Test that resolve_representation calls the representation resolver with the proper arguments.""" dummy_circuit_drawer.representation_resolver.element_representation = Mock( return_value="Test" ) dummy_circuit_drawer.resolve_representation(Grid(dummy_raw_operation_grid), Grid()) args_tuples = [ call[0] for call in dummy_circuit_drawer.representation_resolver.element_representation.call_args_list ] for idx, wire in enumerate(dummy_raw_operation_grid): for op in wire: assert (op, idx) in args_tuples interlocking_multiwire_gate_grid = to_grid( [[qml.CNOT(wires=[0, 4]), qml.CNOT(wires=[1, 5]), qml.Toffoli(wires=[2, 3, 6])]], 7 ) interlocking_multiwire_gate_representation_grid = Grid( [ ["╭", "", ""], ["│", "╭", ""], ["│", "│", "╭"], ["│", "│", "├"], ["╰", "│", "│"], ["", "╰", "│"], ["", "", "╰"], ] ) multiwire_and_single_wire_gate_grid = to_grid( [[qml.Toffoli(wires=[0, 3, 4]), qml.PauliX(wires=[1]), qml.Hadamard(wires=[2])]], 5 ) multiwire_and_single_wire_gate_representation_grid = Grid([["╭"], ["│"], ["│"], ["├"], ["╰"]]) all_wire_state_preparation_grid = to_grid( [[qml.BasisState(np.array([0, 1, 0, 0, 1, 1]), wires=[0, 1, 2, 3, 4, 5])]], 6 ) all_wire_state_preparation_representation_grid = Grid( [["╭"], ["├"], ["├"], ["├"], ["├"], ["╰"]] ) multiwire_gate_grid = to_grid( [[qml.CNOT(wires=[0, 1]), qml.PauliX(2), qml.CNOT(wires=[3, 4])]], 5 ) multiwire_gate_representation_grid = Grid( [ ["╭"], ["╰"], [""], ["╭"], ["╰"], ] ) multi_and_single_wire_gate_grid = to_grid( [ [ qml.CNOT(wires=[0, 1]), qml.PauliX(2), qml.PauliX(4), qml.CNOT(wires=[3, 5]), qml.Hadamard(6), ] ], 7, ) multi_and_single_wire_gate_representation_grid = Grid( [ ["╭"], ["╰"], [""], ["╭"], ["│"], ["╰"], [""], ] ) @pytest.mark.parametrize( "grid,target_representation_grid", [ (interlocking_multiwire_gate_grid, interlocking_multiwire_gate_representation_grid), ( multiwire_and_single_wire_gate_grid, multiwire_and_single_wire_gate_representation_grid, ), (all_wire_state_preparation_grid, all_wire_state_preparation_representation_grid), (multiwire_gate_grid, multiwire_gate_representation_grid), (multi_and_single_wire_gate_grid, multi_and_single_wire_gate_representation_grid), ], ) def test_resolve_decorations(self, grid, target_representation_grid): """Test that decorations are properly resolved.""" representation_grid = Grid() raw_operator_grid = grid.raw_grid # make a dummy observable grid raw_observable_grid = [[None] for _ in range(len(raw_operator_grid))] drawer = CircuitDrawer(raw_operator_grid, raw_observable_grid, Wires(range(10))) drawer.resolve_decorations(grid, representation_grid) assert_nested_lists_equal(representation_grid.raw_grid, target_representation_grid.raw_grid) CNOT04 = qml.CNOT(wires=[0, 4]) CNOT15 = qml.CNOT(wires=[1, 5]) Toffoli236 = qml.Toffoli(wires=[2, 3, 6]) interlocking_CNOT_grid = to_grid([[CNOT04, CNOT15, Toffoli236]], 7) moved_interlocking_CNOT_grid = to_grid([[Toffoli236], [CNOT15], [CNOT04]], 7) SWAP02 = qml.SWAP(wires=[0, 2]) SWAP35 = qml.SWAP(wires=[3, 5]) SWAP14 = qml.SWAP(wires=[1, 4]) SWAP24 = qml.SWAP(wires=[2, 4]) interlocking_SWAP_grid = to_grid([[SWAP02, SWAP35, SWAP14], [SWAP24]], 6) moved_interlocking_SWAP_grid = to_grid([[SWAP35], [SWAP14], [SWAP02], [SWAP24]], 6) @pytest.mark.parametrize( "grid,target_grid", [ (interlocking_CNOT_grid, moved_interlocking_CNOT_grid), (interlocking_SWAP_grid, moved_interlocking_SWAP_grid), ], ) def test_move_multi_wire_gates(self, grid, target_grid): """Test that decorations are properly resolved.""" operator_grid = grid.copy() raw_operator_grid = operator_grid.raw_grid # make a dummy observable grid raw_observable_grid = [[None] for _ in range(len(raw_operator_grid))] drawer = CircuitDrawer(raw_operator_grid, raw_observable_grid, Wires(range(10))) drawer.move_multi_wire_gates(operator_grid) assert_nested_lists_equal(operator_grid.raw_grid, target_grid.raw_grid)
def test_matrix(self): """Test if ControlledQubitUnitary returns the correct matrix for a control-control-X (Toffoli) gate""" mat = qml.ControlledQubitUnitary(X, control_wires=[0, 1], wires=2).matrix mat2 = qml.Toffoli(wires=[0, 1, 2]).matrix assert np.allclose(mat, mat2)
def test_qubit_unitary_decomposition_multiqubit_invalid(self): """Test that QubitUnitary is not decomposed for more than two qubits.""" U = qml.Toffoli(wires=[0, 1, 2]).matrix with pytest.raises(NotImplementedError, match="only supported for single- and two-qubit"): qml.QubitUnitary.decomposition(U, wires=[0, 1, 2])
def qfunc(): qml.PauliX(0) qml.PauliX(5) qml.Toffoli(wires=[5, 1, 0]) return state()
import pytest import pennylane as qml from pennylane.transforms.optimization.optimization_utils import ( find_next_gate, _yzy_to_zyz, fuse_rot_angles, ) from utils import check_matrix_equivalence from pennylane.transforms.get_unitary_matrix import get_unitary_matrix sample_op_list = [ qml.Hadamard(wires="a"), qml.CNOT(wires=["a", "b"]), qml.Toffoli(wires=[0, 1, "b"]), qml.Hadamard(wires="c"), ] class TestFindNextGate: @pytest.mark.parametrize( ("wires,op_list,next_gate_idx"), [ ("a", sample_op_list, 0), ("b", sample_op_list, 1), ("e", sample_op_list, None), ([0, 2], sample_op_list, 2), ([0, 1], sample_op_list, 2), ("c", sample_op_list, 3), ],
def qfunc(): qml.PauliX(wires="a") qml.CNOT(wires=["a", "c"]) qml.RX(0.2, wires="a") qml.Toffoli(wires=["c", "a", "b"])
class TestQVMBasic(BaseTest): """Unit tests for the QVM simulator.""" # pylint: disable=protected-access def test_identity_expectation(self, shots, qvm, compiler): """Test that identity expectation value (i.e. the trace) is 1""" theta = 0.432 phi = 0.123 dev = plf.QVMDevice(device="2q-qvm", shots=shots) with qml.tape.QuantumTape() as tape: qml.RX(theta, wires=[0]) qml.RX(phi, wires=[1]) qml.CNOT(wires=[0, 1]) O1 = qml.expval(qml.Identity(wires=[0])) O2 = qml.expval(qml.Identity(wires=[1])) dev.apply(tape.operations, rotations=tape.diagonalizing_gates) dev._samples = dev.generate_samples() res = np.array([dev.expval(O1.obs), dev.expval(O2.obs)]) # below are the analytic expectation values for this circuit (trace should always be 1) self.assertAllAlmostEqual(res, np.array([1, 1]), delta=3 / np.sqrt(shots)) def test_pauliz_expectation(self, shots, qvm, compiler): """Test that PauliZ expectation value is correct""" theta = 0.432 phi = 0.123 dev = plf.QVMDevice(device="2q-qvm", shots=shots) with qml.tape.QuantumTape() as tape: qml.RX(theta, wires=[0]) qml.RX(phi, wires=[1]) qml.CNOT(wires=[0, 1]) O1 = qml.expval(qml.PauliZ(wires=[0])) O2 = qml.expval(qml.PauliZ(wires=[1])) dev.apply(tape.operations, rotations=tape.diagonalizing_gates) dev._samples = dev.generate_samples() res = np.array([dev.expval(O1.obs), dev.expval(O2.obs)]) # below are the analytic expectation values for this circuit self.assertAllAlmostEqual( res, np.array([np.cos(theta), np.cos(theta) * np.cos(phi)]), delta=3 / np.sqrt(shots)) def test_paulix_expectation(self, shots, qvm, compiler): """Test that PauliX expectation value is correct""" theta = 0.432 phi = 0.123 dev = plf.QVMDevice(device="2q-qvm", shots=shots) with qml.tape.QuantumTape() as tape: qml.RY(theta, wires=[0]) qml.RY(phi, wires=[1]) qml.CNOT(wires=[0, 1]) O1 = qml.expval(qml.PauliX(wires=[0])) O2 = qml.expval(qml.PauliX(wires=[1])) dev.apply(tape.operations, rotations=tape.diagonalizing_gates) dev._samples = dev.generate_samples() res = np.array([dev.expval(O1.obs), dev.expval(O2.obs)]) # below are the analytic expectation values for this circuit self.assertAllAlmostEqual( res, np.array([np.sin(theta) * np.sin(phi), np.sin(phi)]), delta=3 / np.sqrt(shots)) def test_pauliy_expectation(self, shots, qvm, compiler): """Test that PauliY expectation value is correct""" theta = 0.432 phi = 0.123 dev = plf.QVMDevice(device="2q-qvm", shots=shots) with qml.tape.QuantumTape() as tape: qml.RX(theta, wires=[0]) qml.RX(phi, wires=[1]) qml.CNOT(wires=[0, 1]) O1 = qml.expval(qml.PauliY(wires=[0])) O2 = qml.expval(qml.PauliY(wires=[1])) dev.apply(tape.operations, rotations=tape.diagonalizing_gates) dev._samples = dev.generate_samples() res = np.array([dev.expval(O1.obs), dev.expval(O2.obs)]) # below are the analytic expectation values for this circuit self.assertAllAlmostEqual(res, np.array([0, -np.cos(theta) * np.sin(phi)]), delta=3 / np.sqrt(shots)) def test_hadamard_expectation(self, shots, qvm, compiler): """Test that Hadamard expectation value is correct""" theta = 0.432 phi = 0.123 dev = plf.QVMDevice(device="2q-qvm", shots=shots) with qml.tape.QuantumTape() as tape: qml.RY(theta, wires=[0]) qml.RY(phi, wires=[1]) qml.CNOT(wires=[0, 1]) O1 = qml.expval(qml.Hadamard(wires=[0])) O2 = qml.expval(qml.Hadamard(wires=[1])) dev.apply(tape.operations, rotations=tape.diagonalizing_gates) dev._samples = dev.generate_samples() res = np.array([dev.expval(O1.obs), dev.expval(O2.obs)]) # below are the analytic expectation values for this circuit expected = np.array([ np.sin(theta) * np.sin(phi) + np.cos(theta), np.cos(theta) * np.cos(phi) + np.sin(phi) ]) / np.sqrt(2) self.assertAllAlmostEqual(res, expected, delta=3 / np.sqrt(shots)) @flaky(max_runs=10, min_passes=3) def test_hermitian_expectation(self, shots, qvm, compiler): """Test that arbitrary Hermitian expectation values are correct. As the results coming from the qvm are stochastic, a constraint of 3 out of 5 runs was added. """ theta = 0.432 phi = 0.123 dev = plf.QVMDevice(device="2q-qvm", shots=shots) with qml.tape.QuantumTape() as tape: qml.RY(theta, wires=[0]) qml.RY(phi, wires=[1]) qml.CNOT(wires=[0, 1]) O1 = qml.expval(qml.Hermitian(H, wires=[0])) O2 = qml.expval(qml.Hermitian(H, wires=[1])) dev.apply(tape.operations, rotations=tape.diagonalizing_gates) dev._samples = dev.generate_samples() res = np.array([dev.expval(O1.obs), dev.expval(O2.obs)]) # below are the analytic expectation values for this circuit with arbitrary # Hermitian observable H a = H[0, 0] re_b = H[0, 1].real d = H[1, 1] ev1 = ((a - d) * np.cos(theta) + 2 * re_b * np.sin(theta) * np.sin(phi) + a + d) / 2 ev2 = ((a - d) * np.cos(theta) * np.cos(phi) + 2 * re_b * np.sin(phi) + a + d) / 2 expected = np.array([ev1, ev2]) self.assertAllAlmostEqual(res, expected, delta=4 / np.sqrt(shots)) def test_multi_qubit_hermitian_expectation(self, shots, qvm, compiler): """Test that arbitrary multi-qubit Hermitian expectation values are correct""" theta = 0.432 phi = 0.123 A = np.array([ [-6, 2 + 1j, -3, -5 + 2j], [2 - 1j, 0, 2 - 1j, -5 + 4j], [-3, 2 + 1j, 0, -4 + 3j], [-5 - 2j, -5 - 4j, -4 - 3j, -6], ]) dev = plf.QVMDevice(device="2q-qvm", shots=10 * shots) with qml.tape.QuantumTape() as tape: qml.RY(theta, wires=[0]) qml.RY(phi, wires=[1]) qml.CNOT(wires=[0, 1]) O1 = qml.expval(qml.Hermitian(A, wires=[0, 1])) dev.apply(tape.operations, rotations=tape.diagonalizing_gates) dev._samples = dev.generate_samples() res = np.array([dev.expval(O1.obs)]) # below is the analytic expectation value for this circuit with arbitrary # Hermitian observable A expected = 0.5 * (6 * np.cos(theta) * np.sin(phi) - np.sin(theta) * (8 * np.sin(phi) + 7 * np.cos(phi) + 3) - 2 * np.sin(phi) - 6 * np.cos(phi) - 6) self.assertAllAlmostEqual(res, expected, delta=5 / np.sqrt(shots)) def test_var(self, shots, qvm, compiler): """Tests for variance calculation""" dev = plf.QVMDevice(device="2q-qvm", shots=shots) phi = 0.543 theta = 0.6543 with qml.tape.QuantumTape() as tape: qml.RX(phi, wires=[0]) qml.RY(theta, wires=[0]) O1 = qml.var(qml.PauliZ(wires=[0])) dev.apply(tape.operations, rotations=tape.diagonalizing_gates) dev._samples = dev.generate_samples() var = np.array([dev.var(O1.obs)]) expected = 0.25 * (3 - np.cos(2 * theta) - 2 * np.cos(theta)**2 * np.cos(2 * phi)) self.assertAlmostEqual(var, expected, delta=3 / np.sqrt(shots)) def test_var_hermitian(self, shots, qvm, compiler): """Tests for variance calculation using an arbitrary Hermitian observable""" dev = plf.QVMDevice(device="2q-qvm", shots=100 * shots) phi = 0.543 theta = 0.6543 A = np.array([[4, -1 + 6j], [-1 - 6j, 2]]) with qml.tape.QuantumTape() as tape: qml.RX(phi, wires=[0]) qml.RY(theta, wires=[0]) O1 = qml.var(qml.Hermitian(A, wires=[0])) # test correct variance for <A> of a rotated state dev.apply(tape.operations, rotations=tape.diagonalizing_gates) dev._samples = dev.generate_samples() var = np.array([dev.var(O1.obs)]) expected = 0.5 * (2 * np.sin(2 * theta) * np.cos(phi)**2 + 24 * np.sin(phi) * np.cos(phi) * (np.sin(theta) - np.cos(theta)) + 35 * np.cos(2 * phi) + 39) self.assertAlmostEqual(var, expected, delta=0.3) @pytest.mark.parametrize( "op", [ qml.QubitUnitary(np.array(U), wires=0), qml.BasisState(np.array([1, 1, 1]), wires=list(range(3))), qml.PauliX(wires=0), qml.PauliY(wires=0), qml.PauliZ(wires=0), qml.S(wires=0), qml.T(wires=0), qml.RX(0.432, wires=0), qml.RY(0.432, wires=0), qml.RZ(0.432, wires=0), qml.Hadamard(wires=0), qml.Rot(0.432, 2, 0.324, wires=0), qml.Toffoli(wires=[0, 1, 2]), qml.SWAP(wires=[0, 1]), qml.CSWAP(wires=[0, 1, 2]), qml.CZ(wires=[0, 1]), qml.CNOT(wires=[0, 1]), qml.PhaseShift(0.432, wires=0), qml.CSWAP(wires=[0, 1, 2]), plf.CPHASE(0.432, 2, wires=[0, 1]), plf.ISWAP(wires=[0, 1]), plf.PSWAP(0.432, wires=[0, 1]), ], ) def test_apply(self, op, apply_unitary, shots, qvm, compiler): """Test the application of gates to a state""" dev = plf.QVMDevice(device="3q-qvm", shots=shots, parametric_compilation=False) obs = qml.expval(qml.PauliZ(0)) if op.name == "QubitUnitary": state = apply_unitary(U, 3) elif op.name == "BasisState": state = np.array([0, 0, 0, 0, 0, 0, 0, 1]) elif op.name == "CPHASE": state = apply_unitary(test_operation_map["CPHASE"](0.432, 2), 3) elif op.name == "ISWAP": state = apply_unitary(test_operation_map["ISWAP"], 3) elif op.name == "PSWAP": state = apply_unitary(test_operation_map["PSWAP"](0.432), 3) else: state = apply_unitary(op.matrix, 3) with qml.tape.QuantumTape() as tape: qml.apply(op) obs dev.apply(tape.operations, rotations=tape.diagonalizing_gates) dev._samples = dev.generate_samples() res = dev.expval(obs.obs) expected = np.vdot(state, np.kron(np.kron(Z, I), I) @ state) # verify the device is now in the expected state # Note we have increased the tolerance here, since we are only # performing 1024 shots. self.assertAllAlmostEqual(res, expected, delta=3 / np.sqrt(shots)) def test_sample_values(self, qvm, tol): """Tests if the samples returned by sample have the correct values """ dev = plf.QVMDevice(device="1q-qvm", shots=10) with qml.tape.QuantumTape() as tape: qml.RX(1.5708, wires=[0]) O1 = qml.expval(qml.PauliZ(wires=[0])) dev.apply(tape.operations, rotations=tape.diagonalizing_gates) dev._samples = dev.generate_samples() s1 = dev.sample(O1.obs) # s1 should only contain 1 and -1 self.assertAllAlmostEqual(s1**2, 1, delta=tol) self.assertAllAlmostEqual(s1, 1 - 2 * dev._samples[:, 0], delta=tol) def test_sample_values_hermitian(self, qvm, tol): """Tests if the samples of a Hermitian observable returned by sample have the correct values """ theta = 0.543 shots = 1_000_000 A = np.array([[1, 2j], [-2j, 0]]) dev = plf.QVMDevice(device="1q-qvm", shots=shots) with qml.tape.QuantumTape() as tape: qml.RX(theta, wires=[0]) O1 = qml.sample(qml.Hermitian(A, wires=[0])) dev.apply(tape.operations, rotations=tape.diagonalizing_gates) dev._samples = dev.generate_samples() s1 = dev.sample(O1.obs) # s1 should only contain the eigenvalues of # the hermitian matrix eigvals = np.linalg.eigvalsh(A) assert np.allclose(sorted(list(set(s1))), sorted(eigvals), atol=tol, rtol=0) # the analytic mean is 2*sin(theta)+0.5*cos(theta)+0.5 assert np.allclose(np.mean(s1), 2 * np.sin(theta) + 0.5 * np.cos(theta) + 0.5, atol=0.1, rtol=0) # the analytic variance is 0.25*(sin(theta)-4*cos(theta))^2 assert np.allclose(np.var(s1), 0.25 * (np.sin(theta) - 4 * np.cos(theta))**2, atol=0.1, rtol=0) def test_sample_values_hermitian_multi_qubit(self, qvm, tol): """Tests if the samples of a multi-qubit Hermitian observable returned by sample have the correct values """ theta = 0.543 shots = 100_000 A = np.array([ [1, 2j, 1 - 2j, 0.5j], [-2j, 0, 3 + 4j, 1], [1 + 2j, 3 - 4j, 0.75, 1.5 - 2j], [-0.5j, 1, 1.5 + 2j, -1], ]) dev = plf.QVMDevice(device="2q-qvm", shots=shots) with qml.tape.QuantumTape() as tape: qml.RX(theta, wires=[0]) qml.RY(2 * theta, wires=[1]) qml.CNOT(wires=[0, 1]) O1 = qml.sample(qml.Hermitian(A, wires=[0, 1])) dev.apply(tape.operations, rotations=tape.diagonalizing_gates) dev._samples = dev.generate_samples() s1 = dev.sample(O1.obs) # s1 should only contain the eigenvalues of # the hermitian matrix eigvals = np.linalg.eigvalsh(A) assert np.allclose(sorted(list(set(s1))), sorted(eigvals), atol=tol, rtol=0) # make sure the mean matches the analytic mean expected = (88 * np.sin(theta) + 24 * np.sin(2 * theta) - 40 * np.sin(3 * theta) + 5 * np.cos(theta) - 6 * np.cos(2 * theta) + 27 * np.cos(3 * theta) + 6) / 32 assert np.allclose(np.mean(s1), expected, atol=0.1, rtol=0) def test_wires_argument(self): """Test that the wires argument gets processed correctly.""" dev_no_wires = plf.QVMDevice(device="2q-qvm", shots=5) assert dev_no_wires.wires == Wires(range(2)) with pytest.raises(ValueError, match="Device has a fixed number of"): plf.QVMDevice(device="2q-qvm", shots=5, wires=1000) dev_iterable_wires = plf.QVMDevice(device="2q-qvm", shots=5, wires=range(2)) assert dev_iterable_wires.wires == Wires(range(2)) with pytest.raises(ValueError, match="Device has a fixed number of"): plf.QVMDevice(device="2q-qvm", shots=5, wires=range(1000)) @pytest.mark.parametrize("shots", list(range(0, -10, -1))) def test_raise_error_if_shots_is_not_positive(self, shots): """Test that instantiating a QVMDevice if the number of shots is not a postivie integer raises an error""" with pytest.raises( ValueError, match="Number of shots must be a positive integer."): dev = plf.QVMDevice(device="2q-qvm", shots=shots) def test_raise_error_if_shots_is_none(self, shots): """Test that instantiating a QVMDevice to be used for analytic computations raises an error""" with pytest.raises( ValueError, match="QVM device cannot be used for analytic computations."): dev = plf.QVMDevice(device="2q-qvm", shots=None) @pytest.mark.parametrize( "device", ["2q-qvm", np.random.choice(TEST_QPU_LATTICES)]) def test_timeout_set_correctly(self, shots, device): """Test that the timeout attrbiute for the QuantumComputer stored by the QVMDevice is set correctly when passing a value as keyword argument""" dev = plf.QVMDevice(device=device, shots=shots, timeout=100) assert dev.qc.compiler.client.timeout == 100 @pytest.mark.parametrize( "device", ["2q-qvm", np.random.choice(TEST_QPU_LATTICES)]) def test_timeout_default(self, shots, device): """Test that the timeout attrbiute for the QuantumComputer stored by the QVMDevice is set correctly when passing a value as keyword argument""" dev = plf.QVMDevice(device=device, shots=shots) qc = pyquil.get_qc(device, as_qvm=True) # Check that the timeouts are equal (it has not been changed as a side effect of # instantiation assert dev.qc.compiler.client.timeout == qc.compiler.client.timeout def test_compiled_program_stored(self, qvm, monkeypatch): """Test that QVM device stores the latest compiled program.""" dev = qml.device("forest.qvm", device="2q-qvm") dev.compiled_program is None theta = 0.432 phi = 0.123 with qml.tape.QuantumTape() as tape: qml.RX(theta, wires=[0]) qml.RX(phi, wires=[1]) qml.CNOT(wires=[0, 1]) O1 = qml.expval(qml.Identity(wires=[0])) O2 = qml.expval(qml.Identity(wires=[1])) dev.apply(tape.operations, rotations=tape.diagonalizing_gates) dev.generate_samples() dev.compiled_program is not None def test_stored_compiled_program_correct(self, qvm, monkeypatch): """Test that QVM device stores the latest compiled program.""" dev = qml.device("forest.qvm", device="2q-qvm") dev.compiled_program is None theta = 0.432 with qml.tape.QuantumTape() as tape: qml.RZ(theta, wires=[0]) qml.CZ(wires=[0, 1]) O1 = qml.expval(qml.PauliZ(wires=[0])) dev.apply(tape.operations, rotations=tape.diagonalizing_gates) dev.generate_samples() dev.compiled_program.program == compiled_program
"PauliZ": qml.PauliZ(wires=[0]), "PhaseShift": qml.PhaseShift(0, wires=[0]), "ControlledPhaseShift": qml.ControlledPhaseShift(0, wires=[0, 1]), "QubitStateVector": qml.QubitStateVector(np.array([1.0, 0.0]), wires=[0]), "QubitUnitary": qml.QubitUnitary(np.eye(2), wires=[0]), "ControlledQubitUnitary": qml.ControlledQubitUnitary(np.eye(2), control_wires=[1], wires=[0]), "MultiControlledX": qml.MultiControlledX(control_wires=[1, 2], wires=[0]), "RX": qml.RX(0, wires=[0]), "RY": qml.RY(0, wires=[0]), "RZ": qml.RZ(0, wires=[0]), "Rot": qml.Rot(0, 0, 0, wires=[0]), "S": qml.S(wires=[0]), "SWAP": qml.SWAP(wires=[0, 1]), "T": qml.T(wires=[0]), "SX": qml.SX(wires=[0]), "Toffoli": qml.Toffoli(wires=[0, 1, 2]), "QFT": qml.QFT(wires=[0, 1, 2]), "SingleExcitation": qml.SingleExcitation(0, wires=[0, 1]), "SingleExcitationPlus": qml.SingleExcitationPlus(0, wires=[0, 1]), "SingleExcitationMinus": qml.SingleExcitationMinus(0, wires=[0, 1]), "DoubleExcitation": qml.DoubleExcitation(0, wires=[0, 1, 2, 3]), "DoubleExcitationPlus": qml.DoubleExcitationPlus(0, wires=[0, 1, 2, 3]), "DoubleExcitationMinus": qml.DoubleExcitationMinus(0, wires=[0, 1, 2, 3]), "QubitCarry": qml.QubitCarry(wires=[0, 1, 2, 3]), "QubitSum:": qml.QubitSum(wires=[0, 1, 2]), } all_ops = ops.keys() # non-parametrized qubit gates I = np.identity(2)
(qml.Hadamard(0), "H", "H"), (qml.PauliX(0), "X", "X"), (qml.PauliY(0), "Y", "Y"), (qml.PauliZ(0), "Z", "Z"), (qml.S(wires=0), "S", "S⁻¹"), (qml.T(wires=0), "T", "T⁻¹"), (qml.SX(wires=0), "SX", "SX⁻¹"), (qml.CNOT(wires=(0, 1)), "⊕", "⊕"), (qml.CZ(wires=(0, 1)), "Z", "Z"), (qml.CY(wires=(0, 1)), "Y", "Y"), (qml.SWAP(wires=(0, 1)), "SWAP", "SWAP⁻¹"), (qml.ISWAP(wires=(0, 1)), "ISWAP", "ISWAP⁻¹"), (qml.SISWAP(wires=(0, 1)), "SISWAP", "SISWAP⁻¹"), (qml.SQISW(wires=(0, 1)), "SISWAP", "SISWAP⁻¹"), (qml.CSWAP(wires=(0, 1, 2)), "SWAP", "SWAP"), (qml.Toffoli(wires=(0, 1, 2)), "⊕", "⊕"), (qml.MultiControlledX(control_wires=(0, 1, 2), wires=(3)), "⊕", "⊕"), (qml.Barrier(0), "||", "||"), (qml.WireCut(wires=0), "//", "//"), ] @pytest.mark.parametrize("op, label1, label2", label_data) def test_label_method(op, label1, label2): assert op.label() == label1 assert op.label(decimals=2) == label1 op.inv() assert op.label() == label2
def circuit(x, y): qml.RX(x[0], wires=0) qml.Toffoli(wires=(0, 1, 2)) qml.CRY(x[1], wires=(0, 1)) qml.Rot(x[2], x[3], y, wires=2) return qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliX(1))
def circuitz(): qml.Hadamard(wires=0) qml.Hadamard(wires=1) qml.Hadamard(wires=2) qml.Toffoli(wires=[0, 1, 2]) return qml.expval(qml.PauliZ(2))
ax.annotate("CSWAP", xy=(2, 2.5), xycoords='data', xytext=(2.8, 1.5), textcoords='data', arrowprops={'facecolor': 'black'}, fontsize=14) plt.savefig(folder / "postprocessing.png") plt.close() if __name__ == "__main__": with qml.tape.QuantumTape() as tape: qml.templates.GroverOperator(wires=(0, 1, 2, 3)) qml.Toffoli(wires=(0, 1, 2)) qml.CSWAP(wires=(0, 2, 3)) qml.RX(1.2345, wires=0) qml.CRZ(1.2345, wires=(3, 0)) qml.expval(qml.PauliZ(0)) default(tape) decimals() wire_order(tape) show_all_wires(tape) mpl_style(tape) rcparams(tape) wires_and_labels(tape) postprocessing(tape)
def expand(self): with qml.tape.QuantumTape() as tape: qml.Toffoli(wires=[self.wires[0],self.wires[2],self.wires[3]]) qml.CNOT(wires=[self.wires[1],self.wires[2]]) qml.Toffoli(wires=self.wires[1:]) return tape
def qfunc(): qml.PauliX(0) qml.PauliX(5) qml.Toffoli(wires=[5, 1, 0]) return [qml.expval(qml.PauliY(0)), qml.probs(wires=[1, 2, 4])]
def f2(): qml.QubitUnitary(U1, wires=range(3)) qml.Toffoli(wires=control_wires + [target_wire]) qml.QubitUnitary(U2, wires=range(3)) return qml.state()
def oracle(): qml.Hadamard(wires[-1]) qml.Toffoli(wires=wires) qml.Hadamard(wires[-1])
class TestRepresentationResolver: """Test the RepresentationResolver class.""" @pytest.mark.parametrize( "list,element,index,list_after", [ ([1, 2, 3], 2, 1, [1, 2, 3]), ([1, 2, 2, 3], 2, 1, [1, 2, 2, 3]), ([1, 2, 3], 4, 3, [1, 2, 3, 4]), ], ) def test_index_of_array_or_append(self, list, element, index, list_after): """Test the method index_of_array_or_append.""" assert RepresentationResolver.index_of_array_or_append(element, list) == index assert list == list_after @pytest.mark.parametrize( "par,expected", [ (3, "3"), (5.236422, "5.24"), ], ) def test_single_parameter_representation(self, unicode_representation_resolver, par, expected): """Test that single parameters are properly resolved.""" assert unicode_representation_resolver.single_parameter_representation( par) == expected @pytest.mark.parametrize( "op,wire,target", [ (qml.PauliX(wires=[1]), 1, "X"), (qml.CNOT(wires=[0, 1]), 1, "X"), (qml.CNOT(wires=[0, 1]), 0, "C"), (qml.Toffoli(wires=[0, 2, 1]), 1, "X"), (qml.Toffoli(wires=[0, 2, 1]), 0, "C"), (qml.Toffoli(wires=[0, 2, 1]), 2, "C"), (qml.CSWAP(wires=[0, 2, 1]), 1, "SWAP"), (qml.CSWAP(wires=[0, 2, 1]), 2, "SWAP"), (qml.CSWAP(wires=[0, 2, 1]), 0, "C"), (qml.PauliY(wires=[1]), 1, "Y"), (qml.PauliZ(wires=[1]), 1, "Z"), (qml.CZ(wires=[0, 1]), 1, "Z"), (qml.CZ(wires=[0, 1]), 0, "C"), (qml.Identity(wires=[1]), 1, "I"), (qml.Hadamard(wires=[1]), 1, "H"), (qml.PauliRot(3.14, "XX", wires=[0, 1]), 1, "RX(3.14)"), (qml.PauliRot(3.14, "YZ", wires=[0, 1]), 1, "RZ(3.14)"), (qml.PauliRot(3.14, "IXYZI", wires=[0, 1, 2, 3, 4 ]), 0, "RI(3.14)"), (qml.PauliRot(3.14, "IXYZI", wires=[0, 1, 2, 3, 4 ]), 1, "RX(3.14)"), (qml.PauliRot(3.14, "IXYZI", wires=[0, 1, 2, 3, 4 ]), 2, "RY(3.14)"), (qml.PauliRot(3.14, "IXYZI", wires=[0, 1, 2, 3, 4 ]), 3, "RZ(3.14)"), (qml.PauliRot(3.14, "IXYZI", wires=[0, 1, 2, 3, 4 ]), 4, "RI(3.14)"), (qml.MultiRZ(3.14, wires=[0, 1]), 0, "RZ(3.14)"), (qml.MultiRZ(3.14, wires=[0, 1]), 1, "RZ(3.14)"), (qml.CRX(3.14, wires=[0, 1]), 1, "RX(3.14)"), (qml.CRX(3.14, wires=[0, 1]), 0, "C"), (qml.CRY(3.14, wires=[0, 1]), 1, "RY(3.14)"), (qml.CRY(3.14, wires=[0, 1]), 0, "C"), (qml.CRZ(3.14, wires=[0, 1]), 1, "RZ(3.14)"), (qml.CRZ(3.14, wires=[0, 1]), 0, "C"), (qml.CRot(3.14, 2.14, 1.14, wires=[0, 1 ]), 1, "Rot(3.14, 2.14, 1.14)"), (qml.CRot(3.14, 2.14, 1.14, wires=[0, 1]), 0, "C"), (qml.PhaseShift(3.14, wires=[0]), 0, "Rϕ(3.14)"), (qml.Beamsplitter(1, 2, wires=[0, 1]), 1, "BS(1, 2)"), (qml.Beamsplitter(1, 2, wires=[0, 1]), 0, "BS(1, 2)"), (qml.Squeezing(1, 2, wires=[1]), 1, "S(1, 2)"), (qml.TwoModeSqueezing(1, 2, wires=[0, 1]), 1, "S(1, 2)"), (qml.TwoModeSqueezing(1, 2, wires=[0, 1]), 0, "S(1, 2)"), (qml.Displacement(1, 2, wires=[1]), 1, "D(1, 2)"), (qml.NumberOperator(wires=[1]), 1, "n"), (qml.Rotation(3.14, wires=[1]), 1, "R(3.14)"), (qml.ControlledAddition(3.14, wires=[0, 1]), 1, "X(3.14)"), (qml.ControlledAddition(3.14, wires=[0, 1]), 0, "C"), (qml.ControlledPhase(3.14, wires=[0, 1]), 1, "Z(3.14)"), (qml.ControlledPhase(3.14, wires=[0, 1]), 0, "C"), (qml.ThermalState(3, wires=[1]), 1, "Thermal(3)"), ( qml.GaussianState(np.array([[2, 0], [0, 2]]), np.array([1, 2]), wires=[1]), 1, "Gaussian(M0,M1)", ), (qml.QuadraticPhase(3.14, wires=[1]), 1, "P(3.14)"), (qml.RX(3.14, wires=[1]), 1, "RX(3.14)"), (qml.S(wires=[2]), 2, "S"), (qml.T(wires=[2]), 2, "T"), (qml.RX(3.14, wires=[1]), 1, "RX(3.14)"), (qml.RY(3.14, wires=[1]), 1, "RY(3.14)"), (qml.RZ(3.14, wires=[1]), 1, "RZ(3.14)"), (qml.Rot(3.14, 2.14, 1.14, wires=[1]), 1, "Rot(3.14, 2.14, 1.14)"), (qml.U1(3.14, wires=[1]), 1, "U1(3.14)"), (qml.U2(3.14, 2.14, wires=[1]), 1, "U2(3.14, 2.14)"), (qml.U3(3.14, 2.14, 1.14, wires=[1]), 1, "U3(3.14, 2.14, 1.14)"), (qml.BasisState(np.array([0, 1, 0]), wires=[1, 2, 3]), 1, "|0⟩"), (qml.BasisState(np.array([0, 1, 0]), wires=[1, 2, 3]), 2, "|1⟩"), (qml.BasisState(np.array([0, 1, 0]), wires=[1, 2, 3]), 3, "|0⟩"), (qml.QubitStateVector(np.array([0, 1, 0, 0]), wires=[1, 2]), 1, "QubitStateVector(M0)"), (qml.QubitStateVector(np.array([0, 1, 0, 0]), wires=[1, 2]), 2, "QubitStateVector(M0)"), (qml.QubitUnitary(np.eye(2), wires=[1]), 1, "U0"), (qml.QubitUnitary(np.eye(4), wires=[1, 2]), 2, "U0"), (qml.Kerr(3.14, wires=[1]), 1, "Kerr(3.14)"), (qml.CrossKerr(3.14, wires=[1, 2]), 1, "CrossKerr(3.14)"), (qml.CrossKerr(3.14, wires=[1, 2]), 2, "CrossKerr(3.14)"), (qml.CubicPhase(3.14, wires=[1]), 1, "V(3.14)"), (qml.InterferometerUnitary( np.eye(4), wires=[1, 3]), 1, "InterferometerUnitary(M0)"), (qml.InterferometerUnitary( np.eye(4), wires=[1, 3]), 3, "InterferometerUnitary(M0)"), (qml.CatState(3.14, 2.14, 1, wires=[1]), 1, "CatState(3.14, 2.14, 1)"), (qml.CoherentState(3.14, 2.14, wires=[1]), 1, "CoherentState(3.14, 2.14)"), ( qml.FockDensityMatrix(np.kron(np.eye(4), np.eye(4)), wires=[1, 2]), 1, "FockDensityMatrix(M0)", ), ( qml.FockDensityMatrix(np.kron(np.eye(4), np.eye(4)), wires=[1, 2]), 2, "FockDensityMatrix(M0)", ), ( qml.DisplacedSqueezedState(3.14, 2.14, 1.14, 0.14, wires=[1]), 1, "DisplacedSqueezedState(3.14, 2.14, 1.14, 0.14)", ), (qml.FockState(7, wires=[1]), 1, "|7⟩"), (qml.FockStateVector(np.array([4, 5, 7]), wires=[1, 2, 3 ]), 1, "|4⟩"), (qml.FockStateVector(np.array([4, 5, 7]), wires=[1, 2, 3 ]), 2, "|5⟩"), (qml.FockStateVector(np.array([4, 5, 7]), wires=[1, 2, 3 ]), 3, "|7⟩"), (qml.SqueezedState(3.14, 2.14, wires=[1]), 1, "SqueezedState(3.14, 2.14)"), (qml.Hermitian(np.eye(4), wires=[1, 2]), 1, "H0"), (qml.Hermitian(np.eye(4), wires=[1, 2]), 2, "H0"), (qml.X(wires=[1]), 1, "x"), (qml.P(wires=[1]), 1, "p"), (qml.FockStateProjector(np.array([4, 5, 7]), wires=[1, 2, 3]), 1, "|4,5,7╳4,5,7|"), ( qml.PolyXP(np.array([1, 2, 0, -1.3, 6]), wires=[1]), 2, "1+2x₀-1.3x₁+6p₁", ), ( qml.PolyXP(np.array([[1.2, 2.3, 4.5], [-1.2, 1.2, -1.5], [-1.3, 4.5, 2.3]]), wires=[1]), 1, "1.2+1.1x₀+3.2p₀+1.2x₀²+2.3p₀²+3x₀p₀", ), ( qml.PolyXP( np.array([ [1.2, 2.3, 4.5, 0, 0], [-1.2, 1.2, -1.5, 0, 0], [-1.3, 4.5, 2.3, 0, 0], [0, 2.6, 0, 0, 0], [0, 0, 0, -4.7, -1.0], ]), wires=[1], ), 1, "1.2+1.1x₀+3.2p₀+1.2x₀²+2.3p₀²+3x₀p₀+2.6x₀x₁-p₁²-4.7x₁p₁", ), (qml.QuadOperator(3.14, wires=[1]), 1, "cos(3.14)x+sin(3.14)p"), (qml.PauliX(wires=[1]).inv(), 1, "X⁻¹"), (qml.CNOT(wires=[0, 1]).inv(), 1, "X⁻¹"), (qml.CNOT(wires=[0, 1]).inv(), 0, "C"), (qml.Toffoli(wires=[0, 2, 1]).inv(), 1, "X⁻¹"), (qml.Toffoli(wires=[0, 2, 1]).inv(), 0, "C"), (qml.Toffoli(wires=[0, 2, 1]).inv(), 2, "C"), (qml.measure.sample(wires=[0, 1]), 0, "basis"), # not providing an observable in (qml.measure.sample(wires=[0, 1]), 1, "basis"), # sample gets displayed as raw (two_wire_quantum_tape(), 0, "QuantumTape:T0"), (two_wire_quantum_tape(), 1, "QuantumTape:T0"), ], ) def test_operator_representation_unicode(self, unicode_representation_resolver, op, wire, target): """Test that an Operator instance is properly resolved.""" assert unicode_representation_resolver.operator_representation( op, wire) == target @pytest.mark.parametrize( "op,wire,target", [ (qml.PauliX(wires=[1]), 1, "X"), (qml.CNOT(wires=[0, 1]), 1, "X"), (qml.CNOT(wires=[0, 1]), 0, "C"), (qml.Toffoli(wires=[0, 2, 1]), 1, "X"), (qml.Toffoli(wires=[0, 2, 1]), 0, "C"), (qml.Toffoli(wires=[0, 2, 1]), 2, "C"), (qml.CSWAP(wires=[0, 2, 1]), 1, "SWAP"), (qml.CSWAP(wires=[0, 2, 1]), 2, "SWAP"), (qml.CSWAP(wires=[0, 2, 1]), 0, "C"), (qml.PauliY(wires=[1]), 1, "Y"), (qml.PauliZ(wires=[1]), 1, "Z"), (qml.CZ(wires=[0, 1]), 1, "Z"), (qml.CZ(wires=[0, 1]), 0, "C"), (qml.Identity(wires=[1]), 1, "I"), (qml.Hadamard(wires=[1]), 1, "H"), (qml.CRX(3.14, wires=[0, 1]), 1, "RX(3.14)"), (qml.CRX(3.14, wires=[0, 1]), 0, "C"), (qml.CRY(3.14, wires=[0, 1]), 1, "RY(3.14)"), (qml.CRY(3.14, wires=[0, 1]), 0, "C"), (qml.CRZ(3.14, wires=[0, 1]), 1, "RZ(3.14)"), (qml.CRZ(3.14, wires=[0, 1]), 0, "C"), (qml.CRot(3.14, 2.14, 1.14, wires=[0, 1 ]), 1, "Rot(3.14, 2.14, 1.14)"), (qml.CRot(3.14, 2.14, 1.14, wires=[0, 1]), 0, "C"), (qml.PhaseShift(3.14, wires=[0]), 0, "Rϕ(3.14)"), (qml.Beamsplitter(1, 2, wires=[0, 1]), 1, "BS(1, 2)"), (qml.Beamsplitter(1, 2, wires=[0, 1]), 0, "BS(1, 2)"), (qml.Squeezing(1, 2, wires=[1]), 1, "S(1, 2)"), (qml.TwoModeSqueezing(1, 2, wires=[0, 1]), 1, "S(1, 2)"), (qml.TwoModeSqueezing(1, 2, wires=[0, 1]), 0, "S(1, 2)"), (qml.Displacement(1, 2, wires=[1]), 1, "D(1, 2)"), (qml.NumberOperator(wires=[1]), 1, "n"), (qml.Rotation(3.14, wires=[1]), 1, "R(3.14)"), (qml.ControlledAddition(3.14, wires=[0, 1]), 1, "X(3.14)"), (qml.ControlledAddition(3.14, wires=[0, 1]), 0, "C"), (qml.ControlledPhase(3.14, wires=[0, 1]), 1, "Z(3.14)"), (qml.ControlledPhase(3.14, wires=[0, 1]), 0, "C"), (qml.ThermalState(3, wires=[1]), 1, "Thermal(3)"), ( qml.GaussianState(np.array([[2, 0], [0, 2]]), np.array([1, 2]), wires=[1]), 1, "Gaussian(M0,M1)", ), (qml.QuadraticPhase(3.14, wires=[1]), 1, "P(3.14)"), (qml.RX(3.14, wires=[1]), 1, "RX(3.14)"), (qml.S(wires=[2]), 2, "S"), (qml.T(wires=[2]), 2, "T"), (qml.RX(3.14, wires=[1]), 1, "RX(3.14)"), (qml.RY(3.14, wires=[1]), 1, "RY(3.14)"), (qml.RZ(3.14, wires=[1]), 1, "RZ(3.14)"), (qml.Rot(3.14, 2.14, 1.14, wires=[1]), 1, "Rot(3.14, 2.14, 1.14)"), (qml.U1(3.14, wires=[1]), 1, "U1(3.14)"), (qml.U2(3.14, 2.14, wires=[1]), 1, "U2(3.14, 2.14)"), (qml.U3(3.14, 2.14, 1.14, wires=[1]), 1, "U3(3.14, 2.14, 1.14)"), (qml.BasisState(np.array([0, 1, 0]), wires=[1, 2, 3]), 1, "|0>"), (qml.BasisState(np.array([0, 1, 0]), wires=[1, 2, 3]), 2, "|1>"), (qml.BasisState(np.array([0, 1, 0]), wires=[1, 2, 3]), 3, "|0>"), (qml.QubitStateVector(np.array([0, 1, 0, 0]), wires=[1, 2]), 1, "QubitStateVector(M0)"), (qml.QubitStateVector(np.array([0, 1, 0, 0]), wires=[1, 2]), 2, "QubitStateVector(M0)"), (qml.QubitUnitary(np.eye(2), wires=[1]), 1, "U0"), (qml.QubitUnitary(np.eye(4), wires=[1, 2]), 2, "U0"), (qml.Kerr(3.14, wires=[1]), 1, "Kerr(3.14)"), (qml.CrossKerr(3.14, wires=[1, 2]), 1, "CrossKerr(3.14)"), (qml.CrossKerr(3.14, wires=[1, 2]), 2, "CrossKerr(3.14)"), (qml.CubicPhase(3.14, wires=[1]), 1, "V(3.14)"), (qml.InterferometerUnitary( np.eye(4), wires=[1, 3]), 1, "InterferometerUnitary(M0)"), (qml.InterferometerUnitary( np.eye(4), wires=[1, 3]), 3, "InterferometerUnitary(M0)"), (qml.CatState(3.14, 2.14, 1, wires=[1]), 1, "CatState(3.14, 2.14, 1)"), (qml.CoherentState(3.14, 2.14, wires=[1]), 1, "CoherentState(3.14, 2.14)"), ( qml.FockDensityMatrix(np.kron(np.eye(4), np.eye(4)), wires=[1, 2]), 1, "FockDensityMatrix(M0)", ), ( qml.FockDensityMatrix(np.kron(np.eye(4), np.eye(4)), wires=[1, 2]), 2, "FockDensityMatrix(M0)", ), ( qml.DisplacedSqueezedState(3.14, 2.14, 1.14, 0.14, wires=[1]), 1, "DisplacedSqueezedState(3.14, 2.14, 1.14, 0.14)", ), (qml.FockState(7, wires=[1]), 1, "|7>"), (qml.FockStateVector(np.array([4, 5, 7]), wires=[1, 2, 3 ]), 1, "|4>"), (qml.FockStateVector(np.array([4, 5, 7]), wires=[1, 2, 3 ]), 2, "|5>"), (qml.FockStateVector(np.array([4, 5, 7]), wires=[1, 2, 3 ]), 3, "|7>"), (qml.SqueezedState(3.14, 2.14, wires=[1]), 1, "SqueezedState(3.14, 2.14)"), (qml.Hermitian(np.eye(4), wires=[1, 2]), 1, "H0"), (qml.Hermitian(np.eye(4), wires=[1, 2]), 2, "H0"), (qml.X(wires=[1]), 1, "x"), (qml.P(wires=[1]), 1, "p"), (qml.FockStateProjector(np.array([4, 5, 7]), wires=[1, 2, 3]), 1, "|4,5,7X4,5,7|"), ( qml.PolyXP(np.array([1, 2, 0, -1.3, 6]), wires=[1]), 2, "1+2x_0-1.3x_1+6p_1", ), ( qml.PolyXP(np.array([[1.2, 2.3, 4.5], [-1.2, 1.2, -1.5], [-1.3, 4.5, 2.3]]), wires=[1]), 1, "1.2+1.1x_0+3.2p_0+1.2x_0^2+2.3p_0^2+3x_0p_0", ), ( qml.PolyXP( np.array([ [1.2, 2.3, 4.5, 0, 0], [-1.2, 1.2, -1.5, 0, 0], [-1.3, 4.5, 2.3, 0, 0], [0, 2.6, 0, 0, 0], [0, 0, 0, -4.7, 0], ]), wires=[1], ), 1, "1.2+1.1x_0+3.2p_0+1.2x_0^2+2.3p_0^2+3x_0p_0+2.6x_0x_1-4.7x_1p_1", ), (qml.QuadOperator(3.14, wires=[1]), 1, "cos(3.14)x+sin(3.14)p"), (qml.QuadOperator(3.14, wires=[1]), 1, "cos(3.14)x+sin(3.14)p"), (qml.PauliX(wires=[1]).inv(), 1, "X^-1"), (qml.CNOT(wires=[0, 1]).inv(), 1, "X^-1"), (qml.CNOT(wires=[0, 1]).inv(), 0, "C"), (qml.Toffoli(wires=[0, 2, 1]).inv(), 1, "X^-1"), (qml.Toffoli(wires=[0, 2, 1]).inv(), 0, "C"), (qml.Toffoli(wires=[0, 2, 1]).inv(), 2, "C"), (qml.measure.sample(wires=[0, 1]), 0, "basis"), # not providing an observable in (qml.measure.sample(wires=[0, 1]), 1, "basis"), # sample gets displayed as raw (two_wire_quantum_tape(), 0, "QuantumTape:T0"), (two_wire_quantum_tape(), 1, "QuantumTape:T0"), ], ) def test_operator_representation_ascii(self, ascii_representation_resolver, op, wire, target): """Test that an Operator instance is properly resolved.""" assert ascii_representation_resolver.operator_representation( op, wire) == target @pytest.mark.parametrize( "obs,wire,target", [ (qml.expval(qml.PauliX(wires=[1])), 1, "⟨X⟩"), (qml.expval(qml.PauliY(wires=[1])), 1, "⟨Y⟩"), (qml.expval(qml.PauliZ(wires=[1])), 1, "⟨Z⟩"), (qml.expval(qml.Hadamard(wires=[1])), 1, "⟨H⟩"), (qml.expval(qml.Hermitian(np.eye(4), wires=[1, 2])), 1, "⟨H0⟩"), (qml.expval(qml.Hermitian(np.eye(4), wires=[1, 2])), 2, "⟨H0⟩"), (qml.expval(qml.NumberOperator(wires=[1])), 1, "⟨n⟩"), (qml.expval(qml.X(wires=[1])), 1, "⟨x⟩"), (qml.expval(qml.P(wires=[1])), 1, "⟨p⟩"), ( qml.expval( qml.FockStateProjector(np.array([4, 5, 7]), wires=[1, 2, 3])), 1, "⟨|4,5,7╳4,5,7|⟩", ), ( qml.expval(qml.PolyXP(np.array([1, 2, 0, -1.3, 6]), wires=[1 ])), 2, "⟨1+2x₀-1.3x₁+6p₁⟩", ), ( qml.expval( qml.PolyXP(np.array([[1.2, 2.3, 4.5], [-1.2, 1.2, -1.5], [-1.3, 4.5, 2.3]]), wires=[1])), 1, "⟨1.2+1.1x₀+3.2p₀+1.2x₀²+2.3p₀²+3x₀p₀⟩", ), (qml.expval(qml.QuadOperator( 3.14, wires=[1])), 1, "⟨cos(3.14)x+sin(3.14)p⟩"), (qml.var(qml.PauliX(wires=[1])), 1, "Var[X]"), (qml.var(qml.PauliY(wires=[1])), 1, "Var[Y]"), (qml.var(qml.PauliZ(wires=[1])), 1, "Var[Z]"), (qml.var(qml.Hadamard(wires=[1])), 1, "Var[H]"), (qml.var(qml.Hermitian(np.eye(4), wires=[1, 2])), 1, "Var[H0]"), (qml.var(qml.Hermitian(np.eye(4), wires=[1, 2])), 2, "Var[H0]"), (qml.var(qml.NumberOperator(wires=[1])), 1, "Var[n]"), (qml.var(qml.X(wires=[1])), 1, "Var[x]"), (qml.var(qml.P(wires=[1])), 1, "Var[p]"), ( qml.var( qml.FockStateProjector(np.array([4, 5, 7]), wires=[1, 2, 3])), 1, "Var[|4,5,7╳4,5,7|]", ), ( qml.var(qml.PolyXP(np.array([1, 2, 0, -1.3, 6]), wires=[1])), 2, "Var[1+2x₀-1.3x₁+6p₁]", ), ( qml.var( qml.PolyXP(np.array([[1.2, 2.3, 4.5], [-1.2, 1.2, -1.5], [-1.3, 4.5, 2.3]]), wires=[1])), 1, "Var[1.2+1.1x₀+3.2p₀+1.2x₀²+2.3p₀²+3x₀p₀]", ), (qml.var(qml.QuadOperator( 3.14, wires=[1])), 1, "Var[cos(3.14)x+sin(3.14)p]"), (qml.sample(qml.PauliX(wires=[1])), 1, "Sample[X]"), (qml.sample(qml.PauliY(wires=[1])), 1, "Sample[Y]"), (qml.sample(qml.PauliZ(wires=[1])), 1, "Sample[Z]"), (qml.sample(qml.Hadamard(wires=[1])), 1, "Sample[H]"), (qml.sample(qml.Hermitian(np.eye(4), wires=[1, 2 ])), 1, "Sample[H0]"), (qml.sample(qml.Hermitian(np.eye(4), wires=[1, 2 ])), 2, "Sample[H0]"), (qml.sample(qml.NumberOperator(wires=[1])), 1, "Sample[n]"), (qml.sample(qml.X(wires=[1])), 1, "Sample[x]"), (qml.sample(qml.P(wires=[1])), 1, "Sample[p]"), ( qml.sample( qml.FockStateProjector(np.array([4, 5, 7]), wires=[1, 2, 3])), 1, "Sample[|4,5,7╳4,5,7|]", ), ( qml.sample(qml.PolyXP(np.array([1, 2, 0, -1.3, 6]), wires=[1 ])), 2, "Sample[1+2x₀-1.3x₁+6p₁]", ), ( qml.sample( qml.PolyXP(np.array([[1.2, 2.3, 4.5], [-1.2, 1.2, -1.5], [-1.3, 4.5, 2.3]]), wires=[1])), 1, "Sample[1.2+1.1x₀+3.2p₀+1.2x₀²+2.3p₀²+3x₀p₀]", ), (qml.sample(qml.QuadOperator( 3.14, wires=[1])), 1, "Sample[cos(3.14)x+sin(3.14)p]"), ( qml.expval( qml.PauliX(wires=[1]) @ qml.PauliY(wires=[2]) @ qml.PauliZ(wires=[3])), 1, "⟨X ⊗ Y ⊗ Z⟩", ), ( qml.expval( qml.FockStateProjector(np.array([4, 5, 7]), wires=[1, 2, 3]) @ qml.X(wires=[4])), 1, "⟨|4,5,7╳4,5,7| ⊗ x⟩", ), ( qml.expval( qml.FockStateProjector(np.array([4, 5, 7]), wires=[1, 2, 3]) @ qml.X(wires=[4])), 2, "⟨|4,5,7╳4,5,7| ⊗ x⟩", ), ( qml.expval( qml.FockStateProjector(np.array([4, 5, 7]), wires=[1, 2, 3]) @ qml.X(wires=[4])), 3, "⟨|4,5,7╳4,5,7| ⊗ x⟩", ), ( qml.expval( qml.FockStateProjector(np.array([4, 5, 7]), wires=[1, 2, 3]) @ qml.X(wires=[4])), 4, "⟨|4,5,7╳4,5,7| ⊗ x⟩", ), ( qml.sample( qml.Hermitian(np.eye(4), wires=[1, 2]) @ qml.Hermitian( np.eye(4), wires=[0, 3])), 0, "Sample[H0 ⊗ H0]", ), ( qml.sample( qml.Hermitian(np.eye(4), wires=[1, 2]) @ qml.Hermitian( 2 * np.eye(4), wires=[0, 3])), 0, "Sample[H0 ⊗ H1]", ), (qml.probs([0]), 0, "Probs"), (state(), 0, "State"), ], ) def test_output_representation_unicode(self, unicode_representation_resolver, obs, wire, target): """Test that an Observable instance with return type is properly resolved.""" assert unicode_representation_resolver.output_representation( obs, wire) == target def test_fallback_output_representation_unicode( self, unicode_representation_resolver): """Test that an Observable instance with return type is properly resolved.""" obs = qml.PauliZ(0) obs.return_type = "TestReturnType" assert unicode_representation_resolver.output_representation( obs, 0) == "TestReturnType[Z]" @pytest.mark.parametrize( "obs,wire,target", [ (qml.expval(qml.PauliX(wires=[1])), 1, "<X>"), (qml.expval(qml.PauliY(wires=[1])), 1, "<Y>"), (qml.expval(qml.PauliZ(wires=[1])), 1, "<Z>"), (qml.expval(qml.Hadamard(wires=[1])), 1, "<H>"), (qml.expval(qml.Hermitian(np.eye(4), wires=[1, 2])), 1, "<H0>"), (qml.expval(qml.Hermitian(np.eye(4), wires=[1, 2])), 2, "<H0>"), (qml.expval(qml.NumberOperator(wires=[1])), 1, "<n>"), (qml.expval(qml.X(wires=[1])), 1, "<x>"), (qml.expval(qml.P(wires=[1])), 1, "<p>"), ( qml.expval( qml.FockStateProjector(np.array([4, 5, 7]), wires=[1, 2, 3])), 1, "<|4,5,7X4,5,7|>", ), ( qml.expval(qml.PolyXP(np.array([1, 2, 0, -1.3, 6]), wires=[1 ])), 2, "<1+2x_0-1.3x_1+6p_1>", ), ( qml.expval( qml.PolyXP(np.array([[1.2, 2.3, 4.5], [-1.2, 1.2, -1.5], [-1.3, 4.5, 2.3]]), wires=[1])), 1, "<1.2+1.1x_0+3.2p_0+1.2x_0^2+2.3p_0^2+3x_0p_0>", ), (qml.expval(qml.QuadOperator( 3.14, wires=[1])), 1, "<cos(3.14)x+sin(3.14)p>"), (qml.var(qml.PauliX(wires=[1])), 1, "Var[X]"), (qml.var(qml.PauliY(wires=[1])), 1, "Var[Y]"), (qml.var(qml.PauliZ(wires=[1])), 1, "Var[Z]"), (qml.var(qml.Hadamard(wires=[1])), 1, "Var[H]"), (qml.var(qml.Hermitian(np.eye(4), wires=[1, 2])), 1, "Var[H0]"), (qml.var(qml.Hermitian(np.eye(4), wires=[1, 2])), 2, "Var[H0]"), (qml.var(qml.NumberOperator(wires=[1])), 1, "Var[n]"), (qml.var(qml.X(wires=[1])), 1, "Var[x]"), (qml.var(qml.P(wires=[1])), 1, "Var[p]"), ( qml.var( qml.FockStateProjector(np.array([4, 5, 7]), wires=[1, 2, 3])), 1, "Var[|4,5,7X4,5,7|]", ), ( qml.var(qml.PolyXP(np.array([1, 2, 0, -1.3, 6]), wires=[1])), 2, "Var[1+2x_0-1.3x_1+6p_1]", ), ( qml.var( qml.PolyXP(np.array([[1.2, 2.3, 4.5], [-1.2, 1.2, -1.5], [-1.3, 4.5, 2.3]]), wires=[1])), 1, "Var[1.2+1.1x_0+3.2p_0+1.2x_0^2+2.3p_0^2+3x_0p_0]", ), (qml.var(qml.QuadOperator( 3.14, wires=[1])), 1, "Var[cos(3.14)x+sin(3.14)p]"), (qml.sample(qml.PauliX(wires=[1])), 1, "Sample[X]"), (qml.sample(qml.PauliY(wires=[1])), 1, "Sample[Y]"), (qml.sample(qml.PauliZ(wires=[1])), 1, "Sample[Z]"), (qml.sample(qml.Hadamard(wires=[1])), 1, "Sample[H]"), (qml.sample(qml.Hermitian(np.eye(4), wires=[1, 2 ])), 1, "Sample[H0]"), (qml.sample(qml.Hermitian(np.eye(4), wires=[1, 2 ])), 2, "Sample[H0]"), (qml.sample(qml.NumberOperator(wires=[1])), 1, "Sample[n]"), (qml.sample(qml.X(wires=[1])), 1, "Sample[x]"), (qml.sample(qml.P(wires=[1])), 1, "Sample[p]"), ( qml.sample( qml.FockStateProjector(np.array([4, 5, 7]), wires=[1, 2, 3])), 1, "Sample[|4,5,7X4,5,7|]", ), ( qml.sample(qml.PolyXP(np.array([1, 2, 0, -1.3, 6]), wires=[1 ])), 2, "Sample[1+2x_0-1.3x_1+6p_1]", ), ( qml.sample( qml.PolyXP(np.array([[1.2, 2.3, 4.5], [-1.2, 1.2, -1.5], [-1.3, 4.5, 2.3]]), wires=[1])), 1, "Sample[1.2+1.1x_0+3.2p_0+1.2x_0^2+2.3p_0^2+3x_0p_0]", ), (qml.sample(qml.QuadOperator( 3.14, wires=[1])), 1, "Sample[cos(3.14)x+sin(3.14)p]"), ( qml.expval( qml.PauliX(wires=[1]) @ qml.PauliY(wires=[2]) @ qml.PauliZ(wires=[3])), 1, "<X @ Y @ Z>", ), ( qml.expval( qml.FockStateProjector(np.array([4, 5, 7]), wires=[1, 2, 3]) @ qml.X(wires=[4])), 1, "<|4,5,7X4,5,7| @ x>", ), ( qml.expval( qml.FockStateProjector(np.array([4, 5, 7]), wires=[1, 2, 3]) @ qml.X(wires=[4])), 2, "<|4,5,7X4,5,7| @ x>", ), ( qml.expval( qml.FockStateProjector(np.array([4, 5, 7]), wires=[1, 2, 3]) @ qml.X(wires=[4])), 3, "<|4,5,7X4,5,7| @ x>", ), ( qml.expval( qml.FockStateProjector(np.array([4, 5, 7]), wires=[1, 2, 3]) @ qml.X(wires=[4])), 4, "<|4,5,7X4,5,7| @ x>", ), ( qml.sample( qml.Hermitian(np.eye(4), wires=[1, 2]) @ qml.Hermitian( np.eye(4), wires=[0, 3])), 0, "Sample[H0 @ H0]", ), ( qml.sample( qml.Hermitian(np.eye(4), wires=[1, 2]) @ qml.Hermitian( 2 * np.eye(4), wires=[0, 3])), 0, "Sample[H0 @ H1]", ), (qml.probs([0]), 0, "Probs"), (state(), 0, "State"), ], ) def test_output_representation_ascii(self, ascii_representation_resolver, obs, wire, target): """Test that an Observable instance with return type is properly resolved.""" assert ascii_representation_resolver.output_representation( obs, wire) == target def test_element_representation_none(self, unicode_representation_resolver): """Test that element_representation properly handles None.""" assert unicode_representation_resolver.element_representation(None, 0) == "" def test_element_representation_str(self, unicode_representation_resolver): """Test that element_representation properly handles strings.""" assert unicode_representation_resolver.element_representation( "Test", 0) == "Test" def test_element_representation_calls_output( self, unicode_representation_resolver): """Test that element_representation calls output_representation for returned observables.""" unicode_representation_resolver.output_representation = Mock() obs = qml.sample(qml.PauliX(3)) wire = 3 unicode_representation_resolver.element_representation(obs, wire) assert unicode_representation_resolver.output_representation.call_args[ 0] == (obs, wire) def test_element_representation_calls_operator( self, unicode_representation_resolver): """Test that element_representation calls operator_representation for all operators that are not returned.""" unicode_representation_resolver.operator_representation = Mock() op = qml.PauliX(3) wire = 3 unicode_representation_resolver.element_representation(op, wire) assert unicode_representation_resolver.operator_representation.call_args[ 0] == (op, wire)
two_qubit = [ (qml.CNOT(wires=[0, 1]), CNOT), (qml.SWAP(wires=[0, 1]), SWAP), (qml.CZ(wires=[0, 1]), CZ), (qml.CNOT(wires=[0, 1]).inv(), CNOT.conj().T), (qml.SWAP(wires=[0, 1]).inv(), SWAP.conj().T), (qml.CZ(wires=[0, 1]).inv(), CZ.conj().T), ] # list of all parametrized two-qubit gates two_qubit_param = [ (qml.CRZ(0, wires=[0, 1]), crz), (qml.CRZ(0, wires=[0, 1]).inv(), lambda theta: crz(-theta)), ] # list of all three-qubit gates three_qubit = [ (qml.Toffoli(wires=[0, 1, 2]), toffoli), (qml.CSWAP(wires=[0, 1, 2]), CSWAP), (qml.Toffoli(wires=[0, 1, 2]).inv(), toffoli.conj().T), (qml.CSWAP(wires=[0, 1, 2]).inv(), CSWAP.conj().T), ] class TestStateApply: """Test the device's state after application of gates.""" @pytest.mark.parametrize( "state", [ np.array([0, 0, 1, 0]), np.array([0, 0, 1, 0]), np.array([1, 0, 1, 0]), np.array([1, 1, 1, 1]),