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

11 views (last 30 days)
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.

Answers (0)

Categories

Find more on C Shared Library Integration in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!