В документах 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
, чего я точно не ожидал.