|
ひとつ前へ WWWルートへ mad@mail.wind.ne.jp 近似関数 数理設計研究所 Hal.T 2010/01/14 |
Index |
ちょいとせこい方法でとにかく高速化しなくちゃならん場合に使うんだよ。
ただし、適用領域と誤差はよおく考えてくれたまえ。
余弦関数の近似にπ/2を与えればOK
-π/2 〜 +π/2 の両端およびX=0の時にY=1として放物線でフィットさせたもの。
見てわかるように誤差は5.5%ほど大きめになる。
図の説明:
上図は全体赤がcos、青が近似
下図はcos-近似の誤差量
/*atan2の代用になる0〜4を帰す関数、0,0のときは0を帰すようにしてあるのでエラーはない
アルゴリズムC++ R・セジウィック 近代科学者 P402 */
inline double aatan2(const double y, const double x) {
double a = fabs(x) + fabs(y);
double t = (a == 0)? 0 : y/a;
if(x<0) t=2-t; else if(y<0) t+=4;
return t;
}
√(x^2+y^2) の形式で精密に求めるのには遅い場合
手法:
X,Yの大きいほうを1000に規格化してそのための係数を記録、テーブル参照で引いてから、係数処理して元に戻す。
整数計算しかできない非力なCPUのためのお助けコード。
abs2.cpp へのリンク
整数計算しかできないPowerPCにて sqrt(x*x+y*y) は 60マイクロ秒/回 abs_int(x, y) は 0.38マイクロ秒/回
1000,1000のデータだとして計算誤差は0.1%ぐらいある。
1000に規格化するか10000にするかなど自由にしてOKだが、オーバフローしないようにしてね。
short int の範囲±32768ではうまく動く、途中でFIX1倍=1000倍しているのでintの1000分の1までは動作するということだ。
えばって言えば、数値計算アルゴリズムの研究ってのはこういうことの積み重ね。157倍も早くなる。
..end