...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 t ) 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[0] = ( 1.0 + m_eta * I ) * x[0] - ( 1.0 + m_alpha * I ) * norm( x[0] ) * x[0]; }
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. 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 , double , state_type , double , vector_space_algebra > 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
Note | |
---|---|
The fact that we have to configure a different algebra is solely due to
the fact that we use a non-vector state type and not to the usage of complex
values. So for, e.g. |