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

2 Ansichten (letzte 30 Tage)
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.

Antworten (0)

Kategorien

Mehr zu C Shared Library Integration finden Sie in Help Center und File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by