From 1f2bef4aa1b3238731f024cc0ee680529c0a9e37 Mon Sep 17 00:00:00 2001 From: Manoel Marques Date: Wed, 25 Mar 2020 18:15:54 -0400 Subject: [PATCH 1/3] Add QuantumInstance/Backend to algorithm init --- .travis.yml | 9 +++------ .../algorithms/amplitude_amplifiers/grover.py | 17 +++++++++++------ .../amplitude_estimators/ae_algorithm.py | 13 ++++++++++--- qiskit/aqua/algorithms/classifiers/qsvm/qsvm.py | 12 +++++++----- .../algorithms/distribution_learners/qgan.py | 11 +++++++---- .../algorithms/education/bernstein_vazirani.py | 10 ++++++++-- .../aqua/algorithms/education/deutsch_jozsa.py | 11 ++++++++--- qiskit/aqua/algorithms/education/eoh.py | 9 +++++++-- qiskit/aqua/algorithms/education/simon.py | 11 ++++++++--- qiskit/aqua/algorithms/factorizers/shor.py | 12 +++++++++--- qiskit/aqua/algorithms/linear_solvers/hhl.py | 11 +++++++---- .../algorithms/minimum_eigen_solvers/iqpe.py | 10 +++++++--- .../minimum_eigen_solvers/qaoa/qaoa.py | 12 +++++++++--- .../algorithms/minimum_eigen_solvers/qpe.py | 11 +++++++---- .../algorithms/minimum_eigen_solvers/vqe.py | 13 ++++++++----- qiskit/aqua/algorithms/quantum_algorithm.py | 5 ++++- qiskit/aqua/algorithms/vq_algorithm.py | 10 +++++++--- .../algorithms/eigen_solvers/q_eom_vqe.py | 12 ++++++++---- .../minimum_eigen_solvers/vqe_adapt.py | 15 +++++++++------ 19 files changed, 144 insertions(+), 70 deletions(-) diff --git a/.travis.yml b/.travis.yml index e7aa726a6b..212ac2c2b9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -87,25 +87,22 @@ stage_test_aqua: &stage_test_aqua install: - | cat > selection.txt < None: + def __init__(self, + oracle: Oracle, init_state: Optional[InitialState] = None, + incremental: bool = False, + num_iterations: int = 1, + mct_mode: str = 'basic', + quantum_instance: Optional[Union[QuantumInstance, BaseBackend]] = None) -> None: r""" Args: oracle: The oracle component @@ -98,6 +102,7 @@ def __init__(self, oracle: Oracle, init_state: Optional[InitialState] = None, repeated to amplify the amplitude(s) of the target(s). Has a minimum value of 1. mct_mode: Multi-Control Toffoli mode ('basic' | 'basic-dirty-ancilla' | 'advanced' | 'noancilla') + quantum_instance: Quantum Instance or Backend Raises: AquaError: evaluate_classically() missing from the input oracle @@ -106,7 +111,7 @@ def __init__(self, oracle: Oracle, init_state: Optional[InitialState] = None, validate_in_set('mct_mode', mct_mode, {'basic', 'basic-dirty-ancilla', 'advanced', 'noancilla'}) - super().__init__() + super().__init__(quantum_instance) if not callable(getattr(oracle, "evaluate_classically", None)): raise AquaError( diff --git a/qiskit/aqua/algorithms/amplitude_estimators/ae_algorithm.py b/qiskit/aqua/algorithms/amplitude_estimators/ae_algorithm.py index 3be03171a9..0003ef68a0 100644 --- a/qiskit/aqua/algorithms/amplitude_estimators/ae_algorithm.py +++ b/qiskit/aqua/algorithms/amplitude_estimators/ae_algorithm.py @@ -15,11 +15,14 @@ The Amplitude Estimation Algorithm. """ +from typing import Optional, Union import logging from abc import abstractmethod +from qiskit.providers import BaseBackend +from qiskit.aqua import QuantumInstance from qiskit.aqua.algorithms import QuantumAlgorithm - +from qiskit.aqua.utils import CircuitFactory from .q_factory import QFactory logger = logging.getLogger(__name__) @@ -46,12 +49,16 @@ class AmplitudeEstimationAlgorithm(QuantumAlgorithm): """ @abstractmethod - def __init__(self, a_factory=None, q_factory=None, i_objective=None): + def __init__(self, + a_factory: Optional[CircuitFactory] = None, + q_factory=None, + i_objective=None, + quantum_instance: Optional[Union[QuantumInstance, BaseBackend]] = None) -> None: self._a_factory = a_factory self._q_factory = q_factory self._i_objective = i_objective - super().__init__() + super().__init__(quantum_instance) @property def a_factory(self): diff --git a/qiskit/aqua/algorithms/classifiers/qsvm/qsvm.py b/qiskit/aqua/algorithms/classifiers/qsvm/qsvm.py index 8332d7f969..2477c71bef 100644 --- a/qiskit/aqua/algorithms/classifiers/qsvm/qsvm.py +++ b/qiskit/aqua/algorithms/classifiers/qsvm/qsvm.py @@ -14,7 +14,7 @@ """Quantum SVM algorithm.""" -from typing import Dict, Optional +from typing import Dict, Optional, Union import logging import sys @@ -23,8 +23,8 @@ from qiskit.tools import parallel_map from qiskit.tools.events import TextProgressBar from qiskit.circuit import ParameterVector - -from qiskit.aqua import aqua_globals +from qiskit.providers import BaseBackend +from qiskit.aqua import QuantumInstance, aqua_globals from qiskit.aqua.algorithms import QuantumAlgorithm from qiskit.aqua import AquaError from qiskit.aqua.utils.dataset_helper import get_num_classes @@ -80,7 +80,8 @@ def __init__(self, feature_map: FeatureMap, training_dataset: Optional[Dict[str, np.ndarray]] = None, test_dataset: Optional[Dict[str, np.ndarray]] = None, datapoints: Optional[np.ndarray] = None, - multiclass_extension: Optional[MulticlassExtension] = None) -> None: + multiclass_extension: Optional[MulticlassExtension] = None, + quantum_instance: Optional[Union[QuantumInstance, BaseBackend]] = None) -> None: """ Args: feature_map: Feature map module, used to transform data @@ -89,11 +90,12 @@ def __init__(self, feature_map: FeatureMap, datapoints: Prediction dataset. multiclass_extension: If number of classes is greater than 2 then a multiclass scheme must be supplied, in the form of a multiclass extension. + quantum_instance: Quantum Instance or Backend Raises: AquaError: Multiclass extension not supplied when number of classes > 2 """ - super().__init__() + super().__init__(quantum_instance) # check the validity of provided arguments if possible if training_dataset is not None: is_multiclass = get_num_classes(training_dataset) > 2 diff --git a/qiskit/aqua/algorithms/distribution_learners/qgan.py b/qiskit/aqua/algorithms/distribution_learners/qgan.py index 04b42e6140..91dbdae0cb 100644 --- a/qiskit/aqua/algorithms/distribution_learners/qgan.py +++ b/qiskit/aqua/algorithms/distribution_learners/qgan.py @@ -18,7 +18,7 @@ `_ """ -from typing import Optional +from typing import Optional, Union import csv import os import logging @@ -26,7 +26,8 @@ import numpy as np from scipy.stats import entropy -from qiskit.aqua import AquaError, aqua_globals +from qiskit.providers import BaseBackend +from qiskit.aqua import QuantumInstance, AquaError, aqua_globals from qiskit.aqua.algorithms import QuantumAlgorithm from qiskit.aqua.components.neural_networks.discriminative_network import DiscriminativeNetwork from qiskit.aqua.components.neural_networks.generative_network import GenerativeNetwork @@ -65,7 +66,8 @@ def __init__(self, data: np.ndarray, bounds: Optional[np.ndarray] = None, num_epochs: int = 3000, seed: int = 7, discriminator: Optional[DiscriminativeNetwork] = None, generator: Optional[GenerativeNetwork] = None, - tol_rel_ent: Optional[float] = None, snapshot_dir: Optional[str] = None) -> None: + tol_rel_ent: Optional[float] = None, snapshot_dir: Optional[str] = None, + quantum_instance: Optional[Union[QuantumInstance, BaseBackend]] = None) -> None: """ Args: @@ -84,11 +86,12 @@ def __init__(self, data: np.ndarray, bounds: Optional[np.ndarray] = None, If the training achieves relative entropy equal or lower than tolerance it finishes. snapshot_dir: Directory in to which to store cvs file with parameters, if None (default) then no cvs file is created. + quantum_instance: Quantum Instance or Backend Raises: AquaError: invalid input """ validate_min('batch_size', batch_size, 1) - super().__init__() + super().__init__(quantum_instance) if data is None: raise AquaError('Training data not given.') self._data = np.array(data) diff --git a/qiskit/aqua/algorithms/education/bernstein_vazirani.py b/qiskit/aqua/algorithms/education/bernstein_vazirani.py index 98389e029b..d688fbb68e 100644 --- a/qiskit/aqua/algorithms/education/bernstein_vazirani.py +++ b/qiskit/aqua/algorithms/education/bernstein_vazirani.py @@ -15,11 +15,14 @@ The Bernstein-Vazirani algorithm. """ +from typing import Optional, Union import logging import operator import numpy as np from qiskit import ClassicalRegister, QuantumCircuit +from qiskit.providers import BaseBackend +from qiskit.aqua import QuantumInstance from qiskit.aqua.algorithms import QuantumAlgorithm from qiskit.aqua.utils import get_subsystem_density_matrix from qiskit.aqua.components.oracles import Oracle @@ -39,12 +42,15 @@ class BernsteinVazirani(QuantumAlgorithm): :math:`f(x)=s \cdot x (\bmod 2)`. """ - def __init__(self, oracle: Oracle) -> None: + def __init__(self, + oracle: Oracle, + quantum_instance: Optional[Union[QuantumInstance, BaseBackend]] = None) -> None: """ Args: oracle: The oracle component + quantum_instance: Quantum Instance or Backend """ - super().__init__() + super().__init__(quantum_instance) self._oracle = oracle self._circuit = None diff --git a/qiskit/aqua/algorithms/education/deutsch_jozsa.py b/qiskit/aqua/algorithms/education/deutsch_jozsa.py index 9d76696134..97ad52cf23 100644 --- a/qiskit/aqua/algorithms/education/deutsch_jozsa.py +++ b/qiskit/aqua/algorithms/education/deutsch_jozsa.py @@ -15,12 +15,14 @@ The Deutsch-Jozsa algorithm. """ +from typing import Optional, Union import logging import operator import numpy as np from qiskit import ClassicalRegister, QuantumCircuit - +from qiskit.providers import BaseBackend +from qiskit.aqua import QuantumInstance from qiskit.aqua.algorithms import QuantumAlgorithm from qiskit.aqua.utils import get_subsystem_density_matrix from qiskit.aqua.components.oracles import Oracle @@ -45,12 +47,15 @@ class DeutschJozsa(QuantumAlgorithm): implemented by the oracle indeed satisfies the constraint of being either constant or balanced. """ - def __init__(self, oracle: Oracle) -> None: + def __init__(self, + oracle: Oracle, + quantum_instance: Optional[Union[QuantumInstance, BaseBackend]] = None) -> None: """ Args: oracle: The oracle component + quantum_instance: Quantum Instance or Backend """ - super().__init__() + super().__init__(quantum_instance) self._oracle = oracle self._circuit = None diff --git a/qiskit/aqua/algorithms/education/eoh.py b/qiskit/aqua/algorithms/education/eoh.py index 2c1f28610e..77c8b21952 100644 --- a/qiskit/aqua/algorithms/education/eoh.py +++ b/qiskit/aqua/algorithms/education/eoh.py @@ -17,7 +17,10 @@ import logging +from typing import Optional, Union from qiskit import QuantumRegister +from qiskit.providers import BaseBackend +from qiskit.aqua import QuantumInstance from qiskit.aqua.algorithms import QuantumAlgorithm from qiskit.aqua.operators import op_converter from qiskit.aqua.operators import BaseOperator @@ -45,7 +48,8 @@ def __init__(self, operator: BaseOperator, evo_time: float = 1, num_time_slices: int = 1, expansion_mode: str = 'trotter', - expansion_order: int = 1) -> None: + expansion_order: int = 1, + quantum_instance: Optional[Union[QuantumInstance, BaseBackend]] = None) -> None: """ Args: operator: Operator to evaluate @@ -56,12 +60,13 @@ def __init__(self, operator: BaseOperator, expansion_mode: Either ``"trotter"`` (Lloyd's method) or ``"suzuki"`` (for Trotter-Suzuki expansion) expansion_order: The Trotter-Suzuki expansion order. + quantum_instance: Quantum Instance or Backend """ validate_min('evo_time', evo_time, 0) validate_min('num_time_slices', num_time_slices, 1) validate_in_set('expansion_mode', expansion_mode, {'trotter', 'suzuki'}) validate_min('expansion_order', expansion_order, 1) - super().__init__() + super().__init__(quantum_instance) self._operator = op_converter.to_weighted_pauli_operator(operator) self._initial_state = initial_state self._evo_operator = op_converter.to_weighted_pauli_operator(evo_operator) diff --git a/qiskit/aqua/algorithms/education/simon.py b/qiskit/aqua/algorithms/education/simon.py index e4e39d94b1..f30258794b 100644 --- a/qiskit/aqua/algorithms/education/simon.py +++ b/qiskit/aqua/algorithms/education/simon.py @@ -16,11 +16,13 @@ """ import operator # pylint: disable=unused-import +from typing import Optional, Union import numpy as np from sympy import Matrix, mod_inverse from qiskit import ClassicalRegister, QuantumCircuit - +from qiskit.providers import BaseBackend +from qiskit.aqua import QuantumInstance from qiskit.aqua.algorithms import QuantumAlgorithm from qiskit.aqua.utils import get_subsystem_density_matrix from qiskit.aqua.components.oracles import Oracle @@ -42,12 +44,15 @@ class Simon(QuantumAlgorithm): to create one that can be used with the Simon algorithm. """ - def __init__(self, oracle: Oracle) -> None: + def __init__(self, + oracle: Oracle, + quantum_instance: Optional[Union[QuantumInstance, BaseBackend]] = None) -> None: """ Args: oracle: The oracle component + quantum_instance: Quantum Instance or Backend """ - super().__init__() + super().__init__(quantum_instance) self._oracle = oracle self._circuit = None diff --git a/qiskit/aqua/algorithms/factorizers/shor.py b/qiskit/aqua/algorithms/factorizers/shor.py index 2b240b55af..54581a1479 100644 --- a/qiskit/aqua/algorithms/factorizers/shor.py +++ b/qiskit/aqua/algorithms/factorizers/shor.py @@ -17,6 +17,7 @@ Quantum Information and Computation, Vol. 3, No. 2 (2003) pp. 175-185 """ +from typing import Optional, Union import math import array import fractions @@ -24,7 +25,8 @@ import numpy as np from qiskit import ClassicalRegister, QuantumCircuit, QuantumRegister - +from qiskit.providers import BaseBackend +from qiskit.aqua import QuantumInstance from qiskit.aqua.utils.arithmetic import is_power from qiskit.aqua.utils import get_subsystem_density_matrix from qiskit.aqua.algorithms import QuantumAlgorithm @@ -54,17 +56,21 @@ class Shor(QuantumAlgorithm): See also https://arxiv.org/abs/quant-ph/0205095 """ - def __init__(self, N: int = 15, a: int = 2) -> None: + def __init__(self, + N: int = 15, + a: int = 2, + quantum_instance: Optional[Union[QuantumInstance, BaseBackend]] = None) -> None: """ Args: N: The integer to be factored, has a min. value of 3. a: A random integer that satisfies a < N and gcd(a, N) = 1, has a min. value of 2. + quantum_instance: Quantum Instance or Backend Raises: ValueError: Invalid input """ validate_min('N', N, 3) validate_min('a', a, 2) - super().__init__() + super().__init__(quantum_instance) self._n = None self._up_qreg = None self._down_qreg = None diff --git a/qiskit/aqua/algorithms/linear_solvers/hhl.py b/qiskit/aqua/algorithms/linear_solvers/hhl.py index ec8dab3a38..5e712fb866 100644 --- a/qiskit/aqua/algorithms/linear_solvers/hhl.py +++ b/qiskit/aqua/algorithms/linear_solvers/hhl.py @@ -15,12 +15,14 @@ The HHL algorithm. """ -from typing import Optional +from typing import Optional, Union import logging from copy import deepcopy import numpy as np from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit +from qiskit.providers import BaseBackend +from qiskit.aqua import QuantumInstance from qiskit.aqua.algorithms import QuantumAlgorithm from qiskit.ignis.verification.tomography import state_tomography_circuits, \ StateTomographyFitter @@ -95,8 +97,8 @@ def __init__( reciprocal: Optional[Reciprocal] = None, num_q: int = 0, num_a: int = 0, - orig_size: Optional[int] = None - ) -> None: + orig_size: Optional[int] = None, + quantum_instance: Optional[Union[QuantumInstance, BaseBackend]] = None) -> None: """ Args: matrix: The input matrix of linear system of equations @@ -109,10 +111,11 @@ def __init__( num_q: Number of qubits required for the matrix Operator instance num_a: Number of ancillary qubits for Eigenvalues instance orig_size: The original dimension of the problem (if truncate_powerdim) + quantum_instance: Quantum Instance or Backend Raises: ValueError: Invalid input """ - super().__init__() + super().__init__(quantum_instance) if matrix.shape[0] != matrix.shape[1]: raise ValueError("Input matrix must be square!") if matrix.shape[0] != len(vector): diff --git a/qiskit/aqua/algorithms/minimum_eigen_solvers/iqpe.py b/qiskit/aqua/algorithms/minimum_eigen_solvers/iqpe.py index 9a3ba18d57..46e5516c68 100644 --- a/qiskit/aqua/algorithms/minimum_eigen_solvers/iqpe.py +++ b/qiskit/aqua/algorithms/minimum_eigen_solvers/iqpe.py @@ -16,13 +16,15 @@ See https://arxiv.org/abs/quant-ph/0610214 """ -from typing import Optional, List, Dict +from typing import Optional, List, Dict, Union import logging import warnings import numpy as np from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit from qiskit.quantum_info import Pauli +from qiskit.providers import BaseBackend +from qiskit.aqua import QuantumInstance from qiskit.aqua.operators import (WeightedPauliOperator, suzuki_expansion_slice_pauli_list, evolution_instruction, op_converter) from qiskit.aqua.utils import get_subsystem_density_matrix @@ -58,7 +60,8 @@ def __init__(self, num_iterations: int = 1, expansion_mode: str = 'suzuki', expansion_order: int = 2, - shallow_circuit_concat: bool = False) -> None: + shallow_circuit_concat: bool = False, + quantum_instance: Optional[Union[QuantumInstance, BaseBackend]] = None) -> None: """ Args: @@ -70,12 +73,13 @@ def __init__(self, expansion_order: The suzuki expansion order, has a min. value of 1. shallow_circuit_concat: Set True to use shallow (cheap) mode for circuit concatenation of evolution slices. By default this is False. + quantum_instance: Quantum Instance or Backend """ validate_min('num_time_slices', num_time_slices, 1) validate_min('num_iterations', num_iterations, 1) validate_in_set('expansion_mode', expansion_mode, {'trotter', 'suzuki'}) validate_min('expansion_order', expansion_order, 1) - super().__init__() + super().__init__(quantum_instance) self._state_in = state_in self._num_time_slices = num_time_slices self._num_iterations = num_iterations diff --git a/qiskit/aqua/algorithms/minimum_eigen_solvers/qaoa/qaoa.py b/qiskit/aqua/algorithms/minimum_eigen_solvers/qaoa/qaoa.py index d47304df40..5bb0eb83d8 100644 --- a/qiskit/aqua/algorithms/minimum_eigen_solvers/qaoa/qaoa.py +++ b/qiskit/aqua/algorithms/minimum_eigen_solvers/qaoa/qaoa.py @@ -14,9 +14,12 @@ """ The Quantum Approximate Optimization Algorithm. """ -from typing import List, Callable, Optional +from typing import List, Callable, Optional, Union import logging import numpy as np + +from qiskit.providers import BaseBackend +from qiskit.aqua import QuantumInstance from qiskit.aqua.operators import BaseOperator from qiskit.aqua.components.initial_states import InitialState from qiskit.aqua.components.optimizers import Optimizer @@ -64,7 +67,8 @@ def __init__(self, operator: BaseOperator = None, optimizer: Optimizer = None, p mixer: Optional[BaseOperator] = None, initial_point: Optional[np.ndarray] = None, max_evals_grouped: int = 1, aux_operators: Optional[List[BaseOperator]] = None, callback: Optional[Callable[[int, np.ndarray, float, float], None]] = None, - auto_conversion: bool = True) -> None: + auto_conversion: bool = True, + quantum_instance: Optional[Union[QuantumInstance, BaseBackend]] = None) -> None: """ Args: operator: Qubit operator @@ -101,6 +105,7 @@ def __init__(self, operator: BaseOperator = None, optimizer: Optimizer = None, p :class:`~qiskit.aqua.operators.WeightedPauliOperator` - for *qasm simulator or real backend:* :class:`~qiskit.aqua.operators.TPBGroupedWeightedPauliOperator` + quantum_instance: Quantum Instance or Backend """ validate_min('p', p, 1) @@ -112,7 +117,8 @@ def __init__(self, operator: BaseOperator = None, optimizer: Optimizer = None, p # will cause the var form to be built super().__init__(operator, None, optimizer, initial_point=initial_point, max_evals_grouped=max_evals_grouped, aux_operators=aux_operators, - callback=callback, auto_conversion=auto_conversion) + callback=callback, auto_conversion=auto_conversion, + quantum_instance=quantum_instance) @VQE.operator.setter def operator(self, operator: BaseOperator) -> None: diff --git a/qiskit/aqua/algorithms/minimum_eigen_solvers/qpe.py b/qiskit/aqua/algorithms/minimum_eigen_solvers/qpe.py index 8ba2280f28..842cc23869 100644 --- a/qiskit/aqua/algorithms/minimum_eigen_solvers/qpe.py +++ b/qiskit/aqua/algorithms/minimum_eigen_solvers/qpe.py @@ -16,13 +16,14 @@ """ import logging -from typing import Optional, List, Dict +from typing import Optional, List, Dict, Union import warnings import numpy as np from qiskit import QuantumCircuit from qiskit.quantum_info import Pauli - +from qiskit.providers import BaseBackend +from qiskit.aqua import QuantumInstance from qiskit.aqua.operators import op_converter from qiskit.aqua.utils import get_subsystem_density_matrix from qiskit.aqua.algorithms import QuantumAlgorithm @@ -64,7 +65,8 @@ def __init__(self, num_ancillae: int = 1, expansion_mode: str = 'trotter', expansion_order: int = 1, - shallow_circuit_concat: bool = False) -> None: + shallow_circuit_concat: bool = False, + quantum_instance: Optional[Union[QuantumInstance, BaseBackend]] = None) -> None: """ Args: @@ -80,12 +82,13 @@ def __init__(self, shallow_circuit_concat: Set True to use shallow (cheap) mode for circuit concatenation of evolution slices. By default this is False. See :meth:`qiskit.aqua.operators.common.evolution_instruction` for more information. + quantum_instance: Quantum Instance or Backend """ validate_min('num_time_slices', num_time_slices, 1) validate_min('num_ancillae', num_ancillae, 1) validate_in_set('expansion_mode', expansion_mode, {'trotter', 'suzuki'}) validate_min('expansion_order', expansion_order, 1) - super().__init__() + super().__init__(quantum_instance) self._state_in = state_in self._iqft = iqft self._num_time_slices = num_time_slices diff --git a/qiskit/aqua/algorithms/minimum_eigen_solvers/vqe.py b/qiskit/aqua/algorithms/minimum_eigen_solvers/vqe.py index 5e322b0a30..e90360de7c 100644 --- a/qiskit/aqua/algorithms/minimum_eigen_solvers/vqe.py +++ b/qiskit/aqua/algorithms/minimum_eigen_solvers/vqe.py @@ -18,7 +18,7 @@ See https://arxiv.org/abs/1304.3061 """ -from typing import Optional, List, Callable +from typing import Optional, List, Callable, Union import logging import functools import warnings @@ -27,8 +27,8 @@ import numpy as np from qiskit import ClassicalRegister, QuantumCircuit from qiskit.circuit import ParameterVector - -from qiskit.aqua import AquaError +from qiskit.providers import BaseBackend +from qiskit.aqua import QuantumInstance, AquaError from qiskit.aqua.operators import (TPBGroupedWeightedPauliOperator, WeightedPauliOperator, MatrixOperator, op_converter) from qiskit.aqua.utils.backend_utils import (is_statevector_backend, @@ -89,7 +89,8 @@ def __init__(self, max_evals_grouped: int = 1, aux_operators: Optional[List[BaseOperator]] = None, callback: Optional[Callable[[int, np.ndarray, float, float], None]] = None, - auto_conversion: bool = True) -> None: + auto_conversion: bool = True, + quantum_instance: Optional[Union[QuantumInstance, BaseBackend]] = None) -> None: """ Args: @@ -124,6 +125,7 @@ def __init__(self, :class:`~qiskit.aqua.operators.WeightedPauliOperator` - for *qasm simulator or real backend:* :class:`~qiskit.aqua.operators.TPBGroupedWeightedPauliOperator` + quantum_instance: Quantum Instance or Backend """ validate_min('max_evals_grouped', max_evals_grouped, 1) @@ -146,7 +148,8 @@ def __init__(self, super().__init__(var_form=var_form, optimizer=optimizer, cost_fn=self._energy_evaluation, - initial_point=initial_point) + initial_point=initial_point, + quantum_instance=quantum_instance) self._in_operator = None self._operator = None diff --git a/qiskit/aqua/algorithms/quantum_algorithm.py b/qiskit/aqua/algorithms/quantum_algorithm.py index 048120bf25..ca7c314ee4 100644 --- a/qiskit/aqua/algorithms/quantum_algorithm.py +++ b/qiskit/aqua/algorithms/quantum_algorithm.py @@ -34,8 +34,11 @@ class QuantumAlgorithm(ABC): use an exception if a component of the module is available. """ @abstractmethod - def __init__(self) -> None: + def __init__(self, + quantum_instance: Optional[Union[QuantumInstance, BaseBackend]]) -> None: self._quantum_instance = None + if quantum_instance: + self.quantum_instance = quantum_instance @property def random(self): diff --git a/qiskit/aqua/algorithms/vq_algorithm.py b/qiskit/aqua/algorithms/vq_algorithm.py index 5da4c2e08c..3fb7f60cbb 100644 --- a/qiskit/aqua/algorithms/vq_algorithm.py +++ b/qiskit/aqua/algorithms/vq_algorithm.py @@ -22,13 +22,15 @@ overridden to opt-out of this infrastructure but still meet the interface requirements. """ -from typing import Optional, Callable +from typing import Optional, Callable, Union import time import logging import warnings from abc import abstractmethod import numpy as np +from qiskit.providers import BaseBackend +from qiskit.aqua import QuantumInstance from qiskit.aqua.algorithms import AlgorithmResult, QuantumAlgorithm from qiskit.aqua.components.optimizers import Optimizer from qiskit.aqua.components.variational_forms import VariationalForm @@ -46,7 +48,8 @@ def __init__(self, var_form: VariationalForm, optimizer: Optimizer, cost_fn: Optional[Callable] = None, - initial_point: Optional[np.ndarray] = None) -> None: + initial_point: Optional[np.ndarray] = None, + quantum_instance: Optional[Union[QuantumInstance, BaseBackend]] = None) -> None: """ Args: var_form: An optional parameterized variational form (ansatz). @@ -55,10 +58,11 @@ def __init__(self, supplied on :meth:`find_minimum`. initial_point: An optional initial point (i.e. initial parameter values) for the optimizer. + quantum_instance: Quantum Instance or Backend Raises: ValueError: for invalid input """ - super().__init__() + super().__init__(quantum_instance) self._var_form = var_form self._optimizer = optimizer diff --git a/qiskit/chemistry/algorithms/eigen_solvers/q_eom_vqe.py b/qiskit/chemistry/algorithms/eigen_solvers/q_eom_vqe.py index 9911c19e67..687e2723d1 100644 --- a/qiskit/chemistry/algorithms/eigen_solvers/q_eom_vqe.py +++ b/qiskit/chemistry/algorithms/eigen_solvers/q_eom_vqe.py @@ -18,6 +18,8 @@ from typing import Union, List, Optional, Callable import numpy as np +from qiskit.providers import BaseBackend +from qiskit.aqua import QuantumInstance from qiskit.aqua.algorithms import VQE from qiskit.aqua.operators import BaseOperator, Z2Symmetries from qiskit.aqua.components.optimizers import Optimizer @@ -47,7 +49,8 @@ def __init__(self, operator: BaseOperator, var_form: VariationalForm, de_list: Optional[List[List[int]]] = None, z2_symmetries: Optional[Z2Symmetries] = None, untapered_op: Optional[BaseOperator] = None, - aux_operators: Optional[List[BaseOperator]] = None) -> None: + aux_operators: Optional[List[BaseOperator]] = None, + quantum_instance: Optional[Union[QuantumInstance, BaseBackend]] = None) -> None: """ Args: operator: qubit operator @@ -83,8 +86,8 @@ def __init__(self, operator: BaseOperator, var_form: VariationalForm, z2_symmetries: represent the Z2 symmetries untapered_op: if the operator is tapered, we need untapered operator during building element of EoM matrix - aux_operators: Auxiliary operators to be - evaluated at each eigenvalue + aux_operators: Auxiliary operators to be evaluated at each eigenvalue + quantum_instance: Quantum Instance or Backend Raises: ValueError: invalid parameter """ @@ -96,7 +99,8 @@ def __init__(self, operator: BaseOperator, var_form: VariationalForm, num_particles)) super().__init__(operator.copy(), var_form, optimizer, initial_point=initial_point, max_evals_grouped=max_evals_grouped, aux_operators=aux_operators, - callback=callback, auto_conversion=auto_conversion) + callback=callback, auto_conversion=auto_conversion, + quantum_instance=quantum_instance) self.qeom = QEquationOfMotion(operator, num_orbitals, num_particles, qubit_mapping, two_qubit_reduction, active_occupied, diff --git a/qiskit/chemistry/algorithms/minimum_eigen_solvers/vqe_adapt.py b/qiskit/chemistry/algorithms/minimum_eigen_solvers/vqe_adapt.py index 82ca2f6d06..fbc995dc51 100644 --- a/qiskit/chemistry/algorithms/minimum_eigen_solvers/vqe_adapt.py +++ b/qiskit/chemistry/algorithms/minimum_eigen_solvers/vqe_adapt.py @@ -16,14 +16,15 @@ An adaptive VQE implementation. """ -from typing import Optional, List +from typing import Optional, List, Union import logging import warnings import re import numpy as np +from qiskit.providers import BaseBackend from qiskit import ClassicalRegister -from qiskit.aqua import AquaError +from qiskit.aqua import QuantumInstance, AquaError from qiskit.aqua.algorithms import VQAlgorithm, VQE, VQEResult from qiskit.chemistry.components.variational_forms import UCCSD from qiskit.aqua.operators import TPBGroupedWeightedPauliOperator, WeightedPauliOperator @@ -50,7 +51,8 @@ def __init__(self, operator: BaseOperator, excitation_pool: Optional[List[WeightedPauliOperator]] = None, threshold: float = 1e-5, delta: float = 1, max_evals_grouped: int = 1, - aux_operators: Optional[List[BaseOperator]] = None) -> None: + aux_operators: Optional[List[BaseOperator]] = None, + quantum_instance: Optional[Union[QuantumInstance, BaseBackend]] = None) -> None: """ Args: operator: Qubit operator @@ -62,8 +64,8 @@ def __init__(self, operator: BaseOperator, delta: finite difference step size for gradient computation, has a min. value of 1e-5. max_evals_grouped: max number of evaluations performed simultaneously - aux_operators: Auxiliary operators to be evaluated - at each eigenvalue + aux_operators: Auxiliary operators to be evaluated at each eigenvalue + quantum_instance: Quantum Instance or Backend Raises: ValueError: if var_form_base is not an instance of UCCSD. @@ -73,7 +75,8 @@ def __init__(self, operator: BaseOperator, validate_min('delta', delta, 1e-5) super().__init__(var_form=var_form_base, optimizer=optimizer, - initial_point=initial_point) + initial_point=initial_point, + quantum_instance=quantum_instance) self._use_simulator_snapshot_mode = None self._ret = None self._optimizer.set_max_evals_grouped(max_evals_grouped) From 0b3342db7e0e51bd1a920a1f04840cd86e59fa39 Mon Sep 17 00:00:00 2001 From: Manoel Marques Date: Wed, 25 Mar 2020 18:41:04 -0400 Subject: [PATCH 2/3] make pylintrc the same as terra's --- .pylintrc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.pylintrc b/.pylintrc index 6040fbfed6..a8d0c79e1f 100644 --- a/.pylintrc +++ b/.pylintrc @@ -72,7 +72,8 @@ disable=no-self-use, # disabled as it is too verbose too-many-public-methods, too-few-public-methods, too-many-ancestors, unnecessary-pass, # allow for methods with just "pass", for clarity no-else-return, # relax "elif" after a clause with a return - docstring-first-line-empty # relax docstring style + docstring-first-line-empty, # relax docstring style + import-outside-toplevel @@ -119,7 +120,7 @@ evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / stateme # op = operation iterator # b = basis iterator good-names=i,j,k,n,m,ex,v,w,x,y,z,Run,_,logger,q,c,r,qr,cr,qc,nd,pi,op,b,ar,br, - __unittest + __unittest,iSwapGate # Bad variable names which should always be refused, separated by a comma bad-names=foo,bar,toto,tutu,tata @@ -172,7 +173,7 @@ attr-rgx=[a-z_][a-z0-9_]{2,30}$ attr-name-hint=[a-z_][a-z0-9_]{2,30}$ # Regular expression matching correct argument names -argument-rgx=[a-z_][a-z0-9_]{2,30}$ +argument-rgx=[a-z_][a-z0-9_]{2,30}|ax|dt$ # Naming hint for argument names argument-name-hint=[a-z_][a-z0-9_]{2,30}$ @@ -297,7 +298,7 @@ ignore-mixin-members=yes # (useful for modules/projects where namespaces are manipulated during runtime # and thus existing member attributes cannot be deduced by static analysis. It # supports qualified module names, as well as Unix pattern matching. -ignored-modules=matplotlib.cm,numpy.random +ignored-modules=matplotlib.cm,numpy.random,retworkx # List of class names for which member attributes should not be checked (useful # for classes with dynamically set attributes). This supports the use of From 8582021ed2120e6c51adc7c1311a45cfe117f979 Mon Sep 17 00:00:00 2001 From: Manoel Marques Date: Thu, 26 Mar 2020 07:38:09 -0400 Subject: [PATCH 3/3] Add QuantumInstance/Backend to algorithm init --- qiskit/aqua/algorithms/amplitude_estimators/ae.py | 9 ++++++--- .../algorithms/amplitude_estimators/ae_algorithm.py | 12 ++++++++++-- qiskit/aqua/algorithms/amplitude_estimators/iqae.py | 9 ++++++--- qiskit/aqua/algorithms/amplitude_estimators/mlae.py | 9 ++++++--- qiskit/aqua/algorithms/classifiers/vqc.py | 13 ++++++++----- 5 files changed, 36 insertions(+), 16 deletions(-) diff --git a/qiskit/aqua/algorithms/amplitude_estimators/ae.py b/qiskit/aqua/algorithms/amplitude_estimators/ae.py index 2695f30b30..adb3c3bf85 100644 --- a/qiskit/aqua/algorithms/amplitude_estimators/ae.py +++ b/qiskit/aqua/algorithms/amplitude_estimators/ae.py @@ -21,7 +21,8 @@ from scipy.optimize import bisect from qiskit import QuantumCircuit -from qiskit.aqua import AquaError +from qiskit.providers import BaseBackend +from qiskit.aqua import QuantumInstance, AquaError from qiskit.aqua.utils import CircuitFactory from qiskit.aqua.circuits import PhaseEstimationCircuit from qiskit.aqua.components.iqfts import IQFT, Standard @@ -53,7 +54,8 @@ def __init__(self, num_eval_qubits: int, a_factory: Optional[CircuitFactory] = None, q_factory: Optional[CircuitFactory] = None, i_objective: Optional[int] = None, - iqft: Optional[IQFT] = None) -> None: + iqft: Optional[IQFT] = None, + quantum_instance: Optional[Union[QuantumInstance, BaseBackend]] = None) -> None: r""" Args: num_eval_qubits: Number of evaluation qubits, has a min. value of 1. @@ -64,9 +66,10 @@ def __init__(self, num_eval_qubits: int, with the state \|1> and 'bad' solutions with the state \|0>. iqft: The Inverse Quantum Fourier Transform component, defaults to using a standard IQFT when None + quantum_instance: Quantum Instance or Backend """ validate_min('num_eval_qubits', num_eval_qubits, 1) - super().__init__(a_factory, q_factory, i_objective) + super().__init__(a_factory, q_factory, i_objective, quantum_instance) # get parameters self._m = num_eval_qubits diff --git a/qiskit/aqua/algorithms/amplitude_estimators/ae_algorithm.py b/qiskit/aqua/algorithms/amplitude_estimators/ae_algorithm.py index 0003ef68a0..baba28e085 100644 --- a/qiskit/aqua/algorithms/amplitude_estimators/ae_algorithm.py +++ b/qiskit/aqua/algorithms/amplitude_estimators/ae_algorithm.py @@ -51,9 +51,17 @@ class AmplitudeEstimationAlgorithm(QuantumAlgorithm): @abstractmethod def __init__(self, a_factory: Optional[CircuitFactory] = None, - q_factory=None, - i_objective=None, + q_factory: Optional[CircuitFactory] = None, + i_objective: Optional[int] = None, quantum_instance: Optional[Union[QuantumInstance, BaseBackend]] = None) -> None: + """ + Args: + a_factory: The A operator, specifying the QAE problem + q_factory: The Q operator (Grover operator), constructed from the + A operator + i_objective: Index of the objective qubit, that marks the 'good/bad' states + quantum_instance: Quantum Instance or Backend + """ self._a_factory = a_factory self._q_factory = q_factory self._i_objective = i_objective diff --git a/qiskit/aqua/algorithms/amplitude_estimators/iqae.py b/qiskit/aqua/algorithms/amplitude_estimators/iqae.py index 86f62a39e1..1b42868cc0 100644 --- a/qiskit/aqua/algorithms/amplitude_estimators/iqae.py +++ b/qiskit/aqua/algorithms/amplitude_estimators/iqae.py @@ -20,7 +20,8 @@ from scipy.stats import beta from qiskit import ClassicalRegister, QuantumRegister, QuantumCircuit -from qiskit.aqua import AquaError +from qiskit.providers import BaseBackend +from qiskit.aqua import QuantumInstance, AquaError from qiskit.aqua.utils.circuit_factory import CircuitFactory from qiskit.aqua.utils.validation import validate_range, validate_in_set @@ -47,7 +48,8 @@ def __init__(self, epsilon: float, alpha: float, confint_method: str = 'beta', min_ratio: float = 2, a_factory: Optional[CircuitFactory] = None, q_factory: Optional[CircuitFactory] = None, - i_objective: Optional[int] = None) -> None: + i_objective: Optional[int] = None, + quantum_instance: Optional[Union[QuantumInstance, BaseBackend]] = None) -> None: """ The output of the algorithm is an estimate for the amplitude `a`, that with at least probability 1 - alpha has an error of epsilon. The number of A operator calls scales @@ -64,6 +66,7 @@ def __init__(self, epsilon: float, alpha: float, q_factory: The Q operator (Grover operator), constructed from the A operator i_objective: Index of the objective qubit, that marks the 'good/bad' states + quantum_instance: Quantum Instance or Backend Raises: AquaError: if the method to compute the confidence intervals is not supported @@ -73,7 +76,7 @@ def __init__(self, epsilon: float, alpha: float, validate_range('alpha', alpha, 0, 1) validate_in_set('confint_method', confint_method, {'chernoff', 'beta'}) - super().__init__(a_factory, q_factory, i_objective) + super().__init__(a_factory, q_factory, i_objective, quantum_instance) # store parameters self._epsilon = epsilon diff --git a/qiskit/aqua/algorithms/amplitude_estimators/mlae.py b/qiskit/aqua/algorithms/amplitude_estimators/mlae.py index 6b0a277852..a32a804de9 100644 --- a/qiskit/aqua/algorithms/amplitude_estimators/mlae.py +++ b/qiskit/aqua/algorithms/amplitude_estimators/mlae.py @@ -19,8 +19,9 @@ from scipy.optimize import brute from scipy.stats import norm, chi2 +from qiskit.providers import BaseBackend from qiskit import ClassicalRegister, QuantumRegister, QuantumCircuit -from qiskit.aqua import AquaError +from qiskit.aqua import QuantumInstance, AquaError from qiskit.aqua.utils.circuit_factory import CircuitFactory from qiskit.aqua.utils.validation import validate_min from .ae_algorithm import AmplitudeEstimationAlgorithm @@ -45,7 +46,8 @@ def __init__(self, num_oracle_circuits: int, a_factory: Optional[CircuitFactory] = None, q_factory: Optional[CircuitFactory] = None, i_objective: Optional[int] = None, - likelihood_evals: Optional[int] = None) -> None: + likelihood_evals: Optional[int] = None, + quantum_instance: Optional[Union[QuantumInstance, BaseBackend]] = None) -> None: r""" Args: num_oracle_circuits: The number of circuits applying different powers of the Grover @@ -60,9 +62,10 @@ def __init__(self, num_oracle_circuits: int, with the state \|1> and 'bad' solutions with the state \|0> likelihood_evals: The number of gridpoints for the maximum search of the likelihood function + quantum_instance: Quantum Instance or Backend """ validate_min('num_oracle_circuits', num_oracle_circuits, 1) - super().__init__(a_factory, q_factory, i_objective) + super().__init__(a_factory, q_factory, i_objective, quantum_instance) # get parameters self._evaluation_schedule = [0] + [2**j for j in range(num_oracle_circuits)] diff --git a/qiskit/aqua/algorithms/classifiers/vqc.py b/qiskit/aqua/algorithms/classifiers/vqc.py index 916e19d968..f11d054b69 100644 --- a/qiskit/aqua/algorithms/classifiers/vqc.py +++ b/qiskit/aqua/algorithms/classifiers/vqc.py @@ -14,7 +14,7 @@ """ The Variational Quantum Classifier algorithm """ -from typing import Optional, Callable, Dict +from typing import Optional, Callable, Dict, Union import logging import math import numpy as np @@ -23,7 +23,8 @@ from qiskit import ClassicalRegister, QuantumCircuit, QuantumRegister from qiskit.circuit import ParameterVector -from qiskit.aqua import AquaError +from qiskit.providers import BaseBackend +from qiskit.aqua import QuantumInstance, AquaError from qiskit.aqua.utils import map_label_to_class_name from qiskit.aqua.utils import split_dataset_to_data_and_labels from qiskit.aqua.algorithms import VQAlgorithm @@ -56,8 +57,8 @@ def __init__( datapoints: Optional[np.ndarray] = None, max_evals_grouped: int = 1, minibatch_size: int = -1, - callback: Optional[Callable[[int, np.ndarray, float, int], None]] = None - ) -> None: + callback: Optional[Callable[[int, np.ndarray, float, int], None]] = None, + quantum_instance: Optional[Union[QuantumInstance, BaseBackend]] = None) -> None: """ Args: optimizer: The classical optimizer to use. @@ -73,6 +74,7 @@ def __init__( Four parameter values are passed to the callback as follows during each evaluation. These are: the evaluation count, parameters of the variational form, the evaluated value, the index of data batch. + quantum_instance: Quantum Instance or Backend Note: We use `label` to denotes numeric results and `class` the class names (str). Raises: @@ -81,7 +83,8 @@ def __init__( super().__init__( var_form=var_form, optimizer=optimizer, - cost_fn=self._cost_function_wrapper + cost_fn=self._cost_function_wrapper, + quantum_instance=quantum_instance ) self._batches = None self._label_batches = None