https://github.com/r-barnes/simple_integrator
Euler's method integrator with adaptive step size
https://github.com/r-barnes/simple_integrator
Last synced: 10 months ago
JSON representation
Euler's method integrator with adaptive step size
- Host: GitHub
- URL: https://github.com/r-barnes/simple_integrator
- Owner: r-barnes
- Created: 2013-05-03T03:26:46.000Z (over 12 years ago)
- Default Branch: master
- Last Pushed: 2013-07-16T21:43:56.000Z (over 12 years ago)
- Last Synced: 2025-01-26T19:11:20.218Z (11 months ago)
- Language: C++
- Size: 156 KB
- Stars: 3
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
SIMPLE INTEGRATOR
=================
How would you perform a numerical integration of an equation with the form
y'(t)=f(t, y(t))
There are many integrators in the world. Many of the emphasise accuracy and use
high-order methods to estimate and minimize error. This kind of accuracy is
expensive. For systems that are generally well-behaved where the goal is
understanding of dynamics, rather than exact predictions, accuracy is no longer
paramount.
This C++11 library implements a simple adaptive step-size integrator based on
[Euler's method](https://en.wikipedia.org/wiki/Euler_method). The method is
both fast and simple, allowing for the quick simulation of many-dimensional
systems.
Additionally, a special class is provided which allows for discrete-time events
which instantaneously alter the state of a system. The integrator approaches
such events cautiously, using an exponentially-decreasing step-size. It
withdraws with equal caution.
The file **integrator.hpp** implements the integrator.
Examples
========
Two examples of the integrator in action are provided.
The first example **example\_lotka.cpp** simulates a Lotka-Volterra
predator-prey model. This code:
#include
#include "integrator.hpp"
using namespace std;
//Define state_type to be an double array of size 2
typedef si_lib::ArrayState state_type;
//First derivate of the state at a given time
void df(const state_type &state, state_type &dxdt, double t){
dxdt[0]= 1.5*state[0]-1*state[0]*state[1];
dxdt[1]=-3 *state[1]+1*state[0]*state[1];
}
int main(){
//Set the initial state
state_type x={{10,4}};
//Create an EventIntegrator object with initial state **x**, first-derivative
//**df**, minimum step-size 1e-3, and maximum step-size 0.01
si_lib::Integrator stepper(x, df, 1e-3, 0.01);
//Display the initial state
cout<
#include "integrator.hpp"
using namespace std;
//Define state_type to be an double array of size 2
typedef si_lib::ArrayState state_type;
//First derivate of the state at a given time
void df(const state_type &state, state_type &dxdt, double t){
dxdt[0]= 1.5*state[0]-1*state[0]*state[1];
dxdt[1]=-3 *state[1]+1*state[0]*state[1];
}
int main(){
//Set the initial state
state_type x={{10,4}};
//Create an EventIntegrator object with initial state **x**, first-derivative
//**df**, minimum step-size 1e-3, and maximum step-size 0.01
si_lib::EventIntegrator stepper(x, df, 1e-3, 0.01);
//Insert an event which occurs once at t=10
stepper.insert_event(10,"large_drought");
//Insert an event which occurs for the first time at t=4 and every 3 time
//units afterwards
stepper.insert_event(4,"recurring_drought",3);
//Display the initial state
cout<=20
while(stepper.time()<20){
//Has the time step ended on an event?
if(stepper.is_event()){
if(stepper.event()=="large_drought") //Look up the event
stepper.state()[0]*=0.3; //Perform appropriate actions
else if(stepper.event()=="recurring_drought")
stepper.state()[0]*=0.5;
}
//Progress the integrator by one step
stepper.step();
//Print out the current state
cout<