passing sparse arrays from matlab to Eigen (C++) and back to matlab?

[亡魂溺海] 提交于 2019-12-23 23:06:27

问题


The following is a mex code that multiplies dense arrays g and G from matlab using Eigen. How do I do this when g is sparse?

#include <iostream>
#include <Eigen/Dense>
#include "mex.h"
using Eigen::MatrixXd;
using namespace Eigen;
/*gateway function*/
void mexFunction( int nlhs, mxArray *plhs[],
        int nrhs, const mxArray *prhs[]) {

    int nRows=(int)mxGetM(prhs[0]);
    int nCols=nRows;

    double* g=mxGetPr(prhs[0]);
    double* Gr=mxGetPr(prhs[1]);

    Map<MatrixXd> gmap (g, nRows, nCols );
    Map<MatrixXd> Grmap (Gr, nRows, nCols );
    plhs[0] = mxCreateDoubleMatrix(nRows, nCols, mxREAL);
    Map<MatrixXd> resultmap (mxGetPr(plhs[0]), nRows, nCols); 

    resultmap = gmap*Grmap; 

}

回答1:


You can use these functions to pass sparse (compressed) double matrix between MATLAB and Eigen* :

#include "mex.h"
#include <Eigen/Sparse>
#include <type_traits>
#include <limits>

using namespace Eigen;

typedef SparseMatrix<double,ColMajor,std::make_signed<mwIndex>::type> MatlabSparse;


Map<MatlabSparse >
matlab_to_eigen_sparse(const mxArray * mat)
{
    mxAssert(mxGetClassID(mat) == mxDOUBLE_CLASS,
    "Type of the input matrix isn't double");
    mwSize     m = mxGetM (mat);
    mwSize     n = mxGetN (mat);
    mwSize    nz = mxGetNzmax (mat);
    /*Theoretically fails in very very large matrices*/
    mxAssert(nz <= std::numeric_limits< std::make_signed<mwIndex>::type>::max(),
    "Unsupported Data size."
    );
    double  * pr = mxGetPr (mat);
    MatlabSparse::StorageIndex* ir = reinterpret_cast<MatlabSparse::StorageIndex*>(mxGetIr (mat));
    MatlabSparse::StorageIndex* jc = reinterpret_cast<MatlabSparse::StorageIndex*>(mxGetJc (mat));
    Map<MatlabSparse> result (m, n, nz, jc, ir, pr);
    return result;
}

mxArray* 
eigen_to_matlab_sparse(const Ref<const MatlabSparse,StandardCompressedFormat>& mat)
{
    mxArray * result = mxCreateSparse (mat.rows(), mat.cols(), mat.nonZeros(), mxREAL);
    const MatlabSparse::StorageIndex* ir = mat.innerIndexPtr();
    const MatlabSparse::StorageIndex* jc = mat.outerIndexPtr();
    const double* pr = mat.valuePtr();

    mwIndex * ir2 = mxGetIr (result);
    mwIndex * jc2 = mxGetJc (result);
    double  * pr2 = mxGetPr (result);

    for (mwIndex i = 0; i < mat.nonZeros(); i++) {
        pr2[i] = pr[i];
        ir2[i] = ir[i];
    }
    for (mwIndex i = 0; i < mat.cols() + 1; i++) {
        jc2[i] = jc[i];
    }
    return result;
}
  • Reading and writing MATLAB/Octave sparse matrix adopted from here.

  • Thanks to @chtz for their recommendations.



来源:https://stackoverflow.com/questions/49952275/passing-sparse-arrays-from-matlab-to-eigen-c-and-back-to-matlab

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!