Runge Kutta Script | C++ | Beginner

In summary, the conversation discusses the challenges and limitations of using the Runge-Kutta method to find exact solutions for differential equations. The speaker also shares their struggles with using the C++ programming language and the compiler Dev CPP. They mention a workaround for a limitation on the array size, but acknowledge that it results in a loss of precision. The conversation also includes several questions about using scanf and fprintf/printf for long doubles and integrating functions. The expert recommends using a more advanced algorithm and suggests checking out the Numerical Recipe website for resources and methods for solving ODEs.
  • #1
okkvlt
53
0
Hi. I am working on a runge kutta/integral finder. my goal is to make it "exact to the dx", so to speak.
im a beginner at c++, so bear with me.
the compiler I am using is dev cpp, incase it matters.

my main problem was that apparently i can't have a long double array of size greater than 160,000. this would limit me to an x array of 80k and a y array of 80k. (meaning i could only do 80k iterations of runge kutta). i worked around this by making an x and y array of 40k entries each, and then subdividing each increment into a maximum of 40k entries, giving me the maximum of up to 1.6billion runge kutta iterations. (although 40million works fine, and i don't feel like waiting several hours for my POS 1.3ghz computer to do 1.6 billion runge kutta iterations). the only drawback is that after each completion of an interval the fine-precision of the subintervals is lost, i worked around this for the print f[x] and definite integral part, but its kind of messy.

Some questions:
how do i use scanf to declare the function to be integrated/solved? it would be real nice if i could do this in the command prompt window, instead of having to go into the compiler and edit the program.

how do i fprintf or printf a long double? it seems as though the print function only works for double precision, not long double, so i have to convert my long double to merely double precision before i can see it or save it :( .

How do i scanf a double or long double? scanf only seems to work for float numbers; this seriously affects things i want to do with the program, like suppose i want to find the definite integral over some multiple of pi. then id have to go into the compiler and edit the program.

how do i use the second derivative to optimize numerical analysis? i know that if the second derivative is large then i should use a smaller increment size, but i can't figure out how to implement this into the program.

#include <stdio.h>
#include <math.h>


/*define f[x]*/
long double f(long double x, long double y)
{
long double f=cos(atan(y/x))*pow(pow(x,2)+pow(y,2),.5);
return f;
}
int main()
{
/*get values*/
long int num;
float xinit, yinit, xend, xa,xb;
long double x[40000], y[40000], h;
printf("find y[x] given dy/dx=f[x,y]\n");
printf("initial x=");
scanf("%f", &xinit);
printf("initial y=");
scanf("%f", &yinit);
printf("final x=");
scanf("%f", &xend);
printf("number of subincrements=");
scanf("%d", &num);
double dxdisp=(xend-xinit)/(40000*num), xdisp, ydisp;
printf("dx=%.13f\n", dxdisp);
x[0]=xinit;
y[0]=yinit;
long int i=0, n=0;
long double xsub[num],ysub[num],a,b,c,d, dx=(xend-xinit)/(40000*num), yb, ya;
while(i<=40000)
{
n=0;
ysub[0]=y;
xsub[0]=x;
while(n<=num)
{
a=dx*f(xsub[n],ysub[n]);
b=dx*f(xsub[n]+.5*dx,ysub[n]+.5*a);
c=dx*f(xsub[n]+.5*dx,ysub[n]+.5*b);
d=dx*f(xsub[n]+dx,ysub[n]+c);
ysub[n+1]=ysub[n]+(a+2*b+2*c+d)/6;
xsub[n+1]=xsub[n]+dx;
n=n+1;
}
x[i+1]=xsub[num];
y[i+1]=ysub[num];
i=i+1;
printf("%d/40000 completed\r", i);
}
printf("-------------------------------\n");
long int choose=10;
long int display;

printf(" 0:exit\n 1:save data\n 2:print y[x]\n 3:definite integral if f=f[x]\n");

while(choose!=0)
{
choose=10;
printf("choice=");
scanf("%d", &choose);

/*save*/
if(choose==1)
{
display=0;
FILE *fp;
fp=fopen("graph.txt","w");
while(display<=40000)
{
xdisp=x[display];
ydisp=y[display];
fprintf(fp, "%.13f %.13f\n", xdisp, ydisp);
display=display+4;
}
int fclose(FILE *fp);
printf("finished saving\n");
}
/*save*/

/*y[x]*/
if(choose==2)
{
printf("x=");
scanf("%f", &xa);
i=floor((xa-xinit)/(dx*num));
h=(xa-x)/(num);
n=0;
xsub[0]=x;
ysub[0]=y;
while(n<=num)
{
a=h*f(xsub[n],ysub[n]);
b=h*f(xsub[n]+.5*h,ysub[n]+.5*a);
c=h*f(xsub[n]+.5*h,ysub[n]+.5*b);
d=h*f(xsub[n]+h,ysub[n]+c);
ysub[n+1]=ysub[n]+(a+2*b+2*c+d)/6;
xsub[n+1]=xsub[n]+h;
n=n+1;
}
xdisp=xsub[num];
ydisp=ysub[num];
printf("y(%.13f)=%.13f\n\n", xdisp, ydisp);
}
/*defint*/
if(choose==3)
{
printf("b=");
scanf("%f", &xb);
printf("a=");
scanf("%f", &xa);
i=floor((xa-xinit)/(dx*num));
h=(xa-x)/(num);
n=0;
xsub[0]=x;
ysub[0]=y;
while(n<=num)
{
a=h*f(xsub[n],ysub[n]);
b=h*f(xsub[n]+.5*h,ysub[n]+.5*a);
c=h*f(xsub[n]+.5*h,ysub[n]+.5*b);
d=h*f(xsub[n]+h,ysub[n]+c);
ysub[n+1]=ysub[n]+(a+2*b+2*c+d)/6;
xsub[n+1]=xsub[n]+h;
n=n+1;
}
ya=ysub[num];
i=floor((xb-xinit)/(dx*num));
h=(xb-x)/(num);
n=0;
xsub[0]=x;
ysub[0]=y;
while(n<=num)
{
a=h*f(xsub[n],ysub[n]);
b=h*f(xsub[n]+.5*h,ysub[n]+.5*a);
c=h*f(xsub[n]+.5*h,ysub[n]+.5*b);
d=h*f(xsub[n]+h,ysub[n]+c);
ysub[n+1]=ysub[n]+(a+2*b+2*c+d)/6;
xsub[n+1]=xsub[n]+h;
n=n+1;
}
yb=ysub[num];
ydisp=yb-ya;
printf("%f\nSf[x]dx=%.13f\n%f\n\n", xb,ydisp,xa);
}
/*defint*/
}
/*menu*/


/*end*/
}
 
Technology news on Phys.org
  • #2
First you are attempting the impossible, you can only be "exact" to the simplest of systems. Real world problems can only be approximated (sometimes to a very high degree) and even then you can only be as accurate as the machine precision in your CPU. Secondly, RK4 is never going to get you high precision with a real equation or system of equations. You need to use a much more advanced algorithm like 8th order Runge-Kutta. Also, to achieve any hope of fast convergence you need an automated time stepper in your algorithm.

Lastly, you are doing something that has already been done for you. Go to the Numerical Recipe site. www.nr.com and read their methods of numerical solutions to ODE's. Also, you aren't losing programming knowledge by using their routines. In fact, you will gain a lot by just following them and seeing how they work.

Thanks
Matt
 
  • #3
CFDFEAGURU said:
RK4 is never going to get you high precision with a real equation or system of equations. You need to use a much more advanced algorithm like 8th order Runge-Kutta.
An alternative to higher order algorithms is to use a smaller step size. Also, consider using an implicit (predictor-corrector) algorithm, which uses the next step value as an input, by making an initial guess for the next step value, then iterating using sucessive "guesses" from previous steps.

I explained a simple implicit algorithm here:

https://www.physicsforums.com/showpost.php?p=2285015&postcount=10

Another issue is that summation of a large number of values results in truncation, although it woud seem that long doubles (80 bit?) numbers would take care of this. There are algorithms that track truncation errors, similar to: truncation = (number-((sum+number)-sum))). Another option is to use a summation function. One implementation is to use an array of floating point numbers indexed by the exponent of the number. The array is initialized to zeros, and the function called for each new number to be added to the array. The exponent of the new number is used to index into the array. If the entry is zero, the new number is stored. If the entry is non-zero, the new number is added to the array entry, the array entry is zeroed, and the process is repeated using the sum's exponent to index the array until a zero entry is found or overflow occurs. There is a another function that returns the current sum by adding the numbers in array (exponent) order.
 
Last edited:

1. What is Runge Kutta Script?

Runge Kutta Script is a numerical method used for solving ordinary differential equations (ODEs). It is a popular method because it is relatively simple to implement and can accurately approximate the solutions of ODEs.

2. How does Runge Kutta Script work?

Runge Kutta Script works by breaking down an ODE into smaller steps and using a series of calculations to approximate the solution at each step. It uses a combination of slope calculations and weighted averages to improve the accuracy of the approximation.

3. Is Runge Kutta Script suitable for beginners?

Yes, Runge Kutta Script is often recommended for beginners because it is straightforward to understand and implement. However, a basic understanding of calculus and differential equations is necessary.

4. What are the advantages of using Runge Kutta Script?

Some advantages of using Runge Kutta Script include its ability to handle complex ODEs, its relatively simple implementation compared to other numerical methods, and its high accuracy compared to other methods of the same order.

5. Are there any limitations to using Runge Kutta Script?

One limitation of Runge Kutta Script is that it can be computationally expensive for ODEs with a large number of variables. Additionally, it may not be the best method for solving stiff equations, which are ODEs with rapidly changing solutions.

Similar threads

  • Programming and Computer Science
Replies
15
Views
2K
  • Programming and Computer Science
Replies
1
Views
1K
  • Programming and Computer Science
Replies
7
Views
1K
  • Programming and Computer Science
Replies
4
Views
733
  • Programming and Computer Science
Replies
2
Views
931
  • Programming and Computer Science
Replies
4
Views
898
Replies
39
Views
475
  • Programming and Computer Science
Replies
1
Views
943
  • Engineering and Comp Sci Homework Help
Replies
3
Views
880
  • Programming and Computer Science
Replies
1
Views
2K
Back
Top