bits

Defines various classes describing classical or quantum bits.

Bits are identified by unique identifiers, which can by any hashable, comparable type.

Defines classical bits (Cbit) and logical operations on them as well as quantum bits (Qubit).

Supplies helper functions get_q and get_c for easily creating qubits and classical bits from their identifiers.

class parityos.bits.Identifier(*args, **kwargs)

Bases: Hashable, SupportsLessThan, Protocol

A class representing hashable, comparable identifiers.

class parityos.bits.IdentifierT_co

A covariant TypeVar representing an Identifier.

alias of TypeVar(‘IdentifierT_co’, bound=Identifier, covariant=True)

class parityos.bits.Bit

Bases: Generic[IdentifierT_co], ABC

Interface for quantum bits and classical bits.

All bits can be uniquely identified by their hashable, comparable id identifier.

STR_PREFIX: ClassVar[str]

Prefix to be added before id in the string representation for discriminating different Bit types. Subclasses can override this ClassVar.

Example

>>> print(Cbit(3))
# 'c_3'
>>> print(Qubit("a"))
# 'q_a'
abstract property id: IdentifierT_co

Hashable comparable identifier used as unique identifier for this bit.

class parityos.bits.BitT

A TypeVar representing a Bit.

alias of TypeVar(‘BitT’, bound=Bit)

class parityos.bits.HasFrozenCBits

Bases: ABC

Mixin interface for an object holding an immutable collection of classical bits.

property cbits: frozenset[Cbit]

An unordered set of classical bits this object is defined on.

property ordered_cbits: tuple[Cbit, ...]

An ordered sequence of classical bits this object is defined on.

class parityos.bits.HasFrozenUnorderedCBits

Bases: HasFrozenCBits, ABC

Mixin interface for an object holding an unordered set of classical bits.

property ordered_cbits: tuple[Cbit, ...]

A sorted tuple of the unordered set of classical bits this object is defined on.

class parityos.bits.HasFrozenOrderedCBits

Bases: HasFrozenCBits, ABC

Mixin interface for an object holding an ordered sequence of classical bits.

property cbits: frozenset[Cbit]

An unordered set of classical bits this object is defined on.

class parityos.bits.Logical

Bases: ABC

Mixin interface for logical operations on classical bits.

Supported logical operations:

  • NOT (~)

  • AND (&)

  • OR (|)

  • XOR (^)

Examples

>>> a, b, c = Cbit(1), Cbit(2), Cbit(3)
>>> (~a | b) ^ (a & b & ~c)
>>> # CbitExpression(expr=(c_2 | ~c_1) ^ (c_1 & c_2 & ~c_3))
property expr: Boolean

The underlying symbolic Boolean expression of this object.

class parityos.bits.Cbit(id: int)

Bases: Bit[int], Logical

A classical bit that can be used as output for measurements and classical control logic within a quantum circuit.

STR_PREFIX: ClassVar[str] = 'c_'

Prefix to be added before id in the string representation for discriminating different Bit types. Subclasses can override this ClassVar.

Example

>>> print(Cbit(3))
# 'c_3'
>>> print(Qubit("a"))
# 'q_a'
id: int

Integer identifier for this classical bit.

expr: Boolean
classmethod from_str(str_representation: str) Self

Convert from a string representation to a classical bit.

Caution

str_representation must start with STR_PREFIX and the remaining part must be convertible to an integer.

Parameters:

str_representation – The string to be converted. Must start with STR_PREFIX and continue with a string that can be converted to an integer.

Returns:

A classical bit from the input.

Raises:
class parityos.bits.CbitExpression(expr: Boolean)

Bases: Logical, HasFrozenCBits

An expression consisting of classical bits.

CbitExpression instances are usually the result of logical operations on elementary Cbit instances.

Examples

>>> a, b, c = Cbit(1), Cbit(2), Cbit(3)
>>> (~a | b) ^ (a & b & ~c)
>>> # CbitExpression(expr=(c_2 | ~c_1) ^ (c_1 & c_2 & ~c_3))

Note

While a CbitExpression can be directly created from a Boolean expression, the simpler and more natural way to create one is through boolean arithmetic on Cbit instances.

expr: Boolean

Boolean expression of this classical bit expression.

cbits: frozenset[Cbit]
ordered_cbits: tuple[Cbit, ...]
parityos.bits.reduce_and(*args: Logical) CbitExpression

Join all input args with logical AND (&).

Example

>>> c0, c1, c2 = Cbit(0), Cbit(1), Cbit(2)
>>> assert reduce_and(c0, c1, c2) == c0 & c1 & c2
parityos.bits.reduce_or(*args: Logical) CbitExpression

Join all input args with logical OR (|).

Example

>>> c0, c1, c2 = Cbit(0), Cbit(1), Cbit(2)
>>> assert reduce_or(c0, c1, c2) == c0 | c1 | c2
parityos.bits.reduce_xor(*args: Logical) CbitExpression

Join all input args with logical XOR (^).

Example

>>> c0, c1, c2 = Cbit(0), Cbit(1), Cbit(2)
>>> assert reduce_xor(c0, c1, c2) == c0 ^ c1 ^ c2
class parityos.bits.Qubit(id: IdentifierT_co)

Bases: Bit[IdentifierT_co]

A quantum bit.

Used as arguments to Operator or State instances to define the Hilbert space these objects act or are defined on.

Note

A Qubit is an abstract binary quantum variable with a unique identifier and is a priori not associated with any operator eigenbasis (e.g. Pauli Basis). Associations with operator eigenspaces is done in various classes containing qubits (cf. e.g. PauliBasisState).

STR_PREFIX: ClassVar[str] = 'q_'

Prefix to be added before id in the string representation for discriminating different Bit types. Subclasses can override this ClassVar.

Example

>>> print(Cbit(3))
# 'c_3'
>>> print(Qubit("a"))
# 'q_a'
id: IdentifierT_co

Hashable, comparable identifier for this quantum bit.

class parityos.bits.QubitT

A TypeVar representing a Qubit.

alias of TypeVar(‘QubitT’, bound=Qubit)

class parityos.bits.QubitT_co

A covariant TypeVar representing a Qubit.

alias of TypeVar(‘QubitT_co’, bound=Qubit, covariant=True)

class parityos.bits.OtherQubitT

A TypeVar representing another Qubit.

alias of TypeVar(‘OtherQubitT’, bound=Qubit)

class parityos.bits.OtherQubitT_co

A covariant TypeVar representing another Qubit.

alias of TypeVar(‘OtherQubitT_co’, bound=Qubit, covariant=True)

class parityos.bits.HasFrozenQubits

Bases: Generic[QubitT_co], ABC

Mixin interface for an object with qubits.

property qubit_types: frozenset[type[QubitT_co]]

The set of qubit types this object is defined on.

property qubits: frozenset[QubitT_co]

Unordered set of qubits this object is defined on.

property ordered_qubits: tuple[QubitT_co, ...]

Ordered sequence of qubits this object is defined on.

class parityos.bits.HasFrozenUnorderedQubits

Bases: HasFrozenQubits[QubitT_co], ABC

Mixin interface for an object with an unordered set of qubits.

property ordered_qubits: tuple[QubitT_co, ...]

Sorted tuple of the qubits this object is defined on.

class parityos.bits.HasFrozenOrderedQubits

Bases: HasFrozenQubits[QubitT_co], ABC

Mixin interface for an object with an ordered sequence of qubits.

property qubits: frozenset[QubitT_co]

Unordered set of qubits this object is defined on.

parityos.bits.get_q(x: RealT, y: RealT) Qubit[Point2D[RealT]]
parityos.bits.get_q(coordinates: tuple[RealT, RealT]) Qubit[Point2D[RealT]]
parityos.bits.get_q(x: RealT, y: RealT, z: RealT) Qubit[Point3D[RealT]]
parityos.bits.get_q(coordinates: tuple[RealT, RealT, RealT]) Qubit[Point3D[RealT]]
parityos.bits.get_q(id: IdentifierT_co) Qubit[IdentifierT_co]

Helper function for easily creating different kinds of qubits from various formats of their identifiers.

Examples

>>> assert get_q(1) == Qubit(1)
>>> assert get_q("A") == Qubit("A")
>>> assert get_q(0, 1) == Qubit(Point2D(0, 1))
>>> assert get_q((0, 1)) == Qubit(Point2D(0, 1))
>>> assert get_q(Point2D(0, 1)) == Qubit(Point2D(0, 1))
>>> assert get_q(0, 1, 2) == Qubit(Point3D(0, 1, 2))
>>> assert get_q((0, 1, 2)) == Qubit(Point3D(0, 1, 2))
>>> assert get_q(Point3D(0, 1, 2)) == Qubit(Point3D(0, 1, 2))
parityos.bits.get_c(identifier: int) Cbit

Helper function for easily creating a classical bit.

Example

>>> assert get_c(1) == Cbit(1)