Ejemplo n.º 1
0
 def setUp(self) -> None:
     super().setUp()
     self.seed = 97
     backend = BasicAer.get_backend('qasm_simulator')
     q_instance = QuantumInstance(backend, seed_simulator=self.seed, seed_transpiler=self.seed)
     self.sampler = CircuitSampler(q_instance, attach_results=True)
     self.expect = PauliExpectation()
    def _set_quantum_instance(
            self, quantum_instance: Optional[Union[QuantumInstance,
                                                   Backend]]) -> None:
        """
        Internal method to set a quantum instance and compute/initialize a sampler.

        Args:
            quantum_instance: A quantum instance to set.

        Returns:
            None.
        """

        if isinstance(quantum_instance, Backend):
            quantum_instance = QuantumInstance(quantum_instance)
        self._quantum_instance = quantum_instance

        if quantum_instance is not None:
            self._circuit_sampler = CircuitSampler(
                self._quantum_instance,
                param_qobj=is_aer_provider(self._quantum_instance.backend),
                caching="all",
            )
        else:
            self._circuit_sampler = None
    def test_parameter_binding_on_listop(self):
        """Test passing a ListOp with differing parameters works with the circuit sampler."""
        try:
            from qiskit.providers.aer import Aer
        except Exception as ex:  # pylint: disable=broad-except
            self.skipTest(
                "Aer doesn't appear to be installed. Error: '{}'".format(
                    str(ex)))
            return
        x, y = Parameter('x'), Parameter('y')

        circuit1 = QuantumCircuit(1)
        circuit1.p(0.2, 0)
        circuit2 = QuantumCircuit(1)
        circuit2.p(x, 0)
        circuit3 = QuantumCircuit(1)
        circuit3.p(y, 0)

        bindings = {x: -0.4, y: 0.4}
        listop = ListOp(
            [StateFn(circuit) for circuit in [circuit1, circuit2, circuit3]])

        sampler = CircuitSampler(Aer.get_backend('qasm_simulator'))
        sampled = sampler.convert(listop, params=bindings)

        self.assertTrue(all(len(op.parameters) == 0 for op in sampled.oplist))
Ejemplo n.º 4
0
    def _eval_aux_ops(
        self,
        parameters: np.ndarray,
        aux_operators: List[OperatorBase],
        expectation: ExpectationBase,
        threshold: float = 1e-12,
    ) -> np.ndarray:
        # Create new CircuitSampler to avoid breaking existing one's caches.
        sampler = CircuitSampler(self.quantum_instance)

        aux_op_meas = expectation.convert(
            StateFn(ListOp(aux_operators), is_measurement=True))
        aux_op_expect = aux_op_meas.compose(
            CircuitStateFn(self.ansatz.bind_parameters(parameters)))
        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
        _aux_op_nones = [op is None for op in aux_operators]
        aux_operator_eigenvalues = [
            None if is_none else [result]
            for (is_none, result) in zip(_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
        aux_operator_eigenvalues = np.array([aux_operator_eigenvalues],
                                            dtype=object)
        return aux_operator_eigenvalues
Ejemplo n.º 5
0
    def test_grouped_pauli_expectation(self):
        """grouped pauli expectation test"""
        two_qubit_H2 = ((-1.052373245772859 * I ^ I) +
                        (0.39793742484318045 * I ^ Z) +
                        (-0.39793742484318045 * Z ^ I) +
                        (-0.01128010425623538 * Z ^ Z) +
                        (0.18093119978423156 * X ^ X))
        wf = CX @ (H ^ I) @ Zero
        expect_op = PauliExpectation(group_paulis=False).convert(
            ~StateFn(two_qubit_H2) @ wf)
        self.sampler._extract_circuitstatefns(expect_op)
        num_circuits_ungrouped = len(self.sampler._circuit_ops_cache)
        self.assertEqual(num_circuits_ungrouped, 5)

        expect_op_grouped = PauliExpectation(group_paulis=True).convert(
            ~StateFn(two_qubit_H2) @ wf)
        q_instance = QuantumInstance(
            BasicAer.get_backend("statevector_simulator"),
            seed_simulator=self.seed,
            seed_transpiler=self.seed,
        )
        sampler = CircuitSampler(q_instance)
        sampler._extract_circuitstatefns(expect_op_grouped)
        num_circuits_grouped = len(sampler._circuit_ops_cache)
        self.assertEqual(num_circuits_grouped, 2)
Ejemplo n.º 6
0
    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()[0]
            self.assertTrue(
                np.allclose(result[0].toarray(),
                            correct_values[i][0],
                            atol=0.1))
            self.assertTrue(
                np.allclose(result[1].toarray(),
                            correct_values[i][1],
                            atol=0.1))
Ejemplo n.º 7
0
    def _eval_op(self, state, op, quantum_instance, expectation):
        # if the operator is empty we simply return 0
        if op == 0:
            # Note, that for some reason the individual results need to be wrapped in lists.
            # See also: VQE._eval_aux_ops()
            return [0.0j]

        exp = ~StateFn(op) @ state  # <state|op|state>

        if quantum_instance is not None:
            try:
                sampler = CircuitSampler(quantum_instance)
                if expectation is not None:
                    exp = expectation.convert(exp)
                result = sampler.convert(exp).eval()
            except ValueError:
                # TODO make this cleaner. The reason for it being here is that some quantum
                # instances can lead to non-positive statevectors which the Qiskit circuit
                # Initializer is unable to handle.
                result = exp.eval()
        else:
            result = exp.eval()

        # Note, that for some reason the individual results need to be wrapped in lists.
        # See also: VQE._eval_aux_ops()
        return [result]
    def test_circuit_sampler_caching(self, caching):
        """Test caching all operators works."""
        try:
            from qiskit.providers.aer import Aer
        except Exception as ex:  # pylint: disable=broad-except
            self.skipTest(
                "Aer doesn't appear to be installed. Error: '{}'".format(
                    str(ex)))
            return

        x = Parameter('x')
        circuit = QuantumCircuit(1)
        circuit.ry(x, 0)
        expr1 = ~StateFn(H) @ StateFn(circuit)
        expr2 = ~StateFn(X) @ StateFn(circuit)

        sampler = CircuitSampler(Aer.get_backend('statevector_simulator'),
                                 caching=caching)

        res1 = sampler.convert(expr1, params={x: 0}).eval()
        res2 = sampler.convert(expr2, params={x: 0}).eval()
        res3 = sampler.convert(expr1, params={x: 0}).eval()
        res4 = sampler.convert(expr2, params={x: 0}).eval()

        self.assertEqual(res1, res3)
        self.assertEqual(res2, res4)
        if caching == 'last':
            self.assertEqual(len(sampler._cached_ops.keys()), 1)
        else:
            self.assertEqual(len(sampler._cached_ops.keys()), 2)
    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.0)

        shots = 8000
        if method == "fin_diff":
            np.random.seed(8)
            state_grad = Gradient(grad_method=method,
                                  epsilon=shots**(-1 /
                                                  6.0)).convert(operator=op)
        else:
            state_grad = Gradient(grad_method=method).convert(operator=op)
        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],
            [-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)
Ejemplo n.º 10
0
    def quantum_instance(self, quantum_instance: Optional[Union[Backend, QuantumInstance]]) -> None:
        """Set the quantum instance and circuit sampler."""
        if quantum_instance is not None:
            if not isinstance(quantum_instance, QuantumInstance):
                quantum_instance = QuantumInstance(quantum_instance)
            self._sampler = CircuitSampler(quantum_instance)

        self._quantum_instance = quantum_instance
Ejemplo n.º 11
0
    def quantum_instance(self, quantum_instance: Union[QuantumInstance,
                                                       BaseBackend, Backend]) -> None:
        """ set quantum_instance """
        super(VQE, self.__class__).quantum_instance.__set__(self, quantum_instance)

        self._circuit_sampler = CircuitSampler(
            self._quantum_instance,
            param_qobj=is_aer_provider(self._quantum_instance.backend))
Ejemplo n.º 12
0
 def quantum_instance(
     self, quantum_instance: Union[QuantumInstance, BaseBackend,
                                   Backend]) -> None:
     """set quantum_instance"""
     if not isinstance(quantum_instance, QuantumInstance):
         quantum_instance = QuantumInstance(quantum_instance)
     self._quantum_instance = quantum_instance
     self._circuit_sampler = CircuitSampler(quantum_instance,
                                            param_qobj=is_aer_provider(
                                                quantum_instance.backend))
Ejemplo n.º 13
0
    def test_quantum_instance_with_backend_shots(self):
        """Test sampling a circuit where the backend has shots attached."""
        try:
            from qiskit.providers.aer import AerSimulator
        except Exception as ex:  # pylint: disable=broad-except
            self.skipTest("Aer doesn't appear to be installed. Error: '{}'".format(str(ex)))

        backend = AerSimulator(shots=10)
        sampler = CircuitSampler(backend)
        res = sampler.convert(~Plus @ Plus).eval()
        self.assertAlmostEqual(res, 1 + 0j, places=2)
Ejemplo n.º 14
0
    def quantum_instance(self, quantum_instance: Union[QuantumInstance,
                                                       BaseBackend, Backend]) -> None:
        """ set quantum_instance """
        super(VQE, self.__class__).quantum_instance.__set__(self, quantum_instance)

        self._circuit_sampler = CircuitSampler(
            self._quantum_instance,
            param_qobj=is_aer_provider(self._quantum_instance.backend))

        # Expectation was not passed by user, try to create one
        if not self._user_valid_expectation:
            self._try_set_expectation_value_from_factory()
Ejemplo n.º 15
0
    def _eval_aux_ops(
        self,
        parameters: np.ndarray,
        aux_operators: ListOrDict[OperatorBase],
        expectation: ExpectationBase,
        threshold: float = 1e-12,
    ) -> ListOrDict[Tuple[complex, complex]]:
        # Create new CircuitSampler to avoid breaking existing one's caches.
        sampler = CircuitSampler(self.quantum_instance)

        if isinstance(aux_operators, dict):
            list_op = ListOp(list(aux_operators.values()))
        else:
            list_op = ListOp(aux_operators)

        aux_op_meas = expectation.convert(StateFn(list_op,
                                                  is_measurement=True))
        aux_op_expect = aux_op_meas.compose(
            CircuitStateFn(self.ansatz.bind_parameters(parameters)))
        aux_op_expect_sampled = sampler.convert(aux_op_expect)

        # compute means
        values = np.real(aux_op_expect_sampled.eval())

        # compute standard deviations
        variances = np.real(
            expectation.compute_variance(aux_op_expect_sampled))
        if not isinstance(variances, np.ndarray) and variances == 0.0:
            # when `variances` is a single value equal to 0., our expectation value is exact and we
            # manually ensure the variances to be a list of the correct length
            variances = np.zeros(len(aux_operators), dtype=float)
        std_devs = np.sqrt(variances / self.quantum_instance.run_config.shots)

        # Discard values below threshold
        aux_op_means = values * (np.abs(values) > threshold)
        # zip means and standard deviations into tuples
        aux_op_results = zip(aux_op_means, std_devs)

        # Return None eigenvalues for None operators if aux_operators is a list.
        # None operators are already dropped in compute_minimum_eigenvalue if aux_operators is a dict.
        if isinstance(aux_operators, list):
            aux_operator_eigenvalues = [None] * len(aux_operators)
            key_value_iterator = enumerate(aux_op_results)
        else:
            aux_operator_eigenvalues = {}
            key_value_iterator = zip(aux_operators.keys(), aux_op_results)

        for key, value in key_value_iterator:
            if aux_operators[key] is not None:
                aux_operator_eigenvalues[key] = value

        return aux_operator_eigenvalues
    def __init__(self,
                 operator: OperatorBase,
                 input_params: Optional[List[Parameter]] = None,
                 weight_params: Optional[List[Parameter]] = None,
                 exp_val: Optional[ExpectationBase] = None,
                 gradient: Optional[Gradient] = None,
                 quantum_instance: Optional[Union[QuantumInstance, BaseBackend,
                                                  Backend]] = None):
        """Initializes the Opflow Quantum Neural Network.

        Args:
            operator: The parametrized operator that represents the neural network.
            input_params: The operator parameters that correspond to the input of the network.
            weight_params: The operator parameters that correspond to the trainable weights.
            exp_val: The Expected Value converter to be used for the operator.
            gradient: The Gradient converter to be used for the operator's backward pass.
            quantum_instance: The quantum instance to evaluate the network.
        """
        self._input_params = list(input_params) or []
        self._weight_params = list(weight_params) or []

        if isinstance(quantum_instance, (BaseBackend, Backend)):
            quantum_instance = QuantumInstance(quantum_instance)

        if quantum_instance:
            self._quantum_instance = quantum_instance
            self._circuit_sampler = CircuitSampler(
                self._quantum_instance,
                param_qobj=is_aer_provider(self._quantum_instance.backend),
                caching="all")
        else:
            self._quantum_instance = None
            self._circuit_sampler = None

        self._operator = operator
        self._forward_operator = exp_val.convert(
            operator) if exp_val else operator
        self._gradient_operator: OperatorBase = None
        try:
            gradient = gradient or Gradient()
            self._gradient_operator = gradient.convert(
                operator, self._input_params + self._weight_params)
        except (ValueError, TypeError, OpflowError, QiskitError):
            logger.warning(
                'Cannot compute gradient operator! Continuing without gradients!'
            )

        output_shape = self._get_output_shape_from_op(operator)
        super().__init__(len(self._input_params),
                         len(self._weight_params),
                         sparse=False,
                         output_shape=output_shape)
Ejemplo n.º 17
0
    def quantum_instance(
        self, quantum_instance: Optional[Union[QuantumInstance, BaseBackend, Backend]]
    ) -> None:
        """Set quantum instance.

        Args:
            quantum_instance: The quantum instance used to run this algorithm.
                If None, a Statevector calculation is done.
        """
        if quantum_instance is not None:
            self._sampler = CircuitSampler(quantum_instance)
        else:
            self._sampler = None
Ejemplo n.º 18
0
    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=10000
        )
        qubit_op = (0.1 * I ^ I) + (0.2 * I ^ Z) + (0.3 * Z ^ I) + (0.4 * Z ^ Z) + (0.5 * X ^ X)
        ansatz = RealAmplitudes(qubit_op.num_qubits)
        ansatz_circuit_op = CircuitStateFn(ansatz)
        observable = PauliExpectation().convert(~StateFn(qubit_op))
        expect_op = observable.compose(ansatz_circuit_op).reduce()
        params1 = {}
        params2 = {}
        for param in ansatz.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)
Ejemplo n.º 19
0
    def test_ibmq_grouped_pauli_expectation(self):
        """pauli expect op vector state vector test"""
        from qiskit import IBMQ

        p = IBMQ.load_account()
        backend = p.get_backend("ibmq_qasm_simulator")
        q_instance = QuantumInstance(backend, seed_simulator=self.seed, seed_transpiler=self.seed)

        paulis_op = ListOp([X, Y, Z, I])
        states_op = ListOp([One, Zero, Plus, Minus])

        valids = [[+0, 0, 1, -1], [+0, 0, 0, 0], [-1, 1, 0, -0], [+1, 1, 1, 1]]
        converted_meas = self.expect.convert(~StateFn(paulis_op) @ states_op)
        sampled = CircuitSampler(q_instance).convert(converted_meas)
        np.testing.assert_array_almost_equal(sampled.eval(), valids, decimal=1)
Ejemplo n.º 20
0
    def setUp(self) -> None:
        super().setUp()
        try:
            from qiskit import Aer

            self.seed = 97
            self.backend = Aer.get_backend("aer_simulator")
            q_instance = QuantumInstance(
                self.backend, seed_simulator=self.seed, seed_transpiler=self.seed
            )
            self.sampler = CircuitSampler(q_instance, attach_results=True)
            self.expect = AerPauliExpectation()
        except Exception as ex:  # pylint: disable=broad-except
            self.skipTest("Aer doesn't appear to be installed. Error: '{}'".format(str(ex)))
            return
Ejemplo n.º 21
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(ListOp(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)
Ejemplo n.º 22
0
    def _set_quantum_instance(
        self,
        quantum_instance: Optional[Union[QuantumInstance, Backend]],
        output_shape: Union[int, Tuple[int, ...]],
        interpret: Optional[Callable[[int], Union[int, Tuple[int, ...]]]],
    ) -> None:
        """
        Internal method to set a quantum instance and compute/initialize internal properties such
        as an interpret function, output shape and a sampler.

        Args:
            quantum_instance: A quantum instance to set.
            output_shape: An output shape of the custom interpretation.
            interpret: A callable that maps the measured integer to another unsigned integer or
                tuple of unsigned integers.
        """
        if isinstance(quantum_instance, Backend):
            quantum_instance = QuantumInstance(quantum_instance)
        self._quantum_instance = quantum_instance

        if self._quantum_instance is not None:
            # add measurements in case none are given
            if self._quantum_instance.is_statevector:
                if len(self._circuit.clbits) > 0:
                    self._circuit.remove_final_measurements()
            elif len(self._circuit.clbits) == 0:
                self._circuit.measure_all()

            # set interpret and compute output shape
            self.set_interpret(interpret, output_shape)

            # prepare sampler
            self._sampler = CircuitSampler(self._quantum_instance, param_qobj=False, caching="all")

            # transpile the QNN circuit
            try:
                self._circuit = self._quantum_instance.transpile(
                    self._circuit, pass_manager=self._quantum_instance.unbound_pass_manager
                )[0]
                self._circuit_transpiled = True
            except QiskitError:
                # likely it is caused by RawFeatureVector, we just ignore this error and
                # transpile circuits when it is required.
                self._circuit_transpiled = False
        else:
            self._output_shape = output_shape
Ejemplo n.º 23
0
    def test_single_parameter_binds(self):
        """Test passing parameter binds as a dictionary to the circuit sampler."""
        try:
            from qiskit.providers.aer import Aer
        except Exception as ex:  # pylint: disable=broad-except
            self.skipTest("Aer doesn't appear to be installed. Error: '{}'".format(str(ex)))
            return

        x = Parameter("x")
        circuit = QuantumCircuit(1)
        circuit.ry(x, 0)
        expr = ~StateFn(H) @ StateFn(circuit)

        sampler = CircuitSampler(Aer.get_backend("aer_simulator_statevector"))

        res = sampler.convert(expr, params={x: 0}).eval()

        self.assertIsInstance(res, complex)
Ejemplo n.º 24
0
    def get_fidelity(
        circuit: QuantumCircuit,
        backend: Optional[Union[Backend, QuantumInstance]] = None,
        expectation: Optional[ExpectationBase] = None,
    ) -> Callable[[np.ndarray, np.ndarray], float]:
        r"""Get a function to compute the fidelity of ``circuit`` with itself.

        Let ``circuit`` be a parameterized quantum circuit performing the operation
        :math:`U(\theta)` given a set of parameters :math:`\theta`. Then this method returns
        a function to evaluate

        .. math::

            F(\theta, \phi) = \big|\langle 0 | U^\dagger(\theta) U(\phi) |0\rangle  \big|^2.

        The output of this function can be used as input for the ``fidelity`` to the
        :class:~`qiskit.algorithms.optimizers.QNSPSA` optimizer.

        Args:
            circuit: The circuit preparing the parameterized ansatz.
            backend: A backend of quantum instance to evaluate the circuits. If None, plain
                matrix multiplication will be used.
            expectation: An expectation converter to specify how the expected value is computed.
                If a shot-based readout is used this should be set to ``PauliExpectation``.

        Returns:
            A handle to the function :math:`F`.

        """
        params_x = ParameterVector("x", circuit.num_parameters)
        params_y = ParameterVector("y", circuit.num_parameters)

        expression = ~StateFn(circuit.assign_parameters(params_x)) @ StateFn(
            circuit.assign_parameters(params_y))

        if expectation is not None:
            expression = expectation.convert(expression)

        if backend is None:

            def fidelity(values_x, values_y):
                value_dict = dict(
                    zip(params_x[:] + params_y[:],
                        values_x.tolist() + values_y.tolist()))
                return np.abs(expression.bind_parameters(value_dict).eval())**2

        else:
            sampler = CircuitSampler(backend)

            def fidelity(values_x, values_y):
                value_dict = dict(
                    zip(params_x[:] + params_y[:],
                        values_x.tolist() + values_y.tolist()))
                return np.abs(
                    sampler.convert(expression, params=value_dict).eval())**2

        return fidelity
Ejemplo n.º 25
0
    def __init__(self, operator: OperatorBase,
                 input_params: Optional[List[Parameter]] = None,
                 weight_params: Optional[List[Parameter]] = None,
                 exp_val: Optional[ExpectationBase] = None,
                 gradient: Optional[Gradient] = None,
                 quantum_instance: Optional[Union[QuantumInstance, BaseBackend, Backend]] = None):
        """Initializes the Opflow Quantum Neural Network.

        Args:
            operator: The parametrized operator that represents the neural network.
            input_params: The operator parameters that correspond to the input of the network.
            weight_params: The operator parameters that correspond to the trainable weights.
            exp_val: The Expected Value converter to be used for the operator.
            gradient: The Gradient converter to be used for the operator's backward pass.
            quantum_instance: The quantum instance to evaluate the network.
        """
        self.operator = operator
        self.input_params = list(input_params or [])
        self.weight_params = list(weight_params or [])
        self.exp_val = exp_val  # TODO: currently not used by Gradient!
        self.gradient = gradient or Gradient()

        if isinstance(quantum_instance, (BaseBackend, Backend)):
            quantum_instance = QuantumInstance(quantum_instance)

        if quantum_instance:
            self.quantum_instance = quantum_instance
            self.circuit_sampler = CircuitSampler(
                self.quantum_instance,
                param_qobj=is_aer_provider(self.quantum_instance.backend)
            )
            # TODO: replace by extended caching in circuit sampler after merged: "caching='all'"
            self.gradient_sampler = deepcopy(self.circuit_sampler)
        else:
            self.quantum_instance = None
            self.circuit_sampler = None
            self.gradient_sampler = None

        self.forward_operator = self.exp_val.convert(operator) if exp_val else operator
        self.gradient_operator = self.gradient.convert(operator,
                                                       self.input_params + self.weight_params)
        output_shape = self._get_output_shape_from_op(operator)
        super().__init__(len(self.input_params), len(self.weight_params),
                         sparse=False, output_shape=output_shape)
Ejemplo n.º 26
0
 def test_is_measurement_correctly_propagated(self):
     """Test if is_measurement property of StateFn is propagated to converted StateFn."""
     try:
         from qiskit.providers.aer import Aer
     except Exception as ex:  # pylint: disable=broad-except
         self.skipTest("Aer doesn't appear to be installed. Error: '{}'".format(str(ex)))
         return
     backend = Aer.get_backend("aer_simulator")
     q_instance = QuantumInstance(backend)  # no seeds needed since no values are compared
     state = Plus
     sampler = CircuitSampler(q_instance).convert(~state @ state)
     self.assertTrue(sampler.oplist[0].is_measurement)
    def test_coefficients_correctly_propagated(self):
        """Test that the coefficients in SummedOp and states are correctly used."""
        try:
            from qiskit.providers.aer import Aer
        except Exception as ex:  # pylint: disable=broad-except
            self.skipTest(
                "Aer doesn't appear to be installed. Error: '{}'".format(
                    str(ex)))
            return
        with self.subTest('zero coeff in SummedOp'):
            op = 0 * (I + Z)
            state = Plus
            self.assertEqual((~StateFn(op) @ state).eval(), 0j)

        backend = Aer.get_backend('qasm_simulator')
        q_instance = QuantumInstance(backend,
                                     seed_simulator=97,
                                     seed_transpiler=97)
        op = I
        with self.subTest('zero coeff in summed StateFn and CircuitSampler'):
            state = 0 * (Plus + Minus)
            sampler = CircuitSampler(q_instance).convert(~StateFn(op) @ state)
            self.assertEqual(sampler.eval(), 0j)

        with self.subTest(
                'coeff gets squared in CircuitSampler shot-based readout'):
            state = (Plus + Minus) / numpy.sqrt(2)
            sampler = CircuitSampler(q_instance).convert(~StateFn(op) @ state)
            self.assertAlmostEqual(sampler.eval(), 1 + 0j)
Ejemplo n.º 28
0
    def __init__(
        self,
        epsilon: float = 1e-2,
        expectation: Optional[ExpectationBase] = None,
        quantum_instance: Optional[Union[Backend, BaseBackend,
                                         QuantumInstance]] = None,
    ) -> None:
        r"""
        Args:
            epsilon: Error tolerance of the approximation to the solution, i.e. if :math:`x` is the
                exact solution and :math:`\tilde{x}` the one calculated by the algorithm, then
                :math:`||x - \tilde{x}|| \le epsilon`.
            expectation: The expectation converter applied to the expectation values before
                evaluation. If None then PauliExpectation is used.
            quantum_instance: Quantum Instance or Backend. If None, a Statevector calculation is
                done.
        """
        super().__init__()

        self._epsilon = epsilon
        # Tolerance for the different parts of the algorithm as per [1]
        self._epsilon_r = epsilon / 3  # conditioned rotation
        self._epsilon_s = epsilon / 3  # state preparation
        self._epsilon_a = epsilon / 6  # hamiltonian simulation

        self._scaling = None  # scaling of the solution

        if quantum_instance is not None:
            self._sampler = CircuitSampler(quantum_instance)
        else:
            self._sampler = None

        self._expectation = expectation

        # For now the default reciprocal implementation is exact
        self._exact_reciprocal = True
        # Set the default scaling to 1
        self.scaling = 1
Ejemplo n.º 29
0
    def _eval_aux_ops(
        self,
        parameters: np.ndarray,
        aux_operators: ListOrDict[OperatorBase],
        expectation: ExpectationBase,
        threshold: float = 1e-12,
    ) -> ListOrDict[complex]:
        # Create new CircuitSampler to avoid breaking existing one's caches.
        sampler = CircuitSampler(self.quantum_instance)

        if isinstance(aux_operators, dict):
            list_op = ListOp(list(aux_operators.values()))
        else:
            list_op = ListOp(aux_operators)

        aux_op_meas = expectation.convert(StateFn(list_op,
                                                  is_measurement=True))
        aux_op_expect = aux_op_meas.compose(
            CircuitStateFn(self.ansatz.bind_parameters(parameters)))
        values = np.real(sampler.convert(aux_op_expect).eval())

        # Discard values below threshold
        aux_op_results = values * (np.abs(values) > threshold)

        # Return None eigenvalues for None operators if aux_operators is a list.
        # None operators are already dropped in compute_minimum_eigenvalue if aux_operators is a dict.
        if isinstance(aux_operators, list):
            aux_operator_eigenvalues = [None] * len(aux_operators)
            key_value_iterator = enumerate(aux_op_results)
        else:
            aux_operator_eigenvalues = {}
            key_value_iterator = zip(aux_operators.keys(), aux_op_results)

        for key, value in key_value_iterator:
            if aux_operators[key] is not None:
                aux_operator_eigenvalues[key] = value

        return aux_operator_eigenvalues
Ejemplo n.º 30
0
    def quantum_instance(
            self, quantum_instance: Optional[Union[QuantumInstance,
                                                   Backend]]) -> None:
        """
        Sets a quantum instance and a circuit sampler.
        Args:
            quantum_instance: The quantum instance used to run this algorithm.
        """
        if isinstance(quantum_instance, Backend):
            quantum_instance = QuantumInstance(quantum_instance)

        self._circuit_sampler = None
        if quantum_instance is not None:
            self._circuit_sampler = CircuitSampler(quantum_instance)

        self._quantum_instance = quantum_instance