Source code for qiskit.aqua.components.uncertainty_models.multivariate_variational_distribution

# -*- coding: utf-8 -*-

# This code is part of Qiskit.
#
# (C) Copyright IBM 2019, 2020.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

"""The Multivariate Variational Distribution."""

import warnings
from typing import Optional, List, Union
import numpy as np

from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit
from qiskit.aqua.components.variational_forms import VariationalForm
from .multivariate_distribution import MultivariateDistribution

# pylint: disable=invalid-name


[docs]class MultivariateVariationalDistribution(MultivariateDistribution): """The Multivariate Variational Distribution.""" def __init__(self, num_qubits: Union[List[int], np.ndarray], var_form: Union[QuantumCircuit, VariationalForm], params: Union[List[float], np.ndarray], low: Optional[Union[List[float], np.ndarray]] = None, high: Optional[Union[List[float], np.ndarray]] = None) -> None: """ Args: num_qubits: List with the number of qubits per dimension var_form: Variational form params: Parameters for variational form low: List with the lower bounds per dimension, set to 0 for each dimension if None high: List with the upper bounds per dimension, set to 1 for each dimension if None """ if low is None: low = np.zeros(len(num_qubits)) if high is None: high = np.ones(len(num_qubits)) self._num_qubits = num_qubits self._var_form = var_form # fix the order of the parameters in the circuit if isinstance(self._var_form, QuantumCircuit): self._var_form_params = sorted(self._var_form.parameters, key=lambda p: p.name) else: warnings.warn('The VariationalForm type is deprecated as argument of the ' 'MultivariateVariationalDistribution as of 0.7.0 and will be removed no ' 'earlier than 3 months after the release. You should pass an object ' 'of type QuantumCircuit instead (see qiskit.circuit.library for a ' 'collection of suitable objects).', DeprecationWarning, stacklevel=2) self.params = params probabilities = np.zeros(2 ** sum(num_qubits)) super().__init__(num_qubits, probabilities, low, high) self._var_form = var_form self.params = params
[docs] def build(self, qc, q, q_ancillas=None, params=None): if isinstance(self._var_form, QuantumCircuit): param_dict = dict(zip(self._var_form_params, self.params)) circuit_var_form = self._var_form.assign_parameters(param_dict) else: circuit_var_form = self._var_form.construct_circuit(self.params) qc.append(circuit_var_form.to_instruction(), q)
[docs] def set_probabilities(self, quantum_instance): """Set Probabilities Args: quantum_instance (QuantumInstance): Quantum Instance """ q_ = QuantumRegister(self._num_qubits, name='q') qc_ = QuantumCircuit(q_) if isinstance(self._var_form, QuantumCircuit): param_dict = dict(zip(self._var_form_params, self.params)) circuit_var_form = self._var_form.assign_parameters(param_dict) else: circuit_var_form = self._var_form.construct_circuit(self.params) qc_.append(circuit_var_form.to_instruction(), qc_.qubits) if quantum_instance.is_statevector: pass else: c_ = ClassicalRegister(self._num_qubits, name='c') qc_.add_register(c_) qc_.measure(q_, c_) result = quantum_instance.execute(qc_) if quantum_instance.is_statevector: result = result.get_statevector(qc_) values = np.multiply(result, np.conj(result)) values = list(values.real) else: result = result.get_counts(qc_) keys = list(result) values = list(result.values()) values = [float(v) / np.sum(values) for v in values] values = [x for _, x in sorted(zip(keys, values))] probabilities = values self._probabilities = np.array(probabilities)