NNGSAをうまく動かしたい。キモは整数除算。
と思っていたら正規化定数が負になっているのを見て、異常だと思った。アルゴリズムのミスからPython実装まで疑ったが問題なかった。
そこでC言語実装版を見たら誤差が蓄積していた。固定小数演算による誤差蓄積。
対策としては、ブロック計算開始時に真の値にセットし直すこと。
- 固定小数 いつもお世話になってる。
- 固定小数点数の算術関数ライブラリ
- ■固定小数点数の除算 補正によって32bitのまま精度を良くする方法が載っている。
- 整数除算の高速化 これ、どこかで効いてくるはず。
また、除算の誤差もなんとか収まって発散は収まったように見える、が、圧縮率が悪い。
短めの音声で見てみると、先頭10000サンプルぐらいの残差が大きいことが見えてきていた。正規化定数の最小値を大きく取りすぎていたので小さくするなどの対処で若干改善したが、まだLMS(AR(1))に及ばず。
超えないことを真面目に追うべきなのだが、その後色々と弄っていた。すると、(やはりというか…)NGSA(正規化なしの残差の符号を取るだけ)にしたら圧縮性能が向上。。。。しかも、プリエンファシスと組み合わせてさらに圧縮性能向上。。。FLAC(-8)を超えた。SLAでやった残差のlog2を取るのは良くなかった。
フィルタを2段重ねることでttaも超えた。が、wavpack(-hh)は超えない。でも2段重ねは最終手段にしたい。ギリギリまでフィルタ次数8で戦い続ける。(8にするのはAR(2)まで試すことができるから。4は高速モード、16は高圧縮モードにしたい。)
NGSAで行くとして考えたいのはステップサイズ。分散(とAR係数から決まる係数)を掛けたほうがよいはず。自然勾配法の定義から、AR(1)の場合は \(1/(1 - \psi_{1}^{2})\) を掛けてやれば良いことが見えている。 また、デコーダを作る前準備として、ブロックヘッダの仕様を策定したい。
(一瞬怖くなって普通のsignアルゴリズムにしてみたら、NGSAのほうが良いのが確認できた。でも圧縮率の差は1%未満。。。)