Sin関数をより速くより正確に計算する方法は?


8

を計算しますy(n)=32677Sin(45/1024•n)yは整数で、n範囲は0〜2048です。このプロセスをより速く、より正確にするにはどうすればよいですか?以来:今、私はあなたの参照の答えを示したい Sin(a+b)=Sin(a)Cos(b)+Cos(a)Sin(b) とし Cos(a+b)=Cos(a)Cos(b)-Sin(a)Cos(b)。だから私は保存することができ Sin(45/1024•1)、そして Cos(45/1024•1)次の公式を使います:

Sin(45/1024•2)=Sin(45/1024•1+45/1024•1)Cos(45/1024•2)=Cos(45/1024•1+45/1024•1)Sin(45/1024•n)=Sin(45/1024•(n-1)+45/1024•1)Cos(45/1024•n)=Cos(45/1024•(n-1)+45/1024•1)、この方法で多分速く大きな配列を格納せずに。


この質問は、ソフトウェアエンジニアリングの問題の観点から適切なアルゴリズムやデータ構造、あるいはその両方について学ぶことを意図していると想定して、プログラマーに適しています。
Thomas Owens

8
その45は少し疑わしいです。度単位sin(x)であなたが欲しいと思うようになりますx。その場合は、トリガー関数への引数は通常ラジアンであることに注意する必要があります。引数はC ++ではラジアンです。これにより、この質問にタグが付けられます。
David Hammen、2012年

なぜこの質問に答える必要があるのですか?アプリケーションは何ですか?
GlenPeterson、2012年

結果をどの程度正確にする必要がありますか?
dan04

@ dan04 yは整数なので、整数として正確にする必要があります。
LaiJong 2012年

回答:


18

場合はn0から2048までの範囲は、あなたができる配列で、その後、店舗の値を事前に計算します。y(n)になるだろうvalues[n]


+1とその間にある値を補間できます(可能であれば)。
Daniel B

1
これは実行可能なオプションですが、計算よりも効率的であることを確認するためにプロファイリングします(たとえば、FPU fsinが使用され、一部の配列よりもキャッシュフレンドリーになる場合があります)。
ベンジャミンバニエ

値[n]を保存しないのはどうですか?
LaiJong

3
三角関数は、その場で計算するのが非常に遅いです。私はすべての高速実装が事前に計算された値を使用すると確信しています。sin()とcos()は周期的であるため、最初の90度のみを保存する必要があります。象限に応じて、-sin()、sin(90-角度)、または-sin(90-角度)を返すことができます。sin()に関してcos()を定義することもできます。入力値の可能な範囲がわかっている場合は、事前計算して、プログラムに必要な値のみを保存できます。そうでない場合は、限られた数の値の間の補間が最も速いオプションになる場合があります。
GlenPeterson、2012年

1
@Glen:罪の値は-1から1の間なので、実際には16ビットの符号なしに収まります。
vartec 2012年

1

実行時ではなくコンパイル時にテーブルを計算します。

あなたは、16ビットのスケーリングされた整数値の2048要素のテーブルを実行しています。

安価なMatlabスクリプトを書き、最終的なプログラミング言語に適したデータ行を提供する印刷物を使用します。結果を定数データテーブルとしてソースコードにカットアンドペーストし、実行時にテーブルルックアップを実行します。これにより、プログラムの起動時間ではなく、初期計算時間がビルドサイクルに組み込まれます。


追加のプログラマーコストと比較して、どれだけのランタイムが節約されますか?
JBRウィルキンソン2012年

早くて汚い。いいね。
Quant

1

関数の形式を考えると、自然な答えはCORDICアルゴリズムです。これは、質問の内訳よりもはるかにクリーンなアプローチです。一方、必要なテーブルは、他の人が提案したテーブルよりもはるかに小さくなります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.