Skip to content

Base

AbstractOp

Bases: Module

An abstract base class for all quantum objects, including states, gates, channels, and measurements. It provides a common interface for various quantum objects, ensuring consistency and reusability across different types of quantum operations.

Attributes:

Name Type Description
wires tuple[int, ...]

A tuple of nonnegative integers representing the quantum wires on which the operation acts. Each wire corresponds to a specific subsystem in the composite quantum system.

Source code in src/squint/ops/base.py
class AbstractOp(eqx.Module):
    """
    An abstract base class for all quantum objects, including states, gates, channels, and measurements.
    It provides a common interface for various quantum objects, ensuring consistency and reusability across different types
    of quantum operations.

    Attributes:
        wires (tuple[int, ...]): A tuple of nonnegative integers representing the quantum wires
                                 on which the operation acts. Each wire corresponds to a specific subsystem
                                 in the composite quantum system.
    """

    wires: tuple[WiresTypes, ...]

    def __init__(
        self,
        wires: Sequence[WiresTypes],
    ):
        """
        Initializes the AbstractOp instance.

        Args:
            wires (tuple[int, ...], optional): A tuple of nonnegative integers representing the quantum wires
                                               on which the operation acts. Defaults to (0, 1).

        Raises:
            TypeError: If any wire in the provided tuple is not a nonnegative integer.
        """
        # if not all([wire >= 0 for wire in wires]):
        # raise TypeError("All wires must be nonnegative ints.")
        self.wires = wires
        return

    def unwrap(self):
        """
        A base method for unwrapping an operator into constituent parts, important in, e.g., shared weights across operators.

        This method can be overridden by subclasses to provide additional unwrapping functionality, such as
        decomposing composite operations into their components.

        Returns:
            ops (tuple[AbstractOp]): A tuple of AbstractOp which represent the constituent ops.
        """
        return (self,)

__init__(wires: Sequence[WiresTypes])

Initializes the AbstractOp instance.

Parameters:

Name Type Description Default
wires tuple[int, ...]

A tuple of nonnegative integers representing the quantum wires on which the operation acts. Defaults to (0, 1).

required

Raises:

Type Description
TypeError

If any wire in the provided tuple is not a nonnegative integer.

Source code in src/squint/ops/base.py
def __init__(
    self,
    wires: Sequence[WiresTypes],
):
    """
    Initializes the AbstractOp instance.

    Args:
        wires (tuple[int, ...], optional): A tuple of nonnegative integers representing the quantum wires
                                           on which the operation acts. Defaults to (0, 1).

    Raises:
        TypeError: If any wire in the provided tuple is not a nonnegative integer.
    """
    # if not all([wire >= 0 for wire in wires]):
    # raise TypeError("All wires must be nonnegative ints.")
    self.wires = wires
    return

unwrap()

A base method for unwrapping an operator into constituent parts, important in, e.g., shared weights across operators.

This method can be overridden by subclasses to provide additional unwrapping functionality, such as decomposing composite operations into their components.

Returns:

Name Type Description
ops tuple[AbstractOp]

A tuple of AbstractOp which represent the constituent ops.

Source code in src/squint/ops/base.py
def unwrap(self):
    """
    A base method for unwrapping an operator into constituent parts, important in, e.g., shared weights across operators.

    This method can be overridden by subclasses to provide additional unwrapping functionality, such as
    decomposing composite operations into their components.

    Returns:
        ops (tuple[AbstractOp]): A tuple of AbstractOp which represent the constituent ops.
    """
    return (self,)

AbstractState

Bases: AbstractOp

An abstract base class for all quantum states.

Source code in src/squint/ops/base.py
class AbstractState(AbstractOp):
    r"""
    An abstract base class for all quantum states.
    """

    def __init__(
        self,
        wires: Sequence[WiresTypes],
    ):
        super().__init__(wires=wires)
        return

    def __call__(self, dim: int):
        raise NotImplementedError

AbstractPureState

Bases: AbstractState

An abstract base class for all pure quantum states, equivalent to the state vector formalism. Pure states are associated with a Hilbert space of size, \(\ket{\rho} \in \mathcal{H}^{d_1 \times \dots \times d_w}\) and \(w=\) len(wires) and \(d\) is assigned at compile time.

Source code in src/squint/ops/base.py
class AbstractPureState(AbstractState):
    r"""
    An abstract base class for all pure quantum states, equivalent to the state vector formalism.
    Pure states are associated with a Hilbert space of size,
    $\ket{\rho} \in \mathcal{H}^{d_1 \times \dots \times d_w}$
    and $w=$ `len(wires)` and $d$ is assigned at compile time.
    """

    def __init__(
        self,
        wires: Sequence[WiresTypes],
    ):
        super().__init__(wires=wires)
        return

    def __call__(self, dim: int):
        raise NotImplementedError

AbstractMixedState

Bases: AbstractState

An abstract base class for all mixed quantum states, equivalent to the density matrix formalism. Mixed states are associated with a Hilbert space of size, \(\rho \in \mathcal{H}^{d_1 \times \dots \times d_w \times d_1 \times \dots \times d_w}\) and \(w=\) len(wires) and \(d\) is assigned at compile time.

Source code in src/squint/ops/base.py
class AbstractMixedState(AbstractState):
    r"""
    An abstract base class for all mixed quantum states, equivalent to the density matrix formalism.
    Mixed states are associated with a Hilbert space of size,
    $\rho \in \mathcal{H}^{d_1 \times \dots \times d_w \times d_1 \times \dots \times d_w}$
    and $w=$ `len(wires)` and $d$ is assigned at compile time.
    """

    def __init__(
        self,
        wires: Sequence[WiresTypes],
    ):
        super().__init__(wires=wires)
        return

    def __call__(self, dim: int):
        raise NotImplementedError

AbstractGate

Bases: AbstractOp

An abstract base class for all unitary quantum gates, which transform an input state in a reversible way. $ U \in \mathcal{H}^{d_1 \times \dots \times d_w \times d_1 \times \dots \times d_w}$ and \(w=\) len(wires) and \(d\) is assigned at compile time.

Source code in src/squint/ops/base.py
class AbstractGate(AbstractOp):
    r"""
    An abstract base class for all unitary quantum gates, which transform an input state in a reversible way.
    $ U \in \mathcal{H}^{d_1 \times \dots \times d_w \times d_1 \times \dots \times d_w}$
    and $w=$ `len(wires)` and $d$ is assigned at compile time.
    """

    def __init__(
        self,
        wires: Sequence[WiresTypes],
    ):
        super().__init__(wires=wires)
        return

    def __call__(self, dim: int):
        raise NotImplementedError

AbstractChannel

Bases: AbstractOp

An abstract base class for quantum channels, including channels expressed as Kraus operators, erasure (partial trace), and others.

Source code in src/squint/ops/base.py
class AbstractChannel(AbstractOp):
    r"""
    An abstract base class for quantum channels, including channels expressed as Kraus operators, erasure (partial trace), and others.
    """

    def __init__(
        self,
        wires: Sequence[WiresTypes],
    ):
        super().__init__(wires=wires)
        return

    def unwrap(self):
        return (self,)

    def __call__(self, dim: int):
        raise NotImplementedError

AbstractMeasurement

Bases: AbstractOp

An abstract base class for quantum measurements. Currently, this is not supported, and measurements are projective measurements in the computational basis.

Source code in src/squint/ops/base.py
class AbstractMeasurement(AbstractOp):
    r"""
    An abstract base class for quantum measurements. Currently, this is not supported, and measurements are projective measurements in the computational basis.
    """

    def __init__(
        self,
        wires: Sequence[WiresTypes],
    ):
        super().__init__(wires=wires)
        return

    def __call__(self, dim: int):
        raise NotImplementedError

SharedGate

Bases: AbstractGate

A class representing a shared quantum gate, which allows for the sharing of parameters or attributes across multiple copies of a quantum operation. This is useful for scenarios where multiple gates share the same underlying structure or parameters, such as in variational quantum circuits. This is most commonly used when applying the same parameterized gate across different wires, e.g., phase gates, for studying phase estimation protocols.

Attributes:

Name Type Description
op AbstractOp

The base quantum operation that is shared across multiple copies.

copies Sequence[AbstractOp]

A sequence of copies of the base operation, each acting on different wires.

where Callable

A function that determines which attributes of the operation are shared across copies.

get Callable

A function that retrieves the shared attributes from the base operation.

Source code in src/squint/ops/base.py
class SharedGate(AbstractGate):
    r"""
    A class representing a shared quantum gate, which allows for the sharing of parameters or attributes
    across multiple copies of a quantum operation. This is useful for scenarios where multiple gates
    share the same underlying structure or parameters, such as in variational quantum circuits.
    This is most commonly used when applying the same parameterized gate across different wires,
    e.g., phase gates, for studying phase estimation protocols.

    Attributes:
        op (AbstractOp): The base quantum operation that is shared across multiple copies.
        copies (Sequence[AbstractOp]): A sequence of copies of the base operation, each acting on different wires.
        where (Callable): A function that determines which attributes of the operation are shared across copies.
        get (Callable): A function that retrieves the shared attributes from the base operation.
    """

    op: AbstractOp
    copies: Sequence[AbstractOp]
    where: Callable
    get: Callable

    @beartype
    def __init__(
        self,
        op: AbstractOp,
        wires: Union[Sequence[WiresTypes], Sequence[Sequence[WiresTypes]]],
        where: Optional[Callable] = None,
        get: Optional[Callable] = None,
    ):
        # todo: handle the wires coming from both main and the shared wires
        copies = [eqx.tree_at(lambda op: op.wires, op, (wire,)) for wire in wires]
        self.copies = copies
        self.op = op

        if is_bearable(wires, Sequence[WiresTypes]):
            wires = op.wires + wires

        elif is_bearable(wires, Sequence[Sequence[WiresTypes]]):
            wires = op.wires + tuple(itertools.chain.from_iterable(wires))

        # wires = op.wires + wires
        super().__init__(wires=wires)

        # use a default where/get sharing mechanism, such that all ArrayLike attributes are shared exactly
        attrs = [key for key, val in op.__dict__.items() if eqx.is_array_like(val)]

        if where is None:  # todo: check  get/where functions if it is user-defined
            where = lambda pytree: sum(
                [[copy.__dict__[key] for copy in pytree.copies] for key in attrs], []
            )
        if get is None:
            get = lambda pytree: sum(
                [[pytree.op.__dict__[key] for _ in pytree.copies] for key in attrs], []
            )
        self.where = where
        self.get = get

        return

    def __check_init__(self):
        return object.__setattr__(
            self,
            "__dict__",
            eqx.tree_at(self.where, self, replace_fn=lambda _: None).__dict__,
        )

    def unwrap(self):
        """Unwraps the shared ops for compilation and contractions."""
        _self = eqx.tree_at(
            self.where, self, self.get(self), is_leaf=lambda leaf: leaf is None
        )
        return [_self.op] + [op for op in _self.copies]

unwrap()

Unwraps the shared ops for compilation and contractions.

Source code in src/squint/ops/base.py
def unwrap(self):
    """Unwraps the shared ops for compilation and contractions."""
    _self = eqx.tree_at(
        self.where, self, self.get(self), is_leaf=lambda leaf: leaf is None
    )
    return [_self.op] + [op for op in _self.copies]

AbstractKrausChannel

Bases: AbstractChannel

An abstract base class for quantum channels expressed as Kraus operators. The channel \(K\) is of shape \((d_1 \times \dots \times d_w \times d_1 \times \dots \times d_w)\) and \(w=\) len(wires) and \(d\) is assigned at compile time.

Source code in src/squint/ops/base.py
class AbstractKrausChannel(AbstractChannel):
    r"""
    An abstract base class for quantum channels expressed as Kraus operators.
    The channel $K$ is of shape $(d_1 \times \dots \times d_w \times d_1 \times \dots \times d_w)$
    and $w=$ `len(wires)` and $d$ is assigned at compile time.
    """

    def __init__(
        self,
        wires: Sequence[WiresTypes],
    ):
        super().__init__(wires=wires)
        return

    def unwrap(self):
        return (self,)

    def __call__(self, dim: int):
        raise NotImplementedError

AbstractErasureChannel

Bases: AbstractChannel

This channel traces out the local Hilbert space associated with the wires

Source code in src/squint/ops/base.py
class AbstractErasureChannel(AbstractChannel):
    """
    This channel traces out the local Hilbert space associated with the `wires`
    """

    @beartype
    def __init__(self, wires: Sequence[WiresTypes]):
        super().__init__(wires=wires)
        return

    def __call__(self, dim: int):
        return None

Block

Bases: Module

A block operation that represents a sequence of operations.

Source code in src/squint/ops/base.py
class Block(eqx.Module):
    """A block operation that represents a sequence of operations."""

    ops: OrderedDict[Union[str, int], AbstractOp]

    @beartype
    def __init__(
        self,
        ops: Optional[
            Union[dict[Union[str, int], AbstractOp], Sequence[AbstractOp]]
        ] = None,
    ) -> None:
        if ops is None:
            ops = OrderedDict()
        self.ops = ops

    @beartype
    def add(self, op: AbstractOp, key: str = None) -> None:
        """
        Add an operator to the block. Operators are added sequential along the wires.

        Args:
            op (AbstractOp): The operator instance to add to the circuit.
            key (Optional[str]): A string key for indexing into the circuit PyTree instance. Defaults to `None` and an integer counter is used.
        """

        if key is None:
            key = len(self.ops)
        self.ops[key] = op

    def unwrap(self) -> tuple[AbstractOp]:
        """
        Unwrap all operators in the circuit by recursively calling the `op.unwrap()` method.
        """
        return tuple(
            op for op_wrapped in self.ops.values() for op in op_wrapped.unwrap()
        )

add(op: AbstractOp, key: str = None) -> None

Add an operator to the block. Operators are added sequential along the wires.

Parameters:

Name Type Description Default
op AbstractOp

The operator instance to add to the circuit.

required
key Optional[str]

A string key for indexing into the circuit PyTree instance. Defaults to None and an integer counter is used.

None
Source code in src/squint/ops/base.py
@beartype
def add(self, op: AbstractOp, key: str = None) -> None:
    """
    Add an operator to the block. Operators are added sequential along the wires.

    Args:
        op (AbstractOp): The operator instance to add to the circuit.
        key (Optional[str]): A string key for indexing into the circuit PyTree instance. Defaults to `None` and an integer counter is used.
    """

    if key is None:
        key = len(self.ops)
    self.ops[key] = op

unwrap() -> tuple[AbstractOp]

Unwrap all operators in the circuit by recursively calling the op.unwrap() method.

Source code in src/squint/ops/base.py
def unwrap(self) -> tuple[AbstractOp]:
    """
    Unwrap all operators in the circuit by recursively calling the `op.unwrap()` method.
    """
    return tuple(
        op for op_wrapped in self.ops.values() for op in op_wrapped.unwrap()
    )

create(dim) cached

Returns the create operator for a Hilbert space of dimension dim. The create operator is a matrix that adds one excitation to a quantum system, effectively increasing the energy level by one. Args: dim (int): The dimension of the Hilbert space. Returns: jnp.ndarray: A 2D array of shape (dim, dim) representing the create operator.

Source code in src/squint/ops/base.py
@functools.cache
def create(dim):
    """
    Returns the create operator for a Hilbert space of dimension `dim`.
    The create operator is a matrix that adds one excitation to a quantum system,
    effectively increasing the energy level by one.
    Args:
        dim (int): The dimension of the Hilbert space.
    Returns:
        jnp.ndarray: A 2D array of shape (dim, dim) representing the create operator.
    """
    return jnp.diag(jnp.sqrt(jnp.arange(1, dim)), k=-1)

destroy(dim) cached

Returns the destroy operator for a Hilbert space of dimension dim. The destroy operator is a matrix that annihilates one excitation of a quantum system, effectively reducing the energy level by one. Args: dim (int): The dimension of the Hilbert space. Returns: jnp.ndarray: A 2D array of shape (dim, dim) representing the destroy operator.

Source code in src/squint/ops/base.py
@functools.cache
def destroy(dim):
    """
    Returns the destroy operator for a Hilbert space of dimension `dim`.
    The destroy operator is a matrix that annihilates one excitation of a quantum system,
    effectively reducing the energy level by one.
    Args:
        dim (int): The dimension of the Hilbert space.
    Returns:
        jnp.ndarray: A 2D array of shape (dim, dim) representing the destroy operator.
    """
    return jnp.diag(jnp.sqrt(jnp.arange(1, dim)), k=1)

eye(dim) cached

Returns the identity operator for a Hilbert space of dimension dim.

Parameters:

Name Type Description Default
dim int

The dimension of the Hilbert space.

required

Returns: jnp.ndarray: A 2D array of shape (dim, dim) representing the identity operator.

Source code in src/squint/ops/base.py
@functools.cache
def eye(dim):
    """
    Returns the identity operator for a Hilbert space of dimension `dim`.

    Args:
        dim (int): The dimension of the Hilbert space.
    Returns:
        jnp.ndarray: A 2D array of shape (dim, dim) representing the identity operator.
    """
    return jnp.eye(dim)

bases(dim) cached

Returns the computational basis indices for a Hilbert space of dimension dim.

Parameters:

Name Type Description Default
dim int

The dimension of the Hilbert space.

required

Returns:

Type Description

jnp.ndarray: A 1D array of shape (dim,) containing the indices of the computational bases.

Source code in src/squint/ops/base.py
@functools.cache
def bases(dim):
    """

    Returns the computational basis indices for a Hilbert space of dimension `dim`.

    Args:
        dim (int): The dimension of the Hilbert space.

    Returns:
        jnp.ndarray: A 1D array of shape (dim,) containing the indices of the computational bases.
    """
    return jnp.arange(dim)

dft(dim) cached

Returns the discrete Fourier transform matrix of dimension dim.

Parameters:

Name Type Description Default
dim int

The dimension of the DFT matrix.

required

Returns:

Type Description

jnp.ndarray: A 2D array of shape (dim, dim) representing the DFT matrix.

Source code in src/squint/ops/base.py
@functools.cache
def dft(dim):
    """
    Returns the discrete Fourier transform matrix of dimension `dim`.

    Args:
        dim (int): The dimension of the DFT matrix.

    Returns:
        jnp.ndarray: A 2D array of shape (dim, dim) representing the DFT matrix.
    """
    return jnp.array(sp.linalg.dft(dim, scale="sqrtn"))

basis_operators(dim) cached

Return a basis of orthogonal Hermitian operators on a Hilbert space of dimension \(d\), with the identity element in the last place. i.e., the Gell-Mann operators (for dim=2, these are the four Pauli operators).

Parameters:

Name Type Description Default
dim int

The dimension of the Hilbert space.

required

Returns:

Type Description

jnp.ndarray: A 3D array of shape (n_operators, dim, dim) containing the basis operators.

Source code in src/squint/ops/base.py
@functools.cache
def basis_operators(dim):
    """
    Return a basis of orthogonal Hermitian operators on a Hilbert space of
    dimension $d$, with the identity element in the last place.
    i.e., the Gell-Mann operators (for dim=2, these are the four Pauli operators).

    Args:
        dim (int): The dimension of the Hilbert space.

    Returns:
        jnp.ndarray: A 3D array of shape (n_operators, dim, dim) containing the basis operators.
    """
    return jnp.array(
        [
            gellmann(j, k, dim)
            for j, k in itertools.product(range(1, dim + 1), repeat=2)
        ],
        jnp.complex128,
    )