10

sin関数は遅く、cos組み込みシステムで実行するには多くのリソースが必要です。よりリソースを節約し、より高速な方法で計算sinして機能させるにはどうすればよいでしょうか?cos

4

11 に答える 11

16

テイラー級数またはフーリエ級数を計算するには、常に時間がかかります。

組み込みシステムでは、ルックアップ テーブルについて考える必要があります。

Hewlett-Packard が初期の関数電卓でこのような計算をどのように最適化したかについての興味深い情報が 'Net にもあるかもしれません。

当時、こんなものを見た記憶があります

于 2009-10-15T10:26:47.500 に答える
10

補間を使用したルックアップテーブルが間違いなく最も効率的なソリューションです。ただし、使用するメモリを少なくしたい場合、CORDICは三角関数の値を計算するための非常に効率的なアルゴリズムであり、通常、ハンドヘルド計算機に実装されます。

副次的な点として、フーリエ級数を使用してこれらの関数を表すことは意味がありません。これは、級数のsin/cos項を評価する方法の循環問題を作成しているだけだからです。テイラー級数はよく知られている近似法ですが、多くの場合、誤差は許容できないほど大きいことがわかります。

また、Javaの高速三角関数に関するこの質問とその回答を確認することもできます(したがって、コードは簡単に移植できます)。とりわけ、CORDIC近似とChebyshev近似の両方に言及しています。それらの1つは間違いなくあなたのニーズに合うでしょう。

于 2009-10-15T10:35:50.310 に答える
4

この Dobb 博士の記事: Optimizing Math-Intensive Applications with Fixed-Point Arithmeticには、CORDIC アルゴリズムの適切な説明があり、この記事で説明されているライブラリの完全なソース コードが提供されています。

于 2009-10-15T16:01:38.743 に答える
4

何のために必要かによります。角度の精度にあまりこだわらない場合 (たとえば、最も近い角度まで問題がない場合)、値のルックアップ テーブルを使用してください。FPU がない場合は、固定小数点で作業します。

sin/cos 関数を計算する簡単な方法の 1 つは、テイラー級数を使用することです (ここの三角関数で示されているように)。使用する用語が少ないほど、値の精度は低くなりますが、計算は高速になります。

フーリエ級数の計算では、いくつかの sin/cos 値を知る必要があります。ただし、ほとんどの場合、周波数領域に保存すると、実行内容によっては計算を節約できる可能性があります。

于 2009-10-15T10:29:57.477 に答える
2

Stack Overflow の質問を参照してください。三角関数はどのように機能しますか? そこで受け入れられた答えは、範囲削減を行う方法の詳細を説明し、CORDIC を使用して、さらに最適化を行います。

于 2009-10-15T11:57:25.553 に答える
2
  1. ルックアップ テーブル
  2. あなたの言うように、テイラーシリーズ

ルックアップ テーブルを使用すると、ドメインを制限することで物事を最適化できることがよくあることに注意してください。たとえば、角度を unsigned char として表すと、円の周りに 256 ステップしかなく、非常にコンパクトなテーブルが得られます。固定小数点を使用するなど、同様のことが値に対して実行できます。

于 2009-10-15T10:27:55.587 に答える
0

8ビットAVRマイクロコントローラー用のこの任意の固定小数点ライブラリを見ることができます: https ://community.atmel.com/projects/afp-arbitrary-fixed-point-lib

編集:リンクが更新されました

于 2012-06-25T12:47:46.710 に答える
0

これはいくつかの助け/インスピレーションになるかもしれません: Quake IIIの魔法の平方根

于 2012-06-22T18:26:14.320 に答える
0

私はパーティーに少し遅れましたが、とにかく、ルックアップ テーブル (テーブル ジェネレーターが含まれています) を使用する既製の効率的なソリューションを共有したいと思います: DFTrig

DFTrig は 2 つの部分で構成されています。

  • いくつかのオプションを受け取り、C コード (ルックアップ テーブルを持つ const struct) を生成するルックアップ テーブル ジェネレーターtablegen(Java で書かれていますが、それほど重要ではありません)
  • によって生成されたルックアップ テーブルで動作する小さな C モジュールtablegen

もちろん、ルックアップ テーブルには最小限の情報しか含まれていません。つまり、1 つの象限、つまり[0, 90]度の正弦値だけです。これは、任意の角度のサイン/コサインを計算するのに十分です。

動作は非常にカスタマイズ可能です。以下を指定できます。

  • ルックアップ テーブルの各項目に掛ける係数 (テーブルごとに)。
  • テーブル内の各項目間のステップ (テーブルごとに)。テーブル内のアイテムのタイプ (C プロジェクト全体で共通)。

したがって、ニーズに応じて、次のことができます。

  • アプリケーション全体の単一のテーブルを最大係数で生成します。これにより、C プロジェクトの任意のサブシステムがその単一のテーブルを使用して目的の係数を提供できるようになり、要求された係数がテーブルの係数以外の場合は再計算されます。
  • それぞれがアドホック ファクターで複数のテーブルを生成し、C プロジェクトの各サブシステムは専用のテーブルを使用します。次に、再計算せずに、テーブルから値をそのまま返すことができます。それはより速く動作します。

組み込みプロジェクトで使用していますが、うまく機能します。

于 2015-03-23T09:59:42.433 に答える
0

場合によっては、必要な周波数で共振するように調整された IIR フィルターだけで管理できます。こちらをご覧ください: http://www.ee.ic.ac.uk/pcheung/teaching/ee3_Study_Project/Sinewave%20Generation(708).pdf

于 2010-01-06T20:14:44.987 に答える
0

素敵な疑似コードの例がここにあり、明示的なコードがここにあるようです。

ただし、@unwind が提案したように、適切なコンピューターでこれらのテーブルを事前に計算し、そのテーブルを組み込みデバイスにロードすることをお勧めします。

答えがそれほど正確である必要がない場合、ルックアップ テーブルはかなり小さくなり、デバイスのメモリに保存できます。より高い精度が必要な場合は、デバイス内で計算する必要があります。これは、メモリ、時間、および必要な精度の間のトレードオフです。答えは、プロジェクトの特定の性質に依存します。

于 2009-10-15T10:26:59.557 に答える