# 複素振幅の数値範囲を保つ修正案

2026-10-26。FFT複素値・MXCSRの追加観測を待つ間の条件付き検討。以下の修正は未実装・未計測であり、原因の確定や品質改善の主張ではない。

## 入力を増幅する前に、振幅計算の数値範囲を保つ

GCCはfast-mathでベクトル化したfloatの平方根に、逆平方根とNewton補正を用いることを明記している。今回のELFでもその命令列がある。入力を一律に正規化したり、出たNaNを0へ置き換えたりするより、有限の複素値から数学的な振幅を有限に求める局所処理を検討する。

https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html
https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html

ただし、命令が存在することと、今回の値を生じた機構が分かったことは別である。まず実際の複素値・作業スレッドの設定と、非有限になった位置を照合する。

## 有力なのは尺度調整か、二乗前の倍精度化

LAPACKのSLAPY2は、二つの絶対値の大きい方wと小さい方zを使い、w×sqrt(1+(z/w)²)とする。平方根へ渡す値が1から2の範囲になるため、微小な元の値を直接二乗する問題を避けられる。ゼロ・非有限の扱いも分ける。ただし、この式を無制限のfast-mathでコンパイルするだけでは演算順が保たれる保証にならない。

https://www.netlib.org/lapack/explore-html/d8/d5e/group__lapy2_ga1b34ab91f97381308acb6020082ee897.html

もう一つは、実部・虚部をそれぞれ二乗する前にbinary64へ変換し、二乗和と平方根を求めてからfloatへ戻す方法である。有限のbinary32入力では、非ゼロの二乗は2⁻²⁹⁸以上、二つの二乗和は2²⁵⁷未満で、binary64の正規範囲へ収まる。floatで二乗してからdoubleへ変換しても、この保証にはならない。

過去のglibcにもdoubleで二乗・平方根を計算してfloatへ戻す実装例がある。現在の実行環境のlibcがその版だという意味ではなく、数値手法の先例として参照する。

https://sourceware.org/pipermail/glibc-cvs/2021q4/075898.html

この方法も、コンパイラーが広い演算を保つこと、変換時に入力を失わないことが前提である。FPUのDAZ/FTZを勝手に変更する案は採らない。元がfloatでも、中間精度の変更は明示し、通常音量での丸め差や速度を未測定のまま同等と言わない。

## fast-mathの一括停止は最初の変更にしない

平方根だけをstrict-mathで別の小さな翻訳単位へ分離すれば、危険な逆平方根への変換を止められる可能性がある。しかしfloatの二乗自体のunderflowやoverflowは残る。全体のfast-mathを外す案は、無関係なDSPまで変えるため、局所問題への最初の修正としては範囲が広い。

GCC自身はoptimize関数属性を本番用には推奨していない。必要なら独立した小さなソース単位と明示したビルド条件で境界を設ける。実際の命令列も確認する。

https://gcc.gnu.org/onlinedocs/gcc/Common-Attributes.html

## 五役の二巡で、数値修正を音質改善と混同しない

第一巡。数値担当は、直接二乗をしない尺度調整と倍精度中間値の保証を挙げた。信号処理担当は、振幅の数学的定義を変えず、元入力の音量へ手を加えない案を支持した。実装担当はコンパイラーによる再変形とFPU状態を確認事項にした。評価担当は通常範囲の丸め・速度・音質が同一とは限らないとした。批評家は全体の最適化設定や入力正規化まで一緒に変えることを退けた。

第二巡。追加観測で仮説が支持された場合だけ、局所的な数値修正を一つ選び、版と変更範囲を固定する方針にした。NaNの除去を目的にした値の置換や閾値探索はしない。原因への対処と、固定120録音の品質比較・採用判断を別にする。元の未取得品質アーカイブと欠測を修正後の値で埋めない。
