def test_natural_gradient(self, method, regularization):
        """Test the natural gradient"""
        ham = 0.5 * X - 1 * Z
        a = Parameter('a')
        b = Parameter('b')
        params = [a, b]

        q = QuantumRegister(1)
        qc = QuantumCircuit(q)
        qc.h(q)
        qc.rz(params[0], q[0])
        qc.rx(params[1], q[0])

        op = ~StateFn(ham) @ CircuitStateFn(primitive=qc, coeff=1.)
        nat_grad = NaturalGradient(grad_method=method,
                                   regularization=regularization).convert(
                                       operator=op, params=params)
        values_dict = [{params[0]: np.pi / 4, params[1]: np.pi / 2}]
        correct_values = [[-2.36003979, 2.06503481]
                          ] if regularization == 'ridge' else [[-4.2, 0]]
        for i, value_dict in enumerate(values_dict):
            np.testing.assert_array_almost_equal(
                nat_grad.assign_parameters(value_dict).eval(),
                correct_values[i],
                decimal=0)
    def test_natural_gradient4(self, grad_method, qfi_method, regularization):
        """Test the natural gradient 4"""

        # Avoid regularization = lasso intentionally because it does not converge

        ham = 0.5 * X - 1 * Z
        a = Parameter('a')
        params = a

        q = QuantumRegister(1)
        qc = QuantumCircuit(q)
        qc.h(q)
        qc.rz(a, q[0])

        op = ~StateFn(ham) @ CircuitStateFn(primitive=qc, coeff=1.)
        nat_grad = NaturalGradient(grad_method=grad_method,
                                   qfi_method=qfi_method,
                                   regularization=regularization).convert(
                                       operator=op, params=params)
        values_dict = [{a: np.pi / 4}]
        correct_values = [[0.]
                          ] if regularization == 'ridge' else [[-1.41421342]]
        for i, value_dict in enumerate(values_dict):
            np.testing.assert_array_almost_equal(
                nat_grad.assign_parameters(value_dict).eval(),
                correct_values[i],
                decimal=0)
Exemple #3
0
    def test_grad_combo_fn_chain_rule_nat_grad(self):
        """
        Test the chain rule for a custom gradient combo function

        """
        np.random.seed(2)

        def combo_fn(x):
            amplitudes = x[0].primitive.data
            pdf = np.multiply(amplitudes, np.conj(amplitudes))
            return np.sum(np.log(pdf)) / (-len(amplitudes))

        def grad_combo_fn(x):
            amplitudes = x[0].primitive.data
            pdf = np.multiply(amplitudes, np.conj(amplitudes))
            grad = []
            for prob in pdf:
                grad += [-1 / prob]
            return grad

        qc = RealAmplitudes(2, reps=1)
        grad_op = ListOp([StateFn(qc)], combo_fn=combo_fn, grad_combo_fn=grad_combo_fn)
        grad = NaturalGradient(grad_method='lin_comb', regularization='ridge'
                               ).convert(grad_op, qc.ordered_parameters)
        value_dict = dict(
            zip(qc.ordered_parameters, np.random.rand(len(qc.ordered_parameters))))
        correct_values = [[0.20777236], [-18.92560338], [-15.89005475], [-10.44002031]]
        np.testing.assert_array_almost_equal(grad.assign_parameters(value_dict).eval(),
                                             correct_values, decimal=3)