J'ai un Eigen::MatrixXd
et je voudrais modifier tous ses éléments en appliquant une fonction par composant. Par exemple:
MatrixXd m = ...;
for each m[i][j]:
m[i][j] = exp(m[i][j]);
Y a-t-il un moyen d'obtenir ce résultat?
Oui, utilisez la fonction Eigen::MatrixBase<>::unaryExpr()
member. Exemple:
#include <cmath>
#include <iostream>
#include <Eigen/Core>
double Exp(double x) // the functor we want to apply
{
return std::exp(x);
}
int main()
{
Eigen::MatrixXd m(2, 2);
m << 0, 1, 2, 3;
std::cout << m << std::endl << "becomes: ";
std::cout << std::endl << m.unaryExpr(&Exp) << std::endl;
}
La réponse de vsoftco est très générale et convient aux fonctions personnalisées. Cependant, il existe un moyen plus simple pour de nombreuses fonctions couramment utilisées. En adaptant son exemple, nous pouvons utiliser array
s et cela ressemble à ceci:
#include <iostream>
#include <Eigen/Core>
int main()
{
Eigen::MatrixXd m(2, 2);
m << 0, 1, 2, 3;
std::cout << m << "\nbecomes:\n";
std::cout << m.array().exp() << std::endl;
return 0;
}
La réponse de @ vsoftco m'a permis d'obtenir 99% du chemin nécessaire pour résoudre ce problème, mais pour une raison quelconque, passer de &Exp
à .unaryExpr()
me donnait des erreurs de compilation (g ++, c + 11, Eigen 3.3.5 donnait une erreur liée à: base type ‘double (*)(double)’ fails to be a struct or class type
).
Cependant, j’ai trouvé que la création d’un objet std::function
et son transfert corrigeaient ce problème. Copier l'exemple de @ vsoftco:
#include <cmath>
#include <iostream>
#include <Eigen/Core>
double Exp(double x)
{
return std::exp(x);
}
int main()
{
Eigen::MatrixXd m(2, 2);
m << 0, 1, 2, 3;
std::function<double(double)> exp_wrap = Exp; //added to @vsoftco's answer
std::cout << m << std::endl << "becomes: ";
std::cout << std::endl << m.unaryExpr(exp_wrap) << std::endl; //and used here
}
Je ne sais pas combien de temps d'utilisation un objet std::function
(ou std::ptr_fun
) donne par rapport au passage de &Exp
, mais je ne pouvais pas le faire fonctionner sans ces alternatives.
À votre santé