def test_natural_gradient4(self, grad_method, qfi_method, regularization):
        """Test the natural gradient 4"""

        # Avoid regularization = lasso intentionally because it does not converge
        try:
            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.0)
            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.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=3)
        except MissingOptionalLibraryError as ex:
            self.skipTest(str(ex))
    def test_natural_gradient(self, method, regularization):
        """Test the natural gradient"""
        try:
            for params in (ParameterVector("a", 2),
                           [Parameter("a"), Parameter("b")]):
                ham = 0.5 * X - 1 * Z

                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.0)
                nat_grad = NaturalGradient(
                    grad_method=method,
                    regularization=regularization).convert(operator=op)
                values_dict = [{params[0]: np.pi / 4, params[1]: np.pi / 2}]

                # reference values obtained by classically computing the natural gradients
                correct_values = [[
                    -3.26, 1.63
                ]] if regularization == "ridge" else [[-4.24, 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=1)
        except MissingOptionalLibraryError as ex:
            self.skipTest(str(ex))
Exemplo n.º 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

        try:
            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)
        except MissingOptionalLibraryError as ex:
            self.skipTest(str(ex))
Exemplo n.º 4
0
    def test_natural_gradient(self, method, regularization):
        """Test the natural gradient"""
        try:
            for params in (ParameterVector('a', 2),
                           [Parameter('a'), Parameter('b')]):
                ham = 0.5 * X - 1 * Z

                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)
        except MissingOptionalLibraryError as ex:
            self.skipTest(str(ex))
Exemplo n.º 5
0
 def test_natural_gradients_invalid(self):
     """test that an exception is thrown when an invalid gradient method is used"""
     solver = VQEUCCFactory(quantum_instance=QuantumInstance(
         BasicAer.get_backend("statevector_simulator")))
     grad = NaturalGradient(grad_method="fin_diff",
                            qfi_method="lin_comb_full",
                            regularization="ridge")
     calc = AdaptVQE(self.qubit_converter, solver, gradient=grad)
     with self.assertRaises(QiskitNatureError):
         _ = calc.solve(self.problem)
    def test_gradient_wrapper2(self, backend_type, atol):
        """Test the gradient wrapper for gradients checking that statevector and qasm gives the
           same results

        dp0/da = cos(a)sin(b) / 2
        dp1/da = - cos(a)sin(b) / 2
        dp0/db = sin(a)cos(b) / 2
        dp1/db = - sin(a)cos(b) / 2
        """
        method = "lin_comb"
        a = Parameter("a")
        b = Parameter("b")
        params = [a, b]

        qc = QuantumCircuit(2)
        qc.h(1)
        qc.h(0)
        qc.sdg(1)
        qc.cz(0, 1)
        qc.ry(params[0], 0)
        qc.rz(params[1], 0)
        qc.h(1)

        obs = (Z ^ X) - (Y ^ Y)
        op = StateFn(obs, is_measurement=True) @ CircuitStateFn(primitive=qc)

        shots = 8192 if backend_type == "qasm_simulator" else 1

        values = [[0, np.pi / 2], [np.pi / 4, np.pi / 4],
                  [np.pi / 3, np.pi / 9]]
        correct_values = [[-4.0, 0], [-2.0, -4.82842712],
                          [-0.68404029, -7.01396121]]
        for i, value in enumerate(values):
            backend = BasicAer.get_backend(backend_type)
            q_instance = QuantumInstance(backend=backend,
                                         shots=shots,
                                         seed_simulator=2,
                                         seed_transpiler=2)
            grad = NaturalGradient(grad_method=method).gradient_wrapper(
                operator=op, bind_params=params, backend=q_instance)
            result = grad(value)
            self.assertTrue(np.allclose(result, correct_values[i], atol=atol))
 def test_natural_gradient3(self, qfi_method, circuit_qfi):
     """Test the natural gradient 3"""
     nat_grad = NaturalGradient(qfi_method=qfi_method)
     self.assertIsInstance(nat_grad.qfi_method, circuit_qfi)
 def test_natural_gradient2(self):
     """Test the natural gradient 2"""
     with self.assertRaises(TypeError):
         _ = NaturalGradient().convert(None, None)
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.decompose())], 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]]
backend = BasicAer.get_backend("qasm_simulator")
q_instance = QuantumInstance(backend=backend, shots=5000)
sampler = CircuitSampler(backend=q_instance).convert(
    grad, params={k: [v] for k, v in value_dict.items()}
)
print('Sampler ', sampler.eval()[0])
print('Correct Values ', correct_values)