Algorithms_in_C++  1.0.0
Set of algorithms implemented in C++.
Ordinary Differential Equations

Functions

void forward_euler_step (const double dx, const double x, std::valarray< double > *y, std::valarray< double > *dy)
 Compute next step approximation using the forward-Euler method. More...
 
double forward_euler (double dx, double x0, double x_max, std::valarray< double > *y, bool save_to_file=false)
 Compute approximation using the forward-Euler method in the given limits. More...
 
void midpoint_euler_step (const double dx, const double &x, std::valarray< double > *y, std::valarray< double > *dy)
 Compute next step approximation using the midpoint-Euler method. More...
 
double midpoint_euler (double dx, double x0, double x_max, std::valarray< double > *y, bool save_to_file=false)
 Compute approximation using the midpoint-Euler method in the given limits. More...
 
void semi_implicit_euler_step (const double dx, const double &x, std::valarray< double > *y, std::valarray< double > *dy)
 Compute next step approximation using the semi-implicit-Euler method. More...
 
double semi_implicit_euler (double dx, double x0, double x_max, std::valarray< double > *y, bool save_to_file=false)
 Compute approximation using the semi-implicit-Euler method in the given limits. More...
 

Detailed Description

Integration functions for implementations with solving ordinary differential equations (ODEs) of any order and and any number of independent variables.

Function Documentation

◆ forward_euler()

double forward_euler ( double  dx,
double  x0,
double  x_max,
std::valarray< double > *  y,
bool  save_to_file = false 
)

Compute approximation using the forward-Euler method in the given limits.

Parameters
[in]dxstep size
[in]x0initial value of independent variable
[in]x_maxfinal value of independent variable
[in,out]ytake \(y_n\) and compute \(y_{n+1}\)
[in]save_to_fileflag to save results to a CSV file (1) or not (0)
Returns
time taken for computation in seconds
103  {
104  std::valarray<double> dy = *y;
105 
106  std::ofstream fp;
107  if (save_to_file) {
108  fp.open("forward_euler.csv", std::ofstream::out);
109  if (!fp.is_open()) {
110  std::perror("Error! ");
111  }
112  }
113 
114  std::size_t L = y->size();
115 
116  /* start integration */
117  std::clock_t t1 = std::clock();
118  double x = x0;
119 
120  do { // iterate for each step of independent variable
121  if (save_to_file && fp.is_open()) {
122  // write to file
123  fp << x << ",";
124  for (int i = 0; i < L - 1; i++) {
125  fp << y[0][i] << ","; // NOLINT
126  }
127  fp << y[0][L - 1] << "\n"; // NOLINT
128  }
129 
130  forward_euler_step(dx, x, y, &dy); // perform integration
131  x += dx; // update step
132  } while (x <= x_max); // till upper limit of independent variable
133  /* end of integration */
134  std::clock_t t2 = std::clock();
135 
136  if (fp.is_open()) {
137  fp.close();
138  }
139 
140  return static_cast<double>(t2 - t1) / CLOCKS_PER_SEC;
141 }
Here is the call graph for this function:

◆ forward_euler_step()

void forward_euler_step ( const double  dx,
const double  x,
std::valarray< double > *  y,
std::valarray< double > *  dy 
)

Compute next step approximation using the forward-Euler method.

\[y_{n+1}=y_n + dx\cdot f\left(x_n,y_n\right)\]

Parameters
[in]dxstep size
[in]xtake \(x_n\) and compute \(x_{n+1}\)
[in,out]ytake \(y_n\) and compute \(y_{n+1}\)
[in,out]dycompute \(f\left(x_n,y_n\right)\)
87  {
88  problem(x, y, dy);
89  *y += *dy * dx;
90 }
Here is the call graph for this function:

◆ midpoint_euler()

double midpoint_euler ( double  dx,
double  x0,
double  x_max,
std::valarray< double > *  y,
bool  save_to_file = false 
)

Compute approximation using the midpoint-Euler method in the given limits.

Parameters
[in]dxstep size
[in]x0initial value of independent variable
[in]x_maxfinal value of independent variable
[in,out]ytake \(y_n\) and compute \(y_{n+1}\)
[in]save_to_fileflag to save results to a CSV file (1) or not (0)
Returns
time taken for computation in seconds
108  {
109  std::valarray<double> dy = y[0];
110 
111  std::ofstream fp;
112  if (save_to_file) {
113  fp.open("midpoint_euler.csv", std::ofstream::out);
114  if (!fp.is_open()) {
115  std::perror("Error! ");
116  }
117  }
118 
119  std::size_t L = y->size();
120 
121  /* start integration */
122  std::clock_t t1 = std::clock();
123  double x = x0;
124  do { // iterate for each step of independent variable
125  if (save_to_file && fp.is_open()) {
126  // write to file
127  fp << x << ",";
128  for (int i = 0; i < L - 1; i++) {
129  fp << y[0][i] << ",";
130  }
131  fp << y[0][L - 1] << "\n";
132  }
133 
134  midpoint_euler_step(dx, x, y, &dy); // perform integration
135  x += dx; // update step
136  } while (x <= x_max); // till upper limit of independent variable
137  /* end of integration */
138  std::clock_t t2 = std::clock();
139 
140  if (fp.is_open())
141  fp.close();
142 
143  return static_cast<double>(t2 - t1) / CLOCKS_PER_SEC;
144 }
Here is the call graph for this function:

◆ midpoint_euler_step()

void midpoint_euler_step ( const double  dx,
const double &  x,
std::valarray< double > *  y,
std::valarray< double > *  dy 
)

Compute next step approximation using the midpoint-Euler method.

\[y_{n+1} = y_n + dx\, f\left(x_n+\frac{1}{2}dx, y_n + \frac{1}{2}dx\,f\left(x_n,y_n\right)\right)\]

Parameters
[in]dxstep size
[in]xtake \(x_n\) and compute \(x_{n+1}\)
[in,out]ytake \(y_n\) and compute \(y_{n+1}\)
[in,out]dycompute \(f\left(x_n,y_n\right)\)
86  {
87  problem(x, y, dy);
88  double tmp_x = x + 0.5 * dx;
89 
90  std::valarray<double> tmp_y = y[0] + dy[0] * (0.5 * dx);
91 
92  problem(tmp_x, &tmp_y, dy);
93 
94  y[0] += dy[0] * dx;
95 }
Here is the call graph for this function:

◆ semi_implicit_euler()

double semi_implicit_euler ( double  dx,
double  x0,
double  x_max,
std::valarray< double > *  y,
bool  save_to_file = false 
)

Compute approximation using the semi-implicit-Euler method in the given limits.

Parameters
[in]dxstep size
[in]x0initial value of independent variable
[in]x_maxfinal value of independent variable
[in,out]ytake \(y_n\) and compute \(y_{n+1}\)
[in]save_to_fileflag to save results to a CSV file (1) or not (0)
Returns
time taken for computation in seconds
105  {
106  std::valarray<double> dy = y[0];
107 
108  std::ofstream fp;
109  if (save_to_file) {
110  fp.open("semi_implicit_euler.csv", std::ofstream::out);
111  if (!fp.is_open()) {
112  std::perror("Error! ");
113  }
114  }
115 
116  std::size_t L = y->size();
117 
118  /* start integration */
119  std::clock_t t1 = std::clock();
120  double x = x0;
121  do { // iterate for each step of independent variable
122  if (save_to_file && fp.is_open()) {
123  // write to file
124  fp << x << ",";
125  for (int i = 0; i < L - 1; i++) {
126  fp << y[0][i] << ",";
127  }
128  fp << y[0][L - 1] << "\n";
129  }
130 
131  semi_implicit_euler_step(dx, x, y, &dy); // perform integration
132  x += dx; // update step
133  } while (x <= x_max); // till upper limit of independent variable
134  /* end of integration */
135  std::clock_t t2 = std::clock();
136 
137  if (fp.is_open())
138  fp.close();
139 
140  return static_cast<double>(t2 - t1) / CLOCKS_PER_SEC;
141 }
Here is the call graph for this function:

◆ semi_implicit_euler_step()

void semi_implicit_euler_step ( const double  dx,
const double &  x,
std::valarray< double > *  y,
std::valarray< double > *  dy 
)

Compute next step approximation using the semi-implicit-Euler method.

\[y_{n+1}=y_n + dx\cdot f\left(x_n,y_n\right)\]

Parameters
[in]dxstep size
[in]xtake \(x_n\) and compute \(x_{n+1}\)
[in,out]ytake \(y_n\) and compute \(y_{n+1}\)
[in,out]dycompute \(f\left(x_n,y_n\right)\)
84  {
85  problem(x, y, dy); // update dy once
86  y[0][0] += dx * dy[0][0]; // update y0
87  problem(x, y, dy); // update dy once more
88 
89  dy[0][0] = 0.f; // ignore y0
90  y[0] += dy[0] * dx; // update remaining using new dy
91 }
Here is the call graph for this function:
semi_implicit_euler_step
void semi_implicit_euler_step(const double dx, const double &x, std::valarray< double > *y, std::valarray< double > *dy)
Compute next step approximation using the semi-implicit-Euler method.
Definition: ode_semi_implicit_euler.cpp:82
std::clock_t
forward_euler_step
void forward_euler_step(const double dx, const double x, std::valarray< double > *y, std::valarray< double > *dy)
Compute next step approximation using the forward-Euler method.
Definition: ode_forward_euler.cpp:86
midpoint_euler_step
void midpoint_euler_step(const double dx, const double &x, std::valarray< double > *y, std::valarray< double > *dy)
Compute next step approximation using the midpoint-Euler method.
Definition: ode_midpoint_euler.cpp:85
std::clock
T clock(T... args)
std::ofstream
STL class.
std::ofstream::close
T close(T... args)
std::perror
T perror(T... args)
std::valarray< double >
std::ofstream::open
T open(T... args)
problem
void problem(const double &x, std::valarray< double > *y, std::valarray< double > *dy)
Problem statement for a system with first-order differential equations. Updates the system differenti...
Definition: ode_semi_implicit_euler.cpp:53
problem
void problem(const double &x, std::valarray< double > *y, std::valarray< double > *dy)
Problem statement for a system with first-order differential equations. Updates the system differenti...
Definition: ode_forward_euler.cpp:54
problem
void problem(const double &x, std::valarray< double > *y, std::valarray< double > *dy)
Problem statement for a system with first-order differential equations. Updates the system differenti...
Definition: ode_midpoint_euler.cpp:53
std::size_t
std::ofstream::is_open
T is_open(T... args)