2012-11-20 17 views
7

Przyjmuje, że poniżej przedstawiono mat typu Eigen::MatrixXd i zawiera już pewne dane. Próbując uniknąć pamięć powielanie, próbowałem instancji flann::Matrix<double> obiekt ze wskaźnikiem do surowego kawałka pamięci przydzielonej przez Eigen3:Eigen :: MatrixXd na flann :: Matryca <double> konwersja

flann::Matrix<double> input(const_cast<double *>(mat.data(), mat.rows(), mat.cols()) 

Jednak mój algorytm wyprowadza śmieci, ale jest po prostu w porządku z brzydkim:

flann::Matrix<double> input(new double[mat.rows()*mat.cols()], mat.rows(), mat.cols()); 
for (int i = 0; i < mat.rows(); i++) { 
for (int j = 0; j < mat.cols(); j++) { 
    input[i][j] = mat(i, j); 
} 

}

I zbadano możliwość podklasy bazową Matrix_ typu z Flann utworzyć adapter macierzy Eigen3. Problem polega jednak na tym, że Matrix_ polega na implementacji operatora [] w swoim interwale. Czuję, że mogę napotkać ten sam problem z pamięcią, niż w prostym (ale zepsutym) rozwiązaniu pokazanym powyżej.

Co według Ciebie może wyjaśnić takie zachowanie?

  • wiersz/kolumna poważnym problemem
  • Wewnętrzna, zewnętrzna kwestia kroku
  • wyrównanie pamięci Niezgodności
  • Eigen::Map jest słodka, ale nie to, czego szukam. Ssałbym przepisać mój kod, by używać stl::vector<std::vector<double> > jako typów bazowych i Eigen::Map je do Eigen::MatrixXd
  • Niestety zbyt daleko od biblioteki podstawowej biblioteki libflann, aby można było z nich korzystać.

Odpowiedz

0

Eigen :: Matrix zapisuje dane w sposób ciągły, więc nie powinieneś mieć problemów ze śledzeniem. Wyrównanie może być problemem, jeśli próbujesz skonstruować Eigen :: Matrix (ale nie mogę sobie wyobrazić, jak to jest możliwe). Domyślnie Eigen :: Matrix ma kolumnę główną, to może być twój problem. Nie wiem, jak flann traktuje matryce, jeśli są rzędowe, to wszystko. Poniższy przykład działa z Eigen :: Matrix < podwójnym, -1, -1, Eigen :: RowMajor> dla macie i kończy się niepowodzeniem z Eigen :: MatrixXd.

int k = 0; 
for (int i = 0; i<mat.rows(); ++i) 
{ 
    for (int j = 0; j<mat.cols(); ++j, ++k) { 
     mat(i, j) = k; 
    } 
} 

double* mptr = mat.data(); 
for (int i = 0; i<mat.rows() * mat.cols(); ++i) { 
    assert(mptr[i] == i); 
} 

nie mam swój narzekać Eigen :: map. Jest to najmilszy sposób traktowania niektórych danych jako matrycy własnej (pamiętaj, że domyślnie nadal będzie to kolumna-major), podklasy z macierzy lub implementacja własnego wyrażenia własnego mogą być bolesne.

7

Otrzymałem również potwierdzenie od Mariusza Muja, autora libflann, że flann::Matrix sklepów w rzędzie-większej kolejności, podczas gdy Eigen używa domyślnie kolumna-major. Oto odpowiedź, którą podał mi przez e-mail:

Najprawdopodobniej problem polega na tym, że Eigen przechowuje matryce w kolejności kolumnowo-durowej, podczas gdy FLANN wymaga ich w kolejności rzędowej.

Rozwiązaniem byłoby użycie Matrix<double, Dynamic, Dynamic, RowMajor> zamiast MatrixXd, wówczas macierze FLANN i Eigen mogą współdzielić tę samą pamięć, w przeciwnym razie będzie potrzebna kopia. Marius Muja

+0

Miałem ten sam problem z nanoFLANN (chociaż działało to w obie strony, ale domyślna kolumna-majster była bardzo niezręczna dla mojej aplikacji), dziękuję! –