Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.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++ MeX函数来迭代一个矩阵数组,每个矩阵的大小不同。在Matlab中,我可以使用以下代码完成此操作: function Z = myFunction(X, Z, B) for i = 1:size(X, 1) for j = 1:size(X, 2) for k = 1:size(X, 3) temp = X{i, j, k}; for m = 1:size(temp, 1) Z{temp(m, 1)}(temp(m, 2)) = Z{temp(m, 1)}(temp(m, 2)) + B(i, j, k); end end end end_C++_Arrays_Matlab_Indexing_Mex - Fatal编程技术网

mex函数中单元数组和矩阵元素的索引和访问 我试图编写一个C++ MeX函数来迭代一个矩阵数组,每个矩阵的大小不同。在Matlab中,我可以使用以下代码完成此操作: function Z = myFunction(X, Z, B) for i = 1:size(X, 1) for j = 1:size(X, 2) for k = 1:size(X, 3) temp = X{i, j, k}; for m = 1:size(temp, 1) Z{temp(m, 1)}(temp(m, 2)) = Z{temp(m, 1)}(temp(m, 2)) + B(i, j, k); end end end end

mex函数中单元数组和矩阵元素的索引和访问 我试图编写一个C++ MeX函数来迭代一个矩阵数组,每个矩阵的大小不同。在Matlab中,我可以使用以下代码完成此操作: function Z = myFunction(X, Z, B) for i = 1:size(X, 1) for j = 1:size(X, 2) for k = 1:size(X, 3) temp = X{i, j, k}; for m = 1:size(temp, 1) Z{temp(m, 1)}(temp(m, 2)) = Z{temp(m, 1)}(temp(m, 2)) + B(i, j, k); end end end end,c++,arrays,matlab,indexing,mex,C++,Arrays,Matlab,Indexing,Mex,这里X是一个三维单元数组,其中每个单元包含一个矩阵,该矩阵具有可变的行数和2列数。这两列允许我索引向量Z的另一个单元格数组,其中每个向量的长度不同。Z中索引的向量元素由三维矩阵B中的元素递增 到目前为止,我在C++中有以下代码(我以前从未用C++编码): #包括“mex.h” void MEX函数(int nlhs、mxArray*plhs[]、int nrhs、const mxArray*prhs[]) { 常量mxArray*X=prhs[0]; 常量mxArray*Z=prhs[1]; 常

这里X是一个三维单元数组,其中每个单元包含一个矩阵,该矩阵具有可变的行数和2列数。这两列允许我索引向量Z的另一个单元格数组,其中每个向量的长度不同。Z中索引的向量元素由三维矩阵B中的元素递增

到目前为止,我在C++中有以下代码(我以前从未用C++编码):

#包括“mex.h”
void MEX函数(int nlhs、mxArray*plhs[]、int nrhs、const mxArray*prhs[])
{
常量mxArray*X=prhs[0];
常量mxArray*Z=prhs[1];
常量mxArray*B=prhs[2];
常量int*pDims=mxGetDimensions(X);
mwSize nsubs=mxGetNumberOfDimensions(X);
对于(大小i=0;i
问题:

  • 要访问矩阵B的元素,我可以使用与访问单元数组X元素相同的mxCalcSingleSubscript函数吗?如果没有,我该怎么做
  • 如何访问
    temp
    的元素并像在Matlab代码中那样执行索引

  • -由于所有输入数组都是常量
    const
    ,因此您应该复制
    Z

    -
    mxCalcSingleSubscript
    可用于任何类型的阵列,包括单元阵列。在这里,我将其重命名为
    sub2ind

    -
    mxGetPr
    用于访问数组的元素

    下面是一个实现(尚未在实际数据上测试):

    #包括“mex.h”
    #定义sub2ind mxCalcSingleSubscript
    void MEX函数(int nlhs、mxArray*plhs[]、int nrhs、const mxArray*prhs[])
    {
    常量mxArray*X=prhs[0];
    常量mxArray*Z=prhs[1];
    常量mxArray*B=prhs[2];
    mxArray*out=mxDuplicateArray(Z);
    常量int*pDims=mxGetDimensions(X);
    mwSize nsubs=mxGetNumberOfDimensions(X);
    双*B_arr=mxGetPr(B);
    对于(大小i=0;i
    但是,MATLAB和c实现都可以更改为使用线性索引:

    function Z = myFunction(X, Z, B)
        for k = 1:numel(X)
            for m = 1:size(X{k}, 1)
                Z{X{k}(m, 1)}(X{k}(m, 2)) = Z{X{k}(m, 1)}(X{k}(m, 2)) + B(k);
            end
        end
    end
    
    
    #include "mex.h"
    void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
    {
        const mxArray* X = prhs[0];
        const mxArray* Z = prhs[1];
        const mxArray* B = prhs[2];
        mxArray * out = mxDuplicateArray (Z);
    
        mwSize n_X = mxGetNumberOfElements(X);
        double* B_arr = mxGetPr(B);
        for (size_t k = 0; k < n_X; k++) {
            mxArray* temp = mxGetCell(X, k);
            double* temp_arr = mxGetPr(temp);
    
            const int* matDims = mxGetDimensions(temp);
            size_t rows = matDims[0];
            for (size_t m = 0; m < rows; m++) {
                mwIndex temp_m_1 = temp_arr[m]-1;
                mwIndex temp_m_2 = temp_arr[m+rows]-1;
                double* Z_out = mxGetPr (mxGetCell(out,temp_m_1));
                Z_out[temp_m_2] += B_arr[k];
            }
        }
        plhs[0] = out;
    } 
    
    function Z=myFunction(X,Z,B)
    对于k=1:numel(X)
    对于m=1:size(X{k},1)
    Z{X{k}(m,1)}(X{k}(m,2))=Z{X{k}(m,1)}(X{k}(m,2))+B(k);
    结束
    结束
    结束
    #包括“mex.h”
    void MEX函数(int nlhs、mxArray*plhs[]、int nrhs、const mxArray*prhs[])
    {
    常量mxArray*X=prhs[0];
    常量mxArray*Z=prhs[1];
    常量mxArray*B=prhs[2];
    mxArray*out=mxDuplicateArray(Z);
    mwSize n_X=mxGetNumberOfElements(X);
    双*B_arr=mxGetPr(B);
    对于(大小k=0;k
    非常感谢您的宝贵意见!工作完美。我只是想知道,如果我删除
    X
    Z
    B
    声明前面的
    const
    ,并将第27行和第33行中的
    out
    替换为
    Z
    ,为什么
    Z
    没有被修改?
    Z_out
    现在不是指向
    Z
    的元素而不是
    out
    的元素,因此第28行直接修改
    Z
    ?这会比复制数组快吗?同样,避免使用
    mxCalcSingleSubscript
    /
    sub2ind
    和使用
    i
    j
    k
    m
    直接索引
    X
    temp
    会更快吗?mex函数的所有输入,包括X,Z和B是常数,必须/不能修改。因此,您应该创建一个副本并对其进行更改
    Z_out
    指向
    out
    WOW的元素,我希望我能给你更多的分数!我的代码现在快了7-10倍!非常感谢你!原始matlab。。。运行时间为1.767017秒。线性索引matlab。。。运行时间为0.880587秒。普通墨西哥。。。运行时间为0.577665秒。优化的mex。。。运行时间为0.220025秒。
    #include "mex.h"
    #define sub2ind mxCalcSingleSubscript
    void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
    {
        const mxArray* X = prhs[0];
        const mxArray* Z = prhs[1];
        const mxArray* B = prhs[2];
        mxArray * out = mxDuplicateArray (Z);
        const int* pDims = mxGetDimensions(X);
    
        mwSize nsubs = mxGetNumberOfDimensions(X);
        double* B_arr = mxGetPr(B);
        for (size_t i = 0; i < pDims[0]; i++) {
            for (size_t j = 0; j < pDims[1]; j++) {
                for (size_t k = 0; k < pDims[2]; k++) {
                    int subs [] = {i, j, k};
                    mwIndex  idx = sub2ind(X, nsubs, subs);
                    mxArray* temp = mxGetCell(X, idx);
                    double* temp_arr = mxGetPr(temp);
    
                    const int* matDims = mxGetDimensions(temp);
                    mwSize nsubs_temp = mxGetNumberOfDimensions(temp);
                    for (size_t m = 0; m < matDims[0]; m++) {
                        int subs_out_1 [] = {m,0};
                        int subs_out_2 [] = {m,1};
                        mwIndex temp_m_1 = temp_arr[sub2ind(temp, nsubs_temp, subs_out_1)]-1;
                        mwIndex temp_m_2 = temp_arr[sub2ind(temp, nsubs_temp, subs_out_2)]-1;
                        double* Z_out = mxGetPr (mxGetCell(out,temp_m_1));
                        Z_out[temp_m_2] += B_arr[idx];
                    }
                }
            }
        }
        plhs[0] = out;
    }
    
    function Z = myFunction(X, Z, B)
        for k = 1:numel(X)
            for m = 1:size(X{k}, 1)
                Z{X{k}(m, 1)}(X{k}(m, 2)) = Z{X{k}(m, 1)}(X{k}(m, 2)) + B(k);
            end
        end
    end
    
    
    #include "mex.h"
    void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
    {
        const mxArray* X = prhs[0];
        const mxArray* Z = prhs[1];
        const mxArray* B = prhs[2];
        mxArray * out = mxDuplicateArray (Z);
    
        mwSize n_X = mxGetNumberOfElements(X);
        double* B_arr = mxGetPr(B);
        for (size_t k = 0; k < n_X; k++) {
            mxArray* temp = mxGetCell(X, k);
            double* temp_arr = mxGetPr(temp);
    
            const int* matDims = mxGetDimensions(temp);
            size_t rows = matDims[0];
            for (size_t m = 0; m < rows; m++) {
                mwIndex temp_m_1 = temp_arr[m]-1;
                mwIndex temp_m_2 = temp_arr[m+rows]-1;
                double* Z_out = mxGetPr (mxGetCell(out,temp_m_1));
                Z_out[temp_m_2] += B_arr[k];
            }
        }
        plhs[0] = out;
    }