Esempio n. 1
0
    def test_evaluate_qnode_default_input(self, get_circuit, output_dim, n_qubits):
        """Test if the _evaluate_qnode() method works correctly when the inputs argument is a
        default argument, i.e., that it gives the same result as calling the QNode directly"""
        c, w = get_circuit

        @qml.qnode(qml.device("default.qubit", wires=n_qubits), interface="torch")
        def c_default(w1, w2, w3, w4, w5, w6, w7, inputs=None):
            """Version of the circuit with inputs as a default argument"""
            qml.templates.AngleEmbedding(inputs, wires=list(range(n_qubits)))
            qml.templates.StronglyEntanglingLayers(w1, wires=list(range(n_qubits)))
            qml.RX(w2[0], wires=0)
            qml.RX(w3, wires=0)
            qml.Rot(*w4, wires=0)
            qml.templates.StronglyEntanglingLayers(w5, wires=list(range(n_qubits)))
            qml.Rot(*w6, wires=0)
            qml.RX(w7, wires=0)
            return [qml.expval(qml.PauliZ(i)) for i in range(output_dim)]

        layer = TorchLayer(c_default, w)
        x = torch.Tensor(np.ones(n_qubits))

        layer_out = layer._evaluate_qnode(x).detach().numpy()

        weights = [layer.qnode_weights[weight].detach().numpy() for weight in ordered_weights]

        circuit_out = c(x, *weights)
        assert np.allclose(layer_out, circuit_out)
Esempio n. 2
0
    def test_evaluate_qnode_shuffled_args(self, get_circuit, output_dim,
                                          n_qubits):
        """Test if the _evaluate_qnode() method works correctly when the inputs argument is not the
        first positional argument, i.e., that it gives the same result as calling the QNode
        directly"""
        c, w = get_circuit

        @qml.qnode(qml.device("default.qubit", wires=n_qubits),
                   interface="torch")
        def c_shuffled(w1, inputs, w2, w3, w4, w5, w6, w7):
            """Version of the circuit with a shuffled signature"""
            qml.templates.AngleEmbedding(inputs, wires=list(range(n_qubits)))
            qml.templates.StronglyEntanglingLayers(w1,
                                                   wires=list(range(n_qubits)))
            qml.RX(w2[0], wires=0)
            qml.RX(w3, wires=0)
            qml.Rot(*w4, wires=0)
            qml.templates.StronglyEntanglingLayers(w5,
                                                   wires=list(range(n_qubits)))
            qml.Rot(*w6, wires=0)
            qml.RX(w7, wires=0)
            return [qml.expval(qml.PauliZ(i)) for i in range(output_dim)]

        layer = TorchLayer(c_shuffled, w)
        x = torch.Tensor(np.ones(n_qubits))

        layer_out = layer._evaluate_qnode(x)
        weights = layer.qnode_weights.values()
        circuit_out = c(x, *weights).type(x.dtype)

        assert torch.allclose(layer_out, circuit_out)
Esempio n. 3
0
    def test_var_keyword(self, n_qubits, output_dim):
        """Test that variable number of keyword arguments works"""
        dev = qml.device("default.qubit", wires=n_qubits)
        w = {
            "w1": (3, n_qubits, 3),
            "w2": (1,),
            "w3": 1,
            "w4": [3],
            "w5": (2, n_qubits, 3),
            "w6": 3,
            "w7": 0,
        }

        @qml.qnode(dev, interface="torch")
        def c(inputs, **kwargs):
            """A circuit that embeds data using the AngleEmbedding and then performs a variety of
            operations. The output is a PauliZ measurement on the first output_dim qubits. One set of
            parameters, w5, are specified as non-trainable."""
            qml.templates.AngleEmbedding(inputs, wires=list(range(n_qubits)))
            qml.templates.StronglyEntanglingLayers(kwargs["w1"], wires=list(range(n_qubits)))
            qml.RX(kwargs["w2"][0], wires=0 % n_qubits)
            qml.RX(kwargs["w3"], wires=1 % n_qubits)
            qml.Rot(*kwargs["w4"], wires=2 % n_qubits)
            qml.templates.StronglyEntanglingLayers(kwargs["w5"], wires=list(range(n_qubits)))
            qml.Rot(*kwargs["w6"], wires=3 % n_qubits)
            qml.RX(kwargs["w7"], wires=4 % n_qubits)
            return [qml.expval(qml.PauliZ(i)) for i in range(output_dim)]

        layer = TorchLayer(c, w)
        x = torch.ones(n_qubits)

        layer_out = layer._evaluate_qnode(x)
        circuit_out = c(x, **layer.qnode_weights).type(x.dtype)

        assert torch.allclose(layer_out, circuit_out)
Esempio n. 4
0
    def test_evaluate_qnode(self, get_circuit, n_qubits):
        """Test if the _evaluate_qnode() method works correctly, i.e., that it gives the same
        result as calling the QNode directly"""
        c, w = get_circuit
        layer = TorchLayer(c, w)
        x = torch.ones(n_qubits)

        layer_out = layer._evaluate_qnode(x)
        weights = layer.qnode_weights.values()
        circuit_out = c(x, *weights).type(x.dtype)

        assert torch.allclose(layer_out, circuit_out)
Esempio n. 5
0
    def test_evaluate_qnode(self, get_circuit, n_qubits):
        """Test if the _evaluate_qnode() method works correctly, i.e., that it gives the same
        result as calling the QNode directly"""
        c, w = get_circuit
        layer = TorchLayer(c, w)
        x = torch.ones(n_qubits)

        layer_out = layer._evaluate_qnode(x).detach().numpy()

        weights = [layer.qnode_weights[weight].detach().numpy() for weight in ordered_weights]

        circuit_out = c(x, *weights)
        assert np.allclose(layer_out, circuit_out)
Esempio n. 6
0
    def test_non_input_defaults_tape_mode(self, n_qubits, output_dim):
        """Test that everything works when default arguments that are not the input argument are
        present in the QNode in tape mode"""
        if not qml.tape_mode_active():
            pytest.skip("This functionality is only supported in tape mode.")

        dev = qml.device("default.qubit", wires=n_qubits)
        w = {
            "w1": (3, n_qubits, 3),
            "w2": (1, ),
            "w3": 1,
            "w4": [3],
            "w5": (2, n_qubits, 3),
            "w6": 3,
            "w7": 0,
        }

        @qml.qnode(dev, interface="torch")
        def c(inputs, w1, w2, w4, w5, w6, w7, w3=0.5):
            """A circuit that embeds data using the AngleEmbedding and then performs a variety of
            operations. The output is a PauliZ measurement on the first output_dim qubits. One set of
            parameters, w5, are specified as non-trainable."""
            qml.templates.AngleEmbedding(inputs, wires=list(range(n_qubits)))
            qml.templates.StronglyEntanglingLayers(w1,
                                                   wires=list(range(n_qubits)))
            qml.RX(w2[0], wires=0 % n_qubits)
            qml.RX(w3, wires=1 % n_qubits)
            qml.Rot(*w4, wires=2 % n_qubits)
            qml.templates.StronglyEntanglingLayers(w5,
                                                   wires=list(range(n_qubits)))
            qml.Rot(*w6, wires=3 % n_qubits)
            qml.RX(w7, wires=4 % n_qubits)
            return [qml.expval(qml.PauliZ(i)) for i in range(output_dim)]

        layer = TorchLayer(c, w)
        x = torch.ones(n_qubits)

        layer_out = layer._evaluate_qnode(x)
        circuit_out = c(x, **layer.qnode_weights).type(x.dtype)

        assert torch.allclose(layer_out, circuit_out)