`

matlab矩阵转为Eigen库中的矩阵

 
阅读更多
在matlab,C++联合编程的过程中,想使用一下Eigen库(一个C++矩阵运算库)。
为啥不直接用matlab的库呢?
有两点考虑:
  • 1、matlab中写for循环太慢,处理图像块有时还得两层for循环
  • 2、在C++中采用matlab函数,不利于生成独立的C++程序。


不多说了,上代码:
以下是将matlab矩阵转为Eigen中的Map(可以当做矩阵使用)的函数,转为Map而不是Matrix是为了避免不必要的数据拷贝(Eigen的数据共享实在是烂的可以!)

namespace Eigen {
template<typename T> Map<Matrix<T, Dynamic, Dynamic, ColMajor>> matlab2Eigen (const mxArray * pMat, bool needTranspose = true) {
    Map< Matrix<T, Dynamic, Dynamic, ColMajor>> matrixMap ( (T*) mxGetPr (pMat), mxGetM (pMat), mxGetN (pMat) );
    return matrixMap;
}
}

其实就是一行函数而已,也就是Eigen中Map 的基础用法。更多用法参见:http://eigen.tuxfamily.org/dox/group__TutorialMapClass.html
其中的一行用于指定间隔的(注意这里列间距为1(更准确说是外间距,因为矩阵为列优先存储的,外间距为列间距),行间距为4,但矩阵是列优先存储的!也就是说,M(r,c)的计算方法为: M(c*1+r*4);)
Map<Matrix<int,2,4>, Unaligned, Stride<1,4> >(array) ;

如果是常用的写法:
Map<Matrix<int,2,4>>(array) ;

或者展开写:
Map<Matrix<int,2,4>, Unaligned, Stride<0,0> >(array) ;

M(r,c)的计算方法为: M(c*4+r*1)


附上完成的测试代码(两个矩阵相加):

#include <Eigen/Core>


//mex headers and libraries
#include "mex.h"
#pragma comment(lib,"libmx.lib")
#pragma comment(lib,"libmex.lib")
#pragma comment(lib,"libmat.lib")

namespace Eigen {
template<typename T> Map<Matrix<T, Dynamic, Dynamic, ColMajor>> matlab2Eigen (const mxArray * pMat, bool needTranspose = true) {
    Map< Matrix<T, Dynamic, Dynamic, ColMajor>> matrixMap ( (T*) mxGetPr (pMat), mxGetM (pMat), mxGetN (pMat) );
    return matrixMap;
}
}
//define function name in the DLL
#pragma comment(linker,"/EXPORT:mexFunction") //保证了DLL导出的函数名未经过修改,等效于使用.def文件
void mexFunction (int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    /* 检查输入输出变量的个数 */
    if (nrhs != 2) mexErrMsgTxt ("Two inputs required.");
    else if (nlhs > 2) mexErrMsgTxt ("Too many output arguments");


    auto m1 = Eigen::matlab2Eigen<double> (prhs[0]);
    auto m2 = Eigen::matlab2Eigen<double> (prhs[1]);
    if (m1.rows() != m2.rows() || m1.cols() != m2.cols() ) 
		mexErrMsgTxt ("two matrix must be the same size.");


    /* 为返回参数创建矩阵 */
    plhs[0] = mxCreateNumericMatrix (m1.rows(), m1.cols(), mxDOUBLE_CLASS, mxREAL);
    auto m3 = Eigen::matlab2Eigen<double> (plhs[0]);
    m3 = m1 + m2;
}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics