From 2b3ea47dbb7571e2677811bcae74de3b702fe919 Mon Sep 17 00:00:00 2001 From: Cryoris Date: Fri, 3 Apr 2020 15:33:52 +0200 Subject: [PATCH 01/12] use QFT from circuit lib --- .../circuits/fourier_transform_circuits.py | 58 ++++--------------- 1 file changed, 10 insertions(+), 48 deletions(-) diff --git a/qiskit/aqua/circuits/fourier_transform_circuits.py b/qiskit/aqua/circuits/fourier_transform_circuits.py index 7069048520..60cb5c8cdb 100644 --- a/qiskit/aqua/circuits/fourier_transform_circuits.py +++ b/qiskit/aqua/circuits/fourier_transform_circuits.py @@ -15,10 +15,9 @@ Quantum Fourier Transform Circuit. """ -import numpy as np - -from qiskit.circuit import QuantumRegister, QuantumCircuit, Qubit # pylint: disable=unused-import +import warnings +from qiskit.circuit.library import QFT from qiskit.aqua import AquaError @@ -26,14 +25,6 @@ class FourierTransformCircuits: """ Quantum Fourier Transform Circuit. """ - @staticmethod - def _do_swaps(circuit, qubits): - num_qubits = len(qubits) - for i in range(num_qubits // 2): - circuit.cx(qubits[i], qubits[num_qubits - i - 1]) - circuit.cx(qubits[num_qubits - i - 1], qubits[i]) - circuit.cx(qubits[i], qubits[num_qubits - i - 1]) - @staticmethod def construct_circuit( circuit=None, @@ -60,6 +51,10 @@ def construct_circuit( Raises: AquaError: invalid input """ + warnings.warn('The class FourierTransformCircuits is deprecated and will be removed ' + 'no earlier than 3 months after the release 0.7.0. You should use the ' + 'qiskit.circuit.library.QFT class instead.', + DeprecationWarning, stacklevel=2) if circuit is None: raise AquaError('Missing input QuantumCircuit.') @@ -67,43 +62,10 @@ def construct_circuit( if qubits is None: raise AquaError('Missing input qubits.') - if isinstance(qubits, QuantumRegister): - if not circuit.has_register(qubits): - circuit.add_register(qubits) - elif isinstance(qubits, list): - for qubit in qubits: - if isinstance(qubit, Qubit): - if not circuit.has_register(qubit.register): - circuit.add_register(qubit.register) - else: - raise AquaError('A QuantumRegister or a list of qubits ' - 'is expected for the input qubits.') - else: - raise AquaError('A QuantumRegister or a list of qubits ' - 'is expected for the input qubits.') - - if do_swaps and not inverse: - FourierTransformCircuits._do_swaps(circuit, qubits) - - qubit_range = reversed(range(len(qubits))) if inverse else range(len(qubits)) - for j in qubit_range: - neighbor_range = range(np.max([0, j - len(qubits) + approximation_degree + 1]), j) - if inverse: - neighbor_range = reversed(neighbor_range) - circuit.u2(0, np.pi, qubits[j]) - for k in neighbor_range: - lam = 1.0 * np.pi / float(2 ** (j - k)) - if inverse: - lam *= -1 - circuit.u1(lam / 2, qubits[j]) - circuit.cx(qubits[j], qubits[k]) - circuit.u1(-lam / 2, qubits[k]) - circuit.cx(qubits[j], qubits[k]) - circuit.u1(lam / 2, qubits[k]) - if not inverse: - circuit.u2(0, np.pi, qubits[j]) + qft = QFT(len(qubits), approximation_degree=approximation_degree, do_swaps=do_swaps) + if inverse: + qft = qft.inverse() - if do_swaps and inverse: - FourierTransformCircuits._do_swaps(circuit, qubits) + circuit.append(qft.to_instruction(), qubits) return circuit From 55aceff34a751094cfeb339aad353dec47bd1ee7 Mon Sep 17 00:00:00 2001 From: Cryoris Date: Tue, 21 Apr 2020 19:29:45 +0200 Subject: [PATCH 02/12] make algos accept circuits + QFTs --- .../aqua/algorithms/amplitude_estimators/ae.py | 11 +++++------ .../algorithms/minimum_eigen_solvers/qpe.py | 7 +++---- .../aqua/circuits/phase_estimation_circuit.py | 17 +++++++++-------- qiskit/aqua/components/eigs/eigs_qpe.py | 7 +++---- 4 files changed, 20 insertions(+), 22 deletions(-) diff --git a/qiskit/aqua/algorithms/amplitude_estimators/ae.py b/qiskit/aqua/algorithms/amplitude_estimators/ae.py index adb3c3bf85..50639c7cc9 100644 --- a/qiskit/aqua/algorithms/amplitude_estimators/ae.py +++ b/qiskit/aqua/algorithms/amplitude_estimators/ae.py @@ -11,6 +11,7 @@ # 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 Quantum Phase Estimation-based Amplitude Estimation algorithm.""" from typing import Optional, Union, List, Tuple @@ -21,11 +22,12 @@ from scipy.optimize import bisect from qiskit import QuantumCircuit +from qiskit.circuit.library import QFT 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 +from qiskit.aqua.components.iqfts import IQFT from qiskit.aqua.utils.validation import validate_min from .ae_algorithm import AmplitudeEstimationAlgorithm from .ae_utils import pdf_a, derivative_log_pdf_a, bisect_max @@ -54,7 +56,7 @@ 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, + iqft: Optional[QuantumCircuit, IQFT] = None, quantum_instance: Optional[Union[QuantumInstance, BaseBackend]] = None) -> None: r""" Args: @@ -75,10 +77,7 @@ def __init__(self, num_eval_qubits: int, self._m = num_eval_qubits self._M = 2 ** num_eval_qubits - if iqft is None: - iqft = Standard(self._m) - - self._iqft = iqft + self._iqft = iqft or QFT(self._m).inverse() self._circuit = None self._ret = {} diff --git a/qiskit/aqua/algorithms/minimum_eigen_solvers/qpe.py b/qiskit/aqua/algorithms/minimum_eigen_solvers/qpe.py index 842cc23869..3da00de888 100644 --- a/qiskit/aqua/algorithms/minimum_eigen_solvers/qpe.py +++ b/qiskit/aqua/algorithms/minimum_eigen_solvers/qpe.py @@ -11,9 +11,8 @@ # 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 Quantum Phase Estimation Algorithm. -""" + +"""The Quantum Phase Estimation Algorithm.""" import logging from typing import Optional, List, Dict, Union @@ -60,7 +59,7 @@ class QPEMinimumEigensolver(QuantumAlgorithm, MinimumEigensolver): def __init__(self, operator: Optional[BaseOperator] = None, state_in: Optional[InitialState] = None, - iqft: Optional[IQFT] = None, + iqft: Optional[QuantumCircuit, IQFT] = None, num_time_slices: int = 1, num_ancillae: int = 1, expansion_mode: str = 'trotter', diff --git a/qiskit/aqua/circuits/phase_estimation_circuit.py b/qiskit/aqua/circuits/phase_estimation_circuit.py index d9883a1e04..e7b532b343 100644 --- a/qiskit/aqua/circuits/phase_estimation_circuit.py +++ b/qiskit/aqua/circuits/phase_estimation_circuit.py @@ -11,9 +11,8 @@ # 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. -""" -Quantum Phase Estimation Circuit. -""" + +"""Quantum Phase Estimation Circuit.""" import numpy as np @@ -26,9 +25,7 @@ class PhaseEstimationCircuit: - """ - Quantum Phase Estimation Circuit. - """ + """Quantum Phase Estimation Circuit.""" def __init__( self, @@ -52,7 +49,8 @@ def __init__( operator (WeightedPauliOperator): the hamiltonian Operator object state_in (InitialState): the InitialState component representing the initial quantum state - iqft (IQFT): the Inverse Quantum Fourier Transform component + iqft (Union[QuantumCircuit, IQFT]): the Inverse Quantum Fourier Transform as circuit or + Aqua component num_time_slices (int): the number of time slices num_ancillae (int): the number of ancillary qubits to use for the measurement expansion_mode (str): the expansion mode (trotter|suzuki) @@ -209,7 +207,10 @@ def construct_circuit( self._unitary_circuit_factory.build_controlled_power(qc, q, a[i], 2 ** i, aux) # inverse qft on ancillae - self._iqft.construct_circuit(mode='circuit', qubits=a, circuit=qc, do_swaps=False) + if isinstance(self._iqft, QuantumCircuit): + qc.append(self._iqft.to_instruction(), a) + else: + self._iqft.construct_circuit(mode='circuit', qubits=a, circuit=qc, do_swaps=False) if measurement: c_ancilla = ClassicalRegister(self._num_ancillae, name='ca') diff --git a/qiskit/aqua/components/eigs/eigs_qpe.py b/qiskit/aqua/components/eigs/eigs_qpe.py index f0f6f207d3..19bce52a7c 100644 --- a/qiskit/aqua/components/eigs/eigs_qpe.py +++ b/qiskit/aqua/components/eigs/eigs_qpe.py @@ -12,7 +12,7 @@ # copyright notice, and modified files need to carry a notice indicating # that they have been altered from the originals. -""" Quantum Phase Estimation for getting the eigenvalues of a matrix. """ +"""Quantum Phase Estimation for getting the eigenvalues of a matrix.""" from typing import Optional, List import numpy as np @@ -28,8 +28,7 @@ class EigsQPE(Eigenvalues): - """ - Eigenvalues using Quantum Phase Estimation + """Eigenvalues using Quantum Phase Estimation. Specifically, this class is based on PhaseEstimationCircuit with no measurements and has additional handling of negative eigenvalues, e.g. for :class:`~qiskit.aqua.algorithms.HHL`. @@ -39,7 +38,7 @@ class EigsQPE(Eigenvalues): def __init__(self, operator: BaseOperator, - iqft: IQFT, + iqft: Union[QuantumCircuit, IQFT], num_time_slices: int = 1, num_ancillae: int = 1, expansion_mode: str = 'trotter', From ce684e30394a94e431230fd1f6813753e2b23f16 Mon Sep 17 00:00:00 2001 From: Cryoris Date: Tue, 21 Apr 2020 19:36:57 +0200 Subject: [PATCH 03/12] deprecate QFT circ and components --- .../circuits/fourier_transform_circuits.py | 15 +++++------ qiskit/aqua/components/eigs/eigs_qpe.py | 4 +-- qiskit/aqua/components/iqfts/iqft.py | 26 +++++++----------- qiskit/aqua/components/qfts/qft.py | 27 +++++++------------ qiskit/aqua/components/qfts/standard.py | 3 +-- 5 files changed, 29 insertions(+), 46 deletions(-) diff --git a/qiskit/aqua/circuits/fourier_transform_circuits.py b/qiskit/aqua/circuits/fourier_transform_circuits.py index 60cb5c8cdb..7f006596b2 100644 --- a/qiskit/aqua/circuits/fourier_transform_circuits.py +++ b/qiskit/aqua/circuits/fourier_transform_circuits.py @@ -2,7 +2,7 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2019. +# (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 @@ -11,9 +11,8 @@ # 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. -""" -Quantum Fourier Transform Circuit. -""" + +"""DEPRECATED. Quantum Fourier Transform Circuit.""" import warnings @@ -22,9 +21,8 @@ class FourierTransformCircuits: - """ - Quantum Fourier Transform Circuit. - """ + """DEPRECATED. Quantum Fourier Transform Circuit.""" + @staticmethod def construct_circuit( circuit=None, @@ -33,8 +31,7 @@ def construct_circuit( approximation_degree=0, do_swaps=True ): - """ - Construct the circuit representing the desired state vector. + """Construct the circuit representing the desired state vector. Args: circuit (QuantumCircuit): The optional circuit to extend from. diff --git a/qiskit/aqua/components/eigs/eigs_qpe.py b/qiskit/aqua/components/eigs/eigs_qpe.py index 19bce52a7c..5166d96bd7 100644 --- a/qiskit/aqua/components/eigs/eigs_qpe.py +++ b/qiskit/aqua/components/eigs/eigs_qpe.py @@ -14,9 +14,9 @@ """Quantum Phase Estimation for getting the eigenvalues of a matrix.""" -from typing import Optional, List +from typing import Optional, List, Union import numpy as np -from qiskit import QuantumRegister +from qiskit import QuantumRegister, QuantumCircuit from qiskit.aqua.circuits import PhaseEstimationCircuit from qiskit.aqua.operators import op_converter, BaseOperator diff --git a/qiskit/aqua/components/iqfts/iqft.py b/qiskit/aqua/components/iqfts/iqft.py index 45d0eacbd5..03e11096df 100644 --- a/qiskit/aqua/components/iqfts/iqft.py +++ b/qiskit/aqua/components/iqfts/iqft.py @@ -11,10 +11,12 @@ # 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 inverse quantum fourier transforms. + +"""DEPRECATED. This module contains the definition of a base class for inverse quantum fourier +transforms. """ +import warnings from abc import ABC, abstractmethod from qiskit import QuantumRegister, QuantumCircuit # pylint: disable=unused-import @@ -23,21 +25,13 @@ class IQFT(ABC): + """DEPRECATED. Base class for IQFT.""" - """Base class for Inverse QFT. - - This method should initialize the module and - use an exception if a component of the module is not - available. - - Args: - args (list): args - kwargs (list): kwargs - """ - - @abstractmethod - def __init__(self, *args, **kwargs) -> None: - super().__init__() + def __init__(self): + warnings.warn('The class qiskit.aqua.components.iqfts.IQFT is deprecated and will be ' + 'removed no earlier than 3 months after the release 0.7.0. You should use the' + ' qiskit.circuit.library.QFT class instead and its .inverse().', + DeprecationWarning, stacklevel=2) @abstractmethod def _build_matrix(self): diff --git a/qiskit/aqua/components/qfts/qft.py b/qiskit/aqua/components/qfts/qft.py index e7b359b56f..1f5f4984ca 100644 --- a/qiskit/aqua/components/qfts/qft.py +++ b/qiskit/aqua/components/qfts/qft.py @@ -2,7 +2,7 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2018, 2019. +# (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 @@ -11,10 +11,11 @@ # 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 quantum fourier transforms. + +"""DEPRECATED. This module contains the definition of a base class for quantum fourier transforms. """ +import warnings from abc import ABC, abstractmethod from qiskit import QuantumRegister, QuantumCircuit # pylint: disable=unused-import @@ -23,21 +24,13 @@ class QFT(ABC): + """DEPRECATED. Base class for QFT.""" - """Base class for QFT. - - This method should initialize the module and - use an exception if a component of the module is not - available. - - Args: - args (list): args - kwargs (dict): kwargs - """ - - @abstractmethod - def __init__(self, *args, **kwargs): - super().__init__() + def __init__(self): + warnings.warn('The class qiskit.aqua.components.qfts.QFT is deprecated and will be removed ' + 'no earlier than 3 months after the release 0.7.0. You should use the ' + 'qiskit.circuit.library.QFT class instead.', + DeprecationWarning, stacklevel=2) @abstractmethod def _build_matrix(self): diff --git a/qiskit/aqua/components/qfts/standard.py b/qiskit/aqua/components/qfts/standard.py index f96e783acb..0f28aaaedd 100644 --- a/qiskit/aqua/components/qfts/standard.py +++ b/qiskit/aqua/components/qfts/standard.py @@ -21,8 +21,7 @@ class Standard(Approximate): - """ - The Standard QFT. + """The Standard QFT. This is a standard Quantum Fourier Transform """ From c9607e5d20f6b99ef16de291eb1623b99e7963e3 Mon Sep 17 00:00:00 2001 From: Cryoris Date: Tue, 21 Apr 2020 22:08:50 +0200 Subject: [PATCH 04/12] allow QFT to be passed as circuit --- .../algorithms/amplitude_estimators/ae.py | 2 +- .../algorithms/minimum_eigen_solvers/qpe.py | 2 +- .../aqua/circuits/phase_estimation_circuit.py | 4 +++ qiskit/aqua/components/eigs/eigs_qpe.py | 14 ++++++-- test/aqua/test_hhl.py | 32 +++++++++++++------ test/aqua/test_qpe.py | 17 +++++++--- test/chemistry/test_end2end_with_qpe.py | 18 +++++++---- 7 files changed, 63 insertions(+), 26 deletions(-) diff --git a/qiskit/aqua/algorithms/amplitude_estimators/ae.py b/qiskit/aqua/algorithms/amplitude_estimators/ae.py index 50639c7cc9..b9eb65ccda 100644 --- a/qiskit/aqua/algorithms/amplitude_estimators/ae.py +++ b/qiskit/aqua/algorithms/amplitude_estimators/ae.py @@ -56,7 +56,7 @@ def __init__(self, num_eval_qubits: int, a_factory: Optional[CircuitFactory] = None, q_factory: Optional[CircuitFactory] = None, i_objective: Optional[int] = None, - iqft: Optional[QuantumCircuit, IQFT] = None, + iqft: Optional[Union[QuantumCircuit, IQFT]] = None, quantum_instance: Optional[Union[QuantumInstance, BaseBackend]] = None) -> None: r""" Args: diff --git a/qiskit/aqua/algorithms/minimum_eigen_solvers/qpe.py b/qiskit/aqua/algorithms/minimum_eigen_solvers/qpe.py index 3da00de888..92fb8a863e 100644 --- a/qiskit/aqua/algorithms/minimum_eigen_solvers/qpe.py +++ b/qiskit/aqua/algorithms/minimum_eigen_solvers/qpe.py @@ -59,7 +59,7 @@ class QPEMinimumEigensolver(QuantumAlgorithm, MinimumEigensolver): def __init__(self, operator: Optional[BaseOperator] = None, state_in: Optional[InitialState] = None, - iqft: Optional[QuantumCircuit, IQFT] = None, + iqft: Optional[Union[QuantumCircuit, IQFT]] = None, num_time_slices: int = 1, num_ancillae: int = 1, expansion_mode: str = 'trotter', diff --git a/qiskit/aqua/circuits/phase_estimation_circuit.py b/qiskit/aqua/circuits/phase_estimation_circuit.py index e7b532b343..c07042e7c0 100644 --- a/qiskit/aqua/circuits/phase_estimation_circuit.py +++ b/qiskit/aqua/circuits/phase_estimation_circuit.py @@ -208,6 +208,10 @@ def construct_circuit( # inverse qft on ancillae if isinstance(self._iqft, QuantumCircuit): + if hasattr(self._iqft, 'do_swaps'): + self._iqft.do_swaps = False + # TODO make the IQFT not revert to QFT is do_swaps is called + self._iqft = self._iqft.inverse() qc.append(self._iqft.to_instruction(), a) else: self._iqft.construct_circuit(mode='circuit', qubits=a, circuit=qc, do_swaps=False) diff --git a/qiskit/aqua/components/eigs/eigs_qpe.py b/qiskit/aqua/components/eigs/eigs_qpe.py index 5166d96bd7..51d2345ad0 100644 --- a/qiskit/aqua/components/eigs/eigs_qpe.py +++ b/qiskit/aqua/components/eigs/eigs_qpe.py @@ -144,11 +144,21 @@ def construct_circuit(self, mode, register=None): return self._circuit def _handle_negative_evals(self, qc, q): + def apply_ne_qft(ne_qft, inverse=False): # TODO remove inverse once bug with IQFT fixed + if isinstance(ne_qft, QuantumCircuit): + if hasattr(ne_qft, 'do_swaps'): + ne_qft.do_swaps = False + if inverse: + ne_qft = ne_qft.inverse() + qc.append(ne_qft.to_instruction(), qs) + else: + ne_qft.construct_circuit(mode='circuit', qubits=qs, circuit=qc, do_swaps=False) + sgn = q[0] qs = [q[i] for i in range(1, len(q))] for qi in qs: qc.cx(sgn, qi) - self._ne_qfts[0].construct_circuit(mode='circuit', qubits=qs, circuit=qc, do_swaps=False) + apply_ne_qft(self._ne_qfts[0]) for i, qi in enumerate(reversed(qs)): qc.cu1(2*np.pi/2**(i+1), sgn, qi) - self._ne_qfts[1].construct_circuit(mode='circuit', qubits=qs, circuit=qc, do_swaps=False) + apply_ne_qft(self._ne_qfts[1], inverse=True) diff --git a/test/aqua/test_hhl.py b/test/aqua/test_hhl.py index 1fa7ce891d..e144e57b30 100644 --- a/test/aqua/test_hhl.py +++ b/test/aqua/test_hhl.py @@ -18,10 +18,12 @@ from test.aqua import QiskitAquaTestCase import numpy as np -from ddt import ddt, idata, unpack +from ddt import ddt, idata, data, unpack from qiskit import BasicAer from qiskit.quantum_info import state_fidelity +from qiskit.circuit.library import QFT + from qiskit.aqua import aqua_globals, QuantumInstance from qiskit.aqua.algorithms import HHL, NumPyLSsolver from qiskit.aqua.utils import random_matrix_generator as rmg @@ -43,15 +45,23 @@ def setUp(self): aqua_globals.random_seed = self.random_seed @staticmethod - def _create_eigs(matrix, num_ancillae, negative_evals): + def _create_eigs(matrix, num_ancillae, negative_evals, use_circuit_library=True): # Adding an additional flag qubit for negative eigenvalues ne_qfts = [None, None] if negative_evals: num_ancillae += 1 - ne_qfts = [StandardQFTS(num_ancillae - 1), StandardIQFTS(num_ancillae - 1)] + if use_circuit_library: + ne_qfts = [QFT(num_ancillae - 1), QFT(num_ancillae - 1).inverse()] + else: + ne_qfts = [StandardQFTS(num_ancillae - 1), StandardIQFTS(num_ancillae - 1)] + + if use_circuit_library: + iqft = QFT(num_ancillae).inverse() + else: + iqft = StandardIQFTS(num_ancillae) return EigsQPE(MatrixOperator(matrix=matrix), - StandardIQFTS(num_ancillae), + iqft, num_time_slices=1, num_ancillae=num_ancillae, expansion_mode='suzuki', @@ -60,9 +70,10 @@ def _create_eigs(matrix, num_ancillae, negative_evals): negative_evals=negative_evals, ne_qfts=ne_qfts) - @idata([[[0, 1]], [[1, 0]], [[1, 0.1]], [[1, 1]], [[1, 10]]]) + @data([[0, 1], False], [[1, 0], False], [[1, 0.1], False], [[1, 1], False], [[1, 10], False], + [[0, 1], True], [[1, 0], True], [[1, 0.1], True], [[1, 1], True], [[1, 10], True]) @unpack - def test_hhl_diagonal(self, vector): + def test_hhl_diagonal(self, vector, use_circuit_library): """ hhl diagonal test """ self.log.debug('Testing HHL simple test in mode Lookup with statevector simulator') @@ -78,7 +89,7 @@ def test_hhl_diagonal(self, vector): matrix, vector, truncate_powerdim, truncate_hermitian = HHL.matrix_resize(matrix, vector) # Initialize eigenvalue finding module - eigs = TestHHL._create_eigs(matrix, 3, False) + eigs = TestHHL._create_eigs(matrix, 3, False, use_circuit_library) num_q, num_a = eigs.get_register_sizes() # Initialize initial state module @@ -105,9 +116,10 @@ def test_hhl_diagonal(self, vector): self.log.debug('fidelity HHL to algebraic: %s', fidelity) self.log.debug('probability of result: %s', hhl_result["probability_result"]) - @idata([[[-1, 0]], [[0, -1]], [[-1, -1]]]) + @data([[-1, 0], False], [[0, -1], False], [[-1, -1], False], + [[-1, 0], True], [[0, -1], True], [[-1, -1], True]) @unpack - def test_hhl_diagonal_negative(self, vector): + def test_hhl_diagonal_negative(self, vector, use_circuit_library): """ hhl diagonal negative test """ self.log.debug('Testing HHL simple test in mode Lookup with statevector simulator') @@ -123,7 +135,7 @@ def test_hhl_diagonal_negative(self, vector): matrix, vector, truncate_powerdim, truncate_hermitian = HHL.matrix_resize(matrix, vector) # Initialize eigenvalue finding module - eigs = TestHHL._create_eigs(matrix, 4, True) + eigs = TestHHL._create_eigs(matrix, 4, True, use_circuit_library) num_q, num_a = eigs.get_register_sizes() # Initialize initial state module diff --git a/test/aqua/test_qpe.py b/test/aqua/test_qpe.py index f5e2286dc8..5fa31d8a45 100644 --- a/test/aqua/test_qpe.py +++ b/test/aqua/test_qpe.py @@ -24,6 +24,7 @@ from qiskit.aqua.utils import decimal_to_binary from qiskit.aqua.algorithms import NumPyMinimumEigensolver from qiskit.aqua.algorithms import QPEMinimumEigensolver +from qiskit.circuit.library import QFT from qiskit.aqua.components.iqfts import Standard from qiskit.aqua.components.initial_states import Custom @@ -59,12 +60,15 @@ class TestQPE(QiskitAquaTestCase): """QPE tests.""" @idata([ - [QUBIT_OP_SIMPLE, 'qasm_simulator', 1, 5], - [QUBIT_OP_ZZ, 'statevector_simulator', 1, 1], - [QUBIT_OP_H2_WITH_2_QUBIT_REDUCTION, 'statevector_simulator', 1, 6], + [QUBIT_OP_SIMPLE, 'qasm_simulator', 1, 5, False], + [QUBIT_OP_SIMPLE, 'qasm_simulator', 1, 5, True], + [QUBIT_OP_ZZ, 'statevector_simulator', 1, 1, False], + [QUBIT_OP_ZZ, 'statevector_simulator', 1, 1, True], + [QUBIT_OP_H2_WITH_2_QUBIT_REDUCTION, 'statevector_simulator', 1, 6, False], + [QUBIT_OP_H2_WITH_2_QUBIT_REDUCTION, 'statevector_simulator', 1, 6, True], ]) @unpack - def test_qpe(self, qubit_op, simulator, num_time_slices, n_ancillae): + def test_qpe(self, qubit_op, simulator, num_time_slices, n_ancillae, use_circuit_library): """ QPE test """ self.log.debug('Testing QPE') tmp_qubit_op = qubit_op.copy() @@ -77,7 +81,10 @@ def test_qpe(self, qubit_op, simulator, num_time_slices, n_ancillae): self.log.debug('The corresponding eigenvector: %s', ref_eigenvec) state_in = Custom(qubit_op.num_qubits, state_vector=ref_eigenvec) - iqft = Standard(n_ancillae) + if use_circuit_library: + iqft = QFT(n_ancillae).inverse() + else: + iqft = Standard(n_ancillae) qpe = QPEMinimumEigensolver(qubit_op, state_in, iqft, num_time_slices, n_ancillae, expansion_mode='suzuki', expansion_order=2, diff --git a/test/chemistry/test_end2end_with_qpe.py b/test/chemistry/test_end2end_with_qpe.py index 99d1f17d82..6e221333e8 100644 --- a/test/chemistry/test_end2end_with_qpe.py +++ b/test/chemistry/test_end2end_with_qpe.py @@ -16,9 +16,11 @@ import unittest from test.chemistry import QiskitChemistryTestCase +from itertools import product import numpy as np from ddt import ddt, idata, unpack import qiskit +from qiskit.circuit.library import QFT from qiskit.aqua.utils import decimal_to_binary from qiskit.aqua import QuantumInstance from qiskit.aqua.algorithms import QPEMinimumEigensolver, NumPyMinimumEigensolver @@ -33,13 +35,12 @@ class TestEnd2EndWithQPE(QiskitChemistryTestCase): """QPE tests.""" - @idata([ - [0.5], - [0.735], - [1], - ]) + @idata(list(product( + [0.5, 0.735, 1], + [False, True] + ))) @unpack - def test_qpe(self, distance): + def test_qpe(self, distance, use_circuit_library): """ qpe test """ self.log.debug('Testing End-to-End with QPE on ' 'H2 with inter-atomic distance %s.', distance) @@ -73,7 +74,10 @@ def test_qpe(self, distance): state_in = HartreeFock(qubit_op.num_qubits, num_orbitals, num_particles, qubit_mapping, two_qubit_reduction) - iqft = Standard(n_ancillae) + if use_circuit_library: + iqft = QFT(n_ancillae).inverse() + else: + iqft = Standard(n_ancillae) qpe = QPEMinimumEigensolver(qubit_op, state_in, iqft, num_time_slices, n_ancillae, expansion_mode='suzuki', From bcdfe769e300ddd3109aed008085fe8bd9dccc3a Mon Sep 17 00:00:00 2001 From: Cryoris Date: Tue, 21 Apr 2020 22:31:35 +0200 Subject: [PATCH 05/12] add deprecation warnings if QFT component used --- .../algorithms/amplitude_estimators/ae.py | 6 ++++++ qiskit/aqua/algorithms/linear_solvers/hhl.py | 9 +++------ .../algorithms/minimum_eigen_solvers/qpe.py | 8 ++++++++ .../aqua/circuits/phase_estimation_circuit.py | 17 ++++++++++++---- qiskit/aqua/components/eigs/eigs_qpe.py | 17 ++++++++++++++++ test/aqua/test_amplitude_estimation.py | 20 +++++++++++++------ 6 files changed, 61 insertions(+), 16 deletions(-) diff --git a/qiskit/aqua/algorithms/amplitude_estimators/ae.py b/qiskit/aqua/algorithms/amplitude_estimators/ae.py index b9eb65ccda..9c9965434b 100644 --- a/qiskit/aqua/algorithms/amplitude_estimators/ae.py +++ b/qiskit/aqua/algorithms/amplitude_estimators/ae.py @@ -77,6 +77,12 @@ def __init__(self, num_eval_qubits: int, self._m = num_eval_qubits self._M = 2 ** num_eval_qubits + if isinstance(iqft, IQFT): + warnings.warn('The qiskit.aqua.components.iqfts.IQFT module is deprecated as of 0.7.0 ' + 'and will be removed no earlier than 3 months after the release. ' + 'You should pass a QuantumCircuit instead, see ' + 'qiskit.circuit.library.QFT and the .inverse() method.', + DeprecationWarning, stacklevel=2) self._iqft = iqft or QFT(self._m).inverse() self._circuit = None self._ret = {} diff --git a/qiskit/aqua/algorithms/linear_solvers/hhl.py b/qiskit/aqua/algorithms/linear_solvers/hhl.py index 5e712fb866..94b4855200 100644 --- a/qiskit/aqua/algorithms/linear_solvers/hhl.py +++ b/qiskit/aqua/algorithms/linear_solvers/hhl.py @@ -11,9 +11,8 @@ # 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 HHL algorithm. -""" + +"""The HHL algorithm.""" from typing import Optional, Union import logging @@ -37,9 +36,7 @@ class HHL(QuantumAlgorithm): - - r""" - The HHL algorithm. + r"""The HHL algorithm. The HHL algorithm (after the author's surnames Harrow-Hassidim-Lloyd) is a quantum algorithm to solve systems of linear equations :math:`A\overrightarrow{x}=\overrightarrow{b}`. diff --git a/qiskit/aqua/algorithms/minimum_eigen_solvers/qpe.py b/qiskit/aqua/algorithms/minimum_eigen_solvers/qpe.py index 92fb8a863e..0b34c682ea 100644 --- a/qiskit/aqua/algorithms/minimum_eigen_solvers/qpe.py +++ b/qiskit/aqua/algorithms/minimum_eigen_solvers/qpe.py @@ -89,7 +89,15 @@ def __init__(self, validate_min('expansion_order', expansion_order, 1) super().__init__(quantum_instance) self._state_in = state_in + + if isinstance(iqft, IQFT): + warnings.warn('The qiskit.aqua.components.iqfts.IQFT module is deprecated as of 0.7.0 ' + 'and will be removed no earlier than 3 months after the release. ' + 'You should pass a QuantumCircuit instead, see ' + 'qiskit.circuit.library.QFT and the .inverse() method.', + DeprecationWarning, stacklevel=2) self._iqft = iqft + self._num_time_slices = num_time_slices self._num_ancillae = num_ancillae self._expansion_mode = expansion_mode diff --git a/qiskit/aqua/circuits/phase_estimation_circuit.py b/qiskit/aqua/circuits/phase_estimation_circuit.py index c07042e7c0..16b8aca52e 100644 --- a/qiskit/aqua/circuits/phase_estimation_circuit.py +++ b/qiskit/aqua/circuits/phase_estimation_circuit.py @@ -14,6 +14,7 @@ """Quantum Phase Estimation Circuit.""" +import warnings import numpy as np from qiskit import QuantumRegister, QuantumCircuit, ClassicalRegister @@ -22,6 +23,7 @@ from qiskit.aqua.operators import (WeightedPauliOperator, # pylint: disable=unused-import suzuki_expansion_slice_pauli_list, evolution_instruction) +from qiskit.aqua.components.iqfts import IQFT class PhaseEstimationCircuit: @@ -43,8 +45,6 @@ def __init__( pauli_list=None ): """ - Constructor. - Args: operator (WeightedPauliOperator): the hamiltonian Operator object state_in (InitialState): the InitialState component @@ -63,6 +63,7 @@ def __init__( shallow_circuit_concat (bool): indicate whether to use shallow (cheap) mode for circuit concatenation pauli_list (list[Pauli]): the flat list of paulis for the operator + Raises: AquaError: Missing input """ @@ -78,7 +79,15 @@ def __init__( self._unitary_circuit_factory = unitary_circuit_factory self._state_in = state_in self._state_in_circuit_factory = state_in_circuit_factory + + if isinstance(iqft, IQFT): + warnings.warn('The qiskit.aqua.components.iqfts.IQFT module is deprecated as of 0.7.0 ' + 'and will be removed no earlier than 3 months after the release. ' + 'You should pass a QuantumCircuit instead, see ' + 'qiskit.circuit.library.QFT and the .inverse() method.', + DeprecationWarning, stacklevel=2) self._iqft = iqft + self._num_time_slices = num_time_slices self._num_ancillae = num_ancillae self._expansion_mode = expansion_mode @@ -98,8 +107,7 @@ def construct_circuit( auxiliary_register=None, measurement=False, ): - """ - Construct the Phase Estimation circuit + """Construct the Phase Estimation circuit Args: state_register (QuantumRegister): the optional register to use for the quantum state @@ -111,6 +119,7 @@ def construct_circuit( Returns: QuantumCircuit: the QuantumCircuit object for the constructed circuit + Raises: RuntimeError: Multiple identity pauli terms are present ValueError: invalid mode diff --git a/qiskit/aqua/components/eigs/eigs_qpe.py b/qiskit/aqua/components/eigs/eigs_qpe.py index 51d2345ad0..6196146f7e 100644 --- a/qiskit/aqua/components/eigs/eigs_qpe.py +++ b/qiskit/aqua/components/eigs/eigs_qpe.py @@ -14,6 +14,7 @@ """Quantum Phase Estimation for getting the eigenvalues of a matrix.""" +import warnings from typing import Optional, List, Union import numpy as np from qiskit import QuantumRegister, QuantumCircuit @@ -68,14 +69,30 @@ def __init__(self, validate_in_set('expansion_mode', expansion_mode, {'trotter', 'suzuki'}) validate_min('expansion_order', expansion_order, 1) self._operator = op_converter.to_weighted_pauli_operator(operator) + + if isinstance(iqft, IQFT): + warnings.warn('The qiskit.aqua.components.iqfts.IQFT module is deprecated as of 0.7.0 ' + 'and will be removed no earlier than 3 months after the release. ' + 'You should pass a QuantumCircuit instead, see ' + 'qiskit.circuit.library.QFT and the .inverse() method.', + DeprecationWarning, stacklevel=2) self._iqft = iqft + self._num_ancillae = num_ancillae self._num_time_slices = num_time_slices self._expansion_mode = expansion_mode self._expansion_order = expansion_order self._evo_time = evo_time self._negative_evals = negative_evals + + if ne_qfts and any(isinstance(ne_qft, IQFT) for ne_qft in ne_qfts): + warnings.warn('The qiskit.aqua.components.iqfts.IQFT module is deprecated as of 0.7.0 ' + 'and will be removed no earlier than 3 months after the release. ' + 'You should pass a QuantumCircuit instead, see ' + 'qiskit.circuit.library.QFT and the .inverse() method.', + DeprecationWarning, stacklevel=2) self._ne_qfts = ne_qfts + self._circuit = None self._output_register = None self._input_register = None diff --git a/test/aqua/test_amplitude_estimation.py b/test/aqua/test_amplitude_estimation.py index 9dbe66b4f5..fc561ff9f2 100644 --- a/test/aqua/test_amplitude_estimation.py +++ b/test/aqua/test_amplitude_estimation.py @@ -16,9 +16,11 @@ import unittest from test.aqua import QiskitAquaTestCase +from itertools import product import numpy as np from ddt import ddt, idata, data, unpack from qiskit import QuantumRegister, QuantumCircuit, BasicAer, execute +from qiskit.circuit.library import QFT from qiskit.aqua import QuantumInstance from qiskit.aqua.components.iqfts import Standard from qiskit.aqua.components.uncertainty_models import GaussianConditionalIndependenceModel as GCI @@ -185,11 +187,12 @@ def test_qasm(self, prob, shots, qae, expect): self.assertAlmostEqual(value, result[key], places=3, msg="estimate `{}` failed".format(key)) - @idata([ - [True], [False] - ]) + @idata(list(product( + [True, False], + [True, False] + ))) @unpack - def test_qae_circuit(self, efficient_circuit): + def test_qae_circuit(self, efficient_circuit, use_circuit_library): """Test circuits resulting from canonical amplitude estimation. Build the circuit manually and from the algorithm and compare the resulting unitaries. @@ -224,8 +227,13 @@ def test_qae_circuit(self, efficient_circuit): q_factory.build_controlled(circuit, q_objective, q_ancilla[power]) # fourier transform - iqft = Standard(m) - circuit = iqft.construct_circuit(qubits=q_ancilla, circuit=circuit, do_swaps=False) + if use_circuit_library: + iqft = QFT(m, do_swaps=False).inverse() + circuit.append(iqft.to_instruction(), q_ancilla) + else: + iqft = Standard(m) + iqft.construct_circuit(qubits=q_ancilla, circuit=circuit, do_swaps=False) + expected_unitary = self._unitary.execute(circuit).get_unitary() actual_circuit = qae.construct_circuit(measurement=False) From 49b2cef91ce3a174d8f0adcc6e8add3174be0464 Mon Sep 17 00:00:00 2001 From: Cryoris Date: Tue, 21 Apr 2020 23:08:09 +0200 Subject: [PATCH 06/12] fix missing import --- qiskit/aqua/algorithms/amplitude_estimators/ae.py | 1 + 1 file changed, 1 insertion(+) diff --git a/qiskit/aqua/algorithms/amplitude_estimators/ae.py b/qiskit/aqua/algorithms/amplitude_estimators/ae.py index 9c9965434b..cb6cd0cfe3 100644 --- a/qiskit/aqua/algorithms/amplitude_estimators/ae.py +++ b/qiskit/aqua/algorithms/amplitude_estimators/ae.py @@ -15,6 +15,7 @@ """The Quantum Phase Estimation-based Amplitude Estimation algorithm.""" from typing import Optional, Union, List, Tuple +import warnings import logging from collections import OrderedDict import numpy as np From 688fa67a2c81421ba1ae5a7f8f422b38ad2bca56 Mon Sep 17 00:00:00 2001 From: Cryoris Date: Tue, 21 Apr 2020 23:26:02 +0200 Subject: [PATCH 07/12] fix cyclic import --- qiskit/aqua/circuits/phase_estimation_circuit.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qiskit/aqua/circuits/phase_estimation_circuit.py b/qiskit/aqua/circuits/phase_estimation_circuit.py index 16b8aca52e..bcc06abd94 100644 --- a/qiskit/aqua/circuits/phase_estimation_circuit.py +++ b/qiskit/aqua/circuits/phase_estimation_circuit.py @@ -23,7 +23,6 @@ from qiskit.aqua.operators import (WeightedPauliOperator, # pylint: disable=unused-import suzuki_expansion_slice_pauli_list, evolution_instruction) -from qiskit.aqua.components.iqfts import IQFT class PhaseEstimationCircuit: @@ -80,7 +79,8 @@ def __init__( self._state_in = state_in self._state_in_circuit_factory = state_in_circuit_factory - if isinstance(iqft, IQFT): + # cannot check for IQFT type due to circular import + if not isinstance(iqft, QuantumCircuit): warnings.warn('The qiskit.aqua.components.iqfts.IQFT module is deprecated as of 0.7.0 ' 'and will be removed no earlier than 3 months after the release. ' 'You should pass a QuantumCircuit instead, see ' From ce033dbd576afeb962932f3ffa7a124f4d3f1e8b Mon Sep 17 00:00:00 2001 From: Cryoris Date: Wed, 22 Apr 2020 11:01:59 +0200 Subject: [PATCH 08/12] remove todos, fixed in Qiskit/qiskit-terra#4209 --- qiskit/aqua/circuits/phase_estimation_circuit.py | 2 -- qiskit/aqua/components/eigs/eigs_qpe.py | 6 ++---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/qiskit/aqua/circuits/phase_estimation_circuit.py b/qiskit/aqua/circuits/phase_estimation_circuit.py index bcc06abd94..a69eec92f3 100644 --- a/qiskit/aqua/circuits/phase_estimation_circuit.py +++ b/qiskit/aqua/circuits/phase_estimation_circuit.py @@ -219,8 +219,6 @@ def construct_circuit( if isinstance(self._iqft, QuantumCircuit): if hasattr(self._iqft, 'do_swaps'): self._iqft.do_swaps = False - # TODO make the IQFT not revert to QFT is do_swaps is called - self._iqft = self._iqft.inverse() qc.append(self._iqft.to_instruction(), a) else: self._iqft.construct_circuit(mode='circuit', qubits=a, circuit=qc, do_swaps=False) diff --git a/qiskit/aqua/components/eigs/eigs_qpe.py b/qiskit/aqua/components/eigs/eigs_qpe.py index 6196146f7e..bbce728a3b 100644 --- a/qiskit/aqua/components/eigs/eigs_qpe.py +++ b/qiskit/aqua/components/eigs/eigs_qpe.py @@ -161,12 +161,10 @@ def construct_circuit(self, mode, register=None): return self._circuit def _handle_negative_evals(self, qc, q): - def apply_ne_qft(ne_qft, inverse=False): # TODO remove inverse once bug with IQFT fixed + def apply_ne_qft(ne_qft): if isinstance(ne_qft, QuantumCircuit): if hasattr(ne_qft, 'do_swaps'): ne_qft.do_swaps = False - if inverse: - ne_qft = ne_qft.inverse() qc.append(ne_qft.to_instruction(), qs) else: ne_qft.construct_circuit(mode='circuit', qubits=qs, circuit=qc, do_swaps=False) @@ -178,4 +176,4 @@ def apply_ne_qft(ne_qft, inverse=False): # TODO remove inverse once bug with IQ apply_ne_qft(self._ne_qfts[0]) for i, qi in enumerate(reversed(qs)): qc.cu1(2*np.pi/2**(i+1), sgn, qi) - apply_ne_qft(self._ne_qfts[1], inverse=True) + apply_ne_qft(self._ne_qfts[1]) From 68acef58ddeddf2eb918ef53d3c895be0a3eb394 Mon Sep 17 00:00:00 2001 From: Cryoris Date: Wed, 22 Apr 2020 23:01:27 +0200 Subject: [PATCH 09/12] filter deprecations warnings from QFT --- test/aqua/test_amplitude_estimation.py | 8 ++++++++ test/aqua/test_hhl.py | 7 +++++++ test/aqua/test_qpe.py | 10 ++++++++++ test/chemistry/test_end2end_with_qpe.py | 10 ++++++++++ 4 files changed, 35 insertions(+) diff --git a/test/aqua/test_amplitude_estimation.py b/test/aqua/test_amplitude_estimation.py index fc561ff9f2..17864730f5 100644 --- a/test/aqua/test_amplitude_estimation.py +++ b/test/aqua/test_amplitude_estimation.py @@ -14,6 +14,7 @@ """Test the quantum amplitude estimation algorithm.""" +import warnings import unittest from test.aqua import QiskitAquaTestCase from itertools import product @@ -136,6 +137,13 @@ def qasm(shots=100): self._qasm = qasm + # ignore deprecation warnings from QFTs + warnings.filterwarnings(action="ignore", category=DeprecationWarning) + + def tearDown(self): + super().tearDown() + warnings.filterwarnings(action="always", category=DeprecationWarning) + @idata([ [0.2, AmplitudeEstimation(2), {'estimation': 0.5, 'mle': 0.2}], [0.4, AmplitudeEstimation(4), {'estimation': 0.30866, 'mle': 0.4}], diff --git a/test/aqua/test_hhl.py b/test/aqua/test_hhl.py index e144e57b30..c97b69f0b3 100644 --- a/test/aqua/test_hhl.py +++ b/test/aqua/test_hhl.py @@ -14,6 +14,7 @@ """ Test HHL """ +import warnings import unittest from test.aqua import QiskitAquaTestCase @@ -43,6 +44,12 @@ def setUp(self): super(TestHHL, self).setUp() self.random_seed = 0 aqua_globals.random_seed = self.random_seed + # ignore deprecation warnings from QFTs + warnings.filterwarnings(action="ignore", category=DeprecationWarning) + + def tearDown(self): + super().tearDown() + warnings.filterwarnings(action="always", category=DeprecationWarning) @staticmethod def _create_eigs(matrix, num_ancillae, negative_evals, use_circuit_library=True): diff --git a/test/aqua/test_qpe.py b/test/aqua/test_qpe.py index 5fa31d8a45..cc25a28c04 100644 --- a/test/aqua/test_qpe.py +++ b/test/aqua/test_qpe.py @@ -14,6 +14,7 @@ """ Test QPE """ +import warnings import unittest from test.aqua import QiskitAquaTestCase import numpy as np @@ -59,6 +60,15 @@ class TestQPE(QiskitAquaTestCase): """QPE tests.""" + def setUp(self): + super().setUp() + # ignore deprecation warnings from QFTs + warnings.filterwarnings(action="ignore", category=DeprecationWarning) + + def tearDown(self): + super().tearDown() + warnings.filterwarnings(action="always", category=DeprecationWarning) + @idata([ [QUBIT_OP_SIMPLE, 'qasm_simulator', 1, 5, False], [QUBIT_OP_SIMPLE, 'qasm_simulator', 1, 5, True], diff --git a/test/chemistry/test_end2end_with_qpe.py b/test/chemistry/test_end2end_with_qpe.py index 6e221333e8..bbdec9f88e 100644 --- a/test/chemistry/test_end2end_with_qpe.py +++ b/test/chemistry/test_end2end_with_qpe.py @@ -14,6 +14,7 @@ """ Test End to End with QPE """ +import warnings import unittest from test.chemistry import QiskitChemistryTestCase from itertools import product @@ -35,6 +36,15 @@ class TestEnd2EndWithQPE(QiskitChemistryTestCase): """QPE tests.""" + def setUp(self): + super().setUp() + # ignore deprecation warnings from QFTs + warnings.filterwarnings(action="ignore", category=DeprecationWarning) + + def tearDown(self): + super().tearDown() + warnings.filterwarnings(action="always", category=DeprecationWarning) + @idata(list(product( [0.5, 0.735, 1], [False, True] From 2c488041ec9ef8cbb5219fb7d2f68fc45b72ebe7 Mon Sep 17 00:00:00 2001 From: Cryoris Date: Wed, 22 Apr 2020 23:23:54 +0200 Subject: [PATCH 10/12] add checks on qft size --- qiskit/aqua/circuits/phase_estimation_circuit.py | 8 ++++++++ qiskit/aqua/components/eigs/eigs_qpe.py | 13 +++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/qiskit/aqua/circuits/phase_estimation_circuit.py b/qiskit/aqua/circuits/phase_estimation_circuit.py index a69eec92f3..9be2de1b21 100644 --- a/qiskit/aqua/circuits/phase_estimation_circuit.py +++ b/qiskit/aqua/circuits/phase_estimation_circuit.py @@ -217,6 +217,14 @@ def construct_circuit( # inverse qft on ancillae if isinstance(self._iqft, QuantumCircuit): + # check if QFT has the right size + if self._iqft.num_qubits != len(a): + try: # try resizing + self._iqft.num_qubits = len(a) + except AttributeError: + raise ValueError('The IQFT cannot be resized and does not have the ' + 'required size of {}'.format(len(a))) + if hasattr(self._iqft, 'do_swaps'): self._iqft.do_swaps = False qc.append(self._iqft.to_instruction(), a) diff --git a/qiskit/aqua/components/eigs/eigs_qpe.py b/qiskit/aqua/components/eigs/eigs_qpe.py index bbce728a3b..11ef1d30b2 100644 --- a/qiskit/aqua/components/eigs/eigs_qpe.py +++ b/qiskit/aqua/components/eigs/eigs_qpe.py @@ -161,16 +161,25 @@ def construct_circuit(self, mode, register=None): return self._circuit def _handle_negative_evals(self, qc, q): + sgn = q[0] + qs = [q[i] for i in range(1, len(q))] + def apply_ne_qft(ne_qft): if isinstance(ne_qft, QuantumCircuit): + # check if QFT has the right size + if ne_qft.num_qubits != len(qs): + try: # try resizing + ne_qft.num_qubits = len(qs) + except AttributeError: + raise ValueError('The IQFT cannot be resized and does not have the ' + 'required size of {}'.format(len(qs))) + if hasattr(ne_qft, 'do_swaps'): ne_qft.do_swaps = False qc.append(ne_qft.to_instruction(), qs) else: ne_qft.construct_circuit(mode='circuit', qubits=qs, circuit=qc, do_swaps=False) - sgn = q[0] - qs = [q[i] for i in range(1, len(q))] for qi in qs: qc.cx(sgn, qi) apply_ne_qft(self._ne_qfts[0]) From 3aee44d141a3fd6e2c30843974a93bf241978f78 Mon Sep 17 00:00:00 2001 From: Cryoris Date: Wed, 22 Apr 2020 23:37:12 +0200 Subject: [PATCH 11/12] only filter warnings locally --- test/aqua/test_amplitude_estimation.py | 14 +++++++------- test/aqua/test_hhl.py | 8 ++++++-- test/aqua/test_qpe.py | 14 +++++--------- test/chemistry/test_end2end_with_qpe.py | 16 +++++++--------- 4 files changed, 25 insertions(+), 27 deletions(-) diff --git a/test/aqua/test_amplitude_estimation.py b/test/aqua/test_amplitude_estimation.py index 17864730f5..6025117710 100644 --- a/test/aqua/test_amplitude_estimation.py +++ b/test/aqua/test_amplitude_estimation.py @@ -137,13 +137,6 @@ def qasm(shots=100): self._qasm = qasm - # ignore deprecation warnings from QFTs - warnings.filterwarnings(action="ignore", category=DeprecationWarning) - - def tearDown(self): - super().tearDown() - warnings.filterwarnings(action="always", category=DeprecationWarning) - @idata([ [0.2, AmplitudeEstimation(2), {'estimation': 0.5, 'mle': 0.2}], [0.4, AmplitudeEstimation(4), {'estimation': 0.30866, 'mle': 0.4}], @@ -205,6 +198,10 @@ def test_qae_circuit(self, efficient_circuit, use_circuit_library): Build the circuit manually and from the algorithm and compare the resulting unitaries. """ + if not use_circuit_library: + # ignore deprecation warnings from QFTs + warnings.filterwarnings(action="ignore", category=DeprecationWarning) + prob = 0.5 for m in range(2, 7): @@ -250,6 +247,9 @@ def test_qae_circuit(self, efficient_circuit, use_circuit_library): diff = np.sum(np.abs(actual_unitary - expected_unitary)) self.assertAlmostEqual(diff, 0) + if not use_circuit_library: + warnings.filterwarnings(action="always", category=DeprecationWarning) + @idata([ [True], [False] ]) diff --git a/test/aqua/test_hhl.py b/test/aqua/test_hhl.py index c97b69f0b3..35dee07744 100644 --- a/test/aqua/test_hhl.py +++ b/test/aqua/test_hhl.py @@ -44,8 +44,6 @@ def setUp(self): super(TestHHL, self).setUp() self.random_seed = 0 aqua_globals.random_seed = self.random_seed - # ignore deprecation warnings from QFTs - warnings.filterwarnings(action="ignore", category=DeprecationWarning) def tearDown(self): super().tearDown() @@ -83,6 +81,9 @@ def _create_eigs(matrix, num_ancillae, negative_evals, use_circuit_library=True) def test_hhl_diagonal(self, vector, use_circuit_library): """ hhl diagonal test """ self.log.debug('Testing HHL simple test in mode Lookup with statevector simulator') + if not use_circuit_library: + # ignore deprecation warnings from QFTs + warnings.filterwarnings(action="ignore", category=DeprecationWarning) matrix = [[1, 0], [0, 1]] @@ -123,6 +124,9 @@ def test_hhl_diagonal(self, vector, use_circuit_library): self.log.debug('fidelity HHL to algebraic: %s', fidelity) self.log.debug('probability of result: %s', hhl_result["probability_result"]) + if not use_circuit_library: + warnings.filterwarnings(action="always", category=DeprecationWarning) + @data([[-1, 0], False], [[0, -1], False], [[-1, -1], False], [[-1, 0], True], [[0, -1], True], [[-1, -1], True]) @unpack diff --git a/test/aqua/test_qpe.py b/test/aqua/test_qpe.py index cc25a28c04..4d0b1e2862 100644 --- a/test/aqua/test_qpe.py +++ b/test/aqua/test_qpe.py @@ -60,15 +60,6 @@ class TestQPE(QiskitAquaTestCase): """QPE tests.""" - def setUp(self): - super().setUp() - # ignore deprecation warnings from QFTs - warnings.filterwarnings(action="ignore", category=DeprecationWarning) - - def tearDown(self): - super().tearDown() - warnings.filterwarnings(action="always", category=DeprecationWarning) - @idata([ [QUBIT_OP_SIMPLE, 'qasm_simulator', 1, 5, False], [QUBIT_OP_SIMPLE, 'qasm_simulator', 1, 5, True], @@ -94,6 +85,8 @@ def test_qpe(self, qubit_op, simulator, num_time_slices, n_ancillae, use_circuit if use_circuit_library: iqft = QFT(n_ancillae).inverse() else: + # ignore deprecation warnings from QFTs + warnings.filterwarnings(action="ignore", category=DeprecationWarning) iqft = Standard(n_ancillae) qpe = QPEMinimumEigensolver(qubit_op, state_in, iqft, num_time_slices, n_ancillae, @@ -124,6 +117,9 @@ def test_qpe(self, qubit_op, simulator, num_time_slices, n_ancillae, use_circuit np.testing.assert_approx_equal(result.eigenvalue.real, ref_eigenval.real, significant=2) self.assertEqual(tmp_qubit_op, qubit_op, "Operator is modified after QPE.") + if not use_circuit_library: + warnings.filterwarnings(action="always", category=DeprecationWarning) + if __name__ == '__main__': unittest.main() diff --git a/test/chemistry/test_end2end_with_qpe.py b/test/chemistry/test_end2end_with_qpe.py index bbdec9f88e..c0d92ac27a 100644 --- a/test/chemistry/test_end2end_with_qpe.py +++ b/test/chemistry/test_end2end_with_qpe.py @@ -36,15 +36,6 @@ class TestEnd2EndWithQPE(QiskitChemistryTestCase): """QPE tests.""" - def setUp(self): - super().setUp() - # ignore deprecation warnings from QFTs - warnings.filterwarnings(action="ignore", category=DeprecationWarning) - - def tearDown(self): - super().tearDown() - warnings.filterwarnings(action="always", category=DeprecationWarning) - @idata(list(product( [0.5, 0.735, 1], [False, True] @@ -63,6 +54,10 @@ def test_qpe(self, distance, use_circuit_library): except QiskitChemistryError: self.skipTest('PYSCF driver does not appear to be installed') + if not use_circuit_library: + # ignore deprecation warnings from QFTs + warnings.filterwarnings(action="ignore", category=DeprecationWarning) + molecule = driver.run() qubit_mapping = 'parity' fer_op = FermionicOperator( @@ -112,6 +107,9 @@ def test_qpe(self, distance, use_circuit_library): np.testing.assert_approx_equal(result.eigenvalue.real, reference_energy, significant=2) + if not use_circuit_library: + warnings.filterwarnings(action="always", category=DeprecationWarning) + if __name__ == '__main__': unittest.main() From b335561d63bf2853f75ee74a11578cea62e2c4c8 Mon Sep 17 00:00:00 2001 From: Cryoris Date: Wed, 22 Apr 2020 23:43:42 +0200 Subject: [PATCH 12/12] re-enable tests in tearDown to be sure --- test/aqua/test_amplitude_estimation.py | 4 ++++ test/aqua/test_qpe.py | 4 ++++ test/chemistry/test_end2end_with_qpe.py | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/test/aqua/test_amplitude_estimation.py b/test/aqua/test_amplitude_estimation.py index 6025117710..78749a0e18 100644 --- a/test/aqua/test_amplitude_estimation.py +++ b/test/aqua/test_amplitude_estimation.py @@ -137,6 +137,10 @@ def qasm(shots=100): self._qasm = qasm + def tearDown(self): + super().tearDown() + warnings.filterwarnings(action="always", category=DeprecationWarning) + @idata([ [0.2, AmplitudeEstimation(2), {'estimation': 0.5, 'mle': 0.2}], [0.4, AmplitudeEstimation(4), {'estimation': 0.30866, 'mle': 0.4}], diff --git a/test/aqua/test_qpe.py b/test/aqua/test_qpe.py index 4d0b1e2862..c1260fd3b9 100644 --- a/test/aqua/test_qpe.py +++ b/test/aqua/test_qpe.py @@ -60,6 +60,10 @@ class TestQPE(QiskitAquaTestCase): """QPE tests.""" + def tearDown(self): + super().tearDown() + warnings.filterwarnings(action="always", category=DeprecationWarning) + @idata([ [QUBIT_OP_SIMPLE, 'qasm_simulator', 1, 5, False], [QUBIT_OP_SIMPLE, 'qasm_simulator', 1, 5, True], diff --git a/test/chemistry/test_end2end_with_qpe.py b/test/chemistry/test_end2end_with_qpe.py index c0d92ac27a..41f3211f8e 100644 --- a/test/chemistry/test_end2end_with_qpe.py +++ b/test/chemistry/test_end2end_with_qpe.py @@ -36,6 +36,10 @@ class TestEnd2EndWithQPE(QiskitChemistryTestCase): """QPE tests.""" + def tearDown(self): + super().tearDown() + warnings.filterwarnings(action="always", category=DeprecationWarning) + @idata(list(product( [0.5, 0.735, 1], [False, True]