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 */
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 */
135
136 if (fp.is_open()) {
137 fp.close();
138 }
139
140 return static_cast<double>(t2 - t1) / CLOCKS_PER_SEC;
141}
T clock(T... args)
T close(T... args)
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
T is_open(T... args)
T open(T... args)
T perror(T... args)
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}
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
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 */
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 */
139
140 if (fp.is_open())
141 fp.close();
142
143 return static_cast<double>(t2 - t1) / CLOCKS_PER_SEC;
144}
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
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}
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
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 */
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 */
136
137 if (fp.is_open())
138 fp.close();
139
140 return static_cast<double>(t2 - t1) / CLOCKS_PER_SEC;
141}
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
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}
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
Here is the call graph for this function: