def adjoint(self, do_queue=False): with QuantumTape(do_queue=False) as new_tape: # Execute all ops adjointed. adjoint(requeue_ops_in_tape)(self.subtape) return ControlledOperation(new_tape, self.control_wires, do_queue=do_queue)
def my_circuit(): qml.PauliX(wires=0) qml.PauliZ(wires=0) my_op() adjoint(my_op)() qml.PauliY(wires=0) return qml.state()
def test_single_op_non_param_adjoint(self, op, wires): """Test that the adjoint correctly inverts non-parametrized operations""" op_adjoint = adjoint(op)(wires=wires) expected = op(wires=wires).adjoint() assert type(op_adjoint) == type(expected) assert op_adjoint.wires == expected.wires
def adjoint(self): """Returns a new ControlledOperation that is equal to the adjoint of `self`""" active_tape = get_active_tape() if active_tape is not None: with get_active_tape().stop_recording(), QuantumTape() as new_tape: # Execute all ops adjointed. adjoint(requeue_ops_in_tape)(self.subtape) else: # Not within a queuing context with QuantumTape() as new_tape: # Execute all ops adjointed. ops = adjoint(requeue_ops_in_tape)(self.subtape) return ControlledOperation(new_tape, self.control_wires)
def test_single_op_param_adjoint(self, op, par, wires): """Test that the adjoint correctly inverts operations with a single parameter""" param_op_adjoint = adjoint(op)(*par, wires=wires) expected = op(*par, wires=wires).adjoint() assert type(param_op_adjoint) == type(expected) assert param_op_adjoint.parameters == expected.parameters assert param_op_adjoint.wires == expected.wires
def test_cv_template_adjoint(self): """Test that the adjoint correctly inverts CV templates""" template, par, wires = qml.templates.Interferometer, [[1], [0.3], [0.2, 0.3]], [2, 3] result = adjoint(template)(*par, wires=wires).expand().operations expected_ops = template(*par, wires=wires).expand().operations for o1, o2 in zip(result, reversed(expected_ops)): o2 = o2.adjoint() assert type(o1) == type(o2) assert o1.parameters == o2.parameters assert o1.wires == o2.wires
def test_templates_adjoint(self, template, par, wires): """Test that the adjoint correctly inverts templates""" res = adjoint(template)(*par, wires=wires) result = res if hasattr( res, "__iter__") else [res] # handle single operation case expected_ops = template(*par, wires=wires) expected_ops = expected_ops.expand().operations for o1, o2 in zip(result, reversed(expected_ops)): o2 = o2.adjoint() assert type(o1) == type(o2) assert o1.parameters == o2.parameters assert o1.wires == o2.wires
def my_circuit(): adjoint(my_op)() qml.Hadamard(wires=0) adjoint(adjoint(my_op))() return qml.state()
def my_circuit(): adjoint(adjoint(qml.RX))(np.pi / 4.0, wires=0) return qml.state()
dev = qml.device("default.qubit", wires=1) @qml.qnode(dev) def my_circuit(): adjoint(my_op)() qml.Hadamard(wires=0) adjoint(adjoint(my_op))() return qml.state() np.testing.assert_allclose( my_circuit(), np.array([-0.995707, 0.068644 + 6.209710e-02j]), atol=1e-6, rtol=1e-6 ) test_functions = [ lambda fn, *args, **kwargs: adjoint(fn)(*args, **kwargs), lambda fn, *args, **kwargs: qml.inv(fn(*args, **kwargs)), ] @pytest.mark.parametrize("fn", test_functions) class TestTemplateIntegration: """Test that templates work correctly with the adjoint transform""" def test_angle_embedding(self, fn): """Test that the adjoint correctly inverts angle embedding""" dev = qml.device("default.qubit", wires=3) template = qml.templates.AngleEmbedding @qml.qnode(dev) def circuit(weights):
def test_cv_template_adjoint(self): """Test that the adjoint correctly inverts CV templates""" template, par, wires = qml.templates.Interferometer, [[1], [0.3], [0.2, 0.3]], [2, 3] result = qml.adjoint(template)(*par, wires=wires) expected_ops = template(*par, wires=wires) for o1, o2 in zip(result, reversed(expected_ops)): o2 = o2.adjoint() assert type(o1) == type(o2) assert o1.parameters == o2.parameters assert o1.wires == o2.wires fn = lambda func, *args, **kwargs: adjoint(func)(*args, **kwargs) class TestTemplateIntegration: """Test that templates work correctly with the adjoint transform""" def test_angle_embedding(self): """Test that the adjoint correctly inverts angle embedding""" dev = qml.device("default.qubit", wires=3) template = qml.templates.AngleEmbedding @qml.qnode(dev) def circuit(weights): template(features=weights, wires=[0, 1, 2]) fn(template, features=weights, wires=[0, 1, 2]) return qml.state()
def adjoint(self): """Returns a new ControlledOperation that is equal to the adjoint of `self`""" with get_active_tape().stop_recording(), QuantumTape() as new_tape: # Execute all ops adjointed. adjoint(requeue_ops_in_tape)(self.subtape) return ControlledOperation(new_tape, self.control_wires)
def my_circuit(): adjoint(qml.WireCut)(wires=0) return qml.state()
def my_circuit(): adjoint(qml.Barrier)(wires=0) return qml.state()
def test_error_adjoint_on_noncallable(obj): """Test that an error is raised if qml.adjoint is applied to an object that is not callable, as it silently does not have any effect on those.""" with pytest.raises(ValueError, match=f"{type(obj)} is not callable."): adjoint(obj)