Composite simpson rule infinity output - c++

Algorthim:
i have the following code which calculates improper integrals using composite Simpson rule, i am trying to evalute the integral exp(-x)/sqrt(1-x) where a= 0 and b = 1 and while n=6 or the steps =6. However, I keep getting the output to be infinity when it should be = 4.288
#include <cmath>
#include <iostream>
using namespace std;
double f(double x)
{
return exp(-x)/sqrt(1-x);
}
double simpson(double a, double b, double n)
{
double x0=f(a)+f(b);
double x1=0,x2=0;
double x=0;
double h=(b-a)/(n);
for(int i = 1 ; i <n;i++){
x=a+(h*i);
if(i%2==0)
{
x2=x2+f(x);
}
else
{
x1=x1+f(x);
}
}
return (h*(x0+2*x2+4*x1))/3;
;
}
int main(){
cout<<endl;
cout<<"The improper integral is: "<<simpson(0.00000009,1,6)<<" "<<endl;
cout<<endl;
}

I think your problem is that the function f(double x) you are evaluating is not defined at x = 1, since it is equal to exp(-1)/sqrt(1 - 1) which is dividing by zero, yet you are calling f(b) in the first line of simpson when b is 1. You are therefore returning infinity. You might want to set b to 0.9999 instead. If you do this with a much larger value of n for closer approximation to the actual curve (say n = 400), you get very close to the actual answer of 1.076 as found by #macroland on Wolfram Alpha.

Related

No output due to large fractional values

#include<iostream>
#include<cmath>
using namespace std;
float san= 0.25 ; float var= 0.75;
int findFact(int n)//factorial
{
return n == 1 ? 1 : n * findFact(n - 1);
}
int findNcR(int n, int r)//combination nCr
{
return findFact(n) / (findFact(n - r) * findFact(r));
}
double prob(int s, int v){ //recursive function for probability
if(s>=5) return 1; if(v>=5) return 0;
double sum = 0;
int m = 5-s;
for( int i=0; i<=m; i++){
sum += prob(s+i,v+m-i)*findNcR(m,i)*pow(san,i)*pow(var,m-i);
}
return sum;
}
int main(){
cout<< prob(2,1);
}
In DEV C++, there is no output printed when I compile and run the above code. I think its because of large fractional values involved. Any idea how I can get the output?
Please check the logic you use in your double prob(int s, int v) method.
You are going to infinity recursive like
S=2 V=1
S=2 V=4
S=2 V=7
The base case for your recursion, s==5 or v==5 is never getting hit. As you call your function with s=2, every time the prob function is called it is setting m to 3, and so on the first iteration of the loop (when i==0) it calls prob with s=2 and v=v+3. As you start with v==1, it successively calls prob(2,1), prob(2,4), prob(2,7), etc... and never gets any further.
I don't know what probability distribution you are trying to code so I can't offer any specific advice on how to fix this.

Euler method in c++

The following code uses Euler's Method to approximate a value of y(x). My code currently accepts the endpoints a and b as user input and values for values for alpha which is the initial condition and the step size value which is h. Given my code I can now approximate a value of y, say y(8) given the initial condition y(0)=6.
However I have a small mistake in my code and I am not quite sure how to fix it and am looking for help. Right now my code does not check to ensure that the right endpoint b is an integer multiple of the stepsize h. Due to this the final approximation may not be for f(b) but for f(c) where c is the closest integer multiple of h to b. I am looking for some help on how to fix this, Thanks!
#include<iostream>
#include<iomanip>
#include<cmath>
using namespace std;
double dydx (double x, double y)
{
double f = y*(2-y)/(x+3);
return f;
}
int main()
{
double a,b,alpha,h,z;
cout<<"\nEnter the value of endpoint a: \n";
cin>>a;
cout<<"\nEnter the value of endpoint b: \n";
cin>>b;
cout<<"\nEnter the y value of the initial condition: \n";
cin>>alpha;
cout<<"\nEnter the stepsize, h: \n";
cin>>h;
cout<<"\n";
while((b-a)>0.0000001)
{
z=alpha+(h*dydx(a,alpha));
cout<<"z("<<a<<")="<<z<<endl;
alpha=z;
a=a+h;
}
cout<<"\nThe approximate solution of y("<<b<<") is "<<z<<"."<<endl;
return 0;
}
You can calculate step size h from number of steps n:
#include<iostream>
#include<iomanip>
#include<cmath>
using namespace std;
double dydx (double x, double y)
{
double f = y*(2-y)/(x+3);
return f;
}
int main()
{
double a,b,alpha,h,z;
cout<<"\nEnter the value of endpoint a: \n";
cin>>a;
cout<<"\nEnter the value of endpoint b: \n";
cin>>b;
cout<<"\nEnter the y value of the initial condition: \n";
cin>>alpha;
/*
* Obtains step size from number on steps
* h = 0.1 for [a; b] = [0; 8] can be given by n = 80
*/
int n = 0;
cout<<"\nEnter the number of steps, n: \n";
cin>>n;
h = (b - a) / n;
//------
cout<<"\n";
//-- Replaced 0.0000001 by h / 2.0 --
while((b-a)> h / 2.0)
{
z=alpha+(h*dydx(a,alpha));
alpha=z;
a=a+h;
/*
* z - function value in next point,
* so to output correct point a need to be incremented before this.
*/
cout<<"z("<<a<<")="<<z<<endl;
}
cout<<"\nThe approximate solution of y("<<b<<") is "<<z<<"."<<endl;
return 0;
}
Insert this instead of h input.

How do I end this while loop with a precision of 0.00001 ([C++],[Taylor Series])?

I'm working on this program that approximates a taylor series function. I have to approximate it so that the taylor series function stops approximating the sin function with a precision of .00001. In other words,the absolute value of the last approximation minus the current approximation equals less than or equal to 0.00001. It also approximates each angle from 0 to 360 degrees in 15 degree increments. My logic seems to be correct, but I cannot figure out why i am getting garbage values. Any help is appreciated!
#include <math.h>
#include <iomanip>
#include <iostream>
#include <string>
#include <stdlib.h>
#include <cmath>
double fact(int x){
int F = 1;
for(int i = 1; i <= x; i++){
F*=i;
}
return F;
}
double degreesToRadians(double angle_in_degrees){
double rad = (angle_in_degrees*M_PI)/180;
return rad;
}
using namespace std;
double mySine(double x){
int current =99999;
double comSin=x;
double prev=0;
int counter1 = 3;
int counter2 = 1;
while(current>0.00001){
prev = comSin;
if((counter2 % 2) == 0){
comSin += (pow(x,(counter1))/(fact(counter1)));
}else{
comSin -= (pow(x,(counter1))/(fact(counter1)));
}
current=abs(prev-comSin);
cout<<current<<endl;
counter1+=2;
counter2+=1;
}
return comSin;
}
using namespace std;
int main(){
cout<<"Angle\tSine"<<endl;
for (int i = 0; i<=360; i+=15){
cout<<i<<"\t"<<mySine(degreesToRadians(i));
}
}
Here is an example which illustrates how to go about doing this.
Using the pow function and calculating the factorial at each iteration is very inefficient -- these can often be maintained as running values which are updated alongside the sum during each iteration.
In this case, each iteration's addend is the product of two factors: a power of x and a (reciprocal) factorial. To get from one iteration's power factor to the next iteration's, just multiply by x*x. To get from one iteration's factorial factor to the next iteration's, just multiply by ((2*n+1) + 1) * ((2*n+1) + 2), before incrementing n (the iteration number).
And because these two factors are updated multiplicatively, they do not need to exist as separate running values, they can exists as a single running product. This also helps avoid precision problems -- both the power factor and the factorial can become large very quickly, but the ratio of their values goes to zero relatively gradually and is well-behaved as a running value.
So this example maintains these running values, updated at each iteration:
"sum" (of course)
"prod", the ratio: pow(x, 2n+1) / factorial 2n+1
"tnp1", the value of 2*n+1 (used in the factorial update)
The running update value, "prod" is negated every iteration in order to to factor in the (-1)^n.
I also included the function "XlatedSine". When x is too far away from zero, the sum requires more iterations for an accurate result, which takes longer to run and also can require more precision than our floating-point values can provide. When the magnitude of x goes beyond PI, "XlatedSine" finds another x, close to zero, with an equivalent value for sin(x), then uses this shifted x in a call to MaclaurinSine.
#include <iostream>
#include <iomanip>
// Importing cmath seemed wrong LOL, so define Abs and PI
static double Abs(double x) { return x < 0 ? -x : x; }
const double PI = 3.14159265358979323846;
// Taylor series about x==0 for sin(x):
//
// Sum(n=[0...oo]) { ((-1)^n) * (x^(2*n+1)) / (2*n + 1)! }
//
double MaclaurinSine(double x) {
const double xsq = x*x; // cached constant x squared
int tnp1 = 3; // 2*n+1 | n==1
double prod = xsq*x / 6; // pow(x, 2*n+1) / (2*n+1)! | n==1
double sum = x; // sum after n==0
for(;;) {
prod = -prod;
sum += prod;
static const double MinUpdate = 0.00001; // try zero -- the factorial will always dominate the power of x, eventually
if(Abs(prod) <= MinUpdate) {
return sum;
}
// Update the two factors in prod
prod *= xsq; // add 2 to the power factor's exponent
prod /= (tnp1 + 1) * (tnp1 + 2); // update the factorial factor by two iterations
tnp1 += 2;
}
}
// XlatedSine translates x to an angle close to zero which will produce the equivalent result.
double XlatedSine(double x) {
if(Abs(x) >= PI) {
// Use int casting to do an fmod PI (but symmetric about zero).
// Keep in mind that a really big x could overflow the int,
// however such a large double value will have lost so much precision
// at a sub-PI-sized scale that doing this in a legit fashion
// would also disappoint.
const int p = static_cast<int>(x / PI);
x -= PI * p;
if(p % 2) {
x = -x;
}
}
return MaclaurinSine(x);
}
double DegreesToRadians(double angle_deg) {
return PI / 180 * angle_deg;
}
int main() {
std::cout<<"Angle\tSine\n" << std::setprecision(12);
for(int i = 0; i<=360; i+=15) {
std::cout << i << "\t" << MaclaurinSine(DegreesToRadians(i)) << "\n";
//std::cout << i << "\t" << XlatedSine(DegreesToRadians(i)) << "\n";
}
}

Keep getting 1.#INF as my output

#include <iostream>
using namespace std;
double calc(int a, int b);
int main()
{
int n1, n2;
cout << "Enter a number for a: ";
cin >> n1;
cout << "Enter a number for b: ";
cin >> n2;
cout << calc(n1, n2) << endl;
system("PAUSE");
return 0;
}
double calc(int a, int b)
{
double s;
s = (a) / ((sqrt(a / b)));
return s;
}
This program is meant to check whether the two integers are greater than zero. If it is it will calcualte the formula. Otherwise if one of the integers is zero or less than zero it will not return anything and exit the program.
My question here is that no matter what I input for a and b, i keep getting 1.#INF as the output and I have no idea why. I've checked the formula in a seperate program and it worked fine.
Any ideas?
Here, you are operating with int numbers:
s = (a) / ((sqrt(a / b)));
If a is less then b, then a/b (both are integers, remember, so the fractional part of the result will simply be lost) will be equal to 0, which leads to division by 0. You need to cast one of the numbers to double:
s = (a) / ((sqrt(static_cast<double>(a) / b)));
sqrt takes and returns a double. When you call it with integer arguments it will be converted in a double, and will thus get the value of infinity.
change your function signature to:
double calc(double a, double b);
and declare n1 and n2 as double.
You say that the function will exit the program when one of the integers are 0 or less, but where?
Try to check them like this:
Additionally, you should have a check whether a is greater than b
double calc(int a, int b)
{
double s;
if(a <= 0) exit(-1);
if(b <= 0) exit(-1);
if(a < b) exit(-1);
s = (a) / ((sqrt(a / b)));
return s;
}
You are having problems with infinity. For it use isinf. Here is some sample usage:
#include <stdio.h> /* printf */
#include <math.h> /* isinf, sqrt */
int main()
{
printf ("isinf(-1.0/0.0) : %d\n",isinf(-1.0/0.0));
printf ("isinf(sqrt(-1.0)): %d\n",isinf(sqrt(-1.0)));
return 0;
}
output:
isinf(-1.0/0.0) : 1 isinf(sqrt(-1.0): 0

Calculate sin(x) as the form of series in c++

We know that
sin(x)=x-x^3/3!+x^5/5!-x^7/7!+x^9/9! and so on. I have written this code:
#include <iostream>
#include <math.h>
using namespace std;
const int m=19;
int factorial(int n) {
if (n==0){ return 1;}
return n*factorial(n-1);
}
int main() {
float x;
cin >> x;
float sum=0;
int k=1;
for (int i=1;i<=m;i+=2) {
sum+=(k*(powf(x,i)/factorial(i)));
k=k*(-1);
}
cout<<"series sum is equal :"<<sum<<endl;
return 0;
}
One problem is that when I enter x=3 it gives me -10.9136, but I know that values range of sin(x) is [-1, 1] what is problem? Please help me.
The problem is that you're running out of precision due to destructive cancellation.
You have an alternating series where some of the terms get very large. But those terms cancel each other out to a small result. Since float has limited precision, your round off error is larger than your final value.
You can "reduce" the problem by using double-precision. But it won't go away. Standard implementations of sin/cos involve taking the modulo of the argument by 2 pi to make it small.
EDIT :
I found the other problem. You have an integer overflow in your factorial function when i = 19.