'Testing program for convergence?
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;
}
Solution 1:[1]
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)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
