Code Crash

Hello I am using the runge kutta method to calculate the differential equation. I got a crash when I was compiling my result. the crash message is below and my program as well. Please help me out . Thank you.

root [0] 
Processing runge.C...

 *** Break *** segmentation violation
.q



===========================================================
There was a crash.
This is the entire stack trace of all threads:
===========================================================
#0  0x00007f23bea9d45a in __GI___wait4 (pid=17612, stat_loc=stat_loc
entry=0x7ffcf7966878, options=options
entry=0, usage=usage
entry=0x0) at ../sysdeps/unix/sysv/linux/wait4.c:30
#1  0x00007f23bea9d41b in __GI___waitpid (pid=<optimized out>, stat_loc=stat_loc
entry=0x7ffcf7966878, options=options
entry=0) at ./posix/waitpid.c:38
#2  0x00007f23bea03bcb in do_system (line=<optimized out>) at ../sysdeps/posix/system.c:171
#3  0x00007f23bf13b334 in TUnixSystem::Exec (shellcmd=<optimized out>, this=0x55c476bed800) at /home/harriet/fair_install/FairSoft_apr22/Source/root/core/unix/src/TUnixSystem.cxx:2108
#4  TUnixSystem::StackTrace (this=0x55c476bed800) at /home/harriet/fair_install/FairSoft_apr22/Source/root/core/unix/src/TUnixSystem.cxx:2399
#5  0x00007f23bf1386e5 in TUnixSystem::DispatchSignals (this=0x55c476bed800, sig=kSigSegmentationViolation) at /home/harriet/fair_install/FairSoft_apr22/Source/root/core/unix/src/TUnixSystem.cxx:3619
#6  <signal handler called>
#7  0x00007f23bee25372 in ?? ()
#8  0x00007f23bee25000 in ?? ()
#9  0x0000000000000000 in ?? ()
===========================================================


The lines below might hint at the cause of the crash.
You may get help by asking at the ROOT forum https://root.cern/forum
Only if you are really convinced it is a bug in ROOT then please submit a
report at https://root.cern/bugs Please post the ENTIRE stack trace
from above as an attachment in addition to anything else
that might help us fixing this issue.
===========================================================
#7  0x00007f23bee25372 in ?? ()
#8  0x00007f23bee25000 in ?? ()
#9  0x0000000000000000 in ?? ()
===========================================================
#include "TCanvas.h"
#include "TGraph.h"
#include <iostream>
#include <vector>


using namespace std;


//declaration of the function.

Float_t  f (Float_t t[n] , Float_t vy[n]){
        Double_t g=9.81;
        Double_t k = 0.01;
        Double_t f1;
        f1 = k*vy*g;
        return f1;
        }
//solving in the runge

void runge(){
        TCanvas *c1=new TCanvas();
        Double_t t0,v0,tf;
        Double_t k1,k2,k3,k4,h,k,y1;
        t0=0,
        v0=0;
        tf=2000;
        Int_t n = 3 ;
        h=(t0-tf)/n;
        Double_t t[n], vy[n];
        t[1]=t0;
        vy[1]=v0;
//solving in the runge kutta. 


        for(Int_t i=1;i <n;  i++){
                k1 = f(t[i],vy[i]);
                k2=  f(t[i]+h/2,vy[i]+h*k1/2);
                k3=  f(t[i]+h/2,vy[i]+h*k2/2);
                k4=  f(t[i]+h,vy[i]+h*k3);
                k = (k1+2*k2+2*k3+k4)/6;
                //update these values.
                vy[i+1] = vy[i]+h*k;
                t[i+i]=t[i]+h;
        //      std::cout<<t[i]<<" "<<vy[i]<<endl;

        }

        TGraph *gr1 = new TGraph (n, t, vy);
        gr1->Draw("APL*");

}

many mistakes… here is a version correct regarding C++ … check if it does really what you want.

#include "TCanvas.h"
#include "TGraph.h"
#include <iostream>
#include <vector>

using namespace std;

//declaration of the function.

Double_t  f (Double_t t, Double_t vy) {
   Double_t g = 9.81;
   Double_t k = 0.01;
   Double_t f1;
   f1 = k*vy*g;
   return f1;
}

void runge(){
   TCanvas *c1 = new TCanvas();
   Double_t t0,v0,tf;
   Double_t k1,k2,k3,k4,h,k,y1;
   t0 = 0,
   v0 = 0;
   tf = 2000;
   const Int_t n = 3 ;
   h = (t0-tf)/n;
   Double_t t[n], vy[n];
   t[0]  = t0;
   vy[0] = v0;

//solving in the runge kutta.
   for (Int_t i=0;i <n-1;  i++) {
      k1 = f(t[i], vy[i]);
      k2 = f(t[i]+h/2, vy[i]+h*k1/2);
      k3 = f(t[i]+h/2, vy[i]+h*k2/2);
      k4 = f(t[i]+h, vy[i]+h*k3);
      k = (k1+2*k2+2*k3+k4)/6;
      //update these values.
      vy[i+1] = vy[i]+h*k;
      t[i+i]  = t[i]+h;
   }

   TGraph *gr1 = new TGraph (n, t, vy);
   gr1->Draw("APL*");
}

It is working though not doing what I like but I will check the equation well. Thank You

Please I am having this error after running my code.

root [0] 
Processing runge.C...
0 
0 
terminate called after throwing an instance of 'std::out_of_range'
  what():  vector::_M_range_check: __n (which is 2) >= this->size() (which is 2)


this is my whole code too. I would appreciate if you help me out. Thank you.

#include "TCanvas.h"
#include "TGraph.h"
#include <iostream>
#include <vector>
#include <math.h>
#include <TMath.h>

using namespace std;


//declaration of the function.
//Double_t f(Double_t& t, Double_t& vy);
Double_t  f (Double_t t , Double_t vy){
        Double_t g = 9.81;
        Double_t k = 0.01;
        Double_t f1;
        f1 = k*vy*g;
        return f1;
        }
//solving in the runge

void runge(){
        TCanvas *c1=new TCanvas();
        Double_t t0,v0,tf;
        Double_t k1,k2,k3,k4,h;
        tf = 2000;
        t0 = 0.0;
        const Int_t n = 10 ;
        h = (tf-t0)/n;
        std::vector<double> t{0};
        std::vector<double> vy{0};

//Initial Conditions
        t.push_back(0.0);
        vy.push_back(0.0);


//solving in the runge kutta. 




        for(Int_t i=0;i <n;  i++){
                k1 = f(t.at(i),vy.at(i));
                k2=  f(t[i]+h*0.5,vy[i]+h*k1*0.5);
                k3=  f(t[i]+h*0.5,vy[i]+h*k2*0.5);
                k4=  f(t[i]+h,vy[i]+h*k3);
                //update these values.
                vy[i+1]=vy[i]+(k1+2*k2+2*k3+k4)*h/6);
                t[i+i]=t[i]+h;
                vy[i]=vy[i+1];
                t[i]=t[i+1];
                vy.push_back(vy.at(i));
                t.push_back(t.at(i));
                std::cout<<vy[i]<<" "<<t[i]<<std::endl;

        }



        TGraph *gr1 = new TGraph (n, t, vy);
        gr1->GetXaxis()->SetTitle("t [s]");
        gr1->GetYaxis()->SetTitle("vy(t)");
        gr1->GetXaxis()->CenterTitle();
        gr1->GetYaxis()->CenterTitle();
        gr1->Draw("Alp");

}

With these lines you just declared two vectors with one element which is 0

std::vector t{0};
std::vector vy{0};

then you add another element to the two vectors, which is 0

t.push_back(0.0);
vy.push_back(0.0);

At this moment your vectors have just 2 elements.

So when i=1 you try to access vy[i+1] you go outside the boundaries of your vector.

As @couet already suggested to you, try to declare the vectors with n elements (and also a type), initialize the first element of both the vector with your starting condition.
Then go to the for cycle

Here as already shown in the previous post end the for cycle at n-1 to avoid bad access to the vectors.

Finally remove these lines from your code are useless.

Then your code should work.

Best,
Stefano

Yes I have done the one couet told me to. but I wanted to know how I can use it in vectors as well. I guess I will stick to the array. Thank you very much


Double_t  f (Double_t t , Double_t vy){
        Double_t g = -9.81;
        Double_t k = 0.01;
        Double_t f1;
        f1 = k*vy*g;
        return f1;
        }
//solving in the runge

void runge(){
        TCanvas *c1=new TCanvas();
        Double_t t0,v0,tf;
        Double_t k1,k2,k3,k4,h;
        tf = 2000.0;
        t0 = 0.0;
        const Int_t n = 1000 ;
        h = (tf-t0)/n;
        std::vector<double> t(n);
        std::vector<double> vy(n);

//Initial Conditions
        t.at(0)=0.0;
        vy.at(0)=10.0;


//solving in the runge kutta.




        for(Int_t i=0;i <n-1;  i++){
                k1 = f(t.at(i),vy.at(i));
                k2=  f(t.at(i)+h*0.5,vy.at(i)+h*k1*0.5);
                k3=  f(t.at(i)+h*0.5,vy.at(i)+h*k2*0.5);
                k4=  f(t.at(i)+h, vy.at(i)+h*k3);
                //update these values.
                vy.at(i+1)=vy.at(i)+(k1+2*k2+2*k3+k4)*h/6;
                t.at(i+1)=t.at(i)+h;
               
                std::cout<<vy.at(i)<<" "<<t.at(i)<<std::endl;

        }



        TGraph *gr1 = new TGraph (n, &t.at(0), &vy.at(0));
        gr1->GetXaxis()->SetTitle("t [s]");
        gr1->GetYaxis()->SetTitle("vy(t)");
        gr1->GetXaxis()->CenterTitle();
        gr1->GetYaxis()->CenterTitle();
        gr1->Draw("Alp");

}

I changed your code to use vector, for me it works. I changed also the sign of g

I did that but vy[i] is always 0…
Something wrong with your logic…

//declaration of the function.
double  f (double t , double vy){
   double g = 9.81;
   double k = 0.01;
   double f1;
   f1 = k*vy*g;
   return f1;
}

//solving in the runge
void runge(){
   TCanvas *c1=new TCanvas();
   double t0,v0,tf;
   double k1,k2,k3,k4,h;
   tf = 2000;
   t0 = 0.0;
   int i;
   const int n = 10 ;
   h = (tf-t0)/n;
   double t[n];
   double vy[n];
   for (i=0; i<n; i++) t[i] = vy[i] = 0;

   //solving in the runge kutta.

   for (i = 0; i < n-1; i++) {
      k1 = f(t[i],vy[i]);
      k2 = f(t[i]+h*0.5,vy[i]+h*k1*0.5);
      k3 = f(t[i]+h*0.5,vy[i]+h*k2*0.5);
      k4 = f(t[i]+h,vy[i]+h*k3);
      //update these values.
      vy[i+1] = vy[i]+(k1+2*k2+2*k3+k4)*h/6;
      t[i+1]  = t[i]+h;
      vy[i]   = vy[i+1];
      t[i]    = t[i+1];
      cout<<i<<" "<<h<<" "<<vy[i]<<" "<<t[i]<<endl;
   }

   TGraph *gr1 = new TGraph (n, t, vy);
   gr1->GetXaxis()->SetTitle("t [s]");
   gr1->GetYaxis()->SetTitle("vy(t)");
   gr1->GetXaxis()->CenterTitle();
   gr1->GetYaxis()->CenterTitle();
   gr1->Draw("A*");

}

After zeroing all the vy’s you should put a value different for vy at time 0.

I think the differential equation to solve is vy’= g k vy.

The analytical solution is vy(t)= A* exp(g k t). With the initial condition vy(0)=0, the value for A is equal to 0.
So the function is 0 for all the value of t. Change vy to a different value like 10 shows an exponential.

Edit.

The exponential will be decreasing or increasing according to the sign of g k.

Yes I also had vy[i] to be 0 but if you change the initial condition for vy it works

Thank you guys soo much for helping me out.

2 Likes

I am now using the same logic to do for coupled equation like this

#include "TGraph.h"
#include <iostream>
#include <vector>
#include <TMath.h>
#include <math.h>
using namespace std;


//declaration of the functions.
Double_t  f(double t, double x,double y){

        return y;
        }

double  g(double t,  double x,double y,const double u){
        return u*(1-pow(x,x))*y-x;
        }




void eq(){
        TCanvas *c1=new TCanvas();
        const Int_t n = 5;
        Double_t t[n],x[n],y[n],u[n];
        double F1,F2,F3,F4=0.0;
        double G1,G2,G3,G4=0.0;

        Double_t  h=0.01;

//Initial Conditions
        t[0]=0.0;
        x[0]=0.00;
        y[0]=0.01;




        for(Int_t i=0;i <n-1;  i++){
          u[i] = (TMath::Sin(pow(t[i],0.2)));
          F1 = f(t[i],x[i],y[i]);
          G1 = g(t[i],x[i],y[i],u[i]);
          F2=  f(t[i]+h*0.5,x[i]+0.5*h*F1,y[i]+G1*h*0.5);
          G2=  g(t[i]+h*0.5,x[i]+F1*h*0.5,y[i]+G1*h*0.5,u[i]);
          F3=  f(t[i]+h*0.5,x[i]+F2*h*0.5,y[i]+G2*h*0.5);
          G3=  g(t[i]+h*0.5,x[i]+F2*h*0.5,y[i]+G2*h*0.5,u[i]);
          F4=  f(t[i]+h,x[i]+F3*h,y[i]+h*G3);
          G4=  g(t[i]+h,x[i]+h*F3,y[i]+h*G3,u[i]);
          x[i+1] = x[i] + h/6 *( F1 + 2*F2 + 2*F3 + F4);
          y[i+1]  = y[i] + h/6 *( G1 + 2*G2 + 2*G3 + G4);
          t[i+1]= t[i] + h;

          x[i] = x[i+1];
          y[i] = y[i+1];
          t[i] = t[i+1];
        }

//solving in the runge kutta.
       // for (Int_t i=0;i<n;i++){
         //  std::cout<<t[i]<<" "<<x[i]<<" "<<y[i] << " " << u[i]<<std::endl;

       // }
/*
   TGraph *gr1 = new TGraph (n, t, x);
   gr1->GetXaxis()->SetTitle("t[s]");
   gr1->GetYaxis()->SetTitle("y Position");
   gr1->GetXaxis()->CenterTitle();
   gr1->GetYaxis()->CenterTitle();
   gr1->Draw("APL");
*/
}

Ok, is there something wrong we should look at?

Yes Please is there any way I can plot my graphs in three dimension?

Double_t  f(double t, double x,double y){
   return y;
}

double  g(double t,  double x,double y,const double u){
   return u*(1-pow(x,x))*y-x;
}

void eq(){
   const Int_t n = 5;
   Double_t t[n],x[n],y[n],u[n];
   double F1,F2,F3,F4=0.0;
   double G1,G2,G3,G4=0.0;

   Double_t  h=0.01;

   t[0]=0.0;
   x[0]=0.00;
   y[0]=0.01;
   for (Int_t i=0;i <n-1;  i++) {
      u[i] = (TMath::Sin(pow(t[i],0.2)));
      F1 = f(t[i],x[i],y[i]);
      G1 = g(t[i],x[i],y[i],u[i]);
      F2 = f(t[i]+h*0.5,x[i]+0.5*h*F1,y[i]+G1*h*0.5);
      G2 = g(t[i]+h*0.5,x[i]+F1*h*0.5,y[i]+G1*h*0.5,u[i]);
      F3 = f(t[i]+h*0.5,x[i]+F2*h*0.5,y[i]+G2*h*0.5);
      G3 = g(t[i]+h*0.5,x[i]+F2*h*0.5,y[i]+G2*h*0.5,u[i]);
      F4 = f(t[i]+h,x[i]+F3*h,y[i]+h*G3);
      G4 = g(t[i]+h,x[i]+h*F3,y[i]+h*G3,u[i]);
      x[i+1] = x[i] + h/6 *( F1 + 2*F2 + 2*F3 + F4);
      y[i+1] = y[i] + h/6 *( G1 + 2*G2 + 2*G3 + G4);
      t[i+1] = t[i] + h;
      x[i]   = x[i+1];
      y[i]   = y[i+1];
      t[i]   = t[i+1];
   }

   auto gr1 = new TGraph2D (n, x, y, t);
   gr1->Draw("P0 LINE");
}

Thank You soo much . I appreciate the help

Hello, It’s me again. Sorry to disturb you but I am new to both c++ and root. I am still on the Runge Kutta Method. This time I plan to apply it on three dimensional array. The idea is to create the 3D array containing x,y,z values, then apply the runge kutta to each column and draw it in 3D. I have changed my function but root does not understand the array I created and I do not get the graph. How can I do the 3D array well?

#include "TCanvas.h"
#include "TGraph.h"
#include <iostream>
#include <vector>
#include<fstream>
using namespace std;

//declaration of the function with 3d array.

Double_t f1(Double_t t, Double_t y1, Double_t y2,Double_t y3, const Int_t n){
	Double_t sigma=10.0;
	Double_t rho=28.0;
	Double_t beta = 8.0/3.0;
	Double func[n][n][n];
	return 	func[n][n][n]= {{sigma *(y2-y1)},{y1*(rho-y3)-y2},{y1*y2-beta*y3}};

	}


void example(){
	Double_t k1,k2,k3,k4;
	Double_t k;

	TCanvas *c1 = new TCanvas();

//Initial conditions.
	const Int_t  n=10;
	Double_t y[n][n][n],t[n];
	y[0][0][0] = {{-8.0},{8.0},{27}};
	t[0] = 0.0;
	Double_t h=0.001;

//solving for the runge kutta. 

	for (Int_t i=0; i<n-1; i++){
	k1 = f1(t[i],y[i][i][i]);
	k2 = f1(t[i]+h/2, y[i][i][i]+h*k1/2);
	k3 = f1(t[i]+h/2,y[i][i][i]+h*k2/2);
	k4 = f1(t[i] + h ,y[i][i][i]+h*k3);
	k = (k1+2*k2+2*k3+k4)/6;
	//update these values

	y[i+1][i+1][i+1] = y[i][i][i]+h*k;
	t[i+1] = t[i] +h;
      	y[i][i][i]   = y[i+1][i+1][i+1];

	}

// plot each of the 3D array.

   auto gr1 = new TGraph2D (n, y1, y2, y3);
   gr1->Draw("P0 LINE");


}

Sorry but I do not understand your logic, why declaring a 3D array at the end of f1 which returns a single value ?

To add points in the TGraph2D you can add them one by one using SetPoint in the loop.

I wanted to create 3D array with x, y and z coloums. like f1=[2 3 3]

Also in your function f1 has 5 input parameters and you call it only with two.
Your code is really confusing. I do not see how to change it.