Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext

Complex state types

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] 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. vector< complex<double> >, this would not be required.


PrevUpHomeNext