sum of series in c++ using if Conditional - c++

am trying to solve the equation in c++ sum of series and am getting the right result
but I just trying to use the if statement to get the same answer of this equation
but always am getting struggling with it
# include <math.h>
#include <iostream>
using namespace std;
int main()
{
double x = 1;
double som = 0;
double lim_nbr = pow(10.0, -6);
int n = 1;
do{
x = 1.0 / ((n*n*4.0 - 1) * n);
som += x;
n+=1;
}while (x >= lim_nbr);
double correctSum = 2.0*log(2.0) -1.0 ;
cout << "Sum = " << som << endl;
cout << "Sumcorrect = " << correctSum << endl;
}

In this case for you to calculate a loop shape using only if, an alternative is to use recursive functions, look at this example:
#include <math.h>
#include <iostream>
using namespace std;
double calc(double lim_nbr, double som, double x, int n)
{
if(x >= lim_nbr || som == 0)
{
x = 1.0 / ((n*n*4.0 - 1) * n);
som += x;
n+=1;
calc(lim_nbr, som, x, n);
}
else
{
return som;
}
}
int main()
{
double lim_nbr = pow(10.0, -6);
/* Call the function with the initial values */
double som = calc(lim_nbr, 0, 1, 1);
cout << "SumWithIf = " << som <<endl;
}

The result you are getting using the do while loop is an approximation to the exact value that you are getting in correctSum. correctSum is the result obtained by adding the series upto infinte terms, however your do while loop calculates only up to a finite number of terms. Therefore the difference of the two values shows up as the error.

Related

Find sum of series in c++ by function

Find a sum of series by function s= 1!/y!+y!/3!+5!/y!......n
I don't know how to define fact function and is this code correct??
#include <math.h>
#include <iostream>
using namespace std;
float fact(float, float);
float sum(float, float);
int main() {
float n, x, s;
cout << "enter n and x" << endl;
cin >> n >> x;
s = sum(n, x);
cout << "sum =" << s << endl;
return 0;
}
float sum(float n, float x)
{
float x, s = 0;
for (int i = 0; i <= n; i++)
if (i % 2 == 0)
s = s + float(fact(i + 1) / fact(x));
else
s = s + float(fact(x) / fact(i + 1));
return s;
}
Whilst there are ways of defining the factorial of a floating-point number (using a gamma function), I doubt that is what you want. Similarly, the upper index n shouldn't be a float, either.
Your series as written looks awfully divergent.
As somebody else has said, it is rare to calculate new factorials from scratch: divisors of them tend to cancel, and whole terms of your series are simple multiples of earlier terms.

sum of Maclaurin series c++

I am struggling to make this equation equals to each other because of a bad understanding of mathematics.
The problem is that the equation does not equal to each other
here is my code for better understand
#include <iostream>
#include <ccomplex>
using std::cout;
int main() {
int n = 8;
double sum = 0.0;
unsigned long long fact =1;
for (int i = 1; i <= n; i++)
{
fact *= 2*i*(2*i-1);
sum += 1.0 / fact;
}
std::cout << "first equation " << sum << std::endl;
double e = M_E;
double st = 1.0/2.0*(e + (1.0/e));
std::cout <<"second equation " << st << std::endl;
return 0;
}
the output
first equation 0.543081
second equation 1.54308
The result it nearly It must be at least equal before the comma,
You don't account for n = 0, which yields 0! and thus 1. Therefore, you need to add 1 to sum.

C++: about precision of calculating (code is inside)

Can you give me advice about precision of computing Taylor series for an exponent? We have a degree of exponent and a figure of precision calculating as imput data. We should recieve a calculating number with a given precision as output data. I wrote a program, but when I calculate an answer and compare it with embedded function's answer, it has differents. Can you advice me, how I can destroy a difference between answeres? formula of exponent's calculating
#include "stdafx.h"
#include "iostream"
#include <math.h>
#include <Windows.h>
#include <stdlib.h>
using namespace std;
int Factorial(int n);
double Taylor(double x, int q);
int main()
{
double res = 0;
int q = 0;
double number = 0;
cout << "Enter positive number" << "\n";
cin >> number;
cout << "Enter rounding error (precision)" << "\n";
cin >> q;
cout << "\n" << "\n";
res = Taylor(number, q);
cout << "Answer by Taylor : " << res;
cout << "Answer by embedded function: " << exp(number);
Sleep(25000);
return 0;
}
int Factorial(int n) {
int res = 1;
int i = 2;
if (n == 1 || n == 0)
return 1;
else
{
while (i <= n)
{
res *= i;
i++;
}
return res;
}
}
double Taylor(double x, int q) {
double res = 1;
double res1 = 0;
int i =1;
while (i)
{
res += (pow(x, i) / Factorial(i));
if (int(res*pow(10, q)) < (res*pow(10, q)))
{//rounding res below
if ( ( int (res * pow(10,q+1)) - int(res*pow(10, q))) <5 )
res1 = (int(res*pow(10, q))) * pow(10, (-q));
else
res1 = (int(res*pow(10, q))) * pow(10, (-q)) + pow(10,-q);
return res1;
}
i++;
}
}
There are two problems in your code. First, the factorial is very prone to overflow. Actually I dont know when overflow occurs for int factorials, but I remember that eg on usual pocket calculators x! overflows already for x==70. You probably dont need that high factorials, but still it is better to avoid that problem right from the start. If you look at the correction that needs to be added in each step: x^i / i! (maths notation) then you notice that this value is actually much smaller than x^i or i! respectively. Also you can calculate the value easily from the previous one by simply multiplying it by x/i.
Second, I dont understand your calculations for the precision. Maybe it is correct, but to be honest for me it looks too complicated to even try to understand it ;).
Here is how you can get the correct value:
#include <iostream>
#include <cmath>
struct taylor_result {
int iterations;
double value;
taylor_result() : iterations(0),value(0) {}
};
taylor_result taylor(double x,double eps = 1e-8){
taylor_result res;
double accu = 1; // calculate only the correction
// but not its individual terms
while(accu > eps){
res.value += accu;
res.iterations++;
accu *= (x / (res.iterations));
}
return res;
}
int main() {
std::cout << taylor(3.0).value << "\n";
std::cout << exp(3.0) << "\n";
}
Note that I used a struct to return the result, as you should pay attention to the number of iterations needed.
PS: see here for a modified code that lets you use a already calculated result to continue the series for better precision. Imho a nice solution should also provide a way to set a limit for the number of iterations, but this I leave for you to implement ;)

Unable to find the machine epsilon for float in c++ in codeblocks

I wanted to find out the machine epsilon for float and double types through C++, but I am getting the same answer again and again for each data type of variable x I am using, which is that of long double and of the order of O(1e-20). I am running it on my Windows 10 machine using Codeblocks.
I tried using the same code in Ubuntu and also in DevC++ in Windows itself, I am getting the correct answer. What is it that I am doing wrong in codeblocks. Is there any default setting?
#include <iostream>
#include <string>
#include <typeinfo>
using namespace std;
int main()
{
//double x = 5;
//double one = 1;
//double fac = 0.5;
float x=1;
float one = 1.0;
float fac = 0.5;
// cout <<"What is the input of number you are giving"<< endl;
// cin >> x;
cout <<"The no. you have given is: "<< x << endl;
int iter = 1;
while(one+x != one)
{
x = x * fac;
iter = iter + 1;
}
cout<<"The value of machine epsilon for the given data type is "<<x<<endl;
cout<<"The no.of iterations taken place are: "<<iter<<endl;
}
while(one+x != one)
The computation of one+x might well be an extended precision double. The compiler is quite free to do so. In such an implementation, you will indeed see the same value for iter regardless of the type of one and x.
The following works quite nicely on my computer.
#include <iostream>
#include <limits>
template <typename T> void machine_epsilon()
{
T one = 1.0;
T eps = 1.0;
T fac = 0.5;
int iter = 0;
T one_plus_eps = one + eps;
while (one_plus_eps != one)
{
++iter;
eps *= fac;
one_plus_eps = one + eps;
}
--iter;
eps /= fac;
std::cout << iter << ' '
<< eps << ' '
<< std::numeric_limits<T>::epsilon() << '\n';
}
int main ()
{
machine_epsilon<float>();
machine_epsilon<double>();
machine_epsilon<long double>();
}
You could try this code to obtain the machine epsilon for float values:
#include<iostream>
#include<limits>
int main(){
std::cout << "machine epsilon (float): "
<< std::numeric_limits<float>::epsilon() << std::endl;
}

finding pi - using Machin's formula. Different iterations are giving same result

I've written a few programs to find pi, this one being the most advanced. I used Machin's formula, pi/4 = 4(arc-tan(1/5)) - (arc-tan(1/239)).
The problem is that however many iterations I do, I get the same result, and I can't seem to understand why.
#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <math.h>
using namespace std;
double arctan_series(int x, double y) // x is the # of iterations while y is the number
{
double pi = y;
double temp_Pi;
for (int i = 1, j = 3; i < x; i++, j += 2)
{
temp_Pi = pow(y, j) / j; //the actual value of the iteration
if (i % 2 != 0) // for every odd iteration that subtracts
{
pi -= temp_Pi;
}
else // for every even iteration that adds
{
pi += temp_Pi;
}
}
pi = pi * 4;
return pi;
}
double calculations(int x) // x is the # of iterations
{
double value_1, value_2, answer;
value_1 = arctan_series(x, 0.2);
value_2 = arctan_series(x, 1.0 / 239.0);
answer = (4 * value_1) - (value_2);
return answer;
}
int main()
{
double pi;
int iteration_num;
cout << "Enter the number of iterations: ";
cin >> iteration_num;
pi = calculations(iteration_num);
cout << "Pi has the value of: " << setprecision(100) << fixed << pi << endl;
return 0;
}
I have not been able to reproduce your issue, but here is a bit cleaned up code with a few C++11 idioms and better variable names.
#include <iostream>
#include <iomanip>
#include <math.h>
using namespace std;
// double arctan_series(int x, double y) // x is the # of iterations while y is the number
// then why not name the parameters accoringly? In math we usually use x for the parameter.
// prefer C++11 and the auto notation wherever possible
auto arctan_series(int iterations, double x) -> double
{
// note, that we don't need any temporaries here.
// note, that this loop will never run, when iterations = 1
// is that really what was intended?
for (int i = 1, j = 3; i < iterations; i++, j += 2)
{
// declare variables as late as possible and always initialize them
auto t = pow(x, j) / j;
// in such simple cases I prefer ?: over if-else. Your milage may vary
x += (i % 2 != 0) ? -t : t;
}
return x * 4;
}
// double calculations(int x) // x is the # of iterations
// then why not name the parameter accordingly
// BTW rename the function to what it is supposed to do
auto approximate_pi(int iterations) -> double
{
// we don't need all of these temporaries. Just write one expression.
return 4 * arctan_series(iterations, 0.2) - arctan_series(iterations, 1.0 / 239.0);
}
auto main(int, char**) -> int
{
cout << "Enter the number of iterations: ";
// in C++ you should declare variables as late as possible
// and always initialize them.
int iteration_num = 0;
cin >> iteration_num;
cout << "Pi has the value of: "
<< setprecision(100) << fixed
<< approximate_pi(iteration_num) << endl;
return 0;
}
When you remove my explanatory comments, you'll see, that the resulting code is a lot more concise, easier to read, and therefore easier to maintain.
I tried a bit:
Enter the number of iterations: 3
Pi has the value of: 3.1416210293250346197169164952356368303298950195312500000000000000000000000000000000000000000000000000
Enter the number of iterations: 2
Pi has the value of: 3.1405970293260603298790556436870247125625610351562500000000000000000000000000000000000000000000000000
Enter the number of iterations: 7
Pi has the value of: 3.1415926536235549981768144789384678006172180175781250000000000000000000000000000000000000000000000000
Enter the number of iterations: 42
Pi has the value of: 3.1415926535897940041763831686694175004959106445312500000000000000000000000000000000000000000000000000
As you see, I obviously get different results for different numbers of iterations.
That method converges very quickly. You'll get more accuracy if you start with the smallest numbers first. Since 5^23 > 2^53 (the number of bits in the mantissa of a double), probably the maximum number of iterations is 12 (13 won't make any difference). You'll get more accuracy starting with the smaller numbers. The changed lines have comments:
double arctan_series(int x, double y)
{
double pi = y;
double temp_Pi;
for (int i = 1, j = x*2-1; i < x; i++, j -= 2) // changed this line
{
temp_Pi = pow(y, j) / j;
if ((j & 2) != 0) // changed this line
{
pi -= temp_Pi;
}
else
{
pi += temp_Pi;
}
}
pi = pi * 4;
return pi;
}
For doubles, there is no point in setting precision > 18.
If you want an alternative formula that takes more iterations to converge, use pi/4 = arc-tan(1/2) + arc-tan(1/3), which will take about 24 iterations.
This is another way if some of you are interested. The loop calculates the integral of the function : sqrt(1-x²)
Which represents a semicircle of radius 1. Then we multiply by two the area. Finally we got the surface of the circle which is PI.
#include <iomanip>
#include <cmath>
#define f(x) sqrt(1-pow(x,2))
double integral(int a, int b, int p)
{
double d=pow(10, -p), s=0;
for (double x=a ; x+d<=b ; x+=d)
{
s+=f(x)+f(x+d);
}
s*=d/2.0;
return s;
}
int main()
{
cout << "PI=" << setprecision (9) << 2.0*integral(-1,1,6) << endl;
}