基于泰勒级数的Sin()实现,使用c++模板

Taylor Series based Sin() implementation using templates C++

本文关键字:实现 使用 c++ 模板 于泰勒 Sin      更新时间:2023-10-16

我正在使用模板实现基于泰勒级数的sin()函数。到目前为止,我的代码如下:

template<unsigned I>
struct factorial{
    enum{  
    value = I * factorial<I -1>::value
    };
};
template<>
struct factorial<0>
{
    enum{ value = 1};
};
template<unsigned pow>
inline double power(double const& value){
    return value * power<pow-1>(value);
}
template<>
inline double power<1>(double const& value){
    return value;
}
template <unsigned term>
inline double taylor_sine_term(double const& x) {
    return (power<term>(-1) / factorial<(2*term)+1>::value) * power<(2*term)+1>(x);
}

我遇到的问题是创建函数来使用taylor_sine_term函数来展开N个项的级数。该函数在功能上与以下函数等效。

template<unsigned terms>
inline double taylor_sine(double const& x){
    return taylor_sine_term<1>(x)+taylor_sine_term<2>(x) + ... + taylor_sine_term<terms>(x);
}

基本上,我需要找出一种方法来生成一个整数常量序列,可以用作taylor_sine_term函数中N个术语的术语数模板参数,并将它们全部加在一起。结果将展开为N个项的完整泰勒级数。问题是我不知道从哪里开始。

跟你写的一样:递归情况和基本情况:

template<unsigned terms>
inline double taylor_sine(double const& x) {
    return taylor_sine_term<terms>(x) + // current term
           taylor_sine<terms-1>(x);     // rest of terms
}
template <>
inline double taylor_sine<0>(const double& x) {
    return taylor_sine_term<0>(x);
}

或者,您可以使用索引序列技巧来获得所有这些:

template <unsigned terms>
inline double taylor_sine(double const& x) {
    return taylor_sine(x, std::make_index_sequence<terms+1>{});
}
template <unsigned terms, size_t... Is>
inline double taylor_sine(const double& x, std::index_sequence<Is...> ) {
    double res = 0.0;
    for (double t : {taylor_sine_term<Is>(x)...}) {
        res += t;
    }
    return res;
    /* or in C++17
    return (taylor_sine_term<Is>(x) + ...);
    */
}

注意,您应该将power上的基本情况更改为power<0>

听起来你想要一个递归定义的模板

template<unsigned terms>
inline double taylor_sine(double const& x){
    return taylor_sine<terms-1>(x)+taylor_sine_term<terms>(x);
}

希望专门化以使0或1终止。但是我认为你不能专门化函数模板,所以你需要把所有这些都隐藏在一个可以专门化的函子模板中。