Complex state types

| Home | Libraries | People | FAQ | More

### 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 = ( 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