qft2 — QUAT fourier op

データ種: qimageqimage

呼び出し: import quatimage; quatimage.qft2(qimage, side, mu=None) -> 'np.ndarray' (または opsquat.get("qft2"))

使い方

四元数(超複素)2-D フーリエ変換。→ 中心化した (H, W, 4) スペクトル。

> 以下の詳細説明は原文のままです —— 要約と見出しは訳出済み。

The colour analogue of `complexops.cx_fft`: a colour image is transformed

as one hypercomplex signal rather than three unrelated real ones. The

kernel is `exp(-mu * 2*pi*(u*x/W + v*y/H))` for a unit pure quaternion

*mu* (default: the grey axis of RGB, Sangwine's choice), and because

quaternions do not commute the kernel can be applied on either side:

• `side="left"F[u,v] = sum_{x,y} E(x,y,u,v) * f[x,y]`

• `side="right"F[u,v] = sum_{x,y} f[x,y] * E(x,y,u,v)`

The argument is required. Left and right are not a sign convention. On

the fuzzer's `(32, 32)` dichromatic render they differ by

`max|F_L - F_R| = 19.11 against a peak modulus of 1045` (1.8 % of full

scale) and on a random colour field by `33.35 against 892.9` (3.7 %; another seed

gives 34.05 against 892) —

with no exception and no NaN to mark the difference. **Mixing them across a

round trip is much worse**, because there the disagreement is not attenuated

by the spectrum's dynamic range: `iqft2(qft2(q, "left"), "right")` returns

an image whose error reaches `1.113 on data whose own range is 0.9994`

— a completely different picture that still looks like a picture. (On the

grey-axis-dominated dichromatic render the same mistake costs only `0.054`

against a range of `1.076`, which is the dangerous case: a 5 % error is

exactly the size that survives a visual check.)

The spectrum is returned centred (DC at the array centre, via

`fftshift), matching the convention complexops.cx_fft` established for

the `cimage sort. :func:iqft2` un-centres before inverting, and the round

trip is exact: measured `max|iqft2(qft2(q, s), s) - q| = 2.22e-15` for both

sides on a standard-normal `(32, 32, 4)` field.

How it is computed, and why that is not a shortcut

--------------------------------------------------

Every quaternion splits as `q = A + B*nu with A, B` in the commutative

subfield generated by `mu` (the *symplectic decomposition*, Ell &

Sangwine 2007). The kernel commutes with `A` and *anti*-commutes past

`nu`, so the whole transform reduces to two ordinary complex FFTs — for

the left transform both with the standard kernel, for the right one of them

with the conjugate kernel. **That reduction is what makes left and right

differ**, and it is verified against a brute-force `O(N^2)` quaternion DFT

written straight from the definition, on a 4x4 image, for three different

`mu` and both sides: the largest disagreement over all six combinations is

8.2e-15. The fast path is checked against the definition, not against

itself. The choice of the internal `nu` is likewise verified not to matter

(two different `nu, max difference 1.4e-14 — see :func:_mu_basis`).

Honest accounting against the channelwise baseline

--------------------------------------------------

Because the decomposition above is *linear* in the channels, the QFT is a

fixed recombination of the three per-channel complex FFTs: rebuilding

`qft2(q, "left") from three numpy.fft.fft2` calls on the R, G and B

planes agrees to `max|err| = 1.14e-13`. So this transform **buys no

information a channelwise FFT does not already contain**, and this module

does not claim it does. It also does not buy speed — it moves four real

transforms' worth of data where the channelwise route moves three, and pays

for the symplectic pack/unpack on top: measured on `(256, 256)`, best of

20, 8.246 ms against 3.409 ms, i.e. 2.42x slower (run to run, 2.3x-2.4x). What it buys is that

the four numbers stay one algebraic object, so a rotor can be applied to the

spectrum and the colour meaning of `mu` survives the transform.

Raises `ValueError: *qimage* is not a valid (H, W, 4)` field;

*side* is not `'left' / 'right'`; *mu* is not a finite non-zero

3-vector.

詳しい使い方ガイド

quaternion_monogenic ファミリ ガイド

参考(サンプルデータ・文献)

• サンプルデータ カタログ(DL URL / ライセンス) — 2-D は skimage.data(BSD/public)+ 合成、3-D は実データ源(Stanford/PDS 等)の DL URL。

• 演算子の来歴・参考文献 — この op 族の元になった研究/手法の出典。

• アルゴリズムの正典(著者・年)と用途は上記ファミリ使い方ガイドに記載。

実行できる例(この op を実際に呼ぶ検証済みサンプル)

quaternion_monogenicpy -3.11 examples/quaternion_monogenic.py

型が繋がる次の op(qimage を入力に取れる)

quaternion_to_rgb · quat_norm · quat_conjugate_image · quat_normalize_image · quat_image_multiply · monogenic_amplitude · monogenic_phase · monogenic_orientation

同カテゴリ(fourier)

iqft2


*Provenance: quatimage.py — QUAT operator registry. この per-op ノートは tools/opdocs.py md が自動生成(手編集しない)。*

© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.