From e534feda3d0a2ba40a6907ca3d09b724801382e3 Mon Sep 17 00:00:00 2001 From: CZ Date: Wed, 14 Aug 2019 11:06:03 +0200 Subject: [PATCH 01/11] bug fix multivariate variational distribution Changes in Multivariate Distribution induced an error --- .../multivariate_variational_distribution.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/qiskit/aqua/components/uncertainty_models/multivariate_variational_distribution.py b/qiskit/aqua/components/uncertainty_models/multivariate_variational_distribution.py index faed2d422c..9e206f9bd6 100644 --- a/qiskit/aqua/components/uncertainty_models/multivariate_variational_distribution.py +++ b/qiskit/aqua/components/uncertainty_models/multivariate_variational_distribution.py @@ -80,8 +80,7 @@ def __init__(self, num_qubits, var_form, params, low=None, high=None): self._num_qubits = num_qubits self._var_form = var_form self.params = params - probabilities = np.zeros(2 ** sum(num_qubits)) - super().__init__(num_qubits, probabilities, low, high) + super().__init__(num_qubits, low, high) self._var_form = var_form self.params = params From a2c0d977f809e943d7cad3d3047c6b067e80a194 Mon Sep 17 00:00:00 2001 From: CZ Date: Wed, 14 Aug 2019 13:50:36 +0200 Subject: [PATCH 02/11] Update qgan.py --- qiskit/aqua/algorithms/adaptive/qgan/qgan.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/aqua/algorithms/adaptive/qgan/qgan.py b/qiskit/aqua/algorithms/adaptive/qgan/qgan.py index 423816b850..1238eb4cd9 100644 --- a/qiskit/aqua/algorithms/adaptive/qgan/qgan.py +++ b/qiskit/aqua/algorithms/adaptive/qgan/qgan.py @@ -349,7 +349,7 @@ def get_rel_entr(self): temp = np.zeros(len(self._grid_elements)) for j, sample in enumerate(samples_gen): for i, element in enumerate(self._grid_elements): - if all(sample == element): + if sample == element: temp[i] += prob_gen[j] prob_gen = temp prob_gen = [1e-8 if x == 0 else x for x in prob_gen] From 8b65cfd818f7e5908896c86ca3c1e8d8e79de5cc Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Fri, 23 Aug 2019 10:24:56 -0400 Subject: [PATCH 03/11] Remove jsonschema cap We have had the jsonschema version capped since it was capped in terra. However there was no clear reason for this in terra and it limits interoperability with other python packages. Especially because jsonschema is commonly used library across the python ecosystem. The version we were capping to was also quite old being release 2.5 years ago. This commit removes the cap so that people can run aqua in environments where newer jsonschema is required. --- requirements.txt | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 95d7489090..fd30521af0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,7 @@ scipy>=1.0 sympy>=1.3 numpy>=1.13 psutil>=5 -jsonschema>=2.6,<2.7 +jsonschema>=2.6 scikit-learn>=0.20.0 cvxopt dlx diff --git a/setup.py b/setup.py index 05581f69fe..6305acfc5b 100644 --- a/setup.py +++ b/setup.py @@ -31,7 +31,7 @@ "sympy>=1.3", "numpy>=1.13", "psutil>=5", - "jsonschema>=2.6,<2.7", + "jsonschema>=2.6", "scikit-learn>=0.20.0", "cvxopt", "dlx", From a60a152a469d82aec683aea8f868facc160b2010 Mon Sep 17 00:00:00 2001 From: CZ Date: Thu, 5 Dec 2019 10:12:58 +0100 Subject: [PATCH 04/11] fix constructor Multivaritate Distributions --- .../uncertainty_models/multivariate_distribution.py | 2 +- .../multivariate_log_normal_distribution.py | 2 +- .../uncertainty_models/multivariate_normal_distribution.py | 2 +- .../multivariate_uniform_distribution.py | 2 +- .../multivariate_variational_distribution.py | 2 +- .../uncertainty_models/univariate_distribution.py | 7 ++++--- .../univariate_variational_distribution.py | 3 +-- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/qiskit/aqua/components/uncertainty_models/multivariate_distribution.py b/qiskit/aqua/components/uncertainty_models/multivariate_distribution.py index 3c82427da4..f691b4b797 100644 --- a/qiskit/aqua/components/uncertainty_models/multivariate_distribution.py +++ b/qiskit/aqua/components/uncertainty_models/multivariate_distribution.py @@ -34,7 +34,7 @@ class MultivariateDistribution(UncertaintyModel, ABC): def get_section_key_name(cls): return Pluggable.SECTION_KEY_MULTIVARIATE_DIST - def __init__(self, num_qubits, low, high, probabilities=None): + def __init__(self, num_qubits, probabilities=None, low=[], high=[]): """ Constructor. diff --git a/qiskit/aqua/components/uncertainty_models/multivariate_log_normal_distribution.py b/qiskit/aqua/components/uncertainty_models/multivariate_log_normal_distribution.py index 4770984166..d49d5e89b1 100644 --- a/qiskit/aqua/components/uncertainty_models/multivariate_log_normal_distribution.py +++ b/qiskit/aqua/components/uncertainty_models/multivariate_log_normal_distribution.py @@ -101,7 +101,7 @@ def __init__(self, num_qubits, low=None, high=None, mu=None, cov=None): self.cov = cov probs, values = self._compute_probabilities([], [], num_qubits, low, high) probs = np.asarray(probs) / np.sum(probs) - super().__init__(num_qubits, low, high, probs) + super().__init__(num_qubits, probs, low, high) self._values = values def _compute_probabilities(self, probs, values, num_qubits, low, high, x=None): diff --git a/qiskit/aqua/components/uncertainty_models/multivariate_normal_distribution.py b/qiskit/aqua/components/uncertainty_models/multivariate_normal_distribution.py index f938558f25..b2a976549e 100644 --- a/qiskit/aqua/components/uncertainty_models/multivariate_normal_distribution.py +++ b/qiskit/aqua/components/uncertainty_models/multivariate_normal_distribution.py @@ -107,7 +107,7 @@ def __init__(self, num_qubits, low=None, high=None, mu=None, sigma=None): self.sigma = sigma probs = self._compute_probabilities([], num_qubits, low, high) probs = np.asarray(probs) / np.sum(probs) - super().__init__(num_qubits, low, high, probs) + super().__init__(num_qubits, probs, low, high) def _compute_probabilities(self, probs, num_qubits, low, high, x=None): diff --git a/qiskit/aqua/components/uncertainty_models/multivariate_uniform_distribution.py b/qiskit/aqua/components/uncertainty_models/multivariate_uniform_distribution.py index d3fa921e57..4024c1d77e 100644 --- a/qiskit/aqua/components/uncertainty_models/multivariate_uniform_distribution.py +++ b/qiskit/aqua/components/uncertainty_models/multivariate_uniform_distribution.py @@ -79,7 +79,7 @@ def __init__(self, num_qubits, low=None, high=None): num_values = np.prod([2**n for n in num_qubits]) probabilities = np.ones(num_values) - super().__init__(num_qubits, low, high, probabilities) + super().__init__(num_qubits, probabilities, low, high) def build(self, qc, q, q_ancillas=None, params=None): if params is None or params['i_state'] is None: diff --git a/qiskit/aqua/components/uncertainty_models/multivariate_variational_distribution.py b/qiskit/aqua/components/uncertainty_models/multivariate_variational_distribution.py index 7b4aa2ff43..71c6a7cdc7 100644 --- a/qiskit/aqua/components/uncertainty_models/multivariate_variational_distribution.py +++ b/qiskit/aqua/components/uncertainty_models/multivariate_variational_distribution.py @@ -84,7 +84,7 @@ def __init__(self, num_qubits, var_form, params, low=None, high=None): self._num_qubits = num_qubits self._var_form = var_form self.params = params - super().__init__(num_qubits, low, high) + super().__init__(num_qubits, low=low, high=high) self._var_form = var_form self.params = params diff --git a/qiskit/aqua/components/uncertainty_models/univariate_distribution.py b/qiskit/aqua/components/uncertainty_models/univariate_distribution.py index 3c3392af08..bf024e66e9 100644 --- a/qiskit/aqua/components/uncertainty_models/univariate_distribution.py +++ b/qiskit/aqua/components/uncertainty_models/univariate_distribution.py @@ -34,7 +34,7 @@ class UnivariateDistribution(UncertaintyModel, ABC): def get_section_key_name(cls): return Pluggable.SECTION_KEY_UNIVARIATE_DIST - def __init__(self, num_target_qubits, probabilities, low=0, high=1): + def __init__(self, num_target_qubits, probabilities=None, low=0, high=1): """ Abstract univariate distribution class Args: @@ -53,8 +53,9 @@ def __init__(self, num_target_qubits, probabilities, low=0, high=1): self._low = low self._high = high self._values = np.linspace(low, high, self.num_values) - if self.num_values != len(probabilities): - raise AquaError('num qubits and length of probabilities vector do not match!') + 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): diff --git a/qiskit/aqua/components/uncertainty_models/univariate_variational_distribution.py b/qiskit/aqua/components/uncertainty_models/univariate_variational_distribution.py index ba85b6df6c..730475d877 100644 --- a/qiskit/aqua/components/uncertainty_models/univariate_variational_distribution.py +++ b/qiskit/aqua/components/uncertainty_models/univariate_variational_distribution.py @@ -71,8 +71,7 @@ def __init__(self, num_qubits, var_form, params, low=0, high=1): self._num_qubits = num_qubits self._var_form = var_form self.params = params - probabilities = list(np.zeros(2**num_qubits)) - super().__init__(num_qubits, probabilities, low, high) + super().__init__(num_qubits, low=low, high=high) @classmethod def init_params(cls, params): From 9186dbc6f6b327fb0fc878922f5f3f57b5e329cf Mon Sep 17 00:00:00 2001 From: CZ Date: Thu, 5 Dec 2019 10:59:55 +0100 Subject: [PATCH 05/11] fix lint --- .../components/uncertainty_models/multivariate_distribution.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/aqua/components/uncertainty_models/multivariate_distribution.py b/qiskit/aqua/components/uncertainty_models/multivariate_distribution.py index f691b4b797..1f215c0bb6 100644 --- a/qiskit/aqua/components/uncertainty_models/multivariate_distribution.py +++ b/qiskit/aqua/components/uncertainty_models/multivariate_distribution.py @@ -34,7 +34,7 @@ class MultivariateDistribution(UncertaintyModel, ABC): def get_section_key_name(cls): return Pluggable.SECTION_KEY_MULTIVARIATE_DIST - def __init__(self, num_qubits, probabilities=None, low=[], high=[]): + def __init__(self, num_qubits, probabilities=None, low=None, high=None): """ Constructor. From a2dc215a0c5d5ecc12598213116428a8aa09a0d9 Mon Sep 17 00:00:00 2001 From: CZ Date: Thu, 5 Dec 2019 16:27:49 +0100 Subject: [PATCH 06/11] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a185504ece..535cf3c107 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,6 +47,7 @@ Added Fixed ------- +- fix parameter ordering in the init of the multivariate distribution class (#741) - fix bug in list concatenation in VQC algorithm (#733) - A bug where `UCCSD` might generate an empty operator and try to evolve it. (#680) - Decompose causes DAG failure using feature maps. (#719) From e4076ffe8eb2db29e9b9f8477d3c6192dad1b01e Mon Sep 17 00:00:00 2001 From: CZ Date: Fri, 6 Dec 2019 15:23:48 +0100 Subject: [PATCH 07/11] outsource data preparation from qgans into utils/dataset_helper.py --- qiskit/aqua/algorithms/adaptive/qgan/qgan.py | 75 +----------- qiskit/aqua/components/optimizers/aqgd.py | 8 -- .../multivariate_variational_distribution.py | 3 +- .../univariate_variational_distribution.py | 8 +- qiskit/aqua/utils/dataset_helper.py | 114 +++++++++++++++++- 5 files changed, 127 insertions(+), 81 deletions(-) diff --git a/qiskit/aqua/algorithms/adaptive/qgan/qgan.py b/qiskit/aqua/algorithms/adaptive/qgan/qgan.py index ddb22923d7..454df42fd9 100644 --- a/qiskit/aqua/algorithms/adaptive/qgan/qgan.py +++ b/qiskit/aqua/algorithms/adaptive/qgan/qgan.py @@ -29,6 +29,7 @@ from qiskit.aqua.algorithms import QuantumAlgorithm from qiskit.aqua.components.neural_networks.quantum_generator import QuantumGenerator from qiskit.aqua.components.neural_networks.numpy_discriminator import NumpyDiscriminator +from qiskit.aqua.utils.dataset_helper import discretize_and_truncate logger = logging.getLogger(__name__) @@ -145,15 +146,13 @@ def __init__(self, data, bounds=None, num_qubits=None, batch_size=500, num_epoch if np.ndim(data) > 1: if self._num_qubits is None: self._num_qubits = np.ones[len(data[0])]*3 - self._prob_data = \ - np.zeros(int(np.prod(np.power(np.ones(len(self._data[0]))*2, self._num_qubits)))) else: if self._num_qubits is None: self._num_qubits = np.array([3]) - self._prob_data = np.zeros(int(np.prod(np.power(np.array([2]), self._num_qubits)))) - self._data_grid = [] - self._grid_elements = None - self._prepare_data() + self._data, self._data_grid, self._grid_elements, self._prob_data = \ + discretize_and_truncate(self._data, self._bounds, self._num_qubits, + return_data_grid=True, return_data_grid_elements=True, + return_prob=True, prob_non_zero=True) self._batch_size = batch_size self._num_epochs = num_epochs self._snapshot_dir = snapshot_dir @@ -302,70 +301,6 @@ def rel_entr(self): """ returns relative entropy """ return self._rel_entr - def _prepare_data(self): - """ - Discretize and truncate the input data such that it - is compatible wih the chosen data resolution. - """ - # Truncate the data - if np.ndim(self._bounds) == 1: - bounds = np.reshape(self._bounds, (1, len(self._bounds))) - else: - bounds = self._bounds - self._data = self._data.reshape((len(self._data), len(self._num_qubits))) - temp = [] - for i, data_sample in enumerate(self._data): - append = True - for j, entry in enumerate(data_sample): - if entry < bounds[j, 0]: - append = False - if entry > bounds[j, 1]: - append = False - if append: - temp.append(list(data_sample)) - self._data = np.array(temp) - - # Fit the data to the data resolution. i.e. grid - for j, prec in enumerate(self._num_qubits): - data_row = self._data[:, j] # dim j of all data samples - # prepare data grid for dim j - grid = np.linspace(bounds[j, 0], bounds[j, 1], (2 ** prec)) - # find index for data sample in grid - index_grid = np.searchsorted(grid, data_row-(grid[1]-grid[0])*0.5) - for k, index in enumerate(index_grid): - self._data[k, j] = grid[index] - if j == 0: - if len(self._num_qubits) > 1: - self._data_grid = [grid] - else: - self._data_grid = grid - self._grid_elements = grid - elif j == 1: - self._data_grid.append(grid) - temp = [] - for g_e in self._grid_elements: - for g in grid: - temp0 = [g_e] - temp0.append(g) - temp.append(temp0) - self._grid_elements = temp - else: - self._data_grid.append(grid) - temp = [] - for g_e in self._grid_elements: - for g in grid: - temp0 = deepcopy(g_e) - temp0.append(g) - temp.append(temp0) - self._grid_elements = deepcopy(temp) - self._data_grid = np.array(self._data_grid) - self._data = np.reshape(self._data, (len(self._data), len(self._data[0]))) - for data in self._data: - for i, element in enumerate(self._grid_elements): - if all(data == element): - self._prob_data[i] += 1 / len(self._data) - self._prob_data = [1e-10 if x == 0 else x for x in self._prob_data] - def get_rel_entr(self): """ get relative entropy """ samples_gen, prob_gen = self._generator.get_output(self._quantum_instance) diff --git a/qiskit/aqua/components/optimizers/aqgd.py b/qiskit/aqua/components/optimizers/aqgd.py index 00460dae28..cbac38a25c 100644 --- a/qiskit/aqua/components/optimizers/aqgd.py +++ b/qiskit/aqua/components/optimizers/aqgd.py @@ -77,9 +77,7 @@ class AQGD(Optimizer): def __init__(self, maxiter=1000, eta=3.0, tol=1e-6, disp=False, momentum=0.25): """ Constructor. - Performs Analytical Quantum Gradient Descent (AQGD). - Args: maxiter (int): Maximum number of iterations, each iteration evaluation gradient. eta (float): The coefficient of the gradient update. Increasing this value @@ -89,7 +87,6 @@ def __init__(self, maxiter=1000, eta=3.0, tol=1e-6, disp=False, momentum=0.25): disp (bool): Set to true to display convergence messages. momentum (float): Bias towards the previous gradient momentum in current update. Must be within the bounds: [0,1) - """ self.validate(locals()) super().__init__() @@ -105,13 +102,11 @@ def deriv(self, j, params, obj): """ Obtains the analytical quantum derivative of the objective function with respect to the jth parameter. - Args: j (int): Index of the parameter to compute the derivative of. params (array): Current value of the parameters to evaluate the objective function at. obj (callable): Objective function. - Returns: float: The derivative of the objective function w.r.t. j """ @@ -129,7 +124,6 @@ def deriv(self, j, params, obj): def update(self, j, params, deriv, mprev): """ Updates the jth parameter based on the derivative and previous momentum - Args: j (int): Index of the parameter to compute the derivative of. params (array): Current value of the parameters to evaluate @@ -147,13 +141,11 @@ def converged(self, objval, n=2): """ Determines if the objective function has converged by finding the difference between the current value and the previous n values. - Args: objval (float): Current value of the objective function. n (int): Number of previous steps which must be within the convergence criteria in order to be considered converged. Using a larger number will prevent the optimizer from stopping early. - Returns: bool: Whether or not the optimization has converged. """ diff --git a/qiskit/aqua/components/uncertainty_models/multivariate_variational_distribution.py b/qiskit/aqua/components/uncertainty_models/multivariate_variational_distribution.py index 71c6a7cdc7..f90863c984 100644 --- a/qiskit/aqua/components/uncertainty_models/multivariate_variational_distribution.py +++ b/qiskit/aqua/components/uncertainty_models/multivariate_variational_distribution.py @@ -84,7 +84,8 @@ def __init__(self, num_qubits, var_form, params, low=None, high=None): self._num_qubits = num_qubits self._var_form = var_form self.params = params - super().__init__(num_qubits, low=low, high=high) + probabilities = np.zeros(2 ** sum(num_qubits)) + super().__init__(num_qubits, probabilities, low, high) self._var_form = var_form self.params = params diff --git a/qiskit/aqua/components/uncertainty_models/univariate_variational_distribution.py b/qiskit/aqua/components/uncertainty_models/univariate_variational_distribution.py index 730475d877..6a55c23d00 100644 --- a/qiskit/aqua/components/uncertainty_models/univariate_variational_distribution.py +++ b/qiskit/aqua/components/uncertainty_models/univariate_variational_distribution.py @@ -71,7 +71,13 @@ def __init__(self, num_qubits, var_form, params, low=0, high=1): self._num_qubits = num_qubits self._var_form = var_form self.params = params - super().__init__(num_qubits, low=low, high=high) + if isinstance(num_qubits, int): + probabilities = np.zeros(2 ** num_qubits) + elif isinstance(num_qubits, float): + probabilities = np.zeros(2 ** int(num_qubits)) + else: + probabilities = np.zeros(2 ** sum(num_qubits)) + super().__init__(num_qubits, probabilities, low, high) @classmethod def init_params(cls, params): diff --git a/qiskit/aqua/utils/dataset_helper.py b/qiskit/aqua/utils/dataset_helper.py index b03ea42b2f..290d500dcc 100644 --- a/qiskit/aqua/utils/dataset_helper.py +++ b/qiskit/aqua/utils/dataset_helper.py @@ -15,7 +15,7 @@ """ Data set helper """ import operator - +from copy import deepcopy import numpy as np from sklearn.decomposition import PCA @@ -133,3 +133,115 @@ def reduce_dim_to_via_pca(x, dim): """ x_reduced = PCA(n_components=dim).fit_transform(x) return x_reduced + + +def discretize_and_truncate(data, bounds, num_qubits, return_data_grid=False, + return_data_grid_elements=False, + return_prob=False, prob_non_zero=True): + """ + Discretize & truncate classical data to enable digital encoding in qubit registers + Args: + data (list or array or np.array): training data (int or float) of dimension k + bounds (list or array or np.array): k min/max data values + [[min_0,max_0],...,[min_k-1,max_k-1]] if univariate data: [min_0,max_0] + num_qubits (list or array or np.array): k numbers of qubits to determine + representation resolution, i.e. n qubits enable the representation of 2**n + values [num_qubits_0,..., num_qubits_k-1] + return_data_grid (Bool): if True - return an array with the data grid to which the + given data samples are mapped [[grid elements dim 0],..., [grid elements dim k]] + return_data_grid_elements (Bool): if True - return an array with the data grid elements + to which the given data samples are mapped - i.e. (Product_j=0^k-1 2**num_qubits_j) + element vectors + return_prob (Bool): if True - return a normalized frequency count of the discretized and + truncated data samples sorted from smallest to biggest element + + + Returns: discretized and truncated data (array)[, data_grid (array), grid_elements (array), + prob_data (array)] + """ + # Truncate the data + if np.ndim(bounds) == 1: + bounds = np.reshape(bounds, (1, len(bounds))) + + data = data.reshape((len(data), len(num_qubits))) + temp = [] + for i, data_sample in enumerate(data): + append = True + for j, entry in enumerate(data_sample): + if entry < bounds[j, 0]: + append = False + if entry > bounds[j, 1]: + append = False + if append: + temp.append(list(data_sample)) + data = np.array(temp) + + # Fit the data to the data element grid + for j, prec in enumerate(num_qubits): + data_row = data[:, j] # dim j of all data samples + # prepare element grid for dim j + elements_current_dim = np.linspace(bounds[j, 0], bounds[j, 1], (2 ** prec)) + # find index for data sample in grid + index_grid = np.searchsorted(elements_current_dim, + data_row-(elements_current_dim[1]-elements_current_dim[0])*0.5) + for k, index in enumerate(index_grid): + data[k, j] = elements_current_dim[index] + if j == 0: + if len(num_qubits) > 1: + data_grid = [elements_current_dim] + else: + data_grid = elements_current_dim + grid_elements = elements_current_dim + elif j == 1: + temp = [] + for grid_element in grid_elements: + for element_current in elements_current_dim: + temp.append([grid_element, element_current]) + grid_elements = temp + data_grid.append(elements_current_dim) + else: + temp = [] + for grid_element in grid_elements: + for element_current in elements_current_dim: + temp.append(deepcopy(grid_element).append(element_current)) + grid_elements = deepcopy(temp) + data_grid.append(elements_current_dim) + data_grid = np.array(data_grid) + + data = np.reshape(data, (len(data), len(data[0]))) + + if return_prob: + if np.ndim(data) > 1: + prob_data = np.zeros(int(np.prod(np.power(np.ones(len(data[0])) * 2, num_qubits)))) + else: + prob_data = np.zeros(int(np.prod(np.power(np.array([2]), num_qubits)))) + for data_element in data: + for i, element in enumerate(grid_elements): + if all(data_element == element): + prob_data[i] += 1 / len(data) + if prob_non_zero: + # add epsilon to avoid 0 entries which can be problematic in loss functions (division) + prob_data = [1e-10 if x == 0 else x for x in prob_data] + + if return_data_grid_elements: + if return_data_grid: + return data, data_grid, grid_elements, prob_data + else: + return data, grid_elements, prob_data + else: + if return_data_grid: + return data, data_grid, prob_data + else: + return data, prob_data + + else: + if return_data_grid_elements: + if return_data_grid: + return data, data_grid, grid_elements + else: + return data, grid_elements + else: + if return_data_grid: + return data, data_grid + else: + return data From 7d4272cfaeb800f2197ee442a01a036d0168b173 Mon Sep 17 00:00:00 2001 From: CZ Date: Fri, 6 Dec 2019 15:56:27 +0100 Subject: [PATCH 08/11] Update qgan.py --- qiskit/aqua/algorithms/adaptive/qgan/qgan.py | 1 - 1 file changed, 1 deletion(-) diff --git a/qiskit/aqua/algorithms/adaptive/qgan/qgan.py b/qiskit/aqua/algorithms/adaptive/qgan/qgan.py index 454df42fd9..92cd61c491 100644 --- a/qiskit/aqua/algorithms/adaptive/qgan/qgan.py +++ b/qiskit/aqua/algorithms/adaptive/qgan/qgan.py @@ -16,7 +16,6 @@ Quantum Generative Adversarial Network. """ -from copy import deepcopy import csv import os import logging From 875fd9fad62abf775558c8b619f9fc5cf507b87b Mon Sep 17 00:00:00 2001 From: CZ Date: Fri, 6 Dec 2019 18:01:46 +0100 Subject: [PATCH 09/11] fix discretization&truncation lint --- qiskit/aqua/algorithms/adaptive/qgan/qgan.py | 2 +- qiskit/aqua/utils/dataset_helper.py | 44 ++++++++------------ 2 files changed, 19 insertions(+), 27 deletions(-) diff --git a/qiskit/aqua/algorithms/adaptive/qgan/qgan.py b/qiskit/aqua/algorithms/adaptive/qgan/qgan.py index 92cd61c491..a8119bfeb9 100644 --- a/qiskit/aqua/algorithms/adaptive/qgan/qgan.py +++ b/qiskit/aqua/algorithms/adaptive/qgan/qgan.py @@ -150,7 +150,7 @@ def __init__(self, data, bounds=None, num_qubits=None, batch_size=500, num_epoch self._num_qubits = np.array([3]) self._data, self._data_grid, self._grid_elements, self._prob_data = \ discretize_and_truncate(self._data, self._bounds, self._num_qubits, - return_data_grid=True, return_data_grid_elements=True, + return_data_grid_elements=True, return_prob=True, prob_non_zero=True) self._batch_size = batch_size self._num_epochs = num_epochs diff --git a/qiskit/aqua/utils/dataset_helper.py b/qiskit/aqua/utils/dataset_helper.py index 290d500dcc..bf92f27b97 100644 --- a/qiskit/aqua/utils/dataset_helper.py +++ b/qiskit/aqua/utils/dataset_helper.py @@ -135,11 +135,12 @@ def reduce_dim_to_via_pca(x, dim): return x_reduced -def discretize_and_truncate(data, bounds, num_qubits, return_data_grid=False, - return_data_grid_elements=False, +def discretize_and_truncate(data, bounds, num_qubits, return_data_grid_elements=False, return_prob=False, prob_non_zero=True): """ Discretize & truncate classical data to enable digital encoding in qubit registers + whereby the data grid is [[grid elements dim 0],..., [grid elements dim k]] + Args: data (list or array or np.array): training data (int or float) of dimension k bounds (list or array or np.array): k min/max data values @@ -147,17 +148,19 @@ def discretize_and_truncate(data, bounds, num_qubits, return_data_grid=False, num_qubits (list or array or np.array): k numbers of qubits to determine representation resolution, i.e. n qubits enable the representation of 2**n values [num_qubits_0,..., num_qubits_k-1] - return_data_grid (Bool): if True - return an array with the data grid to which the - given data samples are mapped [[grid elements dim 0],..., [grid elements dim k]] - return_data_grid_elements (Bool): if True - return an array with the data grid elements - to which the given data samples are mapped - i.e. (Product_j=0^k-1 2**num_qubits_j) - element vectors + return_data_grid_elements (Bool): if True - return an array with the data grid + elements return_prob (Bool): if True - return a normalized frequency count of the discretized and - truncated data samples sorted from smallest to biggest element + truncated data samples + prob_non_zero (Bool): if True - set 0 values in the prob_data to 10^-1 to avoid potential + problems when using the probabilities in loss functions - division by 0 + Returns: + array: discretized and truncated data + array: data grid [[grid elements dim 0],..., [grid elements dim k]] + array: grid elements, Product_j=0^k-1 2**num_qubits_j element vectors + array: data probability, normalized frequency count sorted from smallest to biggest element - Returns: discretized and truncated data (array)[, data_grid (array), grid_elements (array), - prob_data (array)] """ # Truncate the data if np.ndim(bounds) == 1: @@ -224,24 +227,13 @@ def discretize_and_truncate(data, bounds, num_qubits, return_data_grid=False, prob_data = [1e-10 if x == 0 else x for x in prob_data] if return_data_grid_elements: - if return_data_grid: - return data, data_grid, grid_elements, prob_data - else: - return data, grid_elements, prob_data + return data, data_grid, grid_elements, prob_data else: - if return_data_grid: - return data, data_grid, prob_data - else: - return data, prob_data + return data, data_grid, prob_data else: if return_data_grid_elements: - if return_data_grid: - return data, data_grid, grid_elements - else: - return data, grid_elements + return data, data_grid, grid_elements + else: - if return_data_grid: - return data, data_grid - else: - return data + return data, data_grid From 35100db77c0e1412cbe350c836b76537d9f7a8e5 Mon Sep 17 00:00:00 2001 From: CZ Date: Fri, 6 Dec 2019 21:35:57 +0100 Subject: [PATCH 10/11] Update aqgd.py --- qiskit/aqua/components/optimizers/aqgd.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/qiskit/aqua/components/optimizers/aqgd.py b/qiskit/aqua/components/optimizers/aqgd.py index cbac38a25c..279d0a4752 100644 --- a/qiskit/aqua/components/optimizers/aqgd.py +++ b/qiskit/aqua/components/optimizers/aqgd.py @@ -77,7 +77,9 @@ class AQGD(Optimizer): def __init__(self, maxiter=1000, eta=3.0, tol=1e-6, disp=False, momentum=0.25): """ Constructor. + Performs Analytical Quantum Gradient Descent (AQGD). + Args: maxiter (int): Maximum number of iterations, each iteration evaluation gradient. eta (float): The coefficient of the gradient update. Increasing this value @@ -87,6 +89,7 @@ def __init__(self, maxiter=1000, eta=3.0, tol=1e-6, disp=False, momentum=0.25): disp (bool): Set to true to display convergence messages. momentum (float): Bias towards the previous gradient momentum in current update. Must be within the bounds: [0,1) + """ self.validate(locals()) super().__init__() @@ -102,6 +105,7 @@ def deriv(self, j, params, obj): """ Obtains the analytical quantum derivative of the objective function with respect to the jth parameter. + Args: j (int): Index of the parameter to compute the derivative of. params (array): Current value of the parameters to evaluate @@ -124,6 +128,7 @@ def deriv(self, j, params, obj): def update(self, j, params, deriv, mprev): """ Updates the jth parameter based on the derivative and previous momentum + Args: j (int): Index of the parameter to compute the derivative of. params (array): Current value of the parameters to evaluate @@ -141,11 +146,13 @@ def converged(self, objval, n=2): """ Determines if the objective function has converged by finding the difference between the current value and the previous n values. + Args: objval (float): Current value of the objective function. n (int): Number of previous steps which must be within the convergence criteria in order to be considered converged. Using a larger number will prevent the optimizer from stopping early. + Returns: bool: Whether or not the optimization has converged. """ From fce19de2c9dc372fd3ac67e56af794023cb99305 Mon Sep 17 00:00:00 2001 From: Steve Wood <40241007+woodsp-ibm@users.noreply.github.com> Date: Fri, 6 Dec 2019 16:19:49 -0500 Subject: [PATCH 11/11] Update aqgd.py Remove trailing blank space --- qiskit/aqua/components/optimizers/aqgd.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/aqua/components/optimizers/aqgd.py b/qiskit/aqua/components/optimizers/aqgd.py index 279d0a4752..63adc65783 100644 --- a/qiskit/aqua/components/optimizers/aqgd.py +++ b/qiskit/aqua/components/optimizers/aqgd.py @@ -146,7 +146,7 @@ def converged(self, objval, n=2): """ Determines if the objective function has converged by finding the difference between the current value and the previous n values. - + Args: objval (float): Current value of the objective function. n (int): Number of previous steps which must be within the convergence criteria