ProductFrame

class ProductFrame(frames: dict[tuple[int, ...], T])[source]

Bases: BaseFrame[tuple[int, …]], Generic[T]

Class to represent a set of product frame operators.

A product frame \(M\) is made of local frames \(M1, M2, ...\) acting on respective subsystems. Each global operator can be written as the tensor product of local operators, \(M_{k_1, k_2, ...} = M1_{k_1} \otimes M2_{k_2} \otimes \cdots\).

Note

This is a base class which collects functionality common to various subclasses. As an end-user you would not use this class directly. Check out povm_toolbox.quantum_info for more general information.

Initialize from a mapping of local frames.

Parameters:

frames (dict[tuple[int, ...], T]) – a dictionary mapping from a tuple of subsystem indices to a local frame objects.

Raises:
  • ValueError – if any key in frames is not a tuple consisting of unique integers. In other words, every local frame must act on a distinct set of subsystem indices which do not overlap with each other.

  • ValueError – if any key in frames re-uses a previously used subsystem index. In other words, all local frames must act on mutually exclusive subsystem indices.

  • ValueError – if any key in frames does not specify the number of subsystem indices, which matches the number of systems acted upon by that local frame (MultiQubitFrame.num_subsystems()).

Attributes

dimension

The dimension of the Hilbert space on which the effects act.

informationally_complete

If the frame spans the entire Hilbert space.

num_operators

The number of effects of the frame.

shape

Give the number of operators per sub-system.

sub_systems

Give the number of operators per sub-system.

Inherited Attributes

num_subsystems

The number of subsystems which the frame operators act on.

For qubits, this is always \(\log_2(\)dimension\()\).

Methods

analysis(hermitian_op: SparsePauliOp | Operator, frame_op_idx: tuple[int, ...] | set[tuple[int, ...]] | None = None) float | dict[tuple[int, ...], float] | ndarray[source]

Return the frame coefficients of hermitian_op.

This method implements the analysis operator \(A\) of the frame \(\{F_k\}_k\):

\[A: \mathcal{O} \mapsto \{ \mathrm{Tr}\left[F_k \mathcal{O} \right] \}_k,\]

where \(c_k = \mathrm{Tr}\left[F_k \mathcal{O} \right]\) are called the frame coefficients of the Hermitian operator \(\mathcal{O}\).

Parameters:
  • hermitian_op (SparsePauliOp | Operator) – a hermitian operator whose frame coefficients to compute.

  • frame_op_idx (tuple[int, ...] | set[tuple[int, ...]] | None) – label or set of labels indicating which coefficients are queried. If None, all coefficients are queried.

Returns:

Frame coefficients, specified by frame_op_idx, of the Hermitian operator hermitian_op. If a specific coefficient was queried, a float is returned. If a specific set of coefficients was queried, a dictionary mapping labels to coefficients is returned. If all coefficients were queried, an array with all coefficients is returned.

Raises:
  • TypeError – when the provided single or sequence of labels frame_op_idx does not have a valid type.

  • ValueError – when the dimension of the provided hermitian_op does not match the dimension of the frame operators.

Return type:

float | dict[tuple[int, …], float] | ndarray

classmethod from_list(frames: Sequence[T]) Self[source]

Construct a ProductFrame from a list of MultiQubitFrame objects.

This is a convenience method to simplify the construction of a ProductFrame for the cases in which the local frame objects act on a sequential order of subsystems. In other words, this method converts the sequence of frames to a dictionary of frames in accordance with the input to ProductFrame.__init__() by using the positions along the sequence as subsystem indices.

Below are some examples:

>>> from qiskit.quantum_info import Operator
>>> from povm_toolbox.quantum_info import SingleQubitPOVM, MultiQubitPOVM, ProductPOVM
>>> sqp = SingleQubitPOVM([Operator.from_label("0"), Operator.from_label("1")])
>>> product = ProductPOVM.from_list([sqp, sqp])
>>> # is equivalent to
>>> product = ProductPOVM({(0,): sqp, (1,): sqp})
>>> mqp = MultiQubitPOVM(
...     [
...         Operator.from_label("00"),
...         Operator.from_label("01"),
...         Operator.from_label("10"),
...         Operator.from_label("11"),
...     ]
... )
>>> product = ProductPOVM.from_list([mqp, mqp])
>>> # is equivalent to
>>> product = ProductPOVM({(0, 1): mqp, (2, 3): mqp})
>>> product = ProductPOVM.from_list([sqp, sqp, mqp])
>>> # is equivalent to
>>> product = ProductPOVM({(0,): sqp, (1,): sqp, (2, 3): mqp})
>>> product = ProductPOVM.from_list([sqp, mqp, sqp])
>>> # is equivalent to
>>> product = ProductPOVM({(0,): sqp, (1, 2): mqp, (3,): sqp})
Parameters:

frames (Sequence[T]) – a sequence of MultiQubitFrame objects.

Returns:

A new ProductFrame instance.

Return type:

Self