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))
Exemple #2
0
 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))
Exemple #3
0
 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))
Exemple #5
0
    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))