如何在mex c++;MATLAB函数? 我试图用MEX来编写一个外部的C++函数,用Max操作矩阵,而不能使用多维索引。这里提供了一些示例,但我还没有找到如何解决我在下面描述的问题。 我有一个样本矩阵: >> mat mat = 1 10 2 20 3 30 4 40 5 50
目前,我通过矩阵使用一个线性索引,该索引有效:如何在mex c++;MATLAB函数? 我试图用MEX来编写一个外部的C++函数,用Max操作矩阵,而不能使用多维索引。这里提供了一些示例,但我还没有找到如何解决我在下面描述的问题。 我有一个样本矩阵: >> mat mat = 1 10 2 20 3 30 4 40 5 50,c++,matlab,multidimensional-array,mex,C++,Matlab,Multidimensional Array,Mex,目前,我通过矩阵使用一个线性索引,该索引有效: #include <mex.h> #include <iostream> using namespace std; void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { //1.get pointer to input graph_list and allocate it double *graph_
#include <mex.h>
#include <iostream>
using namespace std;
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
//1.get pointer to input graph_list and allocate it
double *graph_list = mxGetPr(prhs[0]);
mwSize mrows = mxGetM(prhs[0]);
mwSize ncols = mxGetN(prhs[0]);
cout<< mrows<<" rows\n";
cout<< ncols<<" cols\n";
int mm, nn;
for (nn=0;nn<ncols;nn++) {
for (mm=0;mm<mrows;mm++){
cout << graph_list[nn*(mrows) +mm] <<"\n";
}
}
}
当我更改graph_list的定义并尝试对graph_list进行2D索引时,mex
出现编译错误:
double **graph_list = mxGetPr(prhs[0]);
cout << graph_list[nn][mm];
正如所指出的,mxGetPr
返回指向1D数组的指针。因此,C++中不能将其视为<强> 2D<强>数组。
您可以使用函数将N-D下标转换为一个1D索引。编译器会一目了然 在C语言中,2D数组类似于数组的数组。因此,2D阵列从根本上不同于1D阵列;它是一个指针数组,其中每个元素都包含一个指向数组的指针(因此是一个双指针,
double**
)
您要求mxGetPr()
返回一个double**
,但它返回一个double*
,例如指向1D数组的第一个元素的指针。此一维数组只能线性索引
我的猜测是,MATLAB这样做是为了保持索引数组的一致性——对于一个4-D数组,您真的希望/想要一个双****
此外,mxGetPr()
不能通过返回类型重载(毕竟是C)
为了能够对1D数组进行双索引,您可以潜入一个小宏:
#define A(i,j) A[(i) + (j)*numrows]
像这样使用它
double *A = mxGetPr(...);
int numrows = 4; /* or get with mxGetM() or so) */
double blah = A(3,2); /* call to MACRO */
显然,与所有宏一样,有几件事需要注意:
double getValue(double** array, int row, int* dims);
(或者使用所指出的mxCalcSingleSubscript
),但这并不能真正提高表达能力:
double blah = getValue(array, 3,4, dims);
/* or the ugliness from mxCalcSingleSubscript(); */
也可以用C++编写,用<代码>操作器()/Cube制作一个矩阵类型类,用指针和维度构造它,从代码< > MXGETPRE()/<代码>和<代码> MXGETIMDIMS]()/代码>等,在Matlab中使用<代码> G++<代码>或等效代码编译,但这带来了一系列其他问题,并增加了比大多数情况下所需要的复杂得多的复杂性
因此,为了避免所有这些混乱,我总是就地计算索引:)拥有一个矩阵类是迄今为止处理此类问题最简单的方法。有很多可供选择的,所以不要费心写你自己的。犰狳相当不错,如果你使用它的话,它还可以与拉帕克相结合。 见下面的例子
#include <mex.h>
#include <iostream>
#include <armadillo>
using namespace std;
using namespace arma;
//creates an armadillo matrix from a matlab matrix
mat armaMatrix(const mxArray *matlabMatrix[]){
mwSize mrows = mxGetM(matlabMatrix[0]);
mwSize ncols = mxGetN(matlabMatrix[0]);
double *values = mxGetPr(matlabMatrix[0]);
return mat(values, nrows, ncols);
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
mat graph_list = armaMatrix(prhs);
//print the matrix
cout << graph_list<<"\n";
//print the first column
cout << graph_list(span::all,0) <<"\n";
}
#包括
#包括
#包括
使用名称空间std;
使用arma;
//从matlab矩阵创建犰狳矩阵
mat armaMatrix(常数mxArray*matlabMatrix[]){
mwSize mrows=mxGetM(matlabMatrix[0]);
mwSize ncols=mxGetN(matlabMatrix[0]);
双*值=mxGetPr(matlabMatrix[0]);
返回mat(值、nrows、NCOL);
}
void MEX函数(int nlhs、mxArray*plhs[]、int nrhs、const mxArray*prhs[])
{
mat graph_list=ARMA矩阵(prhs);
//打印矩阵
编译错误是不是…?我想是因为mxGetPr(prhs[0])
是指针(而不是指向指针的指针),您是否收到了“双重取消引用”类型的错误?@RodyOldenhuis,我刚刚在编辑中添加了错误消息put@Sahi,我不确定我是否理解。我想使用N-D下标,但他们不知道work@Vass在C++意义上的N-D下标(即,<代码>图形列表[MM ] [NN] < /代码>将不会工作,因为<代码> GraceListBux/Cube >是1-D C++数组(无论它是从代码派生出的<代码> MxReals>代码>的维度)。您可以使用mxCalcSingleSubscripts
绕过此限制-有关此命令的详细信息,请参阅文档。@Vass:很高兴提供帮助。通常,当您陷入困境时,StackOverflow是最快也是最好的解决方案:)我从去年就知道这个答案,但我很难弄清楚为什么numRows/mxGetM
不是numCols/mxGetN
在#定义A(i,j)A[(i)+(j)*numrows]
@SamuelO'Malley这是因为数组具有行主顺序,即,首先向下排列行,然后向下排列列。因此,只需将其分解:如果数组是3×4,并且您希望寻址第二行、第一列上的元素,那么i==1
(第二行)和j==0
(对吗?)。对第一行第二列的元素进行寻址时,i==0
(第一行)和j==3
(它用等于行数的偏移量“包装”,该偏移量在i
增加时保持不变,直到i>2
)谢谢“RodioDounHIS”,我在想,因为它是C++,它是列主序,但是我没有意识到它是如何解释它的。这是很重要的。稍微多的代码,犰狳也可以直接使用Matlab矩阵的内存,即没有复制。参见文档。
double blah = getValue(array, 3,4, dims);
/* or the ugliness from mxCalcSingleSubscript(); */
#include <mex.h>
#include <iostream>
#include <armadillo>
using namespace std;
using namespace arma;
//creates an armadillo matrix from a matlab matrix
mat armaMatrix(const mxArray *matlabMatrix[]){
mwSize mrows = mxGetM(matlabMatrix[0]);
mwSize ncols = mxGetN(matlabMatrix[0]);
double *values = mxGetPr(matlabMatrix[0]);
return mat(values, nrows, ncols);
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
mat graph_list = armaMatrix(prhs);
//print the matrix
cout << graph_list<<"\n";
//print the first column
cout << graph_list(span::all,0) <<"\n";
}