2017-09-22 4 views
0

Dies funktioniertC++ eigen Blockoperationen in templated Funktionen unter DenseBase

Vector2d a(1,2); 
VectorXd cc(10); 
cc << 1.0, 2.0, 3, 4, 5, 6, 7, 8, 9; 
VectorXd rr(10); 
rr << 1.0, 2.0, 3, 4, 5, 6, 7, 8, 9; 
int R(10); 
Vector2d G(Vector2d::Zero()); 


G.noalias() -= cc.segment(4, 2) + 
       (rr.segment(1, 2) - R*Vector2d::Ones()).cwiseQuotient(a); // OK here 

aber wenn rr.segment (1, 2) als Argument eine Funktion übergeben wird, wird der operator- in der letzten Zeile nicht kompiliert . Das Problem tritt in diesem Code

template <typename DerivedA, typename DerivedB, typename DerivedC> 
void testFunc(MatrixBase<DerivedA>& G, const DenseBase<DerivedB>& c, const DenseBase<DerivedC>& r) 
{ 
    Vector2d a(1,2); 
    int R(10); 
    G.noalias() -= c + (r - R*Vector2d::Ones()).cwiseQuotient(a); 
}; 

VectorXd cc(10); 
cc << 1.0, 2.0, 3, 4, 5, 6, 7, 8, 9; 
VectorXd rr(10); 
rr << 1.0, 2.0, 3, 4, 5, 6, 7, 8, 9; 
Vector2d G(Vector2d::Zero()); 
testFunc(G, cc.segment(4, 2), rr.segment(1, 2)); // ERROR : no match for 'operator-' 

Ich verstehe, dass das Problem in der Tatsache ist, dass in TestFunc(), cc.segment als allgemeinem DenseBase Objekt gesehen wird, für die die betreiber sind nicht implementiert, obwohl es implementiert für die bestimmte Klasse .block().

+0

Die Implementierung von testFunc arbeitet mit Matrixausdrücken, so dass MatrixBase <> -Argumente benötigt wird (dh das Hinzufügen eines Vector2d ist eine Matrixoperation). Warum nehmen Sie DenseBase <>? –

+0

weil ich .block() als Argumente übergebe – itQ

+0

AFAIR, ein Block eines Matrixausdrucks ist immer noch ein Matrixausdruck und sollte daher MatrixBase <> ... entsprechen (dh, DenseBase <> durch MatrixBase <> in Ihren Code-Kompilierungen ersetzen) gut für mich) –

Antwort

1

Sie können Eigen mitteilen, den tatsächlichen Typ zu verwenden, der von der Klasse DenseBase gekapselt ist, indem Sie c.derived() und schreiben.

Unrelated: Statt R*Vector2d::Ones() Schreib Vector2d::Constant(R), und wenn der gesamte Ausdruck elementweise Operationen ist, sollten Sie in der Array-Domäne sowieso arbeiten:

template <typename DerivedA, typename DerivedB, typename DerivedC> 
void testFunc(MatrixBase<DerivedA>& G, const DenseBase<DerivedB>& c, const DenseBase<DerivedC>& r) 
{ 
    Array2d a(1,2); 
    int R(10); 
    G.array() -= c.derived().array() + (r.derived().array() - R)/a; 
} 

(Sie könnten alle .derived() auslassen und .array(), wenn Sie geben ArrayBase statt MatrixBase oder DenseBase)

auch ist die .noalias() nur dann notwendig, wenn Matrixprodukte beteiligt sind.

Verwandte Themen