def test_native_inverse_gates(self): """Test that a circuit containing inverse gates that are supported natively by QASM, such as sdg, are correctly serialized.""" ops = [ qml.S(wires=0), qml.S(wires=0).inv(), qml.T(wires=0), qml.T(wires=0).inv(), ] circuit = CircuitGraph(ops, {}) res = circuit.to_openqasm() expected = dedent("""\ OPENQASM 2.0; include "qelib1.inc"; qreg q[1]; creg c[1]; s q[0]; sdg q[0]; t q[0]; tdg q[0]; measure q[0] -> c[0]; """) assert res == expected
class TestOperations: """Tests for the operations""" @pytest.mark.parametrize( "op", [ (qml.Hadamard(wires=0)), (qml.PauliX(wires=0)), (qml.PauliY(wires=0)), (qml.PauliZ(wires=0)), (qml.S(wires=0)), (qml.T(wires=0)), (qml.SX(wires=0)), (qml.RX(0.3, wires=0)), (qml.RY(0.3, wires=0)), (qml.RZ(0.3, wires=0)), (qml.PhaseShift(0.3, wires=0)), (qml.Rot(0.3, 0.4, 0.5, wires=0)), ], ) def test_single_qubit_rot_angles(self, op): """Tests that the Rot gates yielded by single_qubit_rot_angles are equivalent to the true operations up to a global phase.""" angles = op.single_qubit_rot_angles() obtained_mat = qml.Rot(*angles, wires=0).matrix # Check whether the two matrices are each others conjugate transposes mat_product = qml.math.dot(op.matrix, qml.math.conj(obtained_mat.T)) mat_product /= mat_product[0, 0] assert qml.math.allclose(mat_product, I)
def qfunc(): qml.RZ(0.3, wires=0) qml.Hadamard(wires=0) qml.Rot(0.1, 0.2, 0.3, wires=0) qml.RX(0.1, wires=0) qml.SX(wires=0) qml.T(wires=0) qml.PauliX(wires=0)
def qfunc(theta): qml.PauliX(wires=2) qml.S(wires=0) qml.CNOT(wires=[0, 1]) qml.PauliY(wires=1) qml.CRY(theta[0], wires=[2, 1]) qml.PhaseShift(theta[1], wires=0) qml.T(wires=0) qml.Toffoli(wires=[0, 1, 2]) return qml.expval(qml.PauliZ(0))
def test_append_qubit_gates(self): """Test that gates are successfully appended to the queue.""" with qml.beta.queuing.AnnotatedQueue() as q: ops = [ qml.RX(0.5, wires=0), qml.RY(-10.1, wires=1), qml.CNOT(wires=[0, 1]), qml.PhaseShift(-1.1, wires=18), qml.T(wires=99), ] assert q.queue == ops
def qfunc(): qml.CZ(wires=[0, 2]) qml.PauliZ(wires=2) qml.S(wires=0) qml.CNOT(wires=[0, 1]) qml.CRZ(0.5, wires=[0, 1]) qml.RZ(0.2, wires=2) qml.T(wires=0) qml.PauliZ(wires=0)
def op(op_name): ops_list = { "RX": qml.RX(0.123, wires=0), "RY": qml.RY(1.434, wires=0), "RZ": qml.RZ(2.774, wires=0), "S": qml.S(wires=0), "SX": qml.SX(wires=0), "T": qml.T(wires=0), "CNOT": qml.CNOT(wires=[0, 1]), "CZ": qml.CZ(wires=[0, 1]), "CY": qml.CY(wires=[0, 1]), "SWAP": qml.SWAP(wires=[0, 1]), "ISWAP": qml.ISWAP(wires=[0, 1]), "SISWAP": qml.SISWAP(wires=[0, 1]), "SQISW": qml.SQISW(wires=[0, 1]), "CSWAP": qml.CSWAP(wires=[0, 1, 2]), "PauliRot": qml.PauliRot(0.123, "Y", wires=0), "IsingXX": qml.IsingXX(0.123, wires=[0, 1]), "IsingXY": qml.IsingXY(0.123, wires=[0, 1]), "IsingYY": qml.IsingYY(0.123, wires=[0, 1]), "IsingZZ": qml.IsingZZ(0.123, wires=[0, 1]), "Identity": qml.Identity(wires=0), "Rot": qml.Rot(0.123, 0.456, 0.789, wires=0), "Toffoli": qml.Toffoli(wires=[0, 1, 2]), "PhaseShift": qml.PhaseShift(2.133, wires=0), "ControlledPhaseShift": qml.ControlledPhaseShift(1.777, wires=[0, 2]), "CPhase": qml.CPhase(1.777, wires=[0, 2]), "MultiRZ": qml.MultiRZ(0.112, wires=[1, 2, 3]), "CRX": qml.CRX(0.836, wires=[2, 3]), "CRY": qml.CRY(0.721, wires=[2, 3]), "CRZ": qml.CRZ(0.554, wires=[2, 3]), "Hadamard": qml.Hadamard(wires=0), "PauliX": qml.PauliX(wires=0), "PauliY": qml.PauliY(wires=0), "PauliZ": qml.PauliZ(wires=0), "CRot": qml.CRot(0.123, 0.456, 0.789, wires=[0, 1]), "DiagonalQubitUnitary": qml.DiagonalQubitUnitary(np.array([1.0, 1.0j]), wires=1), "ControlledQubitUnitary": qml.ControlledQubitUnitary( np.eye(2) * 1j, wires=[0], control_wires=[2] ), "MultiControlledX": qml.MultiControlledX(wires=(0, 1, 2), control_values="01"), "SingleExcitation": qml.SingleExcitation(0.123, wires=[0, 3]), "SingleExcitationPlus": qml.SingleExcitationPlus(0.123, wires=[0, 3]), "SingleExcitationMinus": qml.SingleExcitationMinus(0.123, wires=[0, 3]), "DoubleExcitation": qml.DoubleExcitation(0.123, wires=[0, 1, 2, 3]), "DoubleExcitationPlus": qml.DoubleExcitationPlus(0.123, wires=[0, 1, 2, 3]), "DoubleExcitationMinus": qml.DoubleExcitationMinus(0.123, wires=[0, 1, 2, 3]), "QFT": qml.QFT(wires=0), "QubitSum": qml.QubitSum(wires=[0, 1, 2]), "QubitCarry": qml.QubitCarry(wires=[0, 1, 2, 3]), "QubitUnitary": qml.QubitUnitary(np.eye(2) * 1j, wires=0), } return ops_list.get(op_name)
def test_four_qubit_random_circuit(self, device, tol): """Compare a four-qubit random circuit with lots of different gates to default.qubit""" n_wires = 4 dev = device(n_wires) dev_def = qml.device("default.qubit", wires=n_wires) if dev.name == dev_def.name: pytest.skip("Device is default.qubit.") if dev.shots is not None: pytest.skip("Device is in non-analytical mode.") 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 = [np.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_def = qml.QNode(circuit, dev_def) qnode = qml.QNode(circuit, dev) assert np.allclose(qnode(), qnode_def(), atol=tol(dev.shots))
def test_t_decomposition(self, tol): """Tests that the decomposition of the T gate is correct""" op = qml.T(wires=0) res = op.decomposition(0) assert len(res) == 1 assert res[0].name == "PhaseShift" assert res[0].wires == [0] #qml.wires.Wires([0]) assert res[0].params[0] == np.pi / 4 decomposed_matrix = res[0].matrix assert np.allclose(decomposed_matrix, op.matrix, atol=tol, rtol=0)
def one_qubit_block(wires=None): """A block containing all of the supported gates in ``lightning.qubit``""" qml.PauliX(wires=wires) qml.PauliY(wires=wires) qml.S(wires=wires) qml.Hadamard(wires=wires) qml.PauliX(wires=wires) qml.T(wires=wires) qml.PhaseShift(-1, wires=wires) qml.Rot(0.1, 0.2, 0.3, wires=wires) qml.RZ(0.11, wires=wires) qml.RY(0.22, wires=wires) qml.RX(0.33, wires=wires) qml.PauliX(wires=wires)
def test_native_inverse_gates(self): """Test that a circuit containing inverse gates that are supported natively by QASM, such as sdg, are correctly serialized.""" with qml.tape.QuantumTape() as circuit: qml.S(wires=0) qml.S(wires=0).inv() qml.T(wires=0) qml.T(wires=0).inv(), res = circuit.to_openqasm() expected = dedent("""\ OPENQASM 2.0; include "qelib1.inc"; qreg q[1]; creg c[1]; s q[0]; sdg q[0]; t q[0]; tdg q[0]; measure q[0] -> c[0]; """) assert res == expected
def qfunc(): qml.PauliX(wires=1) qml.S(wires=0) qml.CZ(wires=[0, 1]) qml.CNOT(wires=[1, 0]) qml.PauliY(wires=1) qml.CRY(0.5, wires=[1, 0]) qml.PhaseShift(0.2, wires=0) qml.PauliY(wires=1) qml.T(wires=0) qml.CRZ(-0.3, wires=[0, 1]) qml.RZ(0.2, wires=0) qml.PauliZ(wires=0) qml.PauliX(wires=1) qml.CRY(0.2, wires=[1, 0])
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 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 circuit(): qml.Hadamard(wires=0) qml.T(wires=0) return qml.state()
def qnode(): qml.S(wires=0) qml.S(wires=0).inv() qml.T(wires=0) qml.T(wires=0).inv() return qml.expval(qml.PauliZ(0))
"PauliX": qml.PauliX(wires=[0]), "PauliY": qml.PauliY(wires=[0]), "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()
class TestWavefunctionBasic(BaseTest): """Unit tests for the NumPy wavefunction simulator.""" def test_var(self, tol): """Tests for variance calculation""" dev = plf.NumpyWavefunctionDevice(wires=2) phi = 0.543 theta = 0.6543 with qml.tape.QuantumTape() as tape: qml.RX(phi, wires=[0]) qml.RY(theta, wires=[0]) O = qml.var(qml.PauliZ(wires=[0])) # test correct variance for <Z> of a rotated state dev.apply(tape.operations, rotations=tape.diagonalizing_gates) var = dev.var(O) expected = 0.25 * (3 - np.cos(2 * theta) - 2 * np.cos(theta)**2 * np.cos(2 * phi)) self.assertAlmostEqual(var, expected, delta=tol) def test_var_hermitian(self, tol): """Tests for variance calculation using an arbitrary Hermitian observable""" dev = plf.NumpyWavefunctionDevice(wires=2) phi = 0.543 theta = 0.6543 H = np.array([[4, -1 + 6j], [-1 - 6j, 2]]) with qml.tape.QuantumTape() as tape: qml.RX(phi, wires=[0]) qml.RY(theta, wires=[0]) O = qml.var(qml.Hermitian(H, wires=[0])) # test correct variance for <Z> of a rotated state dev.apply(tape.operations, rotations=tape.diagonalizing_gates) var = dev.var(O) # test correct variance for <H> of a rotated state 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=tol) @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, tol): """Test the application of gates to a state""" dev = plf.NumpyWavefunctionDevice(wires=3) 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) # verify the device is now in the expected state self.assertAllAlmostEqual(dev._state, state, delta=tol) def test_sample_values(self, tol): """Tests if the samples returned by sample have the correct values """ dev = plf.NumpyWavefunctionDevice(wires=1, shots=10) theta = 1.5708 O = qml.sample(qml.PauliZ(0)) with qml.tape.QuantumTape() as tape: qml.RX(theta, wires=[0]) qml.sample(qml.PauliZ(0)) dev.apply(tape._ops, rotations=tape.diagonalizing_gates) dev._samples = dev.generate_samples() s1 = dev.sample(O.obs) # s1 should only contain 1 and -1 self.assertAllAlmostEqual(s1**2, 1, delta=tol) def test_sample_values_hermitian(self, tol): """Tests if the samples of a Hermitian observable returned by sample have the correct values """ dev = plf.NumpyWavefunctionDevice(wires=1, shots=1_000_000) theta = 0.543 A = np.array([[1, 2j], [-2j, 0]]) circuit_operations = [qml.RX(theta, wires=[0])] O = qml.sample(qml.Hermitian(A, wires=[0])) with qml.tape.QuantumTape() as tape: qml.RX(theta, wires=[0]) O = qml.sample(qml.Hermitian(A, wires=[0])) # test correct variance for <Z> of a rotated state dev.apply(tape.operations, rotations=tape.diagonalizing_gates) dev._samples = dev.generate_samples() s1 = dev.sample(O.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, tol): """Tests if the samples of a multi-qubit Hermitian observable returned by sample have the correct values """ shots = 1_000_000 dev = plf.NumpyWavefunctionDevice(wires=2, shots=shots) theta = 0.543 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], ]) with qml.tape.QuantumTape() as tape: qml.RX(theta, wires=[0]), qml.RY(2 * theta, wires=[1]), qml.CNOT(wires=[0, 1]), O = qml.sample(qml.Hermitian(A, wires=[0, 1])) # test correct variance for <Z> of a rotated state dev.apply(tape.operations, rotations=tape.diagonalizing_gates) dev._samples = dev.generate_samples() s1 = dev.sample(O.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)
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
for op in tape.operations: op.queue() return qml.state() assert np.allclose(f(), rnd_state) spy.assert_called() label_data = [ (qml.Identity(0), "I", "I"), (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), "//", "//"), ]
def circuit(): qml.T(wires=0) return sample(qml.PauliZ(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]), "ISWAP": qml.ISWAP(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]), "IsingXX": qml.IsingXX(0, wires=[0, 1]), "IsingYY": qml.IsingYY(0, wires=[0, 1]), "IsingZZ": qml.IsingZZ(0, wires=[0, 1]), "SingleExcitation": qml.SingleExcitation(0, wires=[0, 1]), "SingleExcitationPlus":
crz = lambda theta: np.array([ [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, np.exp(-1j * theta / 2), 0], [0, 0, 0, np.exp(1j * theta / 2)], ]) # list of all non-parametrized single-qubit gates, # along with the PennyLane operation name single_qubit = [ (qml.PauliX(wires=0), X), (qml.PauliY(wires=0), Y), (qml.PauliZ(wires=0), Z), (qml.Hadamard(wires=0), H), (qml.S(wires=0), S), (qml.T(wires=0), T), (qml.PauliX(wires=0).inv(), X.conj().T), (qml.PauliY(wires=0).inv(), Y.conj().T), (qml.PauliZ(wires=0).inv(), Z.conj().T), (qml.Hadamard(wires=0).inv(), H.conj().T), (qml.S(wires=0).inv(), S.conj().T), (qml.T(wires=0).inv(), T.conj().T), ] # list of all parametrized single-qubit gates single_qubit_param = [ (qml.RX(0, wires=0), rx), (qml.RY(0, wires=0), ry), (qml.RZ(0, wires=0), rz), (qml.PhaseShift(0, wires=0), phase_shift), (qml.RX(0, wires=0).inv(), lambda theta: rx(-theta)),
def circuit(): qml.RX(par, wires=[0]) qml.T(wires=[0]).inv() return qml.expval(qml.PauliX(0))
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))
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)
wires=target_wire).inv() for op in tape.operations: op.queue() return qml.state() assert np.allclose(f(), rnd_state) spy.assert_called() label_data = [ (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)), "⊕", "⊕"), ] @pytest.mark.parametrize("op, label1, label2", label_data)