...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
Home | Libraries | People | FAQ | More |
Thus far we have seen several examples defined for real values. odeint can handle complex state types, hence ODEs which are defined on complex vector spaces, as well. An example is the Stuart-Landau oscillator
d Ψ / dt = ( 1 + i η ) Ψ + ( 1 + i α ) | Ψ |2 Ψ
where Ψ and i is a complex variable. The definition of this ODE in C++ using complex< double > as a state type may look as follows
typedef complex< double > state_type; struct stuart_landau { double m_eta; double m_alpha; stuart_landau( double eta = 1.0 , double alpha = 1.0 ) : m_eta( eta ) , m_alpha( alpha ) { } void operator()( const state_type &x , state_type &dxdt , double ) const { const complex< double > I( 0.0 , 1.0 ); dxdt = ( 1.0 + m_eta * I ) * x - ( 1.0 + m_alpha * I ) * norm( x ) * x; } };
One can also use a function instead of a functor to implement it
double eta = 1.0; double alpha = 1.0; void stuart_landau( const state_type &x , state_type &dxdt , double t ) { const complex< double > I( 0.0 , 1.0 ); dxdt = ( 1.0 + m_eta * I ) * x - ( 1.0 + m_alpha * I ) * norm( x ) * x; }
We strongly recommend to use the first ansatz. In this case you have explicit control over the parameters of the system and are not restricted to use global variables to parametrize the oscillator.
When choosing the stepper type one has to account for the "unusual"
state type: it is a single complex<double>
opposed to the vector types used in the
previous examples. This means that no iterations over vector elements have
to be performed inside the stepper algorithm. Odeint already detects that
and automatically uses the vector_space_algebra
for computation. You can enforce this by supplying additional template arguments
to the stepper including the vector_space_algebra
.
Details on the usage of algebras can be found in the section Adapt
your own state types.
state_type x = complex< double >( 1.0 , 0.0 ); const double dt = 0.1; typedef runge_kutta4< state_type > stepper_type; integrate_const( stepper_type() , stuart_landau( 2.0 , 1.0 ) , x , 0.0 , 10.0 , dt , streaming_observer( cout ) );
The full cpp file for the Stuart-Landau example can be found here stuart_landau.cpp