Skip to content

Commit

Permalink
Replace PauliSumOp with SparsePauliOp
Browse files Browse the repository at this point in the history
  • Loading branch information
manoelmarques authored and mrossinek committed Feb 9, 2023
1 parent 35934fb commit 5df155f
Show file tree
Hide file tree
Showing 30 changed files with 1,051 additions and 533 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

from qiskit.algorithms.eigensolvers import Eigensolver
from qiskit.opflow import PauliSumOp
from qiskit.quantum_info import SparsePauliOp

from qiskit_nature.second_q.mappers import QubitConverter, QubitMapper
from qiskit_nature.second_q.operators import SparseLabelOp
Expand Down Expand Up @@ -63,8 +64,8 @@ def solver(self, solver: Union[Eigensolver, EigensolverFactory]) -> None:
def get_qubit_operators(
self,
problem: BaseProblem,
aux_operators: Optional[dict[str, Union[SparseLabelOp, PauliSumOp]]] = None,
) -> Tuple[PauliSumOp, Optional[dict[str, PauliSumOp]]]:
aux_operators: Optional[dict[str, SparseLabelOp | PauliSumOp | SparsePauliOp]] = None,
) -> Tuple[PauliSumOp | SparsePauliOp, Optional[dict[str, PauliSumOp | SparsePauliOp]]]:
# Note that ``aux_ops`` contains not only the transformed ``aux_operators`` passed by the
# user but also additional ones from the transformation
main_second_q_op, aux_second_q_ops = problem.second_q_ops()
Expand Down Expand Up @@ -127,7 +128,7 @@ def get_qubit_operators(
def solve(
self,
problem: BaseProblem,
aux_operators: Optional[dict[str, Union[SparseLabelOp, PauliSumOp]]] = None,
aux_operators: Optional[dict[str, SparseLabelOp | PauliSumOp | SparsePauliOp]] = None,
) -> EigenstateResult:
"""Compute Ground and Excited States properties.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@
from __future__ import annotations

from abc import ABC, abstractmethod
from typing import Optional, Union, Tuple
from typing import Optional, Tuple

from qiskit.opflow import PauliSumOp
from qiskit.quantum_info import SparsePauliOp

from qiskit_nature.second_q.operators import SparseLabelOp
from qiskit_nature.second_q.problems import BaseProblem
Expand All @@ -31,7 +32,7 @@ class ExcitedStatesSolver(ABC):
def solve(
self,
problem: BaseProblem,
aux_operators: Optional[dict[str, Union[SparseLabelOp, PauliSumOp]]] = None,
aux_operators: Optional[dict[str, SparseLabelOp | PauliSumOp | SparsePauliOp]] = None,
) -> EigenstateResult:
r"""Compute the excited states energies of the molecule that was supplied via the driver.
Expand All @@ -54,8 +55,8 @@ def solver(self):
def get_qubit_operators(
self,
problem: BaseProblem,
aux_operators: Optional[dict[str, Union[SparseLabelOp, PauliSumOp]]] = None,
) -> Tuple[PauliSumOp, Optional[dict[str, PauliSumOp]]]:
aux_operators: Optional[dict[str, SparseLabelOp | PauliSumOp]] = None,
) -> Tuple[PauliSumOp | SparseLabelOp, Optional[dict[str, PauliSumOp | SparseLabelOp]]]:
"""Gets the operator and auxiliary operators, and transforms the provided auxiliary operators
using a ``QubitConverter`` or ``QubitMapper``.
If the user-provided ``aux_operators`` contain a name which clashes with an internally
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from typing import Callable, Dict, List, Tuple

from qiskit.opflow import PauliSumOp
from qiskit.quantum_info import SparsePauliOp
from qiskit.tools import parallel_map
from qiskit.utils import algorithm_globals

Expand All @@ -38,7 +39,7 @@ def build_electronic_ops(
],
qubit_converter: QubitConverter | QubitMapper,
) -> Tuple[
Dict[str, PauliSumOp],
Dict[str, PauliSumOp | SparsePauliOp],
Dict[str, List[bool]],
Dict[str, Tuple[Tuple[int, ...], Tuple[int, ...]]],
]:
Expand Down Expand Up @@ -71,7 +72,7 @@ def build_electronic_ops(
size = len(excitations_list)

# build all hopping operators
hopping_operators: Dict[str, PauliSumOp] = {}
hopping_operators: Dict[str, PauliSumOp | SparsePauliOp] = {}
type_of_commutativities: Dict[str, List[bool]] = {}
excitation_indices: Dict[str, Tuple[Tuple[int, ...], Tuple[int, ...]]] = {}
to_be_executed_list = []
Expand Down Expand Up @@ -102,7 +103,7 @@ def _build_single_hopping_operator(
excitation: Tuple[Tuple[int, ...], Tuple[int, ...]],
num_spatial_orbitals: int,
qubit_converter: QubitConverter | QubitMapper,
) -> Tuple[PauliSumOp, List[bool]]:
) -> Tuple[PauliSumOp | SparsePauliOp, List[bool]]:
label = []
for occ in excitation[0]:
label.append(f"+_{occ}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from typing import Callable, Dict, List, Tuple

from qiskit.opflow import PauliSumOp
from qiskit.quantum_info import SparsePauliOp
from qiskit.tools import parallel_map
from qiskit.utils import algorithm_globals

Expand All @@ -36,7 +37,7 @@ def build_vibrational_ops(
],
qubit_converter: QubitConverter | QubitMapper,
) -> Tuple[
Dict[str, PauliSumOp],
Dict[str, PauliSumOp | SparsePauliOp],
Dict[str, List[bool]],
Dict[str, Tuple[Tuple[int, ...], Tuple[int, ...]]],
]:
Expand All @@ -61,7 +62,7 @@ def build_vibrational_ops(
excitations_list = ansatz._get_excitation_list()
size = len(excitations_list)

hopping_operators: Dict[str, PauliSumOp] = {}
hopping_operators: Dict[str, PauliSumOp | SparsePauliOp] = {}
excitation_indices: Dict[str, Tuple[Tuple[int, ...], Tuple[int, ...]]] = {}
to_be_executed_list = []
for idx in range(size):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@

from qiskit.opflow import PauliSumOp
from qiskit.quantum_info.operators.base_operator import BaseOperator
from qiskit.quantum_info import SparsePauliOp

from qiskit_nature.second_q.operators import SparseLabelOp
from qiskit_nature.second_q.mappers import QubitConverter, QubitMapper
from qiskit_nature.second_q.problems import BaseProblem
from qiskit_nature.second_q.problems import EigenstateResult

QubitOperator = Union[BaseOperator, PauliSumOp]
QubitOperator = Union[BaseOperator, PauliSumOp, SparsePauliOp]


class GroundStateSolver(ABC):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import numpy as np
from qiskit import QuantumRegister
from qiskit.circuit.library import BlueprintCircuit
from qiskit.opflow import PauliSumOp
from qiskit.quantum_info import SparsePauliOp
from qiskit.utils.validation import validate_min

from qiskit_nature.second_q.mappers import (
Expand Down Expand Up @@ -241,7 +241,7 @@ def hartree_fock_bitstring_mapped(
)

# map the `FermionicOp` to a qubit operator
qubit_op: PauliSumOp
qubit_op: SparsePauliOp
if isinstance(qubit_converter, QubitConverter):
if match_convert:
qubit_op = qubit_converter.convert_match(bitstr_op, check_commutes=False)
Expand All @@ -254,10 +254,13 @@ def hartree_fock_bitstring_mapped(
else:
qubit_op = qubit_converter.map(bitstr_op)

if not isinstance(qubit_op, SparsePauliOp):
qubit_op = qubit_op.primitive

# We check the mapped operator `x` part of the paulis because we want to have particles
# i.e. True, where the initial state introduced a creation (`+`) operator.
bits = []
for bit in qubit_op.primitive.paulis.x[0]:
for bit in qubit_op.paulis.x[0]:
bits.append(bit)

return bits
Expand Down
9 changes: 6 additions & 3 deletions qiskit_nature/second_q/circuit/library/initial_states/vscf.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

from qiskit import QuantumRegister
from qiskit.circuit.library import BlueprintCircuit
from qiskit.opflow import PauliSumOp
from qiskit.quantum_info import SparsePauliOp
from qiskit_nature.second_q.mappers import DirectMapper
from qiskit_nature.second_q.mappers import QubitConverter, QubitMapper, TaperedQubitMapper
from qiskit_nature.second_q.operators import VibrationalOp
Expand Down Expand Up @@ -196,7 +196,7 @@ def vscf_bitstring_mapped(
num_modals=num_modals,
)
# map the `VibrationalOp` to a qubit operator
qubit_op: PauliSumOp
qubit_op: SparsePauliOp
if isinstance(qubit_converter, QubitConverter):
qubit_op = qubit_converter.convert_match(bitstr_op, check_commutes=False)
elif isinstance(qubit_converter, TaperedQubitMapper):
Expand All @@ -206,10 +206,13 @@ def vscf_bitstring_mapped(
else:
qubit_op = qubit_converter.map(bitstr_op)

if not isinstance(qubit_op, SparsePauliOp):
qubit_op = qubit_op.primitive

# We check the mapped operator `x` part of the paulis because we want to have particles
# i.e. True, where the initial state introduced a creation (`+`) operator.
bits = []
for bit in qubit_op.primitive.paulis.x[0]:
for bit in qubit_op.paulis.x[0]:
bits.append(bit)

return bits
Expand Down
9 changes: 6 additions & 3 deletions qiskit_nature/second_q/mappers/bksf.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,13 @@
import numpy as np

from qiskit.opflow import PauliSumOp
from qiskit.quantum_info.operators import Pauli, SparsePauliOp
from qiskit.quantum_info import SparsePauliOp
from qiskit.quantum_info.operators import Pauli

from qiskit_nature import settings
from qiskit_nature.second_q.operators import FermionicOp
from .fermionic_mapper import FermionicMapper
from .qubit_mapper import QubitOperator


class BravyiKitaevSuperFastMapper(FermionicMapper):
Expand All @@ -38,7 +41,7 @@ class BravyiKitaevSuperFastMapper(FermionicMapper):

def _map_single(
self, second_q_op: FermionicOp, *, register_length: int | None = None
) -> PauliSumOp:
) -> QubitOperator:
if register_length is None:
register_length = second_q_op.register_length

Expand All @@ -55,7 +58,7 @@ def _map_single(
coeffs = sparse_pauli.coeffs[indices]
sorted_sparse_pauli = SparsePauliOp(table, coeffs)

return PauliSumOp(sorted_sparse_pauli)
return PauliSumOp(sorted_sparse_pauli) if settings.use_pauli_sum_op else sorted_sparse_pauli


class TermType(Enum):
Expand Down
5 changes: 2 additions & 3 deletions qiskit_nature/second_q/mappers/direct_mapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,8 @@
class DirectMapper(VibrationalMapper):
"""The Direct mapper.
This mapper maps a :class:`~.VibrationalOp` to a
:class:`~qiskit.opflow.primitive_ops.PauliSumOp`. In doing so, each modal
of the the ``VibrationalOp`` gets mapped to a single qubit.
This mapper maps a :class:`~.VibrationalOp` to a qubit operator.In doing so, each modal of the
``VibrationalOp`` gets mapped to a single qubit.
"""

@classmethod
Expand Down
6 changes: 2 additions & 4 deletions qiskit_nature/second_q/mappers/fermionic_mapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,9 @@

from __future__ import annotations

from qiskit.opflow.primitive_ops import PauliSumOp

from qiskit_nature.second_q.operators import FermionicOp

from .qubit_mapper import ListOrDictType, QubitMapper
from .qubit_mapper import ListOrDictType, QubitMapper, QubitOperator


class FermionicMapper(QubitMapper):
Expand All @@ -29,5 +27,5 @@ def map(
second_q_ops: FermionicOp | ListOrDictType[FermionicOp],
*,
register_length: int | None = None,
) -> PauliSumOp | ListOrDictType[PauliSumOp]:
) -> QubitOperator | ListOrDictType[QubitOperator]:
return super().map(second_q_ops, register_length=register_length)
6 changes: 4 additions & 2 deletions qiskit_nature/second_q/mappers/interleaved_qubit_mapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@
from qiskit.opflow import PauliSumOp
from qiskit.quantum_info import SparsePauliOp

from qiskit_nature import settings
from qiskit_nature.second_q.operators import FermionicOp

from .fermionic_mapper import FermionicMapper
from .qubit_mapper import QubitOperator


class InterleavedQubitMapper(FermionicMapper):
Expand Down Expand Up @@ -94,7 +96,7 @@ def __init__(self, mapper: FermionicMapper):

def _map_single(
self, second_q_op: FermionicOp, *, register_length: int | None = None
) -> PauliSumOp:
) -> QubitOperator:
blocked_op = self.mapper._map_single(second_q_op, register_length=register_length).primitive

def blocked_to_interleaved(label: str) -> str:
Expand All @@ -104,4 +106,4 @@ def blocked_to_interleaved(label: str) -> str:
[(blocked_to_interleaved(label), coeff) for label, coeff in blocked_op.to_list()]
)

return PauliSumOp(interleaved_op)
return PauliSumOp(interleaved_op) if settings.use_pauli_sum_op else interleaved_op
12 changes: 8 additions & 4 deletions qiskit_nature/second_q/mappers/linear_mapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,21 @@
import numpy as np

from qiskit.opflow import PauliSumOp
from qiskit.quantum_info.operators import Pauli, SparsePauliOp
from qiskit.quantum_info import SparsePauliOp
from qiskit.quantum_info.operators import Pauli

from qiskit_nature import settings
from qiskit_nature.second_q.operators import SpinOp
from .qubit_mapper import QubitOperator
from .spin_mapper import SpinMapper


class LinearMapper(SpinMapper):
"""The Linear spin-to-qubit mapping."""

def _map_single(self, second_q_op: SpinOp, *, register_length: int | None = None) -> PauliSumOp:
def _map_single(
self, second_q_op: SpinOp, *, register_length: int | None = None
) -> QubitOperator:
if register_length is None:
register_length = second_q_op.register_length

Expand All @@ -55,8 +60,7 @@ def _map_single(self, second_q_op: SpinOp, *, register_length: int | None = None
qubit_ops_list.append(coeff * reduce(operator.xor, reversed(operatorlist)))

qubit_op = reduce(operator.add, qubit_ops_list)

return qubit_op
return qubit_op if settings.use_pauli_sum_op else qubit_op.primitive.simplify()

def _linear_encoding(self, spin: Fraction | float) -> list[PauliSumOp]:
"""
Expand Down
11 changes: 8 additions & 3 deletions qiskit_nature/second_q/mappers/logarithmic_mapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,12 @@
import numpy as np

from qiskit.opflow import PauliSumOp
from qiskit.quantum_info.operators import SparsePauliOp, Operator
from qiskit.quantum_info import SparsePauliOp
from qiskit.quantum_info.operators import Operator

from qiskit_nature import settings
from qiskit_nature.second_q.operators import SpinOp
from .qubit_mapper import QubitOperator
from .spin_mapper import SpinMapper


Expand Down Expand Up @@ -71,7 +74,9 @@ def __init__(self, *, padding: float = 1, embed_upper: bool = True) -> None:
self._padding = padding
self._embed_upper = embed_upper

def _map_single(self, second_q_op: SpinOp, *, register_length: int | None = None) -> PauliSumOp:
def _map_single(
self, second_q_op: SpinOp, *, register_length: int | None = None
) -> QubitOperator:
"""Map spins to qubits using the Logarithmic encoding.
Args:
Expand Down Expand Up @@ -104,7 +109,7 @@ def _map_single(self, second_q_op: SpinOp, *, register_length: int | None = None

qubit_op = reduce(operator.add, qubit_ops_list)

return qubit_op
return qubit_op if settings.use_pauli_sum_op else qubit_op.primitive

def _logarithmic_encoding(
self, spin: Fraction | int
Expand Down
13 changes: 8 additions & 5 deletions qiskit_nature/second_q/mappers/parity_mapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@
from qiskit.quantum_info.analysis.z2_symmetries import Z2Symmetries
from qiskit.quantum_info.operators import Pauli, PauliList, SparsePauliOp

from qiskit_nature import settings
from qiskit_nature.deprecation import deprecate_arguments, deprecate_property
from qiskit_nature.second_q.operators import FermionicOp
from .fermionic_mapper import FermionicMapper
from .qubit_mapper import QubitOperator

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -131,10 +133,11 @@ def _two_qubit_reduce(self, operator: SparsePauliOp) -> SparsePauliOp:

def _map_single(
self, second_q_op: FermionicOp, *, register_length: int | None = None
) -> PauliSumOp:
mapped_op = ParityMapper.mode_based_mapping(
second_q_op, register_length=register_length
).primitive
) -> QubitOperator:
mapped_op = ParityMapper.mode_based_mapping(second_q_op, register_length=register_length)

if isinstance(mapped_op, PauliSumOp):
mapped_op = mapped_op.primitive

reduced_op = mapped_op
if self.num_particles is not None:
Expand All @@ -147,4 +150,4 @@ def _map_single(
mapped_op.num_qubits,
)

return PauliSumOp(reduced_op)
return PauliSumOp(reduced_op) if settings.use_pauli_sum_op else reduced_op
Loading

0 comments on commit 5df155f

Please sign in to comment.