Euler method in c++ - 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.

Related

Composite simpson rule infinity output

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.

How to compute sum, average and product of three numbers using different functions

I need to create a program that accepts 3 numbers and find the sum, average and product. I only need to use main(), get_ABC(), compute() and display() functions. I did it right but im not getting the right output about my mathematical operations.
#include<conio.h>
#include<iostream.h>
float get_A(float A)
{
cout<<"Enter First Number: ";
cin>>A;
return(A);
}
float get_B(float B)
{
cout<<"Enter Second Number: ";
cin>>B;
return(B);
}
float get_C(float C)
{
cout<<"Enter Third Number: ";
cin>>C;
return(C);
}
float compute_sum(float A,float B,float C)
{
float sum;
sum = A + B + C;
return(sum);
}
float compute_ave(float A,float B,float C)
{
float ave;
ave = (A + B + C) / 3;
return (ave);
}
float compute_prod(float A,float B,float C)
{
float prod;
prod = A * B * C;
return(prod);
}
void display(float sum,float ave,float prod)
{
cout<<"The sum of three numbers is "<<sum<<".\n";
cout<<"The average of three numbers is "<<ave<<".\n";
cout<<"The product of three numbers is "<<prod<<".";
}
float main()
{
float A,B,C;
float sum;
float ave;
float pro;
clrscr();
get_A(A);
get_B(B);
get_C(C);
sum = compute_sum(A,B,C);
ave = compute_ave(A,B,C);
pro = compute_prod(A,B,C);
display(sum,ave,pro);
getch();
return(0);
}
This is the output.
Enter First Number: 1
Enter Second Number: 2
Enter Third Number: 3
The sum of three numbers is 0.
The average of three numbers is 0.
The product of three numbers is 0.
I really need help. My prof give me this problem without teaching how to code, so i only come up with basics, i really gave up and end up here. You can change, add or replace the codes(with basic codes) if you want and i'll appreciate it.
Change this:
get_A(A);
get_B(B);
get_C(C);
to this:
A = get_A(A);
B = get_B(B);
C = get_C(C);
so that you use the return values of your functions.
Moreover, main() should return an int, not a float.
Furthermore, initialize your variables when you declare them, so that you avoid "is used uninitialized in this function" warnings.

total Number of rectangles in a grid?

Here i want to count the total numbers of rectangles in M*N grid. This code is working properly but not for the large input like M=100000 N=100000. It shows something like -nan or any negative integer.
Thee result will be the modulo of 1000000007. How can i get an accurate answer with this large integer range?
Thank you
#include<iostream>
#include<cmath>
using namespace std;
double factorial(int);
int main(){
int m,n;
double mod= 1000000007;
double p,q,result;
cout << "\nPlease enter the dimensions of grid: ";
cin>>m>>n;
if (m <0&&n<0)
{
cout << "Invalid dimensions!\n";
return 1;
}
m++; n++; /*if n is the no of vertical/horizontal boxes,
there will be n+1 vertical/horizontal lines in the grid */
result=(factorial(m)/(2*factorial(m-2)))*(factorial(n)/(2*factorial(n-2)));
cout<<"\nThe rectangles in the grid is:"<<fmod(result,mod);
return 0;
}
double factorial(int x) {
double temp;
if(x <= 1) return 1;
temp = x * factorial(x - 1);
return temp;
}
You can't do 100000 factorial in a double-precision number, you'll get overflow (as you've observed).
In your case think about this expansion of what you're calculating
m * (m-1) * (m-2) * (m-3) * ... * 2 * 1
-----------------------------------------
2 * (m-2) * (m-3) * ... * 2 * 1
This all simplifies to m * (m-1) / 2. So, you don't need your factorial function at all.
Edit: The code in another post was not right. Try this:
result = static_cast<double>(m) * (m-1) * n * (n-1) / 4;
Not really programming related, but factorial(m)/(2*factorial(m-2) is the same as m * (m-1) / 2 which will probably not cause an overflow.
#include<iostream>
#include<cmath>
using namespace std;
double factorial(int);
int main(){
int m,n;
double mod= 1000000007;
double p,q,result;
cout << "\nPlease enter the dimensions of grid: ";
cin>>m>>n;
if (m <0&&n<0)
{
cout << "Invalid dimensions!\n";
return 1;
}
m++; n++; /*if n is the no of vertical/horizontal boxes,
there will be n+1 vertical/horizontal lines in the grid */
//This is where I had the typo. Forgot to divide by 2.
result=((m*(m-1))/2)*((n*(n-1))/2);
cout<<"\nThe rectangles in the grid is:"<<fmod(result,mod);
return 0;
}
/*double factorial(int x) {
double temp;
if(x <= 1) return 1;
temp = x * factorial(x - 1);
return temp;
} */
This should work fine. There was no need for you to implement a factorial function. You can have just simplified your statement down and you would have gotten your answer.

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

implement crank-nicolson in c++

i want to implement crank-nicolson method in c++ according to that :
−ru(i−1,j+1) + 2(1 + r)u(i,j+1) − ru(i+1,j+1) = 2(1 − r)u(i,j) + r
(u(i−1,j)+ u(i+1,j) )
I use gauss-jordan method to solve the system but i can't figure how to implement the above formula.
const double pi=3.14159265;
double f (double x){
return sin(pi*x);
}
using namespace std;
//gauss-jordan
double* gauss(int n ,double **a){
double factor;
double *b,*x;
x=new double[n];
b=new double[n];
for (int k=1;k<=n;k++) {
for (int i=1;i<=n;i++) {
if (i!=k) {
factor=a[i][k]/a[k][k];
for (int j=1; j<=n; j++ ) {
a[i][j]=a[k][j]*factor-a[i][j];
}
b[i]=b[k]*factor -b[i];
}
}
}
for (int i=1;i<=n;i++) {
x[i]=b[i]/a[i][i];
}
return x;
}
int main()
{
int i,j,n,m,xd,td;
double h,k,r;
double **t,**p;
//----- initialize double pointer------------------
double **u;
u=new double *[m];
for (int o=1;o<=m;o++){
u[o]=new double [n];
}
//----- end of initialization-----------------------
cout <<"\nEnter the value of x dimension : \n";
cin >> xd;
cout <<"\nEnter the step size h for x dimension : \n";
cin >>h;
cout <<"\nEnter the value of time dimension : \n";
cin >>td;
cout<<"\nEnter the step k of time dimension : \n";
cin >>k;
n=xd/h -1.0;
m=td/k -1.0;
cout <<"\n\nThe internal elements of x dimension are :"<<n;
cout <<"\nThe internal elements of t dimension are :"<<m;
r=k/(h*h);
cout <<"\nThe r value is : "<<r;
//initial conditions
for (j=0;j<=m;j++){
u[0][m]=0;
u[10][m]=0;
}
//get the function
for (i=1;i<n;i++){
u[i][0]=f(i*h);
}
//apply crank-nicolson
for (i=1;i<n;i++){
for (j=1;j<n;j++){
-r*u[i-1][j+1] +2.0*(1.0+r)*u[i][j+1] -r*u[i+1][j+1]=2.0*(1.0-r)*u[i][j] +r*(u[i-1][j]+u[i+1][j]);
} // here i can't figure the steps i must follow in order for this to work
//-----delete double pointer-------------
for(int o=1;o<m;o++){
delete [] u[o];
delete [] u;
}
//---------------------------------------
return 0;
}
I am assuming that the variable j represents the time steps. In order to implement Crank-Nicolson, you have to pose the problem as a system of linear equations and solve it. The matrix corresponding to the system will be of tridiagonal form, so it is better to use Thomas' algorithm rather than Gauss-Jordan.
The linear system will be of the form A x = b, with x being the vector (..., u(i-1, j+1), u(i, j+1), u(i+1, j+1), ...) and b being the vector (..., r u(i−1,j), 2(1 − r)u(i,j), r u(i+1,j), ...). The i-th row of the matrix A will be of the form
(0, ..., 0, −r, 2(1 + r), −r, 0, ..., 0). You will have to be careful with the first and last rows, where you'll have to substitute the boundary conditions for your problem.
A good reference for finite difference methods and Crank-Nicolson in particular is the book by John Strikwerda.
Hope this helps.
C++ is not an equation solving system. = does not have the meaning of equals as it does have in math, but mean assignment.
As such having anything complex like you have on the left side makes no sense, what you probably want to do is to solve the equation so there is a single variable that is being assigned to, possibly with an equation solving program.