def test_expand_on_state_fn(self):
        """ Test if expanded StateFn has expected num_qubits. """
        num_qubits = 3
        add_qubits = 2

        # case CircuitStateFn, with primitive QuantumCircuit
        qc2 = QuantumCircuit(num_qubits)
        qc2.cx(0, 1)

        cfn = CircuitStateFn(qc2, is_measurement=True)

        cfn_exp = cfn._expand_dim(add_qubits)
        self.assertEqual(cfn_exp.num_qubits, add_qubits + num_qubits)

        # case OperatorStateFn, with OperatorBase primitive, in our case CircuitStateFn
        osfn = OperatorStateFn(cfn)
        osfn_exp = osfn._expand_dim(add_qubits)

        self.assertEqual(osfn_exp.num_qubits, add_qubits + num_qubits)

        # case DictStateFn
        dsfn = DictStateFn('1'*num_qubits, is_measurement=True)
        self.assertEqual(dsfn.num_qubits, num_qubits)

        dsfn_exp = dsfn._expand_dim(add_qubits)
        self.assertEqual(dsfn_exp.num_qubits, num_qubits + add_qubits)

        # case VectorStateFn
        vsfn = VectorStateFn(np.ones(2**num_qubits, dtype=complex))
        self.assertEqual(vsfn.num_qubits, num_qubits)

        vsfn_exp = vsfn._expand_dim(add_qubits)
        self.assertEqual(vsfn_exp.num_qubits, num_qubits + add_qubits)
Beispiel #2
0
    def construct_circuit(self, parameters, q=None):
        """ construct circuit """
        if not len(parameters) == self.num_parameters:
            raise ValueError(
                'Incorrect number of angles: expecting {}, but {} given.'.
                format(self.num_parameters, len(parameters)))

        # initialize circuit, possibly based on given register/initial state
        if isinstance(self._initial_state, QuantumCircuit):
            circuit = CircuitStateFn(self._initial_state)
        elif self._initial_state is not None:
            circuit = CircuitStateFn(
                self._initial_state.construct_circuit('circuit'))
        else:
            circuit = (H ^ self._num_qubits)

        for idx in range(self._p):
            circuit = (self._cost_operator *
                       parameters[idx]).exp_i().compose(circuit)
            circuit = (self._mixer_operator *
                       parameters[idx + self._p]).exp_i().compose(circuit)

        evolution = EvolutionFactory.build(self._cost_operator)
        circuit = evolution.convert(circuit)
        return circuit.to_circuit()
    def test_gradient_u(self, method):
        """Test the state gradient for U
        Tr(|psi><psi|Z) = - 0.5 sin(a)cos(c)
        Tr(|psi><psi|X) = cos^2(a/2) cos(b+c) - sin^2(a/2) cos(b-c)
        """

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

        q = QuantumRegister(1)
        qc = QuantumCircuit(q)
        qc.h(q)
        qc.u(a, b, c, q[0])

        op = ~StateFn(ham) @ CircuitStateFn(primitive=qc, coeff=1.)
        params = [a, b, c]
        state_grad = Gradient(grad_method=method).convert(operator=op,
                                                          params=params)
        values_dict = [{
            a: np.pi / 4,
            b: 0,
            c: 0
        }, {
            a: np.pi / 4,
            b: np.pi / 4,
            c: np.pi / 4
        }]
        correct_values = [[0.3536, 0, 0], [0.3232, -0.42678, -0.92678]]
        for i, value_dict in enumerate(values_dict):
            np.testing.assert_array_almost_equal(
                state_grad.assign_parameters(value_dict).eval(),
                correct_values[i],
                decimal=1)

        # Tr(|psi><psi|Z) = - 0.5 sin(a)cos(c)
        # Tr(|psi><psi|X) = cos^2(a/2) cos(b+c) - sin^2(a/2) cos(b-c)
        # dTr(|psi><psi|H)/da = 0.5(cos(2a)) + 0.5()

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

        op = ~StateFn(ham) @ CircuitStateFn(primitive=qc, coeff=1.)
        params = [a]
        state_grad = Gradient(grad_method=method).convert(operator=op,
                                                          params=params)
        values_dict = [{a: np.pi / 4}, {a: np.pi / 2}]
        correct_values = [[-1.03033], [-1]]
        for i, value_dict in enumerate(values_dict):
            np.testing.assert_array_almost_equal(
                state_grad.assign_parameters(value_dict).eval(),
                correct_values[i],
                decimal=1)
    def test_jax_chain_rule(self, method: str, autograd: bool):
        """Test the chain rule functionality using Jax

        d<H>/d<X> = 2<X>
        d<H>/d<Z> = - sin(<Z>)
        <Z> = Tr(|psi><psi|Z) = sin(a)sin(b)
        <X> = Tr(|psi><psi|X) = cos(a)
        d<H>/da = d<H>/d<X> d<X>/da + d<H>/d<Z> d<Z>/da = - 2 cos(a)sin(a)
                    - sin(sin(a)sin(b)) * cos(a)sin(b)
        d<H>/db = d<H>/d<X> d<X>/db + d<H>/d<Z> d<Z>/db = - sin(sin(a)sin(b)) * sin(a)cos(b)
        """

        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])

        def combo_fn(x):
            return jnp.power(x[0], 2) + jnp.cos(x[1])

        def grad_combo_fn(x):
            return np.array([2 * x[0], -np.sin(x[1])])

        op = ListOp([
            ~StateFn(X) @ CircuitStateFn(primitive=qc, coeff=1.),
            ~StateFn(Z) @ CircuitStateFn(primitive=qc, coeff=1.)
        ],
                    combo_fn=combo_fn,
                    grad_combo_fn=None if autograd else grad_combo_fn)

        state_grad = Gradient(grad_method=method).convert(operator=op,
                                                          params=params)
        values_dict = [{
            a: np.pi / 4,
            b: np.pi
        }, {
            params[0]: np.pi / 4,
            params[1]: np.pi / 4
        }, {
            params[0]: np.pi / 2,
            params[1]: np.pi / 4
        }]
        correct_values = [[-1., 0.], [-1.2397, -0.2397], [0, -0.45936]]
        for i, value_dict in enumerate(values_dict):
            np.testing.assert_array_almost_equal(
                state_grad.assign_parameters(value_dict).eval(),
                correct_values[i],
                decimal=1)
    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)
Beispiel #6
0
    def test_operator_coefficient_hessian(self, method):
        """Test the operator coefficient hessian

        <Z> = Tr( | psi > < psi | Z) = sin(a)sin(b)
        <X> = Tr( | psi > < psi | X) = cos(a)
        d<H>/dc_0 = 2 * c_0 * <X> + c_1 * <Z>
        d<H>/dc_1 = c_0 * <Z>
        d^2<H>/dc_0^2 = 2 * <X>
        d^2<H>/dc_0dc_1 = <Z>
        d^2<H>/dc_1dc_0 = <Z>
        d^2<H>/dc_1^2 = 0
        """
        a = Parameter('a')
        b = Parameter('b')
        q = QuantumRegister(1)
        qc = QuantumCircuit(q)
        qc.h(q)
        qc.rz(a, q[0])
        qc.rx(b, q[0])

        coeff_0 = Parameter('c_0')
        coeff_1 = Parameter('c_1')
        ham = coeff_0 * coeff_0 * X + coeff_1 * coeff_0 * Z
        op = ~StateFn(ham) @ CircuitStateFn(primitive=qc, coeff=1.)
        gradient_coeffs = [(coeff_0, coeff_0), (coeff_0, coeff_1), (coeff_1, coeff_1)]
        coeff_grad = Hessian(hess_method=method).convert(op, gradient_coeffs)
        values_dict = [{coeff_0: 0.5, coeff_1: -1, a: np.pi / 4, b: np.pi},
                       {coeff_0: 0.5, coeff_1: -1, a: np.pi / 4, b: np.pi / 4}]

        correct_values = [[2 / np.sqrt(2), 0, 0], [2 / np.sqrt(2), 1 / 2, 0]]

        for i, value_dict in enumerate(values_dict):
            np.testing.assert_array_almost_equal(coeff_grad.assign_parameters(value_dict).eval(),
                                                 correct_values[i],
                                                 decimal=1)
Beispiel #7
0
    def test_operator_coefficient_gradient(self, method):
        """Test the operator coefficient gradient

        Tr( | psi > < psi | Z) = sin(a)sin(b)
        Tr( | psi > < psi | X) = cos(a)
        """
        a = Parameter('a')
        b = Parameter('b')
        q = QuantumRegister(1)
        qc = QuantumCircuit(q)
        qc.h(q)
        qc.rz(a, q[0])
        qc.rx(b, q[0])

        coeff_0 = Parameter('c_0')
        coeff_1 = Parameter('c_1')
        ham = coeff_0 * X + coeff_1 * Z
        op = ~StateFn(ham) @ CircuitStateFn(primitive=qc, coeff=1.0)
        gradient_coeffs = [coeff_0, coeff_1]
        coeff_grad = Gradient(grad_method=method).convert(op, gradient_coeffs)
        values_dict = [{coeff_0: 0.5, coeff_1: -1, a: np.pi / 4, b: np.pi},
                       {coeff_0: 0.5, coeff_1: -1, a: np.pi / 4, b: np.pi / 4}]
        correct_values = [[1 / np.sqrt(2), 0], [1 / np.sqrt(2), 1 / 2]]
        for i, value_dict in enumerate(values_dict):
            np.testing.assert_array_almost_equal(coeff_grad.assign_parameters(value_dict).eval(),
                                                 correct_values[i],
                                                 decimal=1)
Beispiel #8
0
    def test_prob_hess(self, method):
        """Test the probability Hessian using linear combination of unitaries method

        d^2p0/da^2 = - sin(a)sin(b) / 2
        d^2p1/da^2 =  sin(a)sin(b) / 2
        d^2p0/dadb = cos(a)cos(b) / 2
        d^2p1/dadb = - cos(a)cos(b) / 2
        """

        a = Parameter('a')
        b = Parameter('b')
        params = [(a, a), (a, b)]

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

        op = CircuitStateFn(primitive=qc, coeff=1.)

        prob_hess = Hessian(hess_method=method).convert(operator=op, params=params)
        values_dict = [{a: np.pi / 4, b: 0}, {a: np.pi / 4, b: np.pi / 4},
                       {a: np.pi / 2, b: np.pi}]
        correct_values = [[[0, 0], [1 / (2 * np.sqrt(2)), - 1 / (2 * np.sqrt(2))]],
                          [[- 1 / 4, 1 / 4], [1 / 4, - 1 / 4]],
                          [[0, 0], [0, 0]]]
        for i, value_dict in enumerate(values_dict):
            for j, prob_hess_result in enumerate(prob_hess.assign_parameters(value_dict).eval()):
                np.testing.assert_array_almost_equal(prob_hess_result,
                                                     correct_values[i][j], decimal=1)
    def test_gradient_p(self, method):
        """Test the state gradient for p
        |psi> = 1/sqrt(2)[[1, exp(ia)]]
        Tr(|psi><psi|Z) = 0
        Tr(|psi><psi|X) = cos(a)
        d<H>/da = - 0.5 sin(a)
        """
        ham = 0.5 * X - 1 * Z
        a = Parameter('a')
        params = a

        q = QuantumRegister(1)
        qc = QuantumCircuit(q)
        qc.h(q)
        qc.p(a, q[0])
        op = ~StateFn(ham) @ CircuitStateFn(primitive=qc, coeff=1.)

        state_grad = Gradient(grad_method=method).convert(operator=op,
                                                          params=params)
        values_dict = [{a: np.pi / 4}, {a: 0}, {a: np.pi / 2}]
        correct_values = [-0.5 / np.sqrt(2), 0, -0.5]

        for i, value_dict in enumerate(values_dict):
            np.testing.assert_array_almost_equal(
                state_grad.assign_parameters(value_dict).eval(),
                correct_values[i],
                decimal=1)
Beispiel #10
0
    def test_state_hessian(self, method):
        """Test the state Hessian

        Tr(|psi><psi|Z) = sin(a)sin(b)
        Tr(|psi><psi|X) = cos(a)
        d^2<H>/da^2 = - 0.5 cos(a) + 1 sin(a)sin(b)
        d^2<H>/dbda = - 1 cos(a)cos(b)
        d^2<H>/dbda = - 1 cos(a)cos(b)
        d^2<H>/db^2 = + 1 sin(a)sin(b)
        """

        ham = 0.5 * X - 1 * Z
        a = Parameter('a')
        b = Parameter('b')
        params = [(a, a), (a, b), (b, b)]

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

        op = ~StateFn(ham) @ CircuitStateFn(primitive=qc, coeff=1.)
        state_hess = Hessian(hess_method=method).convert(operator=op, params=params)

        values_dict = [{a: np.pi / 4, b: np.pi}, {a: np.pi / 4, b: np.pi / 4},
                       {a: np.pi / 2, b: np.pi / 4}]
        correct_values = [[-0.5 / np.sqrt(2), 1 / np.sqrt(2), 0],
                          [-0.5 / np.sqrt(2) + 0.5, -1 / 2., 0.5],
                          [1 / np.sqrt(2), 0, 1 / np.sqrt(2)]]

        for i, value_dict in enumerate(values_dict):
            np.testing.assert_array_almost_equal(state_hess.assign_parameters(value_dict).eval(),
                                                 correct_values[i], decimal=1)
Beispiel #11
0
    def test_state_gradient5(self, method):
        """Test the state gradient

        Tr(|psi><psi|Z) = sin(a0)sin(a1)
        Tr(|psi><psi|X) = cos(a0)
        d<H>/da0 = - 0.5 sin(a0) - 1 cos(a0)sin(a1)
        d<H>/da1 = - 1 sin(a0)cos(a1)
        """

        ham = 0.5 * X - 1 * Z
        a = ParameterVector('a', 2)
        params = a

        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.)

        state_grad = Gradient(grad_method=method).convert(operator=op, params=params)
        values_dict = [{a: [np.pi / 4, np.pi]}, {a: [np.pi / 4, np.pi / 4]},
                       {a: [np.pi / 2, np.pi / 4]}]
        correct_values = [[-0.5 / np.sqrt(2), 1 / np.sqrt(2)], [-0.5 / np.sqrt(2) - 0.5, -1 / 2.],
                          [-0.5, -1 / np.sqrt(2)]]

        for i, value_dict in enumerate(values_dict):
            np.testing.assert_array_almost_equal(state_grad.assign_parameters(value_dict).eval(),
                                                 correct_values[i], decimal=1)
    def test_pauli_expectation_param_qobj(self):
        """ Test PauliExpectation with param_qobj """
        q_instance = QuantumInstance(self.backend,
                                     seed_simulator=self.seed,
                                     seed_transpiler=self.seed,
                                     shots=20000)
        qubit_op = (1 * I ^ I) + (2 * I ^ Z) + (3 * Z ^ I) + (4 * Z ^ Z) + (
            5 * X ^ X)
        var_form = RealAmplitudes(qubit_op.num_qubits)
        ansatz_circuit_op = CircuitStateFn(var_form)
        observable = PauliExpectation().convert(~StateFn(qubit_op))
        expect_op = observable.compose(ansatz_circuit_op).reduce()
        params1 = {}
        params2 = {}
        for param in var_form.parameters:
            params1[param] = [0]
            params2[param] = [0, 0]

        sampler1 = CircuitSampler(backend=q_instance, param_qobj=False)
        samples1 = sampler1.convert(expect_op, params=params1)
        val1 = np.real(samples1.eval())[0]
        samples2 = sampler1.convert(expect_op, params=params2)
        val2 = np.real(samples2.eval())
        sampler2 = CircuitSampler(backend=q_instance, param_qobj=True)
        samples3 = sampler2.convert(expect_op, params=params1)
        val3 = np.real(samples3.eval())
        samples4 = sampler2.convert(expect_op, params=params2)
        val4 = np.real(samples4.eval())

        np.testing.assert_array_almost_equal([val1] * 2, val2, decimal=2)
        np.testing.assert_array_almost_equal(val1, val3, decimal=2)
        np.testing.assert_array_almost_equal([val1] * 2, val4, decimal=2)
Beispiel #13
0
def get_exp(H, circ):
    psi = CircuitStateFn(circ)
    backend = Aer.get_backend('statevector_simulator')
    measurable_expression = StateFn(H, is_measurement=True).compose(psi)
    expectation = AerPauliExpectation().convert(measurable_expression)
    sampler = CircuitSampler(backend).convert(expectation)
    return sampler.eval().real
    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)
Beispiel #15
0
    def test_prob_grad(self, method):
        """Test the probability gradient

        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
        """

        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 = CircuitStateFn(primitive=qc, coeff=1.)

        prob_grad = Gradient(grad_method=method).convert(operator=op, params=params)
        values_dict = [{a: np.pi / 4, b: 0}, {params[0]: np.pi / 4, params[1]: np.pi / 4},
                       {params[0]: np.pi / 2, params[1]: np.pi}]
        correct_values = [[[0, 0], [1 / (2 * np.sqrt(2)), - 1 / (2 * np.sqrt(2))]],
                          [[1 / 4, - 1 / 4], [1 / 4, - 1 / 4]],
                          [[0, 0], [- 1 / 2, 1 / 2]]]
        for i, value_dict in enumerate(values_dict):
            for j, prob_grad_result in enumerate(prob_grad.assign_parameters(value_dict).eval()):
                np.testing.assert_array_almost_equal(prob_grad_result,
                                                     correct_values[i][j], decimal=1)
    def test_state_gradient4(self, method):
        """Test the state gradient 4
         Tr(|psi><psi|ZX) = -cos(a)
         daTr(|psi><psi|ZX) = sin(a)
        """

        ham = X ^ Z
        a = Parameter('a')
        params = a

        q = QuantumRegister(2)
        qc = QuantumCircuit(q)
        qc.x(q[0])
        qc.h(q[1])
        qc.crz(a, q[0], q[1])
        op = ~StateFn(ham) @ CircuitStateFn(primitive=qc, coeff=1.)

        state_grad = Gradient(grad_method=method).convert(operator=op,
                                                          params=params)
        values_dict = [{a: np.pi / 4}, {a: 0}, {a: np.pi / 2}]
        correct_values = [1 / np.sqrt(2), 0, 1]

        for i, value_dict in enumerate(values_dict):
            np.testing.assert_array_almost_equal(
                state_grad.assign_parameters(value_dict).eval(),
                correct_values[i],
                decimal=1)
Beispiel #17
0
        def gradient_function(current_point):
            """
            Gradient function

            Args:
                current_point (np.ndarray): Current values for the variational parameters.

            Returns:
                np.ndarray: array of partial derivatives of the loss
                    function w.r.t. the variational parameters.
            """
            free_params = self._free_parameters
            generated_data, _ = self.get_output(quantum_instance,
                                                params=current_point,
                                                shots=self._shots)
            prediction_generated = discriminator.get_label(generated_data,
                                                           detach=True)
            op = ~CircuitStateFn(primitive=self.generator_circuit)
            grad_object = gradient_object.convert(operator=op,
                                                  params=free_params)
            value_dict = {
                free_params[i]: current_point[i]
                for i in range(len(free_params))
            }
            analytical_gradients = np.array(
                grad_object.assign_parameters(value_dict).eval())
            loss_gradients = self.loss(prediction_generated,
                                       analytical_gradients).real
            return loss_gradients
    def test_qfi(self, method):
        """Test if the quantum fisher information calculation is correct

        QFI = [[1, 0], [0, 1]] - [[0, 0], [0, cos^2(a)]]
        """

        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 = CircuitStateFn(primitive=qc, coeff=1.)
        qfi = QFI(qfi_method=method).convert(operator=op, params=params)
        values_dict = [{
            params[0]: np.pi / 4,
            params[1]: 0.1
        }, {
            params[0]: np.pi,
            params[1]: 0.1
        }, {
            params[0]: np.pi / 2,
            params[1]: 0.1
        }]
        correct_values = [[[1, 0], [0, 0.5]], [[1, 0], [0, 0]], [[1, 0],
                                                                 [0, 1]]]
        for i, value_dict in enumerate(values_dict):
            np.testing.assert_array_almost_equal(
                qfi.assign_parameters(value_dict).eval(),
                correct_values[i],
                decimal=1)
    def test_state_gradient3(self, method):
        """Test the state gradient 3

        Tr(|psi><psi|Z) = sin(a)sin(c(a)) = sin(a)sin(cos(a)+1)
        Tr(|psi><psi|X) = cos(a)
        d<H>/da = - 0.5 sin(a) - 1 cos(a)sin(cos(a)+1) + 1 sin^2(a)cos(cos(a)+1)
        """
        ham = 0.5 * X - 1 * Z
        a = Parameter('a')
        # b = Parameter('b')
        params = a
        c = np.cos(a) + 1
        q = QuantumRegister(1)
        qc = QuantumCircuit(q)
        qc.h(q)
        qc.rz(a, q[0])
        qc.rx(c, q[0])
        op = ~StateFn(ham) @ CircuitStateFn(primitive=qc, coeff=1.)

        state_grad = Gradient(grad_method=method).convert(operator=op,
                                                          params=params)
        values_dict = [{a: np.pi / 4}, {a: 0}, {a: np.pi / 2}]
        correct_values = [-1.1220, -0.9093, 0.0403]
        for i, value_dict in enumerate(values_dict):
            np.testing.assert_array_almost_equal(
                state_grad.assign_parameters(value_dict).eval(),
                correct_values[i],
                decimal=1)
    def test_circuit_state_fn_from_dict_initialize(self):
        """ state fn circuit from dict initialize test """
        statedict = {'101': .5, '100': .1, '000': .2, '111': .5}
        sfc = CircuitStateFn.from_dict(statedict)
        self.assertIsInstance(sfc, CircuitStateFn)
        samples = sfc.sample()
        np.testing.assert_array_almost_equal(
            StateFn(statedict).to_matrix(),
            np.round(sfc.to_matrix(), decimals=1))
        for k, v in samples.items():
            self.assertIn(k, statedict)
            # It's ok if these are far apart because the dict is sampled.
            self.assertAlmostEqual(v, np.abs(statedict[k])**.5, delta=.5)

        # Follows same code path as above, but testing to be thorough
        sfc_vector = CircuitStateFn.from_vector(StateFn(statedict).to_matrix())
        np.testing.assert_array_almost_equal(
            StateFn(statedict).to_matrix(), sfc_vector.to_matrix())
    def test_compose(self):
        """ compose test """
        target = (X + Z) @ (Y + Z)
        expected = 1j * Z - 1j * Y - 1j * X + I
        self.assertEqual(target, expected)

        observable = (X ^ X) + (Y ^ Y) + (Z ^ Z)
        state = CircuitStateFn((CX @ (X ^ H @ X)).to_circuit())
        self.assertAlmostEqual((~OperatorStateFn(observable) @ state).eval(),
                               -3)
    def test_circuit_sampler2(self, method):
        """Test the probability gradient with the circuit sampler

        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
        """

        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 = CircuitStateFn(primitive=qc, coeff=1.)

        shots = 8000
        if method == 'fin_diff':
            np.random.seed(8)
            prob_grad = Gradient(grad_method=method,
                                 epsilon=shots**(-1 / 6.)).convert(
                                     operator=op, params=params)
        else:
            prob_grad = Gradient(grad_method=method).convert(operator=op,
                                                             params=params)
        values_dict = [{
            a: [np.pi / 4],
            b: [0]
        }, {
            params[0]: [np.pi / 4],
            params[1]: [np.pi / 4]
        }, {
            params[0]: [np.pi / 2],
            params[1]: [np.pi]
        }]
        correct_values = [[[0, 0],
                           [1 / (2 * np.sqrt(2)), -1 / (2 * np.sqrt(2))]],
                          [[1 / 4, -1 / 4], [1 / 4, -1 / 4]],
                          [[0, 0], [-1 / 2, 1 / 2]]]

        backend = BasicAer.get_backend('qasm_simulator')
        q_instance = QuantumInstance(backend=backend, shots=shots)

        for i, value_dict in enumerate(values_dict):
            sampler = CircuitSampler(backend=q_instance).convert(
                prob_grad, params=value_dict)
            result = sampler.eval()
            np.testing.assert_array_almost_equal(result[0],
                                                 correct_values[i],
                                                 decimal=1)
    def test_circuit_sampler(self, method):
        """Test the gradient with circuit sampler

        Tr(|psi><psi|Z) = sin(a)sin(b)
        Tr(|psi><psi|X) = cos(a)
        d<H>/da = - 0.5 sin(a) - 1 cos(a)sin(b)
        d<H>/db = - 1 sin(a)cos(b)
        """

        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.)

        shots = 8000
        if method == 'fin_diff':
            np.random.seed(8)
            state_grad = Gradient(grad_method=method,
                                  epsilon=shots**(-1 / 6.)).convert(
                                      operator=op, params=params)
        else:
            state_grad = Gradient(grad_method=method).convert(operator=op,
                                                              params=params)
        values_dict = [{
            a: np.pi / 4,
            b: np.pi
        }, {
            params[0]: np.pi / 4,
            params[1]: np.pi / 4
        }, {
            params[0]: np.pi / 2,
            params[1]: np.pi / 4
        }]
        correct_values = [[-0.5 / np.sqrt(2), 1 / np.sqrt(2)],
                          [-0.5 / np.sqrt(2) - 0.5, -1 / 2.],
                          [-0.5, -1 / np.sqrt(2)]]

        backend = BasicAer.get_backend('qasm_simulator')
        q_instance = QuantumInstance(backend=backend, shots=shots)

        for i, value_dict in enumerate(values_dict):
            sampler = CircuitSampler(backend=q_instance).convert(
                state_grad, params={k: [v]
                                    for k, v in value_dict.items()})
            np.testing.assert_array_almost_equal(sampler.eval()[0],
                                                 correct_values[i],
                                                 decimal=1)
 def test_sampling(self):
     """ state fn circuit from dict initialize test """
     statedict = {'101': .5, '100': .1, '000': .2, '111': .5}
     sfc = CircuitStateFn.from_dict(statedict)
     circ_samples = sfc.sample()
     dict_samples = StateFn(statedict).sample()
     vec_samples = StateFn(statedict).to_matrix_op().sample()
     for k, v in circ_samples.items():
         self.assertIn(k, dict_samples)
         self.assertIn(k, vec_samples)
         # It's ok if these are far apart because the dict is sampled.
         self.assertAlmostEqual(v, np.abs(dict_samples[k])**.5, delta=.5)
         self.assertAlmostEqual(v, np.abs(vec_samples[k])**.5, delta=.5)
Beispiel #25
0
 def test_circuit_state_fn_from_dict_as_sum(self):
     """state fn circuit from dict as sum test """
     statedict = {'1010101': .5,
                  '1000000': .1,
                  '0000000': .2j,
                  '1111111': 0.5j}
     sfc_sum = CircuitStateFn.from_dict(statedict)
     self.assertIsInstance(sfc_sum, SummedOp)
     for sfc_op in sfc_sum.oplist:
         self.assertIsInstance(sfc_op, CircuitStateFn)
         samples = sfc_op.sample()
         self.assertIn(list(samples.keys())[0], statedict)
         self.assertEqual(sfc_op.coeff, statedict[list(samples.keys())[0]])
     np.testing.assert_array_almost_equal(StateFn(statedict).to_matrix(), sfc_sum.to_matrix())
Beispiel #26
0
    def _eval_aux_ops(self, threshold=1e-12):
        # Create new CircuitSampler to avoid breaking existing one's caches.
        sampler = CircuitSampler(self.quantum_instance)

        aux_op_meas = self.expectation.convert(StateFn(self.aux_operators, is_measurement=True))
        aux_op_expect = aux_op_meas.compose(CircuitStateFn(self.get_optimal_circuit()))
        values = np.real(sampler.convert(aux_op_expect).eval())

        # Discard values below threshold
        aux_op_results = (values * (np.abs(values) > threshold))
        # Deal with the aux_op behavior where there can be Nones or Zero qubit Paulis in the list
        self._ret['aux_ops'] = [None if is_none else [result]
                                for (is_none, result) in zip(self._aux_op_nones, aux_op_results)]
        self._ret['aux_ops'] = np.array([self._ret['aux_ops']])
    def test_state_hessian_custom_combo_fn(self, method):
        """Test the state Hessian with on an operator which includes
            a user-defined combo_fn.

        Tr(|psi><psi|Z) = sin(a)sin(b)
        Tr(|psi><psi|X) = cos(a)
        d^2<H>/da^2 = - 0.5 cos(a) + 1 sin(a)sin(b)
        d^2<H>/dbda = - 1 cos(a)cos(b)
        d^2<H>/dbda = - 1 cos(a)cos(b)
        d^2<H>/db^2 = + 1 sin(a)sin(b)
        """

        ham = 0.5 * X - 1 * Z
        a = Parameter('a')
        b = Parameter('b')
        params = [(a, a), (a, b), (b, b)]

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

        op = ListOp([~StateFn(ham) @ CircuitStateFn(primitive=qc, coeff=1.)],
                    combo_fn=lambda x: x[0]**3 + 4 * x[0])
        state_hess = Hessian(hess_method=method).convert(operator=op,
                                                         params=params)

        values_dict = [{
            a: np.pi / 4,
            b: np.pi
        }, {
            a: np.pi / 4,
            b: np.pi / 4
        }, {
            a: np.pi / 2,
            b: np.pi / 4
        }]

        correct_values = [[-1.28163104, 2.56326208, 1.06066017],
                          [-0.04495626, -2.40716991, 1.8125],
                          [2.82842712, -1.5, 1.76776695]]

        for i, value_dict in enumerate(values_dict):
            np.testing.assert_array_almost_equal(
                state_hess.assign_parameters(value_dict).eval(),
                correct_values[i],
                decimal=1)
Beispiel #28
0
    def _eval_aux_ops(self, threshold=1e-12):
        # Create new CircuitSampler to avoid breaking existing one's caches.
        sampler = CircuitSampler(self.quantum_instance)

        aux_op_meas = self.expectation.convert(StateFn(self.aux_operators, is_measurement=True))
        aux_op_expect = aux_op_meas.compose(CircuitStateFn(self.get_optimal_circuit()))
        values = np.real(sampler.convert(aux_op_expect).eval())

        # Discard values below threshold
        aux_op_results = (values * (np.abs(values) > threshold))
        # Deal with the aux_op behavior where there can be Nones or Zero qubit Paulis in the list
        self._ret['aux_ops'] = [None if is_none else [result]
                                for (is_none, result) in zip(self._aux_op_nones, aux_op_results)]
        # As this has mixed types, since it can included None, it needs to explicitly pass object
        # data type to avoid numpy 1.19 warning message about implicit conversion being deprecated
        self._ret['aux_ops'] = np.array([self._ret['aux_ops']], dtype=object)
Beispiel #29
0
    def construct_expectation(
        self, parameter: Union[List[float], List[Parameter], np.ndarray]
    ) -> OperatorBase:
        r"""
        Generate the ansatz circuit and expectation value measurement, and return their
        runnable composition.

        Args:
            parameter: Parameters for the ansatz circuit.

        Returns:
            The Operator equalling the measurement of the ansatz :class:`StateFn` by the
            Observable's expectation :class:`StateFn`.

        Raises:
            AquaError: If no operator has been provided.
        """
        if self.operator is None:
            raise AquaError("The operator was never provided.")

        # ensure operator and varform are compatible
        self._check_operator_varform()

        if isinstance(self.var_form, QuantumCircuit):
            param_dict = dict(zip(self._var_form_params,
                                  parameter))  # type: Dict
            wave_function = self.var_form.assign_parameters(param_dict)
        else:
            wave_function = self.var_form.construct_circuit(parameter)

        # Expectation was never created, try to create one
        if self._expectation is None:
            self._try_set_expectation_value_from_factory()

        # If setting the expectation failed, raise an Error:
        if self._expectation is None:
            raise AquaError(
                'No expectation set and could not automatically set one, please '
                'try explicitly setting an expectation or specify a backend so it '
                'can be chosen automatically.')

        observable_meas = self.expectation.convert(
            StateFn(self.operator, is_measurement=True))
        ansatz_circuit_op = CircuitStateFn(wave_function)
        return observable_meas.compose(ansatz_circuit_op).reduce()
Beispiel #30
0
    def test_gradient_ryy(self, method):
        # pylint: disable=wrong-spelling-in-comment
        """Test the state gradient for YY rotation
        """
        ham = Y ^ Y
        a = Parameter('a')

        q = QuantumRegister(2)
        qc = QuantumCircuit(q)
        qc.ryy(a, q[0], q[1])

        op = ~StateFn(ham) @ CircuitStateFn(primitive=qc, coeff=1.)
        state_grad = Gradient(grad_method=method).convert(operator=op, params=a)
        values_dict = [{a: np.pi / 8}, {a: np.pi}]
        correct_values = [[0], [0]]
        for i, value_dict in enumerate(values_dict):
            np.testing.assert_array_almost_equal(state_grad.assign_parameters(value_dict).eval(),
                                                 correct_values[i], decimal=1)