Как эффективно инициализировать SparseVector в Eigen - PullRequest
0 голосов
/ 11 октября 2018

В документах Eigen для заполнения разреженной матрицы рекомендуется использовать метод триплетного заполнения , так как он может быть намного эффективнее, чем выполнение вызовов coeffRef, что предполагает бинарный поиск.

Однако для заполнения SparseVectors нет четких рекомендаций относительно того, как это сделать эффективно.

Предлагаемый метод в этом ответе SO использует coeffRef, что означает, чтобинарный поиск выполняется для каждой вставки.

Существует ли рекомендуемый эффективный способ построения разреженных векторов?Должен ли я попытаться создать одну строку SparseMatrix, а затем сохранить ее как SparseVector?

Мой пример использования - чтение файлов LibSVM, в которых могут быть миллионы очень редких функций и миллиарды данных.точки.В настоящее время я представляю их как std::vector<Eigen::SparseVector>.Возможно, я должен просто использовать SparseMatrix вместо этого?

Редактировать: я попробовал одну вещь:

// for every data point in a batch do the following:

Eigen::SparseMatrix<float> features(1, num_features);
// copy the data over
typedef Eigen::Triplet<float> T;
std::vector<T> tripletList;
for (int j = 0; j < num_batch_instances; ++j) {
  for (size_t i = batch.offset[j]; i < batch.offset[j + 1]; ++i) {
    uint32_t index = batch.index[i];
    float fvalue = batch.value;
    if (index < num_features) {
      tripletList.emplace_back(T(0, index, fvalue));
    }
  }
  features.setFromTriplets(tripletList.begin(), tripletList.end());
  samples->emplace_back(Eigen::SparseVector<float>(features));
}

. Это создает SparseMatrix с использованием подхода тройного списка, затем создаетSparseVector от этого объекта.В моих экспериментах с ~ 1.4M функциями и очень высокой разреженностью это на 2 порядка медленнее, чем при использовании SparseVector и coeffRef, чего я точно не ожидал.

...