Presentation is loading. Please wait.

Presentation is loading. Please wait.

張智星 jang@cs.nthu.edu.tw http://www.cs.nthu.edu.tw/~jang 清大資工系 多媒體檢索實驗室 MATLAB 程式設計進階篇 應用程式介面 張智星 jang@cs.nthu.edu.tw http://www.cs.nthu.edu.tw/~jang 清大資工系.

Similar presentations


Presentation on theme: "張智星 jang@cs.nthu.edu.tw http://www.cs.nthu.edu.tw/~jang 清大資工系 多媒體檢索實驗室 MATLAB 程式設計進階篇 應用程式介面 張智星 jang@cs.nthu.edu.tw http://www.cs.nthu.edu.tw/~jang 清大資工系."— Presentation transcript:

1 張智星 jang@cs.nthu.edu.tw http://www.cs.nthu.edu.tw/~jang 清大資工系 多媒體檢索實驗室
MATLAB 程式設計進階篇 應用程式介面 張智星 清大資工系 多媒體檢索實驗室

2 3-1 MATLAB應用程式介面 應用程式介面 Application Program Interface 簡稱API
和外部程式或其它程式語言溝通

3 API 的功能 只要遵循 API 規範,可做到下列事項: 從 MATLAB 呼叫 C 語言或 Fortran 語言撰寫的函數
將 MATLAB 當成計算引擎(Computing Engine),並從獨立的 C 或 Fortran 程式呼叫此 MATLAB 引擎,進行各種運算或圖形顯示 以獨立的C或Fortran程式讀寫MATLAB專用的MAT檔 在視窗環境,進行ActiveX Automation,即將 MATLAB視為ActiveX Automation Server,讓其它應用程式(Excel 或 Access等)呼叫,或將MATLAB視為 ActiveX Automation Controller,呼叫視窗下其它應用程式 在微軟視窗環境下,經由 DDE(Dynamic Data Exchange)來和其它應用程式溝通並傳送資料

4 3-2 撰寫能讓MATLAB呼叫的 C 函數:前置測試
撰寫C函數讓 MATLAB 呼叫的原因 MATLAB 程式碼執行效率不佳,希望以 C 程式碼改進。常發生在MATLAB的 JIT 加速器無法加速您的程式碼,或是您的演算法無法改成向量化的程式碼。 隱藏程式碼,保護智慧財產權。C 的原始碼編譯後,變成二進位碼, MATLAB 能夠呼叫,而使用者無法看到原始程式碼 不想將已寫好的 C 程式碼改寫成 MATLAB 程式碼,而希望在 MATLAB 的環境下呼叫這些 C 程式碼 進行其它只有在 C 程式能做到的事

5 只能在 C 程式下完成的工作 更改呼叫端之工作空間的變數
產生常駐記憶體(Persistent Memory),即產生在函數結束後,仍能讓其它函數或 MATLAB 存取的資料結構或變數 串接埠(Serial Port)資料的傳送和接收 Device Drivers 等

6 提示 使用 pcode 指令 優點: 可將一般 M 檔案轉換成二進制檔案 達到隱藏原始程式碼的功能 缺點: 無法大幅提高程式碼的執行效率

7 開始前置測試 (I) 選擇 C 編譯器編譯完成的 C 函數 在 MATLAB 指令視窗內輸入 mex -setup

8 開始前置測試 (II) 選擇已安裝在電腦上的 C 編譯器

9 開始前置測試 (III) 按下 「Enter」 鍵,會出現畫面

10 提示 lcc 執行「mex -setup」 是Public-domain 的 C 程式編譯器
MATLAB 5.x,是隨 Stateflow Toolbox 而來, MATLAB 6.x,是隨 MATLAB 而來。 執行「mex -setup」 MATLAB 5.x 會跳出 DOS 視窗, MATLAB 6.x 不會跳出 DOS 視窗, 都在 MATLAB 命令視窗完成 其內容則與 DOS 視窗的內容大同小異

11 開始前置測試 (IV) 選用 微軟公司的 Visual C/C++,輸入「1」後,再按「Enter」鍵 最後,再按「Enter」鍵確認即可

12 無安裝C編譯器 若 DOS 視窗無顯示可供選擇的 C 編譯器 電腦尚未安裝 C 編譯器 先安裝 C 編譯器才能進行下一步的測試
例如:Microsoft Visual C/C++、Watcom C/C++、Borland C 等

13 開始前置測試 (V) 完成選擇 C 編譯器的程序,可以測試 C 程式編譯 MATLAB 有一現成的 C 程式碼 yprime.c,其位置在
{MATLAB root}\extern\examples\mex\yprime.c 測試之前,須將此檔案拷貝至目前目錄,才可進行測試 >> cd D:\matlabBook\MATLAB程式設計:進階篇\03-應用程式介面 >> copyfile([matlabroot, '\extern\examples\mex\yprime.c']) 若執行 copyfile 指令時產生錯誤訊息,通常表示目前目錄下已經有 yprime.c 檔案

14 開始前置測試 (VI) 在 MATLAB 指令視窗,輸入下列敘述來編譯此 C 程式
>> mex yprime.c MATLAB 即呼叫 Visual C/C++(先前選的 C 編譯器)編譯 yprime.c,並產生編譯的訊息 若無錯誤訊息,編譯完成後,C 編譯器會產生 yprime.dll 或 yprime.mexw32 可執行檔 此即為 MATLAB 可呼叫的 C 函數,所在的位置可顯示如下 >> which yprime D:\matlabBook\MATLAB程式設計:進階篇\03-應用程式介面\yprime.mexw32

15 提示 在 MATLAB 7.1 之前,所產生的檔案是 yprime.dll,但從 MATLAB 7.1(含)之後,所產生的檔案是 yprime.mexw32。

16 開始前置測試 (VII) 測試yprime執行 MEX 檔案 MATLAB 可呼叫的可執行檔通稱
ans = MEX 檔案 MATLAB 可呼叫的可執行檔通稱 在其它電腦平台上,大部份以 mex 為此可執行檔副檔名的一部份

17 整理:MEX檔案的副檔名 平台 MEX 檔案的副檔名 Sun OS 4. x mex4 HP 9000/series 700 mexhp7
Alpha mexds SGI mexsg SGI 64 mexsg64 IBM RS/6000 mexrs6 Linux (32-bit) mexglx Linux x86-64 mexa64 64-bit Solaris SPARC mexs64 Microsoft Windows (32-bit) dll(MATLAB7.1前),mexwin32(MATLAB 7.1或更新) Microsoft Windows (64-bit) dll(MATLAB7.1前),mexwin64(MATLAB 7.1或更新) Macintosh (PPC) mexmac Macintosh (Intel) mexmaci

18 3-3 MATLAB的資料結構 及對應API MATLAB 變數的資料結構 MATLAB 內部只有一種資料型態 宣告成 mxArray
是一個 C 語言下的結構(Structure)

19 mxArray的Structure MATLAB 對應的變數名稱 維度 資料型態 實數或複數 是否為稀疏矩陣(Sparse Matrix)

20 變數的實部和虛部 變數的實部和虛部 欲取得這兩個指標 在每個 mxArray 結構,包含兩個指標(Pointers) pr 及 pi
分別指到這個變數的實部和虛部 兩者都是資料型態為 double 的一維陣列 欲取得這兩個指標 用 MATLAB 提供的 API 函數 mxGetPr 及 mxGetPi 取得 可存取某個 MATLAB 變數內的所有數值

21 MATLAB 提供的API函數 - mx mx 為字頭的 API 函數 MATLAB 變數資料(型態為 mxArray)的存取
mxGetPr(傳回實部指標) mxGetPi(傳回虛部指標) mxGetM(取得矩陣的橫列維度) mxGetN(取得矩陣的直行維度) mxCreateDoubleMatrix(產生變數型態為 double 的矩陣)

22 MATLAB 提供的API函數 - mex mex 為字頭的 API 函數 MATLAB 環境下執行的動作
mexErrMsgTxt(在 MATLAB 印出錯誤訊息,並跳出 MEX 檔案) mexCallMATLAB(呼叫 MATLAB 引擎以執行 MATLAB 之數值運算) mexPrintf(在 MATLAB 印出訊息)

23 MATLAB 提供的API函數 - mat mat 為字頭的 API 函數 對 MAT 檔案的讀寫或處理
matGetArray(從 MAT 檔案讀取 mxArray 陣列) matDeleteArray(從 MAT 檔案移除 mxArray 陣列)

24 3-4一個最簡單的 MEX 檔案 將一個輸入純量(資料型態為 double)乘以 2 此程式碼已內建在 MATLAB 光碟中
{MATLAB root}\extern\examples\refbook\timestwo.c 範例3-1:scalarx2.c 有timestwo.c詳細的中文註解,並改名為 scalarx2.c

25 簡單MEX檔案範例 (I) 在 MATLAB 中,呼叫 C 編譯器對 scalarx2.c 進行編譯 編譯完後,確認可執行檔是否存在
>> mex scalarx2.c 編譯完後,確認可執行檔是否存在 >> which scalarx2 D:\matlabBook\MATLAB程式設計:進階篇\03-應用程式介面\scalarx2.dll

26 簡單MEX檔案範例 (II) 進行各項測試 >> scalarx2(8.5) ans = 17
>> scalarx2('String input') ??? Input must be a scalar. >> scalarx2([1 2 3])

27 MEX檔案的說明 (I) 同時有 scalarx2.m 及scalarx2.mexw32 存在於同一目錄下
MATLAB 選用 scalarx2.mexw32 檔來執行 若輸入「help scalarx2」 MATLAB會列出 scalarx2.m 的線上輔助說明 有關 scalarx2.mexw32 的線上輔助說明,就必須置於 scalarx2.m 之內

28 MEX檔案的說明 (II) >> type scalarx2.m function out = scalarx2(in)
% SCALARX2 A scalar version of "times two". % This serves as an example of putting on-line help in an % M-file, but the actual program body is in another MEX-file % with the same major file name. >> help scalarx2 SCALARX2 A scalar version of "times two". This serves as an example of putting on-line help in an M-file, but the actual program body is in another MEX-file with the same major file name. >> which scalarx2 D:\matlabBook\MATLAB程式設計:進階篇\03-應用程式介面\scalarx2.mexw32

29 3-5 處理二維矩陣的 MEX 檔案範例 將輸入二維矩陣(可能包含實部和虛部)乘以2 編譯程式 確認可執行檔的存在
範例3-2:arrayx2.c 編譯程式 >> mex arrayx2.c 確認可執行檔的存在 >> which arrayx2 D:\matlabBook\MATLAB程式設計:進階篇\03-應用程式介面\yprime.mexw32

30 二維矩陣範例-1 進行測試 >> arrayx2([1 2 3]) ans = 2 4 6
>> arrayx2([1+i 2+2i 3+3i; 4 5 6]) i i i >> arrayx2('Test string') ??? Input must be a double.

31 二維矩陣範例-2 (I) 兩個輸入矩陣 A 和 B 矩陣旳大小分別是 p×m 及 p×n 傳回一個距離矩陣 C
分別代表由 m 個直行向量及 n 個直行向量所形成的集合每一個向量的長度都是 p 傳回一個距離矩陣 C C(i, j)為向量 A(:, i) 和向量 B(:, j) 的矩離

32 提示 大量資料的處理 一般的慣例都是將各個向量以直行向量的方式堆成一個矩陣,再進行各種處理

33 二維矩陣範例-2 (II) 範例3-3:pairdist.c 編譯程式 >> mex pairdist.c

34 二維矩陣範例-2 (III) 測試程式 >> which pairdist
D:\matlabBook\MATLAB程式設計:進階篇\03-應用程式介面\pairdist.dll >> pairdist([2 3], [2 3 4]) ans =

35 二維矩陣範例-2 (IV) >> A = rand(2, 3); >> B = rand(2, 4);
>> C = pairdist(A, B) C = >> pairdist('string1', 'string2') ??? Input 1 is not a full numerical array!

36 3-6 產生基本工作空間變數的 MEX 檔案範例 將輸入矩陣乘以 2 之後,存放成 MATLAB 基本工作空間中的一個變數 測試程式
範例3-4:putarray.c 測試程式 >> clear all >> mex putarray.c >> putarray([1 2 5]) "putarray_output" is created in the base workspace. >> whos Name Size Bytes Class putarray_output x double array Grand total is 3 elements using 24 bytes

37 檢視變數 putarray_output由putarray所置放在 MATLAB基本工作空間的變數,可以檢視 這個範例可能的應用
這個範例可能的應用 從 RS232 埠讀取 GPS 傳回的資料,將資料進行處理後送入MATLAB 的基本工作空間,MATLAB 再根據此工作空間的變數進行即時的圖形繪製或成像 從影像擷取卡抓取影像資像,送入 MATLAB 的基本工作空間,MATLAB 再根據此資料進行即時計算,例如人臉辨識或指紋辨識等

38 3-7 對於結構陣列的處理 MATLAB 也提供比較複雜的資料結構,例如結構陣列、異質陣列等
可以撰寫C程式碼,來和MATLAB內部的結構陣列進行資料的交換和計算。 範例3-5:matlabStruct2c.c

39 結構陣列範例1 –(I) 測試程式 範例3-5:matlabStruct2c01.m mex matlabStruct2c.c
x(1).name = '林政源'; x(1).phone = 2796; x(2).name = '陳江村'; x(2).phone = 3425; x(3).name = '張永森'; x(3).phone = 3213; matlabStruct2c(x)

40 結構陣列範例1 –(II) 結果 由 MATLAB 印出來的訊息,事實上已經是 C 程式碼的結構陣列的欄位值。
friend[0].name = 林政源 friend[0].phone = friend[1].name = 陳江村 friend[1].phone = friend[2].name = 張永森 friend[2].phone = 由 MATLAB 印出來的訊息,事實上已經是 C 程式碼的結構陣列的欄位值。

41 結構陣列範例2 將 C 的結構陣列,送到 MATLAB 工作空間的結構陣列 測試程式 範例3-7:cStruct2matlab.c
範例3-8:cStruct2matlab01.m 1x3 struct array with fields: name phone MATLAB 在工作空間的結構陣列 x 即是由 C 的結構陣列轉換出來的結果。 mex cStruct2matlab.c x = cStruct2matlab

42 3-8從獨立的 C 程式來呼叫MATLAB 引擎 可由獨立的 C 程式呼叫 MATLAB 引擎
Ex: 使用 MATLAB 的數學功能,例如計算反矩陣、行列式、最小平方解、奇異值分解(Singlar Value Decomposition)等 使用 MATLAB 的圖形顯示功能,例如二維及三維圖形、動畫等

43 提示 欲將獨立的 MATLAB 視窗應用程式轉換成單獨的可執行檔
Standalone Executable 不需安裝MATLAB就可運作的 .exe 檔案 需MATLAB 5.x 和 6.x 的「Runtime Server」工具箱 將 MATLAB 視窗應用程式轉成 .exe 檔案,包含所有的圖形顯示功能 讓沒有安裝 MATLAB 的人使用 MATLAB 7.x,「Runtime Server」工具箱已不存在,功能已搬到「MATLAB Compiler」工具箱

44 C 呼叫 MATLAB 範例 (I) C 程式碼裡面啟動 MATLAB 並執行一個 M 檔案 plotSine.m,同時秀出執行 whos 指令後的訊息,C 的範例程式碼是 plotViaMatlab01.c。 在 MATLAB 輸入命令編譯此 C 程式碼 範例3-9:matlabEngine01.m optsFile = [matlabroot '\bin\win32\mexopts\msvc60engmatopts.bat']; mex('-f', optsFile, 'plotViaMatlab01.c'); % 進行編譯 !plotViaMatlab01 % 測試程式

45 C 呼叫 MATLAB 範例 (II) 若一切無誤,將產生plotViaMatlab01.exe 執行此程式碼後 啟動另一個 MATLAB
執行 plotSine.m 畫出右列圖形

46 C 呼叫 MATLAB 範例 (III) 同時跳出一個訊息視窗,以顯示 MATLAB 在執行 whos 指令後 的輸出訊息
同時工作列也會顯示一個 MATLAB 的圖示,代表 MATLAB engine 正在執行中。當你按下訊息視窗的「確定」後,MATLAB engine 也就跟著結束。

47 C 呼叫 MATLAB 的重點 (I) 首先產生一 MATLAB Engine的物件,經由這個物件啟動 MATLAB 及和 MATLAB 溝通,經由下列程式碼完成 Engine *ep=engOpen(NULL);

48 C 呼叫 MATLAB 的重點 (II) 再來假設欲呼叫的MATLAB程式plotSine.m 與呼叫的C程式在同一目錄,將 MATLAB 切換到此目錄 將此程式所在目錄存入字串 buffer:_getcwd(buffer, BUFSIZE ); 產生 MATLAB 內部字串變數 app:app = mxCreateString(buffer); 將字串變數 app 置入工作空間變數 appDir:engPutVariable(ep, "appDir", app); 將 MATLAB 的工作目錄切換至字串 appDir 所指定的目錄 engEvalString(ep, "cd(appDir)");

49 C 呼叫 MATLAB 的重點 (III) 最後就將我們想要呼叫的 MATLAB 程式 plotSine.m 傳入執行,即可大功告成:engEvalString(ep, "plotSine");

50 C 呼叫 MATLAB 的重點 (IV) 接著我們要顯示 MATLAB 在執行 whos 之後所得到的輸出訊息
設定 buffer 可以接收 MATLAB 的輸出訊息: engOutputBuffer(ep, buffer, BUFSIZE); 在 MATLAB engine 執行 whos 指令: engEvalString(ep, "whos"); 顯示 buffer 的內容: MessageBox ((HWND)NULL, (LPSTR)buffer, (LPSTR) "MATLAB - whos", MB_OK); 最後關閉 MATLAB engine: engClose(ep);

51 如果發生編譯錯誤 可能是你所使用的編譯器不是 MSVC6.0,此時要將編譯參數檔 optsFile 改成適合你所用的編譯器,常用的編譯參數檔案可以顯示如下: 範例3-11:showOptsFile.m bcc53engmatopts.bat df50engmatopts.bat msvc70engmatopts.bat bcc54engmatopts.bat df60engmatopts.bat msvc71engmatopts.bat bcc55engmatopts.bat intelc71engmatopts.bat openwatc13engmatopts.bat bcc55freeengmatopts.bat lccengmatopts.bat wat11engmatopts.bat bcc56engmatopts.bat msvc50engmatopts.bat watengmatopts.bat bccengmatopts.bat msvc60engmatopts.bat 編譯參數檔案名稱都符合 *engmatopts.bat 的格式,根據你使用的編譯器,就可以找到相關的編譯參數檔。 dir([matlabroot '\bin\win32\mexopts\*engmatopts.bat'])

52 C 呼叫 MATLAB 的重點 (IV) 在 C 程式碼內反覆將 MATLAB 命令送到 MATLAB 執行,而不用呼叫一個外部的 M 檔案。 範例3-12:matlabEngine02.m optsFile = [matlabroot '\bin\win32\mexopts\msvc60engmatopts.bat']; mex('-f', optsFile, 'plotViaMatlab02.c'); % 進行編譯 !plotViaMatlab % 測試程式

53 C 呼叫 MATLAB 的重點 (V) 執行 plotViaMatlab02.exe 之後,可以畫出「自由落體的距離與時間關係圖」, 如右。
在 plotViaMatlab02.c 程式碼中,因為我們沒有使用「engClose(ep);」來關閉 MATLAB engine,所以最後必須手動來關閉 MATLAB engine。

54 最後 有關更進一步如何使用 C 呼叫 MATLAB 引擎,可查閱 MATLAB Help中的 External Interfaces/API 章節「Calling MATLAB from C and Fortran Programs」,有更詳細的介紹。


Download ppt "張智星 jang@cs.nthu.edu.tw http://www.cs.nthu.edu.tw/~jang 清大資工系 多媒體檢索實驗室 MATLAB 程式設計進階篇 應用程式介面 張智星 jang@cs.nthu.edu.tw http://www.cs.nthu.edu.tw/~jang 清大資工系."

Similar presentations


Ads by Google