j'allais résoudre plusieurs équations différentielles de la matrice, de la forme d/dt (X) = F(X)
, où X
est une grande matrice complexe et F
représente une fonction de celui-ci. J'ai essayé d'utiliser de Boost odeint avec state_type
comme cx_mat
d'Armadillo. Mais il produit une erreur de compilation pour le type pas à pas contrôlé. Mon exemple de code est le suivantde cx_mat Armadillo et l'erreur de compilation odeint Boost
#include <armadillo>
#include <iostream>
#include <boost/numeric/odeint.hpp>
using namespace std;
using namespace arma;
using namespace boost::numeric::odeint;
using state_type = arma::cx_mat;
void ode(const state_type& X, state_type& derr, double) {
derr = X; // sample derivative, can be anything else
}
// define resizable and norm_inf
namespace boost { namespace numeric { namespace odeint {
template <>
struct is_resizeable<arma::cx_mat> {
typedef boost::true_type type;
const static bool value = type::value;
};
template <>
struct same_size_impl<arma::cx_mat, arma::cx_mat> {
static bool same_size(const arma::cx_mat& x, const arma::cx_mat& y)
{
return arma::size(x) == arma::size(y);
}
};
template<>
struct resize_impl<arma::cx_mat, arma::cx_mat> {
static void resize(arma::cx_mat& v1, const arma::cx_mat& v2) {
v1.resize(arma::size(v2));
}
};
template<>
struct vector_space_norm_inf<state_type> {
typedef double result_type;
result_type operator()(const state_type& p) const
{
return arma::norm(p, "inf");
}
};
} } } // namespace boost::numeric::odeint
using stepper = runge_kutta_dopri5<state_type, double, state_type, double, vector_space_algebra>;
int main() {
cx_mat A = randu<cx_mat>(4, 4);
integrate_adaptive(make_controlled<stepper>(1E-10, 1E-10), ode, A, 0.0 , 10.0, 0.1);
}
Ce code donne l'erreur de compilation suivante:
/usr/include/armadillo_bits/Mat_meat.hpp:5153:3: error: static assertion failed: error: incorrect or unsupported type
arma_type_check((is_same_type< eT, typename T1::elem_type >::no));
Ce que je peux comprendre que Armadillo ne supporte pas la copie d'une matrice réelle (mat
) dans un complexe (cx_mat
), comme
mat Z = something;
cx_mat Y = Z; // ERROR
Ce qui se passe quelque part dans odeint. En ce moment, je suis en surmontant cela en copiant la matrice entière dans std::vector<std::complex<double> >
le mettre dans la fonction ode
, puis à l'intérieur de la fonction à nouveau copier std::vector<std::complex<double> >
en cx_mat
, calculer F(X)
, puis le copier dans std::vector<std::complex<double> >
et retour. Évidemment, c'est très lent et inefficace.
Une solution simple au problème? Si possible, je peux vouloir passer à Eigen, si cela aide.
Eigen n'a pas aidé. Je pense que le problème réside dans odeint lui-même. –