2016-06-10 4 views
0

У меня есть матрица А эта форма:Отбора проб из булевой матрицы в Эйгене

Eigen::Matrix<bool, n, m> A(n, m) 

и я хочу, чтобы получить случайный элемент среди тех, которые «истины». Глупый способ сделать это было бы, чтобы получить число «истинного» элементы т, генерировать случайное число в диапазоне от 1 до т и итерации:

//r = random number 
int k = 0; 
for (int i = 0; i < A.rows(); ++i) 
    for (int j = 0; j < A.cols(); ++j) 
    { 
     if (A(i, j)) 
      ++k; 
     if (k == r) 
      std::cout << "(" << i << ", " << j << ")" << std::endl; 
    } 

Этого решение невероятно медленно, когда необходимы несколько образцов и матриц большой. Любое предположение относительно того, как я должен это делать?

Вкратце: я хотел бы найти эффективный способ получить i-й «истинный» элемент вышеуказанной матрицы.

ответ

1

Вместо этого вы можете использовать Eigen::SparseMatrix.

Eigen::SparseMatrix<bool> A(n, m); 

С его сжатым (или нет) схемы хранения столбца/строки, можно найти r -й ненулевой элемент в O (M)/O (п), или O (журнал (м)) с бинарным поиском.

Вы можете использовать утилиту COOEigen::Triplet, чтобы найти r -й ненулевой элемент в O (1) раз.

std::vector<Eigen::Triplet<bool> > a(num_nonzeros); 

И да, так как это матрица bool, хранение значений также необязательно.

+2

Вы можете просто построить 'std :: vector >' содержащий набор допустимых индексов '(i, j)'. Здесь нет необходимости в триплетах. – ggael

+0

Это отличные решения, но мне нужна плотная матричная форма для выполнения других операций, требующих от меня взглянуть на окрестности образцов, которые я беру. Это означает, что мне понадобится создать вторую структуру и обновление между ними, что было бы легко в форме SparseMatrix (но я больше искал решения O (1)), но не столько для других. Идеи? – user6451056

+0

@ user6451056 это C++, вы всегда можете создать свою собственную структуру данных для лучшей производительности. Например, используя COO-вектор с дополнительным массивом 'OuterStarts', похожим на' Eigen :: SparseMatrix', вы все равно можете получить доступ к окрестности почти за время O (1) (на самом деле O (log (n)), если вы используете двоичный поиск в колонка ряд). Остается только вопрос: действительно ли это ваше узкое место в производительности? – kangshiyin

Смежные вопросы