Alex Zywicki
Alex Zywicki

Reputation: 2313

template based Sin() implementation based on taylor series produces incorrect results C++

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<>
inline double power<0>(double const& value){
    return 1;
}

template<unsigned term>
inline double taylor_polynomial(double const& x){
    return power<term>(x) / factorial<term>::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);
}

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

Using the following code I have attempted to implement the sin() function based on an N term taylor series, but when i compare the results of the function the results are incorrect and I'm not sure why. Running the following code:

std::cout<<sin(2 * M_PI * 0.5)<<"   "<<taylor_sine<13>(2 * M_PI * 0.5);

Results in 1.22465e-16 -16546.9

To the best of my knowledge i am calculating the series correctly so i'm not sure what is going wrong.

Upvotes: 0

Views: 174

Answers (1)

Barry
Barry

Reputation: 303147

You're calling the wrong function to recurse:

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

You're adding term n and term n-1 instead of adding term n and the taylor series of n-1 terms.

Upvotes: 3

Related Questions