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

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

# This code is part of Qiskit.
#
# (C) Copyright IBM 2018, 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.

"""
This module contains the definition of a base class for univariate distributions.
"""

from typing import Optional, Union, List
from abc import ABC
import numpy as np

from qiskit.aqua import AquaError
from qiskit.aqua.utils.validation import validate_min
from qiskit.aqua.components.initial_states import Custom
from .uncertainty_model import UncertaintyModel


[docs]class UnivariateDistribution(UncertaintyModel, ABC): """ This module contains the definition of a base class for univariate distributions. (Interface for discrete bounded uncertainty models assuming an equidistant grid) """ def __init__(self, num_target_qubits: int, probabilities: Optional[Union[List[float], np.ndarray]] = None, low: float = 0, high: float = 1): r""" Args: num_target_qubits: Number of qubits it acts on, has a min. value of 1. probabilities: Probabilities for different states low: Lower bound, i.e., the value corresponding to \|0...0> (assuming an equidistant grid) high: Upper bound, i.e., the value corresponding to \|1...1> (assuming an equidistant grid) Raises: AquaError: num qubits and length of probabilities vector do not match """ validate_min('num_target_qubits', num_target_qubits, 1) super().__init__(num_target_qubits) self._num_values = 2 ** self.num_target_qubits self._probabilities = np.array(probabilities) self._low = low self._high = high self._values = np.linspace(low, high, self.num_values) if probabilities is not None: if self.num_values != len(probabilities): raise AquaError('num qubits and length of probabilities vector do not match!') @property def low(self): """ returns low """ return self._low @property def high(self): """ returns high """ return self._high @property def num_values(self): """ returns number of values """ return self._num_values @property def values(self): """ returns values """ return self._values @property def probabilities(self): """ returns probabilities """ return self._probabilities
[docs] def build(self, qc, q, q_ancillas=None, params=None): """ build """ custom_state = Custom(self.num_target_qubits, state_vector=np.sqrt(self.probabilities)) qc.extend(custom_state.construct_circuit('circuit', q))
[docs] @staticmethod def pdf_to_probabilities(pdf, low, high, num_values): """ Takes a probability density function (pdf), and returns a truncated and discretized array of probabilities corresponding to it Args: pdf (function): probability density function low (float): lower bound of equidistant grid high (float): upper bound of equidistant grid num_values (int): number of grid points Returns: list: array of probabilities """ probabilities = np.zeros(num_values) values = np.linspace(low, high, num_values) total = 0 for i, _ in enumerate(values): probabilities[i] = pdf(values[i]) total += probabilities[i] probabilities /= total return probabilities, values