Skip to content

Quantum

Quantum realizations shared by the physics packages: spins, qubits, bosonic modes, and lattice sites.

ModeElement(label, psi=0, *, hilbert=None, visual=VisualSpec('expectations'))

Bases: Element

Bosonic mode of the Hilbert space it takes, with annihilate, create, and number.

Parameters:

Name Type Description Default
label str

The label of the mode.

required
psi Annotated[object, StateSpec(domain=CC)]

The state in the Hilbert space: the number of quanta, or a vector.

0
hilbert HilbertSpec | None

The Hilbert space, mode_space(quanta).

None
visual VisualSpec | None

How the mode is drawn.

VisualSpec('expectations')

Examples:

>>> from skcomplex.models.physics.common.quantum import ModeElement, mode_space
>>> ModeElement('cavity', hilbert=mode_space(4)).hilbert.dimension
5
Source code in src/skcomplex/models/physics/common/quantum/_mode.py
36
37
38
39
40
41
42
43
44
45
46
def __init__(
    self,
    label: str,
    psi: Annotated[object, StateSpec(domain=CC)] = 0,
    *,
    hilbert: HilbertSpec | None = None,
    visual: VisualSpec | None = VisualSpec('expectations'),
) -> None:
    super().__init__(label, visual=visual)
    self.psi = psi
    self.hilbert = hilbert

QubitElement(label, psi='up', *, hilbert=QUBIT, visual=VisualSpec('expectations'))

Bases: Element

Two-level system with the Pauli matrices x, y, z and the ladder operators plus and minus.

The state 'up', also 'excited', is index 0 with z = 1, and 'down', also 'ground', is index 1.

Parameters:

Name Type Description Default
label str

The label of the qubit.

required
psi Annotated[object, StateSpec(domain=CC)]

The state in the Hilbert space: 'up', 'down', 'excited', 'ground', a basis index, or a vector.

'up'
hilbert HilbertSpec

The Hilbert space of the qubit.

QUBIT
visual VisualSpec | None

How the qubit is drawn.

VisualSpec('expectations')

Examples:

>>> from skcomplex.models.physics.common.quantum import QubitElement
>>> sorted(QubitElement('q').hilbert.operators)
['minus', 'plus', 'x', 'y', 'z']
Source code in src/skcomplex/models/physics/common/quantum/_qubit.py
51
52
53
54
55
56
57
58
59
60
61
def __init__(
    self,
    label: str,
    psi: Annotated[object, StateSpec(domain=CC)] = 'up',
    *,
    hilbert: HilbertSpec = QUBIT,
    visual: VisualSpec | None = VisualSpec('expectations'),
) -> None:
    super().__init__(label, visual=visual)
    self.psi = psi
    self.hilbert = hilbert

SiteElement(label, psi=0, *, hilbert=None, visual=VisualSpec('expectations'))

Bases: Element

Single particle on the sites of a lattice or a network, whose basis state k is the particle at site k.

Its laws read the operators of site_space: laplacian, adjacency, and potential.

Parameters:

Name Type Description Default
label str

The label of the particle.

required
psi Annotated[object, StateSpec(domain=CC)]

The state in the Hilbert space: the initial site, or a vector of amplitudes over the sites.

0
hilbert HilbertSpec | None

The Hilbert space, site_space(space, potential).

None
visual VisualSpec | None

How the particle is drawn.

VisualSpec('expectations')

Examples:

>>> from skcomplex.core.spaces import LatticeSpace
>>> from skcomplex.models.physics.common.quantum import SiteElement, site_space
>>> SiteElement('particle', hilbert=site_space(LatticeSpace(16))).hilbert.dimension
16
Source code in src/skcomplex/models/physics/common/quantum/_site.py
39
40
41
42
43
44
45
46
47
48
49
def __init__(
    self,
    label: str,
    psi: Annotated[object, StateSpec(domain=CC)] = 0,
    *,
    hilbert: HilbertSpec | None = None,
    visual: VisualSpec | None = VisualSpec('expectations'),
) -> None:
    super().__init__(label, visual=visual)
    self.psi = psi
    self.hilbert = hilbert

SpinElement(label, psi='up', *, hilbert=SPIN_HALF, visual=VisualSpec('expectations'))

Bases: Element

Spin of the Hilbert space it takes, with the spin components x, y, z and the ladder operators.

The basis is ordered from m = j to m = -j, so 'up' is index 0 and 'down' is the last index. Its laws read the operators of its state psi, such as local_operator(namespace.psi, 'z').

Parameters:

Name Type Description Default
label str

The label of the spin.

required
psi Annotated[object, StateSpec(domain=CC)]

The state in the Hilbert space: 'up', 'down', a basis index, or a vector.

'up'
hilbert HilbertSpec

The Hilbert space, spin_space(j), by default that of a spin one half.

SPIN_HALF
visual VisualSpec | None

How the spin is drawn.

VisualSpec('expectations')

Examples:

>>> from skcomplex.models.physics.common.quantum import SpinElement, spin_space
>>> SpinElement('s', hilbert=spin_space(1)).hilbert.dimension
3
Source code in src/skcomplex/models/physics/common/quantum/_spin.py
82
83
84
85
86
87
88
89
90
91
92
def __init__(
    self,
    label: str,
    psi: Annotated[object, StateSpec(domain=CC)] = 'up',
    *,
    hilbert: HilbertSpec = SPIN_HALF,
    visual: VisualSpec | None = VisualSpec('expectations'),
) -> None:
    super().__init__(label, visual=visual)
    self.psi = psi
    self.hilbert = hilbert

mode_space(quanta=4)

Return the Hilbert space of a bosonic mode truncated at a number of quanta.

Its operators are annihilate, create, and number, and its basis state n holds n quanta.

Parameters:

Name Type Description Default
quanta int

The largest number of quanta, so the dimension is quanta + 1.

4

Returns:

Name Type Description
space HilbertSpec

The Hilbert space.

Raises:

Type Description
ValidationError

The number of quanta is not a positive integer.

Examples:

>>> from skcomplex.models.physics.common.quantum import mode_space
>>> mode_space(4).dimension
5
Source code in src/skcomplex/models/physics/common/quantum/_quantum.py
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
def mode_space(quanta: int = 4) -> HilbertSpec:
    """Return the Hilbert space of a bosonic mode truncated at a number of quanta.

    Its operators are `annihilate`, `create`, and `number`, and its basis state `n` holds `n` quanta.

    Args:
        quanta:
            The largest number of quanta, so the dimension is `quanta + 1`.

    Returns:
        space:
            The Hilbert space.

    Raises:
        ValidationError:
            The number of quanta is not a positive integer.

    Examples:
        >>> from skcomplex.models.physics.common.quantum import mode_space
        >>> mode_space(4).dimension
        5
    """
    if isinstance(quanta, bool) or not isinstance(quanta, int | np.integer) or quanta < 1:
        error_msg = f'A mode has quanta = {quanta!r}, which is not a positive integer.'
        raise ValidationError(error_msg)
    size = int(quanta) + 1
    operators = {
        'annihilate': (qutip.destroy(size).full(), False),
        'create': (qutip.create(size).full(), False),
        'number': (qutip.num(size).full(), True),
    }
    return HilbertSpec(size, operators, display='number')

site_space(space, potential=None, *, projectors=False)

Return the Hilbert space of a particle on the sites of a lattice or a network, whose basis state k is site k.

Its operators are the Laplacian, laplacian, the adjacency of the neighbouring sites, adjacency, with a potential the operator potential with the potential of every site on its diagonal, and with projectors the projector site_<k> on every site k. The Laplacian of a lattice is spectral when the lattice is periodic and of finite differences otherwise, with the spacing of the lattice, and the Laplacian of a network is its graph Laplacian.

Parameters:

Name Type Description Default
space BaseSpace

The lattice or the network.

required
potential ArrayLike | None

The potential of every site, or None for no potential.

None
projectors bool

Whether the space holds the projector on every site.

False

Returns:

Name Type Description
space HilbertSpec

The Hilbert space, of the dimension of the number of sites.

Raises:

Type Description
ValidationError

The space is neither a lattice nor a network.

Examples:

>>> from skcomplex.core.spaces import LatticeSpace
>>> from skcomplex.models.physics.common.quantum import site_space
>>> float(site_space(LatticeSpace(16, boundary='fixed')).operators['laplacian'][0].trace())
-32.0
Source code in src/skcomplex/models/physics/common/quantum/_quantum.py
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
def site_space(space: BaseSpace, potential: npt.ArrayLike | None = None, *, projectors: bool = False) -> HilbertSpec:
    """Return the Hilbert space of a particle on the sites of a lattice or a network, whose basis state `k` is site `k`.

    Its operators are the Laplacian, `laplacian`, the adjacency of the neighbouring sites, `adjacency`, with a
    potential the operator `potential` with the potential of every site on its diagonal, and with projectors the
    projector `site_<k>` on every site `k`. The Laplacian of a lattice is spectral when the lattice is periodic and
    of finite differences otherwise, with the spacing of the lattice, and the Laplacian of a network is its graph
    Laplacian.

    Args:
        space:
            The lattice or the network.

        potential:
            The potential of every site, or `None` for no potential.

        projectors:
            Whether the space holds the projector on every site.

    Returns:
        space:
            The Hilbert space, of the dimension of the number of sites.

    Raises:
        ValidationError:
            The space is neither a lattice nor a network.

    Examples:
        >>> from skcomplex.core.spaces import LatticeSpace
        >>> from skcomplex.models.physics.common.quantum import site_space
        >>> float(site_space(LatticeSpace(16, boundary='fixed')).operators['laplacian'][0].trace())
        -32.0
    """
    if not isinstance(space, LatticeSpace | NetworkSpace):
        error_msg = f'A particle on sites needs a LatticeSpace or a NetworkSpace, not {space!r}.'
        raise ValidationError(error_msg)
    prepared = space.check().prepare()
    size = int(prepared.size_)
    adjacency = np.zeros((size, size))
    for first, second in prepared._neighbor_pairs():
        adjacency[first, second] = adjacency[second, first] = 1.0
    laplacian = (
        _lattice_laplacian(prepared)
        if isinstance(prepared, LatticeSpace)
        else adjacency - np.diag(adjacency.sum(axis=1))
    )
    operators = {'laplacian': (laplacian, True), 'adjacency': (adjacency, True)}
    if potential is not None:
        operators['potential'] = (np.diag(np.broadcast_to(np.asarray(potential, dtype=float), (size,))), True)
    for site in range(size if projectors else 0):
        operators[f'site_{site}'] = (sp.csr_array(([1.0], ([site], [site])), shape=(size, size)), True)
    return HilbertSpec(size, operators, display=None)

spin_space(j=0.5)

Return the Hilbert space of a spin of quantum number j, with the basis from m = j down to m = -j.

Its operators are the spin components x, y, z and the ladder operators plus and minus.

Parameters:

Name Type Description Default
j float

The spin quantum number, a positive multiple of one half.

0.5

Returns:

Name Type Description
space HilbertSpec

The Hilbert space, of dimension 2 j + 1.

Raises:

Type Description
ValidationError

The quantum number is not a positive multiple of one half.

Examples:

>>> from skcomplex.models.physics.common.quantum import spin_space
>>> spin_space(1).dimension
3
Source code in src/skcomplex/models/physics/common/quantum/_spin.py
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
def spin_space(j: float = 0.5) -> HilbertSpec:
    """Return the Hilbert space of a spin of quantum number `j`, with the basis from `m = j` down to `m = -j`.

    Its operators are the spin components `x`, `y`, `z` and the ladder operators `plus` and `minus`.

    Args:
        j:
            The spin quantum number, a positive multiple of one half.

    Returns:
        space:
            The Hilbert space, of dimension `2 j + 1`.

    Raises:
        ValidationError:
            The quantum number is not a positive multiple of one half.

    Examples:
        >>> from skcomplex.models.physics.common.quantum import spin_space
        >>> spin_space(1).dimension
        3
    """
    size = 2 * j + 1
    if not float(size).is_integer() or size < MIN_SPIN_DIMENSION:
        error_msg = f'A spin has j = {j!r}, which is not a positive multiple of one half.'
        raise ValidationError(error_msg)
    operators = {
        'x': (qutip.jmat(j, 'x').full(), True),
        'y': (qutip.jmat(j, 'y').full(), True),
        'z': (qutip.jmat(j, 'z').full(), True),
        'plus': (qutip.jmat(j, '+').full(), False),
        'minus': (qutip.jmat(j, '-').full(), False),
    }
    return HilbertSpec(int(size), operators, basis={'up': 0, 'down': int(size) - 1})