科學計算與視覺化之二(Matlab C/C++函式庫) (轉)
1 引言
1984年美國的Mathworks公司推出Matlab,到目前為止,它已發展成為國際上最優秀的科技應用之一。其強大的科學計算與視覺化功能,簡單易用的開放式可擴充套件環境以及多達30多個面向不同領域而擴充套件的工具箱(Toolbox)支援,使得Matlab在許多學科領域中成為輔助設計與分析、演算法研究和應用開發的基本工具和首選平臺。但是由於其採用偽編譯的方式,在Matlab中編寫的無法脫離其工作環境而獨立執行。針對這個問題,Mathworks公司為Matlab提供了應用程式介面,允許Matlab和其它應用程式進行資料,並且提供了C/C++數學和圖形庫,為在其它語言Matlab高效演算法提供了可能。
C++語言是新一代的以面向()概念為根本的高階程式設計語言,它的物件導向的概念更加符合程式設計師開發軟體的思維習慣,類封裝性和模組化的構造非常適合軟體的移植和維護,使用C++開發有助於提高軟體工程的質量。VC++是美國公司利用C++的底層機理開發的新一代編譯器,與其它一些C++編譯器相同,都是以C++語言為編譯物件。VC++在編譯速度和程式碼方面,是同類產品的佼佼者,並且絕大多數的包都提供了對它的介面,這是VC++得到程式設計師認可的主要原因。對於理工科研究生和一些偏重於數值計算的工程技術人員,為了能夠較好的在短期之內完成一個兼具友善介面和穩定的計算核心的程式,利用軟體介面技術,可以藉助於第三方的函式庫。
2 Matlab應用程式介面
MATLAB提供的應用程式介面按目的一般來說可以分為以下三種:1.利用其它應用程式的優點,例如計算速度快和使用已有演算法而制定的介面;2.建立MATLAB與其它應用程式間的資料交換;3.拓廣MATLAB的應用範圍和應用手段。開發的相應應用程式為MEX、MAT檔案和MATLAB引擎應用程式。其中MEX檔案作為一種動態連結庫檔案,必須透過在MATLAB的工作環境內呼叫才能執行;MAT檔案用於資料交換,不能利用MATLAB提供的功能來完成計算任務;MATLAB引擎應用程式是一種可以獨立的應用程式,但在應用程式執行時,將在後臺啟動一個MATLAB程式,用於接收從應用程式傳送來的指令並執行,然後按照要求返回計算結果。綜上,基於MATLAB應用程式介面開發的應用程式並不完善,這種應用程式的執行不能脫離MATLAB環境。
3 VC++呼叫Matlab數學和圖形庫
6.1版本的Matlab軟體包中提供了C/C++的數學和圖形庫,透過其編譯器支援可以將Matlab中編寫的m檔案轉換成以C/C++程式碼的檔案,而且可以將m檔案生成dll庫,甚至我們可以直接呼叫其中的庫函式,生成併發布不必依賴Matlab的可執行檔案。透過mcc編譯器生成C/C++程式碼,進而可以在VC或者其它編譯器生成可獨立執行的應用程式,具體流程見下圖:
:namespace prefix = v ns = "urn:schemas--com:vml" />
圖 1
下面具體討論如何利用Matlab編譯器從m檔案生成C/C++程式碼,並嵌入程式碼,生成執行時不需Matlab支援的應用程式。設matsum.m檔案,內容如下:
function sum = matbs( a, b )
% sum
sum = a + b
用mcc命令轉換為C/C++程式碼,命令列引數如下
生成C檔案
mcc -t -L C matsum.m
生成C++檔案
mcc -t -L Cpp matsum.m
生成動態連結庫函式
mcc -t -W lib:sum -T link:lib matsum.m
注意①lib:後跟生成的庫檔名不能和原m檔名相同(此處為sum),②此處只能生成C語言方式的動態連結庫。該編譯命令共生成9個檔案,其中sum.lib和sum.dll是可以在C/C++應用程式中呼叫的動態連結庫檔案。
對生成的C++檔案進行分析,不難發現編譯器根據m檔案中的函式,生成一個對應的C++函式:static mwArray Mmatsum(int nargout_, mwArray a, mwArray b);並分別根據C++和Mex檔案的介面方式生成兩種形式的介面函式:extern mwArray matsum(mwArray a = mwArray::DIN, mwArray b = mwArray::DIN);和void mlxMatsum(int nlhs, mxArray * plhs[], int nrhs, mxArray * prhs[]);另外還有區域性函式表宣告/editor/Editor.htm#_ftn1" name=_ftnref1>1。
下面我們在VC++的環境下進行程式設計,為了論述方便首先生成一個基於C++的簡單控制檯應用程式,然後在專案中將用mcc命令生成的matsum.cpp和matsum.hpp包含到專案(project)中,如果該專案含有預編譯標頭檔案StdAfx.h,那麼在matsum.cpp所有包含檔案之首加入#include “StdAfx.h”。然後開啟Project/Setting…選單,在C/C++的Category中選Preprocessor,在預定義(Preprocessor definitions)欄加入MSVC,MSWIND,__STDC__,其中__STDC__可選,在C++專案中可省;選Code Generation,在執行時庫(Use run-time library)欄選擇Multithreaded DLL。在Link的/Library modules中新增庫檔案libmatlb.lib,libmx.lib,libmatpm.lib,當然對於使用圖形函式的程式必須使用相應的庫。
修改選項參考表一,一般在Code Generation中選擇Multithreaded DLL。
使用Static還是DLL工程
是否使用多執行緒庫?
是否使用C庫
使用的C連結庫存
Static
否
否
libc.lib
Static
否
是
libcd.lib
Static
是
否
libcmt.lib
Static
是
是
libcmtd.lib
DLL
否
否
msvcrt.lib(msvcrt.dll)
DLL
否
是
msvcrtd.lib(msvcrtd.dll)
DLL
是
否
msvcrt.lib(mvcrt.dll)
DLL
是
是
msvcrtd.lib(msvcrtd.dll)
表一
例程如下:
#include "stdafx.h"
// #include "matlab.hpp" //C++方式
#include "matsum.hpp"
#pragma comment (lib, "libmatlb.lib")
#pragma comment (lib, "libmx.lib")
#pragma comment (lib, "libmatpm.lib") // c++ maths library
int main(int argc, char* argv[])
{
mwArray a(100),b(250);
mwArray c;
c=matsum(a,b);
return 0;
}
我們可以用動態連結庫的方式呼叫m檔案中的函式,從前面看到的編譯命令,共生成包括sum.lib和sum.dll在內的9個檔案,複製lib和dll檔案到專案中。按以下格式呼叫:sumInitialize(); // 初始化mlfMatsum(); // 對應於Matsum …… sumTenate(); // 釋放 注意:sum.h中的函式的引數和返回值大多為矩陣結構mxArry形式。因為是C語言方式,不詳細論述,例程如下:
{
mxArray *ax, *bx, *cx;
sumInitialize();
// ax=mxCreateDoubleMatrix(1,1,mxREAL);
// bx=mxCreateDoubleMatrix(1,1,mxREAL);
mlfAssign(&ax,mlfScalar(200)); // C語言矩陣結構賦值
mlfAssign(&bx,mlfScalar(522));
cx=mlfMatsum(ax,bx);
// mlfPrintMatrix(cx);
sumTerminate();
}
4 VC++環境下的Matlab開發
從上面的轉換可以看出,利用Matlab編譯器命令生成的C/C++檔案,實際上其函式的輸入輸出引數為mwArray物件。那麼可以考慮直接在VC++或其它C++編譯器中利用Matlab的庫函式來完成簡單計算任務。
Matlab C/C++數學函式庫中最基本的資料型別為矩陣物件,即mwArray類物件,幾乎所有的庫函式均以它們作為計算和處理的物件,掌握mwArray物件的操作,對於學習Matlab C/C++數學庫的使用是至關重要的。
Matlab C/C++數學庫透過類mwArray對數值矩陣、稀疏矩陣、字元矩陣、單元矩陣和結構體矩陣提供了支援,矩陣物件的建立如下:
mwArray A; // 構造一個空矩陣物件
mwArray A(double/int); // 數子的矩陣物件
mwArray A(int row, int col, double/int/unsigned short *real=NULL,
double/int/unsigned short *image=NULL)
mwArray A(const mwArray&) // 複製構造矩陣物件
C/C++呼叫Matlab函式將大量使用矩陣物件的操作,完成C/C++資料到mwArray物件的賦值和mwArray物件到C/C++資料的檢索。Matlab C/C++函式庫提供ExtractScalar和ExtractData兩個函式完成索引操作。另外用GetDate()和mxGetPr、mxGetPi組合可以得到指向mwArray物件的資料的指標。
在VC++環境中呼叫Matlab數學函式庫,還要注意異常的處理。Matlab定義一組以mwException為基類的異常類。異常處理如下:
try{
……
}
catch(mwException){
mwDisplayException(ex);
……
}
5 提供簡單算例
在計算機圖形學中關於曲線、曲面進行插值或擬合,將大量使用求解線性方程組。如在求B樣條曲線插值問題中,要先進行反求控制頂點,然後根據B樣條基求出進行插值,我們利用VC來完成介面,利用IMSL提供的數學函式完成計算。
例題:已知型值點序列Pi,i=0,1,2…,7:
P[0]
P[1]
P[2]
P[3]
P[4]
P[5]
P[6]
P[7]
Abscissae x
8.125
8.400
9.000
9.485
9.600
9.959
10.166
10.200
Ordinates y
0.0774
0.099
0.28
0.6
0.708
1.20
1.80
2.177
表二
求控制頂點序列。
反求B楊條曲線控制頂點的數學問題是:
在VC中呼叫Matlab C/C++函式庫,利用矩陣的左除,可以的反求Deboor控制頂點的座標值,函式如下:
void resDeboorpt(int n, double *ppxs, point *pt, point *deboor)
{
assert(pt!=deboor&&pt!=0&&deboor!=0);
// assign point data
double *ppt=new double[n*2];
for(int i=0;i { *(ppt+i)=pt[i].x; *(ppt+i+n)=pt[i].y; } mwArray xzpt(n,2,ppt); // assign coefficient matrix mwArray xsjz(n,n,ppxs); mwArray kzdjz; try { // compute deboor point matrix kzdjz=mldivide(xsjz,6*xzpt); } catch(mwException ex) { mwDisplayException(ex); } delete []ppa; delete []ppt; for(i=0;i { deboor[i].x=kzdjz.ExtractScalar(i+1); deboor[i].y=kzdjz.ExtractScalar(i+n+1); } } 計算結果 Di, i=0,1,…,9 D[0]=D[1] D[2] D[3] D[4] D[5] D[6] P[7] D[8]=D[9] Abscissae x 8.08523 8.32384 9.01941 9.59854 9.49644 10.0157 10.1948 10.201 Ordinates y 0.07852 0.07183 0.22819 0.69544 0.59008 1.19226 1.84088 2.24422 表三 Matlab C/C++函式庫中的宣告方式是extern的,在外部引用庫函式時無需另外宣告。由於Matlab C/C++庫函式採用動態連結庫的方式,所以在釋出自己的應用程式時必須包括相應的應用程式擴充套件檔案。具體方法如下:執行%MATLAB% externlibmglinstaller.exe,所生成的*.dll 包括bin and toolbox打包即可。注意在執行機上設定路徑。 6 小結 參考文獻3.
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-992682/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 基於MATLAB C/C++數學函式庫開發應用程式 (轉)MatlabC++函式
- Matlab學習-視覺化和程式設計Matlab視覺化程式設計
- L1 複數與複數運算 | matlab視覺化Matlab視覺化
- Shader 函式視覺化函式視覺化
- 科學計算與Matlab筆記:第3章:Matlab程式流程控制Matlab筆記
- 科學計算與Matlab筆記:第2章:Matlab矩陣處理Matlab筆記矩陣
- NumPy科學計算庫
- 計算機視覺與深度學習公司計算機視覺深度學習
- C++的函式和模板函式 (轉)C++函式
- 科學計算器學生時代小作品原始碼(C++版)原始碼C++
- C++中的虛擬函式與虛擬函式表 (轉)C++函式
- c++虛擬函式實現計算表示式子C++函式
- 混沌 IN C++::轉換函式C++函式
- C/C++與Matlab混合程式設計初探C++Matlab程式設計
- 【機器視覺與影象處理】基於MATLAB的角度計算視覺Matlab
- C++“視窗”程式設計啟蒙(之二)C++程式設計
- C++中函式指標與函式物件C++函式指標物件
- C與C++函式的不同特性C++函式
- 《C++ Primer》學習筆記(六):C++模組設計——函式C++筆記函式
- 科學視覺化軟體系列文章視覺化
- Matlab資料視覺化Matlab視覺化
- C++虛擬函式與多型實戰 (轉)C++函式多型
- C++初學解惑(4)——建構函式(上) (轉)C++函式
- 透過例子學習Lua(7)--呼叫C/C++函式(轉)C++函式
- 【C/C++】計時函式比較C++函式
- c++ operator typename 轉換函式C++函式
- matlab符號函式的求導與差分的計算Matlab符號函式求導
- C/C++多引數函式引數的計算順序與壓棧順序C++函式
- c++ for_each()與仿函式C++函式
- c++函式學習總結C++函式
- fill函式與memset函式的區別(c++)函式C++
- C++程式設計思想筆記之二 (轉)C++程式設計筆記
- Effective C++:類與函式的設計和申明C++函式
- 收集的Java科學計算庫Java
- C++函式C++函式
- 【C++】函式C++函式
- 高質量C++/C程式設計指南(第9章 類的建構函式、解構函式與賦值函式) (轉)C++C程式程式設計函式賦值
- C++ lambda 表示式與「函式物件」(functor)C++函式物件