2016-03-29 5 views
0

У меня есть код MATLAB, которыйКак представлять 2D массив MATLAB в MEX код

%% Inputs are theta and h (size NxM) 
alpha=zeros(N,M); 
h_tmp=zeros(N,M); 
h_tmp(1:N-1,:)=h(2:N ,:); 
for i=1:N 
    alpha(i,:)=theta.*(h_tmp(i,:)+h(i,:)); 
end 

Используя векторизованную метод, приведенный выше код может быть

alpha = theta .* [h(1:N-1,:) + h(2:N,:); h(N,:)]; 

Чтобы ускорить код , Я хочу переписать его в файле MEX с помощью C++. Основной отличается от MATLAB и C++ в 2D массива строк крупный заказ (MATLAB) и столбца крупный заказ (C++)

double *h, *alpha, *h_temp; 
int N,M; 
double theta;  
N  = (int) mxGetN(prhs[0]); //cols 
M  = (int) mxGetM(prhs[0]); //rows 
h  = (double *)mxGetData(prhs[0]); 
theta = (double)*mxGetPr(prhs[1]); 
/* Initial zeros matrix*/ 
plhs[0] = mxCreateDoubleMatrix(M, N, mxREAL); alpha = mxGetPr(plhs[0]); 
//////////////Compute alpha/////////  
for (int rows=0; rows < M; rows++) { 
    //h[N*rows+cols] is h_tmp 
    for (int cols=0; cols < N; cols++) {   
     alpha[N*rows+cols]=theta*(h[N*rows+cols+1]+h[N*rows+cols]); 
    } 
} 

ли мой Mex код и MATLAB код эквивалент? Если нет, можете ли вы помочь мне исправить это?

+3

Это не 'строки + строки * N', не так ли? Вы должны иметь цикл столбца и умножать количество строк с индексом столбца, если я правильно понимаю ваш код. Это должно быть что-то вроде 'alpha [N * rows + col]' где 'col' является счетчиком для второго внутреннего цикла ... – kkuilla

+0

Как насчет представления h и h_tmp? Правильно ли. Я исправлю это сейчас и снова проведу проверку. – Jame

+0

Далее условие во втором цикле для обработки НЕ ДОЛЖНО быть 'rows

ответ

0

Кроме исправлений из комментариев к вашему вопросу, есть одно незначительное отличие. Отсутствует то, что вы пропускаете h(N,:) в коде Matlab, где в итерации кода C над кодом выполняется до cols < N, который (из-за индексации 0 на C) также обрабатывает последний элемент в каждом столбце.

#include "mex.h" 
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { 
    double *h, *alpha, *h_temp; 
    int num_columns, num_rows; 
    double theta;  
    num_columns = (int) mxGetN(prhs[0]); //cols 
    num_rows = (int) mxGetM(prhs[0]); //rows 
    h   = (double *)mxGetData(prhs[0]); 
    theta  = (double)*mxGetPr(prhs[1]); 
    /* Initial zeros matrix*/ 
    plhs[0] = mxCreateDoubleMatrix(num_rows, num_columns, mxREAL); alpha = mxGetPr(plhs[0]); 
    //////////////Compute alpha///////// 
    // there are num_rows many elements in each column 
    // and num_columns many rows. Matlab stores column first. 
    // h[0] ... h[num_rows-1] == h(:,1) 
    int idx; // to help make code cleaner 
    for (int column_idx=0; column_idx < num_columns; column_idx++) { 
     //iterate over each column 
     for (int row_idx=0; row_idx < num_rows-1; row_idx++) {// exclude h(end,row_idx) 
      //for each row in a column do 
      idx = num_columns * column_idx + row_idx; 
      alpha[idx]= theta * (h[idx+1] + h[idx]); 
     } 
    } 
    //the last column wasn't modified and set to 0 upon initialization. 
    //set it now 
    for(int rows = 0; rows < num_rows; rows++) { 
     alpha[num_columns*rows+(num_rows-1)] = theta * h[num_columns*rows+(num_rows-1)]; 
    } 
} 

Обратите внимание, что я решил переименовать некоторые из переменных, так что, я думаю, это становится легче читать.

Редактировать: Убрано предложение с prhs[0] = plhs[0], как предложено в комментариях к этому ответу. Это может обойтись при определенных обстоятельствах, но в целом это не очень хорошая практика при кодировании функции matlab .mex, и это может привести к сбою Matlab.

+1

@ user8430, который предназначен. Я не выделяю никакого пространства для 'plhs' и не создаю указатель с именем' alpha'. Я перезаписываю то, что когда-либо хранилось в 'h', итерации над' h'. Таким образом, он сохраняет выделение другой матрицы и с этим временем вычисления. Далее 'h' и' alpha' будут указывать на один и тот же фрагмент памяти. Это может быть или не быть подходящим для вашего приложения, но является одним из способов оптимизации прошлых возможностей компилятора Matlab. –

+0

Итак, вы уверены, что h (2: N, :) эквивалентно h [N * rows + cols + 1]? – Jame

+0

@ user8430 Нет, они не эквивалентны.'h [N * rows + cols + 1]' = h (cols + 1, rows) - это двойной сохраненный 1 блок памяти (64 бит) позади 'h [N * rows + cols]' = h (cols, rows) , Это то, что вы хотите для всех элементов, кроме элементов, расположенных в h (N, :) = 'h (N * rows + N)', потому что h (N + 1, :) не имеет смысла. В C, однако, это все еще действительный синтаксис, но, как описано в моем ответе, не дает желаемого результата. –

Смежные вопросы