Qiskit Nature 0.7.0
Prelude
Qiskit Nature has been migrated to the qiskit-community Github organization to further emphasize that it is a community-driven project. To reflect this change and because we are onboarding additional codeowners and maintainers, with this version (0.7) we have decided to remove all deprecated code, regardless of the time of its deprecation. This ensures that the new members of the development team do not have a large bulk of legacy code to maintain. This can mean one of two things for you as the end-user:
-
Nothing, if you already migrated your code and no longer rely on any deprecated features.
-
Otherwise, you need to migrate your code immediately. If you cannot do that, or want to continue using some of the features that were removed, you should pin your version of Qiskit Nature to 0.6
You can check out the migration guides for details on how to update your code. For more context on the changes around Qiskit Nature and the other application projects as well as the algorithms library in Qiskit, be sure to read this blog post.
New Features
-
Adds a new lattice class,
HexagonalLattice
for the generation of hexagonal lattices.
You construct a hexagonal lattice by specifying the number of rows and columns of hexagons. You can also specify the edge- and on-site-parameters.
Below is a simple example to illustrate this:from qiskit_nature.second_q.hamiltonians.lattices import HexagonalLattice lattice = HexagonalLattice( 2, 3, edge_parameter=1.0, onsite_parameter=1.5, )
-
Adds a new lattice class,
KagomeLattice
for the generation of kagome lattices. For example, you can construct a kagome lattice with 4 and 3 unit cells in the x and y direction, respectively, which has weights 1.0 on all edges, weights 1.5 on self-loops and open boundary conditionsfrom qiskit_nature.second_q.hamiltonians.lattices import ( KagomeLattice, BoundaryCondition, ) kagome = KagomeLattice( 4, 3, edge_parameter = 1.0, onsite_parameter = 1.5, boundary_condition = BoundaryCondition.OPEN )
-
Adds new operator generator functions to allow more fine-grained spin observables. The new functions are:
- the
$S^+$ operator:s_plus_operator()
- the
$S^-$ operator:s_minus_operator()
- the
$S^x$ operator:s_x_operator()
- the
$S^y$ operator:s_y_operator()
- the
$S^z$ operator:s_z_operator()
All of these functions take the number of spatial orbitals as their only argument and return the constructed
FermionicOp
. This also allows a much simpler implementation of theAngularMomentum
which is simply the$S^2$ operator: - the
-
Introduced a new feature that implements the bosonic operator
BosonicOp
. Its functionalities are analogous to theFermioniOp
, but for commuting bosonic particles. It should be used to represent a bosonic operator, so if one wants to represent the boson number operator it should do for example:from qiskit_nature.second_q.operators import BosonicOp bosonic_op = BosonicOp({'+_0 -_0': 1}, num_modes=1)
Due to the nature of bosonic particles, this class uses the commutator relations instead of the anti-commutator ones (used by fermionic particles).
-
In order to use the bosonic operator for quantum applications, this feature also introduces the bosonic linear mapper, which allows to map the BosonicOp to the qubit space. This mapper is based on this paper. To use this mapper one can for example:
from qiskit_nature.second_q.mappers import BosonicLinearMapper mapper = BosonicLinearMapper(truncation=1) qubit_op = mapper.map(bos_op)
-
The symmetry folding and unfolding routines listed below could become severe bottlenecks for larger system sizes. Now, when PySCF is installed, its routine will be used which is significantly faster.
unfold_s4_to_s1()
unfold_s8_to_s1()
unfold_s8_to_s4()
fold_s1_to_s4()
fold_s1_to_s8()
fold_s4_to_s8()
-
Adds a new
multi
argument to thePolynomialTensor.apply()
method which allows handling of numpy routines which return more than one array. The same argument also gets exposed byElectronicIntegrals.apply()
. -
Adds the following new utility methods for splitting and stacking multi-tensors:
PolynomialTensor.split()
PolynomialTensor.stack()
ElectronicIntegrals.split()
ElectronicIntegrals.stack()
-
Adds the
SparseLabelOp.from_terms()
method which is the inverse ofSparseLabelOp.terms()
. -
Adds the
SparseLabelOp.permute_indices()
method which allows index permutations to be applied to an operator. For example:from qiskit_nature.second_q.operators import FermionicOp op = FermionicOp({"+_0 +_2 -_1 -_3": 1.0}, num_spin_orbitals=4) permuted_op = op.permute_indices([3, 1, 0, 2]) print(permuted_op) # Fermionic Operator # number spin orbitals=4, number terms=1 # 1.0 * ( +_3 +_0 -_1 -_2 )
This is a very powerful method so caution is advised when using it as other components of the stack may rely on assumptions which are no longer valid after such a permutation (for example the builtin two-qubit reduction of the
ParityMapper
). -
The
SparseLabelOp.register_length
attribute (and by extension that of its subclasses, too) can no longer takeNone
as its value. However, the attributes which this one might rely on (e.g.FermionicOp.num_spin_orbitals
orBosonicOp.num_modes
) can remainNone
. This ensures that the lower-bound behavior works as intended. -
Added linear algebra utilities for performing the double-factorization of a two-body tensor:
qiskit_nature.utils.double_factorized()
qiskit_nature.utils.modified_cholesky()
-
The
active_orbitals
argument of theActiveSpaceTransformer
may now also take a pair of lists of integers, each of which have a length identical to the number of active spatial orbitals. In this case, the first list indicates the alpha- and the second list the beta-spin orbital indices, respectively. -
Adds a new convenience subclass of the
UCC
ansatz. Namely, the spin-symmetry-adapted ansatz,PUCCSD
, which includes single and double excitations while always pairing the excitations such that both, the number of particles and the total spin, will be preserved.
You can use it like any of the otherUCC
-style ansätze, for example:from qiskit_nature.second_q.circuit.library import PUCCSD from qiskit_nature.second_q.mappers import JordanWignerMapper ansatz = PUCCSD( num_spatial_orbitals=4, num_particles=(2, 2), qubit_mapper=JordanWignerMapper(), )
-
Added the new
include_imaginary
keyword argument to theUCC
,UCCSD
, andPUCCD
classes. WhenTrue
, an extra ansatz parameter is added to each excitation that controls the imaginary contribution to its evolution. Thus, this setting doubles the total number of ansatz parameters, as compared to the default setting ofFalse
.
Upgrade Notes
- Support for running with Python 3.7 has been removed. To run Nature you need a minimum Python version of 3.8.
Bug Fixes
- The
ActiveSpaceTransformer
would sometimes set the wrong number of active particles because of a flawed integer rounding. This has now been fixed. - Fixes a formatting issue when printing an
ElectronicStructureResult
which contains values inextracted_transformer_energies
- Fixes the tutorial for the excited state solvers. In doing so, the
EvaluationRule
is properly exposed for importing and documenting accordingly. - Fixes the computation of
ElectronicEnergy.coulomb()
(and by extensionElectronicEnergy.fock()
) when applied to a purely alpha-spin Hamiltonian but providing a mixed spin density. - Fixes the behavior of the
FreezeCoreTransformer
when a charge is present on the molecule. - When using
SparseLabelOp.from_polynomial_tensor()
constructor for one ofBosonicOp
,FermionicOp
,SpinOp
, orVibrationalOp
, the coefficient for the constant term was a 0d Tensor object rather than a number. This has been fixed. - The
ElectronicStructureProblem.reference_energy
is now properly propagated to theElectronicStructureResult.hartree_fock_energy
. - Fixes the logic of the
InterleavedQubitMapper
to actually perform the interleaving on the second-quantization level rather than the qubit level. This ensures that the actually expected benefits from using an interleaved ordering (for example when mapping a paired double-excitation where all Z terms cancel each other) occur, rather than a naive re-shuffling of the already mapped qubit operator. - Fixes the behavior of
SpinOp.to_matrix()
for operators acting on more than a single spin. - Fixes the
copy.copy
andcopy.deepcopy
operations for theTensor
class. - Fixes a regression in the performance of the
map()
method - Compatibility fix to support optional sparse install under Python 3.11.
- Fixed the support of
use_pauli_sum_op
in theUCC
andUVCC
classes as well as their extensions. This requires version 0.24 or higher of theqiskit-terra
package.