基于Taylor Series的Sin()实现使用模板C ++

时间:2015-07-09 16:11:57

标签: c++ templates

我正在使用模板基于泰勒系列实现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个术语的完整泰勒系列。问题是我不知道从哪里开始。

感谢任何帮助,谢谢。

2 个答案:

答案 0 :(得分:1)

你写其他的方式相同:一个递归的案例和一个基本案例:

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>

答案 1 :(得分:0)

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

class Test_Class
{
    private $a = null;

    public function __construct($a = null)
    {
        $this->a = $a;
    }

    public function __destruct()
    {
        unset($this->a);
    }
}

print 'Memory before: '.memory_get_usage(1).' <br>'; // 262 144 
$a = [];
for ($i=0; $i<600000; $i++)
    $a[] = new Test_Class($i);

print 'Memory after create: '.memory_get_usage(1).' <br>'; // 129 761 280 

for($i=0; $i < count($a); $i++)
    unset($a[$i]);

unset($a);

print 'Memory after: '.memory_get_usage(1).' <br>'; // 35 389 440 

然后你会想要专门针对0或1来终止。但我认为你不能专门化功能模板,所以你需要把它全部放在一个可以专门化的仿函数模板中。