From 5128c6751fc2909131ab38c72358bb1e91c9fd84 Mon Sep 17 00:00:00 2001 From: Manoel Marques Date: Tue, 18 Apr 2023 18:39:24 -0400 Subject: [PATCH] Deprecate QuantumInstance and Opflow (#9176) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Deprecate QuantumInstance and Opflow * Add .. deprecated:: to init modules * Add link to url guide * Remove internal use of opflow * Fix black * Discard old changes in deprecation.py * Update decorators * Remove from docstring * Update sphinx deprecations, fix lint, fix tests * Remove hanging Deprecated in docstring * Remove old Deprecation messages * Revert "Remove old Deprecation messages" This reverts commit 6924130e12ffdfde971ff1e25434ee84bf983482. * Revert "Remove hanging Deprecated in docstring" This reverts commit cfb04f50e6a30a33955b57be4ab5bbdb9035923c. * Revert "Remove from docstring" This reverts commit 50e5954ecd4a729e7101e8ea4bf493240ae8b59e. * Change Deprecation to Deprecated * Remove catch warnings in main code * Fix missing decorators * Fix tests * Shorten message * Fix black * Shorten qi message * Remove checks for QDrift's internal use of opflow (changed in this PR) * Add warning catchers to unit tests * Remove opflow from qaoa ansatz tests * Remove opflow from non-related tests * Restore some opflow tests for completion * Fix black * Remove catch warnings * Refactor adaptVQE tests, remove opflow from observables evaluator * Fix tests, lint Fix tests, lint Fix CI failures Fix tests CI Fix unit tests Fix CI again Fix lint Restore vqd test Remove unused import * Delete qobj test to fix CI until #9322 is merged * Refactor gradients test warnings * Remove warning filter * Refactor rest of tests to assert warnings * Fix formatting * Restore unchanged unit tests Restore opflow test case Restore estimator test Restore unchanged tests * Go back to old opflow test setup * Revert "Refactor gradients test warnings", only keep qi assertWarns This reverts commit 9c0a37f3bc3068a9b1ccd122298cfefe556d4135. * Restore opflow unittests * Fix tests * Fix lint * Fix qaoa repeated test * Add module deprecation warning * Divide message in multiple lines * Fix lint * :mod:: -> :mod: * Deprecate Z2 symmetries --------- Co-authored-by: ElePT Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com> Co-authored-by: woodsp-ibm --- qiskit/algorithms/observables_evaluator.py | 3 +- qiskit/circuit/library/n_local/qaoa_ansatz.py | 5 +- qiskit/opflow/__init__.py | 42 ++- qiskit/opflow/converters/__init__.py | 9 +- qiskit/opflow/converters/abelian_grouper.py | 10 +- qiskit/opflow/converters/circuit_sampler.py | 11 +- qiskit/opflow/converters/converter_base.py | 12 +- .../opflow/converters/dict_to_circuit_sum.py | 14 +- .../opflow/converters/pauli_basis_change.py | 10 +- .../opflow/converters/two_qubit_reduction.py | 12 +- qiskit/opflow/evolutions/__init__.py | 14 +- qiskit/opflow/evolutions/evolution_base.py | 12 +- qiskit/opflow/evolutions/evolution_factory.py | 11 +- qiskit/opflow/evolutions/evolved_op.py | 9 +- qiskit/opflow/evolutions/matrix_evolution.py | 12 +- .../evolutions/pauli_trotter_evolution.py | 13 +- .../evolutions/trotterizations/__init__.py | 6 +- .../evolutions/trotterizations/qdrift.py | 9 +- .../evolutions/trotterizations/suzuki.py | 9 +- .../evolutions/trotterizations/trotter.py | 9 +- .../trotterizations/trotterization_base.py | 11 +- .../trotterizations/trotterization_factory.py | 9 +- qiskit/opflow/exceptions.py | 13 +- qiskit/opflow/expectations/__init__.py | 15 +- .../expectations/aer_pauli_expectation.py | 12 +- .../opflow/expectations/cvar_expectation.py | 10 +- .../opflow/expectations/expectation_base.py | 12 +- .../expectations/expectation_factory.py | 20 +- .../opflow/expectations/matrix_expectation.py | 14 +- .../opflow/expectations/pauli_expectation.py | 10 +- qiskit/opflow/gradients/__init__.py | 15 +- .../gradients/circuit_gradients/__init__.py | 5 +- .../circuit_gradients/circuit_gradient.py | 13 +- .../gradients/circuit_gradients/lin_comb.py | 11 +- .../circuit_gradients/param_shift.py | 11 +- .../gradients/circuit_qfis/circuit_qfi.py | 12 +- .../gradients/circuit_qfis/lin_comb_full.py | 11 +- .../circuit_qfis/overlap_block_diag.py | 12 +- .../gradients/circuit_qfis/overlap_diag.py | 13 +- qiskit/opflow/gradients/derivative_base.py | 13 +- qiskit/opflow/gradients/gradient.py | 13 +- qiskit/opflow/gradients/gradient_base.py | 11 +- qiskit/opflow/gradients/hessian.py | 13 +- qiskit/opflow/gradients/hessian_base.py | 11 +- qiskit/opflow/gradients/natural_gradient.py | 9 +- qiskit/opflow/gradients/qfi.py | 13 +- qiskit/opflow/gradients/qfi_base.py | 12 +- qiskit/opflow/list_ops/__init__.py | 9 +- qiskit/opflow/list_ops/composed_op.py | 9 +- qiskit/opflow/list_ops/list_op.py | 11 +- qiskit/opflow/list_ops/summed_op.py | 9 +- qiskit/opflow/list_ops/tensored_op.py | 11 +- qiskit/opflow/mixins/star_algebra.py | 12 +- qiskit/opflow/mixins/tensor.py | 12 +- qiskit/opflow/operator_base.py | 10 +- qiskit/opflow/operator_globals.py | 9 +- qiskit/opflow/primitive_ops/__init__.py | 8 +- qiskit/opflow/primitive_ops/circuit_op.py | 10 +- qiskit/opflow/primitive_ops/matrix_op.py | 11 +- qiskit/opflow/primitive_ops/pauli_op.py | 11 +- qiskit/opflow/primitive_ops/pauli_sum_op.py | 10 +- qiskit/opflow/primitive_ops/primitive_op.py | 9 +- .../primitive_ops/tapered_pauli_sum_op.py | 15 +- qiskit/opflow/state_fns/__init__.py | 14 +- qiskit/opflow/state_fns/circuit_state_fn.py | 9 +- qiskit/opflow/state_fns/cvar_measurement.py | 9 +- qiskit/opflow/state_fns/dict_state_fn.py | 9 +- qiskit/opflow/state_fns/operator_state_fn.py | 9 +- .../state_fns/sparse_vector_state_fn.py | 9 +- qiskit/opflow/state_fns/state_fn.py | 9 +- qiskit/opflow/state_fns/vector_state_fn.py | 9 +- qiskit/opflow/utils.py | 21 +- qiskit/synthesis/evolution/qdrift.py | 3 +- qiskit/utils/backend_utils.py | 47 ++- qiskit/utils/measurement_error_mitigation.py | 25 +- qiskit/utils/mitigation/__init__.py | 7 +- qiskit/utils/mitigation/_filters.py | 15 +- qiskit/utils/mitigation/circuits.py | 21 +- qiskit/utils/mitigation/fitters.py | 13 +- qiskit/utils/quantum_instance.py | 9 +- qiskit/utils/run_circuits.py | 15 +- .../deprecate-opflow-qi-32f7e27884deea3f.yaml | 14 + .../evolvers/test_evolution_problem.py | 23 +- .../trotterization/test_trotter_qrte.py | 37 +- .../minimum_eigensolvers/test_adapt_vqe.py | 126 +++---- .../minimum_eigensolvers/test_qaoa.py | 36 +- .../minimum_eigensolvers/test_vqe.py | 66 ++-- .../optimizers/test_gradient_descent.py | 13 +- .../optimizers/test_optimizer_aqgd.py | 66 ++-- .../optimizers/test_optimizer_nft.py | 26 +- .../optimizers/test_optimizers_scikitquant.py | 33 +- .../python/algorithms/optimizers/test_spsa.py | 13 +- .../algorithms/test_amplitude_estimators.py | 116 ++++--- .../algorithms/test_aux_ops_evaluator.py | 61 ++-- test/python/algorithms/test_backendv1.py | 78 +++-- test/python/algorithms/test_backendv2.py | 50 ++- test/python/algorithms/test_grover.py | 100 ++++-- .../test_measure_error_mitigation.py | 244 +++++++------ .../algorithms/test_numpy_eigen_solver.py | 45 ++- .../test_numpy_minimum_eigen_solver.py | 62 +++- .../algorithms/test_observables_evaluator.py | 7 +- .../python/algorithms/test_phase_estimator.py | 210 ++++++----- test/python/algorithms/test_qaoa.py | 75 ++-- .../algorithms/test_skip_qobj_validation.py | 91 ++--- test/python/algorithms/test_vqd.py | 177 ++++++---- test/python/algorithms/test_vqe.py | 290 +++++++++------- .../test_scipy_imaginary_evolver.py | 17 +- .../algorithms/time_evolvers/test_pvqd.py | 6 +- .../test_time_evolution_problem.py | 14 +- .../time_evolvers/test_trotter_qrte.py | 21 +- .../circuit/library/test_evolution_gate.py | 82 +++-- .../circuit/library/test_evolved_op_ansatz.py | 53 +-- .../circuit/library/test_qaoa_ansatz.py | 43 +-- .../circuit/test_circuit_load_from_qpy.py | 44 ++- test/python/opflow/opflow_test_case.py | 11 +- .../opflow/test_aer_pauli_expectation.py | 139 ++++---- .../python/opflow/test_expectation_factory.py | 30 +- test/python/opflow/test_gradients.py | 140 ++++---- test/python/opflow/test_matrix_expectation.py | 88 +++-- test/python/opflow/test_pauli_expectation.py | 117 ++++--- .../python/opflow/test_state_op_meas_evals.py | 75 ++-- test/python/result/test_sampled_expval.py | 9 +- .../transpiler/test_swap_strategy_router.py | 32 +- test/python/utils/mitigation/test_meas.py | 326 +++++++++--------- 124 files changed, 2710 insertions(+), 1571 deletions(-) create mode 100644 releasenotes/notes/deprecate-opflow-qi-32f7e27884deea3f.yaml diff --git a/qiskit/algorithms/observables_evaluator.py b/qiskit/algorithms/observables_evaluator.py index 3e8f11dfd6e6..6d40239e229e 100644 --- a/qiskit/algorithms/observables_evaluator.py +++ b/qiskit/algorithms/observables_evaluator.py @@ -20,6 +20,7 @@ from qiskit import QuantumCircuit from qiskit.opflow import PauliSumOp +from qiskit.quantum_info import SparsePauliOp from .exceptions import AlgorithmError from .list_or_dict import ListOrDict from ..primitives import BaseEstimator @@ -88,7 +89,7 @@ def _handle_zero_ops( """Replaces all occurrence of operators equal to 0 in the list with an equivalent ``PauliSumOp`` operator.""" if observables_list: - zero_op = PauliSumOp.from_list([("I" * observables_list[0].num_qubits, 0)]) + zero_op = SparsePauliOp.from_list([("I" * observables_list[0].num_qubits, 0)]) for ind, observable in enumerate(observables_list): if observable == 0: observables_list[ind] = zero_op diff --git a/qiskit/circuit/library/n_local/qaoa_ansatz.py b/qiskit/circuit/library/n_local/qaoa_ansatz.py index c3aa8fc37adf..c8da8d271e2f 100644 --- a/qiskit/circuit/library/n_local/qaoa_ansatz.py +++ b/qiskit/circuit/library/n_local/qaoa_ansatz.py @@ -20,6 +20,7 @@ from qiskit.circuit.parametervector import ParameterVector from qiskit.circuit.quantumcircuit import QuantumCircuit from qiskit.circuit.quantumregister import QuantumRegister +from qiskit.quantum_info import SparsePauliOp class QAOAAnsatz(EvolvedOperatorAnsatz): @@ -219,8 +220,6 @@ def mixer_operator(self): # if no mixer is passed and we know the number of qubits, then initialize it. if self.cost_operator is not None: # local imports to avoid circular imports - from qiskit.opflow import PauliSumOp - num_qubits = self.cost_operator.num_qubits # Mixer is just a sum of single qubit X's on each qubit. Evolving by this operator @@ -228,7 +227,7 @@ def mixer_operator(self): mixer_terms = [ ("I" * left + "X" + "I" * (num_qubits - left - 1), 1) for left in range(num_qubits) ] - mixer = PauliSumOp.from_list(mixer_terms) + mixer = SparsePauliOp.from_list(mixer_terms) return mixer # otherwise we cannot provide a default diff --git a/qiskit/opflow/__init__.py b/qiskit/opflow/__init__.py index 35fa212fcc65..9551dd3f318b 100644 --- a/qiskit/opflow/__init__.py +++ b/qiskit/opflow/__init__.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2019, 2020. +# (C) Copyright IBM 2019, 2023. # # 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 @@ -17,6 +17,12 @@ .. currentmodule:: qiskit.opflow +.. deprecated:: 0.24.0 + + The :mod:`qiskit.opflow` module is deprecated and will be removed no earlier + than 3 months after the release date. For code migration guidelines, + visit https://qisk.it/opflow_migration. + Operators and State functions are the building blocks of Quantum Algorithms. A library for Quantum Algorithms & Applications is more than a collection of @@ -77,8 +83,9 @@ Operator Base Class =================== -The OperatorBase serves as the base class for all Operators, State functions and measurements, and -enforces the presence and consistency of methods to manipulate these objects conveniently. +The OperatorBase serves as the base class for all Operators, State functions +and measurements, and enforces the presence and consistency of methods to manipulate these +objects conveniently. .. autosummary:: :toctree: ../stubs/ @@ -91,8 +98,8 @@ Operator Globals ================ -The :mod:`operator_globals` is a set of immutable Operator instances that are convenient building -blocks to reach for while working with the Operator flow. +The :mod:`operator_globals` is a set of immutable Operator instances that are +convenient building blocks to reach for while working with the Operator flow. One qubit Pauli operators: :attr:`X`, :attr:`Y`, :attr:`Z`, :attr:`I` @@ -109,8 +116,8 @@ Operators --------- -The Operators submodules include the PrimitiveOp, ListOp, and StateFn class groups which -represent the primary Operator modules. +The Operators submodules include the PrimitiveOp, ListOp, and StateFn class +groups which represent the primary Operator modules. .. autosummary:: :toctree: ../stubs/ @@ -123,12 +130,12 @@ Converters ---------- -The Converter submodules include objects which manipulate Operators, usually recursing over an -Operator structure and changing certain Operators' representation. For example, the -:class:`~.expectations.PauliExpectation` traverses an Operator structure, and replaces all of the -:class:`~.state_fns.OperatorStateFn` measurements containing non-diagonal Pauli terms into -diagonalizing circuits following by :class:`~.state_fns.OperatorStateFn` measurement containing -only diagonal Paulis. +The Converter submodules include objects which manipulate Operators, +usually recursing over an Operator structure and changing certain Operators' representation. +For example, the :class:`~.expectations.PauliExpectation` traverses an Operator structure, and +replaces all of the :class:`~.state_fns.OperatorStateFn` measurements containing non-diagonal +Pauli terms into diagonalizing circuits following by :class:`~.state_fns.OperatorStateFn` +measurement containing only diagonal Paulis. .. autosummary:: :toctree: ../stubs/ @@ -158,6 +165,7 @@ OpflowError """ +import warnings # New Operators from .operator_base import OperatorBase @@ -320,3 +328,11 @@ "anti_commutator", "double_commutator", ] + +warnings.warn( + "The ``qiskit.opflow`` module is deprecated as of qiskit-terra 0.24.0. " + "It will be removed no earlier than 3 months after the release date. " + "For code migration guidelines, visit https://qisk.it/opflow_migration.", + category=DeprecationWarning, + stacklevel=2, +) diff --git a/qiskit/opflow/converters/__init__.py b/qiskit/opflow/converters/__init__.py index 14272be076fd..8c2236eaec77 100644 --- a/qiskit/opflow/converters/__init__.py +++ b/qiskit/opflow/converters/__init__.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -16,6 +16,12 @@ .. currentmodule:: qiskit.opflow.converters +.. deprecated:: 0.24.0 + + The :mod:`qiskit.opflow` module is deprecated and will be removed no earlier + than 3 months after the release date. For code migration guidelines, + visit https://qisk.it/opflow_migration. + Converters are objects which manipulate Operators, usually traversing an Operator to change certain sub-Operators into a desired representation. Often the converted Operator is isomorphic or approximate to the original Operator in some way, but not always. For example, @@ -31,6 +37,7 @@ exponential in the number of qubits unless a clever trick is known (such as the use of sparse matrices). + Note: Not all converters are in this module, as :mod:`~qiskit.opflow.expectations` and :mod:`~qiskit.opflow.evolutions` are also converters. diff --git a/qiskit/opflow/converters/abelian_grouper.py b/qiskit/opflow/converters/abelian_grouper.py index 1b8b516166a3..fa1d1842a8ed 100644 --- a/qiskit/opflow/converters/abelian_grouper.py +++ b/qiskit/opflow/converters/abelian_grouper.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -27,10 +27,11 @@ from qiskit.opflow.primitive_ops.pauli_op import PauliOp from qiskit.opflow.primitive_ops.pauli_sum_op import PauliSumOp from qiskit.opflow.state_fns.operator_state_fn import OperatorStateFn +from qiskit.utils.deprecation import deprecate_func class AbelianGrouper(ConverterBase): - """The AbelianGrouper converts SummedOps into a sum of Abelian sums. + """Deprecated: The AbelianGrouper converts SummedOps into a sum of Abelian sums. Meaning, it will traverse the Operator, and when it finds a SummedOp, it will evaluate which of the summed sub-Operators commute with one another. It will then convert each of the groups of @@ -41,12 +42,17 @@ class AbelianGrouper(ConverterBase): diagonalized together. """ + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def __init__(self, traverse: bool = True) -> None: """ Args: traverse: Whether to convert only the Operator passed to ``convert``, or traverse down that Operator. """ + super().__init__() self._traverse = traverse def convert(self, operator: OperatorBase) -> OperatorBase: diff --git a/qiskit/opflow/converters/circuit_sampler.py b/qiskit/opflow/converters/circuit_sampler.py index e3641b0c8d6d..e8e5938617e7 100644 --- a/qiskit/opflow/converters/circuit_sampler.py +++ b/qiskit/opflow/converters/circuit_sampler.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -32,13 +32,14 @@ from qiskit.providers import Backend from qiskit.utils.backend_utils import is_aer_provider, is_statevector_backend from qiskit.utils.quantum_instance import QuantumInstance +from qiskit.utils.deprecation import deprecate_func logger = logging.getLogger(__name__) class CircuitSampler(ConverterBase): """ - The CircuitSampler traverses an Operator and converts any CircuitStateFns into + Deprecated: The CircuitSampler traverses an Operator and converts any CircuitStateFns into approximations of the state function by a DictStateFn or VectorStateFn using a quantum backend. Note that in order to approximate the value of the CircuitStateFn, it must 1) send state function through a depolarizing channel, which will destroy all phase information and @@ -51,6 +52,10 @@ class CircuitSampler(ConverterBase): you are better off using a different CircuitSampler for each Operator to avoid cache thrashing. """ + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def __init__( self, backend: Union[Backend, QuantumInstance], @@ -76,6 +81,8 @@ def __init__( Raises: ValueError: Set statevector or param_qobj True when not supported by backend. """ + super().__init__() + self._quantum_instance = ( backend if isinstance(backend, QuantumInstance) else QuantumInstance(backend=backend) ) diff --git a/qiskit/opflow/converters/converter_base.py b/qiskit/opflow/converters/converter_base.py index 996052c872d7..231f3f2daad7 100644 --- a/qiskit/opflow/converters/converter_base.py +++ b/qiskit/opflow/converters/converter_base.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -15,11 +15,12 @@ from abc import ABC, abstractmethod from qiskit.opflow.operator_base import OperatorBase +from qiskit.utils.deprecation import deprecate_func class ConverterBase(ABC): r""" - Converters take an Operator and return a new Operator, generally isomorphic + Deprecated: Converters take an Operator and return a new Operator, generally isomorphic in some way with the first, but with certain desired properties. For example, a converter may accept ``CircuitOp`` and return a ``SummedOp`` of ``PauliOps`` representing the circuit unitary. Converters may not @@ -29,6 +30,13 @@ class ConverterBase(ABC): in the number of qubits unless a clever trick is known (such as the use of sparse matrices).""" + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) + def __init__(self) -> None: + pass + @abstractmethod def convert(self, operator: OperatorBase) -> OperatorBase: """Accept the Operator and return the converted Operator diff --git a/qiskit/opflow/converters/dict_to_circuit_sum.py b/qiskit/opflow/converters/dict_to_circuit_sum.py index a4582ad08d66..b52f16f185c6 100644 --- a/qiskit/opflow/converters/dict_to_circuit_sum.py +++ b/qiskit/opflow/converters/dict_to_circuit_sum.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -18,16 +18,21 @@ from qiskit.opflow.state_fns.circuit_state_fn import CircuitStateFn from qiskit.opflow.state_fns.dict_state_fn import DictStateFn from qiskit.opflow.state_fns.vector_state_fn import VectorStateFn +from qiskit.utils.deprecation import deprecate_func class DictToCircuitSum(ConverterBase): r""" - Converts ``DictStateFns`` or ``VectorStateFns`` to equivalent ``CircuitStateFns`` or sums - thereof. The behavior of this class can be mostly replicated by calling ``to_circuit_op`` on - an Operator, but with the added control of choosing whether to convert only ``DictStateFns`` + Deprecated: Converts ``DictStateFns`` or ``VectorStateFns`` to equivalent ``CircuitStateFns`` + or sums thereof. The behavior of this class can be mostly replicated by calling ``to_circuit_op`` + on an Operator, but with the added control of choosing whether to convert only ``DictStateFns`` or ``VectorStateFns``, rather than both. """ + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def __init__( self, traverse: bool = True, convert_dicts: bool = True, convert_vectors: bool = True ) -> None: @@ -38,6 +43,7 @@ def __init__( convert_dicts: Whether to convert VectorStateFn. convert_vectors: Whether to convert DictStateFns. """ + super().__init__() self._traverse = traverse self._convert_dicts = convert_dicts self._convert_vectors = convert_vectors diff --git a/qiskit/opflow/converters/pauli_basis_change.py b/qiskit/opflow/converters/pauli_basis_change.py index 325f3e875992..5e432e70ffd3 100644 --- a/qiskit/opflow/converters/pauli_basis_change.py +++ b/qiskit/opflow/converters/pauli_basis_change.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -30,11 +30,12 @@ from qiskit.opflow.state_fns.operator_state_fn import OperatorStateFn from qiskit.opflow.state_fns.state_fn import StateFn from qiskit.quantum_info import Pauli +from qiskit.utils.deprecation import deprecate_func class PauliBasisChange(ConverterBase): r""" - Converter for changing Paulis into other bases. By default, the diagonal basis + Deprecated: Converter for changing Paulis into other bases. By default, the diagonal basis composed only of Pauli {Z, I}^n is used as the destination basis to which to convert. Meaning, if a Pauli containing X or Y terms is passed in, which cannot be sampled or evolved natively on some Quantum hardware, the Pauli can be replaced by a @@ -55,6 +56,10 @@ class PauliBasisChange(ConverterBase): this method, such as the placement of the CNOT chains. """ + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def __init__( self, destination_basis: Optional[Union[Pauli, PauliOp]] = None, @@ -83,6 +88,7 @@ def __init__( beginning and ending operators are equivalent. """ + super().__init__() if destination_basis is not None: self.destination = destination_basis # type: ignore else: diff --git a/qiskit/opflow/converters/two_qubit_reduction.py b/qiskit/opflow/converters/two_qubit_reduction.py index 971f09cf880b..10f596f10494 100644 --- a/qiskit/opflow/converters/two_qubit_reduction.py +++ b/qiskit/opflow/converters/two_qubit_reduction.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -20,14 +20,15 @@ from qiskit.opflow.primitive_ops.pauli_sum_op import PauliSumOp from qiskit.opflow.primitive_ops.tapered_pauli_sum_op import Z2Symmetries from qiskit.quantum_info import Pauli +from qiskit.utils.deprecation import deprecate_func logger = logging.getLogger(__name__) class TwoQubitReduction(ConverterBase): """ - Two qubit reduction converter which eliminates the central and last qubit in a list of Pauli - that has diagonal operators (Z,I) at those positions. + Deprecated: Two qubit reduction converter which eliminates the central and last + qubit in a list of Pauli that has diagonal operators (Z,I) at those positions. Chemistry specific method: It can be used to taper two qubits in parity and binary-tree mapped @@ -35,12 +36,17 @@ class TwoQubitReduction(ConverterBase): sectors, (block spin order) according to the number of particles in the system. """ + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def __init__(self, num_particles: Union[int, List[int], Tuple[int, int]]): """ Args: num_particles: number of particles, if it is a list, the first number is alpha and the second number if beta. """ + super().__init__() if isinstance(num_particles, (tuple, list)): num_alpha = num_particles[0] num_beta = num_particles[1] diff --git a/qiskit/opflow/evolutions/__init__.py b/qiskit/opflow/evolutions/__init__.py index 907781c0d100..6bfeb7d1490d 100644 --- a/qiskit/opflow/evolutions/__init__.py +++ b/qiskit/opflow/evolutions/__init__.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -16,8 +16,15 @@ .. currentmodule:: qiskit.opflow.evolutions -Evolutions are converters which traverse an Operator tree, replacing any :class:`EvolvedOp` `e` -with a Schrodinger equation-style evolution :class:`~qiskit.opflow.primitive_ops.CircuitOp` +.. deprecated:: 0.24.0 + + The :mod:`qiskit.opflow` module is deprecated and will be removed no earlier + than 3 months after the release date. For code migration guidelines, + visit https://qisk.it/opflow_migration. + +Evolutions are converters which traverse an Operator tree, replacing +any :class:`EvolvedOp` `e` with a Schrodinger equation-style evolution +:class:`~qiskit.opflow.primitive_ops.CircuitOp` equalling or approximating the matrix exponential of -i * the Operator contained inside (`e.primitive`). The Evolutions are essentially implementations of Hamiltonian Simulation algorithms, including various methods for Trotterization. @@ -28,6 +35,7 @@ ``.exp_i()`` methods which either return the exponential of the Operator directly, or an :class:`EvolvedOp` containing the Operator. + Note: Evolutions work with parameterized Operator coefficients, so ``my_expectation.convert((t * H).exp_i())``, where t is a scalar or Terra Parameter and H diff --git a/qiskit/opflow/evolutions/evolution_base.py b/qiskit/opflow/evolutions/evolution_base.py index e25edfd91c50..1123c36c34a7 100644 --- a/qiskit/opflow/evolutions/evolution_base.py +++ b/qiskit/opflow/evolutions/evolution_base.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -16,11 +16,12 @@ from qiskit.opflow.operator_base import OperatorBase from qiskit.opflow.converters.converter_base import ConverterBase +from qiskit.utils.deprecation import deprecate_func class EvolutionBase(ConverterBase, ABC): r""" - A base for Evolution converters. + Deprecated: A base for Evolution converters. Evolutions are converters which traverse an Operator tree, replacing any ``EvolvedOp`` `e` with a Schrodinger equation-style evolution ``CircuitOp`` equalling or approximating the matrix exponential of -i * the Operator contained inside (`e.primitive`). The Evolutions are @@ -29,6 +30,13 @@ class EvolutionBase(ConverterBase, ABC): """ + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) + def __init__(self) -> None: + super().__init__() + @abstractmethod def convert(self, operator: OperatorBase) -> OperatorBase: """Traverse the operator, replacing any ``EvolutionOps`` with their equivalent evolution diff --git a/qiskit/opflow/evolutions/evolution_factory.py b/qiskit/opflow/evolutions/evolution_factory.py index a4136edfe0bf..fffad684e816 100644 --- a/qiskit/opflow/evolutions/evolution_factory.py +++ b/qiskit/opflow/evolutions/evolution_factory.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -16,14 +16,19 @@ from qiskit.opflow.evolutions.evolution_base import EvolutionBase from qiskit.opflow.evolutions.pauli_trotter_evolution import PauliTrotterEvolution from qiskit.opflow.evolutions.matrix_evolution import MatrixEvolution +from qiskit.utils.deprecation import deprecate_func class EvolutionFactory: - """A factory class for convenient automatic selection of an Evolution algorithm based on the - Operator to be converted. + """Deprecated: A factory class for convenient automatic selection of an + Evolution algorithm based on the Operator to be converted. """ @staticmethod + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def build(operator: OperatorBase = None) -> EvolutionBase: r""" A factory method for convenient automatic selection of an Evolution algorithm based on the diff --git a/qiskit/opflow/evolutions/evolved_op.py b/qiskit/opflow/evolutions/evolved_op.py index 13a3cb13f77f..03771aa52fa8 100644 --- a/qiskit/opflow/evolutions/evolved_op.py +++ b/qiskit/opflow/evolutions/evolved_op.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -27,11 +27,12 @@ from qiskit.opflow.primitive_ops.matrix_op import MatrixOp from qiskit.opflow.primitive_ops.primitive_op import PrimitiveOp from qiskit.quantum_info import Statevector +from qiskit.utils.deprecation import deprecate_func class EvolvedOp(PrimitiveOp): r""" - Class for wrapping Operator Evolutions for compilation (``convert``) by an EvolutionBase + Deprecated: Class for wrapping Operator Evolutions for compilation (``convert``) by an EvolutionBase method later, essentially acting as a placeholder. Note that EvolvedOp is a weird case of PrimitiveOp. It happens to be that it fits into the PrimitiveOp interface nearly perfectly, and it essentially represents a placeholder for a PrimitiveOp later, even though it doesn't @@ -39,6 +40,10 @@ class EvolvedOp(PrimitiveOp): but would have ended up copying and pasting a lot of code from PrimitiveOp.""" primitive: PrimitiveOp + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def __init__( self, primitive: OperatorBase, coeff: Union[complex, ParameterExpression] = 1.0 ) -> None: diff --git a/qiskit/opflow/evolutions/matrix_evolution.py b/qiskit/opflow/evolutions/matrix_evolution.py index 0d64477079ab..8c18a6a57728 100644 --- a/qiskit/opflow/evolutions/matrix_evolution.py +++ b/qiskit/opflow/evolutions/matrix_evolution.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -20,16 +20,24 @@ from qiskit.opflow.operator_base import OperatorBase from qiskit.opflow.primitive_ops.matrix_op import MatrixOp from qiskit.opflow.primitive_ops.pauli_op import PauliOp +from qiskit.utils.deprecation import deprecate_func logger = logging.getLogger(__name__) class MatrixEvolution(EvolutionBase): r""" - Performs Evolution by classical matrix exponentiation, constructing a circuit with + Deprecated: Performs Evolution by classical matrix exponentiation, constructing a circuit with ``UnitaryGates`` or ``HamiltonianGates`` containing the exponentiation of the Operator. """ + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) + def __init__(self) -> None: + super().__init__() + def convert(self, operator: OperatorBase) -> OperatorBase: r""" Traverse the operator, replacing ``EvolvedOps`` with ``CircuitOps`` containing diff --git a/qiskit/opflow/evolutions/pauli_trotter_evolution.py b/qiskit/opflow/evolutions/pauli_trotter_evolution.py index ca7f096a19c8..414ffd5777ca 100644 --- a/qiskit/opflow/evolutions/pauli_trotter_evolution.py +++ b/qiskit/opflow/evolutions/pauli_trotter_evolution.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -32,6 +32,7 @@ from qiskit.opflow.primitive_ops.circuit_op import CircuitOp from qiskit.opflow.primitive_ops.pauli_sum_op import PauliSumOp from qiskit.opflow.primitive_ops.primitive_op import PrimitiveOp +from qiskit.utils.deprecation import deprecate_func # TODO uncomment when we implement Abelian grouped evolution. # from qiskit.opflow.converters.abelian_grouper import AbelianGrouper @@ -41,8 +42,8 @@ class PauliTrotterEvolution(EvolutionBase): r""" - An Evolution algorithm replacing exponentiated sums of Paulis by changing them each to the - Z basis, rotating with an rZ, changing back, and Trotterizing. + Deprecated: An Evolution algorithm replacing exponentiated sums of Paulis by changing + them each to the Z basis, rotating with an rZ, changing back, and Trotterizing. More specifically, we compute basis change circuits for each Pauli into a single-qubit Z, evolve the Z by the desired evolution time with an rZ gate, and change the basis back using @@ -50,6 +51,10 @@ class PauliTrotterEvolution(EvolutionBase): evolution circuits are composed together by Trotterization scheme. """ + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def __init__( self, trotter_mode: Optional[Union[str, TrotterizationBase]] = "trotter", @@ -69,7 +74,7 @@ def __init__( # sub-groups, so a single diagonalization circuit can be used for each group # rather than each Pauli. """ - + super().__init__() if isinstance(trotter_mode, TrotterizationBase): self._trotter = trotter_mode else: diff --git a/qiskit/opflow/evolutions/trotterizations/__init__.py b/qiskit/opflow/evolutions/trotterizations/__init__.py index f177f5ce36c6..a721bec2fee4 100644 --- a/qiskit/opflow/evolutions/trotterizations/__init__.py +++ b/qiskit/opflow/evolutions/trotterizations/__init__.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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,8 +11,8 @@ # that they have been altered from the originals. """ -Trotterization methods - Algorithms for approximating Exponentials of Operator Sums. - +Trotterization methods - Algorithms for +approximating Exponentials of Operator Sums. """ from .trotterization_base import TrotterizationBase diff --git a/qiskit/opflow/evolutions/trotterizations/qdrift.py b/qiskit/opflow/evolutions/trotterizations/qdrift.py index 89c6ced0b144..865cbd1071ae 100644 --- a/qiskit/opflow/evolutions/trotterizations/qdrift.py +++ b/qiskit/opflow/evolutions/trotterizations/qdrift.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020, 2021. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -26,16 +26,21 @@ from qiskit.opflow.primitive_ops.pauli_sum_op import PauliSumOp from qiskit.opflow.primitive_ops.primitive_op import PrimitiveOp from qiskit.utils import algorithm_globals +from qiskit.utils.deprecation import deprecate_func # pylint: disable=invalid-name class QDrift(TrotterizationBase): - """The QDrift Trotterization method, which selects each each term in the + """Deprecated: The QDrift Trotterization method, which selects each each term in the Trotterization randomly, with a probability proportional to its weight. Based on the work of Earl Campbell in https://arxiv.org/abs/1811.08017. """ + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def __init__(self, reps: int = 1) -> None: r""" Args: diff --git a/qiskit/opflow/evolutions/trotterizations/suzuki.py b/qiskit/opflow/evolutions/trotterizations/suzuki.py index 964102f6b2d9..cfe59acac5a8 100644 --- a/qiskit/opflow/evolutions/trotterizations/suzuki.py +++ b/qiskit/opflow/evolutions/trotterizations/suzuki.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -23,17 +23,22 @@ from qiskit.opflow.operator_base import OperatorBase from qiskit.opflow.primitive_ops.pauli_sum_op import PauliSumOp from qiskit.opflow.primitive_ops.primitive_op import PrimitiveOp +from qiskit.utils.deprecation import deprecate_func class Suzuki(TrotterizationBase): r""" - Suzuki Trotter expansion, composing the evolution circuits of each Operator in the sum + Deprecated: Suzuki Trotter expansion, composing the evolution circuits of each Operator in the sum together by a recursive "bookends" strategy, repeating the whole composed circuit ``reps`` times. Detailed in https://arxiv.org/pdf/quant-ph/0508139.pdf. """ + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def __init__(self, reps: int = 1, order: int = 2) -> None: """ Args: diff --git a/qiskit/opflow/evolutions/trotterizations/trotter.py b/qiskit/opflow/evolutions/trotterizations/trotter.py index 2fc0f50d4611..eb1c48d7e27d 100644 --- a/qiskit/opflow/evolutions/trotterizations/trotter.py +++ b/qiskit/opflow/evolutions/trotterizations/trotter.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -13,14 +13,19 @@ """Trotter Class""" from qiskit.opflow.evolutions.trotterizations.suzuki import Suzuki +from qiskit.utils.deprecation import deprecate_func class Trotter(Suzuki): r""" - Simple Trotter expansion, composing the evolution circuits of each Operator in the sum + Deprecated: Simple Trotter expansion, composing the evolution circuits of each Operator in the sum together ``reps`` times and dividing the evolution time of each by ``reps``. """ + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def __init__(self, reps: int = 1) -> None: r""" Args: diff --git a/qiskit/opflow/evolutions/trotterizations/trotterization_base.py b/qiskit/opflow/evolutions/trotterizations/trotterization_base.py index c62c431f2b82..222d338dfdce 100644 --- a/qiskit/opflow/evolutions/trotterizations/trotterization_base.py +++ b/qiskit/opflow/evolutions/trotterizations/trotterization_base.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -16,17 +16,22 @@ from qiskit.opflow.evolutions.evolution_base import EvolutionBase from qiskit.opflow.operator_base import OperatorBase +from qiskit.utils.deprecation import deprecate_func # TODO centralize handling of commuting groups class TrotterizationBase(EvolutionBase): - """A base for Trotterization methods, algorithms for approximating exponentiations of + """Deprecated: A base for Trotterization methods, algorithms for approximating exponentiations of operator sums by compositions of exponentiations. """ + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def __init__(self, reps: int = 1) -> None: - + super().__init__() self._reps = reps @property diff --git a/qiskit/opflow/evolutions/trotterizations/trotterization_factory.py b/qiskit/opflow/evolutions/trotterizations/trotterization_factory.py index 9c0d7d830cb3..f8d119140502 100644 --- a/qiskit/opflow/evolutions/trotterizations/trotterization_factory.py +++ b/qiskit/opflow/evolutions/trotterizations/trotterization_factory.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -16,12 +16,17 @@ from qiskit.opflow.evolutions.trotterizations.suzuki import Suzuki from qiskit.opflow.evolutions.trotterizations.trotter import Trotter from qiskit.opflow.evolutions.trotterizations.trotterization_base import TrotterizationBase +from qiskit.utils.deprecation import deprecate_func class TrotterizationFactory: - """A factory for conveniently creating TrotterizationBase instances.""" + """Deprecated: A factory for conveniently creating TrotterizationBase instances.""" @staticmethod + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def build(mode: str = "trotter", reps: int = 1) -> TrotterizationBase: """A factory for conveniently creating TrotterizationBase instances. diff --git a/qiskit/opflow/exceptions.py b/qiskit/opflow/exceptions.py index bf80dd3d22c6..27bc0f6cc14d 100644 --- a/qiskit/opflow/exceptions.py +++ b/qiskit/opflow/exceptions.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2017, 2018. +# (C) Copyright IBM 2017, 2023. # # 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 @@ -13,9 +13,16 @@ """Exception for errors raised by Opflow module.""" from qiskit.exceptions import QiskitError +from qiskit.utils.deprecation import deprecate_func class OpflowError(QiskitError): - """For Opflow specific errors.""" + """Deprecated: For Opflow specific errors.""" - pass + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) + def __init__(self, *message): + """Set the error message.""" + super().__init__(*message) diff --git a/qiskit/opflow/expectations/__init__.py b/qiskit/opflow/expectations/__init__.py index 8109dc0bad4c..885d4b7e36f6 100644 --- a/qiskit/opflow/expectations/__init__.py +++ b/qiskit/opflow/expectations/__init__.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -16,9 +16,15 @@ .. currentmodule:: qiskit.opflow.expectations -Expectations are converters which enable the computation of the expectation value of an -Observable with respect to some state function. They traverse an Operator tree, replacing -:class:`~qiskit.opflow.state_fns.OperatorStateFn` measurements with equivalent +.. deprecated:: 0.24.0 + + The :mod:`qiskit.opflow` module is deprecated and will be removed no earlier + than 3 months after the release date. For code migration guidelines, + visit https://qisk.it/opflow_migration. + +Expectations are converters which enable the computation of the expectation +value of an Observable with respect to some state function. They traverse an Operator tree, +replacing :class:`~qiskit.opflow.state_fns.OperatorStateFn` measurements with equivalent measurements which are more amenable to computation on quantum or classical hardware. For example, if one would like to measure the expectation value of an Operator ``o`` expressed as a sum of Paulis with respect to some state @@ -28,6 +34,7 @@ a :class:`~qiskit.opflow.converters.CircuitSampler`. All in all, this would be: ``my_sampler.convert(my_expect.convert(~StateFn(o)) @ my_state).eval()``. + Expectation Base Class ---------------------- diff --git a/qiskit/opflow/expectations/aer_pauli_expectation.py b/qiskit/opflow/expectations/aer_pauli_expectation.py index 511565a33f5c..44d8f6ebcb01 100644 --- a/qiskit/opflow/expectations/aer_pauli_expectation.py +++ b/qiskit/opflow/expectations/aer_pauli_expectation.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -28,16 +28,24 @@ from qiskit.opflow.state_fns.circuit_state_fn import CircuitStateFn from qiskit.opflow.state_fns.operator_state_fn import OperatorStateFn from qiskit.quantum_info import SparsePauliOp +from qiskit.utils.deprecation import deprecate_func logger = logging.getLogger(__name__) class AerPauliExpectation(ExpectationBase): - r"""An Expectation converter for using Aer's operator snapshot to + r"""Deprecated: An Expectation converter for using Aer's operator snapshot to take expectations of quantum state circuits over Pauli observables. """ + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) + def __init__(self) -> None: + super().__init__() + def convert(self, operator: OperatorBase) -> OperatorBase: """Accept an Operator and return a new Operator with the Pauli measurements replaced by AerSnapshot-based expectation circuits. diff --git a/qiskit/opflow/expectations/cvar_expectation.py b/qiskit/opflow/expectations/cvar_expectation.py index 641c17f9619f..9a6711c498ae 100644 --- a/qiskit/opflow/expectations/cvar_expectation.py +++ b/qiskit/opflow/expectations/cvar_expectation.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -20,10 +20,11 @@ from qiskit.opflow.list_ops import ComposedOp, ListOp from qiskit.opflow.operator_base import OperatorBase from qiskit.opflow.state_fns import CVaRMeasurement, OperatorStateFn +from qiskit.utils.deprecation import deprecate_func class CVaRExpectation(ExpectationBase): - r"""Compute the Conditional Value at Risk (CVaR) expectation value. + r"""Deprecated: Compute the Conditional Value at Risk (CVaR) expectation value. The standard approach to calculating the expectation value of a Hamiltonian w.r.t. a state is to take the sample mean of the measurement outcomes. This corresponds to an estimator @@ -54,6 +55,10 @@ class CVaRExpectation(ExpectationBase): """ + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def __init__(self, alpha: float, expectation: Optional[ExpectationBase] = None) -> None: """ Args: @@ -64,6 +69,7 @@ def __init__(self, alpha: float, expectation: Optional[ExpectationBase] = None) Raises: NotImplementedError: If the ``expectation`` is an AerPauliExpecation. """ + super().__init__() self.alpha = alpha if isinstance(expectation, AerPauliExpectation): raise NotImplementedError("AerPauliExpecation currently not supported.") diff --git a/qiskit/opflow/expectations/expectation_base.py b/qiskit/opflow/expectations/expectation_base.py index 64a78832ea7f..593c43b83833 100644 --- a/qiskit/opflow/expectations/expectation_base.py +++ b/qiskit/opflow/expectations/expectation_base.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -19,11 +19,12 @@ from qiskit.opflow.converters import ConverterBase from qiskit.opflow.operator_base import OperatorBase +from qiskit.utils.deprecation import deprecate_func class ExpectationBase(ConverterBase): r""" - A base for Expectation value converters. Expectations are converters which enable the + Deprecated: A base for Expectation value converters. Expectations are converters which enable the computation of the expectation value of an Observable with respect to some state function. They traverse an Operator tree, replacing OperatorStateFn measurements with equivalent measurements which are more amenable to computation on quantum or classical hardware. For @@ -37,6 +38,13 @@ class ExpectationBase(ConverterBase): """ + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) + def __init__(self) -> None: + super().__init__() + @abstractmethod def convert(self, operator: OperatorBase) -> OperatorBase: """Accept an Operator and return a new Operator with the measurements replaced by diff --git a/qiskit/opflow/expectations/expectation_factory.py b/qiskit/opflow/expectations/expectation_factory.py index cd3bc262fc20..58a72ed6daca 100644 --- a/qiskit/opflow/expectations/expectation_factory.py +++ b/qiskit/opflow/expectations/expectation_factory.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -22,18 +22,24 @@ from qiskit.opflow.expectations.pauli_expectation import PauliExpectation from qiskit.opflow.operator_base import OperatorBase from qiskit.providers import Backend -from qiskit.utils.backend_utils import has_aer, is_aer_qasm, is_statevector_backend -from qiskit.utils.quantum_instance import QuantumInstance +from qiskit.utils.backend_utils import is_aer_qasm, is_statevector_backend +from qiskit.utils import QuantumInstance, optionals +from qiskit.utils.deprecation import deprecate_func logger = logging.getLogger(__name__) class ExpectationFactory: - """A factory class for convenient automatic selection of an Expectation based on the + + """Deprecated: factory class for convenient automatic selection of an Expectation based on the Operator to be converted and backend used to sample the expectation value. """ @staticmethod + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def build( operator: OperatorBase, backend: Optional[Union[Backend, QuantumInstance]] = None, @@ -68,10 +74,10 @@ def build( if backend_to_check is None: # If user has Aer but didn't specify a backend, use the Aer fast expectation - if has_aer(): - from qiskit import Aer + if optionals.HAS_AER: + from qiskit_aer import AerSimulator - backend_to_check = Aer.get_backend("qasm_simulator") + backend_to_check = AerSimulator() # If user doesn't have Aer, use statevector_simulator # for < 16 qubits, and qasm with warning for more. else: diff --git a/qiskit/opflow/expectations/matrix_expectation.py b/qiskit/opflow/expectations/matrix_expectation.py index b6979f02f96f..dcd2d64adb08 100644 --- a/qiskit/opflow/expectations/matrix_expectation.py +++ b/qiskit/opflow/expectations/matrix_expectation.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -18,11 +18,19 @@ from qiskit.opflow.list_ops import ComposedOp, ListOp from qiskit.opflow.operator_base import OperatorBase from qiskit.opflow.state_fns.operator_state_fn import OperatorStateFn +from qiskit.utils.deprecation import deprecate_func class MatrixExpectation(ExpectationBase): - """An Expectation converter which converts Operator measurements to be matrix-based so they - can be evaluated by matrix multiplication.""" + """Deprecated: An Expectation converter which converts Operator measurements to + be matrix-based so they can be evaluated by matrix multiplication.""" + + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) + def __init__(self) -> None: + super().__init__() def convert(self, operator: OperatorBase) -> OperatorBase: """Accept an Operator and return a new Operator with the Pauli measurements replaced by diff --git a/qiskit/opflow/expectations/pauli_expectation.py b/qiskit/opflow/expectations/pauli_expectation.py index 0bf31eff2682..0305fc90250a 100644 --- a/qiskit/opflow/expectations/pauli_expectation.py +++ b/qiskit/opflow/expectations/pauli_expectation.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -27,13 +27,14 @@ from qiskit.opflow.primitive_ops.primitive_op import PrimitiveOp from qiskit.opflow.state_fns.operator_state_fn import OperatorStateFn from qiskit.opflow.state_fns.state_fn import StateFn +from qiskit.utils.deprecation import deprecate_func logger = logging.getLogger(__name__) class PauliExpectation(ExpectationBase): r""" - An Expectation converter for Pauli-basis observables by changing Pauli measurements to a + Deprecated: An Expectation converter for Pauli-basis observables by changing Pauli measurements to a diagonal ({Z, I}^n) basis and appending circuit post-rotations to the measured state function. Optionally groups the Paulis with the same post-rotations (those that commute with one another, or form Abelian groups) into single measurements to reduce circuit execution @@ -41,6 +42,10 @@ class PauliExpectation(ExpectationBase): """ + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def __init__(self, group_paulis: bool = True) -> None: """ Args: @@ -48,6 +53,7 @@ def __init__(self, group_paulis: bool = True) -> None: have the same diagonalizing circuit. """ + super().__init__() self._grouper = AbelianGrouper() if group_paulis else None def convert(self, operator: OperatorBase) -> OperatorBase: diff --git a/qiskit/opflow/gradients/__init__.py b/qiskit/opflow/gradients/__init__.py index 01c4b02a62eb..9c2625d078ca 100644 --- a/qiskit/opflow/gradients/__init__.py +++ b/qiskit/opflow/gradients/__init__.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -14,13 +14,20 @@ Gradients (:mod:`qiskit.opflow.gradients`) ========================================== -Given an operator that represents either a quantum state resp. an expectation value, the gradient -framework enables the evaluation of gradients, natural gradients, Hessians, as well as the Quantum -Fisher Information. +.. deprecated:: 0.24.0 + + The :mod:`qiskit.opflow` module is deprecated and will be removed no earlier + than 3 months after the release date. For code migration guidelines, + visit https://qisk.it/opflow_migration. + +Given an operator that represents either a quantum state resp. an expectation value, +the gradient framework enables the evaluation of gradients, natural gradients, +Hessians, as well as the Quantum Fisher Information. Suppose a parameterized quantum state `|ψ(θ)〉 = V(θ)|ψ〉` with input state `|ψ〉` and parameterized Ansatz `V(θ)`, and an Operator `O(ω)`. + **Gradients** We want to compute one of: diff --git a/qiskit/opflow/gradients/circuit_gradients/__init__.py b/qiskit/opflow/gradients/circuit_gradients/__init__.py index eae08898049a..16953b57ff21 100644 --- a/qiskit/opflow/gradients/circuit_gradients/__init__.py +++ b/qiskit/opflow/gradients/circuit_gradients/__init__.py @@ -10,8 +10,9 @@ # copyright notice, and modified files need to carry a notice indicating # that they have been altered from the originals. -"""The module for Aqua's first order derivatives.""" - +""" +The module for first order derivatives. +""" from .circuit_gradient import CircuitGradient from .lin_comb import LinComb from .param_shift import ParamShift diff --git a/qiskit/opflow/gradients/circuit_gradients/circuit_gradient.py b/qiskit/opflow/gradients/circuit_gradients/circuit_gradient.py index 576094758fb9..284cd7da7eb7 100644 --- a/qiskit/opflow/gradients/circuit_gradients/circuit_gradient.py +++ b/qiskit/opflow/gradients/circuit_gradients/circuit_gradient.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -17,12 +17,13 @@ from qiskit import QuantumCircuit, QiskitError, transpile from qiskit.circuit import ParameterExpression, ParameterVector +from qiskit.utils.deprecation import deprecate_func from ...converters.converter_base import ConverterBase from ...operator_base import OperatorBase class CircuitGradient(ConverterBase): - r"""Circuit to gradient operator converter. + r"""Deprecated: Circuit to gradient operator converter. Converter for changing parameterized circuits into operators whose evaluation yields the gradient with respect to the circuit parameters. @@ -35,6 +36,14 @@ class CircuitGradient(ConverterBase): DerivativeBase - uses classical techniques to differentiate operator flow data structures """ + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) + def __init__(self) -> None: + super().__init__() + + # pylint: disable=arguments-differ @abstractmethod def convert( self, diff --git a/qiskit/opflow/gradients/circuit_gradients/lin_comb.py b/qiskit/opflow/gradients/circuit_gradients/lin_comb.py index 4db33fffb761..361d13112e85 100644 --- a/qiskit/opflow/gradients/circuit_gradients/lin_comb.py +++ b/qiskit/opflow/gradients/circuit_gradients/lin_comb.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020, 2021. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -50,6 +50,7 @@ ZGate, ) from qiskit.quantum_info import partial_trace +from qiskit.utils.deprecation import deprecate_func from ...operator_base import OperatorBase from ...list_ops.list_op import ListOp from ...list_ops.composed_op import ComposedOp @@ -67,7 +68,7 @@ class LinComb(CircuitGradient): - """Compute the state gradient d⟨ψ(ω)|O(θ)|ψ(ω)〉/ dω respectively the gradients of the + """Deprecated: Compute the state gradient d⟨ψ(ω)|O(θ)|ψ(ω)〉/ dω respectively the gradients of the sampling probabilities of the basis states of a state |ψ(ω)〉w.r.t. ω. This method employs a linear combination of unitaries, @@ -99,7 +100,11 @@ class LinComb(CircuitGradient): "z", } - # pylint: disable=signature-differs + # pylint: disable=signature-differs, arguments-differ + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def __init__(self, aux_meas_op: OperatorBase = Z): """ Args: diff --git a/qiskit/opflow/gradients/circuit_gradients/param_shift.py b/qiskit/opflow/gradients/circuit_gradients/param_shift.py index 435914f9f342..5329cc4c14c0 100644 --- a/qiskit/opflow/gradients/circuit_gradients/param_shift.py +++ b/qiskit/opflow/gradients/circuit_gradients/param_shift.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -22,6 +22,7 @@ from qiskit import QuantumCircuit from qiskit.circuit import Parameter, ParameterExpression, ParameterVector +from qiskit.utils.deprecation import deprecate_func from .circuit_gradient import CircuitGradient from ...operator_base import OperatorBase from ...state_fns.state_fn import StateFn @@ -39,13 +40,17 @@ class ParamShift(CircuitGradient): - """Compute the gradient d⟨ψ(ω)|O(θ)|ψ(ω)〉/ dω respectively the gradients of the sampling + """Deprecated: Compute the gradient d⟨ψ(ω)|O(θ)|ψ(ω)〉/ dω respectively the gradients of the sampling probabilities of the basis states of a state |ψ(ω)〉w.r.t. ω with the parameter shift method. """ SUPPORTED_GATES = {"x", "y", "z", "h", "rx", "ry", "rz", "p", "u", "cx", "cy", "cz"} + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def __init__(self, analytic: bool = True, epsilon: float = 1e-6): r""" Args: @@ -57,7 +62,7 @@ def __init__(self, analytic: bool = True, epsilon: float = 1e-6): Raises: ValueError: If method != ``fin_diff`` and ``epsilon`` is not None. """ - + super().__init__() self._analytic = analytic self._epsilon = epsilon diff --git a/qiskit/opflow/gradients/circuit_qfis/circuit_qfi.py b/qiskit/opflow/gradients/circuit_qfis/circuit_qfi.py index 02058f25e6a0..9a11d619e6c7 100644 --- a/qiskit/opflow/gradients/circuit_qfis/circuit_qfi.py +++ b/qiskit/opflow/gradients/circuit_qfis/circuit_qfi.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -16,12 +16,13 @@ from typing import List, Union from qiskit.circuit import ParameterExpression, ParameterVector +from qiskit.utils.deprecation import deprecate_func from ...converters.converter_base import ConverterBase from ...operator_base import OperatorBase class CircuitQFI(ConverterBase): - r"""Circuit to Quantum Fisher Information operator converter. + r"""Deprecated: Circuit to Quantum Fisher Information operator converter. Converter for changing parameterized circuits into operators whose evaluation yields Quantum Fisher Information metric tensor @@ -35,6 +36,13 @@ class CircuitQFI(ConverterBase): DerivativeBase - uses classical techniques to differentiate opflow data structures """ + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) + def __init__(self) -> None: + super().__init__() + # pylint: disable=arguments-differ @abstractmethod def convert( diff --git a/qiskit/opflow/gradients/circuit_qfis/lin_comb_full.py b/qiskit/opflow/gradients/circuit_qfis/lin_comb_full.py index 81f00eb5cfc0..71f4eea3d8c2 100644 --- a/qiskit/opflow/gradients/circuit_qfis/lin_comb_full.py +++ b/qiskit/opflow/gradients/circuit_qfis/lin_comb_full.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020, 2021. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -17,7 +17,7 @@ import numpy as np from qiskit.circuit import QuantumCircuit, QuantumRegister, ParameterVector, ParameterExpression from qiskit.utils.arithmetic import triu_to_dense - +from qiskit.utils.deprecation import deprecate_func from ...operator_base import OperatorBase from ...list_ops.list_op import ListOp from ...list_ops.summed_op import SummedOp @@ -29,12 +29,17 @@ class LinCombFull(CircuitQFI): - r"""Compute the full Quantum Fisher Information (QFI). + r"""Deprecated: Compute the full Quantum Fisher Information (QFI). Given a pure, parameterized quantum state this class uses the linear combination of unitaries See also :class:`~qiskit.opflow.QFI`. """ + # pylint: disable=signature-differs, arguments-differ + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def __init__( self, aux_meas_op: OperatorBase = Z, diff --git a/qiskit/opflow/gradients/circuit_qfis/overlap_block_diag.py b/qiskit/opflow/gradients/circuit_qfis/overlap_block_diag.py index 7daf6486685c..86b0bd1094cf 100644 --- a/qiskit/opflow/gradients/circuit_qfis/overlap_block_diag.py +++ b/qiskit/opflow/gradients/circuit_qfis/overlap_block_diag.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -18,6 +18,7 @@ from scipy.linalg import block_diag from qiskit.circuit import Parameter, ParameterVector, ParameterExpression from qiskit.utils.arithmetic import triu_to_dense +from qiskit.utils.deprecation import deprecate_func from ...list_ops.list_op import ListOp from ...primitive_ops.circuit_op import CircuitOp from ...expectations.pauli_expectation import PauliExpectation @@ -32,12 +33,19 @@ class OverlapBlockDiag(CircuitQFI): - r"""Compute the block-diagonal of the QFI given a pure, parameterized quantum state. + r"""Deprecated: Compute the block-diagonal of the QFI given a pure, parameterized quantum state. The blocks are given by all parameterized gates in quantum circuit layer. See also :class:`~qiskit.opflow.QFI`. """ + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) + def __init__(self) -> None: + super().__init__() + def convert( self, operator: Union[CircuitOp, CircuitStateFn], diff --git a/qiskit/opflow/gradients/circuit_qfis/overlap_diag.py b/qiskit/opflow/gradients/circuit_qfis/overlap_diag.py index 9efca9f6791b..3f630fe304b9 100644 --- a/qiskit/opflow/gradients/circuit_qfis/overlap_diag.py +++ b/qiskit/opflow/gradients/circuit_qfis/overlap_diag.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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,6 +11,7 @@ # that they have been altered from the originals. """The module for Quantum the Fisher Information.""" + import copy from typing import List, Union @@ -18,6 +19,7 @@ from qiskit.circuit import ParameterVector, ParameterExpression from qiskit.circuit.library import RZGate, RXGate, RYGate from qiskit.converters import dag_to_circuit, circuit_to_dag +from qiskit.utils.deprecation import deprecate_func from ...list_ops.list_op import ListOp from ...primitive_ops.circuit_op import CircuitOp from ...expectations.pauli_expectation import PauliExpectation @@ -31,11 +33,18 @@ class OverlapDiag(CircuitQFI): - r"""Compute the diagonal of the QFI given a pure, parameterized quantum state. + r"""Deprecated: Compute the diagonal of the QFI given a pure, parameterized quantum state. See also :class:`~qiskit.opflow.QFI`. """ + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) + def __init__(self) -> None: + super().__init__() + def convert( self, operator: Union[CircuitOp, CircuitStateFn], diff --git a/qiskit/opflow/gradients/derivative_base.py b/qiskit/opflow/gradients/derivative_base.py index 83b71621b29e..9ffbc6f0cdf0 100644 --- a/qiskit/opflow/gradients/derivative_base.py +++ b/qiskit/opflow/gradients/derivative_base.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -20,7 +20,6 @@ from qiskit.utils.quantum_instance import QuantumInstance from qiskit.circuit import ParameterExpression, ParameterVector from qiskit.providers import Backend - from ..converters.converter_base import ConverterBase from ..expectations import ExpectationBase, PauliExpectation from ..list_ops.composed_op import ComposedOp @@ -34,7 +33,7 @@ class DerivativeBase(ConverterBase): - r"""Base class for differentiating opflow objects. + r"""Deprecated: Base class for differentiating opflow objects. Converter for differentiating opflow objects and handling things like properly differentiating combo_fn's and enforcing product rules @@ -48,6 +47,14 @@ class DerivativeBase(ConverterBase): DerivativeBase - uses classical techniques to differentiate opflow data structures """ + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) + def __init__(self) -> None: + super().__init__() + + # pylint: disable=arguments-differ @abstractmethod def convert( self, diff --git a/qiskit/opflow/gradients/gradient.py b/qiskit/opflow/gradients/gradient.py index 1b7e6fd10333..b65784127a5a 100644 --- a/qiskit/opflow/gradients/gradient.py +++ b/qiskit/opflow/gradients/gradient.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -19,6 +19,8 @@ from qiskit.circuit.quantumcircuit import _compare_parameters from qiskit.circuit import ParameterExpression, ParameterVector from qiskit.utils import optionals as _optionals +from qiskit.utils.deprecation import deprecate_func +from .circuit_gradients.circuit_gradient import CircuitGradient from ..expectations.pauli_expectation import PauliExpectation from .gradient_base import GradientBase from .derivative_base import _coeff_derivative @@ -33,7 +35,14 @@ class Gradient(GradientBase): - """Convert an operator expression to the first-order gradient.""" + """Deprecated: Convert an operator expression to the first-order gradient.""" + + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) + def __init__(self, grad_method: Union[str, CircuitGradient] = "param_shift", **kwargs): + super().__init__(grad_method=grad_method, **kwargs) def convert( self, diff --git a/qiskit/opflow/gradients/gradient_base.py b/qiskit/opflow/gradients/gradient_base.py index af38b5150b1c..f8da278acc93 100644 --- a/qiskit/opflow/gradients/gradient_base.py +++ b/qiskit/opflow/gradients/gradient_base.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -14,16 +14,21 @@ from typing import Union +from qiskit.utils.deprecation import deprecate_func from .circuit_gradients.circuit_gradient import CircuitGradient from .derivative_base import DerivativeBase class GradientBase(DerivativeBase): - """Base class for first-order operator gradient. + """Deprecated: Base class for first-order operator gradient. Convert an operator expression to the first-order gradient. """ + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def __init__(self, grad_method: Union[str, CircuitGradient] = "param_shift", **kwargs): r""" Args: @@ -35,7 +40,7 @@ def __init__(self, grad_method: Union[str, CircuitGradient] = "param_shift", **k Raises: ValueError: If method != ``fin_diff`` and ``epsilon`` is not None. """ - + super().__init__() if isinstance(grad_method, CircuitGradient): self._grad_method = grad_method elif grad_method == "param_shift": diff --git a/qiskit/opflow/gradients/hessian.py b/qiskit/opflow/gradients/hessian.py index 60a05d131fb4..d25de4ad4cae 100644 --- a/qiskit/opflow/gradients/hessian.py +++ b/qiskit/opflow/gradients/hessian.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -19,6 +19,7 @@ from qiskit.circuit.quantumcircuit import _compare_parameters from qiskit.circuit import ParameterVector, ParameterExpression from qiskit.utils import optionals as _optionals +from qiskit.utils.deprecation import deprecate_func from ..operator_globals import Zero, One from ..state_fns.circuit_state_fn import CircuitStateFn from ..state_fns.state_fn import StateFn @@ -33,10 +34,18 @@ from .hessian_base import HessianBase from ..exceptions import OpflowError from ...utils.arithmetic import triu_to_dense +from .circuit_gradients.circuit_gradient import CircuitGradient class Hessian(HessianBase): - """Compute the Hessian of an expected value.""" + """Deprecated: Compute the Hessian of an expected value.""" + + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) + def __init__(self, hess_method: Union[str, CircuitGradient] = "param_shift", **kwargs): + super().__init__(hess_method=hess_method, **kwargs) def convert( self, diff --git a/qiskit/opflow/gradients/hessian_base.py b/qiskit/opflow/gradients/hessian_base.py index 4ed5b3381821..2230ec28d824 100644 --- a/qiskit/opflow/gradients/hessian_base.py +++ b/qiskit/opflow/gradients/hessian_base.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -14,13 +14,18 @@ from typing import Union +from qiskit.utils.deprecation import deprecate_func from .circuit_gradients.circuit_gradient import CircuitGradient from .derivative_base import DerivativeBase class HessianBase(DerivativeBase): - """Base class for the Hessian of an expected value.""" + """Deprecated: Base class for the Hessian of an expected value.""" + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def __init__(self, hess_method: Union[str, CircuitGradient] = "param_shift", **kwargs): r""" Args: @@ -32,7 +37,7 @@ def __init__(self, hess_method: Union[str, CircuitGradient] = "param_shift", **k Raises: ValueError: If method != ``fin_diff`` and ``epsilon`` is not None. """ - + super().__init__() if isinstance(hess_method, CircuitGradient): self._hess_method = hess_method elif hess_method == "param_shift": diff --git a/qiskit/opflow/gradients/natural_gradient.py b/qiskit/opflow/gradients/natural_gradient.py index d957f3114918..9866b79e943b 100644 --- a/qiskit/opflow/gradients/natural_gradient.py +++ b/qiskit/opflow/gradients/natural_gradient.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2018, 2020. +# (C) Copyright IBM 2018, 2023. # # 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 @@ -20,6 +20,7 @@ from qiskit.circuit.quantumcircuit import _compare_parameters from qiskit.circuit import ParameterVector, ParameterExpression from qiskit.utils import optionals as _optionals +from qiskit.utils.deprecation import deprecate_func from ..operator_base import OperatorBase from ..list_ops.list_op import ListOp from ..list_ops.composed_op import ComposedOp @@ -37,7 +38,7 @@ class NaturalGradient(GradientBase): - r"""Convert an operator expression to the first-order gradient. + r"""Deprecated: Convert an operator expression to the first-order gradient. Given an ill-posed inverse problem @@ -51,6 +52,10 @@ class NaturalGradient(GradientBase): where R(x) represents the penalization term. """ + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def __init__( self, grad_method: Union[str, CircuitGradient] = "lin_comb", diff --git a/qiskit/opflow/gradients/qfi.py b/qiskit/opflow/gradients/qfi.py index f9bd289aaa0e..64ba631455d2 100644 --- a/qiskit/opflow/gradients/qfi.py +++ b/qiskit/opflow/gradients/qfi.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -17,14 +17,16 @@ from qiskit.circuit.quantumcircuit import _compare_parameters from qiskit.circuit import ParameterExpression, ParameterVector +from qiskit.utils.deprecation import deprecate_func from ..list_ops.list_op import ListOp from ..expectations.pauli_expectation import PauliExpectation from ..state_fns.circuit_state_fn import CircuitStateFn from .qfi_base import QFIBase +from .circuit_qfis import CircuitQFI class QFI(QFIBase): - r"""Compute the Quantum Fisher Information (QFI). + r"""Deprecated: Compute the Quantum Fisher Information (QFI). Computes the QFI given a pure, parameterized quantum state, where QFI is: @@ -35,6 +37,13 @@ class QFI(QFIBase): """ + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) + def __init__(self, qfi_method: Union[str, CircuitQFI] = "lin_comb_full"): + super().__init__(qfi_method=qfi_method) + def convert( self, operator: CircuitStateFn, diff --git a/qiskit/opflow/gradients/qfi_base.py b/qiskit/opflow/gradients/qfi_base.py index b0497de840d3..b09f9170dbad 100644 --- a/qiskit/opflow/gradients/qfi_base.py +++ b/qiskit/opflow/gradients/qfi_base.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -14,12 +14,14 @@ from typing import Union +from qiskit.utils.deprecation import deprecate_func from .derivative_base import DerivativeBase from .circuit_qfis import CircuitQFI class QFIBase(DerivativeBase): - r"""Base class for Quantum Fisher Information (QFI). + + r"""Deprecated: Base class for Quantum Fisher Information (QFI). Compute the Quantum Fisher Information (QFI) given a pure, parameterized quantum state. @@ -28,6 +30,10 @@ class QFIBase(DerivativeBase): [QFI]kl= Re[〈∂kψ|∂lψ〉−〈∂kψ|ψ〉〈ψ|∂lψ〉] * 4. """ + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def __init__(self, qfi_method: Union[str, CircuitQFI] = "lin_comb_full"): r""" Args: @@ -38,7 +44,7 @@ def __init__(self, qfi_method: Union[str, CircuitQFI] = "lin_comb_full"): ValueError: if ``qfi_method`` is neither a ``CircuitQFI`` object nor one of the predefined strings. """ - + super().__init__() if isinstance(qfi_method, CircuitQFI): self._qfi_method = qfi_method diff --git a/qiskit/opflow/list_ops/__init__.py b/qiskit/opflow/list_ops/__init__.py index d2ae28d1f05b..b4e4a45b3d72 100644 --- a/qiskit/opflow/list_ops/__init__.py +++ b/qiskit/opflow/list_ops/__init__.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -16,6 +16,12 @@ .. currentmodule:: qiskit.opflow.list_ops +.. deprecated:: 0.24.0 + + The :mod:`qiskit.opflow` module is deprecated and will be removed no earlier + than 3 months after the release date. For code migration guidelines, + visit https://qisk.it/opflow_migration. + List Operators are classes for storing and manipulating lists of Operators, State functions, or Measurements, and include some rule or ``combo_fn`` defining how the Operator functions of the list constituents should be combined to form to cumulative Operator function of the @@ -31,6 +37,7 @@ :mod:`.list_ops` are the basis for constructing large and sophisticated Operators, State Functions, and Measurements. + The base :class:`ListOp` class is particularly interesting, as its ``combo_fn`` is "the identity list Operation". Meaning, if we understand the ``combo_fn`` as a function from a list of complex values to some output, one such function is returning the list as\-is. This is powerful for diff --git a/qiskit/opflow/list_ops/composed_op.py b/qiskit/opflow/list_ops/composed_op.py index 1c2dd46dd434..d47a81fbd796 100644 --- a/qiskit/opflow/list_ops/composed_op.py +++ b/qiskit/opflow/list_ops/composed_op.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -24,15 +24,20 @@ from qiskit.opflow.list_ops.list_op import ListOp from qiskit.opflow.operator_base import OperatorBase from qiskit.quantum_info import Statevector +from qiskit.utils.deprecation import deprecate_func class ComposedOp(ListOp): - """A class for lazily representing compositions of Operators. Often Operators cannot be + """Deprecated: A class for lazily representing compositions of Operators. Often Operators cannot be efficiently composed with one another, but may be manipulated further so that they can be composed later. This class holds logic to indicate that the Operators in ``oplist`` are meant to be composed, and therefore if they reach a point in which they can be, such as after conversion to QuantumCircuits or matrices, they can be reduced by composition.""" + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def __init__( self, oplist: List[OperatorBase], diff --git a/qiskit/opflow/list_ops/list_op.py b/qiskit/opflow/list_ops/list_op.py index 775f82164eca..abf2d2326d0c 100644 --- a/qiskit/opflow/list_ops/list_op.py +++ b/qiskit/opflow/list_ops/list_op.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -23,12 +23,13 @@ from qiskit.opflow.operator_base import OperatorBase from qiskit.quantum_info import Statevector from qiskit.utils import arithmetic +from qiskit.utils.deprecation import deprecate_func class ListOp(OperatorBase): """ - A Class for manipulating List Operators, and parent class to ``SummedOp``, ``ComposedOp``, - and ``TensoredOp``. + Deprecated: A Class for manipulating List Operators, and parent class to ``SummedOp``, + ``ComposedOp`` and ``TensoredOp``. List Operators are classes for storing and manipulating lists of Operators, State functions, or Measurements, and include some rule or ``combo_fn`` defining how the Operator functions @@ -52,6 +53,10 @@ class ListOp(OperatorBase): multiple dimensional lists. """ + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def __init__( self, oplist: Sequence[OperatorBase], diff --git a/qiskit/opflow/list_ops/summed_op.py b/qiskit/opflow/list_ops/summed_op.py index 525e973a562a..52f7faa15083 100644 --- a/qiskit/opflow/list_ops/summed_op.py +++ b/qiskit/opflow/list_ops/summed_op.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -21,15 +21,20 @@ from qiskit.opflow.exceptions import OpflowError from qiskit.opflow.list_ops.list_op import ListOp from qiskit.opflow.operator_base import OperatorBase +from qiskit.utils.deprecation import deprecate_func class SummedOp(ListOp): - """A class for lazily representing sums of Operators. Often Operators cannot be + """Deprecated: A class for lazily representing sums of Operators. Often Operators cannot be efficiently added to one another, but may be manipulated further so that they can be later. This class holds logic to indicate that the Operators in ``oplist`` are meant to be added together, and therefore if they reach a point in which they can be, such as after evaluation or conversion to matrices, they can be reduced by addition.""" + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def __init__( self, oplist: List[OperatorBase], diff --git a/qiskit/opflow/list_ops/tensored_op.py b/qiskit/opflow/list_ops/tensored_op.py index 427703a261d9..e3eb30cfaa41 100644 --- a/qiskit/opflow/list_ops/tensored_op.py +++ b/qiskit/opflow/list_ops/tensored_op.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -22,15 +22,20 @@ from qiskit.opflow.list_ops.list_op import ListOp from qiskit.opflow.operator_base import OperatorBase from qiskit.quantum_info import Statevector +from qiskit.utils.deprecation import deprecate_func class TensoredOp(ListOp): - """A class for lazily representing tensor products of Operators. Often Operators cannot be - efficiently tensored to one another, but may be manipulated further so that they can be + """Deprecated: A class for lazily representing tensor products of Operators. Often Operators + cannot be efficiently tensored to one another, but may be manipulated further so that they can be later. This class holds logic to indicate that the Operators in ``oplist`` are meant to be tensored together, and therefore if they reach a point in which they can be, such as after conversion to QuantumCircuits, they can be reduced by tensor product.""" + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def __init__( self, oplist: List[OperatorBase], diff --git a/qiskit/opflow/mixins/star_algebra.py b/qiskit/opflow/mixins/star_algebra.py index 30ba75b8ffeb..642086d5ba04 100644 --- a/qiskit/opflow/mixins/star_algebra.py +++ b/qiskit/opflow/mixins/star_algebra.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2021. +# (C) Copyright IBM 2021, 2023. # # 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 @@ -16,10 +16,11 @@ from numbers import Integral from qiskit.quantum_info.operators.mixins import MultiplyMixin +from qiskit.utils.deprecation import deprecate_func class StarAlgebraMixin(MultiplyMixin, ABC): - """The star algebra mixin class. + """Deprecated: The star algebra mixin class. Star algebra is an algebra with an adjoint. This class overrides: @@ -39,6 +40,13 @@ class StarAlgebraMixin(MultiplyMixin, ABC): - :meth:`adjoint(self)` """ + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) + def __init__(self) -> None: + pass + # Scalar multiplication @abstractmethod diff --git a/qiskit/opflow/mixins/tensor.py b/qiskit/opflow/mixins/tensor.py index dfec66d5674d..3535db439f09 100644 --- a/qiskit/opflow/mixins/tensor.py +++ b/qiskit/opflow/mixins/tensor.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2021. +# (C) Copyright IBM 2021, 2023. # # 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 @@ -14,10 +14,11 @@ from abc import ABC, abstractmethod from numbers import Integral +from qiskit.utils.deprecation import deprecate_func class TensorMixin(ABC): - """The mixin class for tensor operations. + """Deprecated: The mixin class for tensor operations. This class overrides: - ``^``, ``__xor__``, `__rxor__` -> :meth:`tensor` between two operators and @@ -27,6 +28,13 @@ class TensorMixin(ABC): - :meth:``tensorpower(self, other: int)`` """ + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) + def __init__(self) -> None: + pass + def __xor__(self, other): if isinstance(other, Integral): return self.tensorpower(other) diff --git a/qiskit/opflow/operator_base.py b/qiskit/opflow/operator_base.py index 713cbe38384b..7c1e031d8620 100644 --- a/qiskit/opflow/operator_base.py +++ b/qiskit/opflow/operator_base.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020, 2021. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -25,10 +25,11 @@ from qiskit.opflow.mixins import StarAlgebraMixin, TensorMixin from qiskit.quantum_info import Statevector from qiskit.utils import algorithm_globals +from qiskit.utils.deprecation import deprecate_func class OperatorBase(StarAlgebraMixin, TensorMixin, ABC): - """A base class for all Operators: PrimitiveOps, StateFns, ListOps, etc. Operators are + """Deprecated: A base class for all Operators: PrimitiveOps, StateFns, ListOps, etc. Operators are defined as functions which take one complex binary function to another. These complex binary functions are represented by StateFns, which are themselves a special class of Operators taking only the ``Zero`` StateFn to the complex binary function they represent. @@ -44,7 +45,12 @@ class OperatorBase(StarAlgebraMixin, TensorMixin, ABC): _count = itertools.count() + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def __init__(self) -> None: + super().__init__() self._instance_id = next(self._count) @property diff --git a/qiskit/opflow/operator_globals.py b/qiskit/opflow/operator_globals.py index 7fb3796ea8a9..a5afcd9cf08f 100644 --- a/qiskit/opflow/operator_globals.py +++ b/qiskit/opflow/operator_globals.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -20,6 +20,7 @@ from qiskit.opflow.primitive_ops.pauli_op import PauliOp from qiskit.opflow.primitive_ops.circuit_op import CircuitOp from qiskit.opflow.state_fns.dict_state_fn import DictStateFn +from qiskit.utils.deprecation import deprecate_func # Digits of precision when returning values from eval functions. Without rounding, 1e-17 or 1e-32 # values often show up in place of 0, etc. @@ -32,8 +33,12 @@ # Immutable convenience objects +@deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", +) def make_immutable(obj): - """Delete the __setattr__ property to make the object mostly immutable.""" + r"""Deprecate\: Delete the __setattr__ property to make the object mostly immutable.""" # TODO figure out how to get correct error message # def throw_immutability_exception(self, *args): diff --git a/qiskit/opflow/primitive_ops/__init__.py b/qiskit/opflow/primitive_ops/__init__.py index 1af655893599..7e5cc72fad6b 100644 --- a/qiskit/opflow/primitive_ops/__init__.py +++ b/qiskit/opflow/primitive_ops/__init__.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -16,6 +16,12 @@ .. currentmodule:: qiskit.opflow.primitive_ops +.. deprecated:: 0.24.0 + + The :mod:`qiskit.opflow` module is deprecated and will be removed no earlier + than 3 months after the release date. For code migration guidelines, + visit https://qisk.it/opflow_migration. + Operators are defined to be functions which take State functions to State functions. PrimitiveOps are the classes for representing basic Operators, backed by computational diff --git a/qiskit/opflow/primitive_ops/circuit_op.py b/qiskit/opflow/primitive_ops/circuit_op.py index 916a93c132fb..1a6104a4cac3 100644 --- a/qiskit/opflow/primitive_ops/circuit_op.py +++ b/qiskit/opflow/primitive_ops/circuit_op.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -13,7 +13,6 @@ """CircuitOp Class""" from typing import Dict, List, Optional, Set, Union, cast - import numpy as np import qiskit @@ -24,13 +23,18 @@ from qiskit.opflow.operator_base import OperatorBase from qiskit.opflow.primitive_ops.primitive_op import PrimitiveOp from qiskit.quantum_info import Statevector +from qiskit.utils.deprecation import deprecate_func class CircuitOp(PrimitiveOp): - """Class for Operators backed by Terra's ``QuantumCircuit`` module.""" + """Deprecated: Class for Operators backed by Terra's ``QuantumCircuit`` module.""" primitive: QuantumCircuit + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def __init__( self, primitive: Union[Instruction, QuantumCircuit], diff --git a/qiskit/opflow/primitive_ops/matrix_op.py b/qiskit/opflow/primitive_ops/matrix_op.py index 74d25f32ad82..be8c8ac90eec 100644 --- a/qiskit/opflow/primitive_ops/matrix_op.py +++ b/qiskit/opflow/primitive_ops/matrix_op.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -13,7 +13,6 @@ """MatrixOp Class""" from typing import Dict, List, Optional, Set, Union, cast, get_type_hints - import numpy as np from scipy.sparse import spmatrix @@ -28,13 +27,19 @@ from qiskit.opflow.primitive_ops.primitive_op import PrimitiveOp from qiskit.quantum_info import Operator, Statevector from qiskit.utils import arithmetic +from qiskit.utils.deprecation import deprecate_func class MatrixOp(PrimitiveOp): - """Class for Operators represented by matrices, backed by Terra's ``Operator`` module.""" + """Deprecated: Class for Operators represented by matrices, + backed by Terra's ``Operator`` module.""" primitive: Operator + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def __init__( self, primitive: Union[list, np.ndarray, spmatrix, Operator], diff --git a/qiskit/opflow/primitive_ops/pauli_op.py b/qiskit/opflow/primitive_ops/pauli_op.py index 8bc0878da63a..5720a13357df 100644 --- a/qiskit/opflow/primitive_ops/pauli_op.py +++ b/qiskit/opflow/primitive_ops/pauli_op.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -14,7 +14,6 @@ from math import pi from typing import Dict, List, Optional, Set, Union, cast - import numpy as np from scipy.sparse import spmatrix @@ -28,13 +27,18 @@ from qiskit.opflow.operator_base import OperatorBase from qiskit.opflow.primitive_ops.primitive_op import PrimitiveOp from qiskit.quantum_info import Pauli, SparsePauliOp, Statevector +from qiskit.utils.deprecation import deprecate_func class PauliOp(PrimitiveOp): - """Class for Operators backed by Terra's ``Pauli`` module.""" + """Deprecated: Class for Operators backed by Terra's ``Pauli`` module.""" primitive: Pauli + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def __init__(self, primitive: Pauli, coeff: Union[complex, ParameterExpression] = 1.0) -> None: """ Args: @@ -46,6 +50,7 @@ def __init__(self, primitive: Pauli, coeff: Union[complex, ParameterExpression] """ if not isinstance(primitive, Pauli): raise TypeError(f"PauliOp can only be instantiated with Paulis, not {type(primitive)}") + super().__init__(primitive, coeff=coeff) def primitive_strings(self) -> Set[str]: diff --git a/qiskit/opflow/primitive_ops/pauli_sum_op.py b/qiskit/opflow/primitive_ops/pauli_sum_op.py index 2cad82f6d696..97ecd8fe23ad 100644 --- a/qiskit/opflow/primitive_ops/pauli_sum_op.py +++ b/qiskit/opflow/primitive_ops/pauli_sum_op.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -14,7 +14,6 @@ from collections import defaultdict from typing import Dict, List, Optional, Set, Tuple, Union, cast - import numpy as np from scipy.sparse import spmatrix @@ -27,13 +26,18 @@ from qiskit.opflow.primitive_ops.primitive_op import PrimitiveOp from qiskit.quantum_info import Pauli, SparsePauliOp, Statevector from qiskit.quantum_info.operators.custom_iterator import CustomIterator +from qiskit.utils.deprecation import deprecate_func class PauliSumOp(PrimitiveOp): - """Class for Operators backed by Terra's ``SparsePauliOp`` class.""" + """Deprecated: Class for Operators backed by Terra's ``SparsePauliOp`` class.""" primitive: SparsePauliOp + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def __init__( self, primitive: SparsePauliOp, diff --git a/qiskit/opflow/primitive_ops/primitive_op.py b/qiskit/opflow/primitive_ops/primitive_op.py index 425a25422671..de3ef06c3add 100644 --- a/qiskit/opflow/primitive_ops/primitive_op.py +++ b/qiskit/opflow/primitive_ops/primitive_op.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -22,11 +22,12 @@ from qiskit.circuit import Instruction, ParameterExpression from qiskit.opflow.operator_base import OperatorBase from qiskit.quantum_info import Operator, Pauli, SparsePauliOp, Statevector +from qiskit.utils.deprecation import deprecate_func class PrimitiveOp(OperatorBase): r""" - A class for representing basic Operators, backed by Operator primitives from + Deprecated: A class for representing basic Operators, backed by Operator primitives from Terra. This class (and inheritors) primarily serves to allow the underlying primitives to "flow" - i.e. interoperability and adherence to the Operator formalism - while the core computational logic mostly remains in the underlying primitives. @@ -92,6 +93,10 @@ def __new__( "factory constructor".format(type(primitive)) ) + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def __init__( self, primitive: Union[QuantumCircuit, Operator, Pauli, SparsePauliOp, OperatorBase], diff --git a/qiskit/opflow/primitive_ops/tapered_pauli_sum_op.py b/qiskit/opflow/primitive_ops/tapered_pauli_sum_op.py index 60dec6fc54f0..9411afc71f26 100644 --- a/qiskit/opflow/primitive_ops/tapered_pauli_sum_op.py +++ b/qiskit/opflow/primitive_ops/tapered_pauli_sum_op.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2021. +# (C) Copyright IBM 2021, 2023. # # 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 @@ -27,13 +27,18 @@ from qiskit.opflow.primitive_ops.pauli_sum_op import PauliSumOp from qiskit.opflow.utils import commutator from qiskit.quantum_info import Pauli, SparsePauliOp +from qiskit.utils.deprecation import deprecate_func logger = logging.getLogger(__name__) class TaperedPauliSumOp(PauliSumOp): - """Class for PauliSumOp after tapering""" + """Deprecated: Class for PauliSumOp after tapering""" + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def __init__( self, primitive: SparsePauliOp, @@ -81,8 +86,12 @@ def assign_parameters(self, param_dict: dict) -> OperatorBase: class Z2Symmetries: - """Z2 Symmetries""" + """Deprecated: Z2 Symmetries""" + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def __init__( self, symmetries: List[Pauli], diff --git a/qiskit/opflow/state_fns/__init__.py b/qiskit/opflow/state_fns/__init__.py index 6d71298df145..69b7d960bc20 100644 --- a/qiskit/opflow/state_fns/__init__.py +++ b/qiskit/opflow/state_fns/__init__.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -14,9 +14,15 @@ State Functions (:mod:`qiskit.opflow.state_fns`) ================================================ -State functions are defined to be complex functions over a single binary string (as -compared to an operator, which is defined as a function over two binary strings, or a -function taking a binary function to another binary function). This function may be +.. deprecated:: 0.24.0 + + The :mod:`qiskit.opflow` module is deprecated and will be removed no earlier + than 3 months after the release date. For code migration guidelines, + visit https://qisk.it/opflow_migration. + +State functions are defined to be complex functions over a single binary +string (as compared to an operator, which is defined as a function over two binary strings, +or a function taking a binary function to another binary function). This function may be called by the eval() method. Measurements are defined to be functionals over StateFns, taking them to real values. diff --git a/qiskit/opflow/state_fns/circuit_state_fn.py b/qiskit/opflow/state_fns/circuit_state_fn.py index 3594a33332d0..3f23f89a1cee 100644 --- a/qiskit/opflow/state_fns/circuit_state_fn.py +++ b/qiskit/opflow/state_fns/circuit_state_fn.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -33,16 +33,21 @@ from qiskit.opflow.state_fns.state_fn import StateFn from qiskit.opflow.state_fns.vector_state_fn import VectorStateFn from qiskit.quantum_info import Statevector +from qiskit.utils.deprecation import deprecate_func class CircuitStateFn(StateFn): r""" - A class for state functions and measurements which are defined by the action of a + Deprecated: A class for state functions and measurements which are defined by the action of a QuantumCircuit starting from \|0⟩, and stored using Terra's ``QuantumCircuit`` class. """ primitive: QuantumCircuit # TODO allow normalization somehow? + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def __init__( self, primitive: Union[QuantumCircuit, Instruction] = None, diff --git a/qiskit/opflow/state_fns/cvar_measurement.py b/qiskit/opflow/state_fns/cvar_measurement.py index dda966dbf0d9..858d3b87f671 100644 --- a/qiskit/opflow/state_fns/cvar_measurement.py +++ b/qiskit/opflow/state_fns/cvar_measurement.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -28,10 +28,11 @@ from qiskit.opflow.state_fns.state_fn import StateFn from qiskit.opflow.state_fns.vector_state_fn import VectorStateFn from qiskit.quantum_info import Statevector +from qiskit.utils.deprecation import deprecate_func class CVaRMeasurement(OperatorStateFn): - r"""A specialized measurement class to compute CVaR expectation values. + r"""Deprecated: A specialized measurement class to compute CVaR expectation values. See https://arxiv.org/pdf/1907.04769.pdf for further details. Used in :class:`~qiskit.opflow.CVaRExpectation`, see there for more details. @@ -40,6 +41,10 @@ class CVaRMeasurement(OperatorStateFn): primitive: OperatorBase # TODO allow normalization somehow? + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def __init__( self, primitive: OperatorBase = None, diff --git a/qiskit/opflow/state_fns/dict_state_fn.py b/qiskit/opflow/state_fns/dict_state_fn.py index 6bfed225e887..77d5c32d8772 100644 --- a/qiskit/opflow/state_fns/dict_state_fn.py +++ b/qiskit/opflow/state_fns/dict_state_fn.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020, 2021. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -27,16 +27,21 @@ from qiskit.quantum_info import Statevector from qiskit.result import Result from qiskit.utils import algorithm_globals +from qiskit.utils.deprecation import deprecate_func class DictStateFn(StateFn): - """A class for state functions and measurements which are defined by a lookup table, + """Deprecated: A class for state functions and measurements which are defined by a lookup table, stored in a dict. """ primitive: Dict[str, complex] # TODO allow normalization somehow? + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def __init__( self, primitive: Union[str, dict, Result] = None, diff --git a/qiskit/opflow/state_fns/operator_state_fn.py b/qiskit/opflow/state_fns/operator_state_fn.py index febd57830969..a9cac679deef 100644 --- a/qiskit/opflow/state_fns/operator_state_fn.py +++ b/qiskit/opflow/state_fns/operator_state_fn.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -26,16 +26,21 @@ from qiskit.opflow.state_fns.state_fn import StateFn from qiskit.opflow.state_fns.circuit_state_fn import CircuitStateFn from qiskit.quantum_info import Statevector +from qiskit.utils.deprecation import deprecate_func class OperatorStateFn(StateFn): r""" - A class for state functions and measurements which are defined by a density Operator, + Deprecated: A class for state functions and measurements which are defined by a density Operator, stored using an ``OperatorBase``. """ primitive: OperatorBase # TODO allow normalization somehow? + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def __init__( self, primitive: OperatorBase, diff --git a/qiskit/opflow/state_fns/sparse_vector_state_fn.py b/qiskit/opflow/state_fns/sparse_vector_state_fn.py index 935241a2e197..b26c6dff9df1 100644 --- a/qiskit/opflow/state_fns/sparse_vector_state_fn.py +++ b/qiskit/opflow/state_fns/sparse_vector_state_fn.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020, 2021. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -26,10 +26,11 @@ from qiskit.opflow.state_fns.vector_state_fn import VectorStateFn from qiskit.quantum_info import Statevector from qiskit.utils import algorithm_globals +from qiskit.utils.deprecation import deprecate_func class SparseVectorStateFn(StateFn): - """A class for sparse state functions and measurements in vector representation. + """Deprecated: A class for sparse state functions and measurements in vector representation. This class uses ``scipy.sparse.spmatrix`` for the internal representation. """ @@ -37,6 +38,10 @@ class SparseVectorStateFn(StateFn): primitive: scipy.sparse.spmatrix # TODO allow normalization somehow? + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def __init__( self, primitive: scipy.sparse.spmatrix, diff --git a/qiskit/opflow/state_fns/state_fn.py b/qiskit/opflow/state_fns/state_fn.py index 3a2d4a4eb656..f24592bdaf55 100644 --- a/qiskit/opflow/state_fns/state_fn.py +++ b/qiskit/opflow/state_fns/state_fn.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -21,11 +21,12 @@ from qiskit.opflow.operator_base import OperatorBase from qiskit.quantum_info import Statevector from qiskit.result import Result +from qiskit.utils.deprecation import deprecate_func class StateFn(OperatorBase): r""" - A class for representing state functions and measurements. + Deprecated: A class for representing state functions and measurements. State functions are defined to be complex functions over a single binary string (as compared to an operator, which is defined as a function over two binary strings, or a @@ -112,6 +113,10 @@ def __new__( ) # TODO allow normalization somehow? + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def __init__( self, primitive: Union[ diff --git a/qiskit/opflow/state_fns/vector_state_fn.py b/qiskit/opflow/state_fns/vector_state_fn.py index fb3956e46a5a..8391d92a697b 100644 --- a/qiskit/opflow/state_fns/vector_state_fn.py +++ b/qiskit/opflow/state_fns/vector_state_fn.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020, 2021. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -26,16 +26,21 @@ from qiskit.opflow.state_fns.state_fn import StateFn from qiskit.quantum_info import Statevector from qiskit.utils import algorithm_globals, arithmetic +from qiskit.utils.deprecation import deprecate_func class VectorStateFn(StateFn): - """A class for state functions and measurements which are defined in vector + """Deprecated: A class for state functions and measurements which are defined in vector representation, and stored using Terra's ``Statevector`` class. """ primitive: Statevector # TODO allow normalization somehow? + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", + ) def __init__( self, primitive: Union[list, np.ndarray, Statevector] = None, diff --git a/qiskit/opflow/utils.py b/qiskit/opflow/utils.py index 752cc89346f7..0979fc0bc3e7 100644 --- a/qiskit/opflow/utils.py +++ b/qiskit/opflow/utils.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -13,11 +13,16 @@ """Utility functions for OperatorFlow""" from qiskit.opflow.operator_base import OperatorBase +from qiskit.utils.deprecation import deprecate_func +@deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", +) def commutator(op_a: OperatorBase, op_b: OperatorBase) -> OperatorBase: r""" - Compute commutator of `op_a` and `op_b`. + Deprecated: Compute commutator of `op_a` and `op_b`. .. math:: @@ -32,9 +37,13 @@ def commutator(op_a: OperatorBase, op_b: OperatorBase) -> OperatorBase: return (op_a @ op_b - op_b @ op_a).reduce() +@deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", +) def anti_commutator(op_a: OperatorBase, op_b: OperatorBase) -> OperatorBase: r""" - Compute anti-commutator of `op_a` and `op_b`. + Deprecated: Compute anti-commutator of `op_a` and `op_b`. .. math:: @@ -49,6 +58,10 @@ def anti_commutator(op_a: OperatorBase, op_b: OperatorBase) -> OperatorBase: return (op_a @ op_b + op_b @ op_a).reduce() +@deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/opflow_migration.", +) def double_commutator( op_a: OperatorBase, op_b: OperatorBase, @@ -56,7 +69,7 @@ def double_commutator( sign: bool = False, ) -> OperatorBase: r""" - Compute symmetric double commutator of `op_a`, `op_b` and `op_c`. + Deprecated: Compute symmetric double commutator of `op_a`, `op_b` and `op_c`. See McWeeny chapter 13.6 Equation of motion methods (page 479) If `sign` is `False`, it returns diff --git a/qiskit/synthesis/evolution/qdrift.py b/qiskit/synthesis/evolution/qdrift.py index 009548653988..6707fa2ec411 100644 --- a/qiskit/synthesis/evolution/qdrift.py +++ b/qiskit/synthesis/evolution/qdrift.py @@ -85,14 +85,13 @@ def synthesize(self, evolution): # pylint: disable=cyclic-import from qiskit.circuit.library.pauli_evolution import PauliEvolutionGate - from qiskit.opflow import PauliOp # Build the evolution circuit using the LieTrotter synthesis with the sampled operators lie_trotter = LieTrotter( insert_barriers=self.insert_barriers, atomic_evolution=self.atomic_evolution ) evolution_circuit = PauliEvolutionGate( - sum(PauliOp(op) for op, coeff in self.sampled_ops), + sum(SparsePauliOp(op) for op, coeff in self.sampled_ops), time=evolution_time, synthesis=lie_trotter, ).definition diff --git a/qiskit/utils/backend_utils.py b/qiskit/utils/backend_utils.py index c87bdbd937a9..7f71a7c91897 100644 --- a/qiskit/utils/backend_utils.py +++ b/qiskit/utils/backend_utils.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2018, 2021. +# (C) Copyright IBM 2018, 2023. # # 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 @@ -13,6 +13,7 @@ """backend utility functions""" import logging +from qiskit.utils.deprecation import deprecate_func logger = logging.getLogger(__name__) @@ -49,6 +50,10 @@ def _get_backend_provider(backend): return provider +@deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/qi_migration.", +) def has_ibmq(): """Check if IBMQ is installed.""" if not _PROVIDER_CHECK.checked_ibmq: @@ -66,6 +71,10 @@ def has_ibmq(): return _PROVIDER_CHECK.has_ibmq +@deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/qi_migration.", +) def has_aer(): """Check if Aer is installed.""" if not _PROVIDER_CHECK.checked_aer: @@ -82,6 +91,10 @@ def has_aer(): return _PROVIDER_CHECK.has_aer +@deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/qi_migration.", +) def is_aer_provider(backend): """Detect whether or not backend is from Aer provider. @@ -102,6 +115,10 @@ def is_aer_provider(backend): return False +@deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/qi_migration.", +) def is_basicaer_provider(backend): """Detect whether or not backend is from BasicAer provider. @@ -115,6 +132,10 @@ def is_basicaer_provider(backend): return isinstance(_get_backend_provider(backend), BasicAerProvider) +@deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/qi_migration.", +) def is_ibmq_provider(backend): """Detect whether or not backend is from IBMQ provider. @@ -131,6 +152,10 @@ def is_ibmq_provider(backend): return False +@deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/qi_migration.", +) def is_aer_statevector_backend(backend): """ Return True if backend object is statevector and from Aer provider. @@ -143,6 +168,10 @@ def is_aer_statevector_backend(backend): return is_statevector_backend(backend) and is_aer_provider(backend) +@deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/qi_migration.", +) def is_statevector_backend(backend): """ Return True if backend object is statevector. @@ -168,6 +197,10 @@ def is_statevector_backend(backend): return backend.name.startswith("statevector") +@deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/qi_migration.", +) def is_simulator_backend(backend): """ Return True if backend is a simulator. @@ -183,6 +216,10 @@ def is_simulator_backend(backend): return False +@deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/qi_migration.", +) def is_local_backend(backend): """ Return True if backend is a local backend. @@ -198,6 +235,10 @@ def is_local_backend(backend): return False +@deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/qi_migration.", +) def is_aer_qasm(backend): """ Return True if backend is Aer Qasm simulator @@ -214,6 +255,10 @@ def is_aer_qasm(backend): return ret +@deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/qi_migration.", +) def support_backend_options(backend): """ Return True if backend supports backend_options diff --git a/qiskit/utils/measurement_error_mitigation.py b/qiskit/utils/measurement_error_mitigation.py index 378f6c4b21cf..0ef09c997ec5 100644 --- a/qiskit/utils/measurement_error_mitigation.py +++ b/qiskit/utils/measurement_error_mitigation.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2019, 2021. +# (C) Copyright IBM 2019, 2023. # # 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 @@ -27,13 +27,18 @@ CompleteMeasFitter, TensoredMeasFitter, ) +from qiskit.utils.deprecation import deprecate_func +@deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/qi_migration.", +) def get_measured_qubits( transpiled_circuits: List[QuantumCircuit], ) -> Tuple[List[int], Dict[str, List[int]]]: """ - Retrieve the measured qubits from transpiled circuits. + Deprecated: Retrieve the measured qubits from transpiled circuits. Args: transpiled_circuits: a list of transpiled circuits @@ -73,9 +78,13 @@ def get_measured_qubits( return sorted(qubit_index), qubit_mappings +@deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/qi_migration.", +) def get_measured_qubits_from_qobj(qobj: QasmQobj) -> Tuple[List[int], Dict[str, List[int]]]: """ - Retrieve the measured qubits from transpiled circuits. + Deprecated: Retrieve the measured qubits from transpiled circuits. Args: qobj: qobj @@ -114,6 +123,10 @@ def get_measured_qubits_from_qobj(qobj: QasmQobj) -> Tuple[List[int], Dict[str, return sorted(qubit_index), qubit_mappings +@deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/qi_migration.", +) def build_measurement_error_mitigation_circuits( qubit_list: List[int], fitter_cls: Callable, @@ -122,7 +135,7 @@ def build_measurement_error_mitigation_circuits( compile_config: Optional[Dict] = None, mit_pattern: Optional[List[List[int]]] = None, ) -> Tuple[QuantumCircuit, List[str], List[str]]: - """Build measurement error mitigation circuits + """Deprecated: Build measurement error mitigation circuits Args: qubit_list: list of ordered qubits used in the algorithm fitter_cls: CompleteMeasFitter or TensoredMeasFitter @@ -189,6 +202,10 @@ def build_measurement_error_mitigation_circuits( return t_meas_calibs_circuits, state_labels, circlabel +@deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/qi_migration.", +) def build_measurement_error_mitigation_qobj( qubit_list: List[int], fitter_cls: Callable, diff --git a/qiskit/utils/mitigation/__init__.py b/qiskit/utils/mitigation/__init__.py index 2d2de3040746..c79b107cdc0f 100644 --- a/qiskit/utils/mitigation/__init__.py +++ b/qiskit/utils/mitigation/__init__.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2019. +# (C) Copyright IBM 2019, 2023. # # 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 @@ -21,6 +21,11 @@ .. currentmodule:: qiskit.utils.mitigation +.. deprecated:: 0.24.0 + This module is deprecated and will be removed no sooner than 3 months + after the release date. For code migration guidelines, + visit https://qisk.it/qi_migration. + .. warning:: The user-facing API stability of this module is not guaranteed except for diff --git a/qiskit/utils/mitigation/_filters.py b/qiskit/utils/mitigation/_filters.py index 5fff37e230c9..5d566f625116 100644 --- a/qiskit/utils/mitigation/_filters.py +++ b/qiskit/utils/mitigation/_filters.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2019. +# (C) Copyright IBM 2019, 2023. # # 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 @@ -31,17 +31,22 @@ from qiskit import QiskitError from qiskit.tools import parallel_map from qiskit.utils.mitigation.circuits import count_keys +from qiskit.utils.deprecation import deprecate_func class MeasurementFilter: """ - Measurement error mitigation filter. + Deprecated: Measurement error mitigation filter. Produced from a measurement calibration fitter and can be applied to data. """ + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/qi_migration.", + ) def __init__(self, cal_matrix: np.matrix, state_labels: list): """ Initialize a measurement error mitigation filter using the cal_matrix @@ -214,12 +219,16 @@ def _apply_correction(self, resultidx, raw_data, method): class TensoredFilter: """ - Tensored measurement error mitigation filter. + Deprecated: Tensored measurement error mitigation filter. Produced from a tensored measurement calibration fitter and can be applied to data. """ + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/qi_migration.", + ) def __init__(self, cal_matrices: np.matrix, substate_labels_list: list, mit_pattern: list): """ Initialize a tensored measurement error mitigation filter using diff --git a/qiskit/utils/mitigation/circuits.py b/qiskit/utils/mitigation/circuits.py index af62d1c36fa5..2fdeaa6372a6 100644 --- a/qiskit/utils/mitigation/circuits.py +++ b/qiskit/utils/mitigation/circuits.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2019. +# (C) Copyright IBM 2019, 2023. # # 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 @@ -19,10 +19,15 @@ use the fitters to produce a filter. """ from typing import List, Tuple, Union +from qiskit.utils.deprecation import deprecate_func +@deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/qi_migration.", +) def count_keys(num_qubits: int) -> List[str]: - """Return ordered count keys. + """Deprecated: Return ordered count keys. Args: num_qubits: The number of qubits in the generated list. @@ -35,6 +40,10 @@ def count_keys(num_qubits: int) -> List[str]: return [bin(j)[2:].zfill(num_qubits) for j in range(2**num_qubits)] +@deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/qi_migration.", +) def complete_meas_cal( qubit_list: List[int] = None, qr: Union[int, List["QuantumRegister"]] = None, @@ -42,7 +51,7 @@ def complete_meas_cal( circlabel: str = "", ) -> Tuple[List["QuantumCircuit"], List[str]]: """ - Return a list of measurement calibration circuits for the full + Deprecated: Return a list of measurement calibration circuits for the full Hilbert space. If the circuit contains :math:`n` qubits, then :math:`2^n` calibration circuits @@ -112,6 +121,10 @@ def complete_meas_cal( return cal_circuits, state_labels +@deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/qi_migration.", +) def tensored_meas_cal( mit_pattern: List[List[int]] = None, qr: Union[int, List["QuantumRegister"]] = None, @@ -119,7 +132,7 @@ def tensored_meas_cal( circlabel: str = "", ) -> Tuple[List["QuantumCircuit"], List[List[int]]]: """ - Return a list of calibration circuits + Deprecated: Return a list of calibration circuits Args: mit_pattern: Qubits on which to perform the diff --git a/qiskit/utils/mitigation/fitters.py b/qiskit/utils/mitigation/fitters.py index 3eff35424b94..65357d5dc5b5 100644 --- a/qiskit/utils/mitigation/fitters.py +++ b/qiskit/utils/mitigation/fitters.py @@ -27,13 +27,18 @@ from qiskit import QiskitError from qiskit.utils.mitigation.circuits import count_keys from qiskit.utils.mitigation._filters import MeasurementFilter, TensoredFilter +from qiskit.utils.deprecation import deprecate_func class CompleteMeasFitter: """ - Measurement correction fitter for a full calibration + Deprecated: Measurement correction fitter for a full calibration """ + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/qi_migration.", + ) def __init__( self, results, @@ -211,9 +216,13 @@ def readout_fidelity(self, label_list=None): class TensoredMeasFitter: """ - Measurement correction fitter for a tensored calibration. + Deprecated: Measurement correction fitter for a tensored calibration. """ + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/qi_migration.", + ) def __init__( self, results, diff --git a/qiskit/utils/quantum_instance.py b/qiskit/utils/quantum_instance.py index 3a563e273d8a..a4bbb76e1b00 100644 --- a/qiskit/utils/quantum_instance.py +++ b/qiskit/utils/quantum_instance.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2018, 2022. +# (C) Copyright IBM 2018, 2023. # # 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 @@ -38,6 +38,7 @@ CompleteMeasFitter, TensoredMeasFitter, ) +from qiskit.utils.deprecation import deprecate_func logger = logging.getLogger(__name__) @@ -124,7 +125,7 @@ def type_from_instance(meas_instance): class QuantumInstance: - """Quantum Backend including execution setting.""" + """Deprecated: Quantum Backend including execution setting.""" _BACKEND_CONFIG = ["basis_gates", "coupling_map"] _COMPILE_CONFIG = ["initial_layout", "seed_transpiler", "optimization_level"] @@ -143,6 +144,10 @@ class QuantumInstance: "statevector_hpc_gate_opt", ] + _BACKEND_OPTIONS_QASM_ONLY + @deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/qi_migration.", + ) def __init__( self, backend, diff --git a/qiskit/utils/run_circuits.py b/qiskit/utils/run_circuits.py index a480123b0ee1..9714234ca694 100644 --- a/qiskit/utils/run_circuits.py +++ b/qiskit/utils/run_circuits.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2018, 2021. +# (C) Copyright IBM 2018, 2023. # # 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 @@ -23,6 +23,7 @@ from qiskit.providers import Backend, JobStatus, JobError, Job from qiskit.providers.jobstatus import JOB_FINAL_STATES from qiskit.result import Result +from qiskit.utils.deprecation import deprecate_func from ..exceptions import QiskitError, MissingOptionalLibraryError from .backend_utils import ( is_aer_provider, @@ -39,10 +40,14 @@ logger = logging.getLogger(__name__) +@deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/qi_migration.", +) def find_regs_by_name( circuit: QuantumCircuit, name: str, qreg: bool = True ) -> Optional[Union[QuantumRegister, ClassicalRegister]]: - """Find the registers in the circuits. + """Deprecated: Find the registers in the circuits. Args: circuit: the quantum circuit. @@ -100,6 +105,10 @@ def _safe_get_job_status(job: Job, job_id: str, max_job_retries: int, wait: floa return job_status +@deprecate_func( + since="0.24.0", + additional_msg="For code migration guidelines, visit https://qisk.it/qi_migration.", +) def run_circuits( circuits: Union[QuantumCircuit, List[QuantumCircuit]], backend: Backend, @@ -111,7 +120,7 @@ def run_circuits( max_job_retries: int = 50, ) -> Result: """ - An execution wrapper with Qiskit-Terra, with job auto recover capability. + Deprecated: An execution wrapper with Qiskit-Terra, with job auto recover capability. The auto-recovery feature is only applied for non-simulator backend. This wrapper will try to get the result no matter how long it takes. diff --git a/releasenotes/notes/deprecate-opflow-qi-32f7e27884deea3f.yaml b/releasenotes/notes/deprecate-opflow-qi-32f7e27884deea3f.yaml new file mode 100644 index 000000000000..4e55ffccf0d9 --- /dev/null +++ b/releasenotes/notes/deprecate-opflow-qi-32f7e27884deea3f.yaml @@ -0,0 +1,14 @@ +--- +deprecations: + - | + The modules :mod:`qiskit.opflow`, :mod:`qiskit.utils.backend_utils`, + :mod:`qiskit.utils.mitigation`, + :mod:`qiskit.utils.measurement_error_mitigation`, + class :class:`qiskit.utils.QuantumInstance` and methods + :meth:`~qiskit.utils.run_circuits.find_regs_by_name`, + :meth:`~qiskit.utils.run_circuits.run_circuits` + have been deprecated and will be removed in a future release. + Using :class:`~qiskit.utils.QuantumInstance` is superseded by + :class:`~qiskit.primitives.BaseSampler`. + See `Opflow Migration `__. + See `QuantumInstance Migration `__. diff --git a/test/python/algorithms/evolvers/test_evolution_problem.py b/test/python/algorithms/evolvers/test_evolution_problem.py index 6f0cf4e7fd83..dc9d45f548a2 100644 --- a/test/python/algorithms/evolvers/test_evolution_problem.py +++ b/test/python/algorithms/evolvers/test_evolution_problem.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2022. +# (C) Copyright IBM 2022, 2023. # # 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 @@ -51,7 +51,8 @@ def test_init_default(self): def test_init_all(self): """Tests that all fields are initialized correctly.""" t_parameter = Parameter("t") - hamiltonian = t_parameter * Z + Y + with self.assertWarns(DeprecationWarning): + hamiltonian = t_parameter * Z + Y time = 2 initial_state = One aux_operators = [X, Y] @@ -66,15 +67,17 @@ def test_init_all(self): t_param=t_parameter, param_value_dict=param_value_dict, ) + expected_hamiltonian = Y + t_parameter * Z - expected_hamiltonian = Y + t_parameter * Z expected_time = 2 expected_initial_state = One expected_aux_operators = [X, Y] expected_t_param = t_parameter expected_param_value_dict = {t_parameter: 3.2} - self.assertEqual(evo_problem.hamiltonian, expected_hamiltonian) + with self.assertWarns(DeprecationWarning): + self.assertEqual(evo_problem.hamiltonian, expected_hamiltonian) + self.assertEqual(evo_problem.time, expected_time) self.assertEqual(evo_problem.initial_state, expected_initial_state) self.assertEqual(evo_problem.aux_operators, expected_aux_operators) @@ -93,7 +96,9 @@ def test_validate_params(self): param_x = Parameter("x") param_y = Parameter("y") with self.subTest(msg="Parameter missing in dict."): - hamiltonian = param_x * X + param_y * Y + with self.assertWarns(DeprecationWarning): + hamiltonian = param_x * X + param_y * Y + param_dict = {param_y: 2} with self.assertWarns(DeprecationWarning): evolution_problem = EvolutionProblem( @@ -103,7 +108,9 @@ def test_validate_params(self): evolution_problem.validate_params() with self.subTest(msg="Empty dict."): - hamiltonian = param_x * X + param_y * Y + with self.assertWarns(DeprecationWarning): + hamiltonian = param_x * X + param_y * Y + param_dict = {} with self.assertWarns(DeprecationWarning): evolution_problem = EvolutionProblem( @@ -113,7 +120,9 @@ def test_validate_params(self): evolution_problem.validate_params() with self.subTest(msg="Extra parameter in dict."): - hamiltonian = param_x * X + param_y * Y + with self.assertWarns(DeprecationWarning): + hamiltonian = param_x * X + param_y * Y + param_dict = {param_y: 2, param_x: 1, Parameter("z"): 1} with self.assertWarns(DeprecationWarning): evolution_problem = EvolutionProblem( diff --git a/test/python/algorithms/evolvers/trotterization/test_trotter_qrte.py b/test/python/algorithms/evolvers/trotterization/test_trotter_qrte.py index 7f7f5e797c82..077957d8361d 100644 --- a/test/python/algorithms/evolvers/trotterization/test_trotter_qrte.py +++ b/test/python/algorithms/evolvers/trotterization/test_trotter_qrte.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2021, 2022. +# (C) Copyright IBM 2021, 2023. # # 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 @@ -13,7 +13,6 @@ """Test TrotterQRTE.""" import unittest - from test.python.opflow import QiskitOpflowTestCase from ddt import ddt, data, unpack import numpy as np @@ -52,18 +51,19 @@ def setUp(self): algorithm_globals.random_seed = self.seed backend_statevector = BasicAer.get_backend("statevector_simulator") backend_qasm = BasicAer.get_backend("qasm_simulator") - self.quantum_instance = QuantumInstance( - backend=backend_statevector, - shots=1, - seed_simulator=self.seed, - seed_transpiler=self.seed, - ) - self.quantum_instance_qasm = QuantumInstance( - backend=backend_qasm, - shots=8000, - seed_simulator=self.seed, - seed_transpiler=self.seed, - ) + with self.assertWarns(DeprecationWarning): + self.quantum_instance = QuantumInstance( + backend=backend_statevector, + shots=1, + seed_simulator=self.seed, + seed_transpiler=self.seed, + ) + self.quantum_instance_qasm = QuantumInstance( + backend=backend_qasm, + shots=8000, + seed_simulator=self.seed, + seed_transpiler=self.seed, + ) self.backends_dict = { "qi_sv": self.quantum_instance, "qi_qasm": self.quantum_instance_qasm, @@ -123,10 +123,11 @@ def test_trotter_qrte_trotter_single_qubit_aux_ops(self): with self.subTest(msg=f"Test {backend_name} backend."): algorithm_globals.random_seed = 0 backend = self.backends_dict[backend_name] - expectation = ExpectationFactory.build( - operator=operator, - backend=backend, - ) + with self.assertWarns(DeprecationWarning): + expectation = ExpectationFactory.build( + operator=operator, + backend=backend, + ) with self.assertWarns(DeprecationWarning): trotter_qrte = TrotterQRTE(quantum_instance=backend, expectation=expectation) evolution_result = trotter_qrte.evolve(evolution_problem) diff --git a/test/python/algorithms/minimum_eigensolvers/test_adapt_vqe.py b/test/python/algorithms/minimum_eigensolvers/test_adapt_vqe.py index 2b5d899c7a1b..ea0198259560 100644 --- a/test/python/algorithms/minimum_eigensolvers/test_adapt_vqe.py +++ b/test/python/algorithms/minimum_eigensolvers/test_adapt_vqe.py @@ -37,59 +37,65 @@ class TestAdaptVQE(QiskitAlgorithmsTestCase): def setUp(self): super().setUp() algorithm_globals.random_seed = 42 - self.h2_op = PauliSumOp.from_list( - [ - ("IIII", -0.8105479805373266), - ("ZZII", -0.2257534922240251), - ("IIZI", +0.12091263261776641), - ("ZIZI", +0.12091263261776641), - ("IZZI", +0.17218393261915543), - ("IIIZ", +0.17218393261915546), - ("IZIZ", +0.1661454325638243), - ("ZZIZ", +0.1661454325638243), - ("IIZZ", -0.2257534922240251), - ("IZZZ", +0.16892753870087926), - ("ZZZZ", +0.17464343068300464), - ("IXIX", +0.04523279994605788), - ("ZXIX", +0.04523279994605788), - ("IXZX", -0.04523279994605788), - ("ZXZX", -0.04523279994605788), - ] - ) - self.excitation_pool = [ - PauliSumOp( - SparsePauliOp(["IIIY", "IIZY"], coeffs=[0.5 + 0.0j, -0.5 + 0.0j]), coeff=1.0 - ), - PauliSumOp( - SparsePauliOp(["ZYII", "IYZI"], coeffs=[-0.5 + 0.0j, 0.5 + 0.0j]), coeff=1.0 - ), - PauliSumOp( - SparsePauliOp( - ["ZXZY", "IXIY", "IYIX", "ZYZX", "IYZX", "ZYIX", "ZXIY", "IXZY"], - coeffs=[ - -0.125 + 0.0j, - 0.125 + 0.0j, - -0.125 + 0.0j, - 0.125 + 0.0j, - 0.125 + 0.0j, - -0.125 + 0.0j, - 0.125 + 0.0j, - -0.125 + 0.0j, - ], + + with self.assertWarns(DeprecationWarning): + self.h2_op = PauliSumOp.from_list( + [ + ("IIII", -0.8105479805373266), + ("ZZII", -0.2257534922240251), + ("IIZI", +0.12091263261776641), + ("ZIZI", +0.12091263261776641), + ("IZZI", +0.17218393261915543), + ("IIIZ", +0.17218393261915546), + ("IZIZ", +0.1661454325638243), + ("ZZIZ", +0.1661454325638243), + ("IIZZ", -0.2257534922240251), + ("IZZZ", +0.16892753870087926), + ("ZZZZ", +0.17464343068300464), + ("IXIX", +0.04523279994605788), + ("ZXIX", +0.04523279994605788), + ("IXZX", -0.04523279994605788), + ("ZXZX", -0.04523279994605788), + ] + ) + self.excitation_pool = [ + PauliSumOp( + SparsePauliOp(["IIIY", "IIZY"], coeffs=[0.5 + 0.0j, -0.5 + 0.0j]), coeff=1.0 + ), + PauliSumOp( + SparsePauliOp(["ZYII", "IYZI"], coeffs=[-0.5 + 0.0j, 0.5 + 0.0j]), coeff=1.0 ), - coeff=1.0, - ), - ] - self.initial_state = QuantumCircuit(QuantumRegister(4)) - self.initial_state.x(0) - self.initial_state.x(1) - self.ansatz = EvolvedOperatorAnsatz(self.excitation_pool, initial_state=self.initial_state) - self.optimizer = SLSQP() + PauliSumOp( + SparsePauliOp( + ["ZXZY", "IXIY", "IYIX", "ZYZX", "IYZX", "ZYIX", "ZXIY", "IXZY"], + coeffs=[ + -0.125 + 0.0j, + 0.125 + 0.0j, + -0.125 + 0.0j, + 0.125 + 0.0j, + 0.125 + 0.0j, + -0.125 + 0.0j, + 0.125 + 0.0j, + -0.125 + 0.0j, + ], + ), + coeff=1.0, + ), + ] + self.initial_state = QuantumCircuit(QuantumRegister(4)) + self.initial_state.x(0) + self.initial_state.x(1) + self.ansatz = EvolvedOperatorAnsatz( + self.excitation_pool, initial_state=self.initial_state + ) + self.optimizer = SLSQP() def test_default(self): """Default execution""" calc = AdaptVQE(VQE(Estimator(), self.ansatz, self.optimizer)) - res = calc.compute_minimum_eigenvalue(operator=self.h2_op) + + with self.assertWarns(DeprecationWarning): + res = calc.compute_minimum_eigenvalue(operator=self.h2_op) expected_eigenvalue = -1.85727503 @@ -117,7 +123,8 @@ def test_converged(self): VQE(Estimator(), self.ansatz, self.optimizer), gradient_threshold=1e-3, ) - res = calc.compute_minimum_eigenvalue(operator=self.h2_op) + with self.assertWarns(DeprecationWarning): + res = calc.compute_minimum_eigenvalue(operator=self.h2_op) self.assertEqual(res.termination_criterion, TerminationCriterion.CONVERGED) @@ -127,13 +134,14 @@ def test_maximum(self): VQE(Estimator(), self.ansatz, self.optimizer), max_iterations=1, ) - res = calc.compute_minimum_eigenvalue(operator=self.h2_op) + with self.assertWarns(DeprecationWarning): + res = calc.compute_minimum_eigenvalue(operator=self.h2_op) self.assertEqual(res.termination_criterion, TerminationCriterion.MAXIMUM) def test_eigenvalue_threshold(self): """Test for the eigenvalue_threshold attribute.""" - operator = PauliSumOp.from_list( + operator = SparsePauliOp.from_list( [ ("XX", 1.0), ("ZX", -0.5), @@ -142,8 +150,8 @@ def test_eigenvalue_threshold(self): ) ansatz = EvolvedOperatorAnsatz( [ - PauliSumOp.from_list([("YZ", 0.4)]), - PauliSumOp.from_list([("ZY", 0.5)]), + SparsePauliOp.from_list([("YZ", 0.4)]), + SparsePauliOp.from_list([("ZY", 0.5)]), ], initial_state=QuantumCircuit(2), ) @@ -163,7 +171,8 @@ def test_threshold_attribute(self): VQE(Estimator(), self.ansatz, self.optimizer), threshold=1e-3, ) - res = calc.compute_minimum_eigenvalue(operator=self.h2_op) + with self.assertWarns(DeprecationWarning): + res = calc.compute_minimum_eigenvalue(operator=self.h2_op) self.assertEqual(res.termination_criterion, TerminationCriterion.CONVERGED) @@ -203,9 +212,9 @@ def test_vqe_solver(self): """Test to check if the VQE solver remains the same or not""" solver = VQE(Estimator(), self.ansatz, self.optimizer) calc = AdaptVQE(solver) - _ = calc.compute_minimum_eigenvalue(operator=self.h2_op) - - self.assertEqual(solver.ansatz, calc.solver.ansatz) + with self.assertWarns(DeprecationWarning): + _ = calc.compute_minimum_eigenvalue(operator=self.h2_op) + self.assertEqual(solver.ansatz, calc.solver.ansatz) def test_gradient_calculation(self): """Test to check if the gradient calculation""" @@ -219,7 +228,8 @@ def test_gradient_calculation(self): def test_supports_aux_operators(self): """Test that auxiliary operators are supported""" calc = AdaptVQE(VQE(Estimator(), self.ansatz, self.optimizer)) - res = calc.compute_minimum_eigenvalue(operator=self.h2_op, aux_operators=[self.h2_op]) + with self.assertWarns(DeprecationWarning): + res = calc.compute_minimum_eigenvalue(operator=self.h2_op, aux_operators=[self.h2_op]) expected_eigenvalue = -1.85727503 diff --git a/test/python/algorithms/minimum_eigensolvers/test_qaoa.py b/test/python/algorithms/minimum_eigensolvers/test_qaoa.py index de1bbe5e1492..ff3cce47e239 100644 --- a/test/python/algorithms/minimum_eigensolvers/test_qaoa.py +++ b/test/python/algorithms/minimum_eigensolvers/test_qaoa.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2022. +# (C) Copyright IBM 2022, 2023. # # 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 @@ -81,8 +81,8 @@ def test_qaoa(self, w, reps, mixer, solutions): qubit_op, _ = self._get_operator(w) qaoa = QAOA(self.sampler, COBYLA(), reps=reps, mixer=mixer) - - result = qaoa.compute_minimum_eigenvalue(operator=qubit_op) + with self.assertWarns(DeprecationWarning): + result = qaoa.compute_minimum_eigenvalue(operator=qubit_op) x = self._sample_most_likely(result.eigenstate) graph_solution = self._get_graph_solution(x) self.assertIn(graph_solution, solutions) @@ -111,8 +111,8 @@ def test_qaoa_qc_mixer(self, w, prob, solutions): mixer.rx(theta, range(num_qubits)) qaoa = QAOA(self.sampler, optimizer, reps=prob, mixer=mixer) - - result = qaoa.compute_minimum_eigenvalue(operator=qubit_op) + with self.assertWarns(DeprecationWarning): + result = qaoa.compute_minimum_eigenvalue(operator=qubit_op) x = self._sample_most_likely(result.eigenstate) graph_solution = self._get_graph_solution(x) self.assertIn(graph_solution, solutions) @@ -129,7 +129,8 @@ def test_qaoa_qc_mixer_many_parameters(self): mixer.rx(theta, range(num_qubits)) qaoa = QAOA(self.sampler, optimizer, reps=2, mixer=mixer) - result = qaoa.compute_minimum_eigenvalue(operator=qubit_op) + with self.assertWarns(DeprecationWarning): + result = qaoa.compute_minimum_eigenvalue(operator=qubit_op) x = self._sample_most_likely(result.eigenstate) self.log.debug(x) graph_solution = self._get_graph_solution(x) @@ -145,7 +146,8 @@ def test_qaoa_qc_mixer_no_parameters(self): mixer.rx(np.pi / 2, range(num_qubits)) qaoa = QAOA(self.sampler, COBYLA(), reps=1, mixer=mixer) - result = qaoa.compute_minimum_eigenvalue(operator=qubit_op) + with self.assertWarns(DeprecationWarning): + result = qaoa.compute_minimum_eigenvalue(operator=qubit_op) # we just assert that we get a result, it is not meaningful. self.assertIsNotNone(result.eigenstate) @@ -155,7 +157,8 @@ def test_change_operator_size(self): np.array([[0, 1, 0, 1], [1, 0, 1, 0], [0, 1, 0, 1], [1, 0, 1, 0]]) ) qaoa = QAOA(self.sampler, COBYLA(), reps=1) - result = qaoa.compute_minimum_eigenvalue(operator=qubit_op) + with self.assertWarns(DeprecationWarning): + result = qaoa.compute_minimum_eigenvalue(operator=qubit_op) x = self._sample_most_likely(result.eigenstate) graph_solution = self._get_graph_solution(x) with self.subTest(msg="QAOA 4x4"): @@ -173,8 +176,8 @@ def test_change_operator_size(self): ] ) ) - - result = qaoa.compute_minimum_eigenvalue(operator=qubit_op) + with self.assertWarns(DeprecationWarning): + result = qaoa.compute_minimum_eigenvalue(operator=qubit_op) x = self._sample_most_likely(result.eigenstate) graph_solution = self._get_graph_solution(x) with self.subTest(msg="QAOA 6x6"): @@ -199,8 +202,8 @@ def cb_callback(eval_count, parameters, mean, metadata): initial_point=init_pt, callback=cb_callback, ) - - result = qaoa.compute_minimum_eigenvalue(operator=qubit_op) + with self.assertWarns(DeprecationWarning): + result = qaoa.compute_minimum_eigenvalue(operator=qubit_op) x = self._sample_most_likely(result.eigenstate) graph_solution = self._get_graph_solution(x) @@ -221,7 +224,8 @@ def test_qaoa_random_initial_point(self): ) qubit_op, _ = self._get_operator(w) qaoa = QAOA(self.sampler, NELDER_MEAD(disp=True), reps=2) - result = qaoa.compute_minimum_eigenvalue(operator=qubit_op) + with self.assertWarns(DeprecationWarning): + result = qaoa.compute_minimum_eigenvalue(operator=qubit_op) self.assertLess(result.eigenvalue, -0.97) @@ -235,7 +239,8 @@ def test_optimizer_scipy_callable(self): self.sampler, partial(scipy_minimize, method="Nelder-Mead", options={"maxiter": 2}), ) - result = qaoa.compute_minimum_eigenvalue(qubit_op) + with self.assertWarns(DeprecationWarning): + result = qaoa.compute_minimum_eigenvalue(qubit_op) self.assertEqual(result.cost_function_evals, 5) def _get_operator(self, weight_matrix): @@ -262,7 +267,8 @@ def _get_operator(self, weight_matrix): pauli_list.append([0.5 * weight_matrix[i, j], Pauli((z_p, x_p))]) shift -= 0.5 * weight_matrix[i, j] opflow_list = [(pauli[1].to_label(), pauli[0]) for pauli in pauli_list] - return PauliSumOp.from_list(opflow_list), shift + with self.assertWarns(DeprecationWarning): + return PauliSumOp.from_list(opflow_list), shift def _get_graph_solution(self, x: np.ndarray) -> str: """Get graph solution from binary string. diff --git a/test/python/algorithms/minimum_eigensolvers/test_vqe.py b/test/python/algorithms/minimum_eigensolvers/test_vqe.py index 31a55d27d438..4e61aa89f704 100644 --- a/test/python/algorithms/minimum_eigensolvers/test_vqe.py +++ b/test/python/algorithms/minimum_eigensolvers/test_vqe.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2022. +# (C) Copyright IBM 2022, 2023. # # 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 @@ -208,26 +208,27 @@ def test_gradient_run(self): def test_with_two_qubit_reduction(self): """Test the VQE using TwoQubitReduction.""" - qubit_op = PauliSumOp.from_list( - [ - ("IIII", -0.8105479805373266), - ("IIIZ", 0.17218393261915552), - ("IIZZ", -0.22575349222402472), - ("IZZI", 0.1721839326191556), - ("ZZII", -0.22575349222402466), - ("IIZI", 0.1209126326177663), - ("IZZZ", 0.16892753870087912), - ("IXZX", -0.045232799946057854), - ("ZXIX", 0.045232799946057854), - ("IXIX", 0.045232799946057854), - ("ZXZX", -0.045232799946057854), - ("ZZIZ", 0.16614543256382414), - ("IZIZ", 0.16614543256382414), - ("ZZZZ", 0.17464343068300453), - ("ZIZI", 0.1209126326177663), - ] - ) - tapered_qubit_op = TwoQubitReduction(num_particles=2).convert(qubit_op) + with self.assertWarns(DeprecationWarning): + qubit_op = PauliSumOp.from_list( + [ + ("IIII", -0.8105479805373266), + ("IIIZ", 0.17218393261915552), + ("IIZZ", -0.22575349222402472), + ("IZZI", 0.1721839326191556), + ("ZZII", -0.22575349222402466), + ("IIZI", 0.1209126326177663), + ("IZZZ", 0.16892753870087912), + ("IXZX", -0.045232799946057854), + ("ZXIX", 0.045232799946057854), + ("IXIX", 0.045232799946057854), + ("ZXZX", -0.045232799946057854), + ("ZZIZ", 0.16614543256382414), + ("IZIZ", 0.16614543256382414), + ("ZZZZ", 0.17464343068300453), + ("ZIZI", 0.1209126326177663), + ] + ) + tapered_qubit_op = TwoQubitReduction(num_particles=2).convert(qubit_op) vqe = VQE( Estimator(), self.ry_wavefunction, @@ -406,10 +407,14 @@ def test_aux_operators_list(self): self.assertEqual(len(result.aux_operators_evaluated), 0) with self.subTest("Test with two auxiliary operators."): - aux_op1 = PauliSumOp.from_list([("II", 2.0)]) - aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5), ("XX", -0.5)]) - aux_ops = [aux_op1, aux_op2] - result = vqe.compute_minimum_eigenvalue(self.h2_op, aux_operators=aux_ops) + with self.assertWarns(DeprecationWarning): + aux_op1 = PauliSumOp.from_list([("II", 2.0)]) + aux_op2 = PauliSumOp.from_list( + [("II", 0.5), ("ZZ", 0.5), ("YY", 0.5), ("XX", -0.5)] + ) + aux_ops = [aux_op1, aux_op2] + result = vqe.compute_minimum_eigenvalue(self.h2_op, aux_operators=aux_ops) + self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=5) self.assertEqual(len(result.aux_operators_evaluated), 2) # expectation values @@ -444,10 +449,13 @@ def test_aux_operators_dict(self): self.assertEqual(len(result.aux_operators_evaluated), 0) with self.subTest("Test with two auxiliary operators."): - aux_op1 = PauliSumOp.from_list([("II", 2.0)]) - aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5), ("XX", -0.5)]) - aux_ops = {"aux_op1": aux_op1, "aux_op2": aux_op2} - result = vqe.compute_minimum_eigenvalue(self.h2_op, aux_operators=aux_ops) + with self.assertWarns(DeprecationWarning): + aux_op1 = PauliSumOp.from_list([("II", 2.0)]) + aux_op2 = PauliSumOp.from_list( + [("II", 0.5), ("ZZ", 0.5), ("YY", 0.5), ("XX", -0.5)] + ) + aux_ops = {"aux_op1": aux_op1, "aux_op2": aux_op2} + result = vqe.compute_minimum_eigenvalue(self.h2_op, aux_operators=aux_ops) self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=6) self.assertEqual(len(result.aux_operators_evaluated), 2) diff --git a/test/python/algorithms/optimizers/test_gradient_descent.py b/test/python/algorithms/optimizers/test_gradient_descent.py index abe15f4b5362..8d2396650176 100644 --- a/test/python/algorithms/optimizers/test_gradient_descent.py +++ b/test/python/algorithms/optimizers/test_gradient_descent.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2021, 2022. +# (C) Copyright IBM 2021, 2023. # # 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 @@ -18,7 +18,6 @@ from qiskit.algorithms.optimizers.steppable_optimizer import TellData, AskData from qiskit.circuit.library import PauliTwoDesign from qiskit.opflow import I, Z, StateFn -from qiskit.test.decorators import slow_test class TestGradientDescent(QiskitAlgorithmsTestCase): @@ -37,13 +36,13 @@ def grad(self, x): """Gradient of the objective function""" return 2 * (np.linalg.norm(x) - 1) * x / np.linalg.norm(x) - @slow_test def test_pauli_two_design(self): """Test standard gradient descent on the Pauli two-design example.""" circuit = PauliTwoDesign(3, reps=3, seed=2) parameters = list(circuit.parameters) - obs = Z ^ Z ^ I - expr = ~StateFn(obs) @ StateFn(circuit) + with self.assertWarns(DeprecationWarning): + obs = Z ^ Z ^ I + expr = ~StateFn(obs) @ StateFn(circuit) initial_point = np.array( [ @@ -67,8 +66,8 @@ def objective_pauli(x): optimizer = GradientDescent(maxiter=100, learning_rate=0.1, perturbation=0.1) - result = optimizer.minimize(objective_pauli, x0=initial_point) - + with self.assertWarns(DeprecationWarning): + result = optimizer.minimize(objective_pauli, x0=initial_point) self.assertLess(result.fun, -0.95) # final loss self.assertEqual(result.nfev, 1300) # function evaluations diff --git a/test/python/algorithms/optimizers/test_optimizer_aqgd.py b/test/python/algorithms/optimizers/test_optimizer_aqgd.py index da1c6e8db889..7eebf6bc5ce7 100644 --- a/test/python/algorithms/optimizers/test_optimizer_aqgd.py +++ b/test/python/algorithms/optimizers/test_optimizer_aqgd.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2019, 2022 +# (C) Copyright IBM 2019, 2023 # # 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 @@ -28,17 +28,17 @@ class TestOptimizerAQGD(QiskitAlgorithmsTestCase): def setUp(self): super().setUp() - self.seed = 50 - algorithm_globals.random_seed = self.seed - self.qubit_op = PauliSumOp.from_list( - [ - ("II", -1.052373245772859), - ("IZ", 0.39793742484318045), - ("ZI", -0.39793742484318045), - ("ZZ", -0.01128010425623538), - ("XX", 0.18093119978423156), - ] - ) + algorithm_globals.random_seed = 50 + with self.assertWarns(DeprecationWarning): + self.qubit_op = PauliSumOp.from_list( + [ + ("II", -1.052373245772859), + ("IZ", 0.39793742484318045), + ("ZI", -0.39793742484318045), + ("ZZ", -0.01128010425623538), + ("XX", 0.18093119978423156), + ] + ) @slow_test @unittest.skipUnless(optionals.HAS_AER, "qiskit-aer is required to run this test") @@ -46,13 +46,14 @@ def test_simple(self): """test AQGD optimizer with the parameters as single values.""" from qiskit_aer import Aer - q_instance = QuantumInstance( - Aer.get_backend("aer_simulator_statevector"), - seed_simulator=algorithm_globals.random_seed, - seed_transpiler=algorithm_globals.random_seed, - ) - + with self.assertWarns(DeprecationWarning): + q_instance = QuantumInstance( + Aer.get_backend("aer_simulator_statevector"), + seed_simulator=algorithm_globals.random_seed, + seed_transpiler=algorithm_globals.random_seed, + ) aqgd = AQGD(momentum=0.0) + with self.assertWarns(DeprecationWarning): vqe = VQE( ansatz=RealAmplitudes(), @@ -61,6 +62,7 @@ def test_simple(self): quantum_instance=q_instance, ) result = vqe.compute_minimum_eigenvalue(operator=self.qubit_op) + self.assertAlmostEqual(result.eigenvalue.real, -1.857, places=3) @unittest.skipUnless(optionals.HAS_AER, "qiskit-aer is required to run this test") @@ -68,16 +70,18 @@ def test_list(self): """test AQGD optimizer with the parameters as lists.""" from qiskit_aer import Aer - q_instance = QuantumInstance( - Aer.get_backend("aer_simulator_statevector"), - seed_simulator=algorithm_globals.random_seed, - seed_transpiler=algorithm_globals.random_seed, - ) - + with self.assertWarns(DeprecationWarning): + q_instance = QuantumInstance( + Aer.get_backend("aer_simulator_statevector"), + seed_simulator=algorithm_globals.random_seed, + seed_transpiler=algorithm_globals.random_seed, + ) aqgd = AQGD(maxiter=[1000, 1000, 1000], eta=[1.0, 0.5, 0.3], momentum=[0.0, 0.5, 0.75]) + with self.assertWarns(DeprecationWarning): vqe = VQE(ansatz=RealAmplitudes(), optimizer=aqgd, quantum_instance=q_instance) result = vqe.compute_minimum_eigenvalue(operator=self.qubit_op) + self.assertAlmostEqual(result.eigenvalue.real, -1.857, places=3) def test_raises_exception(self): @@ -90,13 +94,14 @@ def test_int_values(self): """test AQGD with int values passed as eta and momentum.""" from qiskit_aer import Aer - q_instance = QuantumInstance( - Aer.get_backend("aer_simulator_statevector"), - seed_simulator=algorithm_globals.random_seed, - seed_transpiler=algorithm_globals.random_seed, - ) - + with self.assertWarns(DeprecationWarning): + q_instance = QuantumInstance( + Aer.get_backend("aer_simulator_statevector"), + seed_simulator=algorithm_globals.random_seed, + seed_transpiler=algorithm_globals.random_seed, + ) aqgd = AQGD(maxiter=1000, eta=1, momentum=0) + with self.assertWarns(DeprecationWarning): vqe = VQE( ansatz=RealAmplitudes(), @@ -105,6 +110,7 @@ def test_int_values(self): quantum_instance=q_instance, ) result = vqe.compute_minimum_eigenvalue(operator=self.qubit_op) + self.assertAlmostEqual(result.eigenvalue.real, -1.857, places=3) diff --git a/test/python/algorithms/optimizers/test_optimizer_nft.py b/test/python/algorithms/optimizers/test_optimizer_nft.py index 765c0ad3d880..31a29f4abd41 100644 --- a/test/python/algorithms/optimizers/test_optimizer_nft.py +++ b/test/python/algorithms/optimizers/test_optimizer_nft.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020, 2021. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -27,21 +27,20 @@ class TestOptimizerNFT(QiskitAlgorithmsTestCase): def setUp(self): super().setUp() - self.seed = 50 - algorithm_globals.random_seed = self.seed - self.qubit_op = PauliSumOp.from_list( - [ - ("II", -1.052373245772859), - ("IZ", 0.39793742484318045), - ("ZI", -0.39793742484318045), - ("ZZ", -0.01128010425623538), - ("XX", 0.18093119978423156), - ] - ) + algorithm_globals.random_seed = 50 + with self.assertWarns(DeprecationWarning): + self.qubit_op = PauliSumOp.from_list( + [ + ("II", -1.052373245772859), + ("IZ", 0.39793742484318045), + ("ZI", -0.39793742484318045), + ("ZZ", -0.01128010425623538), + ("XX", 0.18093119978423156), + ] + ) def test_nft(self): """Test NFT optimizer by using it""" - with self.assertWarns(DeprecationWarning): vqe = VQE( ansatz=RealAmplitudes(), @@ -53,6 +52,7 @@ def test_nft(self): ), ) result = vqe.compute_minimum_eigenvalue(operator=self.qubit_op) + self.assertAlmostEqual(result.eigenvalue.real, -1.857275, places=6) diff --git a/test/python/algorithms/optimizers/test_optimizers_scikitquant.py b/test/python/algorithms/optimizers/test_optimizers_scikitquant.py index f07a0238f7de..a980b046e758 100644 --- a/test/python/algorithms/optimizers/test_optimizers_scikitquant.py +++ b/test/python/algorithms/optimizers/test_optimizers_scikitquant.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020, 2021. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -35,26 +35,29 @@ def setUp(self): """Set the problem.""" super().setUp() algorithm_globals.random_seed = 50 - self.qubit_op = PauliSumOp.from_list( - [ - ("II", -1.052373245772859), - ("IZ", 0.39793742484318045), - ("ZI", -0.39793742484318045), - ("ZZ", -0.01128010425623538), - ("XX", 0.18093119978423156), - ] - ) + with self.assertWarns(DeprecationWarning): + self.qubit_op = PauliSumOp.from_list( + [ + ("II", -1.052373245772859), + ("IZ", 0.39793742484318045), + ("ZI", -0.39793742484318045), + ("ZZ", -0.01128010425623538), + ("XX", 0.18093119978423156), + ] + ) def _optimize(self, optimizer): """launch vqe""" - qe = QuantumInstance( - BasicAer.get_backend("statevector_simulator"), - seed_simulator=algorithm_globals.random_seed, - seed_transpiler=algorithm_globals.random_seed, - ) + with self.assertWarns(DeprecationWarning): + qe = QuantumInstance( + BasicAer.get_backend("statevector_simulator"), + seed_simulator=algorithm_globals.random_seed, + seed_transpiler=algorithm_globals.random_seed, + ) with self.assertWarns(DeprecationWarning): vqe = VQE(ansatz=RealAmplitudes(), optimizer=optimizer, quantum_instance=qe) result = vqe.compute_minimum_eigenvalue(operator=self.qubit_op) + self.assertAlmostEqual(result.eigenvalue.real, -1.857, places=1) def test_bobyqa(self): diff --git a/test/python/algorithms/optimizers/test_spsa.py b/test/python/algorithms/optimizers/test_spsa.py index 394bee0ba81d..7204a25e2003 100644 --- a/test/python/algorithms/optimizers/test_spsa.py +++ b/test/python/algorithms/optimizers/test_spsa.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2021. +# (C) Copyright IBM 2021, 2023. # # 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 @@ -40,8 +40,9 @@ def test_pauli_two_design(self, method): """Test SPSA on the Pauli two-design example.""" circuit = PauliTwoDesign(3, reps=1, seed=1) parameters = list(circuit.parameters) - obs = Z ^ Z ^ I - expr = ~StateFn(obs) @ StateFn(circuit) + with self.assertWarns(DeprecationWarning): + obs = Z ^ Z ^ I + expr = ~StateFn(obs) @ StateFn(circuit) initial_point = np.array( [0.82311034, 0.02611798, 0.21077064, 0.61842177, 0.09828447, 0.62013131] @@ -201,10 +202,12 @@ def objective(x): def test_qnspsa_fidelity_deprecation(self): """Test using a backend and expectation converter in get_fidelity warns.""" ansatz = PauliTwoDesign(2, reps=1, seed=2) + with self.assertWarns(DeprecationWarning): QNSPSA.get_fidelity(ansatz, backend=StatevectorSimulatorPy()) with self.assertWarns(DeprecationWarning): QNSPSA.get_fidelity(ansatz, expectation=MatrixExpectation()) + # No warning when used correctly. QNSPSA.get_fidelity(ansatz) @@ -230,7 +233,9 @@ def test_qnspsa_max_evals_grouped(self): """Test using max_evals_grouped with QNSPSA.""" circuit = PauliTwoDesign(3, reps=1, seed=1) num_parameters = circuit.num_parameters - obs = Z ^ Z ^ I + + with self.assertWarns(DeprecationWarning): + obs = Z ^ Z ^ I estimator = Estimator(options={"seed": 12}) diff --git a/test/python/algorithms/test_amplitude_estimators.py b/test/python/algorithms/test_amplitude_estimators.py index 4868f2643788..ea0a1af099ee 100644 --- a/test/python/algorithms/test_amplitude_estimators.py +++ b/test/python/algorithms/test_amplitude_estimators.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2018, 2022. +# (C) Copyright IBM 2018, 2023. # # 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 @@ -90,21 +90,24 @@ class TestBernoulli(QiskitAlgorithmsTestCase): def setUp(self): super().setUp() - self._statevector = QuantumInstance( - backend=BasicAer.get_backend("statevector_simulator"), - seed_simulator=2, - seed_transpiler=2, - ) + with self.assertWarns(DeprecationWarning): + self._statevector = QuantumInstance( + backend=BasicAer.get_backend("statevector_simulator"), + seed_simulator=2, + seed_transpiler=2, + ) self._sampler = Sampler(options={"seed": 2}) def qasm(shots=100): - return QuantumInstance( - backend=BasicAer.get_backend("qasm_simulator"), - shots=shots, - seed_simulator=2, - seed_transpiler=2, - ) + with self.assertWarns(DeprecationWarning): + qi = QuantumInstance( + backend=BasicAer.get_backend("qasm_simulator"), + shots=shots, + seed_simulator=2, + seed_transpiler=2, + ) + return qi self._qasm = qasm @@ -128,11 +131,13 @@ def sampler_shots(shots=100): @unpack def test_statevector(self, prob, qae, expect): """statevector test""" + + problem = EstimationProblem(BernoulliStateIn(prob), 0, BernoulliGrover(prob)) + with self.assertWarns(DeprecationWarning): qae.quantum_instance = self._statevector - problem = EstimationProblem(BernoulliStateIn(prob), 0, BernoulliGrover(prob)) + result = qae.estimate(problem) - result = qae.estimate(problem) self._statevector.reset_execution_results() for key, value in expect.items(): self.assertAlmostEqual( @@ -186,11 +191,12 @@ def test_sampler(self, prob, qae, expect): @unpack def test_qasm(self, prob, shots, qae, expect): """qasm test""" + with self.assertWarns(DeprecationWarning): qae.quantum_instance = self._qasm(shots) - problem = EstimationProblem(BernoulliStateIn(prob), [0], BernoulliGrover(prob)) + problem = EstimationProblem(BernoulliStateIn(prob), [0], BernoulliGrover(prob)) + result = qae.estimate(problem) - result = qae.estimate(problem) for key, value in expect.items(): self.assertAlmostEqual( value, getattr(result, key), places=3, msg=f"estimate `{key}` failed" @@ -375,21 +381,24 @@ class TestSineIntegral(QiskitAlgorithmsTestCase): def setUp(self): super().setUp() - self._statevector = QuantumInstance( - backend=BasicAer.get_backend("statevector_simulator"), - seed_simulator=123, - seed_transpiler=41, - ) + with self.assertWarns(DeprecationWarning): + self._statevector = QuantumInstance( + backend=BasicAer.get_backend("statevector_simulator"), + seed_simulator=123, + seed_transpiler=41, + ) self._sampler = Sampler(options={"seed": 123}) def qasm(shots=100): - return QuantumInstance( - backend=BasicAer.get_backend("qasm_simulator"), - shots=shots, - seed_simulator=7192, - seed_transpiler=90000, - ) + with self.assertWarns(DeprecationWarning): + qi = QuantumInstance( + backend=BasicAer.get_backend("qasm_simulator"), + shots=shots, + seed_simulator=7192, + seed_transpiler=90000, + ) + return qi self._qasm = qasm @@ -411,12 +420,13 @@ def test_statevector(self, n, qae, expect): """Statevector end-to-end test""" # construct factories for A and Q # qae.state_preparation = SineIntegral(n) + estimation_problem = EstimationProblem(SineIntegral(n), objective_qubits=[n]) + with self.assertWarns(DeprecationWarning): qae.quantum_instance = self._statevector - estimation_problem = EstimationProblem(SineIntegral(n), objective_qubits=[n]) + # result = qae.run(self._statevector) + result = qae.estimate(estimation_problem) - # result = qae.run(self._statevector) - result = qae.estimate(estimation_problem) self._statevector.reset_execution_results() for key, value in expect.items(): self.assertAlmostEqual( @@ -456,12 +466,12 @@ def test_sampler(self, n, qae, expect): @unpack def test_qasm(self, n, shots, qae, expect): """QASM simulator end-to-end test.""" - # construct factories for A and Q + estimation_problem = EstimationProblem(SineIntegral(n), objective_qubits=[n]) + with self.assertWarns(DeprecationWarning): qae.quantum_instance = self._qasm(shots) - estimation_problem = EstimationProblem(SineIntegral(n), objective_qubits=[n]) + result = qae.estimate(estimation_problem) - result = qae.estimate(estimation_problem) for key, value in expect.items(): self.assertAlmostEqual( value, getattr(result, key), places=3, msg=f"estimate `{key}` failed" @@ -514,12 +524,13 @@ def test_sampler_with_shots(self, n, shots, qae, expect): def test_confidence_intervals(self, qae, key, expect): """End-to-end test for all confidence intervals.""" n = 3 + + estimation_problem = EstimationProblem(SineIntegral(n), objective_qubits=[n]) with self.assertWarns(DeprecationWarning): qae.quantum_instance = self._statevector - estimation_problem = EstimationProblem(SineIntegral(n), objective_qubits=[n]) + # statevector simulator + result = qae.estimate(estimation_problem) - # statevector simulator - result = qae.estimate(estimation_problem) self._statevector.reset_execution_results() methods = ["lr", "fi", "oi"] # short for likelihood_ratio, fisher, observed_fisher alphas = [0.1, 0.00001, 0.9] # alpha shouldn't matter in statevector @@ -534,7 +545,8 @@ def test_confidence_intervals(self, qae, key, expect): alpha = 0.01 with self.assertWarns(DeprecationWarning): qae.quantum_instance = self._qasm(shots) - result = qae.estimate(estimation_problem) + result = qae.estimate(estimation_problem) + for method, expected_confint in expect.items(): confint = qae.compute_confidence_interval(result, alpha, method) np.testing.assert_array_almost_equal(confint, expected_confint) @@ -543,13 +555,14 @@ def test_confidence_intervals(self, qae, key, expect): def test_iqae_confidence_intervals(self): """End-to-end test for the IQAE confidence interval.""" n = 3 - with self.assertWarns(DeprecationWarning): - qae = IterativeAmplitudeEstimation(0.1, 0.01, quantum_instance=self._statevector) expected_confint = (0.1984050, 0.3511015) estimation_problem = EstimationProblem(SineIntegral(n), objective_qubits=[n]) - # statevector simulator - result = qae.estimate(estimation_problem) + with self.assertWarns(DeprecationWarning): + qae = IterativeAmplitudeEstimation(0.1, 0.01, quantum_instance=self._statevector) + # statevector simulator + result = qae.estimate(estimation_problem) + self._statevector.reset_execution_results() confint = result.confidence_interval # confidence interval based on statevector should be empty, as we are sure of the result @@ -558,9 +571,11 @@ def test_iqae_confidence_intervals(self): # qasm simulator shots = 100 + with self.assertWarns(DeprecationWarning): qae.quantum_instance = self._qasm(shots) - result = qae.estimate(estimation_problem) + result = qae.estimate(estimation_problem) + confint = result.confidence_interval np.testing.assert_array_almost_equal(confint, expected_confint) self.assertTrue(confint[0] <= result.estimation <= confint[1]) @@ -611,11 +626,12 @@ def test_run_without_rescaling(self): # construct algo without rescaling backend = BasicAer.get_backend("statevector_simulator") + with self.assertWarns(DeprecationWarning): fae = FasterAmplitudeEstimation(0.1, 1, rescale=False, quantum_instance=backend) - # run the algo - result = fae.estimate(problem) + # run the algo + result = fae.estimate(problem) # assert the result is correct self.assertAlmostEqual(result.estimation, prob) @@ -688,15 +704,17 @@ def is_good_state(bitstr): ) # construct algo - backend = QuantumInstance( - BasicAer.get_backend(backend_str), seed_simulator=2, seed_transpiler=2 - ) + with self.assertWarns(DeprecationWarning): + backend = QuantumInstance( + BasicAer.get_backend(backend_str), seed_simulator=2, seed_transpiler=2 + ) # cannot use rescaling with a custom grover operator + with self.assertWarns(DeprecationWarning): fae = FasterAmplitudeEstimation(0.01, 5, rescale=False, quantum_instance=backend) - # run the algo - result = fae.estimate(problem) + # run the algo + result = fae.estimate(problem) # assert the result is correct self.assertAlmostEqual(result.estimation, expect, places=5) diff --git a/test/python/algorithms/test_aux_ops_evaluator.py b/test/python/algorithms/test_aux_ops_evaluator.py index 5a75843eeac9..11e4c8e76fc5 100644 --- a/test/python/algorithms/test_aux_ops_evaluator.py +++ b/test/python/algorithms/test_aux_ops_evaluator.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2022. +# (C) Copyright IBM 2022, 2023. # # 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 @@ -45,13 +45,14 @@ def setUp(self): super().setUp() self.seed = 50 algorithm_globals.random_seed = self.seed - self.h2_op = ( - -1.052373245772859 * (I ^ I) - + 0.39793742484318045 * (I ^ Z) - - 0.39793742484318045 * (Z ^ I) - - 0.01128010425623538 * (Z ^ Z) - + 0.18093119978423156 * (X ^ X) - ) + with self.assertWarns(DeprecationWarning): + self.h2_op = ( + -1.052373245772859 * (I ^ I) + + 0.39793742484318045 * (I ^ Z) + - 0.39793742484318045 * (Z ^ I) + - 0.01128010425623538 * (Z ^ Z) + + 0.18093119978423156 * (X ^ X) + ) self.threshold = 1e-8 self.backend_names = ["statevector_simulator", "qasm_simulator"] @@ -85,6 +86,7 @@ def _run_test( observables: ListOrDict[OperatorBase], quantum_instance: Union[QuantumInstance, Backend], ): + with self.assertWarns(DeprecationWarning): result = eval_observables( quantum_instance, quantum_state, observables, expectation, self.threshold @@ -133,16 +135,17 @@ def test_eval_observables(self, observables: ListOrDict[OperatorBase]): ) # to accommodate for qasm being imperfect with self.subTest(msg=f"Test {backend_name} backend."): backend = BasicAer.get_backend(backend_name) - quantum_instance = QuantumInstance( - backend=backend, - shots=shots, - seed_simulator=self.seed, - seed_transpiler=self.seed, - ) - expectation = ExpectationFactory.build( - operator=self.h2_op, - backend=quantum_instance, - ) + with self.assertWarns(DeprecationWarning): + quantum_instance = QuantumInstance( + backend=backend, + shots=shots, + seed_simulator=self.seed, + seed_transpiler=self.seed, + ) + expectation = ExpectationFactory.build( + operator=self.h2_op, + backend=quantum_instance, + ) with self.subTest(msg="Test QuantumCircuit."): self._run_test( @@ -174,17 +177,17 @@ def test_eval_observables(self, observables: ListOrDict[OperatorBase]): observables, quantum_instance, ) - - with self.subTest(msg="Test StateFn."): - statefn = StateFn(bound_ansatz) - self._run_test( - expected_result, - statefn, - decimal, - expectation, - observables, - quantum_instance, - ) + with self.assertWarns(DeprecationWarning): + with self.subTest(msg="Test StateFn."): + statefn = StateFn(bound_ansatz) + self._run_test( + expected_result, + statefn, + decimal, + expectation, + observables, + quantum_instance, + ) if __name__ == "__main__": diff --git a/test/python/algorithms/test_backendv1.py b/test/python/algorithms/test_backendv1.py index 2ed807d3d8ce..2dd8ca339e84 100644 --- a/test/python/algorithms/test_backendv1.py +++ b/test/python/algorithms/test_backendv1.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2021, 2022. +# (C) Copyright IBM 2021, 2023. # # 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 @@ -35,18 +35,21 @@ def setUp(self): def test_vqe_qasm(self): """Test the VQE on QASM simulator.""" - h2_op = ( - -1.052373245772859 * (I ^ I) - + 0.39793742484318045 * (I ^ Z) - - 0.39793742484318045 * (Z ^ I) - - 0.01128010425623538 * (Z ^ Z) - + 0.18093119978423156 * (X ^ X) - ) optimizer = SPSA(maxiter=300, last_avg=5) wavefunction = TwoLocal(rotation_blocks="ry", entanglement_blocks="cz") - qasm_simulator = QuantumInstance( - self._qasm, shots=1024, seed_simulator=self.seed, seed_transpiler=self.seed - ) + + with self.assertWarns(DeprecationWarning): + h2_op = ( + -1.052373245772859 * (I ^ I) + + 0.39793742484318045 * (I ^ Z) + - 0.39793742484318045 * (Z ^ I) + - 0.01128010425623538 * (Z ^ Z) + + 0.18093119978423156 * (X ^ X) + ) + qasm_simulator = QuantumInstance( + self._qasm, shots=1024, seed_simulator=self.seed, seed_transpiler=self.seed + ) + with self.assertWarns(DeprecationWarning): vqe = VQE( ansatz=wavefunction, @@ -55,6 +58,7 @@ def test_vqe_qasm(self): quantum_instance=qasm_simulator, ) result = vqe.compute_minimum_eigenvalue(operator=h2_op) + self.assertAlmostEqual(result.eigenvalue.real, -1.86, delta=0.05) def test_run_circuit_oracle(self): @@ -62,12 +66,16 @@ def test_run_circuit_oracle(self): oracle = QuantumCircuit(2) oracle.cz(0, 1) problem = AmplificationProblem(oracle, is_good_state=["11"]) - qi = QuantumInstance( - self._provider.get_backend("fake_vigo"), seed_simulator=12, seed_transpiler=32 - ) + + with self.assertWarns(DeprecationWarning): + qi = QuantumInstance( + self._provider.get_backend("fake_vigo"), seed_simulator=12, seed_transpiler=32 + ) + with self.assertWarns(DeprecationWarning): grover = Grover(quantum_instance=qi) - result = grover.amplify(problem) + result = grover.amplify(problem) + self.assertIn(result.top_measurement, ["11"]) def test_run_circuit_oracle_single_experiment_backend(self): @@ -77,10 +85,14 @@ def test_run_circuit_oracle_single_experiment_backend(self): problem = AmplificationProblem(oracle, is_good_state=["11"]) backend = self._provider.get_backend("fake_vigo") backend._configuration.max_experiments = 1 - qi = QuantumInstance(backend, seed_simulator=12, seed_transpiler=32) + + with self.assertWarns(DeprecationWarning): + qi = QuantumInstance(backend, seed_simulator=12, seed_transpiler=32) + with self.assertWarns(DeprecationWarning): grover = Grover(quantum_instance=qi) - result = grover.amplify(problem) + result = grover.amplify(problem) + self.assertIn(result.top_measurement, ["11"]) def test_measurement_error_mitigation_with_vqe(self): @@ -100,27 +112,29 @@ def test_measurement_error_mitigation_with_vqe(self): backend = self._qasm - quantum_instance = QuantumInstance( - backend=backend, - seed_simulator=167, - seed_transpiler=167, - noise_model=noise_model, - measurement_error_mitigation_cls=CompleteMeasFitter, - ) - - h2_hamiltonian = ( - -1.052373245772859 * (I ^ I) - + 0.39793742484318045 * (I ^ Z) - - 0.39793742484318045 * (Z ^ I) - - 0.01128010425623538 * (Z ^ Z) - + 0.18093119978423156 * (X ^ X) - ) + with self.assertWarns(DeprecationWarning): + quantum_instance = QuantumInstance( + backend=backend, + seed_simulator=167, + seed_transpiler=167, + noise_model=noise_model, + measurement_error_mitigation_cls=CompleteMeasFitter, + ) + h2_hamiltonian = ( + -1.052373245772859 * (I ^ I) + + 0.39793742484318045 * (I ^ Z) + - 0.39793742484318045 * (Z ^ I) + - 0.01128010425623538 * (Z ^ Z) + + 0.18093119978423156 * (X ^ X) + ) + optimizer = SPSA(maxiter=200) ansatz = EfficientSU2(2, reps=1) with self.assertWarns(DeprecationWarning): vqe = VQE(ansatz=ansatz, optimizer=optimizer, quantum_instance=quantum_instance) result = vqe.compute_minimum_eigenvalue(operator=h2_hamiltonian) + self.assertGreater(quantum_instance.time_taken, 0.0) quantum_instance.reset_execution_results() self.assertAlmostEqual(result.eigenvalue.real, -1.86, delta=0.05) diff --git a/test/python/algorithms/test_backendv2.py b/test/python/algorithms/test_backendv2.py index 83bbf848f211..0987a631f690 100644 --- a/test/python/algorithms/test_backendv2.py +++ b/test/python/algorithms/test_backendv2.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2021, 2022. +# (C) Copyright IBM 2021, 2023. # # 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 @@ -35,18 +35,21 @@ def setUp(self): def test_vqe_qasm(self): """Test the VQE on QASM simulator.""" - h2_op = ( - -1.052373245772859 * (I ^ I) - + 0.39793742484318045 * (I ^ Z) - - 0.39793742484318045 * (Z ^ I) - - 0.01128010425623538 * (Z ^ Z) - + 0.18093119978423156 * (X ^ X) - ) optimizer = SPSA(maxiter=300, last_avg=5) wavefunction = TwoLocal(rotation_blocks="ry", entanglement_blocks="cz") - qasm_simulator = QuantumInstance( - self._qasm, shots=1024, seed_simulator=self.seed, seed_transpiler=self.seed - ) + + with self.assertWarns(DeprecationWarning): + h2_op = ( + -1.052373245772859 * (I ^ I) + + 0.39793742484318045 * (I ^ Z) + - 0.39793742484318045 * (Z ^ I) + - 0.01128010425623538 * (Z ^ Z) + + 0.18093119978423156 * (X ^ X) + ) + qasm_simulator = QuantumInstance( + self._qasm, shots=1024, seed_simulator=self.seed, seed_transpiler=self.seed + ) + with self.assertWarns(DeprecationWarning): vqe = VQE( ansatz=wavefunction, @@ -55,6 +58,7 @@ def test_vqe_qasm(self): quantum_instance=qasm_simulator, ) result = vqe.compute_minimum_eigenvalue(operator=h2_op) + self.assertAlmostEqual(result.eigenvalue.real, -1.86, delta=0.05) def test_run_circuit_oracle(self): @@ -62,12 +66,16 @@ def test_run_circuit_oracle(self): oracle = QuantumCircuit(2) oracle.cz(0, 1) problem = AmplificationProblem(oracle, is_good_state=["11"]) - qi = QuantumInstance( - self._provider.get_backend("fake_yorktown"), seed_simulator=12, seed_transpiler=32 - ) + + with self.assertWarns(DeprecationWarning): + qi = QuantumInstance( + self._provider.get_backend("fake_yorktown"), seed_simulator=12, seed_transpiler=32 + ) + with self.assertWarns(DeprecationWarning): grover = Grover(quantum_instance=qi) - result = grover.amplify(problem) + result = grover.amplify(problem) + self.assertIn(result.top_measurement, ["11"]) def test_run_circuit_oracle_single_experiment_backend(self): @@ -77,12 +85,16 @@ def test_run_circuit_oracle_single_experiment_backend(self): problem = AmplificationProblem(oracle, is_good_state=["11"]) backend = self._provider.get_backend("fake_yorktown") backend._configuration.max_experiments = 1 - qi = QuantumInstance( - self._provider.get_backend("fake_yorktown"), seed_simulator=12, seed_transpiler=32 - ) + + with self.assertWarns(DeprecationWarning): + qi = QuantumInstance( + self._provider.get_backend("fake_yorktown"), seed_simulator=12, seed_transpiler=32 + ) + with self.assertWarns(DeprecationWarning): grover = Grover(quantum_instance=qi) - result = grover.amplify(problem) + result = grover.amplify(problem) + self.assertIn(result.top_measurement, ["11"]) diff --git a/test/python/algorithms/test_grover.py b/test/python/algorithms/test_grover.py index ae9e627b411f..8fdeb12a7964 100644 --- a/test/python/algorithms/test_grover.py +++ b/test/python/algorithms/test_grover.py @@ -91,12 +91,13 @@ class TestGrover(QiskitAlgorithmsTestCase): def setUp(self): super().setUp() - self.statevector = QuantumInstance( - BasicAer.get_backend("statevector_simulator"), seed_simulator=12, seed_transpiler=32 - ) - self.qasm = QuantumInstance( - BasicAer.get_backend("qasm_simulator"), seed_simulator=12, seed_transpiler=32 - ) + with self.assertWarns(DeprecationWarning): + self.statevector = QuantumInstance( + BasicAer.get_backend("statevector_simulator"), seed_simulator=12, seed_transpiler=32 + ) + self.qasm = QuantumInstance( + BasicAer.get_backend("qasm_simulator"), seed_simulator=12, seed_transpiler=32 + ) self._sampler = Sampler() self._sampler_with_shots = Sampler(options={"shots": 1024, "seed": 123}) algorithm_globals.random_seed = 123 @@ -108,7 +109,11 @@ def test_implicit_phase_oracle_is_good_state(self, use_sampler): grover = self._prepare_grover(use_sampler) oracle = PhaseOracle("x & y") problem = AmplificationProblem(oracle) - result = grover.amplify(problem) + if not use_sampler: + with self.assertWarns(DeprecationWarning): + result = grover.amplify(problem) + else: + result = grover.amplify(problem) self.assertEqual(result.top_measurement, "11") @idata(itertools.product(["ideal", "shots", False], [[1, 2, 3], None, 2])) @@ -117,7 +122,11 @@ def test_iterations_with_good_state(self, use_sampler, iterations): """Test the algorithm with different iteration types and with good state""" grover = self._prepare_grover(use_sampler, iterations) problem = AmplificationProblem(Statevector.from_label("111"), is_good_state=["111"]) - result = grover.amplify(problem) + if not use_sampler: + with self.assertWarns(DeprecationWarning): + result = grover.amplify(problem) + else: + result = grover.amplify(problem) self.assertEqual(result.top_measurement, "111") @idata(itertools.product(["shots", False], [[1, 2, 3], None, 2])) @@ -126,7 +135,11 @@ def test_iterations_with_good_state_sample_from_iterations(self, use_sampler, it """Test the algorithm with different iteration types and with good state""" grover = self._prepare_grover(use_sampler, iterations, sample_from_iterations=True) problem = AmplificationProblem(Statevector.from_label("111"), is_good_state=["111"]) - result = grover.amplify(problem) + if not use_sampler: + with self.assertWarns(DeprecationWarning): + result = grover.amplify(problem) + else: + result = grover.amplify(problem) self.assertEqual(result.top_measurement, "111") @data("ideal", "shots", False) @@ -134,7 +147,11 @@ def test_fixed_iterations_without_good_state(self, use_sampler): """Test the algorithm with iterations as an int and without good state""" grover = self._prepare_grover(use_sampler, iterations=2) problem = AmplificationProblem(Statevector.from_label("111")) - result = grover.amplify(problem) + if not use_sampler: + with self.assertWarns(DeprecationWarning): + result = grover.amplify(problem) + else: + result = grover.amplify(problem) self.assertEqual(result.top_measurement, "111") @idata(itertools.product(["ideal", "shots", False], [[1, 2, 3], None])) @@ -143,10 +160,15 @@ def test_iterations_without_good_state(self, use_sampler, iterations): """Test the correct error is thrown for none/list of iterations and without good state""" grover = self._prepare_grover(use_sampler, iterations=iterations) problem = AmplificationProblem(Statevector.from_label("111")) + with self.assertRaisesRegex( TypeError, "An is_good_state function is required with the provided oracle" ): - grover.amplify(problem) + if not use_sampler: + with self.assertWarns(DeprecationWarning): + grover.amplify(problem) + else: + grover.amplify(problem) @data("ideal", "shots", False) def test_iterator(self, use_sampler): @@ -163,7 +185,11 @@ def iterator(): grover = self._prepare_grover(use_sampler, iterations=iterator()) problem = AmplificationProblem(Statevector.from_label("111"), is_good_state=["111"]) - result = grover.amplify(problem) + if not use_sampler: + with self.assertWarns(DeprecationWarning): + result = grover.amplify(problem) + else: + result = grover.amplify(problem) self.assertEqual(result.top_measurement, "111") @data("ideal", "shots", False) @@ -171,7 +197,11 @@ def test_growth_rate(self, use_sampler): """Test running the algorithm on a growth rate""" grover = self._prepare_grover(use_sampler, growth_rate=8 / 7) problem = AmplificationProblem(Statevector.from_label("111"), is_good_state=["111"]) - result = grover.amplify(problem) + if not use_sampler: + with self.assertWarns(DeprecationWarning): + result = grover.amplify(problem) + else: + result = grover.amplify(problem) self.assertEqual(result.top_measurement, "111") @data("ideal", "shots", False) @@ -185,7 +215,11 @@ def zero(): grover = self._prepare_grover(use_sampler, iterations=zero()) n = 5 problem = AmplificationProblem(Statevector.from_label("1" * n), is_good_state=["1" * n]) - result = grover.amplify(problem) + if not use_sampler: + with self.assertWarns(DeprecationWarning): + result = grover.amplify(problem) + else: + result = grover.amplify(problem) self.assertEqual(len(result.iterations), 2**n) @data("ideal", "shots", False) @@ -204,7 +238,11 @@ def test_run_circuit_oracle(self, use_sampler): oracle.cz(0, 1) problem = AmplificationProblem(oracle, is_good_state=["11"]) grover = self._prepare_grover(use_sampler) - result = grover.amplify(problem) + if not use_sampler: + with self.assertWarns(DeprecationWarning): + result = grover.amplify(problem) + else: + result = grover.amplify(problem) self.assertIn(result.top_measurement, ["11"]) @data("ideal", "shots", False) @@ -213,7 +251,11 @@ def test_run_state_vector_oracle(self, use_sampler): mark_state = Statevector.from_label("11") problem = AmplificationProblem(mark_state, is_good_state=["11"]) grover = self._prepare_grover(use_sampler) - result = grover.amplify(problem) + if not use_sampler: + with self.assertWarns(DeprecationWarning): + result = grover.amplify(problem) + else: + result = grover.amplify(problem) self.assertIn(result.top_measurement, ["11"]) @data("ideal", "shots", False) @@ -226,8 +268,12 @@ def test_run_custom_grover_operator(self, use_sampler): oracle=oracle, grover_operator=grover_op, is_good_state=["11"] ) grover = self._prepare_grover(use_sampler) - ret = grover.amplify(problem) - self.assertIn(ret.top_measurement, ["11"]) + if not use_sampler: + with self.assertWarns(DeprecationWarning): + result = grover.amplify(problem) + else: + result = grover.amplify(problem) + self.assertIn(result.top_measurement, ["11"]) def test_optimal_num_iterations(self): """Test optimal_num_iterations""" @@ -261,7 +307,11 @@ def test_circuit_result(self, use_sampler): # is_good_state=['00'] is intentionally selected to obtain a list of results problem = AmplificationProblem(oracle, is_good_state=["00"]) grover = self._prepare_grover(use_sampler, iterations=[1, 2, 3, 4]) - result = grover.amplify(problem) + if not use_sampler: + with self.assertWarns(DeprecationWarning): + result = grover.amplify(problem) + else: + result = grover.amplify(problem) if use_sampler: for i, dist in enumerate(result.circuit_results): keys, values = zip(*sorted(dist.items())) @@ -287,7 +337,11 @@ def test_max_probability(self, use_sampler): oracle.cz(0, 1) problem = AmplificationProblem(oracle, is_good_state=["11"]) grover = self._prepare_grover(use_sampler) - result = grover.amplify(problem) + if not use_sampler: + with self.assertWarns(DeprecationWarning): + result = grover.amplify(problem) + else: + result = grover.amplify(problem) self.assertAlmostEqual(result.max_probability, 1.0) @unittest.skipUnless(HAS_TWEEDLEDUM, "tweedledum required for this test") @@ -297,7 +351,11 @@ def test_oracle_evaluation(self, use_sampler): oracle = PhaseOracle("x1 & x2 & (not x3)") problem = AmplificationProblem(oracle, is_good_state=oracle.evaluate_bitstring) grover = self._prepare_grover(use_sampler) - result = grover.amplify(problem) + if not use_sampler: + with self.assertWarns(DeprecationWarning): + result = grover.amplify(problem) + else: + result = grover.amplify(problem) self.assertTrue(result.oracle_evaluation) self.assertEqual("011", result.top_measurement) diff --git a/test/python/algorithms/test_measure_error_mitigation.py b/test/python/algorithms/test_measure_error_mitigation.py index 8a53708ec5f4..a252ab08af7d 100644 --- a/test/python/algorithms/test_measure_error_mitigation.py +++ b/test/python/algorithms/test_measure_error_mitigation.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2019, 2022. +# (C) Copyright IBM 2019, 2023. # # 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 @@ -13,7 +13,6 @@ """Test Measurement Error Mitigation""" import unittest - from test.python.algorithms import QiskitAlgorithmsTestCase from ddt import ddt, data, unpack import numpy as np @@ -72,16 +71,19 @@ def test_measurement_error_mitigation_with_diff_qubit_order( CompleteMeasFitter if fitter_str == "CompleteMeasFitter" else TensoredMeasFitter ) backend = Aer.get_backend("aer_simulator") - quantum_instance = QuantumInstance( - backend=backend, - seed_simulator=1679, - seed_transpiler=167, - shots=1000, - noise_model=noise_model, - measurement_error_mitigation_cls=fitter_cls, - cals_matrix_refresh_period=0, - mit_pattern=mit_pattern, - ) + + with self.assertWarns(DeprecationWarning): + quantum_instance = QuantumInstance( + backend=backend, + seed_simulator=1679, + seed_transpiler=167, + shots=1000, + noise_model=noise_model, + measurement_error_mitigation_cls=fitter_cls, + cals_matrix_refresh_period=0, + mit_pattern=mit_pattern, + ) + # circuit qc1 = QuantumCircuit(2, 2) qc1.h(0) @@ -94,15 +96,16 @@ def test_measurement_error_mitigation_with_diff_qubit_order( qc2.measure(1, 0) qc2.measure(0, 1) - if fails: - self.assertRaisesRegex( - QiskitError, - "Each element in the mit pattern should have length 1.", - quantum_instance.execute, - [qc1, qc2], - ) - else: - quantum_instance.execute([qc1, qc2]) + with self.assertWarns(DeprecationWarning): + if fails: + self.assertRaisesRegex( + QiskitError, + "Each element in the mit pattern should have length 1.", + quantum_instance.execute, + [qc1, qc2], + ) + else: + quantum_instance.execute([qc1, qc2]) self.assertGreater(quantum_instance.time_taken, 0.0) quantum_instance.reset_execution_results() @@ -114,7 +117,8 @@ def test_measurement_error_mitigation_with_diff_qubit_order( qc3.measure(2, 1) qc3.measure(1, 2) - self.assertRaises(QiskitError, quantum_instance.execute, [qc1, qc3]) + with self.assertWarns(DeprecationWarning): + self.assertRaises(QiskitError, quantum_instance.execute, [qc1, qc3]) @unittest.skipUnless(optionals.HAS_AER, "qiskit-aer is required for this test") @data(("CompleteMeasFitter", None), ("TensoredMeasFitter", [[0], [1]])) @@ -133,28 +137,33 @@ def test_measurement_error_mitigation_with_vqe(self, config): CompleteMeasFitter if fitter_str == "CompleteMeasFitter" else TensoredMeasFitter ) backend = Aer.get_backend("aer_simulator") - quantum_instance = QuantumInstance( - backend=backend, - seed_simulator=167, - seed_transpiler=167, - noise_model=noise_model, - measurement_error_mitigation_cls=fitter_cls, - mit_pattern=mit_pattern, - ) - h2_hamiltonian = ( - -1.052373245772859 * (I ^ I) - + 0.39793742484318045 * (I ^ Z) - - 0.39793742484318045 * (Z ^ I) - - 0.01128010425623538 * (Z ^ Z) - + 0.18093119978423156 * (X ^ X) - ) + with self.assertWarns(DeprecationWarning): + quantum_instance = QuantumInstance( + backend=backend, + seed_simulator=167, + seed_transpiler=167, + noise_model=noise_model, + measurement_error_mitigation_cls=fitter_cls, + mit_pattern=mit_pattern, + ) + optimizer = SPSA(maxiter=200) ansatz = EfficientSU2(2, reps=1) + with self.assertWarns(DeprecationWarning): + h2_hamiltonian = ( + -1.052373245772859 * (I ^ I) + + 0.39793742484318045 * (I ^ Z) + - 0.39793742484318045 * (Z ^ I) + - 0.01128010425623538 * (Z ^ Z) + + 0.18093119978423156 * (X ^ X) + ) + with self.assertWarns(DeprecationWarning): vqe = VQE(ansatz=ansatz, optimizer=optimizer, quantum_instance=quantum_instance) result = vqe.compute_minimum_eigenvalue(operator=h2_hamiltonian) + self.assertGreater(quantum_instance.time_taken, 0.0) quantum_instance.reset_execution_results() self.assertAlmostEqual(result.eigenvalue.real, -1.86, delta=0.05) @@ -183,7 +192,9 @@ def _get_operator(self, weight_matrix): pauli_list.append([0.5 * weight_matrix[i, j], Pauli((z_p, x_p))]) shift -= 0.5 * weight_matrix[i, j] opflow_list = [(pauli[1].to_label(), pauli[0]) for pauli in pauli_list] - return PauliSumOp.from_list(opflow_list), shift + + with self.assertWarns(DeprecationWarning): + return PauliSumOp.from_list(opflow_list), shift @unittest.skipUnless(optionals.HAS_AER, "qiskit-aer is required for this test") def test_measurement_error_mitigation_qaoa(self): @@ -197,11 +208,13 @@ def test_measurement_error_mitigation_qaoa(self): initial_point = np.asarray([0.0, 0.0]) # Compute first without noise - quantum_instance = QuantumInstance( - backend=backend, - seed_simulator=algorithm_globals.random_seed, - seed_transpiler=algorithm_globals.random_seed, - ) + with self.assertWarns(DeprecationWarning): + quantum_instance = QuantumInstance( + backend=backend, + seed_simulator=algorithm_globals.random_seed, + seed_transpiler=algorithm_globals.random_seed, + ) + with self.assertWarns(DeprecationWarning): qaoa = QAOA( optimizer=COBYLA(maxiter=3), @@ -209,6 +222,7 @@ def test_measurement_error_mitigation_qaoa(self): initial_point=initial_point, ) result = qaoa.compute_minimum_eigenvalue(operator=qubit_op) + ref_eigenvalue = result.eigenvalue.real # compute with noise @@ -217,22 +231,25 @@ def test_measurement_error_mitigation_qaoa(self): read_err = noise.errors.readout_error.ReadoutError([[0.9, 0.1], [0.25, 0.75]]) noise_model.add_all_qubit_readout_error(read_err) - quantum_instance = QuantumInstance( - backend=backend, - seed_simulator=algorithm_globals.random_seed, - seed_transpiler=algorithm_globals.random_seed, - noise_model=noise_model, - measurement_error_mitigation_cls=CompleteMeasFitter, - shots=10000, - ) + with self.assertWarns(DeprecationWarning): + quantum_instance = QuantumInstance( + backend=backend, + seed_simulator=algorithm_globals.random_seed, + seed_transpiler=algorithm_globals.random_seed, + noise_model=noise_model, + measurement_error_mitigation_cls=CompleteMeasFitter, + shots=10000, + ) with self.assertWarns(DeprecationWarning): + qaoa = QAOA( optimizer=COBYLA(maxiter=3), quantum_instance=quantum_instance, initial_point=initial_point, ) result = qaoa.compute_minimum_eigenvalue(operator=qubit_op) + self.assertAlmostEqual(result.eigenvalue.real, ref_eigenvalue, delta=0.05) @unittest.skipUnless(optionals.HAS_AER, "qiskit-aer is required for this test") @@ -251,15 +268,18 @@ def test_measurement_error_mitigation_with_diff_qubit_order_ignis(self, fitter_s CompleteMeasFitter_IG if fitter_str == "CompleteMeasFitter" else TensoredMeasFitter_IG ) backend = Aer.get_backend("aer_simulator") - quantum_instance = QuantumInstance( - backend=backend, - seed_simulator=1679, - seed_transpiler=167, - shots=1000, - noise_model=noise_model, - measurement_error_mitigation_cls=fitter_cls, - cals_matrix_refresh_period=0, - ) + + with self.assertWarns(DeprecationWarning): + quantum_instance = QuantumInstance( + backend=backend, + seed_simulator=1679, + seed_transpiler=167, + shots=1000, + noise_model=noise_model, + measurement_error_mitigation_cls=fitter_cls, + cals_matrix_refresh_period=0, + ) + # circuit qc1 = QuantumCircuit(2, 2) qc1.h(0) @@ -314,14 +334,16 @@ def test_measurement_error_mitigation_with_vqe_ignis(self, config): CompleteMeasFitter_IG if fitter_str == "CompleteMeasFitter" else TensoredMeasFitter_IG ) backend = Aer.get_backend("aer_simulator") - quantum_instance = QuantumInstance( - backend=backend, - seed_simulator=167, - seed_transpiler=167, - noise_model=noise_model, - measurement_error_mitigation_cls=fitter_cls, - mit_pattern=mit_pattern, - ) + + with self.assertWarns(DeprecationWarning): + quantum_instance = QuantumInstance( + backend=backend, + seed_simulator=167, + seed_transpiler=167, + noise_model=noise_model, + measurement_error_mitigation_cls=fitter_cls, + mit_pattern=mit_pattern, + ) h2_hamiltonian = ( -1.052373245772859 * (I ^ I) @@ -336,6 +358,7 @@ def test_measurement_error_mitigation_with_vqe_ignis(self, config): with self.assertWarnsRegex(DeprecationWarning): vqe = VQE(ansatz=ansatz, optimizer=optimizer, quantum_instance=quantum_instance) result = vqe.compute_minimum_eigenvalue(operator=h2_hamiltonian) + self.assertGreater(quantum_instance.time_taken, 0.0) quantum_instance.reset_execution_results() self.assertAlmostEqual(result.eigenvalue.real, -1.86, delta=0.05) @@ -355,24 +378,25 @@ def test_calibration_results(self): counts_array = [None, None] for idx, is_use_mitigation in enumerate([True, False]): - if is_use_mitigation: - quantum_instance = QuantumInstance( - backend, - seed_simulator=algorithm_globals.random_seed, - seed_transpiler=algorithm_globals.random_seed, - shots=1024, - measurement_error_mitigation_cls=CompleteMeasFitter_IG, - ) - with self.assertWarnsRegex(DeprecationWarning, r".*ignis.*"): + with self.assertWarns(DeprecationWarning): + if is_use_mitigation: + quantum_instance = QuantumInstance( + backend, + seed_simulator=algorithm_globals.random_seed, + seed_transpiler=algorithm_globals.random_seed, + shots=1024, + measurement_error_mitigation_cls=CompleteMeasFitter_IG, + ) + with self.assertWarnsRegex(DeprecationWarning, r".*ignis.*"): + counts_array[idx] = quantum_instance.execute(qc_meas).get_counts() + else: + quantum_instance = QuantumInstance( + backend, + seed_simulator=algorithm_globals.random_seed, + seed_transpiler=algorithm_globals.random_seed, + shots=1024, + ) counts_array[idx] = quantum_instance.execute(qc_meas).get_counts() - else: - quantum_instance = QuantumInstance( - backend, - seed_simulator=algorithm_globals.random_seed, - seed_transpiler=algorithm_globals.random_seed, - shots=1024, - ) - counts_array[idx] = quantum_instance.execute(qc_meas).get_counts() self.assertEqual( counts_array[0], counts_array[1], msg="Counts different with/without fitter." ) @@ -388,19 +412,22 @@ def test_circuit_modified(self): circuit.x(0) circuit.measure_all() - qi = QuantumInstance( - Aer.get_backend("aer_simulator"), - seed_simulator=algorithm_globals.random_seed, - seed_transpiler=algorithm_globals.random_seed, - shots=1024, - measurement_error_mitigation_cls=CompleteMeasFitter, - ) + with self.assertWarns(DeprecationWarning): + qi = QuantumInstance( + Aer.get_backend("aer_simulator"), + seed_simulator=algorithm_globals.random_seed, + seed_transpiler=algorithm_globals.random_seed, + shots=1024, + measurement_error_mitigation_cls=CompleteMeasFitter, + ) # The error happens on transpiled circuits since "execute" was changing the input array # Non transpiled circuits didn't have a problem because a new transpiled array was created # internally. circuits_ref = qi.transpile(circuit) # always returns a new array circuits_input = circuits_ref.copy() - _ = qi.execute(circuits_input, had_transpiled=True) + + with self.assertWarns(DeprecationWarning): + _ = qi.execute(circuits_input, had_transpiled=True) self.assertEqual(circuits_ref, circuits_input, msg="Transpiled circuit array modified.") @unittest.skipUnless(optionals.HAS_AER, "qiskit-aer is required for this test") @@ -422,22 +449,27 @@ def test_tensor_subset_fitter(self): mit_pattern = [[idx] for idx in range(3)] backend = Aer.get_backend("aer_simulator") backend.set_options(seed_simulator=123) - mit_circuits = build_measurement_error_mitigation_circuits( - [0, 1, 2], - TensoredMeasFitter, - backend, - backend_config={}, - compile_config={}, - mit_pattern=mit_pattern, - ) - result = execute(mit_circuits[0], backend, noise_model=noise_model).result() - fitter = TensoredMeasFitter(result, mit_pattern=mit_pattern) + + with self.assertWarns(DeprecationWarning): + mit_circuits = build_measurement_error_mitigation_circuits( + [0, 1, 2], + TensoredMeasFitter, + backend, + backend_config={}, + compile_config={}, + mit_pattern=mit_pattern, + ) + result = execute(mit_circuits[0], backend, noise_model=noise_model).result() + fitter = TensoredMeasFitter(result, mit_pattern=mit_pattern) + cal_matrices = fitter.cal_matrices # Check that permutations and permuted subsets match. for subset in [[1, 0], [1, 2], [0, 2], [2, 0, 1]]: with self.subTest(subset=subset): - new_fitter = fitter.subset_fitter(subset) + with self.assertWarns(DeprecationWarning): + new_fitter = fitter.subset_fitter(subset) + for idx, qubit in enumerate(subset): self.assertTrue(np.allclose(new_fitter.cal_matrices[idx], cal_matrices[qubit])) @@ -458,7 +490,9 @@ def test_tensor_subset_fitter(self): result = execute( circuit, backend, noise_model=noise_model, shots=1000, seed_simulator=0 ).result() - new_result = fitter.subset_fitter([1, 2, 0]).filter.apply(result) + with self.subTest(subset=subset): + with self.assertWarns(DeprecationWarning): + new_result = fitter.subset_fitter([1, 2, 0]).filter.apply(result) # The noisy result should have a poor 111 state, the mit. result should be good. self.assertTrue(result.get_counts()["111"] < 800) diff --git a/test/python/algorithms/test_numpy_eigen_solver.py b/test/python/algorithms/test_numpy_eigen_solver.py index 6b2b41b796a7..36d2b66148d0 100644 --- a/test/python/algorithms/test_numpy_eigen_solver.py +++ b/test/python/algorithms/test_numpy_eigen_solver.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2018, 2021. +# (C) Copyright IBM 2018, 2023. # # 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 @@ -28,21 +28,23 @@ class TestNumPyEigensolver(QiskitAlgorithmsTestCase): def setUp(self): super().setUp() - self.qubit_op = PauliSumOp.from_list( - [ - ("II", -1.052373245772859), - ("ZI", 0.39793742484318045), - ("IZ", -0.39793742484318045), - ("ZZ", -0.01128010425623538), - ("XX", 0.18093119978423156), - ] - ) + with self.assertWarns(DeprecationWarning): + self.qubit_op = PauliSumOp.from_list( + [ + ("II", -1.052373245772859), + ("ZI", 0.39793742484318045), + ("IZ", -0.39793742484318045), + ("ZZ", -0.01128010425623538), + ("XX", 0.18093119978423156), + ] + ) def test_ce(self): """Test basics""" with self.assertWarns(DeprecationWarning): algo = NumPyEigensolver() result = algo.compute_eigenvalues(operator=self.qubit_op, aux_operators=[]) + self.assertEqual(len(result.eigenvalues), 1) self.assertEqual(len(result.eigenstates), 1) self.assertEqual(result.eigenvalues.dtype, np.float64) @@ -53,6 +55,7 @@ def test_ce_k4(self): with self.assertWarns(DeprecationWarning): algo = NumPyEigensolver(k=4) result = algo.compute_eigenvalues(operator=self.qubit_op, aux_operators=[]) + self.assertEqual(len(result.eigenvalues), 4) self.assertEqual(len(result.eigenstates), 4) self.assertEqual(result.eigenvalues.dtype, np.float64) @@ -71,6 +74,7 @@ def criterion(x, v, a_v): with self.assertWarns(DeprecationWarning): algo = NumPyEigensolver(k=4, filter_criterion=criterion) result = algo.compute_eigenvalues(operator=self.qubit_op, aux_operators=[]) + self.assertEqual(len(result.eigenvalues), 2) self.assertEqual(len(result.eigenstates), 2) self.assertEqual(result.eigenvalues.dtype, np.float64) @@ -93,6 +97,7 @@ def criterion(x, v, a_v): @data(X, Y, Z) def test_ce_k1_1q(self, op): """Test for 1 qubit operator""" + with self.assertWarns(DeprecationWarning): algo = NumPyEigensolver(k=1) result = algo.compute_eigenvalues(operator=op) @@ -101,6 +106,7 @@ def test_ce_k1_1q(self, op): @data(X, Y, Z) def test_ce_k2_1q(self, op): """Test for 1 qubit operator""" + with self.assertWarns(DeprecationWarning): algo = NumPyEigensolver(k=2) result = algo.compute_eigenvalues(operator=op) @@ -108,12 +114,16 @@ def test_ce_k2_1q(self, op): def test_aux_operators_list(self): """Test list-based aux_operators.""" - aux_op1 = PauliSumOp.from_list([("II", 2.0)]) - aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5), ("XX", -0.5)]) + + with self.assertWarns(DeprecationWarning): + aux_op1 = PauliSumOp.from_list([("II", 2.0)]) + aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5), ("XX", -0.5)]) aux_ops = [aux_op1, aux_op2] + with self.assertWarns(DeprecationWarning): algo = NumPyEigensolver() result = algo.compute_eigenvalues(operator=self.qubit_op, aux_operators=aux_ops) + self.assertEqual(len(result.eigenvalues), 1) self.assertEqual(len(result.eigenstates), 1) self.assertEqual(result.eigenvalues.dtype, np.float64) @@ -129,8 +139,10 @@ def test_aux_operators_list(self): # Go again with additional None and zero operators extra_ops = [*aux_ops, None, 0] + with self.assertWarns(DeprecationWarning): result = algo.compute_eigenvalues(operator=self.qubit_op, aux_operators=extra_ops) + self.assertEqual(len(result.eigenvalues), 1) self.assertEqual(len(result.eigenstates), 1) self.assertEqual(result.eigenvalues.dtype, np.float64) @@ -149,9 +161,12 @@ def test_aux_operators_list(self): def test_aux_operators_dict(self): """Test dict-based aux_operators.""" - aux_op1 = PauliSumOp.from_list([("II", 2.0)]) - aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5), ("XX", -0.5)]) + + with self.assertWarns(DeprecationWarning): + aux_op1 = PauliSumOp.from_list([("II", 2.0)]) + aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5), ("XX", -0.5)]) aux_ops = {"aux_op1": aux_op1, "aux_op2": aux_op2} + with self.assertWarns(DeprecationWarning): algo = NumPyEigensolver() result = algo.compute_eigenvalues(operator=self.qubit_op, aux_operators=aux_ops) @@ -170,8 +185,10 @@ def test_aux_operators_dict(self): # Go again with additional None and zero operators extra_ops = {**aux_ops, "None_operator": None, "zero_operator": 0} + with self.assertWarns(DeprecationWarning): result = algo.compute_eigenvalues(operator=self.qubit_op, aux_operators=extra_ops) + self.assertEqual(len(result.eigenvalues), 1) self.assertEqual(len(result.eigenstates), 1) self.assertEqual(result.eigenvalues.dtype, np.float64) diff --git a/test/python/algorithms/test_numpy_minimum_eigen_solver.py b/test/python/algorithms/test_numpy_minimum_eigen_solver.py index c4d5a3b43ddd..8f50d5738338 100644 --- a/test/python/algorithms/test_numpy_minimum_eigen_solver.py +++ b/test/python/algorithms/test_numpy_minimum_eigen_solver.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020, 2021. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -28,28 +28,31 @@ class TestNumPyMinimumEigensolver(QiskitAlgorithmsTestCase): def setUp(self): super().setUp() - self.qubit_op = PauliSumOp.from_list( - [ - ("II", -1.052373245772859), - ("ZI", 0.39793742484318045), - ("IZ", -0.39793742484318045), - ("ZZ", -0.01128010425623538), - ("XX", 0.18093119978423156), - ] - ) - - aux_op1 = PauliSumOp.from_list([("II", 2.0)]) - aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5), ("XX", -0.5)]) + with self.assertWarns(DeprecationWarning): + self.qubit_op = PauliSumOp.from_list( + [ + ("II", -1.052373245772859), + ("ZI", 0.39793742484318045), + ("IZ", -0.39793742484318045), + ("ZZ", -0.01128010425623538), + ("XX", 0.18093119978423156), + ] + ) + aux_op1 = PauliSumOp.from_list([("II", 2.0)]) + aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5), ("XX", -0.5)]) + self.aux_ops_list = [aux_op1, aux_op2] self.aux_ops_dict = {"aux_op1": aux_op1, "aux_op2": aux_op2} def test_cme(self): """Basic test""" + with self.assertWarns(DeprecationWarning): algo = NumPyMinimumEigensolver() result = algo.compute_minimum_eigenvalue( operator=self.qubit_op, aux_operators=self.aux_ops_list ) + self.assertAlmostEqual(result.eigenvalue, -1.85727503 + 0j) self.assertEqual(len(result.aux_operator_eigenvalues), 2) np.testing.assert_array_almost_equal(result.aux_operator_eigenvalues[0], [2, 0]) @@ -61,6 +64,7 @@ def test_cme_reuse(self): with self.assertWarns(DeprecationWarning): algo = NumPyMinimumEigensolver() result = algo.compute_minimum_eigenvalue(operator=self.qubit_op) + self.assertEqual(result.eigenvalue.dtype, np.float64) self.assertAlmostEqual(result.eigenvalue, -1.85727503) self.assertIsNone(result.aux_operator_eigenvalues) @@ -70,6 +74,7 @@ def test_cme_reuse(self): result = algo.compute_minimum_eigenvalue( operator=self.qubit_op, aux_operators=self.aux_ops_list ) + self.assertAlmostEqual(result.eigenvalue, -1.85727503 + 0j) self.assertEqual(len(result.aux_operator_eigenvalues), 2) np.testing.assert_array_almost_equal(result.aux_operator_eigenvalues[0], [2, 0]) @@ -78,6 +83,7 @@ def test_cme_reuse(self): # "Remove" aux_operators and go again with self.assertWarns(DeprecationWarning): result = algo.compute_minimum_eigenvalue(operator=self.qubit_op, aux_operators=[]) + self.assertEqual(result.eigenvalue.dtype, np.float64) self.assertAlmostEqual(result.eigenvalue, -1.85727503) self.assertIsNone(result.aux_operator_eigenvalues) @@ -87,16 +93,19 @@ def test_cme_reuse(self): result = algo.compute_minimum_eigenvalue( operator=self.qubit_op, aux_operators=self.aux_ops_list ) + self.assertAlmostEqual(result.eigenvalue, -1.85727503 + 0j) self.assertEqual(len(result.aux_operator_eigenvalues), 2) np.testing.assert_array_almost_equal(result.aux_operator_eigenvalues[0], [2, 0]) np.testing.assert_array_almost_equal(result.aux_operator_eigenvalues[1], [0, 0]) # Finally just set one of aux_operators and main operator, remove aux_operators + with self.assertWarns(DeprecationWarning): result = algo.compute_minimum_eigenvalue( operator=self.aux_ops_list[0], aux_operators=[] ) + self.assertAlmostEqual(result.eigenvalue, 2 + 0j) self.assertIsNone(result.aux_operator_eigenvalues) @@ -113,6 +122,7 @@ def criterion(x, v, a_v): result = algo.compute_minimum_eigenvalue( operator=self.qubit_op, aux_operators=self.aux_ops_list ) + self.assertAlmostEqual(result.eigenvalue, -0.22491125 + 0j) self.assertEqual(len(result.aux_operator_eigenvalues), 2) np.testing.assert_array_almost_equal(result.aux_operator_eigenvalues[0], [2, 0]) @@ -131,6 +141,7 @@ def criterion(x, v, a_v): result = algo.compute_minimum_eigenvalue( operator=self.qubit_op, aux_operators=self.aux_ops_list ) + self.assertEqual(result.eigenvalue, None) self.assertEqual(result.eigenstate, None) self.assertEqual(result.aux_operator_eigenvalues, None) @@ -138,9 +149,11 @@ def criterion(x, v, a_v): @data(X, Y, Z) def test_cme_1q(self, op): """Test for 1 qubit operator""" + with self.assertWarns(DeprecationWarning): algo = NumPyMinimumEigensolver() result = algo.compute_minimum_eigenvalue(operator=op) + self.assertAlmostEqual(result.eigenvalue, -1) def test_cme_aux_ops_dict(self): @@ -149,6 +162,7 @@ def test_cme_aux_ops_dict(self): with self.assertWarns(DeprecationWarning): algo = NumPyMinimumEigensolver() result = algo.compute_minimum_eigenvalue(operator=self.qubit_op, aux_operators={}) + self.assertAlmostEqual(result.eigenvalue, -1.85727503 + 0j) self.assertIsNone(result.aux_operator_eigenvalues) @@ -157,6 +171,7 @@ def test_cme_aux_ops_dict(self): result = algo.compute_minimum_eigenvalue( operator=self.qubit_op, aux_operators=self.aux_ops_dict ) + self.assertAlmostEqual(result.eigenvalue, -1.85727503 + 0j) self.assertEqual(len(result.aux_operator_eigenvalues), 2) np.testing.assert_array_almost_equal(result.aux_operator_eigenvalues["aux_op1"], [2, 0]) @@ -168,6 +183,7 @@ def test_cme_aux_ops_dict(self): result = algo.compute_minimum_eigenvalue( operator=self.qubit_op, aux_operators=extra_ops ) + self.assertAlmostEqual(result.eigenvalue, -1.85727503 + 0j) self.assertEqual(len(result.aux_operator_eigenvalues), 3) np.testing.assert_array_almost_equal(result.aux_operator_eigenvalues["aux_op1"], [2, 0]) @@ -176,12 +192,16 @@ def test_cme_aux_ops_dict(self): def test_aux_operators_list(self): """Test list-based aux_operators.""" - aux_op1 = PauliSumOp.from_list([("II", 2.0)]) - aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5), ("XX", -0.5)]) + + with self.assertWarns(DeprecationWarning): + aux_op1 = PauliSumOp.from_list([("II", 2.0)]) + aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5), ("XX", -0.5)]) aux_ops = [aux_op1, aux_op2] + with self.assertWarns(DeprecationWarning): algo = NumPyMinimumEigensolver() result = algo.compute_minimum_eigenvalue(operator=self.qubit_op, aux_operators=aux_ops) + self.assertAlmostEqual(result.eigenvalue, -1.85727503 + 0j) self.assertEqual(len(result.aux_operator_eigenvalues), 2) # expectation values @@ -193,10 +213,12 @@ def test_aux_operators_list(self): # Go again with additional None and zero operators extra_ops = [*aux_ops, None, 0] + with self.assertWarns(DeprecationWarning): result = algo.compute_minimum_eigenvalue( operator=self.qubit_op, aux_operators=extra_ops ) + self.assertAlmostEqual(result.eigenvalue, -1.85727503 + 0j) self.assertEqual(len(result.aux_operator_eigenvalues), 4) # expectation values @@ -211,12 +233,16 @@ def test_aux_operators_list(self): def test_aux_operators_dict(self): """Test dict-based aux_operators.""" - aux_op1 = PauliSumOp.from_list([("II", 2.0)]) - aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5), ("XX", -0.5)]) + + with self.assertWarns(DeprecationWarning): + aux_op1 = PauliSumOp.from_list([("II", 2.0)]) + aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5), ("XX", -0.5)]) aux_ops = {"aux_op1": aux_op1, "aux_op2": aux_op2} + with self.assertWarns(DeprecationWarning): algo = NumPyMinimumEigensolver() result = algo.compute_minimum_eigenvalue(operator=self.qubit_op, aux_operators=aux_ops) + self.assertAlmostEqual(result.eigenvalue, -1.85727503 + 0j) self.assertEqual(len(result.aux_operator_eigenvalues), 2) # expectation values @@ -228,10 +254,12 @@ def test_aux_operators_dict(self): # Go again with additional None and zero operators extra_ops = {**aux_ops, "None_operator": None, "zero_operator": 0} + with self.assertWarns(DeprecationWarning): result = algo.compute_minimum_eigenvalue( operator=self.qubit_op, aux_operators=extra_ops ) + self.assertAlmostEqual(result.eigenvalue, -1.85727503 + 0j) self.assertEqual(len(result.aux_operator_eigenvalues), 3) # expectation values diff --git a/test/python/algorithms/test_observables_evaluator.py b/test/python/algorithms/test_observables_evaluator.py index 9db5f02b312d..f4df4ba4bdf5 100644 --- a/test/python/algorithms/test_observables_evaluator.py +++ b/test/python/algorithms/test_observables_evaluator.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2022. +# (C) Copyright IBM 2022, 2023. # # 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 @@ -165,8 +165,9 @@ def test_estimate_observables_shots(self): bound_ansatz = ansatz.bind_parameters(parameters) state = bound_ansatz estimator = Estimator(options={"shots": 2048}) - observables = [PauliSumOp.from_list([("ZZ", 2.0)])] - result = estimate_observables(estimator, state, observables, None, self.threshold) + with self.assertWarns(DeprecationWarning): + observables = [PauliSumOp.from_list([("ZZ", 2.0)])] + result = estimate_observables(estimator, state, observables, None, self.threshold) exact_result = self.get_exact_expectation(bound_ansatz, observables) expected_result = [(exact_result[0][0], {"variance": 1.0898, "shots": 2048})] diff --git a/test/python/algorithms/test_phase_estimator.py b/test/python/algorithms/test_phase_estimator.py index 2af6b902a7fc..15a5ef879f1b 100644 --- a/test/python/algorithms/test_phase_estimator.py +++ b/test/python/algorithms/test_phase_estimator.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2018, 2022. +# (C) Copyright IBM 2018, 2023. # # 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 @@ -13,7 +13,6 @@ """Test phase estimation""" import unittest - from test.python.algorithms import QiskitAlgorithmsTestCase from ddt import ddt, data, unpack import numpy as np @@ -35,7 +34,6 @@ Y, Z, I, - T, StateFn, PauliTrotterEvolution, MatrixEvolution, @@ -60,7 +58,10 @@ def hamiltonian_pe( """Run HamiltonianPhaseEstimation and return result with all phases.""" if backend is None: backend = qiskit.BasicAer.get_backend("statevector_simulator") - quantum_instance = qiskit.utils.QuantumInstance(backend=backend, shots=10000) + + with self.assertWarns(DeprecationWarning): + quantum_instance = qiskit.utils.QuantumInstance(backend=backend, shots=10000) + with self.assertWarns(DeprecationWarning): phase_est = HamiltonianPhaseEstimation( num_evaluation_qubits=num_evaluation_qubits, quantum_instance=quantum_instance @@ -76,10 +77,11 @@ def hamiltonian_pe( @data(MatrixEvolution(), PauliTrotterEvolution("suzuki", 4)) def test_pauli_sum_1(self, evolution): """Two eigenvalues from Pauli sum with X, Z""" - hamiltonian = 0.5 * X + Z - state_preparation = StateFn(H.to_circuit()) + with self.assertWarns(DeprecationWarning): + hamiltonian = 0.5 * X + Z + state_preparation = StateFn(H.to_circuit()) + result = self.hamiltonian_pe(hamiltonian, state_preparation, evolution=evolution) - result = self.hamiltonian_pe(hamiltonian, state_preparation, evolution=evolution) phase_dict = result.filter_phases(0.162, as_float=True) phases = list(phase_dict.keys()) phases.sort() @@ -90,10 +92,11 @@ def test_pauli_sum_1(self, evolution): @data(MatrixEvolution(), PauliTrotterEvolution("suzuki", 3)) def test_pauli_sum_2(self, evolution): """Two eigenvalues from Pauli sum with X, Y, Z""" - hamiltonian = 0.5 * X + Y + Z - state_preparation = None + with self.assertWarns(DeprecationWarning): + hamiltonian = 0.5 * X + Y + Z + state_preparation = None + result = self.hamiltonian_pe(hamiltonian, state_preparation, evolution=evolution) - result = self.hamiltonian_pe(hamiltonian, state_preparation, evolution=evolution) phase_dict = result.filter_phases(0.1, as_float=True) phases = list(phase_dict.keys()) phases.sort() @@ -105,15 +108,17 @@ def test_single_pauli_op(self): """Two eigenvalues from Pauli sum with X, Y, Z""" hamiltonian = Z state_preparation = None + with self.assertWarns(DeprecationWarning): + result = self.hamiltonian_pe(hamiltonian, state_preparation, evolution=None) - result = self.hamiltonian_pe(hamiltonian, state_preparation, evolution=None) eigv = result.most_likely_eigenvalue with self.subTest("First eigenvalue"): self.assertAlmostEqual(eigv, 1.0, delta=0.001) - state_preparation = StateFn(X.to_circuit()) + with self.assertWarns(DeprecationWarning): + state_preparation = StateFn(X.to_circuit()) + result = self.hamiltonian_pe(hamiltonian, state_preparation, bound=1.05) - result = self.hamiltonian_pe(hamiltonian, state_preparation, bound=1.05) eigv = result.most_likely_eigenvalue with self.subTest("Second eigenvalue"): self.assertAlmostEqual(eigv, -0.98, delta=0.01) @@ -121,15 +126,16 @@ def test_single_pauli_op(self): @slow_test def test_H2_hamiltonian(self): """Test H2 hamiltonian""" - hamiltonian = ( - (-1.0523732457728587 * (I ^ I)) - + (0.3979374248431802 * (I ^ Z)) - + (-0.3979374248431802 * (Z ^ I)) - + (-0.011280104256235324 * (Z ^ Z)) - + (0.18093119978423147 * (X ^ X)) - ) - state_preparation = StateFn((I ^ H).to_circuit()) - evo = PauliTrotterEvolution(trotter_mode="suzuki", reps=4) + with self.assertWarns(DeprecationWarning): + hamiltonian = ( + (-1.0523732457728587 * (I ^ I)) + + (0.3979374248431802 * (I ^ Z)) + + (-0.3979374248431802 * (Z ^ I)) + + (-0.011280104256235324 * (Z ^ Z)) + + (0.18093119978423147 * (X ^ X)) + ) + state_preparation = StateFn((I ^ H).to_circuit()) + evo = PauliTrotterEvolution(trotter_mode="suzuki", reps=4) result = self.hamiltonian_pe(hamiltonian, state_preparation, evolution=evo) with self.subTest("Most likely eigenvalues"): @@ -145,24 +151,31 @@ def test_H2_hamiltonian(self): def test_matrix_evolution(self): """1Q Hamiltonian with MatrixEvolution""" - hamiltonian = (0.5 * X) + (0.6 * Y) + (0.7 * I) - state_preparation = None - result = self.hamiltonian_pe(hamiltonian, state_preparation, evolution=MatrixEvolution()) + with self.assertWarns(DeprecationWarning): + hamiltonian = (0.5 * X) + (0.6 * Y) + (0.7 * I) + state_preparation = None + result = self.hamiltonian_pe( + hamiltonian, state_preparation, evolution=MatrixEvolution() + ) phase_dict = result.filter_phases(0.2, as_float=True) phases = list(phase_dict.keys()) self.assertAlmostEqual(phases[0], 1.490, delta=0.001) self.assertAlmostEqual(phases[1], -0.090, delta=0.001) def _setup_from_bound(self, evolution, op_class): - hamiltonian = 0.5 * X + Y + Z + with self.assertWarns(DeprecationWarning): + hamiltonian = 0.5 * X + Y + Z state_preparation = None bound = 1.2 * sum(abs(hamiltonian.coeff * coeff) for coeff in hamiltonian.coeffs) if op_class == "MatrixOp": hamiltonian = hamiltonian.to_matrix_op() backend = qiskit.BasicAer.get_backend("statevector_simulator") - qi = qiskit.utils.QuantumInstance(backend=backend, shots=10000) + + with self.assertWarns(DeprecationWarning): + qi = qiskit.utils.QuantumInstance(backend=backend, shots=10000) with self.assertWarns(DeprecationWarning): phase_est = HamiltonianPhaseEstimation(num_evaluation_qubits=6, quantum_instance=qi) + result = phase_est.estimate( hamiltonian=hamiltonian, bound=bound, @@ -173,23 +186,25 @@ def _setup_from_bound(self, evolution, op_class): def test_from_bound(self): """HamiltonianPhaseEstimation with bound""" - for op_class in ("SummedOp", "MatrixOp"): - result = self._setup_from_bound(MatrixEvolution(), op_class) - cutoff = 0.01 - phases = result.filter_phases(cutoff) - with self.subTest(f"test phases has the correct length: {op_class}"): - self.assertEqual(len(phases), 2) - with self.subTest(f"test scaled phases are correct: {op_class}"): - self.assertEqual(list(phases.keys()), [1.5, -1.5]) - phases = result.filter_phases(cutoff, scaled=False) - with self.subTest(f"test unscaled phases are correct: {op_class}"): - self.assertEqual(list(phases.keys()), [0.25, 0.75]) + with self.assertWarns(DeprecationWarning): + for op_class in ("SummedOp", "MatrixOp"): + result = self._setup_from_bound(MatrixEvolution(), op_class) + cutoff = 0.01 + phases = result.filter_phases(cutoff) + with self.subTest(f"test phases has the correct length: {op_class}"): + self.assertEqual(len(phases), 2) + with self.subTest(f"test scaled phases are correct: {op_class}"): + self.assertEqual(list(phases.keys()), [1.5, -1.5]) + phases = result.filter_phases(cutoff, scaled=False) + with self.subTest(f"test unscaled phases are correct: {op_class}"): + self.assertEqual(list(phases.keys()), [0.25, 0.75]) def test_trotter_from_bound(self): """HamiltonianPhaseEstimation with bound and Trotterization""" - result = self._setup_from_bound( - PauliTrotterEvolution(trotter_mode="suzuki", reps=3), op_class="SummedOp" - ) + with self.assertWarns(DeprecationWarning): + result = self._setup_from_bound( + PauliTrotterEvolution(trotter_mode="suzuki", reps=3), op_class="SummedOp" + ) phase_dict = result.filter_phases(0.1) phases = list(phase_dict.keys()) with self.subTest("test phases has the correct length"): @@ -206,24 +221,35 @@ def hamiltonian_pe_sampler( num_evaluation_qubits=6, evolution=None, bound=None, + uses_opflow=True, ): """Run HamiltonianPhaseEstimation and return result with all phases.""" sampler = Sampler() phase_est = HamiltonianPhaseEstimation( num_evaluation_qubits=num_evaluation_qubits, sampler=sampler ) - result = phase_est.estimate( - hamiltonian=hamiltonian, - state_preparation=state_preparation, - evolution=evolution, - bound=bound, - ) + if uses_opflow: + with self.assertWarns(DeprecationWarning): + result = phase_est.estimate( + hamiltonian=hamiltonian, + state_preparation=state_preparation, + evolution=evolution, + bound=bound, + ) + else: + result = phase_est.estimate( + hamiltonian=hamiltonian, + state_preparation=state_preparation, + evolution=evolution, + bound=bound, + ) return result @data(MatrixExponential(), SuzukiTrotter(reps=4)) def test_pauli_sum_1_sampler(self, evolution): """Two eigenvalues from Pauli sum with X, Z""" - hamiltonian = PauliSumOp(SparsePauliOp.from_list([("X", 0.5), ("Z", 1)])) + with self.assertWarns(DeprecationWarning): + hamiltonian = PauliSumOp(SparsePauliOp.from_list([("X", 0.5), ("Z", 1)])) state_preparation = QuantumCircuit(1).compose(HGate()) result = self.hamiltonian_pe_sampler(hamiltonian, state_preparation, evolution=evolution) @@ -237,7 +263,8 @@ def test_pauli_sum_1_sampler(self, evolution): @data(MatrixExponential(), SuzukiTrotter(reps=3)) def test_pauli_sum_2_sampler(self, evolution): """Two eigenvalues from Pauli sum with X, Y, Z""" - hamiltonian = PauliSumOp(SparsePauliOp.from_list([("X", 0.5), ("Z", 1), ("Y", 1)])) + with self.assertWarns(DeprecationWarning): + hamiltonian = PauliSumOp(SparsePauliOp.from_list([("X", 0.5), ("Z", 1), ("Y", 1)])) state_preparation = None result = self.hamiltonian_pe_sampler(hamiltonian, state_preparation, evolution=evolution) @@ -253,14 +280,18 @@ def test_single_pauli_op_sampler(self): hamiltonian = SparsePauliOp(Pauli("Z")) state_preparation = None - result = self.hamiltonian_pe_sampler(hamiltonian, state_preparation, evolution=None) + result = self.hamiltonian_pe_sampler( + hamiltonian, state_preparation, evolution=None, uses_opflow=False + ) eigv = result.most_likely_eigenvalue with self.subTest("First eigenvalue"): self.assertAlmostEqual(eigv, 1.0, delta=0.001) state_preparation = QuantumCircuit(1).compose(XGate()) - result = self.hamiltonian_pe_sampler(hamiltonian, state_preparation, bound=1.05) + result = self.hamiltonian_pe_sampler( + hamiltonian, state_preparation, bound=1.05, uses_opflow=False + ) eigv = result.most_likely_eigenvalue with self.subTest("Second eigenvalue"): self.assertAlmostEqual(eigv, -0.98, delta=0.01) @@ -272,17 +303,19 @@ def test_single_pauli_op_sampler(self): def test_H2_hamiltonian_sampler(self, state_preparation): """Test H2 hamiltonian""" - hamiltonian = PauliSumOp( - SparsePauliOp.from_list( - [ - ("II", -1.0523732457728587), - ("IZ", 0.3979374248431802), - ("ZI", -0.3979374248431802), - ("ZZ", -0.011280104256235324), - ("XX", 0.18093119978423147), - ] + with self.assertWarns(DeprecationWarning): + hamiltonian = PauliSumOp( + SparsePauliOp.from_list( + [ + ("II", -1.0523732457728587), + ("IZ", 0.3979374248431802), + ("ZI", -0.3979374248431802), + ("ZZ", -0.011280104256235324), + ("XX", 0.18093119978423147), + ] + ) ) - ) + evo = SuzukiTrotter(reps=4) result = self.hamiltonian_pe_sampler(hamiltonian, state_preparation, evolution=evo) with self.subTest("Most likely eigenvalues"): @@ -298,7 +331,8 @@ def test_H2_hamiltonian_sampler(self, state_preparation): def test_matrix_evolution_sampler(self): """1Q Hamiltonian with MatrixEvolution""" - hamiltonian = PauliSumOp(SparsePauliOp.from_list([("X", 0.5), ("Y", 0.6), ("I", 0.7)])) + with self.assertWarns(DeprecationWarning): + hamiltonian = PauliSumOp(SparsePauliOp.from_list([("X", 0.5), ("Y", 0.6), ("I", 0.7)])) state_preparation = None result = self.hamiltonian_pe_sampler( hamiltonian, state_preparation, evolution=MatrixExponential() @@ -327,17 +361,21 @@ def one_phase( if backend_type is None: backend_type = "qasm_simulator" backend = qiskit.BasicAer.get_backend(backend_type) - qi = qiskit.utils.QuantumInstance(backend=backend, shots=10000) if phase_estimator is None: phase_estimator = IterativePhaseEstimation with self.assertWarns(DeprecationWarning): + qi = qiskit.utils.QuantumInstance(backend=backend, shots=10000) + + with self.assertWarns(DeprecationWarning): + if phase_estimator == IterativePhaseEstimation: p_est = IterativePhaseEstimation(num_iterations=num_iterations, quantum_instance=qi) elif phase_estimator == PhaseEstimation: p_est = PhaseEstimation(num_evaluation_qubits=6, quantum_instance=qi) else: raise ValueError("Unrecognized phase_estimator") + result = p_est.estimate(unitary=unitary_circuit, state_preparation=state_preparation) phase = result.phase return phase @@ -354,12 +392,13 @@ def one_phase( def test_qpe_Z(self, state_preparation, expected_phase, backend_type, phase_estimator): """eigenproblem Z, |0> and |1>""" unitary_circuit = Z.to_circuit() - phase = self.one_phase( - unitary_circuit, - state_preparation, - backend_type=backend_type, - phase_estimator=phase_estimator, - ) + with self.assertWarns(DeprecationWarning): + phase = self.one_phase( + unitary_circuit, + state_preparation, + backend_type=backend_type, + phase_estimator=phase_estimator, + ) self.assertEqual(phase, expected_phase) @data( @@ -372,7 +411,10 @@ def test_qpe_Z(self, state_preparation, expected_phase, backend_type, phase_esti def test_qpe_X_plus_minus(self, state_preparation, expected_phase, phase_estimator): """eigenproblem X, (|+>, |->)""" unitary_circuit = X.to_circuit() - phase = self.one_phase(unitary_circuit, state_preparation, phase_estimator=phase_estimator) + with self.assertWarns(DeprecationWarning): + phase = self.one_phase( + unitary_circuit, state_preparation, phase_estimator=phase_estimator + ) self.assertEqual(phase, expected_phase) @data( @@ -387,7 +429,10 @@ def test_qpe_RZ(self, state_preparation, expected_phase, phase_estimator): alpha = np.pi / 2 unitary_circuit = QuantumCircuit(1) unitary_circuit.rz(alpha, 0) - phase = self.one_phase(unitary_circuit, state_preparation, phase_estimator=phase_estimator) + with self.assertWarns(DeprecationWarning): + phase = self.one_phase( + unitary_circuit, state_preparation, phase_estimator=phase_estimator + ) self.assertEqual(phase, expected_phase) def test_check_num_iterations(self): @@ -410,7 +455,9 @@ def phase_estimation( """ if backend is None: backend = qiskit.BasicAer.get_backend("statevector_simulator") - qi = qiskit.utils.QuantumInstance(backend=backend, shots=10000) + + with self.assertWarns(DeprecationWarning): + qi = qiskit.utils.QuantumInstance(backend=backend, shots=10000) with self.assertWarns(DeprecationWarning): phase_est = PhaseEstimation( num_evaluation_qubits=num_evaluation_qubits, quantum_instance=qi @@ -422,6 +469,7 @@ def phase_estimation( result = phase_est.estimate( unitary=unitary_circuit, state_preparation=state_preparation ) + return result @data(True, False) @@ -429,12 +477,14 @@ def test_qpe_Zplus(self, construct_circuit): """superposition eigenproblem Z, |+>""" unitary_circuit = Z.to_circuit() state_preparation = H.to_circuit() # prepare |+> - result = self.phase_estimation( - unitary_circuit, - state_preparation, - backend=qiskit.BasicAer.get_backend("statevector_simulator"), - construct_circuit=construct_circuit, - ) + + with self.assertWarns(DeprecationWarning): + result = self.phase_estimation( + unitary_circuit, + state_preparation, + backend=qiskit.BasicAer.get_backend("statevector_simulator"), + construct_circuit=construct_circuit, + ) phases = result.filter_phases(1e-15, as_float=True) with self.subTest("test phases has correct values"): @@ -541,7 +591,9 @@ def test_qpe_RZ_sampler(self, state_preparation, expected_phase, phase_estimator @unpack def test_qpe_two_qubit_unitary(self, state_preparation, expected_phase, phase_estimator): """two qubit unitary T ^ T""" - unitary_circuit = (T ^ T).to_circuit() + unitary_circuit = QuantumCircuit(2) + unitary_circuit.t(0) + unitary_circuit.t(1) phase = self.one_phase_sampler( unitary_circuit, state_preparation, diff --git a/test/python/algorithms/test_qaoa.py b/test/python/algorithms/test_qaoa.py index 15dcc61ad753..7c743af7e263 100644 --- a/test/python/algorithms/test_qaoa.py +++ b/test/python/algorithms/test_qaoa.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2018, 2021. +# (C) Copyright IBM 2018, 2023. # # 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 @@ -63,17 +63,18 @@ def setUp(self): self.seed = 10598 algorithm_globals.random_seed = self.seed - self.qasm_simulator = QuantumInstance( - BasicAer.get_backend("qasm_simulator"), - shots=4096, - seed_simulator=self.seed, - seed_transpiler=self.seed, - ) - self.statevector_simulator = QuantumInstance( - BasicAer.get_backend("statevector_simulator"), - seed_simulator=self.seed, - seed_transpiler=self.seed, - ) + with self.assertWarns(DeprecationWarning): + self.qasm_simulator = QuantumInstance( + BasicAer.get_backend("qasm_simulator"), + shots=4096, + seed_simulator=self.seed, + seed_transpiler=self.seed, + ) + self.statevector_simulator = QuantumInstance( + BasicAer.get_backend("statevector_simulator"), + seed_simulator=self.seed, + seed_transpiler=self.seed, + ) @idata( [ @@ -89,13 +90,15 @@ def test_qaoa(self, w, prob, m, solutions, convert_to_matrix_op): self.log.debug("Testing %s-step QAOA with MaxCut on graph\n%s", prob, w) qubit_op, _ = self._get_operator(w) + if convert_to_matrix_op: - qubit_op = qubit_op.to_matrix_op() + with self.assertWarns(DeprecationWarning): + qubit_op = qubit_op.to_matrix_op() with self.assertWarns(DeprecationWarning): qaoa = QAOA(COBYLA(), prob, mixer=m, quantum_instance=self.statevector_simulator) - result = qaoa.compute_minimum_eigenvalue(operator=qubit_op) + x = self._sample_most_likely(result.eigenstate) graph_solution = self._get_graph_solution(x) self.assertIn(graph_solution, solutions) @@ -120,7 +123,8 @@ def test_qaoa_qc_mixer(self, w, prob, solutions, convert_to_matrix_op): optimizer = COBYLA() qubit_op, _ = self._get_operator(w) if convert_to_matrix_op: - qubit_op = qubit_op.to_matrix_op() + with self.assertWarns(DeprecationWarning): + qubit_op = qubit_op.to_matrix_op() num_qubits = qubit_op.num_qubits mixer = QuantumCircuit(num_qubits) @@ -131,6 +135,7 @@ def test_qaoa_qc_mixer(self, w, prob, solutions, convert_to_matrix_op): qaoa = QAOA(optimizer, prob, mixer=mixer, quantum_instance=self.statevector_simulator) result = qaoa.compute_minimum_eigenvalue(operator=qubit_op) + x = self._sample_most_likely(result.eigenstate) graph_solution = self._get_graph_solution(x) self.assertIn(graph_solution, solutions) @@ -149,6 +154,7 @@ def test_qaoa_qc_mixer_many_parameters(self): with self.assertWarns(DeprecationWarning): qaoa = QAOA(optimizer, reps=2, mixer=mixer, quantum_instance=self.statevector_simulator) result = qaoa.compute_minimum_eigenvalue(operator=qubit_op) + x = self._sample_most_likely(result.eigenstate) self.log.debug(x) graph_solution = self._get_graph_solution(x) @@ -166,6 +172,7 @@ def test_qaoa_qc_mixer_no_parameters(self): with self.assertWarns(DeprecationWarning): qaoa = QAOA(COBYLA(), reps=1, mixer=mixer, quantum_instance=self.statevector_simulator) result = qaoa.compute_minimum_eigenvalue(operator=qubit_op) + # we just assert that we get a result, it is not meaningful. self.assertIsNotNone(result.eigenstate) @@ -177,6 +184,7 @@ def test_change_operator_size(self): with self.assertWarns(DeprecationWarning): qaoa = QAOA(COBYLA(), 1, quantum_instance=self.statevector_simulator) result = qaoa.compute_minimum_eigenvalue(operator=qubit_op) + x = self._sample_most_likely(result.eigenstate) graph_solution = self._get_graph_solution(x) with self.subTest(msg="QAOA 4x4"): @@ -194,9 +202,9 @@ def test_change_operator_size(self): ] ) ) - with self.assertWarns(DeprecationWarning): result = qaoa.compute_minimum_eigenvalue(operator=qubit_op) + x = self._sample_most_likely(result.eigenstate) graph_solution = self._get_graph_solution(x) with self.subTest(msg="QAOA 6x6"): @@ -224,6 +232,7 @@ def cb_callback(eval_count, parameters, mean, std): ) result = qaoa.compute_minimum_eigenvalue(operator=qubit_op) + x = self._sample_most_likely(result.eigenstate) graph_solution = self._get_graph_solution(x) @@ -253,6 +262,7 @@ def test_qaoa_initial_state(self, w, init_state): initial_state.initialize(init_state, initial_state.qubits) zero_init_state = QuantumCircuit(QuantumRegister(qubit_op.num_qubits, "q")) + with self.assertWarns(DeprecationWarning): qaoa_zero_init_state = QAOA( optimizer=optimizer, @@ -266,9 +276,8 @@ def test_qaoa_initial_state(self, w, init_state): initial_point=init_pt, quantum_instance=self.statevector_simulator, ) - - zero_circuits = qaoa_zero_init_state.construct_circuit(init_pt, qubit_op) - custom_circuits = qaoa.construct_circuit(init_pt, qubit_op) + zero_circuits = qaoa_zero_init_state.construct_circuit(init_pt, qubit_op) + custom_circuits = qaoa.construct_circuit(init_pt, qubit_op) self.assertEqual(len(zero_circuits), len(custom_circuits)) @@ -289,11 +298,12 @@ def test_qaoa_initial_state(self, w, init_state): else: original_init_qc = initial_state - job_init_state = self.statevector_simulator.execute(original_init_qc) - job_qaoa_init_state = self.statevector_simulator.execute(custom_init_qc) + with self.assertWarns(DeprecationWarning): + job_init_state = self.statevector_simulator.execute(original_init_qc) + job_qaoa_init_state = self.statevector_simulator.execute(custom_init_qc) - statevector_original = job_init_state.get_statevector(original_init_qc) - statevector_custom = job_qaoa_init_state.get_statevector(custom_init_qc) + statevector_original = job_init_state.get_statevector(original_init_qc) + statevector_custom = job_qaoa_init_state.get_statevector(custom_init_qc) self.assertListEqual(statevector_original.tolist(), statevector_custom.tolist()) @@ -303,6 +313,7 @@ def test_qaoa_random_initial_point(self): rx.undirected_gnp_random_graph(5, 0.5, seed=algorithm_globals.random_seed) ) qubit_op, _ = self._get_operator(w) + with self.assertWarns(DeprecationWarning): qaoa = QAOA( optimizer=NELDER_MEAD(disp=True), reps=1, quantum_instance=self.qasm_simulator @@ -315,13 +326,13 @@ def test_qaoa_construct_circuit_update(self): """Test updating operators with QAOA construct_circuit""" with self.assertWarns(DeprecationWarning): qaoa = QAOA() - ref = qaoa.construct_circuit([0, 0], I ^ Z)[0] - circ2 = qaoa.construct_circuit([0, 0], I ^ Z)[0] - self.assertEqual(circ2, ref) - circ3 = qaoa.construct_circuit([0, 0], Z ^ I)[0] - self.assertNotEqual(circ3, ref) - circ4 = qaoa.construct_circuit([0, 0], I ^ Z)[0] - self.assertEqual(circ4, ref) + ref = qaoa.construct_circuit([0, 0], I ^ Z)[0] + circ2 = qaoa.construct_circuit([0, 0], I ^ Z)[0] + self.assertEqual(circ2, ref) + circ3 = qaoa.construct_circuit([0, 0], Z ^ I)[0] + self.assertNotEqual(circ3, ref) + circ4 = qaoa.construct_circuit([0, 0], I ^ Z)[0] + self.assertEqual(circ4, ref) def test_optimizer_scipy_callable(self): """Test passing a SciPy optimizer directly as callable.""" @@ -357,7 +368,9 @@ def _get_operator(self, weight_matrix): pauli_list.append([0.5 * weight_matrix[i, j], Pauli((z_p, x_p))]) shift -= 0.5 * weight_matrix[i, j] opflow_list = [(pauli[1].to_label(), pauli[0]) for pauli in pauli_list] - return PauliSumOp.from_list(opflow_list), shift + + with self.assertWarns(DeprecationWarning): + return PauliSumOp.from_list(opflow_list), shift def _get_graph_solution(self, x: np.ndarray) -> str: """Get graph solution from binary string. diff --git a/test/python/algorithms/test_skip_qobj_validation.py b/test/python/algorithms/test_skip_qobj_validation.py index f3ef8827e26f..0474d6cff794 100644 --- a/test/python/algorithms/test_skip_qobj_validation.py +++ b/test/python/algorithms/test_skip_qobj_validation.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2019, 2020. +# (C) Copyright IBM 2019, 2023. # # 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 @@ -13,7 +13,6 @@ """Test Skip Qobj Validation""" import unittest - from test.python.algorithms import QiskitAlgorithmsTestCase from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister from qiskit import BasicAer @@ -63,18 +62,20 @@ def setUp(self): def test_wo_backend_options(self): """without backend options test""" - quantum_instance = QuantumInstance( - self.backend, - seed_transpiler=self.random_seed, - seed_simulator=self.random_seed, - shots=1024, - ) - # run without backend_options and without noise - res_wo_bo = quantum_instance.execute(self.qc).get_counts(self.qc) - self.assertGreaterEqual(quantum_instance.time_taken, 0.0) - quantum_instance.reset_execution_results() - quantum_instance.skip_qobj_validation = True - res_wo_bo_skip_validation = quantum_instance.execute(self.qc).get_counts(self.qc) + with self.assertWarns(DeprecationWarning): + quantum_instance = QuantumInstance( + self.backend, + seed_transpiler=self.random_seed, + seed_simulator=self.random_seed, + shots=1024, + ) + # run without backend_options and without noise + res_wo_bo = quantum_instance.execute(self.qc).get_counts(self.qc) + self.assertGreaterEqual(quantum_instance.time_taken, 0.0) + quantum_instance.reset_execution_results() + quantum_instance.skip_qobj_validation = True + res_wo_bo_skip_validation = quantum_instance.execute(self.qc).get_counts(self.qc) + self.assertGreaterEqual(quantum_instance.time_taken, 0.0) quantum_instance.reset_execution_results() self.assertTrue(_compare_dict(res_wo_bo, res_wo_bo_skip_validation)) @@ -82,18 +83,20 @@ def test_wo_backend_options(self): def test_w_backend_options(self): """with backend options test""" # run with backend_options - quantum_instance = QuantumInstance( - self.backend, - seed_transpiler=self.random_seed, - seed_simulator=self.random_seed, - shots=1024, - backend_options={"initial_statevector": [0.5, 0.5, 0.5, 0.5]}, - ) - res_w_bo = quantum_instance.execute(self.qc).get_counts(self.qc) - self.assertGreaterEqual(quantum_instance.time_taken, 0.0) - quantum_instance.reset_execution_results() - quantum_instance.skip_qobj_validation = True - res_w_bo_skip_validation = quantum_instance.execute(self.qc).get_counts(self.qc) + with self.assertWarns(DeprecationWarning): + quantum_instance = QuantumInstance( + self.backend, + seed_transpiler=self.random_seed, + seed_simulator=self.random_seed, + shots=1024, + backend_options={"initial_statevector": [0.5, 0.5, 0.5, 0.5]}, + ) + res_w_bo = quantum_instance.execute(self.qc).get_counts(self.qc) + self.assertGreaterEqual(quantum_instance.time_taken, 0.0) + quantum_instance.reset_execution_results() + quantum_instance.skip_qobj_validation = True + res_w_bo_skip_validation = quantum_instance.execute(self.qc).get_counts(self.qc) + self.assertGreaterEqual(quantum_instance.time_taken, 0.0) quantum_instance.reset_execution_results() self.assertTrue(_compare_dict(res_w_bo, res_w_bo_skip_validation)) @@ -116,26 +119,28 @@ def test_w_noise(self): noise_model = NoiseModel() noise_model.add_readout_error([probs_given0, probs_given1], [0]) - quantum_instance = QuantumInstance( - self.backend, - seed_transpiler=self.random_seed, - seed_simulator=self.random_seed, - shots=1024, - noise_model=noise_model, - ) - res_w_noise = quantum_instance.execute(self.qc).get_counts(self.qc) - - quantum_instance.skip_qobj_validation = True - res_w_noise_skip_validation = quantum_instance.execute(self.qc).get_counts(self.qc) + with self.assertWarns(DeprecationWarning): + quantum_instance = QuantumInstance( + self.backend, + seed_transpiler=self.random_seed, + seed_simulator=self.random_seed, + shots=1024, + noise_model=noise_model, + ) + res_w_noise = quantum_instance.execute(self.qc).get_counts(self.qc) + quantum_instance.skip_qobj_validation = True + res_w_noise_skip_validation = quantum_instance.execute(self.qc).get_counts(self.qc) + self.assertTrue(_compare_dict(res_w_noise, res_w_noise_skip_validation)) - # BasicAer should fail: - with self.assertRaises(QiskitError): - _ = QuantumInstance(BasicAer.get_backend("qasm_simulator"), noise_model=noise_model) + with self.assertWarns(DeprecationWarning): + # BasicAer should fail: + with self.assertRaises(QiskitError): + _ = QuantumInstance(BasicAer.get_backend("qasm_simulator"), noise_model=noise_model) - with self.assertRaises(QiskitError): - quantum_instance = QuantumInstance(BasicAer.get_backend("qasm_simulator")) - quantum_instance.set_config(noise_model=noise_model) + with self.assertRaises(QiskitError): + quantum_instance = QuantumInstance(BasicAer.get_backend("qasm_simulator")) + quantum_instance.set_config(noise_model=noise_model) if __name__ == "__main__": diff --git a/test/python/algorithms/test_vqd.py b/test/python/algorithms/test_vqd.py index 8079a063ddf6..10ac4010cdbf 100644 --- a/test/python/algorithms/test_vqd.py +++ b/test/python/algorithms/test_vqd.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2018, 2021. +# (C) Copyright IBM 2018, 2023. # # 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 @@ -55,17 +55,9 @@ def setUp(self): super().setUp() self.seed = 50 algorithm_globals.random_seed = self.seed - self.h2_op = ( - -1.052373245772859 * (I ^ I) - + 0.39793742484318045 * (I ^ Z) - - 0.39793742484318045 * (Z ^ I) - - 0.01128010425623538 * (Z ^ Z) - + 0.18093119978423156 * (X ^ X) - ) self.h2_energy = -1.85727503 self.h2_energy_excited = [-1.85727503, -1.24458455] - self.test_op = MatrixOp(np.diagflat([3, 5, -1, 0.8, 0.2, 2, 1, -3])).to_pauli_op() self.test_results = [-3, -1] self.ryrz_wavefunction = TwoLocal( @@ -73,23 +65,33 @@ def setUp(self): ) self.ry_wavefunction = TwoLocal(rotation_blocks="ry", entanglement_blocks="cz") - self.qasm_simulator = QuantumInstance( - BasicAer.get_backend("qasm_simulator"), - shots=2048, - seed_simulator=self.seed, - seed_transpiler=self.seed, - ) - self.statevector_simulator = QuantumInstance( - BasicAer.get_backend("statevector_simulator"), - shots=1, - seed_simulator=self.seed, - seed_transpiler=self.seed, - ) + with self.assertWarns(DeprecationWarning): + self.h2_op = ( + -1.052373245772859 * (I ^ I) + + 0.39793742484318045 * (I ^ Z) + - 0.39793742484318045 * (Z ^ I) + - 0.01128010425623538 * (Z ^ Z) + + 0.18093119978423156 * (X ^ X) + ) + self.test_op = MatrixOp(np.diagflat([3, 5, -1, 0.8, 0.2, 2, 1, -3])).to_pauli_op() + self.qasm_simulator = QuantumInstance( + BasicAer.get_backend("qasm_simulator"), + shots=2048, + seed_simulator=self.seed, + seed_transpiler=self.seed, + ) + self.statevector_simulator = QuantumInstance( + BasicAer.get_backend("statevector_simulator"), + shots=1, + seed_simulator=self.seed, + seed_transpiler=self.seed, + ) @slow_test def test_basic_aer_statevector(self): """Test the VQD on BasicAer's statevector simulator.""" wavefunction = self.ryrz_wavefunction + with self.assertWarns(DeprecationWarning): vqd = VQD( k=2, @@ -124,6 +126,7 @@ def test_mismatching_num_qubits(self): """Ensuring circuit and operator mismatch is caught""" wavefunction = QuantumCircuit(1) optimizer = SLSQP(maxiter=50) + with self.assertWarns(DeprecationWarning): vqd = VQD( k=1, @@ -144,20 +147,23 @@ def test_construct_circuit(self, expectation, num_circuits): """Test construct circuits returns QuantumCircuits and the right number of them.""" try: wavefunction = EfficientSU2(2, reps=1) + with self.assertWarns(DeprecationWarning): vqd = VQD(k=2, ansatz=wavefunction, expectation=expectation) - params = [0] * wavefunction.num_parameters - circuits = vqd.construct_circuit(parameter=params, operator=self.h2_op) - + params = [0] * wavefunction.num_parameters + circuits = vqd.construct_circuit(parameter=params, operator=self.h2_op) self.assertEqual(len(circuits), num_circuits) + for circuit in circuits: self.assertIsInstance(circuit, QuantumCircuit) + except MissingOptionalLibraryError as ex: self.skipTest(str(ex)) return def test_missing_varform_params(self): """Test specifying a variational form with no parameters raises an error.""" + circuit = QuantumCircuit(self.h2_op.num_qubits) with self.assertWarns(DeprecationWarning): vqd = VQD( @@ -178,9 +184,9 @@ def test_basic_aer_qasm(self): max_evals_grouped=1, quantum_instance=self.qasm_simulator, ) - # TODO benchmark this later. result = vqd.compute_eigenvalues(operator=self.h2_op) + np.testing.assert_array_almost_equal( result.eigenvalues.real, self.h2_energy_excited, decimal=1 ) @@ -192,11 +198,12 @@ def test_with_aer_statevector(self): wavefunction = self.ry_wavefunction optimizer = L_BFGS_B() - quantum_instance = QuantumInstance( - backend, - seed_simulator=algorithm_globals.random_seed, - seed_transpiler=algorithm_globals.random_seed, - ) + with self.assertWarns(DeprecationWarning): + quantum_instance = QuantumInstance( + backend, + seed_simulator=algorithm_globals.random_seed, + seed_transpiler=algorithm_globals.random_seed, + ) with self.assertWarns(DeprecationWarning): vqd = VQD( k=2, @@ -218,11 +225,12 @@ def test_with_aer_qasm(self): optimizer = COBYLA(maxiter=1000) wavefunction = self.ry_wavefunction - quantum_instance = QuantumInstance( - backend, - seed_simulator=algorithm_globals.random_seed, - seed_transpiler=algorithm_globals.random_seed, - ) + with self.assertWarns(DeprecationWarning): + quantum_instance = QuantumInstance( + backend, + seed_simulator=algorithm_globals.random_seed, + seed_transpiler=algorithm_globals.random_seed, + ) with self.assertWarns(DeprecationWarning): vqd = VQD( @@ -246,12 +254,13 @@ def test_with_aer_qasm_snapshot_mode(self): optimizer = COBYLA(maxiter=400) wavefunction = self.ryrz_wavefunction - quantum_instance = QuantumInstance( - backend, - shots=100, - seed_simulator=algorithm_globals.random_seed, - seed_transpiler=algorithm_globals.random_seed, - ) + with self.assertWarns(DeprecationWarning): + quantum_instance = QuantumInstance( + backend, + shots=100, + seed_simulator=algorithm_globals.random_seed, + seed_transpiler=algorithm_globals.random_seed, + ) with self.assertWarns(DeprecationWarning): vqd = VQD( k=2, @@ -260,8 +269,8 @@ def test_with_aer_qasm_snapshot_mode(self): expectation=AerPauliExpectation(), quantum_instance=quantum_instance, ) - result = vqd.compute_eigenvalues(operator=self.test_op) + np.testing.assert_array_almost_equal(result.eigenvalues.real, self.test_results, decimal=1) def test_callback(self): @@ -306,26 +315,34 @@ def store_intermediate_result(eval_count, parameters, mean, std, step): def test_reuse(self): """Test re-using a VQD algorithm instance.""" + with self.assertWarns(DeprecationWarning): vqd = VQD(k=1) + with self.subTest(msg="assert running empty raises AlgorithmError"): with self.assertWarns(DeprecationWarning), self.assertRaises(AlgorithmError): _ = vqd.compute_eigenvalues(operator=self.h2_op) ansatz = TwoLocal(rotation_blocks=["ry", "rz"], entanglement_blocks="cz") vqd.ansatz = ansatz + with self.subTest(msg="assert missing operator raises AlgorithmError"): with self.assertWarns(DeprecationWarning), self.assertRaises(AlgorithmError): _ = vqd.compute_eigenvalues(operator=self.h2_op) - vqd.expectation = MatrixExpectation() - vqd.quantum_instance = self.statevector_simulator + with self.assertWarns(DeprecationWarning): + vqd.expectation = MatrixExpectation() + vqd.quantum_instance = self.statevector_simulator + with self.subTest(msg="assert VQE works once all info is available"): with self.assertWarns(DeprecationWarning): result = vqd.compute_eigenvalues(operator=self.h2_op) np.testing.assert_array_almost_equal(result.eigenvalues.real, self.h2_energy, decimal=2) - operator = PrimitiveOp(np.array([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, 2, 0], [0, 0, 0, 3]])) + with self.assertWarns(DeprecationWarning): + operator = PrimitiveOp( + np.array([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, 2, 0], [0, 0, 0, 3]]) + ) with self.subTest(msg="assert minimum eigensolver interface works"): with self.assertWarns(DeprecationWarning): @@ -344,6 +361,7 @@ def test_vqd_optimizer(self): def run_check(): with self.assertWarns(DeprecationWarning): result = vqd.compute_eigenvalues(operator=self.h2_op) + np.testing.assert_array_almost_equal( result.eigenvalues.real, self.h2_energy_excited, decimal=3 ) @@ -360,6 +378,7 @@ def run_check(): @data(MatrixExpectation(), None) def test_backend_change(self, user_expectation): """Test that VQE works when backend changes.""" + with self.assertWarns(DeprecationWarning): vqd = VQD( k=1, @@ -368,24 +387,23 @@ def test_backend_change(self, user_expectation): expectation=user_expectation, quantum_instance=BasicAer.get_backend("statevector_simulator"), ) - with self.assertWarns(DeprecationWarning): result0 = vqd.compute_eigenvalues(operator=self.h2_op) - if user_expectation is not None: - with self.subTest("User expectation kept."): - self.assertEqual(vqd.expectation, user_expectation) + if user_expectation is not None: + with self.subTest("User expectation kept."): + self.assertEqual(vqd.expectation, user_expectation) - vqd.quantum_instance = BasicAer.get_backend("qasm_simulator") - - # works also if no expectation is set, since it will be determined automatically with self.assertWarns(DeprecationWarning): + vqd.quantum_instance = BasicAer.get_backend("qasm_simulator") + # works also if no expectation is set, since it will be determined automatically + result1 = vqd.compute_eigenvalues(operator=self.h2_op) - if user_expectation is not None: - with self.subTest("Change backend with user expectation, it is kept."): - self.assertEqual(vqd.expectation, user_expectation) + if user_expectation is not None: + with self.subTest("Change backend with user expectation, it is kept."): + self.assertEqual(vqd.expectation, user_expectation) - with self.subTest("Check results."): - self.assertEqual(len(result0.optimal_point), len(result1.optimal_point)) + with self.subTest("Check results."): + self.assertEqual(len(result0.optimal_point), len(result1.optimal_point)) def test_set_ansatz_to_none(self): """Tests that setting the ansatz to None results in the default behavior""" @@ -401,6 +419,7 @@ def test_set_ansatz_to_none(self): def test_set_optimizer_to_none(self): """Tests that setting the optimizer to None results in the default behavior""" + with self.assertWarns(DeprecationWarning): vqd = VQD( k=1, @@ -414,23 +433,25 @@ def test_set_optimizer_to_none(self): def test_aux_operators_list(self): """Test list-based aux_operators.""" wavefunction = self.ry_wavefunction + with self.assertWarns(DeprecationWarning): vqd = VQD(k=2, ansatz=wavefunction, quantum_instance=self.statevector_simulator) - # Start with an empty list - with self.assertWarns(DeprecationWarning): + # Start with an empty list result = vqd.compute_eigenvalues(self.h2_op, aux_operators=[]) + np.testing.assert_array_almost_equal( result.eigenvalues.real, self.h2_energy_excited, decimal=2 ) self.assertIsNone(result.aux_operator_eigenvalues) # Go again with two auxiliary operators - aux_op1 = PauliSumOp.from_list([("II", 2.0)]) - aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5), ("XX", -0.5)]) - aux_ops = [aux_op1, aux_op2] with self.assertWarns(DeprecationWarning): + aux_op1 = PauliSumOp.from_list([("II", 2.0)]) + aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5), ("XX", -0.5)]) + aux_ops = [aux_op1, aux_op2] result = vqd.compute_eigenvalues(self.h2_op, aux_operators=aux_ops) + np.testing.assert_array_almost_equal( result.eigenvalues.real, self.h2_energy_excited, decimal=2 ) @@ -446,6 +467,7 @@ def test_aux_operators_list(self): extra_ops = [*aux_ops, None, 0] with self.assertWarns(DeprecationWarning): result = vqd.compute_eigenvalues(self.h2_op, aux_operators=extra_ops) + np.testing.assert_array_almost_equal( result.eigenvalues.real, self.h2_energy_excited, decimal=2 ) @@ -463,23 +485,27 @@ def test_aux_operators_list(self): def test_aux_operators_dict(self): """Test dictionary compatibility of aux_operators""" wavefunction = self.ry_wavefunction + with self.assertWarns(DeprecationWarning): vqd = VQD(ansatz=wavefunction, quantum_instance=self.statevector_simulator) # Start with an empty dictionary with self.assertWarns(DeprecationWarning): result = vqd.compute_eigenvalues(self.h2_op, aux_operators={}) + np.testing.assert_array_almost_equal( result.eigenvalues.real, self.h2_energy_excited, decimal=2 ) self.assertIsNone(result.aux_operator_eigenvalues) # Go again with two auxiliary operators - aux_op1 = PauliSumOp.from_list([("II", 2.0)]) - aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5), ("XX", -0.5)]) - aux_ops = {"aux_op1": aux_op1, "aux_op2": aux_op2} + with self.assertWarns(DeprecationWarning): + aux_op1 = PauliSumOp.from_list([("II", 2.0)]) + aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5), ("XX", -0.5)]) + aux_ops = {"aux_op1": aux_op1, "aux_op2": aux_op2} with self.assertWarns(DeprecationWarning): result = vqd.compute_eigenvalues(self.h2_op, aux_operators=aux_ops) + self.assertEqual(len(result.eigenvalues), 2) self.assertEqual(len(result.eigenstates), 2) self.assertEqual(result.eigenvalues.dtype, np.complex128) @@ -516,6 +542,7 @@ def test_aux_operators_dict(self): def test_aux_operator_std_dev_pauli(self): """Test non-zero standard deviations of aux operators with PauliExpectation.""" wavefunction = self.ry_wavefunction + with self.assertWarns(DeprecationWarning): vqd = VQD( ansatz=wavefunction, @@ -534,12 +561,14 @@ def test_aux_operator_std_dev_pauli(self): quantum_instance=self.qasm_simulator, ) - # Go again with two auxiliary operators - aux_op1 = PauliSumOp.from_list([("II", 2.0)]) - aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5), ("XX", -0.5)]) - aux_ops = [aux_op1, aux_op2] + with self.assertWarns(DeprecationWarning): + # Go again with two auxiliary operators + aux_op1 = PauliSumOp.from_list([("II", 2.0)]) + aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5), ("XX", -0.5)]) + aux_ops = [aux_op1, aux_op2] with self.assertWarns(DeprecationWarning): result = vqd.compute_eigenvalues(self.h2_op, aux_operators=aux_ops) + self.assertEqual(len(result.aux_operator_eigenvalues), 2) # expectation values self.assertAlmostEqual(result.aux_operator_eigenvalues[0][0][0], 2.0, places=1) @@ -556,6 +585,7 @@ def test_aux_operator_std_dev_pauli(self): aux_ops = [*aux_ops, None, 0] with self.assertWarns(DeprecationWarning): result = vqd.compute_eigenvalues(self.h2_op, aux_operators=aux_ops) + self.assertEqual(len(result.aux_operator_eigenvalues[0]), 4) # expectation values self.assertAlmostEqual(result.aux_operator_eigenvalues[0][0][0], 2.0, places=1) @@ -589,10 +619,11 @@ def test_aux_operator_std_dev_aer_pauli(self): ), ) - # Go again with two auxiliary operators - aux_op1 = PauliSumOp.from_list([("II", 2.0)]) - aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5), ("XX", -0.5)]) - aux_ops = [aux_op1, aux_op2] + with self.assertWarns(DeprecationWarning): + # Go again with two auxiliary operators + aux_op1 = PauliSumOp.from_list([("II", 2.0)]) + aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5), ("XX", -0.5)]) + aux_ops = [aux_op1, aux_op2] with self.assertWarns(DeprecationWarning): result = vqd.compute_eigenvalues(self.h2_op, aux_operators=aux_ops) self.assertEqual(len(result.aux_operator_eigenvalues), 2) diff --git a/test/python/algorithms/test_vqe.py b/test/python/algorithms/test_vqe.py index c0711e408b7c..c9fee9547d19 100644 --- a/test/python/algorithms/test_vqe.py +++ b/test/python/algorithms/test_vqe.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2018, 2021. +# (C) Copyright IBM 2018, 2023. # # 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 @@ -52,10 +52,7 @@ from qiskit.quantum_info import Statevector from qiskit.transpiler import PassManager, PassManagerConfig from qiskit.transpiler.preset_passmanagers import level_1_pass_manager -from qiskit.utils import QuantumInstance, algorithm_globals, has_aer - -if has_aer(): - from qiskit import Aer +from qiskit.utils import QuantumInstance, algorithm_globals, optionals logger = "LocalLogger" @@ -89,30 +86,31 @@ def setUp(self): super().setUp() self.seed = 50 algorithm_globals.random_seed = self.seed - self.h2_op = ( - -1.052373245772859 * (I ^ I) - + 0.39793742484318045 * (I ^ Z) - - 0.39793742484318045 * (Z ^ I) - - 0.01128010425623538 * (Z ^ Z) - + 0.18093119978423156 * (X ^ X) - ) self.h2_energy = -1.85727503 self.ryrz_wavefunction = TwoLocal(rotation_blocks=["ry", "rz"], entanglement_blocks="cz") self.ry_wavefunction = TwoLocal(rotation_blocks="ry", entanglement_blocks="cz") - self.qasm_simulator = QuantumInstance( - BasicAer.get_backend("qasm_simulator"), - shots=1024, - seed_simulator=self.seed, - seed_transpiler=self.seed, - ) - self.statevector_simulator = QuantumInstance( - BasicAer.get_backend("statevector_simulator"), - shots=1, - seed_simulator=self.seed, - seed_transpiler=self.seed, - ) + with self.assertWarns(DeprecationWarning): + self.h2_op = ( + -1.052373245772859 * (I ^ I) + + 0.39793742484318045 * (I ^ Z) + - 0.39793742484318045 * (Z ^ I) + - 0.01128010425623538 * (Z ^ Z) + + 0.18093119978423156 * (X ^ X) + ) + self.qasm_simulator = QuantumInstance( + BasicAer.get_backend("qasm_simulator"), + shots=1024, + seed_simulator=self.seed, + seed_transpiler=self.seed, + ) + self.statevector_simulator = QuantumInstance( + BasicAer.get_backend("statevector_simulator"), + shots=1, + seed_simulator=self.seed, + seed_transpiler=self.seed, + ) def test_basic_aer_statevector(self): """Test the VQE on BasicAer's statevector simulator.""" @@ -147,6 +145,7 @@ def test_circuit_input(self): """Test running the VQE on a plain QuantumCircuit object.""" wavefunction = QuantumCircuit(2).compose(EfficientSU2(2)) optimizer = SLSQP(maxiter=50) + with self.assertWarns(DeprecationWarning): vqe = VQE( ansatz=wavefunction, @@ -154,6 +153,7 @@ def test_circuit_input(self): quantum_instance=self.statevector_simulator, ) result = vqe.compute_minimum_eigenvalue(operator=self.h2_op) + self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=5) @data( @@ -166,10 +166,11 @@ def test_construct_circuit(self, expectation, num_circuits): """Test construct circuits returns QuantumCircuits and the right number of them.""" try: wavefunction = EfficientSU2(2, reps=1) + with self.assertWarns(DeprecationWarning): vqe = VQE(ansatz=wavefunction, expectation=expectation) - params = [0] * wavefunction.num_parameters - circuits = vqe.construct_circuit(parameter=params, operator=self.h2_op) + params = [0] * wavefunction.num_parameters + circuits = vqe.construct_circuit(parameter=params, operator=self.h2_op) self.assertEqual(len(circuits), num_circuits) for circuit in circuits: @@ -181,6 +182,7 @@ def test_construct_circuit(self, expectation, num_circuits): def test_missing_varform_params(self): """Test specifying a variational form with no parameters raises an error.""" circuit = QuantumCircuit(self.h2_op.num_qubits) + with self.assertWarns(DeprecationWarning): vqe = VQE( ansatz=circuit, quantum_instance=BasicAer.get_backend("statevector_simulator") @@ -203,6 +205,7 @@ def test_max_evals_grouped(self, optimizer, places, max_evals_grouped): quantum_instance=self.statevector_simulator, ) result = vqe.compute_minimum_eigenvalue(operator=self.h2_op) + self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=places) def test_basic_aer_qasm(self): @@ -217,9 +220,8 @@ def test_basic_aer_qasm(self): max_evals_grouped=1, quantum_instance=self.qasm_simulator, ) - - # TODO benchmark this later. result = vqe.compute_minimum_eigenvalue(operator=self.h2_op) + self.assertAlmostEqual(result.eigenvalue.real, -1.86823, places=2) def test_qasm_eigenvector_normalized(self): @@ -232,18 +234,22 @@ def test_qasm_eigenvector_normalized(self): amplitudes = list(result.eigenstate.values()) self.assertAlmostEqual(np.linalg.norm(amplitudes), 1.0, places=4) - @unittest.skipUnless(has_aer(), "qiskit-aer doesn't appear to be installed.") + @unittest.skipUnless(optionals.HAS_AER, "Qiskit aer is required to run these tests") def test_with_aer_statevector(self): """Test VQE with Aer's statevector_simulator.""" - backend = Aer.get_backend("aer_simulator_statevector") + from qiskit_aer import AerSimulator + + backend = AerSimulator(method="statevector") wavefunction = self.ry_wavefunction optimizer = L_BFGS_B() - quantum_instance = QuantumInstance( - backend, - seed_simulator=algorithm_globals.random_seed, - seed_transpiler=algorithm_globals.random_seed, - ) + with self.assertWarns(DeprecationWarning): + quantum_instance = QuantumInstance( + backend, + seed_simulator=algorithm_globals.random_seed, + seed_transpiler=algorithm_globals.random_seed, + ) + with self.assertWarns(DeprecationWarning): vqe = VQE( ansatz=wavefunction, @@ -251,22 +257,25 @@ def test_with_aer_statevector(self): max_evals_grouped=1, quantum_instance=quantum_instance, ) - result = vqe.compute_minimum_eigenvalue(operator=self.h2_op) + self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=6) - @unittest.skipUnless(has_aer(), "qiskit-aer doesn't appear to be installed.") + @unittest.skipUnless(optionals.HAS_AER, "Qiskit aer is required to run these tests") def test_with_aer_qasm(self): """Test VQE with Aer's qasm_simulator.""" - backend = Aer.get_backend("aer_simulator") + from qiskit_aer import AerSimulator + + backend = AerSimulator() optimizer = SPSA(maxiter=200, last_avg=5) wavefunction = self.ry_wavefunction - quantum_instance = QuantumInstance( - backend, - seed_simulator=algorithm_globals.random_seed, - seed_transpiler=algorithm_globals.random_seed, - ) + with self.assertWarns(DeprecationWarning): + quantum_instance = QuantumInstance( + backend, + seed_simulator=algorithm_globals.random_seed, + seed_transpiler=algorithm_globals.random_seed, + ) with self.assertWarns(DeprecationWarning): vqe = VQE( @@ -275,25 +284,27 @@ def test_with_aer_qasm(self): expectation=PauliExpectation(), quantum_instance=quantum_instance, ) - result = vqe.compute_minimum_eigenvalue(operator=self.h2_op) self.assertAlmostEqual(result.eigenvalue.real, -1.86305, places=2) - @unittest.skipUnless(has_aer(), "qiskit-aer doesn't appear to be installed.") + @unittest.skipUnless(optionals.HAS_AER, "Qiskit aer is required to run these tests") def test_with_aer_qasm_snapshot_mode(self): """Test the VQE using Aer's qasm_simulator snapshot mode.""" + from qiskit_aer import AerSimulator - backend = Aer.get_backend("aer_simulator") + backend = AerSimulator() optimizer = L_BFGS_B() wavefunction = self.ry_wavefunction - quantum_instance = QuantumInstance( - backend, - shots=1, - seed_simulator=algorithm_globals.random_seed, - seed_transpiler=algorithm_globals.random_seed, - ) + with self.assertWarns(DeprecationWarning): + quantum_instance = QuantumInstance( + backend, + shots=1, + seed_simulator=algorithm_globals.random_seed, + seed_transpiler=algorithm_globals.random_seed, + ) + with self.assertWarns(DeprecationWarning): vqe = VQE( ansatz=wavefunction, @@ -301,11 +312,11 @@ def test_with_aer_qasm_snapshot_mode(self): expectation=AerPauliExpectation(), quantum_instance=quantum_instance, ) - result = vqe.compute_minimum_eigenvalue(operator=self.h2_op) + self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=6) - @unittest.skipUnless(has_aer(), "qiskit-aer doesn't appear to be installed.") + @unittest.skipUnless(optionals.HAS_AER, "Qiskit aer is required to run these tests") @data( CG(maxiter=1), L_BFGS_B(maxfun=1), @@ -315,12 +326,15 @@ def test_with_aer_qasm_snapshot_mode(self): ) def test_with_gradient(self, optimizer): """Test VQE using Gradient().""" - quantum_instance = QuantumInstance( - backend=Aer.get_backend("qasm_simulator"), - shots=1, - seed_simulator=algorithm_globals.random_seed, - seed_transpiler=algorithm_globals.random_seed, - ) + from qiskit_aer import AerSimulator + + with self.assertWarns(DeprecationWarning): + quantum_instance = QuantumInstance( + backend=AerSimulator(), + shots=1, + seed_simulator=algorithm_globals.random_seed, + seed_transpiler=algorithm_globals.random_seed, + ) with self.assertWarns(DeprecationWarning): vqe = VQE( ansatz=self.ry_wavefunction, @@ -334,26 +348,29 @@ def test_with_gradient(self, optimizer): def test_with_two_qubit_reduction(self): """Test the VQE using TwoQubitReduction.""" - qubit_op = PauliSumOp.from_list( - [ - ("IIII", -0.8105479805373266), - ("IIIZ", 0.17218393261915552), - ("IIZZ", -0.22575349222402472), - ("IZZI", 0.1721839326191556), - ("ZZII", -0.22575349222402466), - ("IIZI", 0.1209126326177663), - ("IZZZ", 0.16892753870087912), - ("IXZX", -0.045232799946057854), - ("ZXIX", 0.045232799946057854), - ("IXIX", 0.045232799946057854), - ("ZXZX", -0.045232799946057854), - ("ZZIZ", 0.16614543256382414), - ("IZIZ", 0.16614543256382414), - ("ZZZZ", 0.17464343068300453), - ("ZIZI", 0.1209126326177663), - ] - ) - tapered_qubit_op = TwoQubitReduction(num_particles=2).convert(qubit_op) + + with self.assertWarns(DeprecationWarning): + qubit_op = PauliSumOp.from_list( + [ + ("IIII", -0.8105479805373266), + ("IIIZ", 0.17218393261915552), + ("IIZZ", -0.22575349222402472), + ("IZZI", 0.1721839326191556), + ("ZZII", -0.22575349222402466), + ("IIZI", 0.1209126326177663), + ("IZZZ", 0.16892753870087912), + ("IXZX", -0.045232799946057854), + ("ZXIX", 0.045232799946057854), + ("IXIX", 0.045232799946057854), + ("ZXZX", -0.045232799946057854), + ("ZZIZ", 0.16614543256382414), + ("IZIZ", 0.16614543256382414), + ("ZZZZ", 0.17464343068300453), + ("ZIZI", 0.1209126326177663), + ] + ) + tapered_qubit_op = TwoQubitReduction(num_particles=2).convert(qubit_op) + for simulator in [self.qasm_simulator, self.statevector_simulator]: with self.subTest(f"Test for {simulator}."), self.assertWarns(DeprecationWarning): vqe = VQE( @@ -395,6 +412,7 @@ def store_intermediate_result(eval_count, parameters, mean, std): def test_reuse(self): """Test re-using a VQE algorithm instance.""" + with self.assertWarns(DeprecationWarning): vqe = VQE() with self.subTest(msg="assert running empty raises AlgorithmError"): @@ -407,15 +425,20 @@ def test_reuse(self): with self.assertWarns(DeprecationWarning), self.assertRaises(AlgorithmError): _ = vqe.compute_minimum_eigenvalue(operator=self.h2_op) - vqe.expectation = MatrixExpectation() - vqe.quantum_instance = self.statevector_simulator + with self.assertWarns(DeprecationWarning): + vqe.expectation = MatrixExpectation() + vqe.quantum_instance = self.statevector_simulator + with self.subTest(msg="assert VQE works once all info is available"), self.assertWarns( DeprecationWarning ): result = vqe.compute_minimum_eigenvalue(operator=self.h2_op) self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=5) - operator = PrimitiveOp(np.array([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, 2, 0], [0, 0, 0, 3]])) + with self.assertWarns(DeprecationWarning): + operator = PrimitiveOp( + np.array([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, 2, 0], [0, 0, 0, 3]]) + ) with self.subTest(msg="assert minimum eigensolver interface works"), self.assertWarns( DeprecationWarning @@ -434,6 +457,7 @@ def test_vqe_optimizer(self): def run_check(): with self.assertWarns(DeprecationWarning): result = vqe.compute_minimum_eigenvalue(operator=self.h2_op) + self.assertAlmostEqual(result.eigenvalue.real, -1.85727503, places=5) run_check() @@ -448,6 +472,7 @@ def run_check(): @data(MatrixExpectation(), None) def test_backend_change(self, user_expectation): """Test that VQE works when backend changes.""" + with self.assertWarns(DeprecationWarning): vqe = VQE( ansatz=TwoLocal(rotation_blocks=["ry", "rz"], entanglement_blocks="cz"), @@ -456,14 +481,14 @@ def test_backend_change(self, user_expectation): quantum_instance=BasicAer.get_backend("statevector_simulator"), ) result0 = vqe.compute_minimum_eigenvalue(operator=self.h2_op) + if user_expectation is not None: with self.subTest("User expectation kept."): self.assertEqual(vqe.expectation, user_expectation) - vqe.quantum_instance = BasicAer.get_backend("qasm_simulator") - # works also if no expectation is set, since it will be determined automatically with self.assertWarns(DeprecationWarning): + vqe.quantum_instance = BasicAer.get_backend("qasm_simulator") result1 = vqe.compute_minimum_eigenvalue(operator=self.h2_op) if user_expectation is not None: @@ -509,34 +534,40 @@ def wrapped_run(circuits, **kwargs): def test_set_ansatz_to_none(self): """Tests that setting the ansatz to None results in the default behavior""" + with self.assertWarns(DeprecationWarning): vqe = VQE( ansatz=self.ryrz_wavefunction, optimizer=L_BFGS_B(), quantum_instance=self.statevector_simulator, ) + vqe.ansatz = None self.assertIsInstance(vqe.ansatz, RealAmplitudes) def test_set_optimizer_to_none(self): """Tests that setting the optimizer to None results in the default behavior""" + with self.assertWarns(DeprecationWarning): vqe = VQE( ansatz=self.ryrz_wavefunction, optimizer=L_BFGS_B(), quantum_instance=self.statevector_simulator, ) + vqe.optimizer = None self.assertIsInstance(vqe.optimizer, SLSQP) def test_optimizer_scipy_callable(self): """Test passing a SciPy optimizer directly as callable.""" + with self.assertWarns(DeprecationWarning): vqe = VQE( optimizer=partial(scipy_minimize, method="L-BFGS-B", options={"maxiter": 2}), quantum_instance=self.statevector_simulator, ) result = vqe.compute_minimum_eigenvalue(Z) + self.assertEqual(result.cost_function_evals, 20) def test_optimizer_callable(self): @@ -554,20 +585,26 @@ def test_optimizer_callable(self): def test_aux_operators_list(self): """Test list-based aux_operators.""" wavefunction = self.ry_wavefunction + + # Start with an empty list with self.assertWarns(DeprecationWarning): vqe = VQE(ansatz=wavefunction, quantum_instance=self.statevector_simulator) # Start with an empty list result = vqe.compute_minimum_eigenvalue(self.h2_op, aux_operators=[]) + self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=6) self.assertIsNone(result.aux_operator_eigenvalues) # Go again with two auxiliary operators - aux_op1 = PauliSumOp.from_list([("II", 2.0)]) - aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5), ("XX", -0.5)]) - aux_ops = [aux_op1, aux_op2] + with self.assertWarns(DeprecationWarning): + aux_op1 = PauliSumOp.from_list([("II", 2.0)]) + aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5), ("XX", -0.5)]) + aux_ops = [aux_op1, aux_op2] + with self.assertWarns(DeprecationWarning): result = vqe.compute_minimum_eigenvalue(self.h2_op, aux_operators=aux_ops) + self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=6) self.assertEqual(len(result.aux_operator_eigenvalues), 2) # expectation values @@ -581,6 +618,7 @@ def test_aux_operators_list(self): extra_ops = [*aux_ops, None, 0] with self.assertWarns(DeprecationWarning): result = vqe.compute_minimum_eigenvalue(self.h2_op, aux_operators=extra_ops) + self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=6) self.assertEqual(len(result.aux_operator_eigenvalues), 4) # expectation values @@ -597,21 +635,26 @@ def test_aux_operators_list(self): def test_aux_operators_dict(self): """Test dictionary compatibility of aux_operators""" wavefunction = self.ry_wavefunction + with self.assertWarns(DeprecationWarning): vqe = VQE(ansatz=wavefunction, quantum_instance=self.statevector_simulator) # Start with an empty dictionary with self.assertWarns(DeprecationWarning): result = vqe.compute_minimum_eigenvalue(self.h2_op, aux_operators={}) + self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=6) self.assertIsNone(result.aux_operator_eigenvalues) # Go again with two auxiliary operators - aux_op1 = PauliSumOp.from_list([("II", 2.0)]) - aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5), ("XX", -0.5)]) - aux_ops = {"aux_op1": aux_op1, "aux_op2": aux_op2} + with self.assertWarns(DeprecationWarning): + aux_op1 = PauliSumOp.from_list([("II", 2.0)]) + aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5), ("XX", -0.5)]) + aux_ops = {"aux_op1": aux_op1, "aux_op2": aux_op2} + with self.assertWarns(DeprecationWarning): result = vqe.compute_minimum_eigenvalue(self.h2_op, aux_operators=aux_ops) + self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=6) self.assertEqual(len(result.aux_operator_eigenvalues), 2) # expectation values @@ -625,6 +668,7 @@ def test_aux_operators_dict(self): extra_ops = {**aux_ops, "None_operator": None, "zero_operator": 0} with self.assertWarns(DeprecationWarning): result = vqe.compute_minimum_eigenvalue(self.h2_op, aux_operators=extra_ops) + self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=6) self.assertEqual(len(result.aux_operator_eigenvalues), 3) # expectation values @@ -648,12 +692,15 @@ def test_aux_operator_std_dev_pauli(self): quantum_instance=self.qasm_simulator, ) - # Go again with two auxiliary operators - aux_op1 = PauliSumOp.from_list([("II", 2.0)]) - aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5), ("XX", -0.5)]) - aux_ops = [aux_op1, aux_op2] + with self.assertWarns(DeprecationWarning): + # Go again with two auxiliary operators + aux_op1 = PauliSumOp.from_list([("II", 2.0)]) + aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5), ("XX", -0.5)]) + aux_ops = [aux_op1, aux_op2] + with self.assertWarns(DeprecationWarning): result = vqe.compute_minimum_eigenvalue(self.h2_op, aux_operators=aux_ops) + self.assertEqual(len(result.aux_operator_eigenvalues), 2) # expectation values self.assertAlmostEqual(result.aux_operator_eigenvalues[0][0], 2.0, places=6) @@ -664,8 +711,10 @@ def test_aux_operator_std_dev_pauli(self): # Go again with additional None and zero operators aux_ops = [*aux_ops, None, 0] + with self.assertWarns(DeprecationWarning): result = vqe.compute_minimum_eigenvalue(self.h2_op, aux_operators=aux_ops) + self.assertEqual(len(result.aux_operator_eigenvalues), 4) # expectation values self.assertAlmostEqual(result.aux_operator_eigenvalues[0][0], 2.0, places=6) @@ -680,9 +729,11 @@ def test_aux_operator_std_dev_pauli(self): self.assertAlmostEqual(result.aux_operator_eigenvalues[2][1], 0.0) self.assertAlmostEqual(result.aux_operator_eigenvalues[3][1], 0.0) - @unittest.skipUnless(has_aer(), "qiskit-aer doesn't appear to be installed.") + @unittest.skipUnless(optionals.HAS_AER, "Qiskit aer is required to run these tests") def test_aux_operator_std_dev_aer_pauli(self): """Test non-zero standard deviations of aux operators with AerPauliExpectation.""" + from qiskit_aer import AerSimulator + wavefunction = self.ry_wavefunction with self.assertWarns(DeprecationWarning): vqe = VQE( @@ -690,19 +741,21 @@ def test_aux_operator_std_dev_aer_pauli(self): expectation=AerPauliExpectation(), optimizer=COBYLA(maxiter=0), quantum_instance=QuantumInstance( - backend=Aer.get_backend("qasm_simulator"), + backend=AerSimulator(), shots=1, seed_simulator=algorithm_globals.random_seed, seed_transpiler=algorithm_globals.random_seed, ), ) + with self.assertWarns(DeprecationWarning): + # Go again with two auxiliary operators + aux_op1 = PauliSumOp.from_list([("II", 2.0)]) + aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5), ("XX", -0.5)]) + aux_ops = [aux_op1, aux_op2] - # Go again with two auxiliary operators - aux_op1 = PauliSumOp.from_list([("II", 2.0)]) - aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5), ("XX", -0.5)]) - aux_ops = [aux_op1, aux_op2] with self.assertWarns(DeprecationWarning): result = vqe.compute_minimum_eigenvalue(self.h2_op, aux_operators=aux_ops) + self.assertEqual(len(result.aux_operator_eigenvalues), 2) # expectation values self.assertAlmostEqual(result.aux_operator_eigenvalues[0][0], 2.0, places=6) @@ -715,6 +768,7 @@ def test_aux_operator_std_dev_aer_pauli(self): aux_ops = [*aux_ops, None, 0] with self.assertWarns(DeprecationWarning): result = vqe.compute_minimum_eigenvalue(self.h2_op, aux_operators=aux_ops) + self.assertEqual(len(result.aux_operator_eigenvalues), 4) # expectation values self.assertAlmostEqual(result.aux_operator_eigenvalues[0][0], 2.0, places=6) @@ -739,21 +793,20 @@ def test_2step_transpile(self): bound_counter = LogPass("bound_pass_manager") bound_pass = PassManager(bound_counter) - quantum_instance = QuantumInstance( - backend=BasicAer.get_backend("statevector_simulator"), - basis_gates=["u3", "cx"], - pass_manager=pre_pass, - bound_pass_manager=bound_pass, - ) - optimizer = SPSA(maxiter=5, learning_rate=0.01, perturbation=0.01) with self.assertWarns(DeprecationWarning): - vqe = VQE(optimizer=optimizer, quantum_instance=quantum_instance) - _ = vqe.compute_minimum_eigenvalue(Z) + quantum_instance = QuantumInstance( + backend=BasicAer.get_backend("statevector_simulator"), + basis_gates=["u3", "cx"], + pass_manager=pre_pass, + bound_pass_manager=bound_pass, + ) - with self.assertLogs(logger, level="INFO") as cm, self.assertWarns(DeprecationWarning): - _ = vqe.compute_minimum_eigenvalue(Z) + with self.assertWarns(DeprecationWarning): + vqe = VQE(optimizer=optimizer, quantum_instance=quantum_instance) + with self.assertLogs(logger, level="INFO") as cm: + _ = vqe.compute_minimum_eigenvalue(Z) expected = [ "pre_passmanager", @@ -777,11 +830,16 @@ def test_construct_eigenstate_from_optpoint(self): """Test constructing the eigenstate from the optimal point, if the default ansatz is used.""" # use Hamiltonian yielding more than 11 parameters in the default ansatz - hamiltonian = Z ^ Z ^ Z + with self.assertWarns(DeprecationWarning): + hamiltonian = Z ^ Z ^ Z + optimizer = SPSA(maxiter=1, learning_rate=0.01, perturbation=0.01) - quantum_instance = QuantumInstance( - backend=BasicAer.get_backend("statevector_simulator"), basis_gates=["u3", "cx"] - ) + + with self.assertWarns(DeprecationWarning): + quantum_instance = QuantumInstance( + backend=BasicAer.get_backend("statevector_simulator"), basis_gates=["u3", "cx"] + ) + with self.assertWarns(DeprecationWarning): vqe = VQE(optimizer=optimizer, quantum_instance=quantum_instance) result = vqe.compute_minimum_eigenvalue(hamiltonian) diff --git a/test/python/algorithms/time_evolvers/classical_methods/test_scipy_imaginary_evolver.py b/test/python/algorithms/time_evolvers/classical_methods/test_scipy_imaginary_evolver.py index 52e26d559623..5671bf221284 100644 --- a/test/python/algorithms/time_evolvers/classical_methods/test_scipy_imaginary_evolver.py +++ b/test/python/algorithms/time_evolvers/classical_methods/test_scipy_imaginary_evolver.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2022. +# (C) Copyright IBM 2022, 2023. # # 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 @@ -123,13 +123,14 @@ def test_quantum_circuit_initial_state(self): def test_paulisumop_hamiltonian(self): """Tests if the hamiltonian can be a PauliSumOp""" - hamiltonian = PauliSumOp.from_list( - [ - ("XI", 1), - ("IX", 1), - ] - ) - observable = PauliSumOp.from_list([("ZZ", 1)]) + with self.assertWarns(DeprecationWarning): + hamiltonian = PauliSumOp.from_list( + [ + ("XI", 1), + ("IX", 1), + ] + ) + observable = PauliSumOp.from_list([("ZZ", 1)]) evolution_problem = TimeEvolutionProblem( hamiltonian=hamiltonian, time=1.0, diff --git a/test/python/algorithms/time_evolvers/test_pvqd.py b/test/python/algorithms/time_evolvers/test_pvqd.py index 55c7c0f45ba7..f0e3b3ae4471 100644 --- a/test/python/algorithms/time_evolvers/test_pvqd.py +++ b/test/python/algorithms/time_evolvers/test_pvqd.py @@ -12,6 +12,7 @@ """Tests for PVQD.""" import unittest +from test.python.algorithms import QiskitAlgorithmsTestCase from functools import partial import numpy as np @@ -53,7 +54,7 @@ def inverse(self): @ddt -class TestPVQD(QiskitTestCase): +class TestPVQD(QiskitAlgorithmsTestCase): """Tests for the pVQD algorithm.""" def setUp(self): @@ -73,7 +74,8 @@ def test_pvqd(self, hamiltonian_type, gradient, num_timesteps): if hamiltonian_type == "ising": hamiltonian = self.hamiltonian elif hamiltonian_type == "pauli_sum_op": - hamiltonian = PauliSumOp(self.hamiltonian) + with self.assertWarns(DeprecationWarning): + hamiltonian = PauliSumOp(self.hamiltonian) else: # hamiltonian_type == "pauli": hamiltonian = Pauli("XX") diff --git a/test/python/algorithms/time_evolvers/test_time_evolution_problem.py b/test/python/algorithms/time_evolvers/test_time_evolution_problem.py index 8cc0134c2cdb..1982fb203749 100644 --- a/test/python/algorithms/time_evolvers/test_time_evolution_problem.py +++ b/test/python/algorithms/time_evolvers/test_time_evolution_problem.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2022. +# (C) Copyright IBM 2022, 2023. # # 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 @@ -52,7 +52,8 @@ def test_init_default(self): def test_init_all(self, initial_state): """Tests that all fields are initialized correctly.""" t_parameter = Parameter("t") - hamiltonian = t_parameter * Z + Y + with self.assertWarns(DeprecationWarning): + hamiltonian = t_parameter * Z + Y time = 2 aux_operators = [X, Y] param_value_dict = {t_parameter: 3.2} @@ -66,14 +67,16 @@ def test_init_all(self, initial_state): param_value_map=param_value_dict, ) - expected_hamiltonian = Y + t_parameter * Z + with self.assertWarns(DeprecationWarning): + expected_hamiltonian = Y + t_parameter * Z expected_time = 2 expected_type = QuantumCircuit expected_aux_operators = [X, Y] expected_t_param = t_parameter expected_param_value_dict = {t_parameter: 3.2} - self.assertEqual(evo_problem.hamiltonian, expected_hamiltonian) + with self.assertWarns(DeprecationWarning): + self.assertEqual(evo_problem.hamiltonian, expected_hamiltonian) self.assertEqual(evo_problem.time, expected_time) self.assertEqual(type(evo_problem.initial_state), expected_type) self.assertEqual(evo_problem.aux_operators, expected_aux_operators) @@ -84,7 +87,8 @@ def test_validate_params(self): """Tests expected errors are thrown on parameters mismatch.""" param_x = Parameter("x") with self.subTest(msg="Parameter missing in dict."): - hamiltonian = PauliSumOp(SparsePauliOp([Pauli("X"), Pauli("Y")]), param_x) + with self.assertWarns(DeprecationWarning): + hamiltonian = PauliSumOp(SparsePauliOp([Pauli("X"), Pauli("Y")]), param_x) evolution_problem = TimeEvolutionProblem(hamiltonian, 2, Zero) with assert_raises(ValueError): evolution_problem.validate_params() diff --git a/test/python/algorithms/time_evolvers/test_trotter_qrte.py b/test/python/algorithms/time_evolvers/test_trotter_qrte.py index e5d07a972c75..c784d2e31363 100644 --- a/test/python/algorithms/time_evolvers/test_trotter_qrte.py +++ b/test/python/algorithms/time_evolvers/test_trotter_qrte.py @@ -52,7 +52,8 @@ def setUp(self): @unpack def test_trotter_qrte_trotter_single_qubit(self, product_formula, expected_state): """Test for default TrotterQRTE on a single qubit.""" - operator = PauliSumOp(SparsePauliOp([Pauli("X"), Pauli("Z")])) + with self.assertWarns(DeprecationWarning): + operator = PauliSumOp(SparsePauliOp([Pauli("X"), Pauli("Z")])) initial_state = QuantumCircuit(1) time = 1 evolution_problem = TimeEvolutionProblem(operator, time, initial_state) @@ -168,7 +169,8 @@ def test_trotter_qrte_trotter_two_qubits(self, operator, expected_state): @unpack def test_trotter_qrte_qdrift(self, initial_state, expected_state): """Test for TrotterQRTE with QDrift.""" - operator = PauliSumOp(SparsePauliOp([Pauli("X"), Pauli("Z")])) + with self.assertWarns(DeprecationWarning): + operator = PauliSumOp(SparsePauliOp([Pauli("X"), Pauli("Z")])) time = 1 evolution_problem = TimeEvolutionProblem(operator, time, initial_state) @@ -177,16 +179,18 @@ def test_trotter_qrte_qdrift(self, initial_state, expected_state): evolution_result = trotter_qrte.evolve(evolution_problem) np.testing.assert_array_almost_equal( - Statevector.from_instruction(evolution_result.evolved_state).data, expected_state.data + Statevector.from_instruction(evolution_result.evolved_state).data, + expected_state.data, ) @data((Parameter("t"), {}), (None, {Parameter("x"): 2}), (None, None)) @unpack def test_trotter_qrte_trotter_param_errors(self, t_param, param_value_dict): """Test TrotterQRTE with raising errors for parameters.""" - operator = Parameter("t") * PauliSumOp(SparsePauliOp([Pauli("X")])) + PauliSumOp( - SparsePauliOp([Pauli("Z")]) - ) + with self.assertWarns(DeprecationWarning): + operator = Parameter("t") * PauliSumOp(SparsePauliOp([Pauli("X")])) + PauliSumOp( + SparsePauliOp([Pauli("Z")]) + ) initial_state = QuantumCircuit(1) self._run_error_test(initial_state, operator, None, None, t_param, param_value_dict) @@ -194,7 +198,10 @@ def test_trotter_qrte_trotter_param_errors(self, t_param, param_value_dict): @unpack def test_trotter_qrte_trotter_aux_ops_errors(self, aux_ops, estimator): """Test TrotterQRTE with raising errors.""" - operator = PauliSumOp(SparsePauliOp([Pauli("X")])) + PauliSumOp(SparsePauliOp([Pauli("Z")])) + with self.assertWarns(DeprecationWarning): + operator = PauliSumOp(SparsePauliOp([Pauli("X")])) + PauliSumOp( + SparsePauliOp([Pauli("Z")]) + ) initial_state = QuantumCircuit(1) self._run_error_test(initial_state, operator, aux_ops, estimator, None, None) diff --git a/test/python/circuit/library/test_evolution_gate.py b/test/python/circuit/library/test_evolution_gate.py index 92926a077986..f6e625f2c0ce 100644 --- a/test/python/circuit/library/test_evolution_gate.py +++ b/test/python/circuit/library/test_evolution_gate.py @@ -38,7 +38,8 @@ def setUp(self): def test_matrix_decomposition(self): """Test the default decomposition.""" - op = (X ^ 3) + (Y ^ 3) + (Z ^ 3) + with self.assertWarns(DeprecationWarning): + op = (X ^ 3) + (Y ^ 3) + (Z ^ 3) time = 0.123 matrix = op.to_matrix() @@ -50,7 +51,8 @@ def test_matrix_decomposition(self): def test_lie_trotter(self): """Test constructing the circuit with Lie Trotter decomposition.""" - op = (X ^ 3) + (Y ^ 3) + (Z ^ 3) + with self.assertWarns(DeprecationWarning): + op = (X ^ 3) + (Y ^ 3) + (Z ^ 3) time = 0.123 reps = 4 evo_gate = PauliEvolutionGate(op, time, synthesis=LieTrotter(reps=reps)) @@ -59,29 +61,32 @@ def test_lie_trotter(self): def test_rzx_order(self): """Test ZX and XZ is mapped onto the correct qubits.""" - for op, indices in zip([X ^ Z, Z ^ X], [(0, 1), (1, 0)]): - with self.subTest(op=op, indices=indices): - evo_gate = PauliEvolutionGate(op) - decomposed = evo_gate.definition.decompose() - - # ┌───┐┌───────┐┌───┐ - # q_0: ─────┤ X ├┤ Rz(2) ├┤ X ├───── - # ┌───┐└─┬─┘└───────┘└─┬─┘┌───┐ - # q_1: ┤ H ├──■─────────────■──┤ H ├ - # └───┘ └───┘ - ref = QuantumCircuit(2) - ref.h(indices[1]) - ref.cx(indices[1], indices[0]) - ref.rz(2.0, indices[0]) - ref.cx(indices[1], indices[0]) - ref.h(indices[1]) - - # don't use circuit equality since RZX here decomposes with RZ on the bottom - self.assertTrue(Operator(decomposed).equiv(ref)) + with self.assertWarns(DeprecationWarning): + op = (X ^ 3) + (Y ^ 3) + (Z ^ 3) + for op, indices in zip([X ^ Z, Z ^ X], [(0, 1), (1, 0)]): + with self.subTest(op=op, indices=indices): + evo_gate = PauliEvolutionGate(op) + decomposed = evo_gate.definition.decompose() + + # ┌───┐┌───────┐┌───┐ + # q_0: ─────┤ X ├┤ Rz(2) ├┤ X ├───── + # ┌───┐└─┬─┘└───────┘└─┬─┘┌───┐ + # q_1: ┤ H ├──■─────────────■──┤ H ├ + # └───┘ └───┘ + ref = QuantumCircuit(2) + ref.h(indices[1]) + ref.cx(indices[1], indices[0]) + ref.rz(2.0, indices[0]) + ref.cx(indices[1], indices[0]) + ref.h(indices[1]) + + # don't use circuit equality since RZX here decomposes with RZ on the bottom + self.assertTrue(Operator(decomposed).equiv(ref)) def test_suzuki_trotter(self): """Test constructing the circuit with Lie Trotter decomposition.""" - op = (X ^ 3) + (Y ^ 3) + (Z ^ 3) + with self.assertWarns(DeprecationWarning): + op = (X ^ 3) + (Y ^ 3) + (Z ^ 3) time = 0.123 reps = 4 for order in [2, 4, 6]: @@ -103,7 +108,8 @@ def test_suzuki_trotter(self): def test_suzuki_trotter_manual(self): """Test the evolution circuit of Suzuki Trotter against a manually constructed circuit.""" - op = X + Y + with self.assertWarns(DeprecationWarning): + op = X + Y time = 0.1 reps = 1 evo_gate = PauliEvolutionGate(op, time, synthesis=SuzukiTrotter(order=4, reps=reps)) @@ -151,7 +157,8 @@ def test_qdrift_manual(self, op, time, reps, sampled_ops): def test_qdrift_evolution(self): """Test QDrift on an example.""" - op = 0.1 * (Z ^ Z) + (X ^ I) + (I ^ X) + 0.2 * (X ^ X) + with self.assertWarns(DeprecationWarning): + op = 0.1 * (Z ^ Z) + (X ^ I) + (I ^ X) + 0.2 * (X ^ X) reps = 20 qdrift = PauliEvolutionGate(op, time=0.5 / reps, synthesis=QDrift(reps=reps)).definition exact = scipy.linalg.expm(-0.5j * op.to_matrix()).dot(np.eye(4)[0, :]) @@ -163,7 +170,8 @@ def energy(evo): def test_passing_grouped_paulis(self): """Test passing a list of already grouped Paulis.""" - grouped_ops = [(X ^ Y) + (Y ^ X), (Z ^ I) + (Z ^ Z) + (I ^ Z), (X ^ X)] + with self.assertWarns(DeprecationWarning): + grouped_ops = [(X ^ Y) + (Y ^ X), (Z ^ I) + (Z ^ Z) + (I ^ Z), (X ^ X)] evo_gate = PauliEvolutionGate(grouped_ops, time=0.12, synthesis=LieTrotter()) decomposed = evo_gate.definition.decompose() self.assertEqual(decomposed.count_ops()["rz"], 4) @@ -172,7 +180,8 @@ def test_passing_grouped_paulis(self): def test_list_from_grouped_paulis(self): """Test getting a string representation from grouped Paulis.""" - grouped_ops = [(X ^ Y) + (Y ^ X), (Z ^ I) + (Z ^ Z) + (I ^ Z), (X ^ X)] + with self.assertWarns(DeprecationWarning): + grouped_ops = [(X ^ Y) + (Y ^ X), (Z ^ I) + (Z ^ Z) + (I ^ Z), (X ^ X)] evo_gate = PauliEvolutionGate(grouped_ops, time=0.12, synthesis=LieTrotter()) pauli_strings = [] @@ -192,7 +201,8 @@ def test_list_from_grouped_paulis(self): def test_dag_conversion(self): """Test constructing a circuit with evolutions yields a DAG with evolution blocks.""" time = Parameter("t") - evo = PauliEvolutionGate((Z ^ 2) + (X ^ 2), time=time) + with self.assertWarns(DeprecationWarning): + evo = PauliEvolutionGate((Z ^ 2) + (X ^ 2), time=time) circuit = QuantumCircuit(2) circuit.h(circuit.qubits) @@ -210,7 +220,8 @@ def test_dag_conversion(self): def test_cnot_chain_options(self, option): """Test selecting different kinds of CNOT chains.""" - op = Z ^ Z ^ Z + with self.assertWarns(DeprecationWarning): + op = Z ^ Z ^ Z synthesis = LieTrotter(reps=1, cx_structure=option) evo = PauliEvolutionGate(op, synthesis=synthesis) @@ -254,14 +265,16 @@ def test_different_input_types(self, op): def test_pauliop_coefficients_respected(self): """Test that global ``PauliOp`` coefficients are being taken care of.""" - evo = PauliEvolutionGate(5 * (Z ^ I), time=1, synthesis=LieTrotter()) + with self.assertWarns(DeprecationWarning): + evo = PauliEvolutionGate(5 * (Z ^ I), time=1, synthesis=LieTrotter()) circuit = evo.definition.decompose() rz_angle = circuit.data[0].operation.params[0] self.assertEqual(rz_angle, 10) def test_paulisumop_coefficients_respected(self): """Test that global ``PauliSumOp`` coefficients are being taken care of.""" - evo = PauliEvolutionGate(5 * (2 * X + 3 * Y - Z), time=1, synthesis=LieTrotter()) + with self.assertWarns(DeprecationWarning): + evo = PauliEvolutionGate(5 * (2 * X + 3 * Y - Z), time=1, synthesis=LieTrotter()) circuit = evo.definition.decompose() rz_angles = [ circuit.data[0].operation.params[0], # X @@ -275,7 +288,8 @@ def test_lie_trotter_two_qubit_correct_order(self): Regression test of Qiskit/qiskit-terra#7544. """ - operator = I ^ Z ^ Z + with self.assertWarns(DeprecationWarning): + operator = I ^ Z ^ Z time = 0.5 exact = scipy.linalg.expm(-1j * time * operator.to_matrix()) lie_trotter = PauliEvolutionGate(operator, time, synthesis=LieTrotter()) @@ -295,7 +309,8 @@ def test_paramtrized_op_raises(self): @data(LieTrotter, MatrixExponential) def test_inverse(self, synth_cls): """Test calculating the inverse is correct.""" - evo = PauliEvolutionGate(X + Y, time=0.12, synthesis=synth_cls()) + with self.assertWarns(DeprecationWarning): + evo = PauliEvolutionGate(X + Y, time=0.12, synthesis=synth_cls()) circuit = QuantumCircuit(1) circuit.append(evo, circuit.qubits) @@ -305,7 +320,8 @@ def test_inverse(self, synth_cls): def test_labels_and_name(self): """Test the name and labels are correct.""" - operators = [X, (X + Y), ((I ^ Z) + (Z ^ I) - 0.2 * (X ^ X))] + with self.assertWarns(DeprecationWarning): + operators = [X, (X + Y), ((I ^ Z) + (Z ^ I) - 0.2 * (X ^ X))] # note: the labels do not show coefficients! expected_labels = ["X", "(X + Y)", "(IZ + ZI + XX)"] diff --git a/test/python/circuit/library/test_evolved_op_ansatz.py b/test/python/circuit/library/test_evolved_op_ansatz.py index 3fc0161eac30..c809fe438820 100644 --- a/test/python/circuit/library/test_evolved_op_ansatz.py +++ b/test/python/circuit/library/test_evolved_op_ansatz.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2021. +# (C) Copyright IBM 2021, 2023. # # 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 @@ -32,18 +32,19 @@ class TestEvolvedOperatorAnsatz(QiskitTestCase): def test_evolved_op_ansatz(self, use_opflow): """Test the default evolution.""" num_qubits = 3 - if use_opflow: - ops = [Z ^ num_qubits, Y ^ num_qubits, X ^ num_qubits] + with self.assertWarns(DeprecationWarning): + ops = [Z ^ num_qubits, Y ^ num_qubits, X ^ num_qubits] + evo = EvolvedOperatorAnsatz(ops, 2) + parameters = evo.parameters + else: ops = [Pauli("Z" * num_qubits), Pauli("Y" * num_qubits), Pauli("X" * num_qubits)] - - strings = ["z" * num_qubits, "y" * num_qubits, "x" * num_qubits] * 2 - - evo = EvolvedOperatorAnsatz(ops, 2) + evo = EvolvedOperatorAnsatz(ops, 2) + parameters = evo.parameters reference = QuantumCircuit(num_qubits) - parameters = evo.parameters + strings = ["z" * num_qubits, "y" * num_qubits, "x" * num_qubits] * 2 for string, time in zip(strings, parameters): reference.compose(evolve(string, time), inplace=True) @@ -53,17 +54,20 @@ def test_evolved_op_ansatz(self, use_opflow): def test_custom_evolution(self, use_opflow): """Test using another evolution than the default (e.g. matrix evolution).""" if use_opflow: - op = X ^ I ^ Z - matrix = op.to_matrix() - evolution = MatrixEvolution() + with self.assertWarns(DeprecationWarning): + op = X ^ I ^ Z + matrix = op.to_matrix() + evolution = MatrixEvolution() + evo = EvolvedOperatorAnsatz(op, evolution=evolution) + parameters = evo.parameters + else: op = SparsePauliOp(["ZIX"]) matrix = np.array(op) evolution = MatrixExponential() + evo = EvolvedOperatorAnsatz(op, evolution=evolution) + parameters = evo.parameters - evo = EvolvedOperatorAnsatz(op, evolution=evolution) - - parameters = evo.parameters reference = QuantumCircuit(3) reference.hamiltonian(matrix, parameters[0], [0, 1, 2]) @@ -77,10 +81,11 @@ def test_changing_operators(self): """Test rebuilding after the operators changed.""" ops = [X, Y, Z] - evo = EvolvedOperatorAnsatz(ops) - evo.operators = [X, Y] + with self.assertWarns(DeprecationWarning): + evo = EvolvedOperatorAnsatz(ops) + evo.operators = [X, Y] + parameters = evo.parameters - parameters = evo.parameters reference = QuantumCircuit(1) reference.rx(2 * parameters[0], 0) reference.ry(2 * parameters[1], 0) @@ -94,13 +99,13 @@ def test_invalid_reps(self): def test_insert_barriers(self): """Test using insert_barriers.""" - evo = EvolvedOperatorAnsatz(Z, reps=4, insert_barriers=True) - ref = QuantumCircuit(1) - for parameter in evo.parameters: - ref.rz(2.0 * parameter, 0) - ref.barrier() - - self.assertEqual(evo.decompose(), ref) + with self.assertWarns(DeprecationWarning): + evo = EvolvedOperatorAnsatz(Z, reps=4, insert_barriers=True) + ref = QuantumCircuit(1) + for parameter in evo.parameters: + ref.rz(2.0 * parameter, 0) + ref.barrier() + self.assertEqual(evo.decompose(), ref) def test_empty_build_fails(self): """Test setting no operators to evolve raises the appropriate error.""" diff --git a/test/python/circuit/library/test_qaoa_ansatz.py b/test/python/circuit/library/test_qaoa_ansatz.py index 9a05b2c420c2..dfbf25da69d4 100644 --- a/test/python/circuit/library/test_qaoa_ansatz.py +++ b/test/python/circuit/library/test_qaoa_ansatz.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2021. +# (C) Copyright IBM 2021, 2023. # # 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 @@ -18,7 +18,7 @@ from qiskit.circuit import QuantumCircuit, Parameter from qiskit.circuit.library import HGate, RXGate, YGate, RYGate, RZGate from qiskit.circuit.library.n_local.qaoa_ansatz import QAOAAnsatz -from qiskit.opflow import I, Y, Z +from qiskit.opflow import I from qiskit.quantum_info import Pauli, SparsePauliOp from qiskit.test import QiskitTestCase @@ -29,8 +29,8 @@ class TestQAOAAnsatz(QiskitTestCase): def test_default_qaoa(self): """Test construction of the default circuit.""" + # To be changed once QAOAAnsatz drops support for opflow circuit = QAOAAnsatz(I, 1) - parameters = circuit.parameters circuit = circuit.decompose() @@ -42,8 +42,7 @@ def test_custom_initial_state(self): """Test circuit with a custom initial state.""" initial_state = QuantumCircuit(1) initial_state.y(0) - circuit = QAOAAnsatz(initial_state=initial_state, cost_operator=I, reps=1) - + circuit = QAOAAnsatz(initial_state=initial_state, cost_operator=Pauli("I"), reps=1) parameters = circuit.parameters circuit = circuit.decompose() self.assertEqual(1, len(parameters)) @@ -53,11 +52,11 @@ def test_custom_initial_state(self): def test_invalid_reps(self): """Test negative reps.""" with self.assertRaises(ValueError): - _ = QAOAAnsatz(I, reps=-1) + _ = QAOAAnsatz(Pauli("I"), reps=-1) def test_zero_reps(self): """Test zero reps.""" - circuit = QAOAAnsatz(I ^ 4, reps=0) + circuit = QAOAAnsatz(Pauli("IIII"), reps=0) reference = QuantumCircuit(4) reference.h(range(4)) @@ -67,7 +66,7 @@ def test_custom_circuit_mixer(self): """Test circuit with a custom mixer as a circuit""" mixer = QuantumCircuit(1) mixer.ry(1, 0) - circuit = QAOAAnsatz(cost_operator=I, reps=1, mixer_operator=mixer) + circuit = QAOAAnsatz(cost_operator=Pauli("I"), reps=1, mixer_operator=mixer) parameters = circuit.parameters circuit = circuit.decompose() @@ -77,18 +76,19 @@ def test_custom_circuit_mixer(self): def test_custom_operator_mixer(self): """Test circuit with a custom mixer as an operator.""" - mixer = Y - circuit = QAOAAnsatz(cost_operator=I, reps=1, mixer_operator=mixer) + mixer = Pauli("Y") + circuit = QAOAAnsatz(cost_operator=Pauli("I"), reps=1, mixer_operator=mixer) parameters = circuit.parameters circuit = circuit.decompose() self.assertEqual(1, len(parameters)) self.assertIsInstance(circuit.data[0].operation, HGate) - self.assertIsInstance(circuit.data[1].operation, RYGate) + self.assertIsInstance(circuit.decompose().data[1].operation, RYGate) def test_parameter_bounds(self): """Test the parameter bounds.""" - circuit = QAOAAnsatz(Z, reps=2) + + circuit = QAOAAnsatz(Pauli("Z"), reps=2) bounds = circuit.parameter_bounds for lower, upper in bounds[:2]: @@ -103,33 +103,34 @@ def test_all_custom_parameters(self): """Test circuit with all custom parameters.""" initial_state = QuantumCircuit(1) initial_state.y(0) - mixer = Z + mixer = Pauli("Z") circuit = QAOAAnsatz( - cost_operator=I, reps=2, initial_state=initial_state, mixer_operator=mixer + cost_operator=Pauli("I"), reps=2, initial_state=initial_state, mixer_operator=mixer ) - parameters = circuit.parameters circuit = circuit.decompose() + self.assertEqual(2, len(parameters)) self.assertIsInstance(circuit.data[0].operation, YGate) - self.assertIsInstance(circuit.data[1].operation, RZGate) - self.assertIsInstance(circuit.data[2].operation, RZGate) + self.assertIsInstance(circuit.decompose().data[1].operation, RZGate) + self.assertIsInstance(circuit.decompose().data[2].operation, RZGate) def test_configuration(self): """Test configuration checks.""" mixer = QuantumCircuit(2) - circuit = QAOAAnsatz(cost_operator=I, reps=1, mixer_operator=mixer) + circuit = QAOAAnsatz(cost_operator=Pauli("I"), reps=1, mixer_operator=mixer) self.assertRaises(ValueError, lambda: circuit.parameters) def test_rebuild(self): """Test how a circuit can be rebuilt.""" - circuit = QAOAAnsatz(cost_operator=Z ^ I) # circuit with 2 qubits + + circuit = QAOAAnsatz(cost_operator=Pauli("IZ")) # circuit with 2 qubits # force circuit to be built _ = circuit.parameters - circuit.cost_operator = Z # now it only has 1 qubit + circuit.cost_operator = Pauli("Z") # now it only has 1 qubit circuit.reps = 5 # and now 5 repetitions # rebuild the circuit self.assertEqual(1, circuit.num_qubits) @@ -143,7 +144,7 @@ def test_circuit_mixer(self): mixer.ry(x2, 1) reps = 4 - circuit = QAOAAnsatz(cost_operator=Z ^ Z, mixer_operator=mixer, reps=reps) + circuit = QAOAAnsatz(cost_operator=Pauli("ZZ"), mixer_operator=mixer, reps=reps) self.assertEqual(circuit.num_parameters, 3 * reps) def test_empty_op(self): diff --git a/test/python/circuit/test_circuit_load_from_qpy.py b/test/python/circuit/test_circuit_load_from_qpy.py index 7788dab97abb..3bedc5cb9da0 100644 --- a/test/python/circuit/test_circuit_load_from_qpy.py +++ b/test/python/circuit/test_circuit_load_from_qpy.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2020. +# (C) Copyright IBM 2020, 2023. # # 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 @@ -42,9 +42,9 @@ from qiskit.circuit.parametervector import ParameterVector from qiskit.synthesis import LieTrotter, SuzukiTrotter from qiskit.extensions import UnitaryGate -from qiskit.opflow import I, X, Y, Z from qiskit.test import QiskitTestCase from qiskit.qpy import dump, load +from qiskit.quantum_info import Pauli, SparsePauliOp from qiskit.quantum_info.random import random_unitary from qiskit.circuit.controlledgate import ControlledGate @@ -303,7 +303,12 @@ def test_parameter_expression(self): def test_string_parameter(self): """Test a PauliGate instruction that has string parameters.""" - circ = (X ^ Y ^ Z).to_circuit_op().to_circuit() + + circ = QuantumCircuit(3) + circ.z(0) + circ.y(1) + circ.x(2) + qpy_file = io.BytesIO() dump(circ, qpy_file) qpy_file.seek(0) @@ -677,8 +682,9 @@ def test_single_bit_teleportation(self): def test_qaoa(self): """Test loading a QAOA circuit works.""" - cost_operator = Z ^ I ^ I ^ Z + cost_operator = Pauli("ZIIZ") qaoa = QAOAAnsatz(cost_operator, reps=2) + qpy_file = io.BytesIO() dump(qaoa, qpy_file) qpy_file.seek(0) @@ -692,7 +698,10 @@ def test_qaoa(self): def test_evolutiongate(self): """Test loading a circuit with evolution gate works.""" synthesis = LieTrotter(reps=2) - evo = PauliEvolutionGate((Z ^ I) + (I ^ Z), time=2, synthesis=synthesis) + evo = PauliEvolutionGate( + SparsePauliOp.from_list([("ZI", 1), ("IZ", 1)]), time=2, synthesis=synthesis + ) + qc = QuantumCircuit(2) qc.append(evo, range(2)) qpy_file = io.BytesIO() @@ -713,7 +722,10 @@ def test_evolutiongate_param_time(self): """Test loading a circuit with an evolution gate that has a parameter for time.""" synthesis = LieTrotter(reps=2) time = Parameter("t") - evo = PauliEvolutionGate((Z ^ I) + (I ^ Z), time=time, synthesis=synthesis) + evo = PauliEvolutionGate( + SparsePauliOp.from_list([("ZI", 1), ("IZ", 1)]), time=time, synthesis=synthesis + ) + qc = QuantumCircuit(2) qc.append(evo, range(2)) qpy_file = io.BytesIO() @@ -734,7 +746,10 @@ def test_evolutiongate_param_expr_time(self): """Test loading a circuit with an evolution gate that has a parameter for time.""" synthesis = LieTrotter(reps=2) time = Parameter("t") - evo = PauliEvolutionGate((Z ^ I) + (I ^ Z), time=time * time, synthesis=synthesis) + evo = PauliEvolutionGate( + SparsePauliOp.from_list([("ZI", 1), ("IZ", 1)]), time=time * time, synthesis=synthesis + ) + qc = QuantumCircuit(2) qc.append(evo, range(2)) qpy_file = io.BytesIO() @@ -755,7 +770,10 @@ def test_evolutiongate_param_vec_time(self): """Test loading a an evolution gate that has a param vector element for time.""" synthesis = LieTrotter(reps=2) time = ParameterVector("TimeVec", 1) - evo = PauliEvolutionGate((Z ^ I) + (I ^ Z), time=time[0], synthesis=synthesis) + evo = PauliEvolutionGate( + SparsePauliOp.from_list([("ZI", 1), ("IZ", 1)]), time=time[0], synthesis=synthesis + ) + qc = QuantumCircuit(2) qc.append(evo, range(2)) qpy_file = io.BytesIO() @@ -774,7 +792,10 @@ def test_evolutiongate_param_vec_time(self): def test_op_list_evolutiongate(self): """Test loading a circuit with evolution gate works.""" - evo = PauliEvolutionGate([(Z ^ I) + (I ^ Z)] * 5, time=0.2, synthesis=None) + + evo = PauliEvolutionGate( + [SparsePauliOp.from_list([("ZI", 1), ("IZ", 1)])] * 5, time=0.2, synthesis=None + ) qc = QuantumCircuit(2) qc.append(evo, range(2)) qpy_file = io.BytesIO() @@ -794,7 +815,10 @@ def test_op_list_evolutiongate(self): def test_op_evolution_gate_suzuki_trotter(self): """Test qpy path with a suzuki trotter synthesis method on an evolution gate.""" synthesis = SuzukiTrotter() - evo = PauliEvolutionGate((Z ^ I) + (I ^ Z), time=0.2, synthesis=synthesis) + evo = PauliEvolutionGate( + SparsePauliOp.from_list([("ZI", 1), ("IZ", 1)]), time=0.2, synthesis=synthesis + ) + qc = QuantumCircuit(2) qc.append(evo, range(2)) qpy_file = io.BytesIO() diff --git a/test/python/opflow/opflow_test_case.py b/test/python/opflow/opflow_test_case.py index ef8d8c6824c7..142fb1db76b5 100644 --- a/test/python/opflow/opflow_test_case.py +++ b/test/python/opflow/opflow_test_case.py @@ -12,10 +12,19 @@ """Opflow Test Case""" +import warnings from qiskit.test import QiskitTestCase class QiskitOpflowTestCase(QiskitTestCase): """Opflow test Case""" - pass + def setUp(self): + super().setUp() + # ignore opflow msgs + warnings.filterwarnings("ignore", category=DeprecationWarning, message=r".*opflow.*") + + def tearDown(self): + super().tearDown() + # restore opflow msgs + warnings.filterwarnings("error", category=DeprecationWarning, message=r".*opflow.*") diff --git a/test/python/opflow/test_aer_pauli_expectation.py b/test/python/opflow/test_aer_pauli_expectation.py index c0676544a91e..808f7bab8716 100644 --- a/test/python/opflow/test_aer_pauli_expectation.py +++ b/test/python/opflow/test_aer_pauli_expectation.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2018, 2021. +# (C) Copyright IBM 2018, 2023. # # 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 @@ -15,7 +15,6 @@ import itertools import unittest from test.python.opflow import QiskitOpflowTestCase - import numpy as np from qiskit.circuit.library import RealAmplitudes @@ -40,36 +39,34 @@ Zero, MatrixOp, ) -from qiskit.utils import QuantumInstance +from qiskit.utils import QuantumInstance, optionals class TestAerPauliExpectation(QiskitOpflowTestCase): """Pauli Change of Basis Expectation tests.""" + @unittest.skipUnless(optionals.HAS_AER, "qiskit-aer is required to run this test") def setUp(self) -> None: super().setUp() - try: - from qiskit_aer import Aer + from qiskit_aer import AerSimulator - self.seed = 97 - self.backend = Aer.get_backend("aer_simulator") + self.seed = 97 + self.backend = AerSimulator() + with self.assertWarns(DeprecationWarning): q_instance = QuantumInstance( self.backend, seed_simulator=self.seed, seed_transpiler=self.seed ) self.sampler = CircuitSampler(q_instance, attach_results=True) self.expect = AerPauliExpectation() - except Exception as ex: # pylint: disable=broad-except - self.skipTest(f"Aer doesn't appear to be installed. Error: '{str(ex)}'") - return def test_pauli_expect_pair(self): """pauli expect pair test""" op = Z ^ Z # wvf = (Pl^Pl) + (Ze^Ze) wvf = CX @ (H ^ I) @ Zero - converted_meas = self.expect.convert(~StateFn(op) @ wvf) - sampled = self.sampler.convert(converted_meas) + with self.assertWarns(DeprecationWarning): + sampled = self.sampler.convert(converted_meas) self.assertAlmostEqual(sampled.eval(), 0, delta=0.1) def test_pauli_expect_single(self): @@ -79,7 +76,8 @@ def test_pauli_expect_single(self): for pauli, state in itertools.product(paulis, states): converted_meas = self.expect.convert(~StateFn(pauli) @ state) matmulmean = state.adjoint().to_matrix() @ pauli.to_matrix() @ state.to_matrix() - sampled = self.sampler.convert(converted_meas) + with self.assertWarns(DeprecationWarning): + sampled = self.sampler.convert(converted_meas) self.assertAlmostEqual(sampled.eval(), matmulmean, delta=0.1) def test_pauli_expect_op_vector(self): @@ -87,33 +85,36 @@ def test_pauli_expect_op_vector(self): paulis_op = ListOp([X, Y, Z, I]) converted_meas = self.expect.convert(~StateFn(paulis_op)) - plus_mean = converted_meas @ Plus - sampled_plus = self.sampler.convert(plus_mean) - np.testing.assert_array_almost_equal(sampled_plus.eval(), [1, 0, 0, 1], decimal=1) + with self.assertWarns(DeprecationWarning): + plus_mean = converted_meas @ Plus + sampled_plus = self.sampler.convert(plus_mean) + np.testing.assert_array_almost_equal(sampled_plus.eval(), [1, 0, 0, 1], decimal=1) + + minus_mean = converted_meas @ Minus + sampled_minus = self.sampler.convert(minus_mean) + np.testing.assert_array_almost_equal(sampled_minus.eval(), [-1, 0, 0, 1], decimal=1) - minus_mean = converted_meas @ Minus - sampled_minus = self.sampler.convert(minus_mean) - np.testing.assert_array_almost_equal(sampled_minus.eval(), [-1, 0, 0, 1], decimal=1) + zero_mean = converted_meas @ Zero + sampled_zero = self.sampler.convert(zero_mean) + np.testing.assert_array_almost_equal(sampled_zero.eval(), [0, 0, 1, 1], decimal=1) - zero_mean = converted_meas @ Zero - sampled_zero = self.sampler.convert(zero_mean) - np.testing.assert_array_almost_equal(sampled_zero.eval(), [0, 0, 1, 1], decimal=1) + sum_zero = (Plus + Minus) * (0.5**0.5) + sum_zero_mean = converted_meas @ sum_zero + sampled_zero_mean = self.sampler.convert(sum_zero_mean) - sum_zero = (Plus + Minus) * (0.5**0.5) - sum_zero_mean = converted_meas @ sum_zero - sampled_zero_mean = self.sampler.convert(sum_zero_mean) - # !!NOTE!!: Depolarizing channel (Sampling) means interference - # does not happen between circuits in sum, so expectation does - # not equal expectation for Zero!! - np.testing.assert_array_almost_equal(sampled_zero_mean.eval(), [0, 0, 0, 1]) + # !!NOTE!!: Depolarizing channel (Sampling) means interference + # does not happen between circuits in sum, so expectation does + # not equal expectation for Zero!! + np.testing.assert_array_almost_equal(sampled_zero_mean.eval(), [0, 0, 0, 1]) def test_pauli_expect_state_vector(self): """pauli expect state vector test""" states_op = ListOp([One, Zero, Plus, Minus]) - paulis_op = X converted_meas = self.expect.convert(~StateFn(paulis_op) @ states_op) - sampled = self.sampler.convert(converted_meas) + + with self.assertWarns(DeprecationWarning): + sampled = self.sampler.convert(converted_meas) # Small test to see if execution results are accessible for composed_op in sampled: @@ -124,24 +125,21 @@ def test_pauli_expect_state_vector(self): def test_pauli_expect_non_hermitian_matrixop(self): """pauli expect state vector with non hermitian operator test""" states_op = ListOp([One, Zero, Plus, Minus]) - op_mat = np.array([[0, 1], [2, 3]]) op = MatrixOp(op_mat) - converted_meas = self.expect.convert(StateFn(op, is_measurement=True) @ states_op) - sampled = self.sampler.convert(converted_meas) + with self.assertWarns(DeprecationWarning): + sampled = self.sampler.convert(converted_meas) np.testing.assert_array_almost_equal(sampled.eval(), [3, 0, 3, 0], decimal=1) def test_pauli_expect_non_hermitian_pauliop(self): """pauli expect state vector with non hermitian operator test""" states_op = ListOp([One, Zero, Plus, Minus]) - op = 1j * X - converted_meas = self.expect.convert(StateFn(op, is_measurement=True) @ states_op) - sampled = self.sampler.convert(converted_meas) - + with self.assertWarns(DeprecationWarning): + sampled = self.sampler.convert(converted_meas) np.testing.assert_array_almost_equal(sampled.eval(), [0, 0, 1j, -1j], decimal=1) def test_pauli_expect_op_vector_state_vector(self): @@ -156,22 +154,27 @@ def test_pauli_expect_op_vector_state_vector(self): [+1, 1, 1, 1], ] converted_meas = self.expect.convert(~StateFn(paulis_op) @ states_op) - sampled = self.sampler.convert(converted_meas) + with self.assertWarns(DeprecationWarning): + sampled = self.sampler.convert(converted_meas) np.testing.assert_array_almost_equal(sampled.eval(), valids, decimal=1) def test_multi_representation_ops(self): """Test observables with mixed representations""" + mixed_ops = ListOp([X.to_matrix_op(), H, H + I, X]) converted_meas = self.expect.convert(~StateFn(mixed_ops)) plus_mean = converted_meas @ Plus - sampled_plus = self.sampler.convert(plus_mean) + with self.assertWarns(DeprecationWarning): + sampled_plus = self.sampler.convert(plus_mean) + np.testing.assert_array_almost_equal( sampled_plus.eval(), [1, 0.5**0.5, (1 + 0.5**0.5), 1], decimal=1 ) def test_parameterized_qobj(self): """grouped pauli expectation test""" + two_qubit_h2 = ( (-1.052373245772859 * I ^ I) + (0.39793742484318045 * I ^ Z) @@ -179,11 +182,10 @@ def test_parameterized_qobj(self): + (-0.01128010425623538 * Z ^ Z) + (0.18093119978423156 * X ^ X) ) - - aer_sampler = CircuitSampler( - self.sampler.quantum_instance, param_qobj=True, attach_results=True - ) - + with self.assertWarns(DeprecationWarning): + aer_sampler = CircuitSampler( + self.sampler.quantum_instance, param_qobj=True, attach_results=True + ) ansatz = RealAmplitudes() ansatz.num_qubits = 2 @@ -201,12 +203,13 @@ def generate_parameters(num): return param_bindings def validate_sampler(ideal, sut, param_bindings): - expect_sampled = ideal.convert(expect_op, params=param_bindings).eval() - actual_sampled = sut.convert(expect_op, params=param_bindings).eval() - self.assertTrue( - np.allclose(actual_sampled, expect_sampled), - f"{actual_sampled} != {expect_sampled}", - ) + with self.assertWarns(DeprecationWarning): + expect_sampled = ideal.convert(expect_op, params=param_bindings).eval() + actual_sampled = sut.convert(expect_op, params=param_bindings).eval() + self.assertTrue( + np.allclose(actual_sampled, expect_sampled), + f"{actual_sampled} != {expect_sampled}", + ) def get_circuit_templates(sampler): return sampler._transpiled_circ_templates @@ -236,9 +239,10 @@ def validate_aer_templates_reused(prev_templates, cur_templates): def test_pauli_expectation_param_qobj(self): """Test PauliExpectation with param_qobj""" - q_instance = QuantumInstance( - self.backend, seed_simulator=self.seed, seed_transpiler=self.seed, shots=10000 - ) + with self.assertWarns(DeprecationWarning): + q_instance = QuantumInstance( + self.backend, seed_simulator=self.seed, seed_transpiler=self.seed, shots=10000 + ) qubit_op = (0.1 * I ^ I) + (0.2 * I ^ Z) + (0.3 * Z ^ I) + (0.4 * Z ^ Z) + (0.5 * X ^ X) ansatz = RealAmplitudes(qubit_op.num_qubits) ansatz_circuit_op = CircuitStateFn(ansatz) @@ -250,16 +254,17 @@ def test_pauli_expectation_param_qobj(self): params1[param] = [0] params2[param] = [0, 0] - sampler1 = CircuitSampler(backend=q_instance, param_qobj=False) - samples1 = sampler1.convert(expect_op, params=params1) - val1 = np.real(samples1.eval())[0] - samples2 = sampler1.convert(expect_op, params=params2) - val2 = np.real(samples2.eval()) - sampler2 = CircuitSampler(backend=q_instance, param_qobj=True) - samples3 = sampler2.convert(expect_op, params=params1) - val3 = np.real(samples3.eval()) - samples4 = sampler2.convert(expect_op, params=params2) - val4 = np.real(samples4.eval()) + with self.assertWarns(DeprecationWarning): + sampler1 = CircuitSampler(backend=q_instance, param_qobj=False) + samples1 = sampler1.convert(expect_op, params=params1) + val1 = np.real(samples1.eval())[0] + samples2 = sampler1.convert(expect_op, params=params2) + val2 = np.real(samples2.eval()) + sampler2 = CircuitSampler(backend=q_instance, param_qobj=True) + samples3 = sampler2.convert(expect_op, params=params1) + val3 = np.real(samples3.eval()) + samples4 = sampler2.convert(expect_op, params=params2) + val4 = np.real(samples4.eval()) np.testing.assert_array_almost_equal([val1] * 2, val2, decimal=2) np.testing.assert_array_almost_equal(val1, val3, decimal=2) @@ -277,12 +282,14 @@ def test_expectation_with_coeff(self): """Test AerPauliExpectation with coefficients.""" with self.subTest("integer coefficients"): exp = 3 * ~StateFn(X) @ (2 * Minus) - target = self.sampler.convert(self.expect.convert(exp)).eval() + with self.assertWarns(DeprecationWarning): + target = self.sampler.convert(self.expect.convert(exp)).eval() self.assertAlmostEqual(target, -12) with self.subTest("complex coefficients"): exp = 3j * ~StateFn(X) @ (2j * Minus) - target = self.sampler.convert(self.expect.convert(exp)).eval() + with self.assertWarns(DeprecationWarning): + target = self.sampler.convert(self.expect.convert(exp)).eval() self.assertAlmostEqual(target, -12j) diff --git a/test/python/opflow/test_expectation_factory.py b/test/python/opflow/test_expectation_factory.py index 47c9302e8c54..f03a8517733d 100644 --- a/test/python/opflow/test_expectation_factory.py +++ b/test/python/opflow/test_expectation_factory.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2018, 2021. +# (C) Copyright IBM 2018, 2023. # # 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 @@ -16,26 +16,24 @@ from test.python.opflow import QiskitOpflowTestCase from qiskit.opflow import PauliExpectation, AerPauliExpectation, ExpectationFactory, Z, I, X -from qiskit.utils import has_aer - - -if has_aer(): - from qiskit import Aer +from qiskit.utils import optionals class TestExpectationFactory(QiskitOpflowTestCase): """Tests for the expectation factory.""" - @unittest.skipUnless(has_aer(), "qiskit-aer doesn't appear to be installed.") + @unittest.skipUnless(optionals.HAS_AER, "qiskit-aer is required to run this test") def test_aer_simulator_pauli_sum(self): """Test expectation selection with Aer's qasm_simulator.""" - backend = Aer.get_backend("aer_simulator") - op = 0.2 * (X ^ X) + 0.1 * (Z ^ I) + from qiskit_aer import AerSimulator - with self.subTest("Defaults"): - expectation = ExpectationFactory.build(op, backend, include_custom=False) - self.assertIsInstance(expectation, PauliExpectation) - - with self.subTest("Include custom"): - expectation = ExpectationFactory.build(op, backend, include_custom=True) - self.assertIsInstance(expectation, AerPauliExpectation) + backend = AerSimulator() + op = 0.2 * (X ^ X) + 0.1 * (Z ^ I) + with self.assertWarns(DeprecationWarning): + with self.subTest("Defaults"): + expectation = ExpectationFactory.build(op, backend, include_custom=False) + self.assertIsInstance(expectation, PauliExpectation) + + with self.subTest("Include custom"): + expectation = ExpectationFactory.build(op, backend, include_custom=True) + self.assertIsInstance(expectation, AerPauliExpectation) diff --git a/test/python/opflow/test_gradients.py b/test/python/opflow/test_gradients.py index 490d2d839ee7..07ada8e56ef9 100644 --- a/test/python/opflow/test_gradients.py +++ b/test/python/opflow/test_gradients.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2019, 2021. +# (C) Copyright IBM 2019, 2023. # # 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 @@ -840,6 +840,7 @@ def grad_combo_fn(x): qc = RealAmplitudes(2, reps=1) grad_op = ListOp([StateFn(qc.decompose())], combo_fn=combo_fn, grad_combo_fn=grad_combo_fn) grad = Gradient(grad_method=method).convert(grad_op) + value_dict = dict(zip(qc.ordered_parameters, np.random.rand(len(qc.ordered_parameters)))) correct_values = [ [(-0.16666259133549044 + 0j)], @@ -998,13 +999,17 @@ def test_circuit_sampler(self, method): ] backend = BasicAer.get_backend("qasm_simulator") - q_instance = QuantumInstance(backend=backend, shots=shots) + with self.assertWarns(DeprecationWarning): + q_instance = QuantumInstance(backend=backend, shots=shots) - for i, value_dict in enumerate(values_dict): - sampler = CircuitSampler(backend=q_instance).convert( - state_grad, params={k: [v] for k, v in value_dict.items()} - ) - np.testing.assert_array_almost_equal(sampler.eval()[0], correct_values[i], decimal=1) + with self.assertWarns(DeprecationWarning): + for i, value_dict in enumerate(values_dict): + sampler = CircuitSampler(backend=q_instance).convert( + state_grad, params={k: [v] for k, v in value_dict.items()} + ) + np.testing.assert_array_almost_equal( + sampler.eval()[0], correct_values[i], decimal=1 + ) @data("lin_comb", "param_shift", "fin_diff") def test_circuit_sampler2(self, method): @@ -1048,13 +1053,15 @@ def test_circuit_sampler2(self, method): ] backend = BasicAer.get_backend("qasm_simulator") - q_instance = QuantumInstance(backend=backend, shots=shots) + with self.assertWarns(DeprecationWarning): + q_instance = QuantumInstance(backend=backend, shots=shots) - for i, value_dict in enumerate(values_dict): - sampler = CircuitSampler(backend=q_instance).convert(prob_grad, params=value_dict) - result = sampler.eval()[0] - self.assertTrue(np.allclose(result[0].toarray(), correct_values[i][0], atol=0.1)) - self.assertTrue(np.allclose(result[1].toarray(), correct_values[i][1], atol=0.1)) + with self.assertWarns(DeprecationWarning): + for i, value_dict in enumerate(values_dict): + sampler = CircuitSampler(backend=q_instance).convert(prob_grad, params=value_dict) + result = sampler.eval()[0] + self.assertTrue(np.allclose(result[0].toarray(), correct_values[i][0], atol=0.1)) + self.assertTrue(np.allclose(result[1].toarray(), correct_values[i][1], atol=0.1)) @idata(["statevector_simulator", "qasm_simulator"]) def test_gradient_wrapper(self, backend_type): @@ -1079,31 +1086,38 @@ def test_gradient_wrapper(self, backend_type): shots = 8000 backend = BasicAer.get_backend(backend_type) - q_instance = QuantumInstance( - backend=backend, shots=shots, seed_simulator=2, seed_transpiler=2 - ) + + with self.assertWarns(DeprecationWarning): + q_instance = QuantumInstance( + backend=backend, shots=shots, seed_simulator=2, seed_transpiler=2 + ) + if method == "fin_diff": np.random.seed(8) prob_grad = Gradient(grad_method=method, epsilon=shots ** (-1 / 6.0)).gradient_wrapper( operator=op, bind_params=params, backend=q_instance ) else: - prob_grad = Gradient(grad_method=method).gradient_wrapper( - operator=op, bind_params=params, backend=q_instance - ) + + with self.assertWarns(DeprecationWarning): + prob_grad = Gradient(grad_method=method).gradient_wrapper( + operator=op, bind_params=params, backend=q_instance + ) + values = [[np.pi / 4, 0], [np.pi / 4, np.pi / 4], [np.pi / 2, np.pi]] correct_values = [ [[0, 0], [1 / (2 * np.sqrt(2)), -1 / (2 * np.sqrt(2))]], [[1 / 4, -1 / 4], [1 / 4, -1 / 4]], [[0, 0], [-1 / 2, 1 / 2]], ] - for i, value in enumerate(values): - result = prob_grad(value) - if backend_type == "qasm_simulator": # sparse result - result = [result[0].toarray(), result[1].toarray()] + with self.assertWarns(DeprecationWarning): + for i, value in enumerate(values): + result = prob_grad(value) + if backend_type == "qasm_simulator": # sparse result + result = [result[0].toarray(), result[1].toarray()] - self.assertTrue(np.allclose(result[0], correct_values[i][0], atol=0.1)) - self.assertTrue(np.allclose(result[1], correct_values[i][1], atol=0.1)) + self.assertTrue(np.allclose(result[0], correct_values[i][0], atol=0.1)) + self.assertTrue(np.allclose(result[1], correct_values[i][1], atol=0.1)) @data(("statevector_simulator", 1e-7), ("qasm_simulator", 2e-1)) @unpack @@ -1139,13 +1153,14 @@ def test_gradient_wrapper2(self, backend_type, atol): correct_values = [[-4.0, 0], [-2.0, -4.82842712], [-0.68404029, -7.01396121]] for i, value in enumerate(values): backend = BasicAer.get_backend(backend_type) - q_instance = QuantumInstance( - backend=backend, shots=shots, seed_simulator=2, seed_transpiler=2 - ) - grad = NaturalGradient(grad_method=method).gradient_wrapper( - operator=op, bind_params=params, backend=q_instance - ) - result = grad(value) + with self.assertWarns(DeprecationWarning): + q_instance = QuantumInstance( + backend=backend, shots=shots, seed_simulator=2, seed_transpiler=2 + ) + grad = NaturalGradient(grad_method=method).gradient_wrapper( + operator=op, bind_params=params, backend=q_instance + ) + result = grad(value) self.assertTrue(np.allclose(result, correct_values[i], atol=atol)) @slow_test @@ -1154,9 +1169,12 @@ def test_vqe(self): method = "lin_comb" backend = "qasm_simulator" - q_instance = QuantumInstance( - BasicAer.get_backend(backend), seed_simulator=79, seed_transpiler=2 - ) + + with self.assertWarns(DeprecationWarning): + q_instance = QuantumInstance( + BasicAer.get_backend(backend), seed_simulator=79, seed_transpiler=2 + ) + # Define the Hamiltonian h2_hamiltonian = ( -1.05 * (I ^ I) + 0.39 * (I ^ Z) - 0.39 * (Z ^ I) - 0.01 * (Z ^ Z) + 0.18 * (X ^ X) @@ -1183,11 +1201,11 @@ def test_vqe(self): grad = Gradient(grad_method=method) # Gradient callable - vqe = VQE( - ansatz=wavefunction, optimizer=optimizer, gradient=grad, quantum_instance=q_instance - ) - - result = vqe.compute_minimum_eigenvalue(operator=h2_hamiltonian) + with self.assertWarns(DeprecationWarning): + vqe = VQE( + ansatz=wavefunction, optimizer=optimizer, gradient=grad, quantum_instance=q_instance + ) + result = vqe.compute_minimum_eigenvalue(operator=h2_hamiltonian) np.testing.assert_almost_equal(result.optimal_value, h2_energy, decimal=0) def test_qfi_overlap_works_with_bound_parameters(self): @@ -1500,15 +1518,15 @@ def test_aux_meas_op(self, aux_meas_op): for backend_type in ["qasm_simulator", "statevector_simulator"]: for j, value_dict in enumerate(value_dicts): - - q_instance = QuantumInstance( - backend=BasicAer.get_backend(backend_type), shots=shots - ) - result = ( - CircuitSampler(backend=q_instance) - .convert(prob_grad, params=value_dict) - .eval()[0] - ) + with self.assertWarns(DeprecationWarning): + q_instance = QuantumInstance( + backend=BasicAer.get_backend(backend_type), shots=shots + ) + result = ( + CircuitSampler(backend=q_instance) + .convert(prob_grad, params=value_dict) + .eval()[0] + ) if backend_type == "qasm_simulator": # sparse result result = [result[0].toarray()[0], result[1].toarray()[0]] for i, item in enumerate(result): @@ -1544,7 +1562,8 @@ def test_unsupported_aux_meas_op(self): value_dict = {a: [np.pi / 4], b: [0]} backend = BasicAer.get_backend("qasm_simulator") - q_instance = QuantumInstance(backend=backend, shots=shots) + with self.assertWarns(DeprecationWarning): + q_instance = QuantumInstance(backend=backend, shots=shots) CircuitSampler(backend=q_instance).convert(prob_grad, params=value_dict).eval() def test_nat_grad_error(self): @@ -1577,14 +1596,19 @@ def test_nat_grad_error(self): value = [0, np.pi / 2] backend = BasicAer.get_backend(backend_type) - q_instance = QuantumInstance( - backend=backend, shots=shots, seed_simulator=2, seed_transpiler=2 - ) - grad = NaturalGradient(grad_method=method).gradient_wrapper( - operator=op, bind_params=params, backend=q_instance - ) - with self.assertRaises(ValueError): - grad(value) + with self.assertWarns(DeprecationWarning): + q_instance = QuantumInstance( + backend=backend, shots=shots, seed_simulator=2, seed_transpiler=2 + ) + + with self.assertWarns(DeprecationWarning): + grad = NaturalGradient(grad_method=method).gradient_wrapper( + operator=op, bind_params=params, backend=q_instance + ) + + with self.assertWarns(DeprecationWarning): + with self.assertRaises(ValueError): + grad(value) if __name__ == "__main__": diff --git a/test/python/opflow/test_matrix_expectation.py b/test/python/opflow/test_matrix_expectation.py index 5b873a5f6983..10448c3a64e1 100644 --- a/test/python/opflow/test_matrix_expectation.py +++ b/test/python/opflow/test_matrix_expectation.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2018, 2020. +# (C) Copyright IBM 2018, 2023. # # 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 @@ -10,7 +10,7 @@ # copyright notice, and modified files need to carry a notice indicating # that they have been altered from the originals. -"Test MatrixExpectation" +"""Test MatrixExpectation""" import unittest from test.python.opflow import QiskitOpflowTestCase @@ -45,60 +45,71 @@ def setUp(self) -> None: super().setUp() self.seed = 97 backend = BasicAer.get_backend("statevector_simulator") - q_instance = QuantumInstance(backend, seed_simulator=self.seed, seed_transpiler=self.seed) - self.sampler = CircuitSampler(q_instance, attach_results=True) + + with self.assertWarns(DeprecationWarning): + q_instance = QuantumInstance( + backend, seed_simulator=self.seed, seed_transpiler=self.seed + ) + self.sampler = CircuitSampler(q_instance, attach_results=True) + self.expect = MatrixExpectation() def test_pauli_expect_pair(self): """pauli expect pair test""" + op = Z ^ Z # wf = (Pl^Pl) + (Ze^Ze) wf = CX @ (H ^ I) @ Zero - converted_meas = self.expect.convert(~StateFn(op) @ wf) self.assertAlmostEqual(converted_meas.eval(), 0, delta=0.1) - sampled = self.sampler.convert(converted_meas) + with self.assertWarns(DeprecationWarning): + sampled = self.sampler.convert(converted_meas) self.assertAlmostEqual(sampled.eval(), 0, delta=0.1) def test_pauli_expect_single(self): """pauli expect single test""" + paulis = [Z, X, Y, I] states = [Zero, One, Plus, Minus, S @ Plus, S @ Minus] for pauli, state in itertools.product(paulis, states): converted_meas = self.expect.convert(~StateFn(pauli) @ state) matmulmean = state.adjoint().to_matrix() @ pauli.to_matrix() @ state.to_matrix() self.assertAlmostEqual(converted_meas.eval(), matmulmean, delta=0.1) - - sampled = self.sampler.convert(converted_meas) + with self.assertWarns(DeprecationWarning): + sampled = self.sampler.convert(converted_meas) self.assertAlmostEqual(sampled.eval(), matmulmean, delta=0.1) def test_pauli_expect_op_vector(self): """pauli expect op vector test""" + paulis_op = ListOp([X, Y, Z, I]) converted_meas = self.expect.convert(~StateFn(paulis_op)) - plus_mean = converted_meas @ Plus - np.testing.assert_array_almost_equal(plus_mean.eval(), [1, 0, 0, 1], decimal=1) - sampled_plus = self.sampler.convert(plus_mean) - np.testing.assert_array_almost_equal(sampled_plus.eval(), [1, 0, 0, 1], decimal=1) - - minus_mean = converted_meas @ Minus - np.testing.assert_array_almost_equal(minus_mean.eval(), [-1, 0, 0, 1], decimal=1) - sampled_minus = self.sampler.convert(minus_mean) - np.testing.assert_array_almost_equal(sampled_minus.eval(), [-1, 0, 0, 1], decimal=1) - - zero_mean = converted_meas @ Zero - np.testing.assert_array_almost_equal(zero_mean.eval(), [0, 0, 1, 1], decimal=1) - sampled_zero = self.sampler.convert(zero_mean) - np.testing.assert_array_almost_equal(sampled_zero.eval(), [0, 0, 1, 1], decimal=1) - - sum_zero = (Plus + Minus) * (0.5**0.5) - sum_zero_mean = converted_meas @ sum_zero - np.testing.assert_array_almost_equal(sum_zero_mean.eval(), [0, 0, 1, 1], decimal=1) - sampled_zero = self.sampler.convert(sum_zero) - np.testing.assert_array_almost_equal( - (converted_meas @ sampled_zero).eval(), [0, 0, 1, 1], decimal=1 - ) + with self.assertWarns(DeprecationWarning): + + plus_mean = converted_meas @ Plus + np.testing.assert_array_almost_equal(plus_mean.eval(), [1, 0, 0, 1], decimal=1) + sampled_plus = self.sampler.convert(plus_mean) + np.testing.assert_array_almost_equal(sampled_plus.eval(), [1, 0, 0, 1], decimal=1) + + minus_mean = converted_meas @ Minus + np.testing.assert_array_almost_equal(minus_mean.eval(), [-1, 0, 0, 1], decimal=1) + sampled_minus = self.sampler.convert(minus_mean) + np.testing.assert_array_almost_equal(sampled_minus.eval(), [-1, 0, 0, 1], decimal=1) + + zero_mean = converted_meas @ Zero + np.testing.assert_array_almost_equal(zero_mean.eval(), [0, 0, 1, 1], decimal=1) + sampled_zero = self.sampler.convert(zero_mean) + np.testing.assert_array_almost_equal(sampled_zero.eval(), [0, 0, 1, 1], decimal=1) + + sum_zero = (Plus + Minus) * (0.5**0.5) + sum_zero_mean = converted_meas @ sum_zero + np.testing.assert_array_almost_equal(sum_zero_mean.eval(), [0, 0, 1, 1], decimal=1) + sampled_zero = self.sampler.convert(sum_zero) + + np.testing.assert_array_almost_equal( + (converted_meas @ sampled_zero).eval(), [0, 0, 1, 1], decimal=1 + ) for i, op in enumerate(paulis_op.oplist): mat_op = op.to_matrix() @@ -120,13 +131,13 @@ def test_pauli_expect_op_vector(self): def test_pauli_expect_state_vector(self): """pauli expect state vector test""" - states_op = ListOp([One, Zero, Plus, Minus]) + states_op = ListOp([One, Zero, Plus, Minus]) paulis_op = X converted_meas = self.expect.convert(~StateFn(paulis_op) @ states_op) np.testing.assert_array_almost_equal(converted_meas.eval(), [0, 0, 1, -1], decimal=1) - - sampled = self.sampler.convert(converted_meas) + with self.assertWarns(DeprecationWarning): + sampled = self.sampler.convert(converted_meas) np.testing.assert_array_almost_equal(sampled.eval(), [0, 0, 1, -1], decimal=1) # Small test to see if execution results are accessible @@ -135,29 +146,36 @@ def test_pauli_expect_state_vector(self): def test_pauli_expect_op_vector_state_vector(self): """pauli expect op vector state vector test""" + paulis_op = ListOp([X, Y, Z, I]) states_op = ListOp([One, Zero, Plus, Minus]) valids = [[+0, 0, 1, -1], [+0, 0, 0, 0], [-1, 1, 0, -0], [+1, 1, 1, 1]] converted_meas = self.expect.convert(~StateFn(paulis_op)) np.testing.assert_array_almost_equal((converted_meas @ states_op).eval(), valids, decimal=1) + with self.assertWarns(DeprecationWarning): + sampled = self.sampler.convert(states_op) - sampled = self.sampler.convert(states_op) np.testing.assert_array_almost_equal((converted_meas @ sampled).eval(), valids, decimal=1) def test_multi_representation_ops(self): """Test observables with mixed representations""" + mixed_ops = ListOp([X.to_matrix_op(), H, H + I, X]) converted_meas = self.expect.convert(~StateFn(mixed_ops)) plus_mean = converted_meas @ Plus - sampled_plus = self.sampler.convert(plus_mean) + + with self.assertWarns(DeprecationWarning): + sampled_plus = self.sampler.convert(plus_mean) + np.testing.assert_array_almost_equal( sampled_plus.eval(), [1, 0.5**0.5, (1 + 0.5**0.5), 1], decimal=1 ) def test_matrix_expectation_non_hermite_op(self): """Test MatrixExpectation for non hermitian operator""" + exp = ~StateFn(1j * Z) @ One self.assertEqual(self.expect.convert(exp).eval(), 1j) diff --git a/test/python/opflow/test_pauli_expectation.py b/test/python/opflow/test_pauli_expectation.py index f346fa25e80f..f50ddc347b62 100644 --- a/test/python/opflow/test_pauli_expectation.py +++ b/test/python/opflow/test_pauli_expectation.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2018, 2021. +# (C) Copyright IBM 2018, 2023. # # 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 @@ -50,23 +50,29 @@ def setUp(self) -> None: super().setUp() self.seed = 97 backend = BasicAer.get_backend("qasm_simulator") - q_instance = QuantumInstance(backend, seed_simulator=self.seed, seed_transpiler=self.seed) - self.sampler = CircuitSampler(q_instance, attach_results=True) + with self.assertWarns(DeprecationWarning): + q_instance = QuantumInstance( + backend, seed_simulator=self.seed, seed_transpiler=self.seed + ) + self.sampler = CircuitSampler(q_instance, attach_results=True) self.expect = PauliExpectation() def test_pauli_expect_pair(self): """pauli expect pair test""" + op = Z ^ Z # wf = (Pl^Pl) + (Ze^Ze) wf = CX @ (H ^ I) @ Zero converted_meas = self.expect.convert(~StateFn(op) @ wf) self.assertAlmostEqual(converted_meas.eval(), 0, delta=0.1) - sampled = self.sampler.convert(converted_meas) + with self.assertWarns(DeprecationWarning): + sampled = self.sampler.convert(converted_meas) self.assertAlmostEqual(sampled.eval(), 0, delta=0.1) def test_pauli_expect_single(self): """pauli expect single test""" + paulis = [Z, X, Y, I] states = [Zero, One, Plus, Minus, S @ Plus, S @ Minus] for pauli, state in itertools.product(paulis, states): @@ -74,33 +80,42 @@ def test_pauli_expect_single(self): matmulmean = state.adjoint().to_matrix() @ pauli.to_matrix() @ state.to_matrix() self.assertAlmostEqual(converted_meas.eval(), matmulmean, delta=0.1) - sampled = self.sampler.convert(converted_meas) + with self.assertWarns(DeprecationWarning): + sampled = self.sampler.convert(converted_meas) + self.assertAlmostEqual(sampled.eval(), matmulmean, delta=0.1) def test_pauli_expect_op_vector(self): """pauli expect op vector test""" + paulis_op = ListOp([X, Y, Z, I]) converted_meas = self.expect.convert(~StateFn(paulis_op)) plus_mean = converted_meas @ Plus np.testing.assert_array_almost_equal(plus_mean.eval(), [1, 0, 0, 1], decimal=1) - sampled_plus = self.sampler.convert(plus_mean) - np.testing.assert_array_almost_equal(sampled_plus.eval(), [1, 0, 0, 1], decimal=1) - - minus_mean = converted_meas @ Minus - np.testing.assert_array_almost_equal(minus_mean.eval(), [-1, 0, 0, 1], decimal=1) - sampled_minus = self.sampler.convert(minus_mean) - np.testing.assert_array_almost_equal(sampled_minus.eval(), [-1, 0, 0, 1], decimal=1) - - zero_mean = converted_meas @ Zero - np.testing.assert_array_almost_equal(zero_mean.eval(), [0, 0, 1, 1], decimal=1) - sampled_zero = self.sampler.convert(zero_mean) - np.testing.assert_array_almost_equal(sampled_zero.eval(), [0, 0, 1, 1], decimal=1) - - sum_zero = (Plus + Minus) * (0.5**0.5) - sum_zero_mean = converted_meas @ sum_zero - np.testing.assert_array_almost_equal(sum_zero_mean.eval(), [0, 0, 1, 1], decimal=1) - sampled_zero_mean = self.sampler.convert(sum_zero_mean) + + with self.assertWarns(DeprecationWarning): + sampled_plus = self.sampler.convert(plus_mean) + np.testing.assert_array_almost_equal(sampled_plus.eval(), [1, 0, 0, 1], decimal=1) + + minus_mean = converted_meas @ Minus + np.testing.assert_array_almost_equal(minus_mean.eval(), [-1, 0, 0, 1], decimal=1) + + sampled_minus = self.sampler.convert(minus_mean) + np.testing.assert_array_almost_equal(sampled_minus.eval(), [-1, 0, 0, 1], decimal=1) + + zero_mean = converted_meas @ Zero + np.testing.assert_array_almost_equal(zero_mean.eval(), [0, 0, 1, 1], decimal=1) + + sampled_zero = self.sampler.convert(zero_mean) + np.testing.assert_array_almost_equal(sampled_zero.eval(), [0, 0, 1, 1], decimal=1) + + sum_zero = (Plus + Minus) * (0.5**0.5) + sum_zero_mean = converted_meas @ sum_zero + np.testing.assert_array_almost_equal(sum_zero_mean.eval(), [0, 0, 1, 1], decimal=1) + + sampled_zero_mean = self.sampler.convert(sum_zero_mean) + # !!NOTE!!: Depolarizing channel (Sampling) means interference # does not happen between circuits in sum, so expectation does # not equal expectation for Zero!! @@ -126,13 +141,16 @@ def test_pauli_expect_op_vector(self): def test_pauli_expect_state_vector(self): """pauli expect state vector test""" + states_op = ListOp([One, Zero, Plus, Minus]) paulis_op = X converted_meas = self.expect.convert(~StateFn(paulis_op) @ states_op) np.testing.assert_array_almost_equal(converted_meas.eval(), [0, 0, 1, -1], decimal=1) - sampled = self.sampler.convert(converted_meas) + with self.assertWarns(DeprecationWarning): + sampled = self.sampler.convert(converted_meas) + np.testing.assert_array_almost_equal(sampled.eval(), [0, 0, 1, -1], decimal=1) # Small test to see if execution results are accessible @@ -141,6 +159,7 @@ def test_pauli_expect_state_vector(self): def test_pauli_expect_op_vector_state_vector(self): """pauli expect op vector state vector test""" + paulis_op = ListOp([X, Y, Z, I]) states_op = ListOp([One, Zero, Plus, Minus]) @@ -148,12 +167,15 @@ def test_pauli_expect_op_vector_state_vector(self): converted_meas = self.expect.convert(~StateFn(paulis_op) @ states_op) np.testing.assert_array_almost_equal(converted_meas.eval(), valids, decimal=1) - sampled = self.sampler.convert(converted_meas) + with self.assertWarns(DeprecationWarning): + sampled = self.sampler.convert(converted_meas) + np.testing.assert_array_almost_equal(sampled.eval(), valids, decimal=1) def test_to_matrix_called(self): """test to matrix called in different situations""" qs = 45 + states_op = ListOp([Zero ^ qs, One ^ qs, (Zero ^ qs) + (One ^ qs)]) paulis_op = ListOp([Z ^ qs, (I ^ Z ^ I) ^ int(qs / 3)]) @@ -189,6 +211,7 @@ def test_not_to_matrix_called(self): def test_grouped_pauli_expectation(self): """grouped pauli expectation test""" + two_qubit_H2 = ( (-1.052373245772859 * I ^ I) + (0.39793742484318045 * I ^ Z) @@ -203,14 +226,18 @@ def test_grouped_pauli_expectation(self): self.assertEqual(num_circuits_ungrouped, 5) expect_op_grouped = PauliExpectation(group_paulis=True).convert(~StateFn(two_qubit_H2) @ wf) - q_instance = QuantumInstance( - BasicAer.get_backend("statevector_simulator"), - seed_simulator=self.seed, - seed_transpiler=self.seed, - ) - sampler = CircuitSampler(q_instance) - sampler._extract_circuitstatefns(expect_op_grouped) - num_circuits_grouped = len(sampler._circuit_ops_cache) + + with self.assertWarns(DeprecationWarning): + q_instance = QuantumInstance( + BasicAer.get_backend("statevector_simulator"), + seed_simulator=self.seed, + seed_transpiler=self.seed, + ) + + sampler = CircuitSampler(q_instance) + sampler._extract_circuitstatefns(expect_op_grouped) + num_circuits_grouped = len(sampler._circuit_ops_cache) + self.assertEqual(num_circuits_grouped, 2) @unittest.skip(reason="IBMQ testing not available in general.") @@ -220,34 +247,43 @@ def test_ibmq_grouped_pauli_expectation(self): p = IBMQ.load_account() backend = p.get_backend("ibmq_qasm_simulator") - q_instance = QuantumInstance(backend, seed_simulator=self.seed, seed_transpiler=self.seed) + with self.assertWarns(DeprecationWarning): + q_instance = QuantumInstance( + backend, seed_simulator=self.seed, seed_transpiler=self.seed + ) paulis_op = ListOp([X, Y, Z, I]) states_op = ListOp([One, Zero, Plus, Minus]) valids = [[+0, 0, 1, -1], [+0, 0, 0, 0], [-1, 1, 0, -0], [+1, 1, 1, 1]] converted_meas = self.expect.convert(~StateFn(paulis_op) @ states_op) - sampled = CircuitSampler(q_instance).convert(converted_meas) - np.testing.assert_array_almost_equal(sampled.eval(), valids, decimal=1) + + with self.assertWarns(DeprecationWarning): + sampled = CircuitSampler(q_instance).convert(converted_meas) + np.testing.assert_array_almost_equal(sampled.eval(), valids, decimal=1) def test_multi_representation_ops(self): """Test observables with mixed representations""" + mixed_ops = ListOp([X.to_matrix_op(), H, H + I, X]) converted_meas = self.expect.convert(~StateFn(mixed_ops)) - plus_mean = converted_meas @ Plus - sampled_plus = self.sampler.convert(plus_mean) + + with self.assertWarns(DeprecationWarning): + sampled_plus = self.sampler.convert(plus_mean) np.testing.assert_array_almost_equal( sampled_plus.eval(), [1, 0.5**0.5, (1 + 0.5**0.5), 1], decimal=1 ) def test_pauli_expectation_non_hermite_op(self): """Test PauliExpectation for non hermitian operator""" + exp = ~StateFn(1j * Z) @ One self.assertEqual(self.expect.convert(exp).eval(), 1j) def test_list_pauli_sum_op(self): """Test PauliExpectation for List[PauliSumOp]""" + test_op = ListOp([~StateFn(PauliSumOp.from_list([("XX", 1), ("ZI", 3), ("ZZ", 5)]))]) observable = self.expect.convert(test_op) self.assertIsInstance(observable, ListOp) @@ -256,14 +292,17 @@ def test_list_pauli_sum_op(self): def test_expectation_with_coeff(self): """Test PauliExpectation with coefficients.""" + with self.subTest("integer coefficients"): exp = 3 * ~StateFn(X) @ (2 * Minus) - target = self.sampler.convert(self.expect.convert(exp)).eval() + with self.assertWarns(DeprecationWarning): + target = self.sampler.convert(self.expect.convert(exp)).eval() self.assertEqual(target, -12) with self.subTest("complex coefficients"): exp = 3j * ~StateFn(X) @ (2j * Minus) - target = self.sampler.convert(self.expect.convert(exp)).eval() + with self.assertWarns(DeprecationWarning): + target = self.sampler.convert(self.expect.convert(exp)).eval() self.assertEqual(target, -12j) diff --git a/test/python/opflow/test_state_op_meas_evals.py b/test/python/opflow/test_state_op_meas_evals.py index 6a9f2fee5f02..e6d23390ea78 100644 --- a/test/python/opflow/test_state_op_meas_evals.py +++ b/test/python/opflow/test_state_op_meas_evals.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2018, 2021. +# (C) Copyright IBM 2018, 2023. # # 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 @@ -43,6 +43,7 @@ def test_statefn_overlaps(self): def test_wf_evals_x(self): """wf evals x test""" qbits = 4 + wf = ((Zero ^ qbits) + (One ^ qbits)) * (1 / 2**0.5) # Note: wf = Plus^qbits fails because TensoredOp can't handle it. wf_vec = StateFn(wf.to_matrix()) @@ -76,17 +77,20 @@ def test_coefficients_correctly_propagated(self): self.assertEqual((~StateFn(op) @ state).eval(), 0j) backend = Aer.get_backend("aer_simulator") - q_instance = QuantumInstance(backend, seed_simulator=97, seed_transpiler=97) + with self.assertWarns(DeprecationWarning): + q_instance = QuantumInstance(backend, seed_simulator=97, seed_transpiler=97) op = I with self.subTest("zero coeff in summed StateFn and CircuitSampler"): - state = 0 * (Plus + Minus) - sampler = CircuitSampler(q_instance).convert(~StateFn(op) @ state) - self.assertEqual(sampler.eval(), 0j) + with self.assertWarns(DeprecationWarning): + state = 0 * (Plus + Minus) + sampler = CircuitSampler(q_instance).convert(~StateFn(op) @ state) + self.assertEqual(sampler.eval(), 0j) with self.subTest("coeff gets squared in CircuitSampler shot-based readout"): - state = (Plus + Minus) / numpy.sqrt(2) - sampler = CircuitSampler(q_instance).convert(~StateFn(op) @ state) - self.assertAlmostEqual(sampler.eval(), 1 + 0j) + with self.assertWarns(DeprecationWarning): + state = (Plus + Minus) / numpy.sqrt(2) + sampler = CircuitSampler(q_instance).convert(~StateFn(op) @ state) + self.assertAlmostEqual(sampler.eval(), 1 + 0j) def test_is_measurement_correctly_propagated(self): """Test if is_measurement property of StateFn is propagated to converted StateFn.""" @@ -96,10 +100,12 @@ def test_is_measurement_correctly_propagated(self): self.skipTest(f"Aer doesn't appear to be installed. Error: '{str(ex)}'") return backend = Aer.get_backend("aer_simulator") - q_instance = QuantumInstance(backend) # no seeds needed since no values are compared - state = Plus - sampler = CircuitSampler(q_instance).convert(~state @ state) - self.assertTrue(sampler.oplist[0].is_measurement) + + with self.assertWarns(DeprecationWarning): + q_instance = QuantumInstance(backend) # no seeds needed since no values are compared + state = Plus + sampler = CircuitSampler(q_instance).convert(~state @ state) + self.assertTrue(sampler.oplist[0].is_measurement) def test_parameter_binding_on_listop(self): """Test passing a ListOp with differing parameters works with the circuit sampler.""" @@ -117,16 +123,17 @@ def test_parameter_binding_on_listop(self): circuit3 = QuantumCircuit(1) circuit3.p(y, 0) - bindings = {x: -0.4, y: 0.4} - listop = ListOp([StateFn(circuit) for circuit in [circuit1, circuit2, circuit3]]) - - sampler = CircuitSampler(Aer.get_backend("aer_simulator")) - sampled = sampler.convert(listop, params=bindings) + with self.assertWarns(DeprecationWarning): + bindings = {x: -0.4, y: 0.4} + listop = ListOp([StateFn(circuit) for circuit in [circuit1, circuit2, circuit3]]) + sampler = CircuitSampler(Aer.get_backend("aer_simulator")) + sampled = sampler.convert(listop, params=bindings) self.assertTrue(all(len(op.parameters) == 0 for op in sampled.oplist)) def test_list_op_eval_coeff_with_nonlinear_combofn(self): """Test evaluating a ListOp with non-linear combo function works with coefficients.""" + state = One op = ListOp(5 * [I], coeff=2, combo_fn=numpy.prod) expr1 = ~StateFn(op) @ state @@ -147,11 +154,11 @@ def test_single_parameter_binds(self): x = Parameter("x") circuit = QuantumCircuit(1) circuit.ry(x, 0) - expr = ~StateFn(H) @ StateFn(circuit) - - sampler = CircuitSampler(Aer.get_backend("aer_simulator_statevector")) - res = sampler.convert(expr, params={x: 0}).eval() + with self.assertWarns(DeprecationWarning): + expr = ~StateFn(H) @ StateFn(circuit) + sampler = CircuitSampler(Aer.get_backend("aer_simulator_statevector")) + res = sampler.convert(expr, params={x: 0}).eval() self.assertIsInstance(res, complex) @@ -167,15 +174,17 @@ def test_circuit_sampler_caching(self, caching): x = Parameter("x") circuit = QuantumCircuit(1) circuit.ry(x, 0) - expr1 = ~StateFn(H) @ StateFn(circuit) - expr2 = ~StateFn(X) @ StateFn(circuit) - sampler = CircuitSampler(Aer.get_backend("aer_simulator_statevector"), caching=caching) + with self.assertWarns(DeprecationWarning): - res1 = sampler.convert(expr1, params={x: 0}).eval() - res2 = sampler.convert(expr2, params={x: 0}).eval() - res3 = sampler.convert(expr1, params={x: 0}).eval() - res4 = sampler.convert(expr2, params={x: 0}).eval() + expr1 = ~StateFn(H) @ StateFn(circuit) + expr2 = ~StateFn(X) @ StateFn(circuit) + sampler = CircuitSampler(Aer.get_backend("aer_simulator_statevector"), caching=caching) + + res1 = sampler.convert(expr1, params={x: 0}).eval() + res2 = sampler.convert(expr2, params={x: 0}).eval() + res3 = sampler.convert(expr1, params={x: 0}).eval() + res4 = sampler.convert(expr2, params={x: 0}).eval() self.assertEqual(res1, res3) self.assertEqual(res2, res4) @@ -201,9 +210,10 @@ def test_evaluating_nonunitary_circuit_state(self): """ circuit = QuantumCircuit(1) circuit.initialize([0, 1], [0]) - op = Z + op = Z res = (~StateFn(op) @ StateFn(circuit)).eval() + self.assertAlmostEqual(-1 + 0j, res) def test_quantum_instance_with_backend_shots(self): @@ -214,12 +224,15 @@ def test_quantum_instance_with_backend_shots(self): self.skipTest(f"Aer doesn't appear to be installed. Error: '{str(ex)}'") backend = AerSimulator(shots=10) - sampler = CircuitSampler(backend) - res = sampler.convert(~Plus @ Plus).eval() + + with self.assertWarns(DeprecationWarning): + sampler = CircuitSampler(backend) + res = sampler.convert(~Plus @ Plus).eval() self.assertAlmostEqual(res, 1 + 0j, places=2) def test_adjoint_vector_to_circuit_fn(self): """Test it is possible to adjoint a VectorStateFn that was converted to a CircuitStateFn.""" + left = StateFn([0, 1]) left_circuit = left.to_circuit_op().primitive diff --git a/test/python/result/test_sampled_expval.py b/test/python/result/test_sampled_expval.py index 65ebc3dd966f..f7cb06c5b86b 100644 --- a/test/python/result/test_sampled_expval.py +++ b/test/python/result/test_sampled_expval.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2017, 2018. +# (C) Copyright IBM 2017, 2023. # # 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 @@ -13,7 +13,6 @@ """Tests for qiskit.quantum_info.analysis""" import unittest - from qiskit.result import Counts, QuasiDistribution, ProbDistribution, sampled_expectation_value from qiskit.quantum_info import Pauli, SparsePauliOp from qiskit.opflow import PauliOp, PauliSumOp @@ -83,11 +82,13 @@ def test_same(self): exp2 = sampled_expectation_value(counts, Pauli(oper)) self.assertAlmostEqual(exp2, ans) - exp3 = sampled_expectation_value(counts, PauliOp(Pauli(oper))) + with self.assertWarns(DeprecationWarning): + exp3 = sampled_expectation_value(counts, PauliOp(Pauli(oper))) self.assertAlmostEqual(exp3, ans) spo = SparsePauliOp([oper], coeffs=[1]) - exp4 = sampled_expectation_value(counts, PauliSumOp(spo, coeff=2)) + with self.assertWarns(DeprecationWarning): + exp4 = sampled_expectation_value(counts, PauliSumOp(spo, coeff=2)) self.assertAlmostEqual(exp4, 2 * ans) exp5 = sampled_expectation_value(counts, SparsePauliOp.from_list([[oper, 1]])) diff --git a/test/python/transpiler/test_swap_strategy_router.py b/test/python/transpiler/test_swap_strategy_router.py index 7f5291fd0ee3..67f746d66724 100644 --- a/test/python/transpiler/test_swap_strategy_router.py +++ b/test/python/transpiler/test_swap_strategy_router.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2022. +# (C) Copyright IBM 2022, 2023. # # 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 @@ -21,8 +21,7 @@ from qiskit.circuit.library.n_local import QAOAAnsatz from qiskit.converters import circuit_to_dag from qiskit.exceptions import QiskitError -from qiskit.opflow import PauliSumOp -from qiskit.quantum_info import Pauli +from qiskit.quantum_info import Pauli, SparsePauliOp from qiskit.transpiler.passes import FullAncillaAllocation from qiskit.transpiler.passes import EnlargeWithAncilla from qiskit.transpiler.passes import ApplyLayout @@ -77,7 +76,7 @@ def test_basic_zz(self): """ - op = PauliSumOp.from_list([("IZZI", 1), ("ZIIZ", 2), ("ZIZI", 3)]) + op = SparsePauliOp.from_list([("IZZI", 1), ("ZIIZ", 2), ("ZIZI", 3)]) circ = QuantumCircuit(4) circ.append(PauliEvolutionGate(op, 1), range(4)) @@ -113,7 +112,7 @@ def test_basic_xx(self): └─────────────────┘ └────────────────┘ """ - op = PauliSumOp.from_list([("XXII", -1), ("IIXX", 1), ("XIIX", -2), ("IXIX", 2)]) + op = SparsePauliOp.from_list([("XXII", -1), ("IIXX", 1), ("XIIX", -2), ("IXIX", 2)]) circ = QuantumCircuit(4) circ.append(PauliEvolutionGate(op, 3), range(4)) @@ -150,7 +149,8 @@ def test_idle_qubit(self): q_3: ───────────────────────────────────────── """ - op = PauliSumOp.from_list([("IIXX", 1), ("IXIX", 2)]) + + op = SparsePauliOp.from_list([("IIXX", 1), ("IXIX", 2)]) cmap = CouplingMap(couplinglist=[(0, 1), (1, 2), (2, 3)]) swap_strat = SwapStrategy(cmap, swap_layers=(((0, 1),),)) @@ -191,7 +191,7 @@ def test_basic_xx_with_measure(self): 0 1 2 3 """ - op = PauliSumOp.from_list([("XXII", -1), ("IIXX", 1), ("XIIX", -2), ("IXIX", 2)]) + op = SparsePauliOp.from_list([("XXII", -1), ("IIXX", 1), ("XIIX", -2), ("IXIX", 2)]) circ = QuantumCircuit(4, 4) circ.append(PauliEvolutionGate(op, 3), range(4)) @@ -258,10 +258,10 @@ def test_qaoa(self): for idx in range(4): mixer.ry(-idx, idx) - op = PauliSumOp.from_list([("IZZI", 1), ("ZIIZ", 2), ("ZIZI", 3)]) + op = SparsePauliOp.from_list([("IZZI", 1), ("ZIIZ", 2), ("ZIZI", 3)]) circ = QAOAAnsatz(op, reps=2, mixer_operator=mixer) - swapped = self.pm_.run(circ.decompose()) + param_dict = {p: idx + 1 for idx, p in enumerate(swapped.parameters)} swapped.assign_parameters(param_dict, inplace=True) @@ -303,7 +303,7 @@ def test_enlarge_with_ancilla(self): """This pass tests that idle qubits after an embedding are left idle.""" # Create a four qubit problem. - op = PauliSumOp.from_list([("IZZI", 1), ("ZIIZ", 2), ("ZIZI", 3)]) + op = SparsePauliOp.from_list([("IZZI", 1), ("ZIIZ", 2), ("ZIZI", 3)]) circ = QuantumCircuit(4) circ.append(PauliEvolutionGate(op, 1), range(4)) @@ -380,7 +380,7 @@ def test_ccx(self): Commuting2qGateRouter(swap_strat), ] ) - op = PauliSumOp.from_list([("IZZ", 1), ("ZIZ", 2)]) + op = SparsePauliOp.from_list([("IZZ", 1), ("ZIZ", 2)]) circ = QuantumCircuit(4) circ.append(PauliEvolutionGate(op, 1), range(3)) circ.ccx(0, 2, 1) @@ -425,7 +425,7 @@ def test_t_device(self): swap_strat = SwapStrategy(cmap, swaps) # A dense Pauli op. - op = PauliSumOp.from_list( + op = SparsePauliOp.from_list( [ ("IIIZZ", 1), ("IIZIZ", 2), @@ -495,7 +495,8 @@ def inst_info(op, qargs, qreg): def test_single_qubit_circuit(self): """Test that a circuit with only single qubit gates is left unchanged.""" - op = PauliSumOp.from_list([("IIIX", 1), ("IIXI", 2), ("IZII", 3), ("XIII", 4)]) + + op = SparsePauliOp.from_list([("IIIX", 1), ("IIXI", 2), ("IZII", 3), ("XIII", 4)]) circ = QuantumCircuit(4) circ.append(PauliEvolutionGate(op, 1), range(4)) @@ -508,7 +509,8 @@ def test_single_qubit_circuit(self): ) def test_edge_coloring(self, edge_coloring): """Test that the edge coloring works.""" - op = PauliSumOp.from_list([("IIZZ", 1), ("IZZI", 2), ("ZZII", 3), ("ZIZI", 4)]) + + op = SparsePauliOp.from_list([("IIZZ", 1), ("IZZI", 2), ("ZZII", 3), ("ZIZI", 4)]) swaps = (((1, 2),),) cmap = CouplingMap([[0, 1], [1, 2], [2, 3]]) @@ -572,7 +574,7 @@ def setUp(self): super().setUp() # A fully connected problem. - op = PauliSumOp.from_list( + op = SparsePauliOp.from_list( [("IIZZ", 1), ("IZIZ", 1), ("ZIIZ", 1), ("IZZI", 1), ("ZIZI", 1), ("ZZII", 1)] ) self.circ = QuantumCircuit(4) diff --git a/test/python/utils/mitigation/test_meas.py b/test/python/utils/mitigation/test_meas.py index 21c6322b09bd..a5105b5ba4d5 100644 --- a/test/python/utils/mitigation/test_meas.py +++ b/test/python/utils/mitigation/test_meas.py @@ -1,6 +1,6 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2021. +# (C) Copyright IBM 2021, 2023. # # 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 @@ -46,9 +46,9 @@ if optionals.HAS_AER: # pylint: disable=no-name-in-module - from qiskit.providers.aer import Aer - from qiskit.providers.aer.noise import NoiseModel - from qiskit.providers.aer.noise.errors.standard_errors import pauli_error + from qiskit_aer import AerSimulator + from qiskit_aer.noise import NoiseModel + from qiskit_aer.noise.errors.standard_errors import pauli_error # fixed seed for tests - for both simulator and transpiler SEED = 42 @@ -156,7 +156,7 @@ def meas_calibration_circ_execution(shots: int, seed: int): noise_model.add_all_qubit_quantum_error(error_meas, "measure") # run the circuits multiple times - backend = qiskit.Aer.get_backend("qasm_simulator") + backend = AerSimulator() cal_results = qiskit.execute( meas_calibs, backend=backend, shots=shots, noise_model=noise_model, seed_simulator=seed ).result() @@ -193,7 +193,7 @@ def tensored_calib_circ_execution(shots: int, seed: int): noise_model.add_all_qubit_quantum_error(error_meas, "measure") # run the circuits multiple times - backend = qiskit.Aer.get_backend("qasm_simulator") + backend = AerSimulator() cal_results = qiskit.execute( meas_calibs, backend=backend, shots=shots, noise_model=noise_model, seed_simulator=seed ).result() @@ -278,16 +278,20 @@ def test_ideal_meas_cal(self): # Generate the quantum register according to the pattern qubits, weight = self.choose_calibration(nq, pattern_type) - # Generate the calibration circuits - meas_calibs, state_labels = complete_meas_cal(qubit_list=qubits, circlabel="test") + with self.assertWarns(DeprecationWarning): + # Generate the calibration circuits + meas_calibs, state_labels = complete_meas_cal( + qubit_list=qubits, circlabel="test" + ) # Perform an ideal execution on the generated circuits - backend = Aer.get_backend("qasm_simulator") + backend = AerSimulator() job = qiskit.execute(meas_calibs, backend=backend, shots=self.shots) cal_results = job.result() - # Make a calibration matrix - meas_cal = CompleteMeasFitter(cal_results, state_labels, circlabel="test") + with self.assertWarns(DeprecationWarning): + # Make a calibration matrix + meas_cal = CompleteMeasFitter(cal_results, state_labels, circlabel="test") # Assert that the calibration matrix is equal to identity IdentityMatrix = np.identity(2**weight) @@ -307,8 +311,9 @@ def test_ideal_meas_cal(self): # Generate ideal (equally distributed) results results_dict, results_list = self.generate_ideal_results(state_labels, weight) - # Output the filter - meas_filter = meas_cal.filter + with self.assertWarns(DeprecationWarning): + # Output the filter + meas_filter = meas_cal.filter # Apply the calibration matrix to results # in list and dict forms using different methods @@ -329,10 +334,11 @@ def test_ideal_meas_cal(self): def test_meas_cal_on_circuit(self): """Test an execution on a circuit.""" # Generate the calibration circuits - meas_calibs, state_labels, ghz = meas_calib_circ_creation() + with self.assertWarns(DeprecationWarning): + meas_calibs, state_labels, ghz = meas_calib_circ_creation() # Run the calibration circuits - backend = Aer.get_backend("qasm_simulator") + backend = AerSimulator() job = qiskit.execute( meas_calibs, backend=backend, @@ -342,8 +348,9 @@ def test_meas_cal_on_circuit(self): ) cal_results = job.result() - # Make a calibration matrix - meas_cal = CompleteMeasFitter(cal_results, state_labels) + with self.assertWarns(DeprecationWarning): + # Make a calibration matrix + meas_cal = CompleteMeasFitter(cal_results, state_labels) # Calculate the fidelity fidelity = meas_cal.readout_fidelity() @@ -355,7 +362,8 @@ def test_meas_cal_on_circuit(self): # Predicted equally distributed results predicted_results = {"000": 0.5, "111": 0.5} - meas_filter = meas_cal.filter + with self.assertWarns(DeprecationWarning): + meas_filter = meas_cal.filter # Calculate the results after mitigation output_results_pseudo_inverse = meas_filter.apply( @@ -390,14 +398,16 @@ def test_ideal_tensored_meas_cal(self): meas_layout = [1, 2, 3, 4, 5, 6] # Generate the calibration circuits - meas_calibs, _ = tensored_meas_cal(mit_pattern=mit_pattern) + with self.assertWarns(DeprecationWarning): + meas_calibs, _ = tensored_meas_cal(mit_pattern=mit_pattern) # Perform an ideal execution on the generated circuits - backend = Aer.get_backend("qasm_simulator") + backend = AerSimulator() cal_results = qiskit.execute(meas_calibs, backend=backend, shots=self.shots).result() - # Make calibration matrices - meas_cal = TensoredMeasFitter(cal_results, mit_pattern=mit_pattern) + with self.assertWarns(DeprecationWarning): + # Make calibration matrices + meas_cal = TensoredMeasFitter(cal_results, mit_pattern=mit_pattern) # Assert that the calibration matrices are equal to identity cal_matrices = meas_cal.cal_matrices @@ -419,20 +429,19 @@ def test_ideal_tensored_meas_cal(self): "Error: the average fidelity is not equal to 1", ) - # Generate ideal (equally distributed) results - results_dict, _ = self.generate_ideal_results(count_keys(6), 6) - - # Output the filter - meas_filter = meas_cal.filter - - # Apply the calibration matrix to results - # in list and dict forms using different methods - results_dict_1 = meas_filter.apply( - results_dict, method="least_squares", meas_layout=meas_layout - ) - results_dict_0 = meas_filter.apply( - results_dict, method="pseudo_inverse", meas_layout=meas_layout - ) + with self.assertWarns(DeprecationWarning): + # Generate ideal (equally distributed) results + results_dict, _ = self.generate_ideal_results(count_keys(6), 6) + # Output the filter + meas_filter = meas_cal.filter + # Apply the calibration matrix to results + # in list and dict forms using different methods + results_dict_1 = meas_filter.apply( + results_dict, method="least_squares", meas_layout=meas_layout + ) + results_dict_0 = meas_filter.apply( + results_dict, method="pseudo_inverse", meas_layout=meas_layout + ) # Assert that the results are equally distributed self.assertDictEqual(results_dict, results_dict_0) @@ -444,11 +453,12 @@ def test_ideal_tensored_meas_cal(self): def test_tensored_meas_cal_on_circuit(self): """Test an execution on a circuit.""" - # Generate the calibration circuits - meas_calibs, mit_pattern, ghz, meas_layout = tensored_calib_circ_creation() + with self.assertWarns(DeprecationWarning): + # Generate the calibration circuits + meas_calibs, mit_pattern, ghz, meas_layout = tensored_calib_circ_creation() # Run the calibration circuits - backend = Aer.get_backend("qasm_simulator") + backend = AerSimulator() cal_results = qiskit.execute( meas_calibs, backend=backend, @@ -457,8 +467,9 @@ def test_tensored_meas_cal_on_circuit(self): seed_transpiler=SEED, ).result() - # Make a calibration matrix - meas_cal = TensoredMeasFitter(cal_results, mit_pattern=mit_pattern) + with self.assertWarns(DeprecationWarning): + # Make a calibration matrix + meas_cal = TensoredMeasFitter(cal_results, mit_pattern=mit_pattern) # Calculate the fidelity fidelity = meas_cal.readout_fidelity(0) * meas_cal.readout_fidelity(1) @@ -469,15 +480,15 @@ def test_tensored_meas_cal_on_circuit(self): # Predicted equally distributed results predicted_results = {"000": 0.5, "111": 0.5} - meas_filter = meas_cal.filter - - # Calculate the results after mitigation - output_results_pseudo_inverse = meas_filter.apply( - results, method="pseudo_inverse", meas_layout=meas_layout - ).get_counts(0) - output_results_least_square = meas_filter.apply( - results, method="least_squares", meas_layout=meas_layout - ).get_counts(0) + with self.assertWarns(DeprecationWarning): + meas_filter = meas_cal.filter + # Calculate the results after mitigation + output_results_pseudo_inverse = meas_filter.apply( + results, method="pseudo_inverse", meas_layout=meas_layout + ).get_counts(0) + output_results_least_square = meas_filter.apply( + results, method="least_squares", meas_layout=meas_layout + ).get_counts(0) # Compare with expected fidelity and expected results self.assertAlmostEqual(fidelity, 1.0) @@ -501,89 +512,89 @@ def test_meas_fitter_with_noise(self): """Test the MeasurementFitter with noise.""" tests = [] runs = 3 - for run in range(runs): - cal_results, state_labels, circuit_results = meas_calibration_circ_execution( - 1000, SEED + run - ) - - meas_cal = CompleteMeasFitter(cal_results, state_labels) - meas_filter = MeasurementFilter(meas_cal.cal_matrix, state_labels) - - # Calculate the results after mitigation - results_pseudo_inverse = meas_filter.apply(circuit_results, method="pseudo_inverse") - results_least_square = meas_filter.apply(circuit_results, method="least_squares") - tests.append( - { - "cal_matrix": convert_ndarray_to_list_in_data(meas_cal.cal_matrix), - "fidelity": meas_cal.readout_fidelity(), - "results": circuit_results, - "results_pseudo_inverse": results_pseudo_inverse, - "results_least_square": results_least_square, - } - ) + with self.assertWarns(DeprecationWarning): + for run in range(runs): + cal_results, state_labels, circuit_results = meas_calibration_circ_execution( + 1000, SEED + run + ) - # Set the state labels - state_labels = ["000", "001", "010", "011", "100", "101", "110", "111"] - meas_cal = CompleteMeasFitter(None, state_labels, circlabel="test") + meas_cal = CompleteMeasFitter(cal_results, state_labels) + meas_filter = MeasurementFilter(meas_cal.cal_matrix, state_labels) + + # Calculate the results after mitigation + results_pseudo_inverse = meas_filter.apply(circuit_results, method="pseudo_inverse") + results_least_square = meas_filter.apply(circuit_results, method="least_squares") + tests.append( + { + "cal_matrix": convert_ndarray_to_list_in_data(meas_cal.cal_matrix), + "fidelity": meas_cal.readout_fidelity(), + "results": circuit_results, + "results_pseudo_inverse": results_pseudo_inverse, + "results_least_square": results_least_square, + } + ) + # Set the state labels + state_labels = ["000", "001", "010", "011", "100", "101", "110", "111"] + meas_cal = CompleteMeasFitter(None, state_labels, circlabel="test") - for tst_index, _ in enumerate(tests): - # Set the calibration matrix - meas_cal.cal_matrix = tests[tst_index]["cal_matrix"] - # Calculate the fidelity - fidelity = meas_cal.readout_fidelity() + for tst_index, _ in enumerate(tests): + # Set the calibration matrix + meas_cal.cal_matrix = tests[tst_index]["cal_matrix"] + # Calculate the fidelity + fidelity = meas_cal.readout_fidelity() - meas_filter = MeasurementFilter(tests[tst_index]["cal_matrix"], state_labels) + meas_filter = MeasurementFilter(tests[tst_index]["cal_matrix"], state_labels) - # Calculate the results after mitigation - output_results_pseudo_inverse = meas_filter.apply( - tests[tst_index]["results"], method="pseudo_inverse" - ) - output_results_least_square = meas_filter.apply( - tests[tst_index]["results"], method="least_squares" - ) + # Calculate the results after mitigation + output_results_pseudo_inverse = meas_filter.apply( + tests[tst_index]["results"], method="pseudo_inverse" + ) + output_results_least_square = meas_filter.apply( + tests[tst_index]["results"], method="least_squares" + ) - # Compare with expected fidelity and expected results - self.assertAlmostEqual(fidelity, tests[tst_index]["fidelity"], places=0) - self.assertAlmostEqual( - output_results_pseudo_inverse["000"], - tests[tst_index]["results_pseudo_inverse"]["000"], - places=0, - ) + # Compare with expected fidelity and expected results + self.assertAlmostEqual(fidelity, tests[tst_index]["fidelity"], places=0) + self.assertAlmostEqual( + output_results_pseudo_inverse["000"], + tests[tst_index]["results_pseudo_inverse"]["000"], + places=0, + ) - self.assertAlmostEqual( - output_results_least_square["000"], - tests[tst_index]["results_least_square"]["000"], - places=0, - ) + self.assertAlmostEqual( + output_results_least_square["000"], + tests[tst_index]["results_least_square"]["000"], + places=0, + ) - self.assertAlmostEqual( - output_results_pseudo_inverse["111"], - tests[tst_index]["results_pseudo_inverse"]["111"], - places=0, - ) + self.assertAlmostEqual( + output_results_pseudo_inverse["111"], + tests[tst_index]["results_pseudo_inverse"]["111"], + places=0, + ) - self.assertAlmostEqual( - output_results_least_square["111"], - tests[tst_index]["results_least_square"]["111"], - places=0, - ) + self.assertAlmostEqual( + output_results_least_square["111"], + tests[tst_index]["results_least_square"]["111"], + places=0, + ) def test_tensored_meas_fitter_with_noise(self): """Test the TensoredFitter with noise.""" - cal_results, mit_pattern, circuit_results, meas_layout = tensored_calib_circ_execution( - 1000, SEED - ) - - meas_cal = TensoredMeasFitter(cal_results, mit_pattern=mit_pattern) - meas_filter = meas_cal.filter + with self.assertWarns(DeprecationWarning): + cal_results, mit_pattern, circuit_results, meas_layout = tensored_calib_circ_execution( + 1000, SEED + ) + meas_cal = TensoredMeasFitter(cal_results, mit_pattern=mit_pattern) + meas_filter = meas_cal.filter + # Calculate the results after mitigation + results_pseudo_inverse = meas_filter.apply( + circuit_results.get_counts(), method="pseudo_inverse", meas_layout=meas_layout + ) + results_least_square = meas_filter.apply( + circuit_results.get_counts(), method="least_squares", meas_layout=meas_layout + ) - # Calculate the results after mitigation - results_pseudo_inverse = meas_filter.apply( - circuit_results.get_counts(), method="pseudo_inverse", meas_layout=meas_layout - ) - results_least_square = meas_filter.apply( - circuit_results.get_counts(), method="least_squares", meas_layout=meas_layout - ) saved_info = { "cal_results": cal_results.to_dict(), "results": circuit_results.to_dict(), @@ -597,26 +608,27 @@ def test_tensored_meas_fitter_with_noise(self): saved_info["cal_results"] = Result.from_dict(saved_info["cal_results"]) saved_info["results"] = Result.from_dict(saved_info["results"]) - meas_cal = TensoredMeasFitter( - saved_info["cal_results"], mit_pattern=saved_info["mit_pattern"] - ) + with self.assertWarns(DeprecationWarning): + meas_cal = TensoredMeasFitter( + saved_info["cal_results"], mit_pattern=saved_info["mit_pattern"] + ) + # Calculate the fidelity + fidelity = meas_cal.readout_fidelity(0) * meas_cal.readout_fidelity(1) + # Compare with expected fidelity and expected results - # Calculate the fidelity - fidelity = meas_cal.readout_fidelity(0) * meas_cal.readout_fidelity(1) - # Compare with expected fidelity and expected results self.assertAlmostEqual(fidelity, saved_info["fidelity"], places=0) - meas_filter = meas_cal.filter - - # Calculate the results after mitigation - output_results_pseudo_inverse = meas_filter.apply( - saved_info["results"].get_counts(0), - method="pseudo_inverse", - meas_layout=saved_info["meas_layout"], - ) - output_results_least_square = meas_filter.apply( - saved_info["results"], method="least_squares", meas_layout=saved_info["meas_layout"] - ) + with self.assertWarns(DeprecationWarning): + meas_filter = meas_cal.filter + # Calculate the results after mitigation + output_results_pseudo_inverse = meas_filter.apply( + saved_info["results"].get_counts(0), + method="pseudo_inverse", + meas_layout=saved_info["meas_layout"], + ) + output_results_least_square = meas_filter.apply( + saved_info["results"], method="least_squares", meas_layout=saved_info["meas_layout"] + ) self.assertAlmostEqual( output_results_pseudo_inverse["000"], @@ -643,30 +655,30 @@ def test_tensored_meas_fitter_with_noise(self): ) substates_list = [] - for qubit_list in saved_info["mit_pattern"]: - substates_list.append(count_keys(len(qubit_list))[::-1]) - - fitter_other_order = TensoredMeasFitter( - saved_info["cal_results"], - substate_labels_list=substates_list, - mit_pattern=saved_info["mit_pattern"], - ) + with self.assertWarns(DeprecationWarning): + for qubit_list in saved_info["mit_pattern"]: + substates_list.append(count_keys(len(qubit_list))[::-1]) + fitter_other_order = TensoredMeasFitter( + saved_info["cal_results"], + substate_labels_list=substates_list, + mit_pattern=saved_info["mit_pattern"], + ) fidelity = fitter_other_order.readout_fidelity(0) * meas_cal.readout_fidelity(1) self.assertAlmostEqual(fidelity, saved_info["fidelity"], places=0) - meas_filter = fitter_other_order.filter - - # Calculate the results after mitigation - output_results_pseudo_inverse = meas_filter.apply( - saved_info["results"].get_counts(0), - method="pseudo_inverse", - meas_layout=saved_info["meas_layout"], - ) - output_results_least_square = meas_filter.apply( - saved_info["results"], method="least_squares", meas_layout=saved_info["meas_layout"] - ) + with self.assertWarns(DeprecationWarning): + meas_filter = fitter_other_order.filter + # Calculate the results after mitigation + output_results_pseudo_inverse = meas_filter.apply( + saved_info["results"].get_counts(0), + method="pseudo_inverse", + meas_layout=saved_info["meas_layout"], + ) + output_results_least_square = meas_filter.apply( + saved_info["results"], method="least_squares", meas_layout=saved_info["meas_layout"] + ) self.assertAlmostEqual( output_results_pseudo_inverse["000"],