MEX C++ Sparse array: How to efficiently get std::vectors from the sparse array

2 ビュー (過去 30 日間)
Breno Vincenzo de Almeida
Breno Vincenzo de Almeida 2020 年 9 月 27 日
I would like to know how to extract the values from a matlab::data::SparseArray<T> to std::vectors efficiently.
As a minimum working example of what I would like to achieve, consider a MEX function that recieves one sparse array of doubles as input and returns another sparse array with its nonzero values equal to double the input's values:
#include "mex.hpp"
#include "mexAdapter.hpp"
#include <vector>
class MexFunction : public matlab::mex::Function
{
public:
void operator() (matlab::mex::ArgumentList outputs, matlab::mex::ArgumentList inputs)
{
// get the input
matlab::data::SparseArray<double> spArrayInp = std::move(inputs[0]);
// copy the input sparse matrix information to std::vectors
size_t nnzSpIn = spArrayInp.getNumberOfNonZeroElements();
auto dim = spArrayInp.getDimensions();
std::vector<int> rows(nnzSpIn), cols(nnzSpIn);
std::vector<double> vals(nnzSpIn);
// ******* IMPROVE THIS ******* //
auto idx = spArrayInp.getIndex(spArrayInp.begin());
size_t itr=0;
for (matlab::data::TypedIterator<double> inpSpArrayPtr = spArrayInp.begin(); inpSpArrayPtr != spArrayInp.end(); ++inpSpArrayPtr)
{
idx = spArrayInp.getIndex(inpSpArrayPtr);
rows[itr] = idx.first;
cols[itr] = idx.second;
vals[itr++] = *inpSpArrayPtr;
}
// ****** ****** ****** ****** //
// double the values
std::for_each(vals.begin(),vals.end(),[](double &a){a*=2;});
// output doubled sparse matrix
matlab::data::ArrayFactory factory;
auto data_p = factory.createBuffer<double>(nnzSpIn);
auto rows_p = factory.createBuffer<size_t>(nnzSpIn);
auto cols_p = factory.createBuffer<size_t>(nnzSpIn);
double* dataPtr = data_p.get();
size_t* rowsPtr = rows_p.get();
size_t* colsPtr = cols_p.get();
std::for_each(vals.begin(), vals.end(), [&](const double& e) { *(dataPtr++) = e; });
std::for_each(rows.begin(), rows.end(), [&](const size_t& e) { *(rowsPtr++) = e; });
std::for_each(cols.begin(), cols.end(), [&](const size_t& e) { *(colsPtr++) = e; });
outputs[0] = factory.createSparseArray<double>({dim[0],dim[1]}, nnzSpIn, std::move(data_p),
std::move(rows_p), std::move(cols_p));
}
};
I tried at least to do the following to improve performance
vals.assign(spArrayInp.begin(), spArrayInp.end());
but that crashed MATLAB when compiling with MEX.

回答 (0 件)

カテゴリ

Help Center および File ExchangeC Shared Library Integration についてさらに検索

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by