Skip to main content

Python Signals

PyPI Python License: MIT CI Docs

Uniformly sampled axes and signals on them, for any kind of numerical application, classical or quantum. It depends on NumPy and qiu-python-encore, and optionally on SymPy.

The quantum packages of this monorepo, e.g. qiu-quantum-computing, encode these signals in the basis states of qubit registers, and qiu-classical-simulation builds its optical elements on them.

Installation

pip install qiu-signals

Concepts

Axes

Axes come in two layers, each in its own module together with the enum it uses:

  • integer_axis.IntegerAxis(size, ordering) is a set of size uniformly spaced samples labeled by integer indices. The sample at array position k has the index index[k], fixed by the axis ordering (integer_axis.IndexOrdering).

  • physical_axis.PhysicalAxis(size, period, ordering, domain) is an IntegerAxis placed in a physical domain, with a spacing period between neighboring samples. The sample at array position k lies at

    values[k] = index[k] * period
    

The orderings of the integer indices are:

ordering indices for size = 4 indices for size = 5 equivalent to
NATURAL 0, 1, 2, 3 0, 1, 2, 3, 4 numpy.arange(size)
FFT 0, 1, -2, -1 0, 1, 2, -2, -1 numpy.fft.fftfreq(size) * size
CENTERED -2, -1, 0, 1 -2, -1, 0, 1, 2 numpy.fft.fftshift of the FFT ones

The FFT ordering is the one in which numpy.fft returns the transform of a signal, so a Fourier conjugate axis defaults to it.

The domain (physical_axis.AxisDomain) of a physical axis is POSITION, or one of its Fourier conjugates MOMENTUM, ANGULAR_WAVENUMBER and SPATIAL_FREQUENCY. The concrete physical axis classes in physical_axis fix the domain:

  • PositionAxis(size, delta_x, ordering) samples positions spaced by delta_x.
  • MomentumAxis(size, delta_p, ordering), AngularWavenumberAxis(size, delta_k, ordering) and SpatialFrequencyAxis(size, delta_f, ordering) sample the Fourier conjugate domains with the given spacing.
  • Their from_position_axis constructors create the axis conjugate to a position axis of size samples spaced by delta_x, with the spacing of the discrete Fourier transform: 2 pi hbar / (size delta_x), 2 pi / (size delta_x) and 1 / (size delta_x) respectively (see reciprocal_period). MomentumAxis.from_position_axis(position_axis, hbar) has no default for hbar, so the units are always explicit, e.g. scipy.constants.hbar for SI or 1.0 for natural units.

Signals

A signal lives on a PhysicalAxis, and comes in two forms:

  • signal.Signal(axis, data) is given by its sampled values: data[k] is the value at axis.values[k], real or complex. normalized_data holds the values scaled to unit Euclidean norm.
  • algebraic_signal.AlgebraicSignal(axis, function) is given by an algebraic expression of the axis values, held as a vectorized function such as a lambda or a NumPy function. data evaluates it on the axis values, calling the signal evaluates it at arbitrary values, and to_signal() returns the sampled Signal.
    • AlgebraicSignal.from_sympy(axis, expression, symbol=None) creates it from a SymPy expression (or a string SymPy parses), keeping the symbolic expression and its symbol for inspection. It needs the optional sympy extra, qiu-signals[sympy].
    • PolynomialSignal(axis, alpha, power) is the algebraic signal alpha * x**power. Its effective_alpha is the coefficient in terms of the integer indices, so that data == effective_alpha * axis.index**power.
    • QuadraticSignal(axis, alpha) is the polynomial signal of power 2, also called an intensity signal.
  • algebraic_signal.SampledSignal is the type Signal | AlgebraicSignal, for code that only needs the axis and the sampled values data of either kind.

The SignalFunctionType aliases for the functions of algebraic signals live in algebraic_signal as well.

Arithmetic

Signals support +, -, *, /, ** and negation, elementwise, with scalars (from either side) and with signals on an equal axis (axes compare by value). Raw NumPy arrays are rejected rather than silently broadcast.

operands result
Signal and scalar or Signal a Signal of the combined samples
AlgebraicSignal and scalar or AlgebraicSignal an AlgebraicSignal of the composed functions, and of the composed SymPy expressions if both operands have one
AlgebraicSignal and Signal a Signal, sampling the algebraic operand first
PolynomialSignal * or / scalar a PolynomialSignal (or QuadraticSignal) with the scaled alpha, so effective_alpha stays available

Usage

import numpy as np
import sympy
from qiu_signals.algebraic_signal import AlgebraicSignal, QuadraticSignal
from qiu_signals.integer_axis import IndexOrdering
from qiu_signals.physical_axis import PositionAxis, SpatialFrequencyAxis
from qiu_signals.signal import Signal

x_axis = PositionAxis(size=256, delta_x=0.1, ordering=IndexOrdering.FFT)

# an algebraic signal, from a lambda or from a symbolic expression
gaussian = AlgebraicSignal(x_axis, lambda x: np.exp(-(x**2)))
x = sympy.Symbol("x")
symbolic = AlgebraicSignal.from_sympy(x_axis, sympy.exp(-(x**2)))
assert np.allclose(gaussian.data, symbolic.data)
assert sympy.diff(symbolic.expression, x) == -2 * x * sympy.exp(-(x**2))

# the spectrum is a sampled signal on the conjugate axis, in the same ordering
f_axis = SpatialFrequencyAxis.from_position_axis(x_axis)
spectrum = Signal(f_axis, np.fft.fft(gaussian.data))
assert np.allclose(f_axis.values, np.fft.fftfreq(256, d=0.1))

# a quadratic phase profile, and its coefficient in terms of the integer indices
lens = QuadraticSignal(x_axis, alpha=-0.5)
assert np.allclose(lens.data, lens.effective_alpha * x_axis.index**2)

# arithmetic: scaled monomials stay monomials, other combinations are algebraic
phase = -0.1 * lens
assert isinstance(phase, QuadraticSignal)
beam = 2 * gaussian + symbolic
assert beam.expression is None and np.allclose(beam.data, 3 * gaussian.data)
assert (2 * symbolic + 1).expression == 2 * sympy.exp(-(x**2)) + 1

Documentation

The documentation, with the API reference from the docstrings, is built from docs/ with MkDocs and published at https://blackwild.github.io/qiu/qiu-signals/. To serve it locally, from the repository root:

uv run mkdocs serve -f packages/qiu-signals/mkdocs.yml

Tests

From the repository root:

uv run pytest packages/qiu-signals

Release files for qiu-signals 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for qiu-signals 0.1.0
File Size Uploaded
qiu_signals-0.1.0.tar.gz 11.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for qiu-signals 0.1.0
File Interpreter ABI Platform
qiu_signals-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 27.1 kB

Release files / qiu_signals-0.1.0.tar.gz

Download URL qiu_signals-0.1.0.tar.gz
Size 11.8 kB
Tags Source
SHA-256 checksum
How to use checksums
f2d58a0a99e7e4f0ae0e9c09dfbc71ba8bae65cf515be61c57bb2cf9083b3c99
BLAKE2b-256 checksum
How to use checksums
b851d1221a1f00564294c7e703606df2f3ebc8943271def8715344e0c1925607
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.18 {"installer":{"name":"uv","version":"0.12.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / qiu_signals-0.1.0-py3-none-any.whl

Download URL qiu_signals-0.1.0-py3-none-any.whl
Size 15.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
23840b9badcce4fc3f5d0420a03a35c7171b6fb73df83f7b4fbbcf522d768d6f
BLAKE2b-256 checksum
How to use checksums
264a8d7e95ac04cfa746536fec4db4d23d5432c82d17c7fe244d62cc518efada
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.18 {"installer":{"name":"uv","version":"0.12.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page