2016-03-29 68 views
0

我有一個MATLAB代碼是如何表示MATLAB在MEX代碼的2D陣列

%% 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,:)]; 

爲了加快代碼,我想用C++在MEX文件中重寫它。在2D陣列MATLAB和C++之間的主要不同是行優先順序(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]); 
    } 
} 

是我的墨西哥代碼和MATLAB等效代碼?如果不是,你能幫我解決嗎?

+3

它不是'行+行* N',是嗎?如果我正確理解你的代碼,你必須有一個列循環,並將行數乘以列索引。它應該像'alpha [N * rows + col]'其中'col'是第二個內部循環的計數器...... – kkuilla

+0

如何表示h和h_tmp?這是對的嗎。我現在將更正它,並再次檢查 – Jame

+0

此外,第二個for循環中的條件絕不能是'rows

回答

0

除了評論對您的問題的更正之外,還有一點不同之處。缺少的是你在Matlab代碼中跳過h(N,:),在代碼中的C代碼迭代完成,直到cols < N(其由於C中的0索引)也將處理每列中的最後一個元素。

#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)是'h [N * rows + cols]'= h(cols,rows)後面的雙重存儲的1個存儲器塊(64位) 。這是除了位於h(N,:) ='h(N * rows + N)'上的元素之外的所有元素所需要的,因爲h(N + 1,:)沒有意義。在C語言中,它仍然是有效的語法,但正如我的回答中所述,並不能給出預期的結果。 –