示例#1
0
def _ml_defaults(hyperparams):
    """Uses hyperparameters or defaults to construct the components of the machine learning benchmark.

    Args:
            hyperparams (dict): hyperparameters provided by user
    """
    # get hyperparameters or set default values
    n_features = hyperparams.pop("n_features", 4)
    n_samples = hyperparams.pop("n_samples", 20)
    interface = hyperparams.pop("interface", "autograd")
    diff_method = hyperparams.pop("diff_method", "best")
    device = hyperparams.pop("device", "default.qubit")

    # if device name is given, create device
    if isinstance(device, str):
        device = qml.device(device, wires=n_features)

    # data
    x0 = np.random.normal(loc=-1, scale=1, size=(n_samples // 2, n_features))
    x1 = np.random.normal(loc=1, scale=1, size=(n_samples // 2, n_features))
    x = np.concatenate([x0, x1], axis=0)
    y = np.concatenate([-np.ones(50), np.ones(50)], axis=0)
    data = list(zip(x, y))

    return data, device, diff_method, interface
    def test_wrong_dy_statevector(self, tol, dev):
        """Tests raise an exception when dy is incorrect"""
        x, y, z = [0.5, 0.3, -0.7]

        with qml.tape.QuantumTape() as tape:
            qml.RX(0.4, wires=[0])
            qml.Rot(x, y, z, wires=[0])
            qml.RY(-0.2, wires=[0])
            qml.state()

        tape.trainable_params = {1, 2, 3}

        dy1 = np.ones(3, dtype=dev.C_DTYPE)

        with pytest.raises(
                ValueError,
                match=
                "Size of the provided vector dy must be the same as the size of"
        ):
            dev.vjp(tape.measurements, dy1)

        dy2 = np.ones(4, dtype=dev.R_DTYPE)

        with pytest.warns(
                UserWarning,
                match="The vjp method only works with complex-valued dy"):
            dev.vjp(tape.measurements, dy2)
示例#3
0
 def test_calculate_WAW(self):
     """Test that the calculate_WAW method calculates correctly"""
     const = 2
     A = 0.1767767 * np.ones((4, 4))
     params = const * np.ones(4)
     waw = StrawberryFieldsGBS.calculate_WAW(params, A)
     assert np.allclose(waw, const * A)
示例#4
0
    def test_caching_samples_at_input(self, mocker):
        """Test caching in non-analytic mode with pre-generated input samples. No call to the
        QNode should result in more samples being generated."""
        dev = qml.device(
            "strawberryfields.gbs",
            wires=4,
            cutoff_dim=3,
            use_cache=True,
            shots=4,
            samples=samples,
        )
        A = 0.1767767 * np.ones((4, 4), requires_grad=False)
        params = np.ones(4)

        @qml.qnode(dev)
        def vgbs(params):
            ParamGraphEmbed(params, A, 1, wires=range(4))
            return qml.probs(wires=range(4))

        spy = mocker.spy(sf.Engine, "run")
        p1 = vgbs(params)
        samps = dev.samples.copy()
        p2 = vgbs(0.5 * params)
        samps2 = dev.samples.copy()
        p2_expected = dev._reparametrize_probability(p1.reshape((3, 3, 3, 3))).ravel()
        assert np.allclose(samps, samples)
        assert np.allclose(samps2, samples)
        assert np.allclose(p2_expected, p2)
        spy.assert_not_called()
示例#5
0
 def test_apply_mask(self):
     size = 3
     mp = DropoutMask((size, ))
     with pytest.raises(IndexError):
         mp.apply_mask(pnp.ones((size - 1, size)))
     mp.mask[1] = True
     result = mp.apply_mask(pnp.ones((size, ), dtype=bool))
     assert pnp.sum(mp.mask) == 1
     assert pnp.sum(result) == size - 1
示例#6
0
def test_generate_hamiltonian(symbols, geometry, h_ref_data):
    r"""Test that generate_hamiltonian returns the correct Hamiltonian."""

    mol = Molecule(symbols, geometry)
    args = []
    h = generate_hamiltonian(mol)(*args)
    h_ref = qml.Hamiltonian(h_ref_data[0], h_ref_data[1])

    assert np.allclose(h.terms[0], h_ref.terms[0])
    assert qml.Hamiltonian(np.ones(len(h.terms[0])), h.terms[1]).compare(
        qml.Hamiltonian(np.ones(len(h_ref.terms[0])), h_ref.terms[1]))
示例#7
0
 def test_apply_mask(self):
     size = 3
     mp = ValueMask((size, ))
     with pytest.raises(ValueError):
         mp.apply_mask(pnp.ones((size - 1, )))
     mp.mask[1] = 1
     result = mp.apply_mask(pnp.ones((size, ), dtype=float))
     assert pnp.sum(mp.mask) == 1
     assert pnp.sum(result) == size + 1
     mp.mask[1] = -1
     result = mp.apply_mask(pnp.ones((size, ), dtype=float))
     assert pnp.sum(result) == size - 1
示例#8
0
    def test_apply_wrong_dim(self):
        """Test that the apply method raises a ValueError when the number of variable parameters
        does not match the number of modes"""
        dev = qml.device("strawberryfields.gbs", wires=4, cutoff_dim=3)
        op = "ParamGraphEmbed"
        wires = list(range(4))

        A = 0.1767767 * np.ones((4, 4), requires_grad=False)
        params = np.ones(3)
        n_mean = 1
        par = [params, A, n_mean]

        with pytest.raises(ValueError, match="The number of variable parameters must be"):
            dev.apply(op, wires, par)
示例#9
0
def optimize(alpha, beta):
    """Define a function that optimizes theta_A0, theta_A1, theta_B0, theta_B1 to maximize the probability of winning the game

    Args:
        - alpha (float): real coefficient of |00>
        - beta (float): real coefficient of |11>

    Returns:
        - (float): Probability of winning
    """
    def cost(params):
        """Define a cost function that only depends on params, given alpha and beta fixed"""
        return -winning_prob(params, alpha, beta)

    # QHACK #

    #Initialize parameters, choose an optimization method and number of steps
    init_params = np.ones(4)
    opt = qml.AdagradOptimizer()
    steps = 2000

    # QHACK #

    # set the initial parameter values
    params = init_params

    for i in range(steps):
        # update the circuit parameters
        # QHACK #

        params = opt.step(cost, params)

        # QHACK #

    return winning_prob(params, alpha, beta)
示例#10
0
    def test_compile_autograd(self, diff_method):
        """Test QNode and gradient in autograd interface."""

        original_qnode = qml.QNode(qfunc,
                                   dev,
                                   interface="autograd",
                                   diff_method=diff_method)
        transformed_qnode = qml.QNode(transformed_qfunc,
                                      dev,
                                      interface="autograd",
                                      diff_method=diff_method)

        x = np.array([0.1, 0.2, 0.3], requires_grad=False)
        params = np.ones((2, 3))

        # Check that the numerical output is the same
        assert qml.math.allclose(original_qnode(x, params),
                                 transformed_qnode(x, params))

        # Check that the gradient is the same
        assert qml.math.allclose(
            qml.grad(original_qnode)(x, params),
            qml.grad(transformed_qnode)(x, params))

        # Check operation list
        ops = transformed_qnode.qtape.operations
        compare_operation_lists(ops, expected_op_list, expected_wires_list)
示例#11
0
    def test_with_qnode(self, qnode, params, ids, nums_frequency, spectra,
                        shifts, exp_calls, mocker):
        """Run a full reconstruction on a QNode."""
        qnode = qml.QNode(qnode, dev_1)

        with qml.Tracker(qnode.device) as tracker:
            recons = reconstruct(qnode, ids, nums_frequency, spectra,
                                 shifts)(*params)
        assert tracker.totals["executions"] == exp_calls
        arg_names = list(signature(qnode.func).parameters.keys())
        for outer_key in recons:
            outer_key_num = arg_names.index(outer_key)
            for inner_key, rec in recons[outer_key].items():
                x0 = params[outer_key_num]
                if not pnp.isscalar(x0):
                    x0 = x0[inner_key]
                    shift_vec = qml.math.zeros_like(params[outer_key_num])
                    shift_vec[inner_key] = 1.0
                shift_vec = 1.0 if pnp.isscalar(
                    params[outer_key_num]) else shift_vec
                mask = (0.0 if pnp.isscalar(params[outer_key_num]) else
                        pnp.ones(qml.math.shape(params[outer_key_num])) -
                        shift_vec)
                univariate = lambda x: qnode(
                    *params[:outer_key_num],
                    params[outer_key_num] * mask + x * shift_vec,
                    *params[outer_key_num + 1:],
                )
                assert np.isclose(rec(x0), qnode(*params))
                assert np.isclose(rec(x0 + 0.1), univariate(x0 + 0.1))
                assert fun_close(rec, univariate, 10)
示例#12
0
        def circuit_aux(cparams):
            diag = np.ones(2**num_wires)
            diag[0] *= -1

            # Initialization
            init_circuit(cparams)

            # Non-Boolean Amplitude Amplification go brrrrr
            for k in range(1, K + 1):
                # Act the oracle during odd iterations, or its inverse during
                # the even iterations
                if k % 2 == 1:
                    self.oracle(cparams, num_qparams)
                else:
                    qml.inv(self.oracle(cparams, num_qparams))

                # Diffusion operator
                qml.inv(init_circuit(cparams))
                # Evan: This is incredibly painful to implement with a standard
                # gate decomposition, so we can't actually use Floq beyond this
                # point...
                qml.DiagonalQubitUnitary(diag, wires=range(num_wires))
                init_circuit(cparams)

            # Measurement of the control registers post amplification
            return qml.probs(wires=range(self.num_qubits, num_wires))
示例#13
0
def diffusion_matrix():

    # DO NOT MODIFY anything in this code block

    psi_piece = (1 / 2**4) * np.ones(2**4)
    ident_piece = np.eye(2**4)
    return 2 * psi_piece - ident_piece
示例#14
0
    def test_compile_template(self):
        """Test that functions with templates are correctly expanded and compiled."""

        # Push commuting gates to the right and merging rotations gives a circuit
        # with alternating RX and CNOT gates
        def qfunc(x, params):
            qml.templates.AngleEmbedding(x, wires=range(3))
            qml.templates.BasicEntanglerLayers(params, wires=range(3))
            return qml.expval(qml.PauliZ(wires=2))

        dev = qml.device("default.qubit", wires=3)
        qnode = qml.QNode(qfunc, dev)

        pipeline = [commute_controlled, merge_rotations]
        transformed_qfunc = compile(pipeline=pipeline)(qfunc)
        transformed_qnode = qml.QNode(transformed_qfunc, dev)

        x = np.array([0.1, 0.2, 0.3])
        params = np.ones((2, 3))

        original_result = qnode(x, params)
        transformed_result = transformed_qnode(x, params)
        assert np.allclose(original_result, transformed_result)

        names_expected = ["RX", "CNOT"] * 6
        wires_expected = [
            Wires(0),
            Wires([0, 1]),
            Wires(1),
            Wires([1, 2]),
            Wires(2),
            Wires([2, 0]),
        ] * 2

        compare_operation_lists(transformed_qnode.qtape.operations, names_expected, wires_expected)
示例#15
0
 def test_apply_mask(self):
     size = 3
     mp = self._create_circuit(size)
     with pytest.raises(ValueError):
         mp.apply_mask(pnp.ones((size, size - 1)))
     mp.mask(Axis.WIRES)[:size - 1] = True
     result = mp.apply_mask(pnp.ones((size, size), dtype=bool))
     assert pnp.sum(~mp.full_mask(DropoutMask)) == size
     assert pnp.sum(result) == size
     mp.mask(Axis.LAYERS)[:size - 1] = True
     result = mp.apply_mask(pnp.ones((size, size), dtype=bool))
     assert pnp.sum(~mp.full_mask(DropoutMask)) == 1
     assert pnp.sum(result) == 1
     mp.mask(Axis.PARAMETERS)[(size - 1, size - 1)] = True
     result = mp.apply_mask(pnp.ones((size, size), dtype=bool))
     assert pnp.sum(~mp.full_mask(DropoutMask)) == 0
     assert pnp.sum(result) == 0
示例#16
0
    def test_reparametrize_probability(self):
        """Test the _reparametrize_probability method applied to a fixed 2-mode example"""
        dev = qml.device("strawberryfields.gbs", wires=2, cutoff_dim=3, shots=None)
        A = 0.35355339 * np.ones((2, 2))
        dev._WAW = 0.9 * A
        dev.Z_inv = 1 / np.sqrt(2)
        dev._params = 0.9 * np.ones(2)

        p = np.array(
            [0.70710678, 0.0, 0.04419417, 0.0, 0.08838835, 0.0, 0.04419417, 0.0, 0.02485922]
        ).reshape((3, 3))
        p_reparam = dev._reparametrize_probability(p)
        p_target = np.array(
            [0.77136243, 0.0, 0.03905022, 0.0, 0.07810045, 0.0, 0.03905022, 0.0, 0.01779226]
        ).reshape((3, 3))

        assert np.allclose(p_reparam, p_target)
示例#17
0
    def test_jacobian_all_wires(self):
        """Test that the _jacobian_all_wires method returns the correct jacobian for a fixed
        input probability distribution"""
        dev = qml.device("strawberryfields.gbs", wires=4, cutoff_dim=3)
        dev._WAW = 0.1767767 * np.ones((4, 4))
        params = np.array([1, 2, 3, 4])
        n_mean = np.ones(4) / 4
        dev._params = params

        indices = np.indices([3, 3, 3, 3]).reshape(4, -1).T
        probs = np.arange(3 ** 4)
        jac_expected = np.zeros((3 ** 4, 4))

        for i, ind in enumerate(indices):
            jac_expected[i] = probs[i] * (ind - n_mean) / params

        jac = dev._jacobian_all_wires(probs)
        assert np.allclose(jac, jac_expected)
示例#18
0
    def test_apply_analytic(self):
        """Test that the apply method constructs the correct program"""
        dev = qml.device("strawberryfields.gbs", wires=4, cutoff_dim=3)
        op = "ParamGraphEmbed"
        wires = list(range(4))

        A = 0.1767767 * np.ones((4, 4), requires_grad=False)
        params = 0.5 * np.ones(4)
        n_mean = 1
        par = [params, A, n_mean]

        with dev.execution_context():
            dev.apply(op, wires, par)

        circ = dev.prog.circuit
        assert len(circ) == 1
        assert isinstance(circ[0].op, GraphEmbed)
        assert np.allclose(circ[0].op.p[0], 0.5 * A)
示例#19
0
    def oracle(self, cparams, num_qparams):
        diag = np.ones(2**self.num_qubits)
        diag[0] *= -1

        qml.inv(self.rand_circuit(cparams, num_qparams))
        qml.DiagonalQubitUnitary(diag, wires=range(self.num_qubits))

        self.rand_circuit(cparams, num_qparams)
        qml.DiagonalQubitUnitary(diag, wires=range(self.num_qubits))
示例#20
0
 def test_pre_measure_eng(self, tol):
     """Test that the pre_measure method operates as expected by initializing the engine
     correctly"""
     dev = qml.device("strawberryfields.gbs", wires=4, cutoff_dim=3)
     prog = Program(4)
     op1 = GraphEmbed(0.1767767 * np.ones((4, 4)), mean_photon_per_mode=0.25)
     prog.append(op1, prog.register)
     dev.prog = prog
     dev.pre_measure()
     assert dev.eng.backend_name == "gaussian"
     assert dev.eng.backend_options == {"cutoff_dim": 3}
示例#21
0
    def test_shape(self, wires, cutoff_dim):
        """Test that the probabilities and jacobian are returned with the expected shape"""
        dev = qml.device("strawberryfields.gbs", wires=wires, cutoff_dim=cutoff_dim)
        a = np.ones((wires, wires), requires_grad=False)
        params = np.ones(wires)

        @qnode_decorator(dev)
        def vgbs(params):
            ParamGraphEmbed(params, a, 1, wires=range(wires))
            return qml.probs(wires=range(wires))

        d_vgbs = qml.jacobian(vgbs, argnum=0)

        p = vgbs(params)
        dp = d_vgbs(params)

        assert p.shape == (cutoff_dim ** wires,)
        assert dp.shape == (cutoff_dim ** wires, wires)
        assert (p >= 0).all()
        assert (p <= 1).all()
        assert np.sum(p) <= 1
    def test_template_integration(self, strategy, tol):
        """Test that the metric tensor transform acts on QNodes
        correctly when the QNode contains a template"""
        dev = qml.device("default.qubit", wires=3)

        @qml.beta.qnode(dev, expansion_strategy=strategy)
        def circuit(weights):
            qml.templates.StronglyEntanglingLayers(weights, wires=[0, 1, 2])
            return qml.probs(wires=[0, 1])

        weights = np.ones([2, 3, 3], dtype=np.float64, requires_grad=True)
        res = qml.metric_tensor(circuit, approx="block-diag")(weights)
        assert res.shape == (2, 3, 3, 2, 3, 3)
示例#23
0
 def test_pre_measure_non_analytic_cache(self, mocker):
     """Test that the pre_measure method does not overwrite existing samples if present in
     non-analytic mode when use_cache is ``True``"""
     samples = -1 * np.ones((10, 4))
     dev = qml.device(
         "strawberryfields.gbs",
         wires=4,
         cutoff_dim=3,
         shots=10,
         samples=samples,
         use_cache=True,
     )
     prog = Program(4)
     op1 = GraphEmbed(0.1767767 * np.ones((4, 4)), mean_photon_per_mode=0.25)
     op2 = MeasureFock()
     prog.append(op1, prog.register)
     prog.append(op2, prog.register)
     dev.prog = prog
     dev.pre_measure()
     spy = mocker.spy(sf.Engine, "run")
     assert np.allclose(dev.samples, samples)
     spy.assert_not_called()
示例#24
0
    def test_pre_measure_state_and_samples(self, tol):
        """Test that the pre_measure method operates as expected in analytic mode by generating the
        correct output state and not generating samples"""
        dev = qml.device("strawberryfields.gbs", wires=4, cutoff_dim=3)
        prog = Program(4)
        op1 = GraphEmbed(0.1767767 * np.ones((4, 4)), mean_photon_per_mode=0.25)
        prog.append(op1, prog.register)
        dev.prog = prog
        dev.pre_measure()

        assert np.allclose(dev.state.displacement(), np.zeros(4))
        assert np.allclose(dev.state.cov(), target_cov, atol=tol)
        assert dev.samples.size == 0
示例#25
0
    def test_shape_reduced_wires(self, wires, cutoff_dim):
        """Test that the probabilities and jacobian are returned with the expected shape when
        probabilities are measured on a subset of wires"""
        dev = qml.device("strawberryfields.gbs", wires=wires, cutoff_dim=cutoff_dim)
        a = np.ones((wires, wires))
        params = np.ones(wires)

        @qml.qnode(dev)
        def vgbs(params):
            ParamGraphEmbed(params, a, 1, wires=range(wires))
            return qml.probs(wires=[0, 1])

        d_vgbs = qml.jacobian(vgbs, argnum=0)

        p = vgbs(params)
        dp = d_vgbs(params)

        assert p.shape == (cutoff_dim ** 2,)
        assert dp.shape == (cutoff_dim ** 2, wires)
        assert (p >= 0).all()
        assert (p <= 1).all()
        assert np.sum(p) <= 1
示例#26
0
    def test_custom_rotation(self, rotation):
        """Tests that non-default rotation gates are used correctly."""
        n_layers = 2
        n_wires = 4
        weights = np.ones(shape=(n_layers, n_wires))

        with pennylane._queuing.OperationRecorder() as rec:
            BasicEntanglerLayers(weights, wires=range(n_wires), rotation=rotation)

        # assert queue contains the custom rotations and CNOTs only
        gates = rec.queue
        for op in gates:
            if not isinstance(op, CNOT):
                assert isinstance(op, rotation)
示例#27
0
    def test_pre_measure_state_and_samples_non_analytic(self, tol):
        """Test that the pre_measure method operates as expected in non-analytic mode by
        generating the correct output state and samples of the right shape"""
        dev = qml.device("strawberryfields.gbs", wires=4, cutoff_dim=3, analytic=False, shots=2)
        prog = Program(4)
        op1 = GraphEmbed(0.1767767 * np.ones((4, 4)), mean_photon_per_mode=0.25)
        op2 = MeasureFock()
        prog.append(op1, prog.register)
        prog.append(op2, prog.register)
        dev.prog = prog
        dev.pre_measure()

        assert np.allclose(dev.state.displacement(), np.zeros(4))
        assert np.allclose(dev.state.cov(), target_cov, atol=tol)
        assert dev.samples.shape == (2, 4)
示例#28
0
    def test_caching_samples(self, mocker):
        """Test caching in non-analytic mode. Samples should be generated upon first call and
        then not generated subsequently."""
        dev = qml.device(
            "strawberryfields.gbs", wires=4, cutoff_dim=3, use_cache=True, shots=10
        )
        A = 0.1767767 * np.ones((4, 4), requires_grad=False)
        params = np.ones(4)

        @qml.qnode(dev)
        def vgbs(params):
            ParamGraphEmbed(params, A, 1, wires=range(4))
            return qml.probs(wires=range(4))

        vgbs(params)
        samps = dev.samples.copy()
        circ = dev.prog.circuit
        assert np.allclose(circ[0].op.p[0], A)

        spy = mocker.spy(sf.Engine, "run")
        vgbs(0.5 * params)
        samps2 = dev.samples.copy()
        assert np.allclose(samps, samps2)
        spy.assert_not_called()
示例#29
0
    def oracle(self, cparams, num_qparams):
        diag = np.ones(2**self.num_qubits)
        diag[0] *= -1

        qml.inv(self.rand_circuit(cparams, num_qparams))
        if self.floq:
            decomposed_oracle(self.num_qubits)
        else:
            qml.DiagonalQubitUnitary(diag, wires=range(self.num_qubits))

        self.rand_circuit(cparams, num_qparams)
        if self.floq:
            decomposed_oracle(self.num_qubits)
        else:
            qml.DiagonalQubitUnitary(diag, wires=range(self.num_qubits))
示例#30
0
    def test_apply_non_analytic(self, use_cache):
        """Test that the apply method constructs the correct program when in non-analytic mode"""
        dev = qml.device(
            "strawberryfields.gbs", wires=4, cutoff_dim=3, shots=100, use_cache=use_cache
        )
        op = "ParamGraphEmbed"
        wires = list(range(4))

        A = 0.1767767 * np.ones((4, 4), requires_grad=False)
        params = 0.5 * np.ones(4)
        n_mean = 1
        par = [params, A, n_mean]

        with dev.execution_context():
            dev.apply(op, wires, par)

        circ = dev.prog.circuit
        assert len(circ) == 2
        assert isinstance(circ[0].op, GraphEmbed)
        if use_cache:
            assert np.allclose(circ[0].op.p[0], A)
        else:
            assert np.allclose(circ[0].op.p[0], 0.5 * A)
        assert isinstance(circ[1].op, MeasureFock)