Solving Problems with v0.5#
Overview#
The major focus of the Qiskit Nature v0.5 refactoring was the
description and representation of second-quantized operators and
problems. Nonetheless, the algorithms module and supporting modules
did also receive significant updates. Most importantly all algorithms In
Nature are now dependent on the new Qiskit Terra algorithms, and these
are now based on Qiskit
Primitives
and were added in Qiskit Terra 0.22. It is not the intention to provide
detailed explanations of the primitives in this migration guide. We
suggest that you read the corresponding
resources
of the Qiskit Terra documentation instead.
Further Resources#
For more details, please refer to the corresponding tutorials:
qiskit_nature.mappers#
The mappers of Qiskit Nature did not receive any API changes (other
than potentially requiring certain arguments to be keywords; see also
the “Too many positional arguments” section).
However, the entire module qiskit_nature.mappers.second_quantization
has been moved to qiskit_nature.second_q.mappers. So updating your
import is all you need to do here.
qiskit_nature.converters#
This module contained a single component: QubitConverter. This has
been moved to qiskit_nature.second_q.mappers.QubitConverter so you
can simply update your import path.
API changes were again minimal but the operators being translated by
this class are no longer the legacy SecondQuantizedOp but rather the
new SparseLabelOp objects.
qiskit_nature.circuit#
The entire qiskit_nature.circuit module was relocated to
qiskit_nature.second_q.circuit. The reason for this, is that the
existing circuit were actually only applicable to second-quantized
applications, but the API did not reflect this. Updating your imports
should fix most issues.
However, there are two more details to take note of, detailed below.
Number of Orbitals#
We have been consistently describing the number of orbitals via
num_spin_orbitals throughout the package. However, what this
oftentimes implied (without rigorous checks) was that an even number
was supplied, since the number of spin orbitals was assumed to equal
twice the number of spatial orbitals.
To be more rigorous and avoid the ill-defined behavior when providing
odd numbers for num_spin_orbitals, we have switched the entire
stack to use num_spatial_orbitals instead. This is well defined for
any positive integer value (and negative values are guarded against).
What this means for you in practice, is that whenever you supply the
num_spin_orbitals manually in the past, you now need to supply
half the value to represent the num_spatial_orbitals.
Previously#
from qiskit_nature.circuit.library import UCCSD
ansatz = UCCSD()
ansatz.num_spin_orbitals = 10
New#
from qiskit_nature.second_q.circuit.library import UCCSD
ansatz = UCCSD()
ansatz.num_spatial_orbitals = 5
UCC/UVCC __init__ arguments#
The UCC and UVCC subclasses used to take the following arguments
for their __init__:
Previously#
from qiskit_nature.circuit.library import UCC, UVCC
ucc = UCC(qubit_converter=None, num_particles=None, num_spin_orbitals=None, excitations=None)
uvcc = UVCC(qubit_converter=None, num_modals=None, excitations=None)
New#
This was mismatching the API of the HartreeFock and VSCF initial
states. We have aligned these APIs to look like in the following:
from qiskit_nature.second_q.circuit.library import UCC, UVCC
ucc = UCC(num_spatial_orbitals=None, num_particles=None, excitations=None, qubit_converter=None)
uvcc = UVCC(num_modals=None, excitations=None, qubit_converter=None)
HartreeFock/VSCF initial states#
The HartreeFock and VSCF initial state circuits are now
implemented as BlueprintCircuit. That means, that you can initialize
them without any arguments and supply the information later as shown
below:
Previously#
from qiskit_nature.circuit.library import HartreeFock, VSCF
from qiskit_nature.converters.second_quantization import QubitConverter
from qiskit_nature.mappers.second_quantization import DirectMapper, JordanWignerMapper
hf = HartreeFock(
num_spin_orbitals=4, num_particles=(1, 1), qubit_converter=QubitConverter(JordanWignerMapper())
)
vscf = VSCF(num_modals=[2, 2])
New#
from qiskit_nature.second_q.circuit.library import HartreeFock, VSCF
from qiskit_nature.second_q.mappers import DirectMapper, JordanWignerMapper, QubitConverter
hf = HartreeFock()
hf.num_spatial_orbitals = 2
hf.num_particles = (1, 1)
hf.qubit_converter = QubitConverter(JordanWignerMapper())
vscf = VSCF()
vscf.num_modals = [2, 2]
qiskit_nature.algorithms#
The algorithms in Qiskit Nature have been updated to use the new
qiskit.algorithms components which are based on the
qiskit.primitives as of Qiskit Terra 0.22.
For most changes to take effect, you can once again simply update your
import paths from qiskit_nature.algorithms to
qiskit_nature.second_q.algorithms. However, there are some details
which you need to pay attention to, due to the change to the
primitive-based algorithms of Qiskit Terra being used under the hood.
These details are explained below.
qiskit_nature.algorithms.initial_points#
This module was moved to
qiskit_nature.second_q.algorithms.initial_points. All you need to do
is update your imports.
qiskit_nature.algorithms.pes_samplers#
This module was removed without a replacement. The reason for that, is that we are working towards a driver-less design of Qiskit Nature, in which case the sampling of the potential energy surface becomes the responsibility of the classical code rather than Qiskit Nature.
qiskit_nature.algorithms.ground_state_solvers#
This module was moved to
qiskit_nature.second_q.algorithms.ground_state_solvers. Besides
updating your imports, you need to pay attention to the following:
AdaptVQEwas migrated to Qiskit Terra:qiskit.algorithms.minimum_eigensolver.AdaptVQE. In doing so, this is no longer aGroundStateSolverbut rather became aMinimumEigensolverwhich means that you would use it like any otherVQEand inject it into aGroundStateSolverof Qiskit Nature. To see the newAdaptVQEin action, check out the How to use the AdaptVQE.the API of the
VQEUCCFactoryandVQEUVCCFactoryhas been matched with the new primitive-basedVQEAPI
Previously#
from qiskit.providers.basicaer import BasicAer
from qiskit.utils import QuantumInstance
from qiskit_nature.algorithms.ground_state_solvers import VQEUCCFactory
quantum_instance = QuantumInstance(BasicAer.get_backend("statevector_simulator"))
vqe_factory = VQEUCCFactory(quantum_instance=quantum_instance)
New#
from qiskit.algorithms.optimizers import SLSQP
from qiskit.primitives import Estimator
from qiskit_nature.second_q.circuit.library import UCCSD
from qiskit_nature.second_q.algorithms.ground_state_solvers import VQEUCCFactory
estimator = Estimator()
ansatz = UCCSD()
optimizer = SLSQP()
vqe_factory = VQEUCCFactory(estimator, ansatz, optimizer)
qiskit_nature.algorithms.excited_states_solvers#
This module was moved to
qiskit_nature.second_q.algorithms.excited_states_solvers. Besides
updating your imports, you need to pay attention to the following:
the
QEOMAPI now also requires an Estimator primitiver to be provided
Previously#
from qiskit_nature.algorithms.ground_state_solvers import GroundStateEigensolver, VQEUCCFactory
from qiskit_nature.algorithms.excited_states_solvers import QEOM
from qiskit_nature.converters.second_quantization import QubitConverter
from qiskit_nature.mappers.second_quantization import JordanWignerMapper
vqe_factory = VQEUCCFactory()
converter = QubitConverter(JordanWignerMapper())
ground_state_solver = GroundStateEigensolver(converter, vqe_factory)
qeom = QEOM(ground_state_solver)
New#
from qiskit.algorithms.optimizers import SLSQP
from qiskit.primitives import Estimator
from qiskit_nature.second_q.circuit.library import UCCSD
from qiskit_nature.second_q.algorithms.ground_state_solvers import (
GroundStateEigensolver,
VQEUCCFactory,
)
from qiskit_nature.second_q.algorithms.excited_states_solvers import QEOM
from qiskit_nature.second_q.mappers import JordanWignerMapper, QubitConverter
estimator = Estimator()
ansatz = UCCSD()
optimizer = SLSQP()
vqe_factory = VQEUCCFactory(estimator, ansatz, optimizer)
converter = QubitConverter(JordanWignerMapper())
ground_state_solver = GroundStateEigensolver(converter, vqe_factory)
qeom = QEOM(ground_state_solver, estimator)