2017-03-06 3 views
1

Ich mag würde eine Eigen coeffientwise Bediener haben, wo der Rückgabetyp von dem Eingangsmatrixtyp unterscheidet, z.B.Eigen Koeffizient wise Bediener mit verschiedenem Rückgabetyp

struct TimesPi { 
    double operator()(int v) { return 3.14 * v; } 
}; 

// in main 
Eigen::Vector3i vec_ints(1, 2, 3); 
Eigen::Vector3d vec_dbls = vec_ints.unaryExpr<TimesPi>(); 

Dies führt zu einer Fehlermeldung Compiler error: static assertion failed: YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY.

Wie kann ich eine elementweise Operation erzeugen, die einen anderen Typ zurückgibt?

edit: Für den speziellen Fall habe ich (anders als Beispiel), kann ich nicht anwenden (z. B. mit einem benutzerdefinierten Skalar-Typ). Ich denke, unaryExpr könnte hier falsch eingesetzt werden. Vielleicht etwas mit CwiseUnaryOp?

könnte eine angemessenere Beispiel

sein
struct SomeOperation { 
    double operator()(const Foo& v) { return v.attribute; } 
}; 

// in main 
Eigen::Matrix<Foo, 3, 1> vec_foos; 
Eigen::Matrix<double, 3, 1> = vec_foos.unaryExpr<SomeOperation>(); 
+0

I haven‘ t verwendet Eigen, aber ich kann anhand der Fehlermeldung erraten, dass es so etwas wie 'vec_ints.cast () .unaryExpr ()' ist. – chris

+0

Für den speziellen Fall, den ich habe (anders als Beispiel), kann ich keine Besetzung verwenden. Ich denke, "unaryExpr" könnte hier falsch sein. Vielleicht etwas mit 'CwiseUnaryOp'? – Jeff

+0

Das sieht wie eine Expression-Template-Klasse aus, die nicht explizit verwendet werden sollte. Auf der entsprechenden Seite sehe ich auch, dass 'x * vec' direkt erlaubt sein sollte. – chris

Antwort

1

Ich denke, dies ist nur ein vereinfachtes Beispiel und dass in Ihrem realen Szenario der Funktor ist viel komplexer und kann nicht erreicht werden, durch Verketten von standardmäßigen unären Operatoren. Wenn ja, dann haben Sie zwei Möglichkeiten: automatisch

  1. Kompilieren in C++ 11-Modus (zum Beispiel -std=c++11), so dass Eigen Verwendung von C++ 11 std :: result_of geben Sie die Rückkehr, um herauszufinden, machen. (Sie müssen auch Ihre operator() const machen)
  2. Wenn Sie C++ 98-Kompatibilität, dann haben Sie die result_type zu Eigen sagen, wie folgt:


#include <Eigen/Dense> 

struct TimesPi { 
    typedef double result_type; // needed for c++98/03 only 
    double operator()(int v) const { return 3.14 * v; } 
}; 

int main() 
{ 
    Eigen::Vector3i vec_ints(1, 2, 3); 
    Eigen::Vector3d vec_dbls = vec_ints.unaryExpr(TimesPi()); 
} 
+0

Danke, das war genau das, was ich gesucht habe. Die Angabe von result_type funktionierte für meinen benutzerdefinierten Skalar-Typ. – Jeff

0

ich nicht so aussehen wie Sie die Struktur verwenden, benötigen einen Unary Expr zu erstellen. Warum nicht einfach ...

Eigen::Vector3i vec_ints(1,2,3); 
Eigen::Vector3d vec_dbls = vec_ints.cast<double>() * M_PI; 

std::cout << vec_dbls << std::endl; 

kehrt ...

3.14159 
6.28319 
9.42478