[心得] 用 Matlab 寫 MEX 函數加速 vol.5
這一篇是我和朋友討論怎麼處理 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
05/19 15:00, 1F
※ 編輯: lihgong 來自: 140.113.236.184 (05/20 17:10)
MATLAB 近期熱門文章
PTT數位生活區 即時熱門文章