Download presentation
Presentation is loading. Please wait.
1
MATLAB 程式設計入門篇 MATLAB 編譯器
張智星 清大資工系 多媒體檢索實驗室
2
14-1 MATLAB編譯器簡介 MATLAB編譯器具有下列功能: 產生獨立應用程式(Stand-alone Applications)
產生C或C++的程式庫: 含動態程式庫(Dynamically Linked Libraries,簡稱DLL,用於微軟視窗系統)或共享程式庫(Shared Libraries,用於UNIX/LINUX系統) 可用於任何外部應用程式
3
14-1 MATLAB編譯器簡介 軟體元件: 例如 Java 類別庫(Java Classes)、Excel 增益程式(Excel Add-ins)、COM 及 .NET 物件等,這些軟體元件的產生 需要使用 MATLAB Builder
4
14-1 MATLAB編譯器簡介 進入範例說明前,必須先設定電腦上的C編譯器,以便用於MATLAB編譯器,方法如下述
在MATLAB命令視窗下輸入「mbuild -setup」,系統回應如下: Please choose your compiler for building standalone MATLAB applications: Would you like mbuild to locate installed compilers [y]/n?
5
14-1 MATLAB編譯器簡介 輸入「y」之後,按下 Enter,系統回應如下:
這些C編譯器是MATLAB在你的電腦自動偵測出來的結果(所以在不同的電腦會得到不同的結果) Select a compiler: [1] Lcc C version in C:\PROGRAM FILES\MATLAB\R2006A\sys\lcc [2] Microsoft Visual C/C++ version 8.0 in C:\Program Files\Microsoft Visual Studio 8 [3] Microsoft Visual C/C++ version 6.0 in C:\PROGRA~1\MIAF9D~1 [0] None Compiler:
6
提示 若在上述過程中,出現錯誤訊息,你可以先進行「mex -setup」,再進行「mbuild -setup」,可能就可以解決你的問題。
7
14-2 產生獨立應用程式 若要MATLAB編譯器將一個MATLAB函式編譯成獨立應用程式,所使用的指令是 mcc,格式如下
mcc –m userFunc.m 先撰寫一個 MATLAB 函式myEigValue.m 範例14-1:myEigValue/myEigValue.m function eigValue = myEigValue(mat) %myEigValue: Generate the eigenvalues of the given matrix if (isstr(mat)) % 若輸入是字串,轉成數值 mat=eval(mat); end [a, b] = eig(mat); eigValue=diag(b); disp(eigValue); % 顯示固有值 eigenValue
8
14-2 產生獨立應用程式 測試此範例,可以在MATLAB命令視窗輸入: 即可在螢幕顯示一個 5X5 的魔術方陣所對應的固有值
myEigValue(magic(5)); 即可在螢幕顯示一個 5X5 的魔術方陣所對應的固有值
9
提示 在將此MATLAB函式編譯成為可執行檔的過程中,會產生一些額外檔案,所以你必須將本範例由光碟拷貝至硬碟,才能進行以下的操作。
10
14-2 產生獨立應用程式 將 myEigValue.m 轉換成 myEigValue.exe,有一些細節要特別小心:
myEigValue.exe 將使用命列列參數的方式來得到輸入方陣,所以 myEigValue.m 必須先使用 eval 將輸入字串轉為方陣。 myEigValue.m 必須使用 disp 結果印在螢幕上,以方便 myEigValue.exe 來印出同樣的結果。
11
14-2 產生獨立應用程式 接著,我們在MATLAB命令視窗下,將工作目錄改變至 myEigValue.m 所在的目錄
然後使用下列命令來將 myEigValue.m 編譯成 myEigValue.exe,如下: mcc –m myEigValue.m 經過半分鐘的時間,就會完成編譯,並產生數個檔案,包含 一個可執行檔 myEigValue.exe 若要測試此可執行檔,可以直接在 DOS 命令視窗下輸入: myEigValue.exe magic(5)
12
14-2 產生獨立應用程式 即可在螢幕顯示一個 5X5 的魔術方陣所對應的固有值
若要輸入一個特定的方陣,可以使用類雙引號來包住代表方陣的字串,範例如下: myEigValue.exe "[1 2 3; 3 2 1; 1 1 1]"
13
提示 在第一次執行 myEigValue.exe時,會產生myEigValue_mcr 目錄,以便使用MATLAB的程式庫,所以花的時間會比較久一點。之後再執行 myEigValue.exe,就會直接取用速度就會變快了。
14
14-2 產生獨立應用程式 使用 mcc 時,還有幾點要注意: 如果你的 MATLAB 函式有呼叫任何你自己定義的函式,要一併放進來編譯。
如果只是要產生C程式碼,而不產生可執行檔,可以使用「mcc –mc myEigValue.m」 (c 代表只產生 C 語言的包裝程式檔案)。 如果要檢視MATLAB編譯器在編譯時所產生的訊息,可以使用「mcc –mv myEigValue.m」(v 代表 verbose)。 如果你的函式沒有用到繪圖功能,可以使用「mcc –m –R –nojvm myFunc.m」,以減小所產生的檔案大小。
15
14-2 產生獨立應用程式 若要將編譯後所產生的可執行檔案搬到其他電腦上執行,必須將下列檔案放在一起,才能順利執行:
myEigValue.exe myEigValue.ctf myEigValue.ctf 用來記錄各種資訊,讓myEigValue.exe在第一次執行時,可以產生myEigValue_mcr目錄 mcr代表MATLAB Compiler Runtime,用來存放myEigValue.exe會取用到的MATLAB程式庫
16
14-3 產生共享資料庫 使用MATLAB編譯器可以產生共享程式庫(Shared Libraries),包含所有由使用者定義的函式,以便讓其他獨立應用程式來呼叫。 產生一個共享程式庫。首先先定義這兩個 MATLAB 函式 範例14-2:sharedLibrary/myMatMultiply.m function out = myMatMultiply(mat1, mat2) %myMatEig: Generate the product of two given matrices out=mat1*mat2;
17
14-3 產生共享資料庫 接著將這兩個 MATLAB 函式編譯成共享程式庫,程式庫名稱為 matLib,所使用的指令如下
範例14-3:sharedLibrary/myMatInv.m 接著將這兩個 MATLAB 函式編譯成共享程式庫,程式庫名稱為 matLib,所使用的指令如下 mcc -B csharedlib:matLib myMatInv.m myMatMultiply.m 此時會在工作目錄下產生數個檔案,主檔名都是 matLib,這些檔案即是 matLib 程式庫 function invMat = myMatInv(mat) %myMatInv: Generate the inverse matrix of the given matrix invMat=inv(mat);
18
14-3 產生共享資料庫 可以使用一般獨立應用程式來呼叫這個程式庫內所定義的函式。
程式庫是由兩個 MATLAB 函式編譯所得,因此我們可以得到兩個對應的C函式,分別是 mlfMyMatInv 及 mlfMyMatMultiply,對應關係如下: out=myMatInv(in) mlfMyMatInv(1, &out, in); out=myMatMultiply(in1, in2) mlfMyMatMultiply(1, &out, in1, in2);
19
14-3 產生共享資料庫 使用 matLib 程式庫來呼叫這兩個C函式的獨立應用程式範例如下 範例10-4:myMatLibMain.c
/*=================================================== * 此範例程式可以呼叫 MATLAB 編譯器所產生的程式庫 matLib * Roger Jang, *==================================================*/ #include <stdio.h> #include "matLib.h" /* 顯示C資料型態為 mxArray 的雙倍精準陣列 */ void matDisplay(const mxArray* in){
20
14-3 產生共享資料庫 int i, j; int rowNum = mxGetM(in); /* 橫列個數 */
int colNum = mxGetN(in); /* 直行個數 */ double *data = mxGetPr(in); /* 指到輸入陣列中的雙倍精準資料 */ /* 印出資料 */ for(i=0; i<colNum; i++){ for(j=0; j<rowNum; j++) printf("%4.2f\t", data[j*colNum+i]); printf("\n"); } /* 主要工作函式 */ void *mainFunction(int *errorCode){
21
14-3 產生共享資料庫 mxArray *in1, *in2; /* 定義送到程式庫函式的輸入矩陣 */
mxArray *out = NULL; /* 定義程式庫函式的輸出矩陣 */ double data[] = {1, 3, 5, 2, 4, 6, 0, 8, 9}; /* 測試用的資料 */ /*確認此應用程式已經被正確地啟始 */ if(!mclInitializeApplication(NULL, 0)){ fprintf(stderr, "錯誤:無法啟始應用程式!\n"); *errorCode=-1; return; } /*確認程式庫matLib已經被正確地啟始 */ if (!matLibInitialize()){ fprintf(stderr,"錯誤:無法啟始程式庫!\n"); *errorCode=-2;
22
14-3 產生共享資料庫 } /* 創造輸入矩陣 */ in1 = mxCreateDoubleMatrix(3, 3, mxREAL);
/* 將 data 中的資料拷貝至 in1 */ memcpy(mxGetPr(in1), data, 9*sizeof(double)); /* 將 data 中的資料拷貝至 in2 */ memcpy(mxGetPr(in2), data, 9*sizeof(double)); /* 呼叫由 MATLAB 編譯器產生的程式庫 matLib 中的函式 */ /* 計算矩陣相乘 */ mlfMyMatMultiply(1, &out, in1, in2); printf("矩陣相乘的結果:\n"); matDisplay(out); mxDestroyArray(out); out=NULL; /* 收回配置給 out 的記憶體 */
23
14-3 產生共享資料庫 /* 計算反矩陣 */ mlfMyMatInv(1, &out, in1);
printf("計算反矩陣的結果:\n"); matDisplay(out); mxDestroyArray(out); out=NULL; /* 收回配置給 out 的記憶體 */ /* 收回配置給 in1 和 in2 的記憶體 */ mxDestroyArray(in1); in1=NULL; mxDestroyArray(in2); in2=NULL; /* 呼叫 matLibTerminate() 以終止應用程式庫 */ matLibTerminate(); /* 呼叫 mclTerminateApplication() 以終止此應用程式 */ mclTerminateApplication(); }
24
14-3 產生共享資料庫 若要編譯此獨立程式,可在 MATLAB 命令視窗輸入如下:
/* 主程式 */ int main(){ int errorCode=0; mainFunction(&errorCode); return(errorCode); } 若要編譯此獨立程式,可在 MATLAB 命令視窗輸入如下: mbuild myMatLibMain.c matLib.lib 此時即可產生獨立應用程式 myMatLibMain.exe,只要在 DOS 命令視窗下輸入「myMatLibMain」,即可看到此程式碼執行的結果。
Similar presentations