[心得] 用 Matlab 寫 MEX 函數加速 vol.5

看板MATLAB作者 (人生,是一句引用句)時間17年前 (2007/05/19 14:55), 編輯推噓1(100)
留言1則, 1人參與, 最新討論串1/1
這一篇是我和朋友討論怎麼處理 3-dimension 的輸入 弄了一陣子, 我們討論出一個滿好用的 MACRO 可以把 (x, y, z) 轉成 array 的 index TWO_D_INDEX(dim_x, dim_y, x, y) THREE_D_INDEX(dim_x, dim_y, dim_z, x, y, z) 舉例來說, 有個 Matrix A 大小是 3x6 如果 A(3, 5) = 6 因為 C 語言的index從 0 開始, (3, 5) 轉到 C 語言變成 (2, 4) 把(2, 4) 轉成 data-array 的 index, 可以套用 TWO_D_INDEX() 這個 macro TWO_D_INDEX(3, 6, 2, 4) dim_x dim_y x y 把 MACRO 裡的運算看懂, 並且實際驗證 之後就不用煩惱這些麻煩的 index 轉換了 ---- 另外這一篇 note 還有一個主題, 是取出 mxArray 裡的 dimension 資訊 mxArray 裡有兩個欄位, 分別記錄有幾個 dimension, 以及每個 dimension 的大小 轉成程式碼, 就是類似下面的操作... // Input dimension processing input_num_of_dimensions = mxGetNumberOfDimensions(prhs[0]); input_dim = mxGetDimensions(prhs[0]); // print dimension information printf("Number of dimensions of the input: %d\n", input_num_of_dimensions); for(i=0; i<input_num_of_dimensions; i++) printf("Length of dimension #%d is %d\n", i+1, input_dim[i]); 為什麼要取出 dimension 的資料? 因為要把 (x, y, z) 轉成 data-Array index 時, 需要這些資料 所以這一小段程式碼是必要的 ---- 最後是範例程式在做什麼 程式的輸入是一個 3-D matrix 印出 (desired_index_x, desired_index_y, desired_index_z) int desired_index_x = 32 -1; int desired_index_y = 3 -1; int desired_index_z = 160 -1; 每個數都減 1 的理由是 C 的 index 從 0 開始 餵給這個函數的輸入也有特別設計, 如下 for i=1:32 for j=1:3 for k=1:16384 input(i, j, k) = i + j*1000 + k*1000*1000; end end end zzzzyyyyxxxx index-x index-y index-z ---- #include "mex.h" #include <math.h> #include <stdio.h> // Program test for input // usage: /* * MATLAB code clear all; input = zeros(32, 3, 16384); for i=1:32 for j=1:3 for k=1:16384 input(i, j, k) = i + j*1000 + k*1000*1000; end end end */ // mex test4.c // test4(input) // note: type all commands above in Matlab Command Window #define TWO_D_INDEX(d_x, d_y, x, y) (x + y*d_x) #define THREE_D_INDEX(d_x, d_y, d_z, x, y, z) (x + y*d_x + z*d_x*d_y) void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { int i, j, k; // input int input_num_of_dimensions; int *input_dim; double *in; // pointer to process content of the input int input_dim_x; int input_dim_y; int input_dim_z; int desired_index_x = 32 -1; int desired_index_y = 3 -1; int desired_index_z = 160 -1; int index_desired; /* -------------------------------- */ /* NECESSARY: dimension & data pointer for input */ in = mxGetPr(prhs[0]); // get data pointer // Input dimension processing input_num_of_dimensions = mxGetNumberOfDimensions(prhs[0]); input_dim = mxGetDimensions(prhs[0]); // print dimension information printf("Number of dimensions of the input: %d\n", input_num_of_dimensions); for(i=0; i<input_num_of_dimensions; i++) printf("Length of dimension #%d is %d\n", i+1, input_dim[i]); // specify the length of dimension x, y, and z input_dim_x = input_dim[0]; input_dim_y = input_dim[1]; input_dim_z = input_dim[2]; /* -------------------------------- */ index_desired = THREE_D_INDEX( input_dim_x, input_dim_y, input_dim_z, desired_index_x, desired_index_y, desired_index_z); printf("%f\n", in[index_desired]); } -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.113.236.184

05/19 15:00, , 1F
順帶一提...matlab有內建指令ind2sub及sub2ind
05/19 15:00, 1F
※ 編輯: lihgong 來自: 140.113.236.184 (05/20 17:10)
文章代碼(AID): #16JfzYzh (MATLAB)
文章代碼(AID): #16JfzYzh (MATLAB)