def test_apply(self, n_wires): """Test if the apply_controlled_Q performs the correct transformation by reconstructing the unitary and comparing against the one provided in make_Q. Random unitaries are chosen for a_mat and r_mat.""" n_all_wires = n_wires + 1 wires = range(n_wires) target_wire = n_wires - 1 control_wire = n_wires a_mat = unitary_group.rvs(2**(n_wires - 1), random_state=1967) r_mat = unitary_group.rvs(2**n_wires, random_state=1967) q_mat = make_Q(a_mat, r_mat) def fn(): qml.QubitUnitary(a_mat, wires=wires[:-1]) qml.QubitUnitary(r_mat, wires=wires) circ = apply_controlled_Q(fn, wires=wires, target_wire=target_wire, control_wire=control_wire, work_wires=None) u = get_unitary(circ, n_all_wires) circ = lambda: qml.ControlledQubitUnitary( q_mat, wires=wires, control_wires=control_wire) u_ideal = get_unitary(circ, n_all_wires) assert np.allclose(u_ideal, u)
def test_apply(self, n_wires): """Test if the quantum_monte_carlo performs the correct transformation by reconstructing the unitary and comparing against the one provided in the QuantumPhaseEstimation template. Random unitaries are chosen for a_mat and r_mat.""" n_all_wires = 2 * n_wires wires = range(n_wires) target_wire = n_wires - 1 estimation_wires = range(n_wires, 2 * n_wires) a_mat = unitary_group.rvs(2**(n_wires - 1), random_state=1967) r_mat = unitary_group.rvs(2**n_wires, random_state=1967) q_mat = make_Q(a_mat, r_mat) def fn(): qml.QubitUnitary(a_mat, wires=wires[:-1]) qml.QubitUnitary(r_mat, wires=wires) circ = quantum_monte_carlo(fn, wires=wires, target_wire=target_wire, estimation_wires=estimation_wires) u = get_unitary(circ, n_all_wires) def circ_ideal(): fn() qml.templates.QuantumPhaseEstimation( q_mat, target_wires=wires, estimation_wires=estimation_wires) u_ideal = get_unitary(circ_ideal, n_all_wires) assert np.allclose(u_ideal, u)
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_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))
def test_Q(): """Test for the make_Q function using a fixed example""" A = np.array([ [0.85358423 - 0.32239299j, -0.12753659 + 0.38883306j], [0.39148136 - 0.11915985j, 0.34064316 - 0.84646648j], ]) R = np.array([ [ 0.45885289 + 0.03972856j, 0.2798685 - 0.05981098j, 0.64514642 - 0.51555038j, 0.11015177 - 0.10877695j, ], [ 0.19407005 - 0.35483005j, 0.29756077 + 0.80153453j, -0.19147104 + 0.0507968j, 0.15553799 - 0.20493631j, ], [ 0.35083011 - 0.20807392j, -0.27602911 - 0.13934692j, 0.11874165 + 0.34532609j, -0.45945242 - 0.62734969j, ], [ -0.11379919 - 0.66706921j, -0.21120956 - 0.2165113j, 0.30133006 + 0.23367271j, 0.54593491 + 0.08446372j, ], ]) Q_expected = np.array([ [ -0.46513201 - 1.38777878e-17j, -0.13035515 - 2.23341802e-01j, -0.74047856 + 7.08652160e-02j, -0.0990036 - 3.91977176e-01j, ], [ 0.13035515 - 2.23341802e-01j, 0.46494302 + 0.00000000e00j, 0.05507901 - 1.19182067e-01j, -0.80370146 - 2.31904873e-01j, ], [ -0.74047856 - 7.08652160e-02j, -0.05507901 - 1.19182067e-01j, 0.62233412 - 2.77555756e-17j, -0.0310774 - 2.02894077e-01j, ], [ 0.0990036 - 3.91977176e-01j, -0.80370146 + 2.31904873e-01j, 0.0310774 - 2.02894077e-01j, -0.30774091 + 2.77555756e-17j, ], ]) Q = make_Q(A, R) assert np.allclose(Q, Q_expected)