發表文章

目前顯示的是有「Matlab」標籤的文章

文章總列表

用 Matlab 寫 MEX 函數加速 vol.6

這篇不講程式, 只說個奇怪的 bug 大部分的EDA-tool, 都是老外寫的 他們沒有處理中文檔名的問題 所以這些tool碰到中文路徑, 中文檔名, 掛掉是很正常的 不信的話 讓modelsim吃個 "加法器.vhd" 試試看就知道了 ---- 很不巧, Matlab 內建的 C-complier: lcc 也有這個問題 在我研究 MEX function 時 我第一個問題就是程式編譯不過 他會在最後 linking 的時候, 告訴我 link error 原因是 linker 要吃一個在 C:\document ... \ user-name\ ooxx.pl 之類的 剛好我的 user-name 是 QQ毛 中文字啊 話說這個問題 整整耗了我兩個鐘頭找原因 Orz ---- 所以我建議, 在開始寫程式之前 先來個空白測試吧, 這個測試必須非常非常簡單, 越無腦越好 我個人認為 Hello World 是個不錯的選擇 XD 先把工作環境測試好 :) ---- 另外, 還是 lcc 的一個 bug 就是程式碼裡的註解, 也不可以有 中文註解 喔 不只是 lcc 我碰到過一些 EDA-tool 都有這樣的問題 大家以後碰到軟體不能執行 找半天找不出原因 先回過頭懷疑中文環境 也許會有意想不到的發現 XD -- 科科...

用 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-...

用 Matlab 寫 MEX 函數加速 vol.4

最後一篇, 這篇會提出一個簡單的 MEX file 的 Framework 廢話不多說, 直接看 example, 程式碼才是最好的說明書 這個 example 實際上是 vol.2 和 vol.3 的合體 如果前面的程式都看懂了, 這個程式應該不會有任何困難 建議把 code 複製到 Matlab 的 Editor 來看, 比較不會傷眼睛 :p 範例程式接受一個 2-D 的 input, 把每個元素 +1 以後輸出 output = input + 1; 在程式碼裡, 我把程式區分了很多塊 以一個標準的 MEX 檔來說, 大概會有這幾個部分 * 取得輸入參數的資料 (eg. dimension) * 配置輸出參數 (Output Allocation) * 根據輸入, 計算輸出 (Data Processing) 把下面的程式看懂, 碰到要寫 MEX 的時候 直接套下面這個範例, 應該可以省不少時間 :) #include "mex.h" #include <math.h> #include <stdio.h> // Program framework for input, output and processing // usage: // input = zeros(2, 10) // input(1, :) = 1:10 // input(2, :) = 10:-1:1 // mex test3.c // a = test3(input) // note: type all commands above in Matlab Command Window void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { int i, j, k; // input int input_dim_x; int input_dim_y; double *in; // pointer to process content of the input // output int output_dimensi...

用 Matlab 寫 MEX 函數加速 vol.3

上一篇在講怎麼處理 output 這一篇我們來看看怎麼處理 input 圍繞著整個主題, C-style 和 Fortran-style 之間的轉換 是看懂這些程式的關鍵 outline * 辨識有多少個輸入變數 * 讀取輸入變數的內容 ---- 直接從一個 example 開始吧 #include "mex.h" #include #include void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { printf("%d\n", nrhs); } 把檔案取名為 test_input.c 編譯 mex test_input.c 並且執行以下指令, 觀察結果 test_input(1) test_input(1, 2, 3) test_input(1, 2, 3, 4, 6) 這個做完以後, 應該可以看出 nrhs 這個變數的意義 先用這個簡單的例子當做開場 ---- 接下來, 設計一組簡單的輸入... input = zeros(2, 5) input(1, :) = 1:5 input(2, :) = 5:-1:1 如此 input = [ 1 2 3 4 5 5 4 3 2 1] 我想設計一個 MEX-function 讀取並印出第一個 row, 其次是第二個 row 注意在下面的程式裡 mxGetM() 取得 Matrix 有幾個 row mxGetN() 取得 Matrix 有幾個 column 程式不困難, 有任何問題打 helpwin 配上 search 函數名稱打進去都看得到使用說明 ---- #include "mex.h" #include #include // Program test for input // usage: // input = zeros(2, 10) // input(1, :) = 1:10 // input(2, :) = 10:-1:1 // mex test2.c // test2(input) // note: type all commands above in Matlab Comm...

用 Matlab 寫 MEX 函數加速 vol.2

在繼續走下去之前, 先打開 Matlab, 輸入 helpwin 關於這個主題, Matlab 提供的說明在... Contents/ MATLAB/ External Interfaces/ Calling C and Fortran Programs from MATLAB Creating C Language MEX-Files 上述兩個章節跟這個主題的關係很密切 Matlab的 help 寫得相當好 有問題都可以在這找到答案, 不用可惜啊 ---- MEX 函數的用途, 是用 C 語言加速 Matlab 函數 既然是函數, 就會有輸入, 輸出 這一篇針對輸出介面做說明 輸出, 顧名思義, 函數丟出的東西 Matlab語言允許函數有多個輸出, 例如 [a, b] = myfun(c, d, e) 這個例子裡有三個輸入, 兩個輸出 ---- 傳統上, C語言的 main() 的輸入變數的數目一開始無法確定 所以用了類似下面這種語法... int main(int argc, char *argv[]) int argc 告訴 main(), 有幾個參數丟進來 char *argv[] 則是指向一張參數表, programmer 可以透過 argv[] 存取每個參數 ---- 回過頭來看 mex function 的 prototype void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) nlhs -> Number of Left-Hand-Side (input) plhs -> Parameter of Left-Hand-Side (input) nrhs -> Number of Right-Hand-Side (output) prhs -> Parameter of Right-Hand-Side (output) 這種寫法, 是不是和上面的 main() 基本上一模一樣 藉由這種作法, 我們可以讓 MEX function 有多個輸出入數值 如此一來, 就可以對應到 Matlab 的指令 [a, b] = myfun(c, d, e) 在這個...

用 Matlab 寫 MEX 函數加速 vol.1

在 Matlab 的 Command Window 輸入 mex -setup 選擇用 lcc 這個 compiler 據說也可以用其他的編譯器 有興趣的人自己試試 ---- 來寫第一個程式吧, 我認可的範例必須要非常簡單 這個範例只用來測試 compiler 是不是可以正常工作 Hello World 顯然正是我要的 #include #include"mex.h" void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { printf("Hello, world.\n"); } 把這個程式存成 hello.c 在 Command Window 輸入 mex hello.c hello 正確的話, 應該會看到 Hello, world. 如此表示 mex 編譯的環境設置成功 ---- 大致說明一下上面的程式 首先一定要 #include "mex.h" 其次是函數名稱必須是 mexFunction() 並且他的傳入值必須是上面那樣 不知道為什麼沒關係, 先照抄 後面會說明