TheAlgorithms/C++ 1.0.0
All the algorithms implemented in C++
Loading...
Searching...
No Matches
ode_midpoint_euler.cpp
Go to the documentation of this file.
1
38#include <cmath>
39#include <ctime>
40#include <fstream>
41#include <iostream>
42#include <valarray>
43
53void problem(const double &x, std::valarray<double> *y,
54 std::valarray<double> *dy) {
55 const double omega = 1.F; // some const for the problem
56 dy[0][0] = y[0][1]; // x dot
57 dy[0][1] = -omega * omega * y[0][0]; // y dot
58}
59
66void exact_solution(const double &x, std::valarray<double> *y) {
67 y[0][0] = std::cos(x);
68 y[0][1] = -std::sin(x);
69}
70
85void midpoint_euler_step(const double dx, const double &x,
86 std::valarray<double> *y, std::valarray<double> *dy) {
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}
96
107double midpoint_euler(double dx, double x0, double x_max,
108 std::valarray<double> *y, bool save_to_file = false) {
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}
145
156void save_exact_solution(const double &X0, const double &X_MAX,
157 const double &step_size,
158 const std::valarray<double> &Y0) {
159 double x = X0;
160 std::valarray<double> y = Y0;
161
162 std::ofstream fp("exact.csv", std::ostream::out);
163 if (!fp.is_open()) {
164 std::perror("Error! ");
165 return;
166 }
167 std::cout << "Finding exact solution\n";
168
169 std::clock_t t1 = std::clock();
170 do {
171 fp << x << ",";
172 for (int i = 0; i < y.size() - 1; i++) {
173 fp << y[i] << ",";
174 }
175 fp << y[y.size() - 1] << "\n";
176
177 exact_solution(x, &y);
178
179 x += step_size;
180 } while (x <= X_MAX);
181
182 std::clock_t t2 = std::clock();
183 double total_time = static_cast<double>(t2 - t1) / CLOCKS_PER_SEC;
184 std::cout << "\tTime = " << total_time << " ms\n";
185
186 fp.close();
187}
188
192int main(int argc, char *argv[]) {
193 double X0 = 0.f; /* initial value of x0 */
194 double X_MAX = 10.F; /* upper limit of integration */
195 std::valarray<double> Y0 = {1.f, 0.f}; /* initial value Y = y(x = x_0) */
196 double step_size;
197
198 if (argc == 1) {
199 std::cout << "\nEnter the step size: ";
200 std::cin >> step_size;
201 } else {
202 // use commandline argument as independent variable step size
203 step_size = std::atof(argv[1]);
204 }
205
206 // get approximate solution
207 double total_time = midpoint_euler(step_size, X0, X_MAX, &Y0, true);
208 std::cout << "\tTime = " << total_time << " ms\n";
209
210 /* compute exact solution for comparion */
211 save_exact_solution(X0, X_MAX, step_size, Y0);
212
213 return 0;
214}
int main()
Main function.
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 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.
void save_exact_solution(const double &X0, const double &X_MAX, const double &step_size, const std::valarray< double > &Y0)
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...
void exact_solution(const double &x, std::valarray< double > *y)
Exact solution of the problem. Used for solution comparison.