Algorithms migration guide
Deprecation Notice
This guide precedes the introduction of the V2 primitives interface. Following the introduction of the V2 primitives, some providers have deprecated V1 primitive implementations in favor of the V2 alternatives. If you are interested in following this guide, we recommend combining it with the Migrate to V2 primitives guide to bring your code to the most updated state.
In Qiskit 0.44 and later releases, the qiskit.algorithms
module has been superseded by a new standalone library, qiskit_algorithms
,
available on GitHub and
PyPi. The qiskit.algorithms
module was migrated to a
separate package in order to clarify the purpose of Qiskit and make a distinction between the tools and libraries built on top of it.
If your code used qiskit.algorithms
, follow these steps:
- Check your code for any uses of the
qiskit.algorithms
module. If you are, follow this guide to migrate to the primitives-based implementation. - After updating your code, run
pip install qiskit-algorithms
and update your imports fromqiskit.algorithms
toqiskit_algorithms
.
Background
The qiskit.algorithms
module was originally built on top of the qiskit.opflow
library and the
qiskit.utils.QuantumInstance
utility. The development of the qiskit.primitives
introduced a higher-level execution paradigm, with the Estimator for computing expectation values for observables, and Sampler for executing circuits and returning probability distributions. These tools allowed the qiskit.algorithms
module to be refactored, after which,
qiskit.opflow
and qiskit.utils.QuantumInstance
were deprecated.
The transition away from qiskit.opflow
affects the classes that algorithms use as part of the problem
setup. Most qiskit.opflow
dependencies have a direct qiskit.quantum_info
replacement. One common example is the class qiskit.opflow.primitive_ops.PauliSumOp
, used to define Hamiltonians
(for example, to plug into VQE), which can be replaced by qiskit.quantum_info.SparsePauliOp
.
For information to migrate other qiskit.opflow
objects, refer to the Opflow migration guide.
For further background and detailed migration steps, see these guides:
What has changed
The qiskit.algorithms
module has been fully refactored to use the qiskit.primitives
, for circuit execution, instead of the qiskit.utils.QuantumInstance
, which is now deprecated.
There have been three types of refactoring:
- Algorithms that were refactored in a new location to support
qiskit.primitives
. These algorithms have the same class names as theqiskit.utils.QuantumInstance
-based ones but are in a new subpackage.
Be careful with import paths. The legacy algorithms can still be imported from
qiskit.algorithms
. Until the legacy imports are removed, this convenience import is not available
for the refactored algorithms. Thus, to import the refactored algorithms you must specify the full import path. For example, from qiskit.algorithms.eigensolvers import VQD
.
- Algorithms that were refactored in-place (same namespace) to support both
qiskit.utils.QuantumInstance
andqiskit.primitives
. In the future,qiskit.utils.QuantumInstance
will be removed.
- Algorithms that were deprecated and are now removed entirely from
qiskit.algorithms
. These are algorithms that do not serve as building blocks for applications and are only valuable for education, as described in the following tutorials:
This migration guide focuses on the algorithms with migration alternatives within
qiskit.algorithms
, that is, refactoring types 1 and 2.
How to choose a primitive configuration for your algorithm
The classes in
qiskit.algorithms
are initialized with any implementation of qiskit.primitives.BaseSampler
or qiskit.primitives.BaseEstimator
.
Once you know which primitive you want to use, choose the primitive implementation that meets your needs. For example:
-
For quick prototyping, use the reference implementations of primitives included in Qiskit:
qiskit.primitives.Sampler
andqiskit.primitives.Estimator
. -
For finer algorithm tuning, use a local simulator such as the primitive implementation in Aer:
qiskit_aer.primitives.Sampler
andqiskit_aer.primitives.Estimator
. -
For running on quantum hardware choose from these options:
- Access services with native primitive implementations, such as the Qiskit Runtime service, by using
qiskit_ibm_runtime.Sampler
andqiskit_ibm_runtime.Estimator
. - Wrap any QPU (quantum processing unti) with
Backend
primitives (qiskit.primitives.BackendSampler
andqiskit.primitives.BackendEstimator
). These wrappers implement a primitive interface on top of a backend that only supportsbackend.run()
.
- Access services with native primitive implementations, such as the Qiskit Runtime service, by using
For detailed information and examples, particularly on the use of the Backend
primitives, refer to
the QuantumInstance migration guide.
This guide describes these common configurations for algorithms that determine which primitive import to use:
- Running an algorithm with a statevector simulator when you want the ideal outcome without shot noise. For example, using the
qiskit.opflow
legacyqiskit.opflow.expectations.MatrixExpectation
:
- Reference Primitives with default configuration. See QAOA for an example.
from qiskit.primitives import Sampler, Estimator
- Aer Primitives with statevector simulator. See QAOA for an example.
from qiskit_aer.primitives import Sampler, Estimator
sampler = Sampler(backend_options={"method": "statevector"})
estimator = Estimator(backend_options={"method": "statevector"})
- Running an algorithm using a simulator or device with shot noise. For example, using the
qiskit.opflow
legacyqiskit.opflow.expectations.PauliExpectation
:
- Reference primitives with shots. See the VQE examples.
from qiskit.primitives import Sampler, Estimator
sampler = Sampler(options={"shots": 100})
estimator = Estimator(options={"shots": 100})
# or...
sampler = Sampler()
job = sampler.run(circuits, shots=100)
estimator = Estimator()
job = estimator.run(circuits, observables, shots=100)
- Aer primitives with default configuration. See the VQE examples.
from qiskit_aer.primitives import Sampler, Estimator
- IBM Qiskit Runtime primitives with default configuration. See VQD for an example.
from qiskit_ibm_runtime import Sampler, Estimator
- Running an algorithm on an Aer simulator using a custom instruction. For example, using the
qiskit.opflow
legacyqiskit.opflow.expectations.AerPauliExpectation
.
- Aer Primitives with default options. See TrotterQRTE for examples.
from qiskit_aer.primitives import Sampler, Estimator
sampler = Sampler()
estimator = Estimator()
Minimum Eigensolvers
The minimum eigensolver algorithms were refactored in a new location.
Instead of a qiskit.utils.QuantumInstance
, qiskit.algorithms.minimum_eigensolvers
are now initialized
by using an instance of the qiskit.primitives.Sampler
or qiskit.primitives.Estimator
primitive, depending
on the algorithm. The legacy classes can still be found in qiskit.algorithms.minimum_eigen_solvers
.
For the qiskit.algorithms.minimum_eigensolvers
classes, depending on the import path,
you will access either the primitive-based or the quantum-instance-based implementation. You have to be careful, because the class name does not change.
- Old import (QuantumInstance-based):
from qiskit.algorithms import VQE, QAOA, NumPyMinimumEigensolver
- New import (Primitives-based):
from qiskit.algorithms.minimum_eigensolvers import VQE, SamplingVQE, QAOA, NumPyMinimumEigensolver
VQE
The legacy qiskit.algorithms.minimum_eigen_solvers.VQE
class has now been split according to the use case:
- For general-purpose Hamiltonians, use the Estimator-based
qiskit.algorithms.minimum_eigensolvers.VQE
class. - If you have a diagonal Hamiltonian and want the algorithm to return a sampling of the state, use
the new Sampler-based
qiskit.algorithms.minimum_eigensolvers.SamplingVQE
algorithm. Previously, this was done by using the legacyqiskit.algorithms.minimum_eigen_solvers.VQE
withqiskit.opflow.expectations.CVaRExpectation
.
In addition to taking in an qiskit.primitives.Estimator
instance instead of a qiskit.utils.QuantumInstance
,
the new qiskit.algorithms.minimum_eigensolvers.VQE
signature has undergone the following changes:
- The
expectation
andinclude_custom
parameters have been removed, as this functionality is now defined at the Estimator level. - The
gradient
parameter now takes in an instance of a primitive-based gradient class fromqiskit.algorithms.gradients
instead of the legacyqiskit.opflow.gradients.Gradient
class. - The
max_evals_grouped
parameter has been removed, as it can be set directly on the optimizer class. - The
estimator
,ansatz
andoptimizer
are the only parameters that can be defined positionally (and in this order). All others have become keyword-only arguments.
The new qiskit.algorithms.minimum_eigensolvers.VQEResult
class does not include the state, as
this output was only useful in the case of diagonal operators. However, it is available as part of the new
qiskit.algorithms.minimum_eigensolvers.SamplingVQE
qiskit.algorithms.minimum_eigensolvers.SamplingVQEResult
.
VQE examples
[Legacy] Using QuantumInstance:
from qiskit.algorithms import VQE
from qiskit.algorithms.optimizers import SPSA
from qiskit.circuit.library import TwoLocal
from qiskit.opflow import PauliSumOp
from qiskit.utils import QuantumInstance
from qiskit_aer import AerSimulator
ansatz = TwoLocal(2, 'ry', 'cz')
opt = SPSA(maxiter=50)
# shot-based simulation
backend = AerSimulator()
qi = QuantumInstance(backend=backend, shots=2048, seed_simulator=42)
vqe = VQE(ansatz, optimizer=opt, quantum_instance=qi)
hamiltonian = PauliSumOp.from_list([("XX", 1), ("XY", 1)])
result = vqe.compute_minimum_eigenvalue(hamiltonian)
print(result.eigenvalue)
(-0.9775390625+0j)
[Updated] Using primitives:
from qiskit.algorithms.minimum_eigensolvers import VQE # new import!!!
from qiskit.algorithms.optimizers import SPSA
from qiskit.circuit.library import TwoLocal
from qiskit.quantum_info import SparsePauliOp
from qiskit.primitives import Estimator
from qiskit_aer.primitives import Estimator as AerEstimator
ansatz = TwoLocal(2, 'ry', 'cz')
opt = SPSA(maxiter=50)
# shot-based simulation
estimator = Estimator(options={"shots": 2048})
vqe = VQE(estimator, ansatz, opt)
# another option
aer_estimator = AerEstimator(run_options={"shots": 2048, "seed": 42})
vqe = VQE(aer_estimator, ansatz, opt)
hamiltonian = SparsePauliOp.from_list([("XX", 1), ("XY", 1)])
result = vqe.compute_minimum_eigenvalue(hamiltonian)
print(result.eigenvalue)
-0.986328125
VQE applying CVaR (SamplingVQE) example
[Legacy] Using QuantumInstance:
from qiskit.algorithms import VQE
from qiskit.algorithms.optimizers import SLSQP
from qiskit.circuit.library import TwoLocal
from qiskit.opflow import PauliSumOp, CVaRExpectation
from qiskit.utils import QuantumInstance
from qiskit_aer import AerSimulator
ansatz = TwoLocal(2, 'ry', 'cz')
opt = SLSQP(maxiter=50)
# shot-based simulation
backend = AerSimulator()
qi = QuantumInstance(backend=backend, shots=2048)
expectation = CVaRExpectation(alpha=0.2)
vqe = VQE(ansatz, optimizer=opt, expectation=expectation, quantum_instance=qi)
# diagonal Hamiltonian
hamiltonian = PauliSumOp.from_list([("ZZ",1), ("IZ", -0.5), ("II", 0.12)])
result = vqe.compute_minimum_eigenvalue(hamiltonian)
print(result.eigenvalue.real)
-1.38
[Updated] Using primitives:
from qiskit.algorithms.minimum_eigensolvers import SamplingVQE # new import!!!
from qiskit.algorithms.optimizers import SPSA
from qiskit.circuit.library import TwoLocal
from qiskit.quantum_info import SparsePauliOp
from qiskit.primitives import Sampler
from qiskit_aer.primitives import Sampler as AerSampler
ansatz = TwoLocal(2, 'ry', 'cz')
opt = SPSA(maxiter=50)
# shot-based simulation
sampler = Sampler(options={"shots": 2048})
vqe = SamplingVQE(sampler, ansatz, opt, aggregation=0.2)
# another option
aer_sampler = AerSampler(run_options={"shots": 2048, "seed": 42})
vqe = SamplingVQE(aer_sampler, ansatz, opt, aggregation=0.2)
# diagonal Hamiltonian
hamiltonian = SparsePauliOp.from_list([("ZZ",1), ("IZ", -0.5), ("II", 0.12)])
result = vqe.compute_minimum_eigenvalue(hamiltonian)
print(result.eigenvalue.real)
-1.38
For complete code examples, see the following updated tutorials:
QAOA
The new QAOA only supports diagonal operators. This is because the legacy qiskit.algorithms.minimum_eigen_solvers.QAOA
class extended
qiskit.algorithms.minimum_eigen_solvers.VQE
, but now, qiskit.algorithms.minimum_eigensolvers.QAOA
extends qiskit.algorithms.minimum_eigensolvers.SamplingVQE
.
In addition to taking in a qiskit.primitives.Sampler
instance instead of a qiskit.utils.QuantumInstance
,
the new qiskit.algorithms.minimum_eigensolvers.QAOA
signature has undergone the following changes:
- The
expectation
andinclude_custom
parameters have been removed and theaggregation
parameter has been added. This was previously defined through a customexpectation
parameter. - The
gradient
parameter now takes in an instance of a primitive-based gradient class fromqiskit.algorithms.gradients
instead of the legacyqiskit.opflow.gradients.Gradient
class. - The
max_evals_grouped
parameter has been removed, as it can be set directly on the optimizer class. - The
sampler
andoptimizer
parameters are the only parameters that can be defined positionally (and in this order). All others have become keyword-only arguments.
If you want to run QAOA on a non-diagonal operator, use the qiskit.circuit.library.QAOAAnsatz
with
qiskit.algorithms.minimum_eigensolvers.VQE
, but there will be no state result.
If your application requires the final probability distribution, instantiate SamplerV2
and run it with the optimal circuit after qiskit.algorithms.minimum_eigensolvers.VQE
.
QAOA example
[Legacy] Using QuantumInstance:
from qiskit.algorithms import QAOA
from qiskit.algorithms.optimizers import COBYLA
from qiskit.opflow import PauliSumOp
from qiskit.utils import QuantumInstance
from qiskit_aer import AerSimulator
# exact statevector simulation
backend = AerSimulator()
qi = QuantumInstance(backend=backend, shots=None,
seed_simulator = 42, seed_transpiler = 42,
backend_options={"method": "statevector"})
optimizer = COBYLA()
qaoa = QAOA(optimizer=optimizer, reps=2, quantum_instance=qi)
# diagonal operator
qubit_op = PauliSumOp.from_list([("ZIII", 1),("IZII", 1), ("IIIZ", 1), ("IIZI", 1)])
result = qaoa.compute_minimum_eigenvalue(qubit_op)
print(result.eigenvalue.real)
-4.0
[Updated] Using primitives:
from qiskit.algorithms.minimum_eigensolvers import QAOA
from qiskit.algorithms.optimizers import COBYLA
from qiskit.quantum_info import SparsePauliOp
from qiskit.primitives import Sampler
from qiskit_aer.primitives import Sampler as AerSampler
# exact statevector simulation
sampler = Sampler()
# another option
sampler = AerSampler(backend_options={"method": "statevector"},
run_options={"shots": None, "seed": 42})
optimizer = COBYLA()
qaoa = QAOA(sampler, optimizer, reps=2)
# diagonal operator
qubit_op = SparsePauliOp.from_list([("ZIII", 1),("IZII", 1), ("IIIZ", 1), ("IIZI", 1)])
result = qaoa.compute_minimum_eigenvalue(qubit_op)
print(result.eigenvalue)
-3.999999832366272
For complete code examples, see the updated QAOA tutorial.
NumPyMinimumEigensolver
Because this is a classical solver, the workflow has not changed between the old and new implementation.
However, the import has changed from qiskit.algorithms.minimum_eigen_solvers.NumPyMinimumEigensolver
to qiskit.algorithms.minimum_eigensolvers.NumPyMinimumEigensolver
to conform to the new interfaces
and result classes.
NumPyMinimumEigensolver example
[Legacy] Using QuantumInstance:
from qiskit.algorithms import NumPyMinimumEigensolver
from qiskit.opflow import PauliSumOp
solver = NumPyMinimumEigensolver()
hamiltonian = PauliSumOp.from_list([("XX", 1), ("XY", 1)])
result = solver.compute_minimum_eigenvalue(hamiltonian)
print(result.eigenvalue)
-1.4142135623730958
[Updated] Using primitives:
from qiskit.algorithms.minimum_eigensolvers import NumPyMinimumEigensolver
from qiskit.quantum_info import SparsePauliOp
solver = NumPyMinimumEigensolver()
hamiltonian = SparsePauliOp.from_list([("XX", 1), ("XY", 1)])
result = solver.compute_minimum_eigenvalue(hamiltonian)
print(result.eigenvalue)
-1.414213562373095
For complete code examples, see the updated VQE, callback, gradients, initial point tutorial.
Eigensolvers
The eigensolver algorithms were refactored in a new location. Instead of using
qiskit.utils.QuantumInstance
, qiskit.algorithms.eigensolvers
are now initialized
using an instance of the qiskit.primitives.Sampler
or qiskit.primitives.Estimator
primitive, or
a primitive-based subroutine, depending on the algorithm. The legacy classes can still be found
in qiskit.algorithms.eigen_solvers
.
For the qiskit.algorithms.eigensolvers
classes, depending on the import path,
you will access either the primitive-based or the QuantumInstance-based
implementation. You have to be careful, because the class name is the same.
- Old import path (QuantumInstance):
from qiskit.algorithms import VQD, NumPyEigensolver
- New import path (primitives):
from qiskit.algorithms.eigensolvers import VQD, NumPyEigensolver
VQD
The new qiskit.algorithms.eigensolvers.VQD
class is initialized with an instance of the
qiskit.primitives.Estimator
primitive instead of a qiskit.utils.QuantumInstance
.
It also takes an instance of a state fidelity class from mod:qiskit.algorithms.state_fidelities
,
such as the qiskit.primitives.Sampler
-based qiskit.algorithms.state_fidelities.ComputeUncompute
.
In addition to taking in a qiskit.primitives.Estimator
instance instead of a qiskit.utils.QuantumInstance
,
the new qiskit.algorithms.eigensolvers.VQD
signature has undergone the following changes:
- The
expectation
andinclude_custom
parameters have been removed, as this functionality is now defined at the Estimator level. - The custom
fidelity
parameter has been added and the customgradient
parameter has been removed because current classes inqiskit.algorithms.gradients
cannot use state fidelity gradients. - The
max_evals_grouped
parameter has been removed because it can be set directly on theoptimizer
class. - The
estimator
,fidelity
,ansatz
andoptimizer
parameters are the only parameters that can be defined positionally (and in this order). All others have become keyword-only arguments.
Similar to VQE, the new qiskit.algorithms.eigensolvers.VQDResult
class does not include
the state. If your application requires the final probability distribution, instantiate
SamplerV2
and run it with the optimal circuit for the desired excited state
after running qiskit.algorithms.eigensolvers.VQD
.
VQD Example
[Legacy] Using QuantumInstance:
from qiskit import IBMQ
from qiskit.algorithms import VQD
from qiskit.algorithms.optimizers import SLSQP
from qiskit.circuit.library import TwoLocal
from qiskit.opflow import PauliSumOp
from qiskit.utils import QuantumInstance
ansatz = TwoLocal(3, rotation_blocks=["ry", "rz"], entanglement_blocks="cz", reps=1)
optimizer = SLSQP(maxiter=10)
hamiltonian = PauliSumOp.from_list([("XXZ", 1), ("XYI", 1)])
# example executing in cloud simulator
provider = IBMQ.load_account()
backend = provider.get_backend("ibmq_qasm_simulator")
qi = QuantumInstance(backend=backend)
vqd = VQD(ansatz, k=3, optimizer=optimizer, quantum_instance=qi)
result = vqd.compute_eigenvalues(operator=hamiltonian)
print(result.eigenvalues)
[ 0.01765114+0.0e+00j -0.58507654+0.0e+00j -0.15003642-2.8e-17j]
[Updated] Using primitives:
from qiskit_ibm_runtime import Sampler, Estimator, QiskitRuntimeService, Session
from qiskit.algorithms.eigensolvers import VQD
from qiskit.algorithms.optimizers import SLSQP
from qiskit.algorithms.state_fidelities import ComputeUncompute
from qiskit.circuit.library import TwoLocal
from qiskit.quantum_info import SparsePauliOp
ansatz = TwoLocal(3, rotation_blocks=["ry", "rz"], entanglement_blocks="cz", reps=1)
optimizer = SLSQP(maxiter=10)
hamiltonian = SparsePauliOp.from_list([("XXZ", 1), ("XYI", 1)])
# example executing on a QPU
service = QiskitRuntimeService(channel="ibm_quantum")
backend = service.backend("ibm_sherbrooke")
with Session(backend=backend) as session:
estimator = Estimator()
sampler = Sampler()
fidelity = ComputeUncompute(sampler)
vqd = VQD(estimator, fidelity, ansatz, optimizer, k=3)
result = vqd.compute_eigenvalues(operator=hamiltonian)
print(result.eigenvalues)
[ 0.01765114+0.0e+00j -0.58507654+0.0e+00j -0.15003642-2.8e-17j]
For complete code examples, see the updated VQD tutorial.
NumPyEigensolver
Similarly to its minimum eigensolver counterpart, because this is a classical solver, the workflow has not changed
between the old and new implementation.
However, the import has changed from qiskit.algorithms.eigen_solvers.NumPyEigensolver
to qiskit.algorithms.eigensolvers.NumPyEigensolver
to conform to the new interfaces and result classes.
NumPyEigensolver Example
[Legacy]:
from qiskit.algorithms import NumPyEigensolver
from qiskit.opflow import PauliSumOp
solver = NumPyEigensolver(k=2)
hamiltonian = PauliSumOp.from_list([("XX", 1), ("XY", 1)])
result = solver.compute_eigenvalues(hamiltonian)
print(result.eigenvalues)
[-1.41421356 -1.41421356]
[Updated]:
from qiskit.algorithms.eigensolvers import NumPyEigensolver
from qiskit.quantum_info import SparsePauliOp
solver = NumPyEigensolver(k=2)
hamiltonian = SparsePauliOp.from_list([("XX", 1), ("XY", 1)])
result = solver.compute_eigenvalues(hamiltonian)
print(result.eigenvalues)
[-1.41421356 -1.41421356]
Time Evolvers
The time evolvers were refactored in a new location.
Instead of using a qiskit.utils.QuantumInstance
, qiskit.algorithms.time_evolvers
are now initialized
using a qiskit.primitives.Estimator
primitive instance. The legacy classes can still be found
in qiskit.algorithms.evolvers
.
In addition to the migration, the module has been substantially expanded to include Variational Quantum Time Evolution
(qiskit.algorithms.time_evolvers.VarQTE
) solvers.
TrotterQRTE
For the TrotterQRTE
class, depending on the import path,
you will access either the primitive-based or the QuantumInstance-based
implementation. You have to be careful because the class name did not change.
- Old import path (QuantumInstance):
from qiskit.algorithms import TrotterQRTE
- New import path (Primitives):
from qiskit.algorithms.time_evolvers import TrotterQRTE
In addition to taking in a qiskit.primitives.Estimator
instance instead of a qiskit.utils.QuantumInstance
,
the new qiskit.algorithms.eigensolvers.VQD
signature has undergone the following changes:
- The
expectation
parameter has been removed, as this functionality is now defined at the Estimator level. - The
num_timesteps
parameter has been added so you can define how many steps to divide the full evolution time in to.
TrotterQRTE Example
[Legacy] Using QuantumInstance:
from qiskit.algorithms import EvolutionProblem, TrotterQRTE
from qiskit.circuit import QuantumCircuit
from qiskit.opflow import PauliSumOp, AerPauliExpectation
from qiskit.utils import QuantumInstance
from qiskit_aer import AerSimulator
operator = PauliSumOp.from_list([("X", 1),("Z", 1)])
initial_state = QuantumCircuit(1) # zero
time = 1
evolution_problem = EvolutionProblem(operator, 1, initial_state)
# Aer simulator using custom instruction
backend = AerSimulator()
quantum_instance = QuantumInstance(backend=backend)
expectation = AerPauliExpectation()
# LieTrotter with 1 rep
trotter_qrte = TrotterQRTE(expectation=expectation, quantum_instance=quantum_instance)
evolved_state = trotter_qrte.evolve(evolution_problem).evolved_state
print(evolved_state)
CircuitStateFn(
┌─────────────────────┐
q: ┤ exp(-it (X + Z))(1) ├
└─────────────────────┘
)
[Updated] Using primitives:
from qiskit.algorithms.time_evolvers import TimeEvolutionProblem, TrotterQRTE # note new import!!!
from qiskit.circuit import QuantumCircuit
from qiskit.quantum_info import SparsePauliOp
from qiskit_aer.primitives import Estimator as AerEstimator
operator = SparsePauliOp.from_list([("X", 1),("Z", 1)])
initial_state = QuantumCircuit(1) # zero
time = 1
evolution_problem = TimeEvolutionProblem(operator, 1, initial_state)
# Aer simulator using custom instruction
estimator = AerEstimator()
# LieTrotter with 1 rep
trotter_qrte = TrotterQRTE(estimator=estimator)
evolved_state = trotter_qrte.evolve(evolution_problem).evolved_state
print(evolved_state.decompose())
┌───────────┐┌───────────┐
q: ┤ exp(it X) ├┤ exp(it Z) ├
└───────────┘└───────────┘
Amplitude amplifiers
The amplitude amplifier algorithms were refactored in-place.
Instead of a qiskit.utils.QuantumInstance
, qiskit.algorithms.amplitude_amplifiers
are now initialized
using an instance of any Sampler primitive. That is, qiskit.primitives.Sampler
.
The full qiskit.algorithms.amplitude_amplifiers
module has been refactored in place. Therefore, you don't need to
change import paths.
Grover example
[Legacy] Using QuantumInstance:
from qiskit.algorithms import Grover
from qiskit.utils import QuantumInstance
qi = QuantumInstance(backend=backend)
grover = Grover(quantum_instance=qi)
[Updated] Using primitives:
from qiskit.algorithms import Grover
from qiskit.primitives import Sampler
grover = Grover(sampler=Sampler())
For complete code examples, see the following updated tutorials:
Amplitude estimators
Similarly to the amplitude amplifiers, the amplitude estimators were refactored in-place.
Instead of a qiskit.utils.QuantumInstance
, qiskit.algorithms.amplitude_estimators
are now initialized
using an instance of any Sampler primitive. That is, qiskit.primitives.Sampler
.
The full qiskit.algorithms.amplitude_estimators
module has been refactored in place. You do not need to
change import paths.
IAE example
[Legacy] Using QuantumInstance:
from qiskit.algorithms import IterativeAmplitudeEstimation
from qiskit.utils import QuantumInstance
qi = QuantumInstance(backend=backend)
iae = IterativeAmplitudeEstimation(
epsilon_target=0.01, # target accuracy
alpha=0.05, # width of the confidence interval
quantum_instance=qi
)
[Updated] Using primitives:
from qiskit.algorithms import IterativeAmplitudeEstimation
from qiskit.primitives import Sampler
iae = IterativeAmplitudeEstimation(
epsilon_target=0.01, # target accuracy
alpha=0.05, # width of the confidence interval
sampler=Sampler()
)
For a complete code example, see the updated Amplitude Estimation tutorial.
Phase estimators
The phase estimators were refactored in-place.
Instead of a qiskit.utils.QuantumInstance
, qiskit.algorithms.phase_estimators
are now initialized by
using an instance of any Sampler primitive. That is, qiskit.primitives.Sampler
.
The full qiskit.algorithms.phase_estimators
module has been refactored in place. Therefore, you do not need to change import paths.
IPE example
[Legacy] Using QuantumInstance:
from qiskit.algorithms import IterativePhaseEstimation
from qiskit.utils import QuantumInstance
qi = QuantumInstance(backend=backend)
ipe = IterativePhaseEstimation(
num_iterations=num_iter,
quantum_instance=qi
)
[Updated] Using primitives:
from qiskit.algorithms import IterativePhaseEstimation
from qiskit.primitives import Sampler
ipe = IterativePhaseEstimation(
num_iterations=num_iter,
sampler=Sampler()
)
For a complete code examples, see the updated Iterative phase estimation tutorial.