Skip to content

treams_rs.diff

Records: values with analytic first-order pushforward and pullback contexts.

A record is a function that returns a value and a reusable context. The context stores what is needed to compute derivatives later: context.pullback(g) takes the gradient g of a real-valued loss with respect to the value and returns the gradients with respect to the inputs, one for each differentiable input, in the order of the arguments. Gradients follow the convention dL = Re Σ conj(g)·dx.

The same context provides pushforward(*input_tangents), the first-order Jacobian-vector product. Input tangents have their original input shapes and follow the dynamic-input order; the result has the output's shape and tuple structure. Both derivative directions can be called repeatedly on the same context. Higher derivatives are unsupported.

One record used in both derivative directions:

import numpy as np
from treams_rs import diff

value, context = diff.solve(2 * np.eye(2), np.ones((2, 1)))
grad_operator, grad_rhs = context.pullback(np.ones((2, 1)))
assert value.shape == grad_rhs.shape == (2, 1)

tangent = context.pushforward(np.zeros((2, 2)), np.ones((2, 1)))
np.testing.assert_allclose(tangent, 0.5)

Terms:

  • record: a function of diff, or a record method, that returns (value, context).
  • context: the object that stores what the derivatives need. Repeated pushforward and pullback calls share its immutable residual.
  • residual: the Rust name of the data a context stores.
  • pullback: context.pullback(g), the map from the gradient with respect to the value to the gradients with respect to the inputs.
  • cotangent: the gradient g of the loss with respect to one value. It has the shape of that value and is complex for a complex value.
  • pushforward: context.pushforward(*tangents), the map from input perturbations to the corresponding output perturbation. Real inputs require real tangents; shape and finite-value errors leave the context available.
  • dynamic inputs: the inputs that get a gradient, in pullback order.
  • static configuration: labels, bases, cutoffs and options. They stay fixed and get no gradient. A record without gradients lists all its inputs here.

A pullback returns one gradient per dynamic input, in the order of the forward arguments; a basis contributes the gradient of its positions. Two variants change that list:

  • context.pullback_axial(g) of cylindrical expansions, fields and lattice expansions appends the gradient of the axial wavenumbers kz.
  • context.pullback_blocks(g) of factors built from separate particle blocks returns a list with one gradient per block in place of the local matrix.

pushforward_axial appends an axial-wavenumber tangent to the ordinary input tangents. pushforward_blocks takes a sequence of block tangents in place of the dense local matrix tangent. Both return the ordinary output tangent.

Objects record too: InteractionFactor.record(incident) (the factor that factor_interaction, factor_interaction_blocks and sphere_cluster_factor return) and iterative.SphereCluster.record.

advect.X differentiates diff.X in Advect. JAX, PyTorch and HIPS Autograd provide bessel, illuminate, interaction, solve and sphere directly, and wrap for other records. All four support first-order forward and reverse mode. NumPy physics objects (TMatrix, SMatrix, Wave, ...) call records for their values and drop the contexts; framework objects retain the derivative connection.

Each advect function that differentiates a record (advect.X for diff.X) takes the inputs of that record, with the dynamic arrays positional in pullback order and the static configuration keyword-only. Most signatures are identical; these differ:

  • bessel, angular, incgamma, intkambe and wignerd take their arguments (z, z and eta, or the three angles) first and the labels as keywords; lattice_sum takes k, kpar, a, r and eta first and dim, degree and order as keywords.
  • expansion, lattice_expansion, field, field_operator, plane_expansion, spherical_channels and periodic_to_cw take the positions as arrays (positions, or destination_positions and source_positions) and the bases as keywords; plane_expansion, spherical_channels and cylindrical_channels also take their polarizations as keywords. The cylindrical variants take the axial wavenumbers as an array too: kzs (distinct values) for expansions, kz (one per mode) for fields and periodic_to_cw.
  • plane_field, plane_permutation, rotation and lattice_expansion_from_table take their polarizations, bases or permutation count as keywords.
  • cylindrical_channels splits q into static kz_labels and a dynamic kx and has no fixed_q.
  • mie calls its size parameters sizes instead of x.
  • factor_interaction, factor_interaction_blocks and sphere_cluster_factor exist only in diff.

angular

angular(degree: ArrayLike, order: ArrayLike, z: ArrayLike, *, function: str='legendre') -> tuple[NDArray[np.complex128], _native.AngularContext]

Legendre, pi or tau angular functions, broadcast over z.

Legendre also accepts noninteger degrees for real z in (-1, 1]. The pi and tau functions, and arguments with a nonzero imaginary part, require integer degrees.

A derivative at a branch point raises ValueError unless its cotangent is zero.

Returns

complex128 array with the broadcast shape of degree, order and z.

Dynamic inputs

  • z: complex argument; its gradient has the shape of z.

Static configuration

  • degree: degree l, broadcast; integer except for real-domain Legendre.
  • order: integer order m, broadcast.
  • function: "legendre", "pi" or "tau".

Pullback AngularContext.pullback(cotangent: ComplexArray) -> ComplexArray

bands

bands(smats: ArrayLike, period: float) -> tuple[tuple[NDArray[np.complex128], NDArray[np.complex128]], _native.BandsContext]

Bloch wavenumbers along the normal and right eigenvectors of a periodic cell.

The wavenumbers use the principal logarithm. Derivatives hold its branch and the eigenvector pivot phase fixed; single modes at repeated eigenvalues have no gradient.

Returns

(wavenumbers, vectors): complex128 arrays (2 * n,) and (2 * n, 2 * n); column i of vectors belongs to wavenumbers[i]. context.pullback takes one cotangent for each.

Dynamic inputs

  • smats: S-matrix blocks of the cell, shape (2, 2, n, n).
  • period: cell length along the normal.

Static configuration

none.

Pullback BandsContext.pullback(wavenumbers: ArrayLike, eigenvectors: ArrayLike) -> tuple[ComplexArray, float]

bessel

bessel(order: ArrayLike, z: ArrayLike, *, function: str='j', spherical: bool=False, derivative: bool=False) -> tuple[NDArray[np.complex128], _native.BesselContext]

Bessel functions or their first derivatives, broadcast over order and z.

Returns

complex128 array with the broadcast shape of order and z. Two Python numbers give a 0-d array.

Dynamic inputs

  • z: complex argument. Its gradient has the shape of z; broadcast axes are summed.

Static configuration

  • order: real order, broadcast with z.
  • function: "j", "y", "h1" or "h2".
  • spherical: spherical instead of cylindrical Bessel functions.
  • derivative: the first derivative with respect to z instead of the value.

Pullback BesselContext.pullback(cotangent: ComplexArray) -> ComplexArray

chirality_density

chirality_density(ks: ArrayLike, normal: ArrayLike, z: ArrayLike=(0.0, 0.0)) -> tuple[NDArray[np.complex128], _native.ChiralityDensityContext]

Chirality density forms of plane waves in an xy basis.

Multiply by helicity signs, or pair opposite parity modes, to form operators. The cross form contracts as Re(down.conj() @ cross @ up). The transverse wavevectors are real.

Returns

complex128 array (3, modes): the up, down and cross forms.

Dynamic inputs

  • ks: wavenumber of each mode, shape (modes,).
  • normal: complex normal component of each wavevector, shape (modes,).
  • z: interval (start, end) along the normal; equal ends give the density on one plane.

Static configuration

none.

Pullback ChiralityDensityContext.pullback(cotangent: ArrayLike) -> tuple[ComplexArray, ComplexArray, RealArray]

coordinates

coordinates(points: ArrayLike, *, function: str | None=None, kind: str | None=None) -> tuple[NDArray[np.float64], _native.CoordinatesContext]

Coordinate conversion of points, such as car2sph.

Angular derivatives at an axis or at the origin raise ValueError unless their cotangent is zero.

Returns

float64 array with the shape of points.

Dynamic inputs

  • points: last axis of two polar or three spatial components.

Static configuration

  • function: "car2sph", "sph2car", "car2cyl", "cyl2car", "cyl2sph", "sph2cyl", "car2pol" or "pol2car"; kind is an alias.

Pullback CoordinatesContext.pullback(cotangent: RealArray) -> RealArray

cylinder

cylinder(kzs: ArrayLike, mmax: int, k0: float, radii: ArrayLike, epsilon: ArrayLike, mu: ArrayLike | None=None, kappa: ArrayLike | None=None) -> tuple[NDArray[np.complex128], _native.CylinderContext]

Helicity T-matrix of a multilayer infinite cylinder along z.

Returns

complex128 array (n, n) with n = 2len(kzs)(2*mmax+1), ordered by kz as given, then m, then pol 1 before pol 0.

Dynamic inputs

  • kzs: distinct real axial wavenumbers, shape (axial,).
  • k0: vacuum angular wavenumber.
  • radii: layer radii, inside out, shape (layers,).
  • epsilon: relative permittivities, shape (layers + 1,): the layers inside out, then the embedding medium.
  • mu: relative permeabilities, same shape; ones when omitted.
  • kappa: chirality parameters, same shape; zeros when omitted.

Static configuration

  • mmax: maximum order.

Pullback CylinderContext.pullback(cotangent: ArrayLike) -> tuple[RealArray, float, RealArray, ComplexArray, ComplexArray, ComplexArray]

cylindrical_channels

cylindrical_channels(basis: CylindricalBasis, ks: ArrayLike, q: ArrayLike, polarizations: ArrayLike, period: float, *, poltype: str | None=None, fixed_q: bool=False) -> tuple[NDArray[np.complex128], _native.CylindricalChannelsContext]

Incidence and emission channels of a periodic array of cylinders along x.

Indexed like spherical_channels; up and down refer to +y and -y.

Returns

complex128 array (2, 2, len(basis), ports).

Dynamic inputs

  • basis.positions: shape (positions, 3).
  • ks: wavenumbers for pol 0 and 1, shape (2,).
  • q: (kz, kx) of each zx-aligned port, shape (ports, 2). The kz are fixed labels, so the gradient of q[:, 0] is zero.
  • period: period along x.

Static configuration

  • basis: CylindricalBasis of the multipoles.
  • polarizations: pol index of each port.
  • poltype: "helicity" (default) or "parity".
  • fixed_q: also hold kx fixed.

Pullback CylindricalChannelsContext.pullback(cotangent: ArrayLike) -> tuple[RealArray, ComplexArray, RealArray, float]

cylindrical_translation

cylindrical_translation(krr: ArrayLike, phi: ArrayLike, z: ArrayLike, kz: ArrayLike, *, order: ArrayLike, singular: bool=True) -> tuple[NDArray[np.complex128], _native.CylindricalTranslationContext]

Cylindrical translation kernel of the order difference, broadcast.

The two matching axial labels move together with kz; changing which labels are equal is a discrete step without a gradient.

Returns

complex128 array with the broadcast shape of the inputs.

Dynamic inputs

  • krr: radial wavenumber times radial distance.
  • phi: azimuthal angle of the displacement.
  • z: axial distance.
  • kz: axial wavenumber.

Static configuration

  • order: source order minus destination order.
  • singular: singular instead of regular translation.

Pullback CylindricalTranslationContext.pullback(cotangent: ComplexArray) -> tuple[ComplexArray, ComplexArray, ComplexArray, ComplexArray]

ebcm_qmat

ebcm_qmat(radii: ArrayLike, slopes: ArrayLike, ks: ArrayLike, zs: ArrayLike, *, theta: ArrayLike, weights: ArrayLike, destination: Modes, source: Modes | None=None, singular: bool=True, radial_area_factor: bool=True) -> tuple[NDArray[np.complex128], _native.EbcmQmatContext]

Q matrix of an axisymmetric particle from a sampled surface (EBCM).

destination and source are the modes that ebcm.qmat calls out and in_. radial_area_factor=False reproduces treams.ebcm.qmat, which omits the radial surface-area factor; see Differences from treams.

Returns

complex128 array (len(destination), len(source)).

Dynamic inputs

  • radii: surface radius at each polar node, shape (nodes,).
  • slopes: derivative of the radius with respect to the polar angle, shape (nodes,).
  • ks: wavenumbers, shape (2, 2): inside then outside, negative then positive helicity.
  • zs: impedances, shape (2,): inside then outside.

Static configuration

  • theta: polar quadrature nodes in [0, pi], shape (nodes,).
  • weights: quadrature weights, shape (nodes,).
  • destination: (l, m, pol) modes of the rows.
  • source: (l, m, pol) modes of the columns; defaults to destination.
  • singular: singular (True) or regular (False) radial functions, as in ebcm.qmat.
  • radial_area_factor: keep the factor r of the surface element.

Pullback EbcmQmatContext.pullback(cotangent: ArrayLike) -> tuple[RealArray, RealArray, ComplexArray, ComplexArray]

eig

eig(operator: ArrayLike) -> tuple[tuple[NDArray[np.complex128], NDArray[np.complex128]], _native.EigContext]

Eigenvalues and unit right eigenvectors of a complex matrix.

The largest component of each vector is real and positive. Single modes at repeated eigenvalues have no gradient; equal value cotangents with zero vector cotangents still give the gradient of their spectral sums. A pushforward also needs a unique largest component in every eigenvector to fix its phase. Use :func:eigvals when only eigenvalues are needed.

Returns

(values, vectors): complex128 arrays (n,) and (n, n); column i of vectors belongs to values[i]. context.pullback takes one cotangent for each.

Dynamic inputs

  • operator: square matrix, shape (n, n).

Static configuration

none.

Pullback EigContext.pullback(eigenvalues: ArrayLike, eigenvectors: ArrayLike) -> ComplexArray

eigvals

eigvals(operator: ArrayLike) -> tuple[NDArray[np.complex128], _native.EigvalsContext]

Eigenvalues of a complex matrix, without an eigenvector phase constraint.

Pushforwards require eigenvalues with distinct real parts, so the returned order stays fixed under small perturbations. At ties, including repeated eigenvalues, pullbacks support equal loss weights, such as the trace. A tie in real parts is an ordering limitation even for distinct complex eigenvalues; follow individual modes explicitly to cross it.

Returns

complex128 array (n,), sorted by real part, then imaginary part. Follow individual modes explicitly when this ordering changes.

Dynamic inputs

  • operator: square matrix, shape (n, n).

Static configuration

none.

Pullback EigvalsContext.pullback(eigenvalues: ArrayLike) -> ComplexArray

expansion

expansion(destination: SphericalBasis | CylindricalBasis, source: SphericalBasis | CylindricalBasis, ks: ArrayLike, *, poltype: str | None=None, singular: bool=False) -> tuple[NDArray[np.complex128], _native.ExpansionContext]

Expansion matrix between two multipole bases (the treams Expand operator).

Supports spherical to spherical, cylindrical to cylindrical and cylindrical to spherical (regular waves only). The parity convention with cylinders needs an achiral medium. For two cylindrical bases, context.pullback_axial appends the gradient of kzs, the sorted distinct axial wavenumbers of both bases; each moves all modes with that value together.

Returns

complex128 array (len(destination), len(source)).

Dynamic inputs

  • destination.positions: shape (positions, 3).
  • source.positions: shape (positions, 3).
  • ks: wavenumbers for pol 0 and 1, shape (2,).

Static configuration

  • destination: SphericalBasis or CylindricalBasis of the rows.
  • source: basis of the columns.
  • poltype: "helicity" (default) or "parity".
  • singular: expand singular source waves into regular destination waves (False: regular into regular).

Pullback ExpansionContext.pullback_axial(cotangent: ArrayLike) -> tuple[RealArray, RealArray, ComplexArray, RealArray]

Pullback ExpansionContext.pullback(cotangent: ArrayLike) -> tuple[RealArray, RealArray, ComplexArray]

factor_interaction

factor_interaction(local: ArrayLike, coupling: ArrayLike) -> _native.InteractionFactor

Factor I - T C once to solve only requested incident columns.

Returns

an InteractionFactor. factor.solve(incident) gives the scattered coefficients; factor.record(incident) also returns an IlluminateContext.

Dynamic inputs

  • local: T, shape (n, n).
  • coupling: C, shape (n, n). The pullback of factor.record returns gradients for local, coupling and the incident columns.

Static configuration

none.

Pullback InteractionFactor.pullback_incident(cotangent: ArrayLike) -> ComplexArray

factor_interaction_blocks

factor_interaction_blocks(local: Sequence[ArrayLike], coupling: ArrayLike) -> _native.InteractionFactor

Factor I - T C with the local T-matrix kept as separate dense blocks.

Returns

an InteractionFactor; see factor_interaction.

Dynamic inputs

  • local: one block per particle, each square.
  • coupling: C, shape (n, n), n the sum of the block sizes. The context of factor.record takes pullback_blocks, which returns a list of block gradients, the coupling gradient and the incident gradient.

Static configuration

none.

Pullback InteractionFactor.pullback_incident(cotangent: ArrayLike) -> ComplexArray

field

field(coefficients: ArrayLike, points: ArrayLike, basis: SphericalBasis | CylindricalBasis, ks: ArrayLike, *, poltype: str | None=None, singular: bool=False) -> tuple[NDArray[np.complex128], _native.FieldContext]

Electric field of multipole coefficients at Cartesian points.

Use singular=True for scattered (outgoing) coefficients; the default samples regular waves. wave.efield(points) chooses this from the kind of the wave. The context stores no (points, 3, modes) operator. For a cylindrical basis, context.pullback_axial appends the real gradient of kz, one per mode.

Returns

complex128 array (points, 3).

Dynamic inputs

  • coefficients: multipole amplitudes, shape (len(basis),).
  • points: Cartesian points, shape (points, 3).
  • basis.positions: shape (positions, 3).
  • ks: wavenumbers for pol 0 and 1, shape (2,); both k0 in vacuum.

Static configuration

  • basis: SphericalBasis or CylindricalBasis.
  • poltype: "helicity" (default) or "parity".
  • singular: singular instead of regular waves.

Pullback FieldContext.pullback(cotangent: ArrayLike) -> tuple[ComplexArray, RealArray, RealArray, ComplexArray]

Pullback FieldContext.pullback_axial(cotangent: ArrayLike) -> tuple[ComplexArray, RealArray, RealArray, ComplexArray, RealArray]

field_operator

field_operator(points: ArrayLike, basis: SphericalBasis | CylindricalBasis, ks: ArrayLike, *, poltype: str | None=None, singular: bool=False) -> tuple[NDArray[np.complex128], _native.FieldOperatorContext]

Electric field matrix of every basis mode at every point.

For a cylindrical basis, context.pullback_axial appends the real gradient of kz, one per mode.

Returns

complex128 array (points, 3, len(basis)).

Dynamic inputs

  • points: Cartesian points, shape (points, 3).
  • basis.positions: shape (positions, 3).
  • ks: wavenumbers for pol 0 and 1, shape (2,).

Static configuration

  • basis: SphericalBasis or CylindricalBasis.
  • poltype: "helicity" (default) or "parity".
  • singular: singular instead of regular waves.

Pullback FieldOperatorContext.pullback(cotangent: ArrayLike) -> tuple[RealArray, RealArray, ComplexArray]

Pullback FieldOperatorContext.pullback_axial(cotangent: ArrayLike) -> tuple[RealArray, RealArray, ComplexArray, RealArray]

fresnel

fresnel(ks: ArrayLike, kzs: ArrayLike, zs: ArrayLike) -> tuple[NDArray[np.complex128], _native.FresnelContext]

Fresnel blocks of one chiral interface, ordered as coeffs.fresnel.

Returns

complex128 array (2, 2, 2, 2).

Dynamic inputs

  • ks: wavenumbers, shape (2, 2): negative then positive medium, pol 0 then 1.
  • kzs: normal wavevector components, same shape and order.
  • zs: impedances of the negative and the positive medium, shape (2,).

Static configuration

none.

Pullback FresnelContext.pullback(cotangent: ArrayLike) -> tuple[ComplexArray, ComplexArray, ComplexArray]

illuminate

illuminate(local: ArrayLike, coupling: ArrayLike, incident: ArrayLike) -> tuple[NDArray[np.complex128], _native.IlluminateContext]

Solve (I - T C) scattered = T incident for the requested columns.

It never forms the full coupled T-matrix. factor_interaction keeps the LU factors for several calls.

Returns

complex128 array (n, illuminations).

Dynamic inputs

  • local: T, shape (n, n).
  • coupling: C, shape (n, n).
  • incident: incident coefficients, shape (n, illuminations).

Static configuration

none.

Pullback IlluminateContext.pullback(cotangent: ArrayLike) -> tuple[ComplexArray, ComplexArray, ComplexArray]

Pullback IlluminateContext.pullback_blocks(cotangent: ArrayLike) -> tuple[list[ComplexArray], ComplexArray, ComplexArray]

incgamma

incgamma(n: ArrayLike, z: ArrayLike) -> tuple[NDArray[np.complex128], _native.IncgammaContext]

Upper incomplete gamma function Gamma(n, z) for half-integer n.

Returns

complex128 array with the broadcast shape of n and z.

Dynamic inputs

  • z: complex argument; its gradient has the shape of z.

Static configuration

  • n: half-integer degree, broadcast with z.

Pullback IncgammaContext.pullback(cotangent: ComplexArray) -> ComplexArray

interaction

interaction(local: ArrayLike, coupling: ArrayLike) -> tuple[NDArray[np.complex128], _native.InteractionContext]

Coupled T-matrix X = (I - T C)^-1 T.

Returns

complex128 array (n, n).

Dynamic inputs

  • local: T, shape (n, n).
  • coupling: C, shape (n, n).

Static configuration

none.

Pullback InteractionContext.pullback(cotangent: ArrayLike) -> tuple[ComplexArray, ComplexArray]

interface_coefficients

interface_coefficients(ks: ArrayLike, zs: ArrayLike, q: ArrayLike, *, alignment: str='xy', fixed_q: bool=False) -> tuple[NDArray[np.complex128], _native.InterfaceCoefficientsContext]

Blocks of one planar interface for one transverse wavevector.

Returns

complex128 array (2, 2, 2, 2): outgoing and incoming direction, then pol 0 and 1.

Dynamic inputs

  • ks: wavenumbers, shape (2, 2): negative (below) then positive (above) medium, pol 0 then 1.
  • zs: impedances of the two media, shape (2,).
  • q: transverse wavevector, shape (2,).

Static configuration

  • alignment: "xy", "yz" or "zx", the transverse axes; the remaining axis is the normal.
  • fixed_q: hold q fixed.

Pullback InterfaceCoefficientsContext.pullback(cotangent: ArrayLike) -> tuple[ComplexArray, ComplexArray, RealArray]

intkambe

intkambe(n: ArrayLike, z: ArrayLike, eta: ArrayLike) -> tuple[NDArray[np.complex128], _native.IntkambeContext]

Kambe integral of the Ewald lattice sums, broadcast over n, z and eta.

Derivatives follow the selected complex branch. At z=0, n=-2 has a cusp without a derivative, and n<=-3 has a zero z derivative.

Returns

complex128 array with the broadcast shape of n, z and eta.

Dynamic inputs

  • z: complex argument.
  • eta: complex Ewald split parameter.

Static configuration

  • n: integer order, broadcast.

Pullback IntkambeContext.pullback(cotangent: ComplexArray) -> tuple[ComplexArray, ComplexArray]

lattice_expansion

lattice_expansion(destination: SphericalBasis | CylindricalBasis, source: SphericalBasis | CylindricalBasis, ks: ArrayLike, kpar: ArrayLike, a: ArrayLike, *, poltype: str | None=None, eta: complex=0) -> tuple[NDArray[np.complex128], _native.LatticeExpansionContext]

Lattice coupling from singular to regular waves, including nonzero self images.

The Ewald method splits each lattice sum into a real-space and a reciprocal-space series; eta sets where, and 0 picks it automatically. For two cylindrical bases, context.pullback_axial appends the gradient of kzs, the sorted distinct axial wavenumbers of both bases, with matching groups fixed.

Returns

complex128 array (len(destination), len(source)).

Dynamic inputs

  • destination.positions: shape (positions, 3).
  • source.positions: shape (positions, 3).
  • ks: wavenumbers for pol 0 and 1, shape (2,).
  • kpar: Bloch vector.
  • a: lattice vectors.

Static configuration

  • destination: basis of the rows.
  • source: basis of the same family for the columns.
  • poltype: "helicity" (default) or "parity".
  • eta: Ewald split parameter.

Pullback LatticeExpansionContext.pullback_axial(cotangent: ArrayLike) -> tuple[RealArray, RealArray, ComplexArray, RealArray, RealArray, RealArray]

Pullback LatticeExpansionContext.pullback(cotangent: ArrayLike) -> tuple[RealArray, RealArray, ComplexArray, RealArray, RealArray]

lattice_expansion_from_table

lattice_expansion_from_table(values: ArrayLike, destination: SphericalBasis, source: SphericalBasis | None=None, *, poltype: str | None=None) -> tuple[NDArray[np.complex128], _native.LatticeExpansionFromTableContext]

Lattice expansion from a table of lattice harmonics computed elsewhere.

The context stores only the sparse angular map; whatever computes the table owns its derivatives. Parity needs one wavenumber channel.

Returns

complex128 array (len(destination), len(source)).

Dynamic inputs

  • values: the table, shape (destination positions, source positions, 1 or 2 wavenumber channels, harmonics). The last index is l*l+l+m, up to the sum of the largest degrees of both bases.

Static configuration

  • destination: SphericalBasis of the rows.
  • source: SphericalBasis of the columns; defaults to destination.
  • poltype: "helicity" (default) or "parity".

Pullback LatticeExpansionFromTableContext.pullback(cotangent: ArrayLike) -> ComplexArray

lattice_sum

lattice_sum(dim: int, degree: ArrayLike, order: ArrayLike, k: ArrayLike, kpar: ArrayLike, a: ArrayLike, r: ArrayLike, eta: ArrayLike=0, *, spherical: bool=True, part: str='full', shell: ArrayLike=0) -> tuple[NDArray[np.complex128], _native.LatticeSumContext]

Lattice sums of one Bloch lattice, broadcast over labels and geometry.

The Ewald method splits each sum into a real-space and a reciprocal-space series; eta sets where, and 0 picks it automatically. Ewald sums require Im k >= 0 and, for spherical waves, Re k >= 0. Finite direct shells accept every finite nonzero complex wavenumber.

Returns

complex128 array with the broadcast batch shape of all inputs.

Dynamic inputs

  • k: complex wavenumber.
  • kpar: Bloch vector, last axis of length dim.
  • a: lattice vectors as rows, last axes (dim, dim); a scalar in 1D.
  • r: shift, last axis 3 (spherical) or 2 (cylindrical).
  • eta: complex Ewald split parameter. The full sum does not depend on it, so its gradient is zero for part="full"; the real and reciprocal parts need an explicit nonzero eta for gradients.

Static configuration

  • dim: lattice dimension, 1 to 3 for spherical and 1 to 2 for cylindrical sums.
  • degree: integer degree l, broadcast.
  • order: integer order m, broadcast.
  • spherical: spherical (lsumsw) or cylindrical (lsumcw) sums.
  • part: "full", "real", "reciprocal" or "direct".
  • shell: integer cube shell of the direct sum (part="direct").

Pullback LatticeSumContext.pullback(cotangent: ArrayLike) -> tuple[ComplexArray, RealArray, RealArray, RealArray, ComplexArray]

layer_stack

layer_stack(ks: ArrayLike, zs: ArrayLike, q: ArrayLike, thickness: ArrayLike, *, alignment: str='xy', fixed_q: bool=False) -> tuple[NDArray[np.complex128], _native.LayerStackContext]

Blocks of planar layers for independent transverse wavevectors.

Returns

complex128 array (channels, 2, 2, 2, 2): per channel the outgoing and incoming direction, then pol 0 and 1.

Dynamic inputs

  • ks: wavenumbers, shape (media, 2), from the negative to the positive side, pol 0 then 1.
  • zs: impedances, shape (media,).
  • q: transverse wavevector of each channel, shape (channels, 2).
  • thickness: one thickness per interior medium, shape (media - 2,); a scalar is also accepted for a single interior medium.

Static configuration

  • alignment: "xy", "yz" or "zx", the transverse axes.
  • fixed_q: hold q fixed.

Pullback LayerStackContext.pullback(cotangent: ArrayLike) -> tuple[ComplexArray, ComplexArray, RealArray, RealArray]

mie

mie(degree: int, x: ArrayLike, epsilon: ArrayLike, mu: ArrayLike, kappa: ArrayLike) -> tuple[NDArray[np.complex128], _native.MieContext]

Mie coefficients of a multilayer sphere for one degree, ordered as coeffs.mie.

Returns

complex128 array (2, 2).

Dynamic inputs

  • x: size parameters k0 * radius of the layers, inside out, shape (layers,).
  • epsilon: relative permittivities, shape (layers + 1,): the layers inside out, then the embedding medium.
  • mu: relative permeabilities, same shape and order.
  • kappa: chirality parameters, same shape and order.

Static configuration

  • degree: the degree l.

Pullback MieContext.pullback(cotangent: ArrayLike) -> tuple[RealArray, ComplexArray, ComplexArray, ComplexArray]

mie_cyl

mie_cyl(kz: float, order: int, k0: float, radii: ArrayLike, epsilon: ArrayLike, mu: ArrayLike, kappa: ArrayLike) -> tuple[NDArray[np.complex128], _native.MieCylContext]

Coefficients of a multilayer cylinder for one order, ordered as coeffs.mie_cyl.

Returns

complex128 array (2, 2).

Dynamic inputs

  • kz: real axial wavenumber.
  • k0: vacuum angular wavenumber.
  • radii: layer radii, inside out, shape (layers,).
  • epsilon: relative permittivities, shape (layers + 1,): the layers inside out, then the embedding medium.
  • mu: relative permeabilities, same shape and order.
  • kappa: chirality parameters, same shape and order.

Static configuration

  • order: the order m.

Pullback MieCylContext.pullback(cotangent: ArrayLike) -> tuple[float, float, RealArray, ComplexArray, ComplexArray, ComplexArray]

oriented_chirality

oriented_chirality(transverse: ArrayLike, normal: ArrayLike, z: ArrayLike=(0.0, 0.0), *, polarizations: ArrayLike, axis: int=2) -> tuple[NDArray[np.complex128], _native.OrientedChiralityContext]

Signed helicity chirality forms for any Cartesian normal.

Returns

complex128 array (3, modes): the up, down and cross forms.

Dynamic inputs

  • transverse: real transverse components, shape (modes, 2), in cyclic order after axis.
  • normal: complex normal component of each wavevector, shape (modes,).
  • z: interval (start, end) along the normal.

Static configuration

  • polarizations: pol index of each mode.
  • axis: the normal axis, 0, 1 or 2.

Pullback OrientedChiralityContext.pullback(cotangent: ArrayLike) -> tuple[RealArray, ComplexArray, RealArray]

particle_cluster

particle_cluster(local: Sequence[ArrayLike], positions: ArrayLike, ks: ArrayLike, *, bases: Sequence[SphericalBasis | CylindricalBasis], poltype: str | None=None) -> tuple[NDArray[np.complex128], _native.ParticleClusterContext]

Coupled T-matrix of particles with different T-matrices.

Local bases can have different cutoffs and mode subsets; each uses one position. The enclosing surfaces of the particles must not overlap.

Returns

complex128 array (N, N), N the sum of the basis lengths, particle by particle.

Dynamic inputs

  • local: one T-matrix per particle, each (len(basis), len(basis)). The pullback returns one gradient per particle.
  • positions: particle positions, shape (particles, 3).
  • ks: wavenumbers for pol 0 and 1, shape (2,).

Static configuration

  • bases: one global basis per particle, all of one wave family.
  • poltype: "helicity" (default) or "parity".

Pullback ParticleClusterContext.pullback(cotangent: ArrayLike) -> tuple[list[ComplexArray], RealArray, ComplexArray]

periodic_to_cw

periodic_to_cw(destination: CylindricalBasis, source: SphericalBasis, ks: ArrayLike, period: float, *, poltype: str | None=None) -> tuple[NDArray[np.complex128], _native.PeriodicToCwContext]

Spherical waves of a z-periodic chain radiated as singular cylindrical waves.

Physical diffraction orders satisfy kz = kpar + 2pin/period; the kz of each cylindrical mode has its own gradient.

Returns

complex128 array (len(destination), len(source)).

Dynamic inputs

  • destination.positions: shape (positions, 3).
  • source.positions: shape (positions, 3).
  • ks: wavenumbers for pol 0 and 1, shape (2,).
  • destination.kz: real axial wavenumber of each cylindrical mode. Its gradient comes before that of period.
  • period: chain period along z.

Static configuration

  • destination: CylindricalBasis of the rows.
  • source: SphericalBasis of the columns.
  • poltype: "helicity" (default) or "parity".

Pullback PeriodicToCwContext.pullback(cotangent: ArrayLike) -> tuple[RealArray, RealArray, ComplexArray, RealArray, float]

plane_expansion

plane_expansion(destination: SphericalBasis | CylindricalBasis, vectors: ArrayLike, polarizations: ArrayLike, *, poltype: str | None=None, fixed_vectors: bool=False) -> tuple[NDArray[np.complex128], _native.PlaneExpansionContext]

Regular multipole coefficients of plane waves.

Cylindrical axial components are fixed labels with zero gradients. Along the axis, fixed_vectors gives position gradients at fixed incidence.

Returns

complex128 array (len(destination), modes).

Dynamic inputs

  • destination.positions: shape (positions, 3).
  • vectors: complex wavevectors, shape (modes, 3).

Static configuration

  • destination: SphericalBasis or CylindricalBasis.
  • polarizations: pol index of each plane wave.
  • poltype: "helicity" (default) or "parity".
  • fixed_vectors: hold the vectors fixed.

Pullback PlaneExpansionContext.pullback(cotangent: ArrayLike) -> tuple[RealArray, ComplexArray]

plane_field

plane_field(coefficients: ArrayLike | None, points: ArrayLike, vectors: ArrayLike, polarizations: ArrayLike, *, poltype: str | None=None, fixed_vectors: bool=False) -> tuple[NDArray[np.complex128], _native.PlaneFieldContext]

Electric field of weighted plane waves, or its operator.

Returns

complex128 array (points, 3), or the operator (points, 3, modes) when coefficients is None.

Dynamic inputs

  • coefficients: amplitudes, shape (modes,); the gradient is empty for an operator.
  • points: Cartesian points, shape (points, 3).
  • vectors: complex wavevectors, shape (modes, 3).

Static configuration

  • polarizations: pol index of each mode.
  • poltype: "helicity" (default) or "parity".
  • fixed_vectors: hold the vectors fixed. Along the polarization axis the treams polarization vectors have no direction derivative.

Pullback PlaneFieldContext.pullback(cotangent: ArrayLike) -> tuple[ComplexArray, RealArray, ComplexArray]

plane_permutation

plane_permutation(vectors: ArrayLike, polarizations: ArrayLike, n: int=1, *, poltype: str | None=None) -> tuple[NDArray[np.complex128], _native.PlanePermutationContext]

Change of the Cartesian axes of plane waves, x to y to z cyclically.

The permuted wavevectors are np.roll(vectors, n, axis=1).

Returns

complex128 array (2, modes): the amplitudes of both output pols for each input mode.

Dynamic inputs

  • vectors: complex wavevectors, shape (modes, 3).

Static configuration

  • polarizations: pol index of each mode.
  • n: number of cyclic permutations.
  • poltype: "helicity" (default) or "parity".

Pullback PlanePermutationContext.pullback(cotangent: ArrayLike) -> ComplexArray

plane_phases

plane_phases(points: ArrayLike, vectors: ArrayLike) -> tuple[NDArray[np.complex128], _native.PlanePhasesContext]

Phase factors exp(i k.r) of complex wavevectors at real displacements.

Axial wavevectors are supported. The context stores only the inputs.

Returns

complex128 array (points, vectors).

Dynamic inputs

  • points: real displacements, shape (points, 3).
  • vectors: complex wavevectors, shape (vectors, 3).

Static configuration

none.

Pullback PlanePhasesContext.pullback(cotangent: ArrayLike) -> tuple[RealArray, ComplexArray]

propagation_matrix

propagation_matrix(vectors: ArrayLike, distance: ArrayLike) -> tuple[NDArray[np.complex128], _native.PropagationMatrixContext]

S-matrix of homogeneous propagation by a Cartesian displacement.

Returns

complex128 array (2, 2, modes, modes).

Dynamic inputs

  • vectors: complex wavevectors of the upgoing modes, shape (modes, 3), with the normal component last.
  • distance: displacement in the same axis order, shape (3,).

Static configuration

none.

Pullback PropagationMatrixContext.pullback(cotangent: ArrayLike) -> tuple[ComplexArray, RealArray]

rotation

rotation(angles: ArrayLike, destination: SphericalBasis | CylindricalBasis, source: SphericalBasis | CylindricalBasis | None=None) -> tuple[NDArray[np.complex128], _native.RotationContext]

Rotation matrix of z-y-z Euler angles between two multipole bases.

The positions stay where they are. Cylindrical bases allow only theta=0.

Returns

complex128 array (len(destination), len(source)).

Dynamic inputs

  • angles: (phi, theta, psi) in radians. The pullback returns three floats.

Static configuration

  • destination: SphericalBasis or CylindricalBasis of the rows.
  • source: basis of the same family for the columns; defaults to destination.

Pullback RotationContext.pullback(cotangent: ArrayLike) -> list[float]

smatrix_add

smatrix_add(lower: ArrayLike, upper: ArrayLike) -> tuple[NDArray[np.complex128], _native.SMatrixAddContext]

Cascade two S-matrices: upper on the positive side of lower.

Returns

complex128 array (2, 2, n, n).

Dynamic inputs

  • lower: S-matrix blocks, shape (2, 2, n, n).
  • upper: S-matrix blocks, same shape.

Static configuration

none.

Pullback SMatrixAddContext.pullback(cotangent: ArrayLike) -> tuple[ComplexArray, ComplexArray]

smatrix_from_array

smatrix_from_array(response: ArrayLike, channels: ArrayLike) -> tuple[NDArray[np.complex128], _native.SMatrixFromArrayContext]

S-matrix of a periodic array from its solved response and its channels.

Returns

complex128 array (2, 2, ports, ports) in the block order of SMatrix.

Dynamic inputs

  • response: solved periodic response in local multipole channels, shape (multipoles, multipoles).
  • channels: incidence and emission channels of spherical_channels or cylindrical_channels, shape (2, 2, multipoles, ports).

Static configuration

none.

Pullback SMatrixFromArrayContext.pullback(cotangent: ArrayLike) -> tuple[ComplexArray, ComplexArray]

smatrix_illuminate

smatrix_illuminate(lower: ArrayLike, upper: ArrayLike, up: ArrayLike, down: ArrayLike) -> tuple[NDArray[np.complex128], _native.SMatrixIlluminateContext]

Outgoing and internal fields of two adjacent stacks lit from both sides.

The solve computes only these right-hand sides, never the combined network.

Returns

complex128 array (4, modes, illuminations): outgoing up, outgoing down, then the internal up and down coefficients between the two stacks.

Dynamic inputs

  • lower: S-matrix blocks of the lower stack, shape (2, 2, modes, modes).
  • upper: S-matrix blocks of the upper stack, same shape.
  • up: amplitudes travelling up into the lower stack, shape (modes, illuminations).
  • down: amplitudes travelling down into the upper stack, same shape.

Static configuration

none.

Pullback SMatrixIlluminateContext.pullback(cotangent: ArrayLike) -> tuple[ComplexArray, ComplexArray, ComplexArray, ComplexArray]

smatrix_periodic

smatrix_periodic(smats: ArrayLike) -> tuple[NDArray[np.complex128], _native.SMatrixPeriodicContext]

Transfer matrix of one S-matrix cell for periodic repetition.

Returns

complex128 array (2 * n, 2 * n).

Dynamic inputs

  • smats: S-matrix blocks, shape (2, 2, n, n).

Static configuration

none.

Pullback SMatrixPeriodicContext.pullback(cotangent: ArrayLike) -> ComplexArray

smatrix_tr

smatrix_tr(matrices: ArrayLike, incident: ArrayLike, ks: ArrayLike, zs: ArrayLike, q: ArrayLike, *, modes: Sequence[tuple[int, int]], axis: int=2, poltype: str | None=None, modetype: str='up', fixed_q: bool=False) -> tuple[NDArray[np.float64], _native.SMatrixTrContext]

Transmitted and reflected power fractions of a planar network.

Each incident column is one illumination. At normal incidence the polarization vectors have no derivative with respect to the direction; pass fixed_q=True there.

Returns

float64 array (2, illuminations): transmission, then reflection.

Dynamic inputs

  • matrices: S-matrix blocks, shape (2, 2, n, n).
  • incident: amplitudes, shape (n, illuminations).
  • ks: wavenumbers, shape (2, 2): the positive then the negative exterior medium (the order of SMatrix.material), pol 0 then 1.
  • zs: impedances of the positive and the negative exterior medium, shape (2,).
  • q: transverse wavevector of each diffraction group, shape (groups, 2). Groups need distinct q values.

Static configuration

  • modes: (group index, pol) of each port; all distinct.
  • axis: the normal axis, 0, 1 or 2.
  • poltype: "helicity" (default) or "parity".
  • modetype: "up" for light from the negative side, "down" for light from the positive side.
  • fixed_q: hold q fixed.

Pullback SMatrixTrContext.pullback(cotangent: ArrayLike) -> tuple[ComplexArray, ComplexArray, ComplexArray, ComplexArray, RealArray]

solve

solve(operator: ArrayLike, rhs: ArrayLike) -> tuple[NDArray[np.complex128], _native.SolveContext]

Solve A X = B.

The pullback reuses the LU factors of the forward solve.

Returns

complex128 array X with the shape of rhs.

Dynamic inputs

  • operator: square matrix A, shape (n, n).
  • rhs: right-hand sides B, shape (n, columns).

Static configuration

none.

Pullback SolveContext.pullback(cotangent: ArrayLike) -> tuple[ComplexArray, ComplexArray]

sph_harm

sph_harm(theta: ArrayLike, phi: ArrayLike, *, degree: ArrayLike, order: ArrayLike) -> tuple[NDArray[np.complex128], _native.VectorWaveContext]

Normalized spherical harmonics Y_lm(theta, phi), broadcast.

Returns

complex128 array with the broadcast shape of the inputs.

Dynamic inputs

  • theta: polar angle.
  • phi: azimuthal angle.

Static configuration

  • degree: integer degree l.
  • order: integer order m.

Pullback VectorWaveContext.pullback(cotangent: ComplexArray) -> tuple[ComplexArray, ...]

sphere

sphere(lmax: int, k0: float, radii: ArrayLike, epsilon: ArrayLike, mu: ArrayLike | None=None, kappa: ArrayLike | None=None) -> tuple[NDArray[np.complex128], _native.SphereContext]

Helicity T-matrix of a multilayer sphere at the origin.

Returns

complex128 array (n, n) with n = 2lmax(lmax+2), in the order of SphericalBasis.default(lmax).

Dynamic inputs

  • k0: vacuum angular wavenumber.
  • radii: layer radii, inside out, shape (layers,).
  • epsilon: relative permittivities, shape (layers + 1,): the layers inside out, then the embedding medium.
  • mu: relative permeabilities, same shape; ones when omitted.
  • kappa: chirality parameters, same shape; zeros when omitted.

Static configuration

  • lmax: maximum degree.

Pullback SphereContext.pullback(cotangent: ArrayLike) -> tuple[float, RealArray, ComplexArray, ComplexArray, ComplexArray]

sphere_cluster

sphere_cluster(lmax: int, k0: float, radii: ArrayLike, epsilon: ArrayLike, positions: ArrayLike) -> tuple[NDArray[np.complex128], _native.SphereClusterContext]

Coupled T-matrix of homogeneous nonmagnetic spheres in vacuum.

Returns

complex128 array (N, N) with N = spheres * 2lmax(lmax+2), sphere by sphere, each in the order of SphericalBasis.default(lmax).

Dynamic inputs

  • k0: vacuum angular wavenumber.
  • radii: sphere radii, shape (spheres,).
  • epsilon: relative permittivities, shape (spheres,).
  • positions: sphere centres, shape (spheres, 3).

Static configuration

  • lmax: maximum degree.

Pullback SphereClusterContext.pullback(cotangent: ArrayLike) -> tuple[float, RealArray, ComplexArray, RealArray]

sphere_cluster_factor

sphere_cluster_factor(lmax: int, k0: float, radii: ArrayLike, epsilon: ArrayLike, positions: ArrayLike) -> _native.InteractionFactor

Factor I - T C of homogeneous nonmagnetic spheres in vacuum, assembled in Rust.

The spheres are those of sphere_cluster. The factor never forms the block-diagonal local matrix or the coupled T-matrix. For gradients with respect to radii, materials and positions use iterative.SphereCluster. The context of factor.record(incident) takes pullback_blocks, which returns gradients for the local blocks (one per sphere), the coupling and the incident columns.

Returns

an InteractionFactor; see factor_interaction.

Dynamic inputs

none (use iterative.SphereCluster for gradients).

Static configuration

  • lmax: maximum degree.
  • k0: vacuum angular wavenumber.
  • radii: sphere radii, shape (spheres,).
  • epsilon: relative permittivities, shape (spheres,).
  • positions: sphere centres, shape (spheres, 3).

Pullback InteractionFactor.pullback_incident(cotangent: ArrayLike) -> ComplexArray

spherical_channels

spherical_channels(basis: SphericalBasis, ks: ArrayLike, q: ArrayLike, polarizations: ArrayLike, area: float, *, poltype: str | None=None, fixed_q: bool=False) -> tuple[NDArray[np.complex128], _native.SphericalChannelsContext]

Incidence and emission channels between multipoles and plane-wave ports.

Index the result as channels[role, side]: role 0 for incidence and 1 for emission, side 0 for up and 1 for down. Emitted arrays are transposed: channels[1, side].T maps multipoles to outgoing plane waves. At exactly normal incidence the azimuth is undefined; pass fixed_q=True for gradients there.

Returns

complex128 array (2, 2, len(basis), ports).

Dynamic inputs

  • basis.positions: positions of the multipoles, shape (positions, 3).
  • ks: wavenumbers for pol 0 and 1, shape (2,).
  • q: transverse wavevector of each port, shape (ports, 2).
  • area: area of the unit cell.

Static configuration

  • basis: SphericalBasis of the multipoles.
  • polarizations: pol index of each port.
  • poltype: "helicity" (default) or "parity".
  • fixed_q: hold q fixed.

Pullback SphericalChannelsContext.pullback(cotangent: ArrayLike) -> tuple[RealArray, ComplexArray, RealArray, float]

spherical_translation

spherical_translation(kr: ArrayLike, theta: ArrayLike, phi: ArrayLike, *, destination: Sequence[ArrayLike], source: Sequence[ArrayLike], poltype: str | None=None, singular: bool=True) -> tuple[NDArray[np.complex128], _native.SphericalTranslationContext]

Spherical translation coefficient of one mode pair (sw.translate), broadcast.

Returns

complex128 array with the broadcast shape of the inputs.

Dynamic inputs

  • kr: complex wavenumber times distance.
  • theta: polar angle of the displacement.
  • phi: azimuthal angle of the displacement.

Static configuration

  • destination: (degree, order, pol) labels of the destination mode.
  • source: (degree, order, pol) labels of the source mode.
  • poltype: "helicity" (default) or "parity".
  • singular: singular instead of regular translation.

Pullback SphericalTranslationContext.pullback(cotangent: ComplexArray) -> tuple[ComplexArray, ComplexArray, ComplexArray]

svdvals

svdvals(operator: ArrayLike) -> tuple[NDArray[np.float64], _native.SvdvalsContext]

Singular values of a complex matrix, in descending order.

The pullback uses the thin singular vectors. Repeated positive values need equal cotangents. A zero singular value needs a zero cotangent: single values there have no gradient. Pushforwards require distinct positive values. Values below 64 * eps * largest_value count as numerically zero; the pullback applies the same relative tolerance to their cotangents.

Returns

float64 array (min(rows, columns),).

Dynamic inputs

  • operator: complex matrix (rows, columns).

Static configuration

none.

Pullback SvdvalsContext.pullback(cotangent: ArrayLike) -> ComplexArray

tmatrix_metric

tmatrix_metric(operator: ArrayLike, ks: ArrayLike=(1.0, 1.0), *, polarizations: ArrayLike, metric: str | None=None, kind: str | None=None) -> tuple[float, _native.TMatrixMetricContext]

Global helicity metric of a T-matrix: cd, db or chi.

A zero scattering norm, or zero total absorption for cd, has no defined metric. At zero contrast, chi has a value but its derivative is undefined; only zero tangent and cotangent requests return zero.

Returns

float.

Dynamic inputs

  • operator: helicity T-matrix in a global basis, shape (modes, modes).
  • ks: real wavenumbers for pol 0 and 1, shape (2,); only cd depends on them.

Static configuration

  • polarizations: pol index of each mode.
  • metric: "cd" (circular dichroism), "db" (duality breaking) or "chi" (electromagnetic chirality); kind is an alias.

Pullback TMatrixMetricContext.pullback(cotangent: float) -> tuple[ComplexArray, RealArray]

vector_coordinates

vector_coordinates(vectors: ArrayLike, points: ArrayLike, *, function: str | None=None, kind: str | None=None) -> tuple[NDArray[np.complex128], _native.VectorCoordinatesContext]

Vector components converted between coordinate systems.

Returns

complex128 array with the broadcast shape of vectors and points.

Dynamic inputs

  • vectors: vector components, last axis 2 or 3.
  • points: the points in the source coordinates, same last axis. Each gradient has the shape of its input.

Static configuration

  • function: a coordinate conversion such as "car2sph", the name of the vector function without its v prefix; kind is an alias.

Pullback VectorCoordinatesContext.pullback(cotangent: ComplexArray) -> tuple[ComplexArray, RealArray]

vector_wave

vector_wave(*arguments: ArrayLike, function: str, degree: ArrayLike=0, order: ArrayLike=0, pol: ArrayLike | None=None, polarization: ArrayLike | None=None) -> tuple[NDArray[np.complex128], _native.VectorWaveContext]

Vector waves and harmonics with a gradient for every continuous argument.

The arguments are those of the public function without the labels: (kr, theta, phi) for spherical waves, (theta, phi) for harmonics, (kz, krr, phi, z[, k]) for cylindrical waves and (kx, ky, kz, x, y, z) for plane waves.

Returns

complex128 array with the broadcast shape of the arguments and labels, plus a last axis of 3 for vector functions.

Dynamic inputs

  • arguments: one gradient each, with the shape of its argument.

Static configuration

  • function: a special function name, such as "vsw_rA".
  • degree: integer degree l.
  • order: integer order m.
  • pol: pol index 0 or 1 (default 0); polarization is an alias.

Pullback VectorWaveContext.pullback(cotangent: ComplexArray) -> tuple[ComplexArray, ...]

wignerd

wignerd(degree: ArrayLike, row: ArrayLike, column: ArrayLike, phi: ArrayLike, theta: ArrayLike, psi: ArrayLike) -> tuple[NDArray[np.complex128], _native.WignerdContext]

Wigner D matrix elements D^l_{m m'}(phi, theta, psi), broadcast.

Returns

complex128 array with the broadcast shape of the labels and the angles.

Dynamic inputs

  • phi: first z-y-z Euler angle, complex allowed.
  • theta: second Euler angle.
  • psi: third Euler angle. Each gradient has the shape of its angle.

Static configuration

  • degree: integer degree l.
  • row: integer order m.
  • column: integer order m'.

Pullback WignerdContext.pullback(cotangent: ComplexArray) -> tuple[ComplexArray, ComplexArray, ComplexArray]