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 20, 2023
1 parent e8befeb commit 2a0c7d7
Show file tree
Hide file tree
Showing 35 changed files with 1,176 additions and 612 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@

import logging

from typing import Union, Optional, Tuple

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
from qiskit_nature.second_q.problems import BaseProblem
from qiskit_nature.second_q.problems import EigenstateResult
from qiskit_nature.deprecation import warn_deprecated, DeprecatedType

from .excited_states_solver import ExcitedStatesSolver
from .eigensolver_factories import EigensolverFactory
Expand All @@ -38,7 +38,7 @@ class ExcitedStatesEigensolver(ExcitedStatesSolver):
def __init__(
self,
qubit_converter: QubitConverter | QubitMapper,
solver: Union[Eigensolver, EigensolverFactory],
solver: Eigensolver | EigensolverFactory,
) -> None:
"""
Expand All @@ -51,20 +51,20 @@ def __init__(
self._solver = solver

@property
def solver(self) -> Union[Eigensolver, EigensolverFactory]:
def solver(self) -> Eigensolver | EigensolverFactory:
"""Returns the minimum eigensolver or factory."""
return self._solver

@solver.setter
def solver(self, solver: Union[Eigensolver, EigensolverFactory]) -> None:
def solver(self, solver: Eigensolver | EigensolverFactory) -> None:
"""Sets the minimum eigensolver or factory."""
self._solver = solver

def get_qubit_operators(
self,
problem: BaseProblem,
aux_operators: Optional[dict[str, Union[SparseLabelOp, PauliSumOp]]] = None,
) -> Tuple[PauliSumOp, Optional[dict[str, PauliSumOp]]]:
aux_operators: dict[str, SparseLabelOp | PauliSumOp | SparsePauliOp] | None = None,
) -> tuple[PauliSumOp | SparsePauliOp, dict[str, PauliSumOp | SparsePauliOp] | None]:
# 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 All @@ -85,6 +85,13 @@ def get_qubit_operators(

if aux_operators is not None:
for name_aux, aux_op in aux_operators.items():
if isinstance(aux_op, PauliSumOp):
warn_deprecated(
"0.6.0",
old_type=DeprecatedType.ARGUMENT,
old_name="PauliSumOp",
new_name="SparsePauliOp",
)
if isinstance(aux_op, SparseLabelOp):
if isinstance(self._qubit_converter, QubitConverter):
converted_aux_op = self._qubit_converter.convert_match(
Expand Down Expand Up @@ -127,7 +134,7 @@ def get_qubit_operators(
def solve(
self,
problem: BaseProblem,
aux_operators: Optional[dict[str, Union[SparseLabelOp, PauliSumOp]]] = None,
aux_operators: dict[str, SparseLabelOp | PauliSumOp | SparsePauliOp] | None = 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,9 @@
from __future__ import annotations

from abc import ABC, abstractmethod
from typing import Optional, Union, 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 +31,7 @@ class ExcitedStatesSolver(ABC):
def solve(
self,
problem: BaseProblem,
aux_operators: Optional[dict[str, Union[SparseLabelOp, PauliSumOp]]] = None,
aux_operators: dict[str, SparseLabelOp | PauliSumOp | SparsePauliOp] | None = None,
) -> EigenstateResult:
r"""Compute the excited states energies of the molecule that was supplied via the driver.
Expand All @@ -54,8 +54,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: dict[str, SparseLabelOp | PauliSumOp] | None = None,
) -> tuple[PauliSumOp | SparseLabelOp, dict[str, PauliSumOp | SparseLabelOp] | None]:
"""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
20 changes: 13 additions & 7 deletions qiskit_nature/second_q/algorithms/excited_states_solvers/qeom.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

from __future__ import annotations

from typing import Any, Callable, Sequence, cast
from typing import Any, Callable, Sequence
from enum import Enum
import itertools
import logging
Expand All @@ -38,7 +38,6 @@
from qiskit.primitives import BaseEstimator

from qiskit_nature.second_q.algorithms.ground_state_solvers import GroundStateSolver
from qiskit_nature.second_q.algorithms.ground_state_solvers.ground_state_solver import QubitOperator
from qiskit_nature.second_q.algorithms.ground_state_solvers.minimum_eigensolver_factories import (
MinimumEigensolverFactory,
)
Expand All @@ -58,6 +57,7 @@
EigenstateResult,
ElectronicStructureResult,
)
from qiskit_nature.deprecation import warn_deprecated, DeprecatedType

from .qeom_electronic_ops_builder import build_electronic_ops
from .qeom_vibrational_ops_builder import build_vibrational_ops
Expand Down Expand Up @@ -270,8 +270,8 @@ def _taper_operators(
def get_qubit_operators(
self,
problem: BaseProblem,
aux_operators: dict[str, SparseLabelOp | QubitOperator] | None = None,
) -> tuple[QubitOperator, dict[str, QubitOperator] | None]:
aux_operators: dict[str, SparseLabelOp | PauliSumOp] | None = None,
) -> tuple[SparsePauliOp | PauliSumOp, dict[str, SparsePauliOp | PauliSumOp] | None]:
"""
Gets the operator and auxiliary operators, and transforms the provided auxiliary operators.
If the user-provided ``aux_operators`` contain a name which clashes with an internally
Expand Down Expand Up @@ -308,9 +308,15 @@ def get_qubit_operators(
if self.solver.supports_aux_operators():
aux_ops = self._map_operators(aux_second_q_operators)

cast(ListOrDictType[QubitOperator], aux_ops)
if aux_operators is not None:
for name, op in aux_operators.items():
if isinstance(op, PauliSumOp):
warn_deprecated(
"0.6.0",
old_type=DeprecatedType.ARGUMENT,
old_name="PauliSumOp",
new_name="SparsePauliOp",
)
if isinstance(op, (SparseLabelOp)):
converted_aux_op = self._map_operators(op)
else:
Expand Down Expand Up @@ -350,7 +356,7 @@ def get_qubit_operators(
def solve(
self,
problem: BaseProblem,
aux_operators: dict[str, SparseLabelOp | QubitOperator] | None = None,
aux_operators: dict[str, SparseLabelOp | SparsePauliOp | PauliSumOp] | None = None,
) -> EigenstateResult:
"""Run the excited-states calculation.
Expand Down Expand Up @@ -433,7 +439,7 @@ def solve(
def _build_hopping_ops(
self, problem: BaseProblem
) -> tuple[
dict[str, QubitOperator],
dict[str, SparsePauliOp | PauliSumOp],
dict[str, list[bool]],
dict[str, tuple[tuple[int, ...], tuple[int, ...]]],
]:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@

from __future__ import annotations

from typing import Callable, Dict, List, Tuple
from typing import Callable

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 @@ -28,7 +29,7 @@

def build_electronic_ops(
num_spatial_orbitals: int,
num_particles: Tuple[int, int],
num_particles: tuple[int, int],
excitations: str
| int
| list[int]
Expand All @@ -37,10 +38,10 @@ def build_electronic_ops(
list[tuple[tuple[int, ...], tuple[int, ...]]],
],
qubit_converter: QubitConverter | QubitMapper,
) -> Tuple[
Dict[str, PauliSumOp],
Dict[str, List[bool]],
Dict[str, Tuple[Tuple[int, ...], Tuple[int, ...]]],
) -> tuple[
dict[str, PauliSumOp | SparsePauliOp],
dict[str, list[bool]],
dict[str, tuple[tuple[int, ...], tuple[int, ...]]],
]:
"""Builds the product of raising and lowering operators (basic excitation operators)
Expand Down Expand Up @@ -71,9 +72,9 @@ def build_electronic_ops(
size = len(excitations_list)

# build all hopping operators
hopping_operators: Dict[str, PauliSumOp] = {}
type_of_commutativities: Dict[str, List[bool]] = {}
excitation_indices: Dict[str, Tuple[Tuple[int, ...], Tuple[int, ...]]] = {}
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 = []
for idx in range(size):
to_be_executed_list += [excitations_list[idx], excitations_list[idx][::-1]]
Expand All @@ -99,10 +100,10 @@ def build_electronic_ops(


def _build_single_hopping_operator(
excitation: Tuple[Tuple[int, ...], Tuple[int, ...]],
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 All @@ -125,13 +126,14 @@ def _build_single_hopping_operator(
commutativities = []
if not len(symmetries_for_commutativity) == 0:
for symmetry in symmetries_for_commutativity:
symmetry_op = PauliSumOp.from_list([(symmetry.to_label(), 1.0)])
paulis = qubit_op.primitive.paulis
symmetry_op = SparsePauliOp.from_list([(symmetry.to_label(), 1.0)])
if isinstance(qubit_op, PauliSumOp):
paulis = qubit_op.primitive.paulis
else:
paulis = qubit_op.paulis
len_paulis = len(paulis)
commuting = len(paulis.commutes_with_all(symmetry_op.primitive.paulis)) == len_paulis
anticommuting = (
len(paulis.anticommutes_with_all(symmetry_op.primitive.paulis)) == len_paulis
)
commuting = len(paulis.commutes_with_all(symmetry_op.paulis)) == len_paulis
anticommuting = len(paulis.anticommutes_with_all(symmetry_op.paulis)) == len_paulis

if commuting != anticommuting: # only one of them is True
if commuting:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@

from __future__ import annotations

from typing import Callable, Dict, List, Tuple
from typing import Callable

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 @@ -26,7 +27,7 @@


def build_vibrational_ops(
num_modals: List[int],
num_modals: list[int],
excitations: str
| int
| list[int]
Expand All @@ -35,10 +36,10 @@ def build_vibrational_ops(
list[tuple[tuple[int, ...], tuple[int, ...]]],
],
qubit_converter: QubitConverter | QubitMapper,
) -> Tuple[
Dict[str, PauliSumOp],
Dict[str, List[bool]],
Dict[str, Tuple[Tuple[int, ...], Tuple[int, ...]]],
) -> tuple[
dict[str, PauliSumOp | SparsePauliOp],
dict[str, list[bool]],
dict[str, tuple[tuple[int, ...], tuple[int, ...]]],
]:
"""
Args:
Expand All @@ -61,8 +62,8 @@ def build_vibrational_ops(
excitations_list = ansatz._get_excitation_list()
size = len(excitations_list)

hopping_operators: Dict[str, PauliSumOp] = {}
excitation_indices: Dict[str, Tuple[Tuple[int, ...], Tuple[int, ...]]] = {}
hopping_operators: dict[str, PauliSumOp | SparsePauliOp] = {}
excitation_indices: dict[str, tuple[tuple[int, ...], tuple[int, ...]]] = {}
to_be_executed_list = []
for idx in range(size):
to_be_executed_list += [excitations_list[idx], excitations_list[idx][::-1]]
Expand All @@ -83,14 +84,14 @@ def build_vibrational_ops(

# This variable is required for compatibility with the ElectronicStructureProblem
# at the moment we do not have any type of commutativity in the bosonic case.
type_of_commutativities: Dict[str, List[bool]] = {}
type_of_commutativities: dict[str, list[bool]] = {}

return hopping_operators, type_of_commutativities, excitation_indices


def _build_single_hopping_operator(
excitation: Tuple[Tuple[int, ...], Tuple[int, ...]],
num_modals: List[int],
excitation: tuple[tuple[int, ...], tuple[int, ...]],
num_modals: list[int],
qubit_converter: QubitConverter | QubitMapper,
) -> PauliSumOp:
label = []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@
import logging

from qiskit.algorithms.minimum_eigensolvers import MinimumEigensolver
from qiskit.opflow import PauliSumOp
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

from .ground_state_solver import GroundStateSolver, QubitOperator
from .ground_state_solver import GroundStateSolver
from .minimum_eigensolver_factories import MinimumEigensolverFactory

LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -57,7 +59,7 @@ def supports_aux_operators(self):
def solve(
self,
problem: BaseProblem,
aux_operators: dict[str, SparseLabelOp | QubitOperator] | None = None,
aux_operators: dict[str, SparseLabelOp | SparsePauliOp | PauliSumOp] | None = None,
) -> EigenstateResult:
"""Compute Ground State properties.
Expand All @@ -81,8 +83,8 @@ def solve(
def get_qubit_operators(
self,
problem: BaseProblem,
aux_operators: dict[str, SparseLabelOp | QubitOperator] | None = None,
) -> tuple[QubitOperator, dict[str, QubitOperator] | None]:
aux_operators: dict[str, SparseLabelOp | SparsePauliOp | PauliSumOp] | None = None,
) -> tuple[SparsePauliOp | PauliSumOp, dict[str, SparsePauliOp | PauliSumOp] | None]:
# 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
Loading

0 comments on commit 2a0c7d7

Please sign in to comment.