2

他の質問で示したように、私は現在、特にコンパイル時の演算用の型とメタ関数のセットを含む C++ メタプログラミング ライブラリを実装しています。

私の目標は、三角関数sincos固定小数点型を実装することです。
私の問題は、三角アルゴリズムについて私が見つけたすべての論文がCORDICまたはある種のテイラー級数について述べていることです。CORDIC の問題は、ルックアップ テーブルを介して事前に計算された値の膨大なセットが必要であり、tmp で簡単に提供できないことです。また、CORDIC のポイントは、乗数を持たないハードウェアでその三角関数を計算することであり、ライブラリで乗算を行うことが完全に可能です。

私の質問は次のとおりです。三角関数を計算するために、CORDIC と Taylor Series に代わる簡単な方法はありますか?

4

2 に答える 2

3

Finally I have implemented the sin metafunction through Taylor series, using series of 10 terms by default (Could be configurable). I have based my implementation in this interesting article.

My library includes an implementation of a tmp for loop using iterators, and expression templates to allow write complex expressions in a "clear" way (Clear compared to the common template-meta-programming syntax add<mul<sub<1,2>>>...). This allows me to literally copy-paste the C implementation provided by the article:

template<typename T , typename TERMS_COUNT = mpl::uinteger<4>>
struct sin_t;

template<typename T , typename TERMS_COUNT = mpl::uinteger<4>>
using sin = typename sin_t<T,TERMS_COUNT>::result;

/*
 * sin() function implementation through Taylor series (Check http://www10.informatik.uni-erlangen.de/~pflaum/pflaum/ProSeminar/meta-art.html)
 * 
 * The C equivalent code is:
 * 
 * // Calculate sin(x) using j terms
 * float sine(float x, int j)
 * {
 *     float val = 1;
 *
 *     for (int k = j - 1; k >= 0; --k)
 *         val = 1 - x*x/(2*k+2)/(2*k+3)*val;
 *
 *     return x * val;
 * }
 */

template<mpl::fpbits BITS , mpl::fbcount PRECISION , unsigned int TERMS_COUNT>
struct sin_t<mpl::fixed_point<BITS,PRECISION>,mpl::uinteger<TERMS_COUNT>>
{
private:
    using x = mpl::fixed_point<BITS,PRECISION>;

    using begin = mpl::make_integer_backward_iterator<TERMS_COUNT-1>;
    using end   = mpl::make_integer_backward_iterator<-1>;

    using one   = mpl::decimal<1,0,PRECISION>;
    using two   = mpl::decimal<2,0,PRECISION>;
    using three = mpl::decimal<3,0,PRECISION>;

    template<typename K , typename VAL>
    struct kernel : public mpl::function<decltype( one() - ( x() * x() )/(two() * K() + two())/(two()*K()+three())*VAL() )> {};

public:
    using result = decltype( x() * mpl::for_loop<begin , end , one , kernel>() );
};

Here is the header of the implementation in the project repo.

于 2013-09-14T14:25:08.123 に答える
2

ルックアップ テーブルによる事前計算された値の膨大なセット

「巨大」はいくつ?1 回限りの作業のように思えますが、完了すると非常に高速になります。私のアドバイス?シャベルを手に入れて、その表に記入してください。ここで別の回答が得られるまでに完了しているはずです。

于 2013-09-12T01:14:42.623 に答える