1

So, I'm pretty inexperienced with calculus, and in C++, so please bear with me if I'm misunderstanding this completely. I'm supposed to be testing this Taylor series program for convergence, which I'm told is when the output value does no change. However, the way mine is written out, it seems impossible as I'm iterating through for loops while implementing it. After around 12 it's no longer accurate to the library sin(); but I'm not sure if that's the same thing because it doesn't seem to be. Advice on what I'm looking for would be grand, I really appreciate it. Apologies again if this question is stupid!

Here is my code:

#include <iostream>
#include<cmath>

using namespace std;



double getFactorial (double num)
{
  long double factorial = 1.0;
  
      for (int i = 1; i <= num; ++i)
    {
      factorial *= i;   //iterates from 1 to num value, multiplying by each number
    }
      
      return factorial;
    }



double taylorSin(double num){
    
    double value=0;
    
   for(int i=0;i<20;i++){
        
        value+=pow(-1.0,i)*pow(num,2*i+1)/getFactorial(2*i+1);
   }
     return value;
}


int main ()
{ cout<<getFactorial(6);
   
  for(double i=1;i<=12;i++){ 
      //loops through given amount of values to test function
    double series=i; //assign double type variable with value of i

  
  //cout<<"Taylor function result is "<<taylorSin(series)<<endl;
  //cout<<"Library sin result is "<<sin(series)<<endl;
  
  }
  return 0;
}
AstralV
  • 119
  • 7
  • Before trying to answer your question, do you need convergence check programatically? I mean, do you need to truncate the series when the addition result is same when add a term? – K.R.Park Feb 24 '22 at 01:47
  • Is there a better way? I'm kind of struggling with how I'd efficiently check it writing it out... – AstralV Feb 24 '22 at 01:50
  • There is many known way to check the convergence of the series available, https://en.wikipedia.org/wiki/Convergence_tests , And Although your approach ( when sum has no effect truncate ) is not mathematically rigorous, many people does that anyway. What I want to know is, do you need rigorous test or just working one. – K.R.Park Feb 24 '22 at 01:52
  • And I need to know you need the series sum or just check its convergence. – K.R.Park Feb 24 '22 at 02:05
  • If you want to check it programmatically, python might be easier to catch up. I think even excel might do it well. With some automation. – Louis Go Feb 24 '22 at 02:11
  • And do you really need the factorial implementation? there is `std::tgamma` already to perform factorial operation... And combined with my convergence check, taylor expansion of `sin` agreed to `std::sin()`. To answer your question, you need to specify what exactly you are trying and what is your problem. – K.R.Park Feb 24 '22 at 02:17

1 Answers1

0

Based on your answer, I wrote a taylor summing program:

#include <iostream>
#include <cmath>
#include <limits>
#include <concepts>

template<typename F>
concept my_lambda = requires(F f, unsigned long long int x) {
    { f(x) } -> std::same_as<long double>;
};

template<my_lambda ftn>
long double Taylor_sum(ftn term) noexcept {
    using namespace std;
    long double value = 0, prev = 0;
    unsigned long long int i = 0;
    try {
        do {
            if (i == numeric_limits<unsigned long long>::max() || !isfinite(prev)) return numeric_limits<long double>::quiet_NaN();
            prev = value;
            value += term(i++);
        } while (prev != value);
        return value;
    }
    catch (...) { return numeric_limits<long double>::quiet_NaN(); }
};

int main() {
    using namespace std;  long double x; cin >> x ;
    long double series_sum = Taylor_sum([x](unsigned long long int i) -> long double { return /*Your implementation here*/; });
    if (!isfinite(series_sum)) cout << "Series does not converge!" << endl;
    else {
        cout << "Series converged, its value is : " << series_sum << endl;
        cout << "Compared to sin                : " << sinl(x) << endl;
    }
    return 0;
}

Although comparing term before & after summing is not much rigorous way to check convergence, but this approach is usual approach in practice.

Note: When I used this function for large x, it differed from the std::sin() and diverged when x is large enough. This is because the floating-point arithmetic has limited precision (std::sin() is more accurate because it takes the periodic nature of the original sine function)

K.R.Park
  • 1,015
  • 1
  • 4
  • 18