Skip to content

qiu_signals.physical_axis

Uniformly sampled axes for position and its Fourier conjugate domains.

Classes:

  • AxisDomain –

    Physical domains an axis can live in.

  • PhysicalAxis –

    A uniformly sampled axis in a physical domain.

  • PositionAxis –

    An axis representing position.

  • MomentumAxis –

    An axis representing momentum, the Fourier conjugate of a position axis.

  • AngularWavenumberAxis –

    An axis representing angular wavenumber, conjugate of a position axis.

  • SpatialFrequencyAxis –

    An axis representing spatial frequency, conjugate of a position axis.

Functions:

  • reciprocal_period –

    Return the sampling period of the Fourier conjugate of a position axis.

AxisDomain

Bases: ExtendedEnum

Physical domains an axis can live in.

Either the position domain, or one of its Fourier conjugate domains.

Attributes:

POSITION class-attribute instance-attribute

POSITION = 'position'

MOMENTUM class-attribute instance-attribute

MOMENTUM = 'momentum'

ANGULAR_WAVENUMBER class-attribute instance-attribute

ANGULAR_WAVENUMBER = 'angular_wavenumber'

SPATIAL_FREQUENCY class-attribute instance-attribute

SPATIAL_FREQUENCY = 'spatial_frequency'

is_in_fourier_domain property

is_in_fourier_domain: bool

Whether the domain is a Fourier conjugate of the position domain.

PhysicalAxis

PhysicalAxis(size: int, period: float, ordering: IndexOrdering, domain: AxisDomain)

Bases: IntegerAxis

A uniformly sampled axis in a physical domain.

The sample at array position k lies at index[k] * period, where the integer indices are given by the ordering of the axis.

Parameters:

  • size (int) –

    Number of samples, at least 1.

  • period (float) –

    Spacing between neighboring samples, positive and finite.

  • ordering (IndexOrdering) –

    Ordering of the integer indices of the samples.

  • domain (AxisDomain) –

    Physical domain the axis lives in.

Raises:

  • ValueError –

    If the size is smaller than 1, or if the period is not positive and finite.

Attributes:

Source code in packages/qiu-signals/src/qiu_signals/physical_axis.py
 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
def __init__(
    self,
    size: int,
    period: float,
    ordering: IndexOrdering,
    domain: AxisDomain,
) -> None:
    """Initialize a physical axis.

    Args:
        size: Number of samples, at least 1.
        period: Spacing between neighboring samples, positive and finite.
        ordering: Ordering of the integer indices of the samples.
        domain: Physical domain the axis lives in.

    Raises:
        ValueError: If the size is smaller than 1, or if the period is not positive
            and finite.
    """
    super().__init__(size=size, ordering=ordering)

    if not (np.isfinite(period) and period > 0):
        raise ValueError(f"The period must be positive and finite, got {period}.")

    self.period = period
    self.domain = AxisDomain(domain)

period instance-attribute

period: float = period

Spacing between neighboring samples.

domain instance-attribute

domain: AxisDomain = AxisDomain(domain)

Physical domain the axis lives in.

values property

values: NDArray[number]

Return the physical values of the samples.

sampling_window_length property

sampling_window_length: float

Return the total length of the sampling window.

is_fourier_domain property

is_fourier_domain: bool

Whether the axis lives in a Fourier conjugate domain of position.

PositionAxis

PositionAxis(size: int, delta_x: float, ordering: IndexOrdering)

Bases: PhysicalAxis

An axis representing position.

Parameters:

  • size (int) –

    Number of samples.

  • delta_x (float) –

    Spacing between the position samples.

  • ordering (IndexOrdering) –

    Ordering of the integer indices of the samples.

Source code in packages/qiu-signals/src/qiu_signals/physical_axis.py
147
148
149
150
151
152
153
154
155
156
157
158
159
160
def __init__(self, size: int, delta_x: float, ordering: IndexOrdering) -> None:
    """Initialize a position axis.

    Args:
        size: Number of samples.
        delta_x: Spacing between the position samples.
        ordering: Ordering of the integer indices of the samples.
    """
    super().__init__(
        size=size,
        period=delta_x,
        ordering=ordering,
        domain=AxisDomain.POSITION,
    )

MomentumAxis

MomentumAxis(size: int, delta_p: float, ordering: IndexOrdering)

Bases: PhysicalAxis

An axis representing momentum, the Fourier conjugate of a position axis.

Parameters:

  • size (int) –

    Number of samples.

  • delta_p (float) –

    Spacing between the momentum samples.

  • ordering (IndexOrdering) –

    Ordering of the integer indices of the samples.

Methods:

Source code in packages/qiu-signals/src/qiu_signals/physical_axis.py
166
167
168
169
170
171
172
173
174
175
176
177
178
179
def __init__(self, size: int, delta_p: float, ordering: IndexOrdering) -> None:
    """Initialize a momentum axis.

    Args:
        size: Number of samples.
        delta_p: Spacing between the momentum samples.
        ordering: Ordering of the integer indices of the samples.
    """
    super().__init__(
        size=size,
        period=delta_p,
        ordering=ordering,
        domain=AxisDomain.MOMENTUM,
    )

from_position_axis classmethod

from_position_axis(position_axis: PositionAxis, hbar: float, keep_ordering: bool = False) -> MomentumAxis

Create the momentum axis conjugate to a position axis.

The momentum spacing is $2 pi hbar / (N delta_x)$, see reciprocal_period.

Parameters:

  • position_axis (PositionAxis) –

    The position axis.

  • hbar (float) –

    Reduced Planck's constant, in the units of choice.

  • keep_ordering (bool, default: False ) –

    If True, retain the ordering of the position axis; otherwise, use the FFT ordering of the discrete Fourier transform.

Returns:

Source code in packages/qiu-signals/src/qiu_signals/physical_axis.py
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
@classmethod
def from_position_axis(
    cls,
    position_axis: PositionAxis,
    hbar: float,
    keep_ordering: bool = False,
) -> "MomentumAxis":
    """Create the momentum axis conjugate to a position axis.

    The momentum spacing is $2 pi hbar / (N delta_x)$, see `reciprocal_period`.

    Args:
        position_axis: The position axis.
        hbar: Reduced Planck's constant, in the units of choice.
        keep_ordering: If True, retain the ordering of the position axis;
            otherwise, use the `FFT` ordering of the discrete Fourier transform.

    Returns:
        The conjugate momentum axis.
    """
    return cls(
        size=position_axis.size,
        delta_p=reciprocal_period(
            position_axis.size,
            position_axis.period,
            AxisDomain.MOMENTUM,
            hbar=hbar,
        ),
        ordering=position_axis.ordering if keep_ordering else IndexOrdering.FFT,
    )

AngularWavenumberAxis

AngularWavenumberAxis(size: int, delta_k: float, ordering: IndexOrdering)

Bases: PhysicalAxis

An axis representing angular wavenumber, conjugate of a position axis.

Parameters:

  • size (int) –

    Number of samples.

  • delta_k (float) –

    Spacing between the angular wavenumber samples.

  • ordering (IndexOrdering) –

    Ordering of the integer indices of the samples.

Methods:

Source code in packages/qiu-signals/src/qiu_signals/physical_axis.py
216
217
218
219
220
221
222
223
224
225
226
227
228
229
def __init__(self, size: int, delta_k: float, ordering: IndexOrdering) -> None:
    """Initialize an angular wavenumber axis.

    Args:
        size: Number of samples.
        delta_k: Spacing between the angular wavenumber samples.
        ordering: Ordering of the integer indices of the samples.
    """
    super().__init__(
        size=size,
        period=delta_k,
        ordering=ordering,
        domain=AxisDomain.ANGULAR_WAVENUMBER,
    )

from_position_axis classmethod

from_position_axis(position_axis: PositionAxis, keep_ordering: bool = False) -> AngularWavenumberAxis

Create the angular wavenumber axis conjugate to a position axis.

The angular wavenumber spacing is $2 pi / (N delta_x)$, see reciprocal_period.

Parameters:

  • position_axis (PositionAxis) –

    The position axis.

  • keep_ordering (bool, default: False ) –

    If True, retain the ordering of the position axis; otherwise, use the FFT ordering of the discrete Fourier transform.

Returns:

Source code in packages/qiu-signals/src/qiu_signals/physical_axis.py
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
@classmethod
def from_position_axis(
    cls,
    position_axis: PositionAxis,
    keep_ordering: bool = False,
) -> "AngularWavenumberAxis":
    """Create the angular wavenumber axis conjugate to a position axis.

    The angular wavenumber spacing is $2 pi / (N delta_x)$, see
    `reciprocal_period`.

    Args:
        position_axis: The position axis.
        keep_ordering: If True, retain the ordering of the position axis;
            otherwise, use the `FFT` ordering of the discrete Fourier transform.

    Returns:
        The conjugate angular wavenumber axis.
    """
    return cls(
        size=position_axis.size,
        delta_k=reciprocal_period(
            position_axis.size,
            position_axis.period,
            AxisDomain.ANGULAR_WAVENUMBER,
        ),
        ordering=position_axis.ordering if keep_ordering else IndexOrdering.FFT,
    )

SpatialFrequencyAxis

SpatialFrequencyAxis(size: int, delta_f: float, ordering: IndexOrdering)

Bases: PhysicalAxis

An axis representing spatial frequency, conjugate of a position axis.

Parameters:

  • size (int) –

    Number of samples.

  • delta_f (float) –

    Spacing between the spatial frequency samples.

  • ordering (IndexOrdering) –

    Ordering of the integer indices of the samples.

Methods:

Source code in packages/qiu-signals/src/qiu_signals/physical_axis.py
264
265
266
267
268
269
270
271
272
273
274
275
276
277
def __init__(self, size: int, delta_f: float, ordering: IndexOrdering) -> None:
    """Initialize a spatial frequency axis.

    Args:
        size: Number of samples.
        delta_f: Spacing between the spatial frequency samples.
        ordering: Ordering of the integer indices of the samples.
    """
    super().__init__(
        size=size,
        period=delta_f,
        ordering=ordering,
        domain=AxisDomain.SPATIAL_FREQUENCY,
    )

from_position_axis classmethod

from_position_axis(position_axis: PositionAxis, keep_ordering: bool = False) -> SpatialFrequencyAxis

Create the spatial frequency axis conjugate to a position axis.

The spatial frequency spacing is $1 / (N delta_x)$, see reciprocal_period.

Parameters:

  • position_axis (PositionAxis) –

    The position axis.

  • keep_ordering (bool, default: False ) –

    If True, retain the ordering of the position axis; otherwise, use the FFT ordering of the discrete Fourier transform.

Returns:

Source code in packages/qiu-signals/src/qiu_signals/physical_axis.py
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
@classmethod
def from_position_axis(
    cls,
    position_axis: PositionAxis,
    keep_ordering: bool = False,
) -> "SpatialFrequencyAxis":
    """Create the spatial frequency axis conjugate to a position axis.

    The spatial frequency spacing is $1 / (N delta_x)$, see `reciprocal_period`.

    Args:
        position_axis: The position axis.
        keep_ordering: If True, retain the ordering of the position axis;
            otherwise, use the `FFT` ordering of the discrete Fourier transform.

    Returns:
        The conjugate spatial frequency axis.
    """
    return cls(
        size=position_axis.size,
        delta_f=reciprocal_period(
            position_axis.size,
            position_axis.period,
            AxisDomain.SPATIAL_FREQUENCY,
        ),
        ordering=position_axis.ordering if keep_ordering else IndexOrdering.FFT,
    )

reciprocal_period

reciprocal_period(size: int, delta_x: float, domain: AxisDomain, *, hbar: float | None = None) -> float

Return the sampling period of the Fourier conjugate of a position axis.

For a position axis of size samples spaced by delta_x, the discrete Fourier transform samples the conjugate domain with the period - $2 pi hbar / (N delta_x)$ for momentum, - $2 pi / (N delta_x)$ for angular wavenumber, - $1 / (N delta_x)$ for spatial frequency, where $N$ is the number of samples.

Parameters:

  • size (int) –

    Number of samples of the position axis.

  • delta_x (float) –

    Spacing between the samples of the position axis.

  • domain (AxisDomain) –

    The Fourier conjugate domain to compute the period for.

  • hbar (float | None, default: None ) –

    Reduced Planck's constant, in the units of choice. Must be given for the momentum domain, and only for it.

Returns:

  • float –

    The spacing between the samples of the conjugate axis.

Raises:

  • ValueError –

    If hbar is omitted for the momentum domain or given for another one, or if the domain is not a Fourier conjugate domain.

Source code in packages/qiu-signals/src/qiu_signals/physical_axis.py
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
def reciprocal_period(
    size: int, delta_x: float, domain: AxisDomain, *, hbar: float | None = None
) -> float:
    """Return the sampling period of the Fourier conjugate of a position axis.

    For a position axis of `size` samples spaced by `delta_x`, the discrete Fourier
    transform samples the conjugate domain with the period
        - $2 pi hbar / (N delta_x)$ for momentum,
        - $2 pi / (N delta_x)$ for angular wavenumber,
        - $1 / (N delta_x)$ for spatial frequency,
    where $N$ is the number of samples.

    Args:
        size: Number of samples of the position axis.
        delta_x: Spacing between the samples of the position axis.
        domain: The Fourier conjugate domain to compute the period for.
        hbar: Reduced Planck's constant, in the units of choice. Must be given for
            the momentum domain, and only for it.

    Returns:
        The spacing between the samples of the conjugate axis.

    Raises:
        ValueError: If `hbar` is omitted for the momentum domain or given for another
            one, or if the domain is not a Fourier conjugate domain.
    """

    if (domain == AxisDomain.MOMENTUM) != (hbar is not None):
        raise ValueError(
            "hbar must be given for the momentum domain, and only for it, "
            f"got hbar={hbar} for the {AxisDomain(domain).value} domain."
        )

    window_length = size * delta_x
    if domain == AxisDomain.MOMENTUM:
        return 2 * np.pi * hbar / window_length  # type: ignore[operator]
    if domain == AxisDomain.ANGULAR_WAVENUMBER:
        return 2 * np.pi / window_length
    if domain == AxisDomain.SPATIAL_FREQUENCY:
        return 1 / window_length
    raise ValueError(f"Not a Fourier conjugate domain: {domain}")