pyFDN.kronecker_transform#

pyFDN.kronecker_transform(x, angles, kernel_type='rotation')[source]#

Apply the Kronecker feedback matrix to x in O(N log2 N) per row.

Equivalent to x @ kronecker_matrix(angles, kernel_type).T but computed with the in-place divide-and-conquer butterfly of the paper’s Algorithm 2: M = log2(N) levels, each touching every sample once. Level i mixes the channel pairs that differ in bit i - 1 of their index, which is exactly the pairing kernel K_i addresses.

Angles may vary per sample, which is what makes an audio-rate modulated feedback matrix cheap: only the modulated 2x2 kernel changes, never a rebuilt N x N matrix.

Parameters:
  • x (ArrayLike) – Signal of shape (N,) or (num_samples, N); the last axis is the channel axis.

  • angles (ArrayLike) – M angles of shape (M,) for a fixed matrix, or (num_samples, M) for one angle set per sample.

  • kernel_type (str | Sequence[str]) – "rotation" or "reflection", either once for all kernels or one per kernel (innermost first).

Return type:

ndarray

Returns:

  • np.ndarray – Mixed signal, same shape as x (2-D input stays 2-D).

  • Example:: – >>> import numpy as np >>> angles = np.full(3, np.pi / 4) >>> x = np.random.randn(16, 8) >>> fast = kronecker_transform(x, angles) >>> np.allclose(fast, x @ kronecker_matrix(angles).T) True