2016-07-14 16 views
0

Ich möchte folgende MATLAB-Code in Eigen schreiben (wo Kpxp und W ist pxb ist):Eigen: Wie kann ich Matrix positive Werte mit 1 und 0 sonst ersetzen?

H = (K*W)>0; 

aber das einzige, was ich bisher kam ist:

H = ((K*W.array() > 0).select(1,0)); 

Diese Code funktioniert nicht wie erklärt here, aber ersetzen 0 durch VectorXd::Constant(p,0) (wie in der Link-Frage vorgeschlagen) erzeugt einen Laufzeitfehler:

Eigen::internal::variable_if_dynamic<T, Value>::variable_if_dynamic(T) [with T = long int; int Value = 1]: Assertion `v == T(Value)' failed. 

Wie kann ich das lösen?

Antwort

2

Sie benötigen keine .select(). Sie müssen lediglich ein Array von bool in ein Array des Komponententyps H umwandeln.

H = ((K * W).array() > 0.0).cast<double>(); 

gescheitert Ihr ursprünglicher Versuch, weil die Größe der Konstante 1/0 Array wird mit der Größe von H nicht überein. Die Verwendung von VectorXd::Constant ist keine gute Wahl, wenn HMatrixXd ist. Sie haben auch ein Problem mit Klammern. Ich denke, Sie wollen * statt .* in Matlab-Notation.

#include <iostream> 
#include <Eigen/Eigen> 
using namespace Eigen; 

int main() { 
    const int p = 5; 
    const int b = 10; 
    MatrixXd H(p, b), K(p, p), W(p, b); 
    K.setRandom(); 
    W.setRandom(); 
    H = ((K * W).array() > 0.0).cast<double>(); 
    std::cout << H << std::endl << std::endl; 

    H = ((K * W).array() > 0).select(MatrixXd::Constant(p, b, 1), 
            MatrixXd::Constant(p, b, 0)); 
    std::cout << H << std::endl; 
    return 0; 
} 

Wenn eine Vorlage Member-Funktion in einer Vorlage aufrufen, müssen Sie die template Schlüsselwort verwenden.

#include <iostream> 
#include <Eigen/Eigen> 
using namespace Eigen; 

template<typename Mat, typename Vec> 
void createHashTable(const Mat &K, Eigen::MatrixXi &H, Mat &W, int b) { 
    Mat CK = K; 
    H = ((CK * W).array() > 0.0).template cast<int>(); 
} 

int main() { 
    const int p = 5; 
    const int b = 10; 
    Eigen::MatrixXi H(p, b); 
    Eigen::MatrixXf W(p, b), K(p, p); 
    K.setRandom(); 
    W.setRandom(); 
    createHashTable<Eigen::MatrixXf, Eigen::VectorXf>(K, H, W, b); 
    std::cout << H << std::endl; 
    return 0; 
} 

Siehe dies für einige Erklärung.

Issue casting C++ Eigen::Matrix types via templates

+0

Danke für Ihre Antwort. Wäre nicht noch besser '.cast ()'? – justHelloWorld

+0

"abhängig von' H's Typ ". Da Sie den Typ "H" nicht angegeben haben, nehme ich an, dass es MatrixXd ist. – kangshiyin

+0

Danke. Jedoch bekomme ich diesen Kompilierfehler: '../Math.hpp:82:32: Fehler: erwarteter primärer Ausdruck vor 'int' H = ((CK * W) .array()> 0.0) .cast (); ^ ../Math.hpp:82:32: Fehler: erwartet ';' vor 'Int'' – justHelloWorld