diff --git a/qiskit/aqua/algorithms/amplitude_estimators/ae.py b/qiskit/aqua/algorithms/amplitude_estimators/ae.py index adb3c3bf85..cb6cd0cfe3 100644 --- a/qiskit/aqua/algorithms/amplitude_estimators/ae.py +++ b/qiskit/aqua/algorithms/amplitude_estimators/ae.py @@ -11,9 +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. + """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 @@ -21,11 +23,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 +57,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[Union[QuantumCircuit, IQFT]] = None, quantum_instance: Optional[Union[QuantumInstance, BaseBackend]] = None) -> None: r""" Args: @@ -75,10 +78,13 @@ 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 + 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 842cc23869..0b34c682ea 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[Union[QuantumCircuit, IQFT]] = None, num_time_slices: int = 1, num_ancillae: int = 1, expansion_mode: str = 'trotter', @@ -90,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/fourier_transform_circuits.py b/qiskit/aqua/circuits/fourier_transform_circuits.py index 7069048520..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,28 +11,17 @@ # 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. -""" -import numpy as np +"""DEPRECATED. Quantum Fourier Transform Circuit.""" -from qiskit.circuit import QuantumRegister, QuantumCircuit, Qubit # pylint: disable=unused-import +import warnings +from qiskit.circuit.library import QFT from qiskit.aqua import AquaError 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]) + """DEPRECATED. Quantum Fourier Transform Circuit.""" @staticmethod def construct_circuit( @@ -42,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. @@ -60,6 +48,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 +59,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 diff --git a/qiskit/aqua/circuits/phase_estimation_circuit.py b/qiskit/aqua/circuits/phase_estimation_circuit.py index d9883a1e04..9be2de1b21 100644 --- a/qiskit/aqua/circuits/phase_estimation_circuit.py +++ b/qiskit/aqua/circuits/phase_estimation_circuit.py @@ -11,10 +11,10 @@ # 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 warnings import numpy as np from qiskit import QuantumRegister, QuantumCircuit, ClassicalRegister @@ -26,9 +26,7 @@ class PhaseEstimationCircuit: - """ - Quantum Phase Estimation Circuit. - """ + """Quantum Phase Estimation Circuit.""" def __init__( self, @@ -46,13 +44,12 @@ def __init__( pauli_list=None ): """ - Constructor. - Args: 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) @@ -65,6 +62,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 """ @@ -80,7 +78,16 @@ def __init__( self._unitary_circuit_factory = unitary_circuit_factory self._state_in = state_in self._state_in_circuit_factory = state_in_circuit_factory + + # 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 ' + '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 @@ -100,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 @@ -113,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 @@ -209,7 +216,20 @@ 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): + # 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) + 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..11ef1d30b2 100644 --- a/qiskit/aqua/components/eigs/eigs_qpe.py +++ b/qiskit/aqua/components/eigs/eigs_qpe.py @@ -12,11 +12,12 @@ # 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 warnings +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 @@ -28,8 +29,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 +39,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', @@ -69,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 @@ -147,9 +163,26 @@ def construct_circuit(self, mode, register=None): 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) + 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]) 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 """ diff --git a/test/aqua/test_amplitude_estimation.py b/test/aqua/test_amplitude_estimation.py index 9dbe66b4f5..78749a0e18 100644 --- a/test/aqua/test_amplitude_estimation.py +++ b/test/aqua/test_amplitude_estimation.py @@ -14,11 +14,14 @@ """Test the quantum amplitude estimation algorithm.""" +import warnings 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 @@ -134,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}], @@ -185,15 +192,20 @@ 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. """ + 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): @@ -224,8 +236,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) @@ -234,6 +251,9 @@ def test_qae_circuit(self, efficient_circuit): 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 1fa7ce891d..35dee07744 100644 --- a/test/aqua/test_hhl.py +++ b/test/aqua/test_hhl.py @@ -14,14 +14,17 @@ """ Test HHL """ +import warnings import unittest 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 @@ -42,16 +45,28 @@ def setUp(self): self.random_seed = 0 aqua_globals.random_seed = self.random_seed + def tearDown(self): + super().tearDown() + warnings.filterwarnings(action="always", category=DeprecationWarning) + @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,11 +75,15 @@ 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') + if not use_circuit_library: + # ignore deprecation warnings from QFTs + warnings.filterwarnings(action="ignore", category=DeprecationWarning) matrix = [[1, 0], [0, 1]] @@ -78,7 +97,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 +124,13 @@ 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]]]) + 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 - 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 +146,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..c1260fd3b9 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 @@ -24,6 +25,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 @@ -58,13 +60,20 @@ class TestQPE(QiskitAquaTestCase): """QPE tests.""" + def tearDown(self): + super().tearDown() + warnings.filterwarnings(action="always", category=DeprecationWarning) + @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 +86,12 @@ 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: + # 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, expansion_mode='suzuki', expansion_order=2, @@ -107,6 +121,9 @@ def test_qpe(self, qubit_op, simulator, num_time_slices, n_ancillae): 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 99d1f17d82..41f3211f8e 100644 --- a/test/chemistry/test_end2end_with_qpe.py +++ b/test/chemistry/test_end2end_with_qpe.py @@ -14,11 +14,14 @@ """ Test End to End with QPE """ +import warnings 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 +36,16 @@ class TestEnd2EndWithQPE(QiskitChemistryTestCase): """QPE tests.""" - @idata([ - [0.5], - [0.735], - [1], - ]) + def tearDown(self): + super().tearDown() + warnings.filterwarnings(action="always", category=DeprecationWarning) + + @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) @@ -52,6 +58,10 @@ def test_qpe(self, distance): 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( @@ -73,7 +83,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', @@ -98,6 +111,9 @@ def test_qpe(self, distance): 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()