Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在mex c++;MATLAB函数? 我试图用MEX来编写一个外部的C++函数,用Max操作矩阵,而不能使用多维索引。这里提供了一些示例,但我还没有找到如何解决我在下面描述的问题。 我有一个样本矩阵: >> mat mat = 1 10 2 20 3 30 4 40 5 50_C++_Matlab_Multidimensional Array_Mex - Fatal编程技术网

如何在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 */
显然,与所有宏一样,有几件事需要注意:

  • 没有边界检查
  • C是基于0的,Matlab是基于1的,这使得所有指标都不同
  • 所有数组都必须称为“A”
  • 您可以编写一个函数来缓解这些缺点:

    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";
    }