Calculating Pi using the Taylor series C++ - c++

I'm trying to implement a function to calculate pi using the taylor series, here is my code to do that
#include <iostream>
#include <math.h>
using namespace std;
double pi(int n)
{
double sum = 1.0;
int sign = -1;
for (int i = 1; i < n; i++)
{
sum += sign / (2.0 * i + 1.0);
sign = -sign;
}
return 4.0 * sum;
}
int main()
{
cout << "the value for pi is" << pi ;
}
For some reason my code keeps returning 1, but I cant see why
as a side note I want to make it so the code doing the taylor series stops running if the absolute value of the latest term of the series is less than the error in the latest estimate for pi
I was thinking of doing this by using a similar for loop to calculate the error, and a do... while loop across the whole function that stops the calculation of pi once this condition is met, but I'm not sure if there's an easier way to do this or where to start.
I'm fairly new to this forum and c++, any help I can get is really appreciated

You should evaluate the function with some value, for example 10:
cout << "the value for pi is " << pi(2000)<<endl;
Output:
the value for pi is 3.14109

pi in your example is a function that takes an argument. Hence you have to add parenthesis and an argument like this pi(50). 50 is just an example use whatever you want.

Related

C++ - dealing with infinitesimal numbers

I need to find some way to deal with infinitesimial double values.
For example:
exp(-0.00000000000000000000000000000100000000000000000003)= 0.99999999999999999999999999999899999999999999999997
But exp function produce result = 1.000000000000000000000000000000
So my first thought was to make my own exp function. Unfortunately I am getting same output.
double my_exp(double x)
{
bool minus = x < 0;
x = abs(x);
double exp = (double)1 + x;
double temp = x;
for (int i = 2; i < 100000; i++)
{
temp *= x / (double)i;
exp = exp + temp;
}
return minus ? exp : (double)1 / exp;
}
I found that issue is when such small numbers like 1.00000000000000000003e-030 doesn't work well when we try to subtract it, neither both if we subtracting or adding such a small number the result always is equal to 1.
Have U any idea how to manage with this?
Try using std::expm1
Computes the e (Euler's number, 2.7182818) raised to the given power
arg, minus 1.0. This function is more accurate than the expression
std::exp(arg)-1.0 if arg is close to zero.
#include <iostream>
#include <cmath>
int main()
{
std::cout << "expm1(-0.00000000000000000000000000000100000000000000000003) = " << std::expm1(-0.00000000000000000000000000000100000000000000000003) << '\n';
}
Run the example in the below source by changing the arguments to your very small numbers.
Source: https://en.cppreference.com/w/cpp/numeric/math/expm1
I think the best way of dealing with such small numbers is to use existing libraries. You could try GMP starting with their example to calculate billions of digits of pi. Another library, MPFR which is based on GMP, seems to be a good choice. I don't know when to choose one over the other.

How to find value of pi 5 digit by leibniz's series

I am starting to learn C++ and I have a problem with my code. I want to find the pi value using the Leibniz series and also the number of iterations to reach five significant digits (3.14159) but it's doesn't work.
#include<iostream>
#include <math.h>
using namespace std;
int main(){
double pi = 0.0;
int count = 0;
for ( int i = 0 ; i <= 10000 ; i++){
pi += 4*pow(-1,i)/(2*i+1);
if ( pi == 3.14159){
cout<<i;
break;
}
}
}
You may check if the absolute difference between the computed value via Leibniz series and the "true" value of pi is below a given tolerance. Instead of using 3.14159 as value for pi, you may use the built-in constant contained in math.h: M_PI.
#include<iostream>
#include <math.h>
int main(){
double pi = 0.0;
for ( int i = 0 ; i <= 10000 ; i++){
// i-th value via Lieibniz formula
pi += 4*pow(-1,i)/(2*i+1);
// Check if the difference is below a given tolerance equal to 0.0001
if (abs(pi - M_PI)<0.0001){
// Print the iteration at which the given tolerance is achieved
std::cout<<i<< std::endl;
// Break the for cycle
break;
}
}
return 0;
}
The above code checks if the absolute difference between the approximated value and the "true" value of pi is below 0.0001.
You may also check if the relative difference from the actual value is below a given tolerance, by substituting the check with
if (abs(pi - M_PI)/M_PI<0.0001){
// Print the iteration at which the given tolerance is achieved
std::cout<<i<< std::endl;
// Break the for cycle
break;
}
In your code, the variable count is unused. Let me give you a little advice: do not use using namespace::std.

Sin x program dosn't work

# include <iostream>
# include <math.h>
using namespace std;
int main()
{
int count=1;
double x;
double sine, num, dem, sign, term;
sine=0;
sign = 1;
cout << "Get x: ";
cin >> x;
num = x;
dem = count;
while ( count <= 10 )
{
term = (num/dem);
sine = sine + term*sign;
num = num*x*x;
count = count + 2;
dem = dem * count * (count-1);
sign = -sign;
}
cout << "The result is: ";
cout << sine;
return 0;
}
This is the code I wrote for sin x in C++, can someone point out my errors since the program doesn't calculate the correct value, I have try to debug for hours of time but my effort is kinda futile, I appreciate your help!Thanks!
*num=numerator, dem=denominator
Try going out to 20 terms, not just 10.
And since the series converges more slowly when x is large, take x modulo 2π before you start.
Polynomial approximations to sine etc. only really work for a narrow range of values. Using more terms, effectively a higher degree polynomial, can improve accuracy up to a point, but you soon get into increased rounding errors.
You need to pick a narrow domain to calculate using the series, and then reduce inputs outside that range to a value in the range with the same sine.
After you have done that, experiment with the number of terms.
Buddy, your program is right. Check in your regular calc for sin(3.1416) keep the value in radians. The value you got is for 3.1416 degrees.. And the formula works for radians

C++ Use secant method to solve function

I have a school problem but I do not understand what it actually asks. Any of you have an idea what it's really asking for? I don't need code, I just need to understand it.
This is the problem:
Construct a computer program that uses the Secant method to solve the problem:
f(x)  =  (1+x) cos( sin(x)3 ) -  1.4   =  0
Starting with the initial guesses of x=2.0 and x=2.1, obtain an approximation to x such that  |f(x)| < 0.0000001.
This is my code from what I understand, but I think I'm not understanding the question correctly.
#include <iostream>
#include <cmath>
double secant(double x);
using namespace std;
int main()
{
double x = 2.0;
double r = 0.0;
int counter = 0;
while( r < 0 && counter <= 40)
{
r =secant(x);
cout << "x: " << x << ", f(x): " << r << endl;
counter++;
x += 0.1;
}
return 0;
}
double secant(double x)
{
double r;
r = (1+x) * cos(pow(sin(x), 3.0)) - 1.4;
return r;
}
You are supposed to use the Secant Method: http://en.wikipedia.org/wiki/Secant_method
Follow the method as described in the article. It is an iterative method much like Netwon's method. You'll need to make a function to evaluate x(n+1) given x(n) and iterate it until your margin of error is less than specified.
The coding side of this may prove fairly straightforward as long as you know what the secant method is. Also, that page has a code example. That should prove pretty useful. :)

Calculating the value of pi-what is wrong with my code

I'm doing another C++ exercise. I have to calculate the value of pi from the infinite series:
pi=4 - 4/3 + 4/5 – 4/7 + 4/9 -4/11+ . . .
The program has to print the approximate value of pi after each of the first 1,000 terms of this series.
Here is my code:
#include <iostream>
using namespace std;
int main()
{
double pi=0.0;
int counter=1;
for (int i=1;;i+=2)//infinite loop, should "break" when pi=3.14159
{
double a=4.0;
double b=0.0;
b=a/static_cast<double>(i);
if(counter%2==0)
pi-=b;
else
pi+=b;
if(i%1000==0)//should print pi value after 1000 terms,but it doesn't
cout<<pi<<endl;
if(pi==3.14159)//this if statement doesn't work as well
break;
counter++;
}
return 0;
}
It compiles without errors and warnings, but only the empty console window appears after execution. If I remove line” if(i%1000==0)” , I can see it does run and print every pi value, but it doesn’t stop, which means the second if statement doesn’t work either. I’m not sure what else to do. I’m assuming it is probably a simple logical error.
Well, i % 1000 will never = 0, as your counter runs from i = 1, then in increments of 2. Hence, i is always odd, and will never be a multiple of 1000.
The reason it never terminates is that the algorithm doesn't converge to exactly 3.14157 - it'll be a higher precision either under or over approximation. You want to say "When within a given delta of 3.14157", so write
if (fabs(pi - 3.14157) < 0.001)
break
or something similar, for however "close" you want to get before you stop.
Since you start i at 1 and increment by 2, i is always an odd number, so i % 1000 will never be 0.
you have more than one problem:
A. i%1000==0 will never be true because you're iterating only odd numbers.
B. pi==3.14159 : you cannot compare double values just like that because the way floating point numbers are represented (you can read about it here in another question). in order for it to work you should compare the values in another way - one way is to subtract them from each other and check that the absolute result is lower than 0.0000001.
You have floating point precision issues. Try if(abs(pi - 3.14159) < 0.000005).
i%1000 will never be 0 because i is always odd.
Shouldn't it be:
if (counter%1000==0)
i starts at 1 and then increments by 2. Therefore i is always odd and will never be a multiple of 1000, which is why if (i % 1000 == 0) never passes.
Directly comparing floats doesn't work, due to floating precision issues. You will need to compare that the difference between the values is close enough.
pi=4 - 4/3 + 4/5 – 4/7 + 4/9 -4/11 + ...
Generalising
pi = Σi=0∞ (-1)i 4 / (2i+1)
Which gives us a cleaner approach to each term; the i'th term is given by:
double term = pow(-1,i%2) * 4 / (2*i+1);
where i=0,1,2,...,N
So, our loop can be fairly simple, given some number of iterations N
int N=2000;
double pi=0;
for(int i=0; i<N; i++)
{
double term = pow(-1,i%2) * 4 / (2*(double)i+1);
pi += term;
cout << i << "\t" << pi <<endl;
}
Your original question stated "The program has to print the approximate value of pi after each of the first 1,000 terms of this series". This does not imply any need to check whether 3.14159 has been reached, so I have not included this here. The pow(-1,i%2) call is just to avoid if statements (which are slow) and prevent any complications with large i.
Be aware that after a number of iterations, the difference between the magnitude of pi and the magnitude of the correcting term (say -4/25) will be so small that it will go beyond the precision of a double, so you would need higher precision types to deal with it.
By default abs uses the abs macro which is for int. For doubles, use the cmath library.
#include <iostream>
#include <cmath>
int main()
{
double pi=0.0;
double a=4.0;
int i = 1;
for (i=1;;i+=2)
{
pi += (1 - 2 * ((i/2)%2)) * a/static_cast<double>(i);
if( std::abs(pi - 3.14159) < 0.000001 )
break;
if (i > 2000) //1k iterations
break;
}
std::cout<<pi<<std::endl;
return 0;
}
Here is the corrected code. I thought it may be helpful in the future if somebody has similar problem.
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
double pi=0.0;
int counter=1;
for (int i=1;;i+=2)
{
double a=4.0;
double b=0.0;
b=a/static_cast<double>(i);
if(counter%2==0)
pi-=b;
else
pi+=b;
if(counter%1000==0)
cout<<pi<<" "<<counter<<endl;
if (fabs(pi - 3.14159) < 0.000001)
break;
counter++;
}
cout<<pi;
return 0;
}
Here is a better one:
class pi_1000
{
public:
double doLeibniz( int i ) // Leibniz famous formula for pi, source: Calculus II :)
{
return ( ( pow( -1, i ) ) * 4 ) / ( ( 2 * i ) + 1 );
}
void piCalc()
{
double pi = 4;
int i;
cout << "\npi calculated each iteration from 1 to 1000\n"; //wording was a bit confusing.
//I wasn't sure which one is the right one: 0-1000 or each 1000th.
for( i = 1; i < 1000; i++ )
{
pi = pi + doLeibniz( i );
cout << fixed << setprecision( 5 ) << pi << "\t" << i + 1 << "\n";
}
pi = 4;
cout << "\npi calculated each 1000th iteration from 1 to 20000\n";
for( i = 1; i < 21000; i++ )
{
pi = pi + doLeibniz( i );
if( ( ( i - 1 ) % 1000 ) == 0 )
cout << fixed << setprecision( 5 ) << pi << "\t" << i - 1 << "\n";
}
}