sin
関数は遅く、cos
組み込みシステムで実行するには多くのリソースが必要です。よりリソースを節約し、より高速な方法で計算sin
して機能させるにはどうすればよいでしょうか?cos
11 に答える
テイラー級数またはフーリエ級数を計算するには、常に時間がかかります。
組み込みシステムでは、ルックアップ テーブルについて考える必要があります。
Hewlett-Packard が初期の関数電卓でこのような計算をどのように最適化したかについての興味深い情報が 'Net にもあるかもしれません。
当時、こんなものを見た記憶があります
補間を使用したルックアップテーブルが間違いなく最も効率的なソリューションです。ただし、使用するメモリを少なくしたい場合、CORDICは三角関数の値を計算するための非常に効率的なアルゴリズムであり、通常、ハンドヘルド計算機に実装されます。
副次的な点として、フーリエ級数を使用してこれらの関数を表すことは意味がありません。これは、級数のsin/cos項を評価する方法の循環問題を作成しているだけだからです。テイラー級数はよく知られている近似法ですが、多くの場合、誤差は許容できないほど大きいことがわかります。
また、Javaの高速三角関数に関するこの質問とその回答を確認することもできます(したがって、コードは簡単に移植できます)。とりわけ、CORDIC近似とChebyshev近似の両方に言及しています。それらの1つは間違いなくあなたのニーズに合うでしょう。
この Dobb 博士の記事: Optimizing Math-Intensive Applications with Fixed-Point Arithmeticには、CORDIC アルゴリズムの適切な説明があり、この記事で説明されているライブラリの完全なソース コードが提供されています。
何のために必要かによります。角度の精度にあまりこだわらない場合 (たとえば、最も近い角度まで問題がない場合)、値のルックアップ テーブルを使用してください。FPU がない場合は、固定小数点で作業します。
sin/cos 関数を計算する簡単な方法の 1 つは、テイラー級数を使用することです (ここの三角関数で示されているように)。使用する用語が少ないほど、値の精度は低くなりますが、計算は高速になります。
フーリエ級数の計算では、いくつかの sin/cos 値を知る必要があります。ただし、ほとんどの場合、周波数領域に保存すると、実行内容によっては計算を節約できる可能性があります。
Stack Overflow の質問を参照してください。三角関数はどのように機能しますか? そこで受け入れられた答えは、範囲削減を行う方法の詳細を説明し、CORDIC を使用して、さらに最適化を行います。
- ルックアップ テーブル
- あなたの言うように、テイラーシリーズ
ルックアップ テーブルを使用すると、ドメインを制限することで物事を最適化できることがよくあることに注意してください。たとえば、角度を unsigned char として表すと、円の周りに 256 ステップしかなく、非常にコンパクトなテーブルが得られます。固定小数点を使用するなど、同様のことが値に対して実行できます。
8ビットAVRマイクロコントローラー用のこの任意の固定小数点ライブラリを見ることができます: https ://community.atmel.com/projects/afp-arbitrary-fixed-point-lib
編集:リンクが更新されました
これはいくつかの助け/インスピレーションになるかもしれません: Quake IIIの魔法の平方根
私はパーティーに少し遅れましたが、とにかく、ルックアップ テーブル (テーブル ジェネレーターが含まれています) を使用する既製の効率的なソリューションを共有したいと思います: DFTrig。
DFTrig は 2 つの部分で構成されています。
- いくつかのオプションを受け取り、C コード (ルックアップ テーブルを持つ const struct) を生成するルックアップ テーブル ジェネレーター
tablegen
(Java で書かれていますが、それほど重要ではありません) - によって生成されたルックアップ テーブルで動作する小さな C モジュール
tablegen
。
もちろん、ルックアップ テーブルには最小限の情報しか含まれていません。つまり、1 つの象限、つまり[0, 90]
度の正弦値だけです。これは、任意の角度のサイン/コサインを計算するのに十分です。
動作は非常にカスタマイズ可能です。以下を指定できます。
- ルックアップ テーブルの各項目に掛ける係数 (テーブルごとに)。
- テーブル内の各項目間のステップ (テーブルごとに)。テーブル内のアイテムのタイプ (C プロジェクト全体で共通)。
したがって、ニーズに応じて、次のことができます。
- アプリケーション全体の単一のテーブルを最大係数で生成します。これにより、C プロジェクトの任意のサブシステムがその単一のテーブルを使用して目的の係数を提供できるようになり、要求された係数がテーブルの係数以外の場合は再計算されます。
- それぞれがアドホック ファクターで複数のテーブルを生成し、C プロジェクトの各サブシステムは専用のテーブルを使用します。次に、再計算せずに、テーブルから値をそのまま返すことができます。それはより速く動作します。
組み込みプロジェクトで使用していますが、うまく機能します。
場合によっては、必要な周波数で共振するように調整された IIR フィルターだけで管理できます。こちらをご覧ください: http://www.ee.ic.ac.uk/pcheung/teaching/ee3_Study_Project/Sinewave%20Generation(708).pdf