如何在MATLAB的mex c ++函数中循环遍历矩阵元素? [英] How to loop through matrix elements in mex c++ function for MATLAB?

查看:281
本文介绍了如何在MATLAB的mex c ++函数中循环遍历矩阵元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用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:

  1. 没有边界检查
  2. C是基于0的,而Matlab是基于1的,这使得所有索引都不相同
  3. 所有数组都必须称为"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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆