如何在MATLAB的mex c ++函数中循环遍历矩阵元素? [英] How to loop through matrix elements in mex c++ function for MATLAB?
问题描述
我正在尝试使用mex操纵矩阵为MATLAB编写外部c ++函数的索引,但是无法使用多维索引.在此处中提供了示例,但是我还没有找到解决以下问题的方法. 我有一个样本矩阵:
I am trying to index write an external c++ function for MATLAB using mex to manipulate matrices, and am not able to use multidimensional indexing. There are examples provided here, but I have not found how to fix the problem I describe below. I have a sample matrix:
>> mat
mat =
1 10
2 20
3 30
4 40
5 50
目前,我在整个矩阵中使用了线性索引,
Currently I use a linear index through the matrix which works:
#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";
}
}
}
这将产生:
>> mexTryAlex(mat)
5 rows
2 cols
1
2
3
4
5
10
20
30
40
50
当我更改graph_list的定义并尝试将2D索引到graph_list时,出现mex
的编译错误:
When I change the definition of graph_list and try 2D indexing to graph_list there is a compilation error with mex
:
double **graph_list = mxGetPr(prhs[0]);
cout << graph_list[nn][mm];
这是收到的错误消息
>> mex mexTryAlex.cpp
Warning: You are using gcc version "4.4.3-4ubuntu5)". The version
currently supported with MEX is "4.3.4".
For a list of currently supported compilers see:
http://www.mathworks.com/support/compilers/current_release/
mexTryAlex.cpp: In function ‘void mexFunction(int, mxArray**, int, const mxArray**)’:
mexTryAlex.cpp:16: error: cannot convert ‘double*’ to ‘double**’ in initialization
mex: compile of ' "mexTryAlex.cpp"' failed.
??? Error using ==> mex at 208
Unable to complete successfully.
推荐答案
编译器说了一切.
在C语言中,二维数组就像一个数组数组.因此,2D阵列与1D阵列根本不同.它是一个指针数组,其中每个元素都包含一个指向数组的指针(因此为双指针double**
).
In C, a 2D array is like an array of arrays. Therefore, a 2D array is fundamentally different from a 1D array; it's an array of pointers, in which each element contains a pointer to an array (hence a double-pointer, double**
).
您要mxGetPr()
返回一个double**
,但是它返回一个double*
,例如,指向一维数组第一个元素的指针.此一维数组只能线性地索引 .
You're asking mxGetPr()
to return a double**
, but it returns a double*
, e.g., a pointer to the first element of a 1D array. This 1D array can only be indexed linearly.
我的猜测是MATLAB以此方式来保持索引数组的一致性-您真的希望/想要4-D数组的double****
吗?
My guess is that MATLAB does this it this way to keep indexing arrays consistent -- would you really expect/want a double****
for a 4-D array?
此外,mxGetPr()
不能由返回类型重载(毕竟为C).
Moreover, mxGetPr()
cannot be overloaded by return type (it's C after all).
为了能够对一维数组进行双索引,您可以潜入一个小宏:
In order to be able to double-index a 1D array, you could sneak in a little macro:
#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 */
很显然,与所有宏一样,有一些注意事项:
Obviously, as with all macros, there's a few things to look out for:
- 没有边界检查
- C是基于0的,而Matlab是基于1的,这使得所有索引都不相同
- 所有数组都必须称为"A"
您可以编写函数来减轻这些缺点:
You could write a function to mitigate these drawbacks:
double getValue(double** array, int row, int* dims);
(或使用 Shai 指出的mxCalcSingleSubscript
),但这并不能真正改善表达力恕我直言:
(or use mxCalcSingleSubscript
as pointed out by Shai), but that doesn't really improve expressive power IMHO:
double blah = getValue(array, 3,4, dims);
/* or the ugliness from mxCalcSingleSubscript(); */
您还可以用C ++编写代码,使用operator()
制作Matrix类型的类,使用mxGetPr()
和mxGetDims()
等的指针和尺寸来构造它,并在Matlab中使用g++
或同等功能进行编译,但这带来了许多其他问题,并增加了大多数情况下所需的复杂性.
You could also write in C++, make a Matrix-type class with an operator()
, construct it with the pointer and dimensions from mxGetPr()
and mxGetDims()
etc., compile in Matlab using g++
or equivalent, but that introduces a whole host of other problems and adds way much more complexity than needed for most cases.
因此,为了避免所有此类混乱,我总是始终就地计算索引:)
Therefore, to avoid all of this mess, I just always compute the index in-place :)
这篇关于如何在MATLAB的mex c ++函数中循环遍历矩阵元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!