ashdan ashdan - 1 month ago 12
C++ Question

Compile error C2440 with make_dense_output in boost odeint

I am getting the following error the state_type

ublas::vector<std::complex<double>>
with 'dense output', but compiles with
just runge_kutta_dopri5 stepper.

C2440 'return': cannot convert from 'std::complex' to 'double' at boost\numeric\odeint\stepper\controlled_runge_kutta.hpp 89

#include <iostream>
#include <complex>
#include <boost/numeric/ublas/blas.hpp>
#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/vector_proxy.hpp>
#include <boost/numeric/ublas/assignment.hpp>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/io.hpp>
#include <boost/numeric/odeint.hpp>

using namespace boost::numeric::odeint;
namespace bnu = boost::numeric::ublas;

typedef bnu::vector<std::complex< double >> state_type;

struct solver_test
{
state_type & m_a;
solver_test(state_type& a): m_a(a) { }

void operator()(const state_type &x, state_type &dxdt, double t) const
{
// dummy!
dxdt = element_prod(x, m_a);
}
};

struct observer
{
std::vector<double> & m_tm;
std::vector<state_type> & m_out;

observer(std::vector<double>& tm, std::vector<state_type> & out)
:m_tm(tm), m_out(out) { }

template< class State >
void operator()(const State &x, double t) const
{
m_tm.push_back(t);
m_out.push_back(x);
}
};

int main(int argc, char **argv)
{
std::vector<double> tm;
std::vector<state_type> out;
state_type a_vec(10);
std::fill_n(a_vec.begin(), 10, std::complex<double>(1.0, 0.5));

state_type noise(10);
std::fill_n(noise.begin(), 10, std::complex<double>(1.5, 1.5));

const double dt = 0.1;

typedef runge_kutta_dopri5<state_type> dp_stepper_type;

integrate_const(make_dense_output(1.0e-6, 1.0e-3, dp_stepper_type()),
solver_test(a_vec), noise, 0.0, 10.0, dt, observer(tm, out));

// This works
//integrate_const(dp_stepper_type(),
// solver_test(a_vec), noise, 0.0, 10.0, dt, observer(tm, out));

return 0;
}


I am using boost 1_64_0 with MS Visual Studio Community 2017.
What am I missing?

Answer Source

For the sake of others with this problem, I used the following workaround for the state_type variable.

typedef std::vector<std::complex<double>> state_type;

I used boost::numeric::ublas inside solvers (function objects) to take advantage of matrix operations. It's not perfect but it worked.