def qnode(x1, x2, params, **kwargs):
            if self.noise_application_level == 'per_gate':
                add_noise_channel(
                    ansatz(x1, params, **kwargs),
                    self.noise_channel_mapped,
                    self.idling_gate_noise_channel,
                )
            else:
                ansatz(x1, params, **kwargs)

            if self.noise_application_level == 'per_embedding':
                # Invoke noise channel with default kwarg data.
                self.noise_channel(*self.args_noise_channel,
                                   wires=device.wires)

            elif self.noise_application_level == 'per_gate':
                add_noise_channel(
                    ansatz(x2, params, **kwargs),
                    self.noise_channel_mapped,
                    self.idling_gate_noise_channel,
                    adjoint=True,
                )
            else:
                qml.adjoint(ansatz)(x2, params, **kwargs)

            if self.noise_application_level in ('per_embedding', 'global'):
                # Invoke noise channel with default kwarg data.
                self.noise_channel(*self.args_noise_channel,
                                   wires=device.wires)

            return qml.probs(wires=device.wires)
Beispiel #2
0
def test_adjoint_of_control():
    """Test adjoint(ctrl(fn)) and ctrl(adjoint(fn))"""
    def my_op(a, b, c):
        qml.RX(a, wires=2)
        qml.RY(b, wires=3)
        qml.RZ(c, wires=0)

    with QuantumTape() as tape1:
        cmy_op_dagger = qml.adjoint(ctrl(my_op, 5))
        # Execute controlled and adjointed version of my_op.
        cmy_op_dagger(0.789, 0.123, c=0.456)

    with QuantumTape() as tape2:
        cmy_op_dagger = ctrl(qml.adjoint(my_op), 5)
        # Execute adjointed and controlled version of my_op.
        cmy_op_dagger(0.789, 0.123, c=0.456)

    expected = [
        qml.CRZ(-0.456, wires=[5, 0]),
        qml.CRY(-0.123, wires=[5, 3]),
        qml.CRX(-0.789, wires=[5, 2]),
    ]
    for tape in [tape1, tape2]:
        assert len(tape.operations) == 1
        ctrl_op = tape.operations[0]
        assert isinstance(ctrl_op, ControlledOperation)
        expanded = ctrl_op.expand()
        assert_equal_operations(expanded.operations, expected)
Beispiel #3
0
 def circuit(phi):
     qml.PauliX(wires=0)
     qml.PauliX(wires=1)
     qml.OrbitalRotation(phi, wires=[0, 1, 2, 3])
     qml.adjoint(qml.OrbitalRotation)(phi, wires=[0, 1, 2, 3])
     qml.PauliX(wires=0)
     qml.PauliX(wires=1)
     return qml.state()
def test_adjoint_with_decomposition(op_builder):
    """Tests the ``QubitCarry`` op under adjoint and decomposition."""
    op = op_builder()
    decomposed_ops = op.decompose()
    with qml.tape.QuantumTape() as adjoint_tape:
        qml.adjoint(op_builder)()
    for a, b in zip(decomposed_ops, reversed(adjoint_tape.operations)):
        np.testing.assert_allclose(a.matrix, np.conj(b.matrix).T)
def qfunc(theta):
    qml.Hadamard(wires=0)
    qml.PauliX(wires=1)
    qml.S(wires=1)
    qml.adjoint(qml.S)(wires=1)
    qml.Hadamard(wires=0)
    qml.CNOT(wires=[0, 1])
    qml.RZ(theta[0], wires=2)
    qml.PauliX(wires=1)
    qml.CZ(wires=[1, 0])
    qml.RY(theta[1], wires=2)
    qml.CZ(wires=[0, 1])
    return qml.expval(qml.PauliX(0) @ qml.PauliX(2))
    def test_single_op_non_param_adjoint(self, op, wires):
        """Test that the adjoint correctly inverts non-parametrized
        operations"""
        op_adjoint = qml.adjoint(op)(wires=wires)
        expected = op(wires=wires).adjoint()

        assert type(op_adjoint) == type(expected)
        assert op_adjoint.wires == expected.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 = qml.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
Beispiel #8
0
        def qpe_circuit():

            qml.Hadamard(wires=0)
            qml.PauliX(wires=1)
            qml.QuantumPhaseEstimation(
                qml.PauliX.matrix,
                target_wires=[0],
                estimation_wires=[1, 2],
            )

            qml.adjoint(qml.QuantumPhaseEstimation)(
                qml.PauliX.matrix,
                target_wires=[0],
                estimation_wires=[1, 2],
            )
            qml.Hadamard(wires=0)
            qml.PauliX(wires=1)

            return qml.state()
    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
Beispiel #10
0
    def test_templates_adjoint(self, template, par, wires):
        """Test that the adjoint correctly inverts templates"""
        res = qml.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
Beispiel #11
0
    def test_single_par_op(self):
        """Test a single parametrized operation for the adjoint method of
        ControlledOperation"""
        op, par, control_wires, wires = qml.RY, np.array(0.3), qml.wires.Wires(1), [2]
        adjoint_of_controlled_op = qml.ctrl(op, control=control_wires)(par, wires=wires).adjoint()

        assert adjoint_of_controlled_op.control_wires == control_wires
        res_ops = adjoint_of_controlled_op.subtape.operations
        op1 = res_ops[0]
        op2 = qml.adjoint(op)(par, wires=wires)

        assert type(op1) == type(op2)
        assert op1.parameters == op2.parameters
        assert op1.wires == op2.wires
Beispiel #12
0
    def test_template(self):
        """Test a template for the adjoint method of ControlledOperation"""
        op, par = qml.templates.StronglyEntanglingLayers, np.ones((1, 2, 3))
        control_wires, wires = qml.wires.Wires(1), [2, 3]
        adjoint_of_controlled_op = qml.ctrl(op, control=control_wires)(par, wires=wires).adjoint()

        assert adjoint_of_controlled_op.control_wires == control_wires
        res_ops = adjoint_of_controlled_op.subtape.operations[0].operations
        expected = qml.adjoint(op)(par, wires=wires)

        for op1, op2 in zip(res_ops, expected):
            assert type(op1) == type(op2)
            assert op1.parameters == op2.parameters
            assert op1.wires == op2.wires
Beispiel #13
0
    def test_cv_template(self):
        """Test a CV template that returns a list of operations for the adjoint
        method of ControlledOperation"""
        op, par = qml.templates.Interferometer, [[1], [0.3], [0.2, 0.3]]
        control_wires, wires = qml.wires.Wires(1), [2, 3]
        adjoint_of_controlled_op = qml.ctrl(op, control=control_wires)(*par, wires=wires).adjoint()

        assert adjoint_of_controlled_op.control_wires == control_wires
        res_ops = adjoint_of_controlled_op.subtape.operations[0].expand().operations
        expected = qml.adjoint(op)(*par, wires=wires).expand().operations

        for op1, op2 in zip(res_ops, expected):
            assert type(op1) == type(op2)
            assert op1.parameters == op2.parameters
            assert op1.wires == op2.wires
Beispiel #14
0
 def adjoint(self):  # pylint: disable=arguments-differ
     return qml.adjoint(qml.MottonenStatePreparation)(self.parameters[0],
                                                      wires=self.wires)
 def circuit():
     qml.CVNeuralNetLayers(*weights, wires=[0, 1])
     qml.adjoint(qml.CVNeuralNetLayers)(*weights, wires=[0, 1])
     return qml.expval(qml.X(0))
Beispiel #16
0
        i += inc
        qml.RY(params[0, j], wires=[wire])

    qml.broadcast(unitary=qml.CRZ,
                  pattern="ring",
                  wires=wires,
                  parameters=params[1])


def ansatz(x, params, wires):
    """The embedding ansatz"""
    for j, layer_params in enumerate(params):
        layer(x, layer_params, wires, i0=j * len(wires))


adjoint_ansatz = qml.adjoint(ansatz)


def random_params(num_wires, num_layers):
    """Generate random variational parameters in the shape for the ansatz."""
    return np.random.uniform(0, 2 * np.pi, (num_layers, 2, num_wires))


# The kernel function itself is now obtained by looking at the probability
# of observing the all-zero state at the end of the kernel circuit –
# because of the ordering in qml.probs, this is the first entry:
def kernel(x1, x2, params):
    return kernel_circuit(x1, x2, params)[0]


# ## Init QEK
 def circuit():
     # Adjoint is RX(-0.2), so expect RY(-0.2) H
     qml.adjoint(qml.RX)(0.2, wires="a")
     return qml.expval(qml.PauliZ("a"))
 def mitigated_qnode(w1, w2):
     qml.SimplifiedTwoDesign(w1, w2, wires=range(2))
     qml.adjoint(qml.SimplifiedTwoDesign)(w1, w2, wires=range(2))
     return qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliZ(1))
Beispiel #19
0
 def my_circuit():
     qml.adjoint(qml.Barrier)(wires=0)
     return qml.state()
Beispiel #20
0
 def kernel_circuit(x1, x2):
     qml.templates.AngleEmbedding(x1, wires=wires)
     qml.adjoint(qml.templates.AngleEmbedding)(x2, wires=wires)
     return qml.probs(wires)
Beispiel #21
0
 def circuit():
     identity()
     qml.adjoint(identity)()
     return qml.state()
Beispiel #22
0
 def adjoint_evolution_circuit(time):
     for i in range(n_wires):
         qml.Hadamard(i)
     qml.adjoint(qml.CommutingEvolution)(hamiltonian, time, frequencies)
     return qml.expval(qml.PauliZ(1))
Beispiel #23
0
 def circuit():
     barrier()
     qml.adjoint(barrier)()
     return qml.state()
Beispiel #24
0
 def circ(n_qubits):
     qml.adjoint(qml.templates.QFT)(wires=range(n_qubits))
     qml.templates.QFT(wires=range(n_qubits))
     return qml.state()
Beispiel #25
0
def kernel(x1, x2):
    """The quantum kernel."""
    AngleEmbedding(x1, wires=range(n_qubits))
    qml.adjoint(AngleEmbedding)(x2, wires=range(n_qubits))
    return qml.expval(qml.Hermitian(projector, wires=range(n_qubits)))
Beispiel #26
0
def kernel(x1, x2, params):
    ansatz(x1, params, wires)
    qml.adjoint(ansatz)(x2, params, wires)
    return qml.expval(qml.Projector([0] * width, wires=wires))
Beispiel #27
0
def kernel_circuit(x1, x2, params):
    ansatz(x1, params, wires=wires)
    qml.adjoint(ansatz(x2, params, wires=wires))

    return qml.probs(wires=wires)
Beispiel #28
0
def inv(operation_list):
    """Invert a list of operations or a :doc:`template </introduction/templates>`.

    If the inversion happens inside a QNode, the operations are removed and requeued
    in the reversed order for proper inversion.

    **Example:**

    The following example illuminates the inversion of a template:

    .. code-block:: python3

        @qml.template
        def ansatz(weights, wires):
            for idx, wire in enumerate(wires):
                qml.RX(weights[idx], wires=[wire])

            for idx in range(len(wires) - 1):
                qml.CNOT(wires=[wires[idx], wires[idx + 1]])

        dev = qml.device('default.qubit', wires=2)

        @qml.qnode(dev)
        def circuit(weights):
            qml.inv(ansatz(weights, wires=[0, 1]))
            return qml.expval(qml.PauliZ(0) @ qml.PauliZ(1))

    We may also invert an operation sequence:

    .. code-block:: python3

        dev = qml.device('default.qubit', wires=2)

        @qml.qnode(dev)
        def circuit1():
            qml.T(wires=[0]).inv()
            qml.Hadamard(wires=[0]).inv()
            qml.S(wires=[0]).inv()
            return qml.expval(qml.PauliZ(0) @ qml.PauliZ(1))

        @qml.qnode(dev)
        def circuit2():
            qml.inv([qml.S(wires=[0]), qml.Hadamard(wires=[0]), qml.T(wires=[0])])
            return qml.expval(qml.PauliZ(0) @ qml.PauliZ(1))

    Double checking that both circuits produce the same output:

    >>> ZZ1 = circuit1()
    >>> ZZ2 = circuit2()
    >>> assert ZZ1 == ZZ2
    True

    Args:
        operation_list (Iterable[~.Operation]): An iterable of operations

    Returns:
        List[~.Operation]: The inverted list of operations
    """
    if isinstance(operation_list, qml.operation.Operation):
        operation_list = [operation_list]
    elif operation_list is None:
        raise ValueError(
            "None was passed as an argument to inv. "
            "This could happen if inversion of a template without the template decorator is attempted."
        )
    elif callable(operation_list):
        raise ValueError(
            "A function was passed as an argument to inv. "
            "This could happen if inversion of a template function is attempted. "
            "Please use inv on the function including its arguments, as in inv(template(args))."
        )
    elif isinstance(operation_list, qml.tape.QuantumTape):
        new_tape = operation_list.adjoint()
        return new_tape

    elif not isinstance(operation_list, Iterable):
        raise ValueError("The provided operation_list is not iterable.")

    non_ops = [
        (idx, op)
        for idx, op in enumerate(operation_list)
        if not isinstance(op, qml.operation.Operation)
    ]

    if non_ops:
        string_reps = [" operation_list[{}] = {}".format(idx, op) for idx, op in non_ops]
        raise ValueError(
            "The given operation_list does not only contain Operations."
            + "The following elements of the iterable were not Operations:"
            + ",".join(string_reps)
        )

    for op in operation_list:
        try:
            # remove the queued operation to be inverted
            # from the existing queuing context
            qml.QueuingContext.remove(op)
        except KeyError:
            # operation to be inverted does not
            # exist on the queuing context
            pass

    def qfunc():
        for o in operation_list:
            o.queue()

    with qml.tape.QuantumTape() as tape:
        qml.adjoint(qfunc)()

    return tape
 def circuit(w1, w2):
     qml.SimplifiedTwoDesign(w1, w2, wires=range(2))
     qml.adjoint(qml.SimplifiedTwoDesign)(w1, w2, wires=range(2))
     return qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliZ(1))
 def f(state):
     qml.QubitStateVector(state, wires=range(3))
     qml.adjoint(qml.QubitSum)(wires=range(3))
     return qml.probs(wires=range(3))