A comprehensive C++ implementation of various numerical methods for solving Ordinary Differential Equations (ODEs). This library provides accurate and efficient algorithms for approximating solutions to differential equations that are commonly encountered in science, engineering, and mathematical modeling.
-
Multiple numerical methods implemented:
- Euler's Method: Simple first-order method
- Modified Euler's Method (Heun's Method): Second-order predictor-corrector method
- Runge-Kutta 2nd Order Method: Improved accuracy over Euler's method
- Runge-Kutta 4th Order Method: High accuracy, widely used method
- Adams-Bashforth Method: Multi-step method for improved efficiency
-
Advanced capabilities:
- Error Analysis: Compare numerical solutions with exact analytical solutions
- Data Export: Save results to CSV files for further analysis or visualization
- Method Comparison: Compare the accuracy and performance of different methods
- Easy Customization: Define your own differential equations with a simple function
- Precision Control: All results are rounded to 4 decimal places for clarity
- Installation
- Usage
- Implemented Methods
- Project Structure
- Customizing Differential Equations
- Example Problems
- Performance Comparison
- Contributing
- License
- Author
- C++ compiler with C++11 support or later
- CMake 3.10 or later (for building the project)
- Standard C++ libraries
-
Clone the repository:
git clone https://github.com/prathameshkhade/solution-of-differential-equation.git cd solution-of-differential-equation
-
Create a build directory and configure with CMake:
mkdir build cd build cmake ..
-
Build the project:
cmake --build .
-
Run the executable:
./bin/solver
If you don't have CMake, you can compile manually:
g++ src/*.cpp -I include/ -o numerical_solver -std=c++11
When you run the program, you'll be prompted to:
- Enter initial conditions (xโ, yโ)
- Specify the target x value to solve for
- Set the step size (h)
- Choose additional options:
- Compare with exact solution (if available)
- Save results to CSV files
- Run a comparison of all methods
- Select a numerical method to use
===============================================
Numerical Differential Equation Solver v2.0
===============================================
By Prathamesh Khade
===============================================
Enter initial conditions and parameters:
Initial x (x0) = 0
Initial y (y0) = 1
Target x = 1
Step size (h) = 0.1
Additional options:
Compare with exact solution? (1 for yes, 0 for no): 1
Save results to CSV files? (1 for yes, 0 for no): 1
Run comparison of all methods? (1 for yes, 0 for no): 0
Which method do you want to perform?
1. Euler's Method
2. Modified Euler's Method (Heun's Method)
3. 2nd Order Runge-Kutta Method
4. 4th Order Runge-Kutta Method
5. Adams-Bashforth Method
6. All Methods (for comparison)
Enter your choice (1-6): 4
=== 4th Order Runge-Kutta Method ===
Initial values: x0 = 0.0000, y0 = 1.0000
Step size: h = 0.1000
Target x = 1.0000
Step 1:
At x = 0.0000, y = 1.0000
k1 = 0.1000
k2 = 0.1050
k3 = 0.1053
k4 = 0.1108
delta k = 0.1044
New y = 1.1044 at x = 0.1000
Exact solution: 1.1103
Error: 0.0059
... [additional steps] ...
Final result at x = 1.0000: y = 4.4366
Exact solution: 4.4366
Error: 0.0000
The simplest numerical method for solving ODEs. It uses the formula:
y_{n+1} = y_n + h * f(x_n, y_n)
Advantages: Simple to implement and understand Disadvantages: Lower accuracy, requires small step size
A second-order predictor-corrector method that improves on Euler's method:
y_{n+1} = y_n + h/2 * [f(x_n, y_n) + f(x_{n+1}, y_n + h * f(x_n, y_n))]
Advantages: Better accuracy than Euler's method Disadvantages: Requires two function evaluations per step
A second-order method with improved accuracy:
k1 = h * f(x_n, y_n)
k2 = h * f(x_n + h, y_n + k1)
y_{n+1} = y_n + 1/2 * (k1 + k2)
Advantages: Good balance between accuracy and computational cost Disadvantages: Less accurate than higher-order methods
A highly accurate fourth-order method:
k1 = h * f(x_n, y_n)
k2 = h * f(x_n + h/2, y_n + k1/2)
k3 = h * f(x_n + h/2, y_n + k2/2)
k4 = h * f(x_n + h, y_n + k3)
y_{n+1} = y_n + 1/6 * (k1 + 2*k2 + 2*k3 + k4)
Advantages: High accuracy, widely used Disadvantages: Requires four function evaluations per step
A multi-step method that uses previous points to calculate the next value:
y_{n+1} = y_n + h/24 * (55*f_n - 59*f_{n-1} + 37*f_{n-2} - 9*f_{n-3})
Advantages: Efficient for long integrations Disadvantages: Requires startup values from another method
The project is organized into the following directory structure:
solution-of-differential-equation/
โโโ include/ # Header files
โ โโโ NumericalMethod.h # Base class for all methods
โ โโโ Euler.h # Euler's method
โ โโโ ModifiedEuler.h # Modified Euler's method
โ โโโ RungeKutta2.h # 2nd order Runge-Kutta
โ โโโ RungeKutta4.h # 4th order Runge-Kutta
โ โโโ AdamsBashforth.h # Adams-Bashforth method
โ โโโ Utility.h # Utility functions
โโโ src/ # Source files
โ โโโ NumericalMethod.cpp # Base class implementation
โ โโโ Euler.cpp # Euler's method implementation
โ โโโ ModifiedEuler.cpp # Modified Euler's implementation
โ โโโ RungeKutta2.cpp # RK2 implementation
โ โโโ RungeKutta4.cpp # RK4 implementation
โ โโโ AdamsBashforth.cpp # Adams-Bashforth implementation
โ โโโ Utility.cpp # Utility functions implementation
โ โโโ main.cpp # Main program
โโโ CMakeLists.txt # Build system configuration
โโโ README.md # Project documentation
To solve your own differential equation, modify the differentialFunction
function in src/NumericalMethod.cpp
:
double differentialFunction(double x, double y) {
// Change this to your differential equation
return x + y; // Example: dy/dx = x + y
// Other examples:
// return x * x + y; // dy/dx = xยฒ + y
// return x * y; // dy/dx = xy
// return std::sin(x) + std::cos(y); // dy/dx = sin(x) + cos(y)
}
If you know the exact solution to your equation, you can also modify the exactSolution
function:
double exactSolution(double x) {
// Change this to the exact solution of your equation
return 2 * std::exp(x) - x - 1; // Solution for dy/dx = x + y
}
// Exponential growth/decay: dy/dx = ky
double differentialFunction(double x, double y) {
double k = 0.5; // Growth rate
return k * y;
}
// Exact solution: y = yโ * e^(kx)
double exactSolution(double x) {
double k = 0.5;
double y0 = 1.0; // Initial condition
return y0 * std::exp(k * x);
}
// Simple harmonic oscillator (convert to first-order system)
// y'' + y = 0 becomes y' = z, z' = -y
// This is for y' = z
double differentialFunction(double x, double y) {
// Assuming z is stored elsewhere
return z;
}
// Exact solution: y = A*cos(x) + B*sin(x)
double exactSolution(double x) {
// With initial conditions y(0)=1, y'(0)=0
return std::cos(x);
}
// Logistic growth model: dy/dx = ry(1-y/K)
double differentialFunction(double x, double y) {
double r = 0.5; // Growth rate
double K = 10.0; // Carrying capacity
return r * y * (1 - y/K);
}
// No simple exact solution for arbitrary initial conditions
The table below shows a comparison of the different methods for solving the equation dy/dx = x + y with initial conditions (0,1) to x = 1 with different step sizes:
Method | Step Size | Result | Exact Solution | Error |
---|---|---|---|---|
Euler's | 0.1 | 4.2579 | 4.4366 | 0.1787 |
Modified Euler's | 0.1 | 4.4059 | 4.4366 | 0.0307 |
RK2 | 0.1 | 4.4059 | 4.4366 | 0.0307 |
RK4 | 0.1 | 4.4366 | 4.4366 | 0.0000 |
Adams-Bashforth | 0.1 | 4.4364 | 4.4366 | 0.0002 |
Euler's | 0.01 | 4.4141 | 4.4366 | 0.0225 |
RK4 | 0.01 | 4.4366 | 4.4366 | 0.0000 |
As the table shows, higher-order methods like RK4 provide much better accuracy even with larger step sizes.
Contributions are welcome! Here's how you can contribute:
- Fork the repository
- Create a feature branch:
git checkout -b feature-name
- Commit your changes:
git commit -m 'Add some feature'
- Push to the branch:
git push origin feature-name
- Open a pull request
Please make sure to update tests as appropriate and adhere to the existing coding style.
This project is licensed under the MIT License - see the LICENSE file for details.
Prathamesh Khade
- GitHub: prathameshkhade
- Last Update: 2025-06-07 07:08:45 UTC