Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve noisy tomography bases #997

Merged
merged 12 commits into from
Feb 6, 2023
27 changes: 24 additions & 3 deletions qiskit_experiments/library/tomography/basis/base_basis.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,14 @@ class PreparationBasis(BaseBasis):

@abstractmethod
def matrix_shape(self, qubits: Sequence[int]) -> Tuple[int, ...]:
"""Return the shape of subsystem dimensions of a matrix element."""
"""Return the shape of subsystem dimensions of the state :py:attr:`~matrix`.

Args:
qubits: the physical qubit subsystems.

Returns:
A tuple of subsystem dimensions for the specified qubits.
"""

@abstractmethod
def matrix(self, index: Sequence[int], qubits: Optional[Sequence[int]] = None) -> np.ndarray:
Expand Down Expand Up @@ -152,11 +159,25 @@ class MeasurementBasis(BaseBasis):

@abstractmethod
def outcome_shape(self, qubits: Sequence[int]) -> Tuple[int, ...]:
"""Return the shape of allowed measurement outcomes on specified qubits."""
"""Return the shape of allowed measurement outcomes on specified qubits.

Args:
qubits: the physical qubit subsystems.

Returns:
A tuple of the number of measurement outcomes for specified qubits.
"""

@abstractmethod
def matrix_shape(self, qubits: Sequence[int]) -> Tuple[int, ...]:
"""Return the shape of subsystem dimensions of a POVM matrix element."""
"""Return the shape of subsystem dimensions of a POVM :py:attr:`~matrix`.

Args:
qubits: the physical qubit subsystems.

Returns:
A tuple of subsystem dimensions for the specified qubits.
"""

@abstractmethod
def matrix(
Expand Down
68 changes: 68 additions & 0 deletions qiskit_experiments/library/tomography/basis/cache_method.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2022.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.
"""
Method decorator for caching regular methods in class instances.
"""

from typing import Dict, Callable, Optional
import functools


def _method_cache_name(instance: any) -> str:
"""Attribute name for storing cache in an instance"""
return "_CACHE_" + type(instance).__name__


def _get_method_cache(instance: any) -> Dict:
"""Return instance cache for cached methods"""
cache_name = _method_cache_name(instance)
try:
return getattr(instance, cache_name)
except AttributeError:
setattr(instance, cache_name, {})
return getattr(instance, cache_name)


def cache_method(maxsize: Optional[int] = None) -> Callable:
"""Decorator for caching class instance methods.

Args:
maxsize: The maximum size of this method's LRU cache.

Returns:
The decorator for caching methods.
"""

def cache_method_decorator(method: Callable) -> Callable:
"""Decorator for caching method.

Args:
method: A method to cache.

Returns:
The wrapped cached method.
"""

@functools.wraps(method)
def _cached_method(self, *args, **kwargs):
cache = _get_method_cache(self)
key = method.__name__
try:
meth = cache[key]
except KeyError:
meth = cache[key] = functools.lru_cache(maxsize)(functools.partial(method, self))

return meth(*args, **kwargs)

return _cached_method

return cache_method_decorator
Loading