def test_expected_circuit(self): """Test if the circuit applied when using the QMC template is the same as the expected circuit for a fixed example""" p = np.ones(4) / 4 target_wires, estimation_wires = Wires(range(3)), Wires(range(3, 5)) with qml.tape.QuantumTape() as tape: QuantumMonteCarlo(p, self.func, target_wires, estimation_wires) queue_before_qpe = tape.queue[:2] queue_after_qpe = tape.queue[2:] A = probs_to_unitary(p) R = func_to_unitary(self.func, 4) assert len(queue_before_qpe) == 2 assert queue_before_qpe[0].name == "QubitUnitary" assert queue_before_qpe[1].name == "QubitUnitary" assert np.allclose(queue_before_qpe[0].matrix, A) assert np.allclose(queue_before_qpe[1].matrix, R) assert queue_before_qpe[0].wires == target_wires[:-1] assert queue_before_qpe[1].wires == target_wires Q = make_Q(A, R) with qml.tape.QuantumTape() as qpe_tape: qml.templates.QuantumPhaseEstimation(Q, target_wires, estimation_wires) assert len(queue_after_qpe) == len(qpe_tape.queue) assert all(o1.name == o2.name for o1, o2 in zip(queue_after_qpe, qpe_tape.queue)) assert all( np.allclose(o1.matrix, o2.matrix) for o1, o2 in zip(queue_after_qpe, qpe_tape.queue) ) assert all(o1.wires == o2.wires for o1, o2 in zip(queue_after_qpe, qpe_tape.queue))
def test_non_flat(self): """Test if a ValueError is raised when a non-flat array is input""" p = np.ones((4, 1)) / 4 with pytest.raises( ValueError, match="The probability distribution must be specified as a"): QuantumMonteCarlo(p, self.func, range(3), range(3, 5))
def test_wrong_size_p(self): """Test if a ValueError is raised when a probability distribution is passed whose length cannot be mapped to qubits""" p = np.ones(5) / 5 with pytest.raises( ValueError, match="The probability distribution must have a length"): QuantumMonteCarlo(p, self.func, range(3), range(3, 5))
def test_unexpected_target_wires_number(self): """Test if a ValueError is raised when the number of target wires is incompatible with the expected number of target wires inferred from the length of the input probability distribution""" p = np.ones(4) / 4 with pytest.raises( ValueError, match="The probability distribution of dimension 4 requires" " 3 target wires", ): QuantumMonteCarlo(p, self.func, range(4), range(4, 6))
def test_expected_circuit(self): """Test if the circuit applied when using the QMC template is the same as the expected circuit for a fixed example""" p = np.ones(4) / 4 target_wires, estimation_wires = Wires(range(3)), Wires(range(3, 5)) op = QuantumMonteCarlo(p, self.func, target_wires, estimation_wires) tape = op.expand() # Do expansion in two steps to avoid also decomposing the first QubitUnitary queue_before_qpe = tape.operations[:2] # 2-qubit decomposition has 10 operations, and after is a 3-qubit gate so start at 11 queue_after_qpe = tape.expand().operations[11:] A = probs_to_unitary(p) R = func_to_unitary(self.func, 4) assert len(queue_before_qpe) == 2 assert queue_before_qpe[0].name == "QubitUnitary" assert queue_before_qpe[1].name == "QubitUnitary" assert np.allclose(queue_before_qpe[0].matrix, A) assert np.allclose(queue_before_qpe[1].matrix, R) assert queue_before_qpe[0].wires == target_wires[:-1] assert queue_before_qpe[1].wires == target_wires Q = make_Q(A, R) with qml.tape.QuantumTape() as qpe_tape: qml.QuantumPhaseEstimation(Q, target_wires, estimation_wires) qpe_tape = qpe_tape.expand() assert len(queue_after_qpe) == len(qpe_tape.operations) assert all(o1.name == o2.name for o1, o2 in zip(queue_after_qpe, qpe_tape.operations)) assert all( np.allclose(o1.matrix, o2.matrix) for o1, o2 in zip(queue_after_qpe, qpe_tape.operations)) assert all(o1.wires == o2.wires for o1, o2 in zip(queue_after_qpe, qpe_tape.operations))