TheAlgorithms/C++ 1.0.0
All the algorithms implemented in C++
Loading...
Searching...
No Matches
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.
 
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.
 
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.
 
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.
 
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.
 
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.
 

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

Definition at line 102 of file ode_forward_euler.cpp.

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}
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.

◆ 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)\)

Definition at line 86 of file ode_forward_euler.cpp.

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...

◆ 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

Definition at line 107 of file ode_midpoint_euler.cpp.

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}
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.

◆ 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)\)

Definition at line 85 of file ode_midpoint_euler.cpp.

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...

◆ 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

Definition at line 103 of file ode_semi_implicit_euler.cpp.

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}
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.

◆ 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)\)

Definition at line 82 of file ode_semi_implicit_euler.cpp.

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...