Expand description
Discrete transforms on exact sequences (convolution, NTT, Walsh–Hadamard, Möbius).
Discrete transforms on exact sequences (SymPy’s sympy.discrete):
linear, cyclic and subset convolutions, the number-theoretic transform,
the Walsh–Hadamard transform and the Möbius (subset/superset-sum)
transform. (0.9)
Everything here is exact. Sequences are Ratio<BigInt> (or
BigInt residues for the NTT) and every result is an exact rational or
residue. There is deliberately no floating-point FFT
(sympy.discrete.transforms.fft) and no symbolic DFT over Ex roots of
unity: the exact tool for polynomial multiplication is convolution
(or convolution_ntt modulo a prime), and a symbolic result is
obtained by mapping the rationals through Context::from_ratio or by
using convolution_ex directly on Ex coefficients.
Transforms that need a power-of-two length (ntt, fwht,
mobius_transform and their inverses, convolution_subset) zero-pad
their input to the next power of two, exactly as SymPy does; the empty
sequence is returned unchanged.
§Examples
use symplex::discrete::{convolution, fwht, ifwht, mobius_transform};
use num_bigint::BigInt;
use num_rational::Ratio;
let q = |v: &[i64]| -> Vec<Ratio<BigInt>> {
v.iter().map(|&t| Ratio::from_integer(BigInt::from(t))).collect()
};
// (1 + 2x + 3x²)(4 + 5x + 6x²) = 4 + 13x + 28x² + 27x³ + 18x⁴
assert_eq!(convolution(&q(&[1, 2, 3]), &q(&[4, 5, 6])), q(&[4, 13, 28, 27, 18]));
assert_eq!(fwht(&q(&[1, 2, 3, 4])), q(&[10, -2, -4, 0]));
assert_eq!(ifwht(&fwht(&q(&[1, 2, 3, 4]))), q(&[1, 2, 3, 4]));
assert_eq!(mobius_transform(&q(&[1, 2, 3, 4])), q(&[1, 3, 4, 10]));Functions§
- convolution
- Linear convolution
c[k] = Σᵢ a[i]·b[k−i](SymPyconvolution(a, b)): the coefficients of the product of the polynomials with coefficient listsaandb(index = degree). - convolution_
cyclic - Cyclic convolution of length
n(SymPyconvolution(a, b, cycle=n)): the linear convolution folded modulon,c[k] = Σ_{i ≡ k (mod n)} lin[i]. - convolution_
ex - Linear convolution of symbolic coefficient lists:
c[k] = Σᵢ a[i]·b[k−i]asEx(the coefficients of the product of two polynomials given by theirExcoefficients). Empty if either input is empty. - convolution_
ntt - Linear convolution modulo a prime through the NTT (SymPy
convolution(a, b, prime=p)/convolution_ntt):nttboth inputs at a power-of-two length≥ |a| + |b| − 1, multiply pointwise,intt. - convolution_
subset - Subset convolution (SymPy
convolution_subset): indices are bitmasks andc[k] = Σ_{s ⊆ k} a[s]·b[k ∖ s]— the sum over all ways of writingkas a disjoint union of two subsets. - fwht
- Walsh–Hadamard transform (SymPy
fwht), Hadamard ordering:A[k] = Σⱼ (−1)^{popcount(j & k)} a[j]. The input is zero-padded to a power of two. - ifwht
- Inverse Walsh–Hadamard transform (SymPy
ifwht):fwhtdivided by the (padded) length, soifwht(fwht(a)) == afor a power-of-two length. - intt
- Inverse number-theoretic transform (SymPy
intt):a[j] = n⁻¹·Σₖ A[k]·ω⁻ʲᵏ mod p, so thatintt(ntt(a)) == afor a power-of-two length. - inverse_
mobius_ transform - Inverse of
mobius_transform(SymPyinverse_mobius_transform(seq)): recoversafrom its subset sums,a[k] = Σ_{s ⊆ k} (−1)^{|k∖s|} A[s]. - inverse_
mobius_ transform_ superset - Inverse of
mobius_transform_superset(SymPyinverse_mobius_transform(seq, subset=False)). - mobius_
transform - Möbius transform over subsets (SymPy
mobius_transform(seq)withsubset=True): indices are bitmasks andA[k] = Σ_{s ⊆ k} a[s]. The input is zero-padded to a power of two. - mobius_
transform_ superset - Möbius transform over supersets (SymPy
mobius_transform(seq, subset=False)):A[k] = Σ_{s ⊇ k} a[s]over the padded index range. - ntt
- Number-theoretic transform (SymPy
ntt): the discrete Fourier transform ofaoverℤ/pℤ,A[k] = Σⱼ a[j]·ωʲᵏ mod p, withω = g^{(p−1)/n}for the smallest primitive rootg(the same root SymPy uses, so the outputs agree entry for entry).