覃釗
(河池市城市規劃測繪綜合技術服務中心,廣西河池 547000)
在測繪等科學研究和工程計算領域經常要運用到微分、線性代數等數學知識進行公式的推導,運用到大量的矩陣運算,過去人們耗費大量的時間來進行公式推導和編寫數學計算函數。MATLAB的出現使公式的微分、線性化等工作可以用軟件來進行,也提供了一般的高級編程語言都沒有的強大矩陣計算、數值分析等功能,把人們從低級的算法程序編寫及公式推導中解放出來。本文將研究如何用Visual Basic通過.Net調用MATLAB函數來提高軟件編寫的效率。
Visual Basic是一種由微軟公司開發的包含協助開發環境的事件驅動編程語言。從任何標準來說,VB都是世界上使用人數最多的編程語言——不僅是盛贊VB的開發者還是抱怨VB的開發者的數量。它源自于BASIC編程語言。Visual Basic擁有圖形用戶界面(GUI)和快速應用程序開發(RAD)系統,可以輕易地使用DAO、RDO、ADO連接數據庫,或者輕松創建ActiveX控件。程序員即使是初學者都可以輕松使用Visual Basic提供的組件快速建立一個應用程序,特別適合廣大工程技術人員用來開發本專業的應用軟件。Visual Basic 2011是微軟公司推出的Visual Basic最新版本,其功能比以前任何版本都強大,可與C++等語言相媲美。
MATLAB是由美國MathWorks公司發布的主要面對科學計算、可視化以及交互式程序設計的高科技計算環境。它將數值分析、矩陣計算、科學數據可視化以及非線性動態系統的建模和仿真等諸多強大功能集成在一個易于使用的視窗環境中,為科學研究、工程設計以及必須進行有效數值計算的眾多科學領域提供了一種全面的解決方案,并在很大程度上擺脫了傳統非交互式程序設計語言(如C、Fortran)的編輯模式,代表了當今國際科學計算軟件的先進水平。在MATLAB環境下,許多復雜的數學運算,如求矩陣的行列式值、求矩陣的逆及其特征值、求函數的微分、求函數的積分、進行多項式插值、解微分方程等,都有現成的函數可以調用。MATLAB的基本數據單位是矩陣,它的指令表達式與數學、工程中常用的形式十分相似,故用MATLAB來解算問題要比用C,FORTRAN等語言完成相同的事情簡捷得多。但是,很多時候僅僅依靠MATLAB環境還是不能很好地完成工作,MATLAB和其他程序之間的數據交換就顯得十分必要。MATLAB程序接口的出現,就解決了這些問題,通過接口與其他編程環境交互,各取所長,充分發揮 MATLAB計算的優點。MATLAB從R2006a開始,就開始用.NET接口逐漸取代了.COM接口。
.NET是微軟公司的一組軟件技術,核心部分是.NET Framework,最新版本為4.0,它提供CLR(公共語言運行庫)對各種程序的支持,通常將在CLR的控制下運行的代碼,稱為托管代碼(managed code),使用.NET開發的程序需要在.NET Framework下才能運行。通過使用Visual Studio.NET開發工具,可以使用多種語言開發,采用公共語言規范(CLS)后,編譯為中間語言,這種語言是專門針對公共語言的,和其他高級語言無關,因此,高級語言可以在這個層面上實現融合和互通。MATLAB Builder NE就是將M文件編譯為位于Basic Class Library同一層,實現了程序的運行。
為了將MATLAB中的程序作為組件提供給其他.NET程序使用,需要做兩方面的工作:首先是在MATLAB環境中將M文件打包編譯為.NET程序集,其次在外部程序中添加對程序集的引用。
在這里以一個平面坐標轉換四參數的計算為例子,四個參數分別是:平移參數x0,y0,旋轉參數θ,尺度參數m。
四參數坐標轉換函數模型為:

已知2個公共點(見表1):

公共點坐標表 表1
把2個公共點代入可得到4個方程,寫成矩陣形式:

系數陣 A為4×4方陣,可以直接求逆,因此V=A-1F。
V為各參數改正數矩陣,X為參數矩陣,X0為參數近似值矩陣。

上述公式中需要運用到矩陣的乘法、逆運算、加法。為了在Visual Basic中能直接進行矩陣運算,需要把MATLAB中的3個矩陣運算函數打包發行為.NET程序集。
在MATLAB環境下,把外部程序需要調用的函數保存為M文件,通過deploytool把數個M文件編譯為.NET程序集。
(1)建立M文件
點擊菜單File→New→Function M-File,建立新的函數型M文件,在編輯窗口出現下列函數原型:


這個函數是用于返回m*n階的所有元素為0的矩陣。然后把這個函數保存為NewWmarray.m文件,MATLAB的默認文件名就是函數名.m。逆運算、加法、乘法的M文件以此依次建立,下面是各個函數的代碼:

從這些函數我們可以看出,我們不需要知道這些矩陣運算是怎么進行的,也不需要寫太多的代碼就可以完成MATLAB的函數打包,省去了大量用于編寫函數的時間。
(2)編譯.NET程序集
①新建工程項目
在MATLAB命令窗口中輸入:

在出現的Deployment Tool工具中選擇新建工程項目將出現圖1所示對話框。

圖1 新建MATLAB.NET項目
選擇 MATLAB Builder NE→.NET Component,設置好項目名稱、保存位置,在這里把項目名稱設置為MatrixNet,然后按確定。
②為項目添加M文件
在Deployment Tool中把與項目名稱相同的類改名為Functions,并為該類添加我們事先準備好的M文件,如圖2所示。

圖2 Deployment Tool界面
M文件中的函數將作為Functions類的方法而存在。再點擊settings按鈕,在.NET選項里,把 Microsoft Framework設置為 default,Assmly Type設置為 private,如果開發的軟件需要通過網絡遠程連接的點選Enable.NET remoting,見圖3,最后按 OK。

圖3 .NET設置界面
③編譯
在Deployment Tool窗體中點擊Build the project按鈕進行編譯,編譯后的文件保存在項目目錄下的distrib子目錄中,共3個文件:項目名.dll(MATLABNet.dll),項目名 Native.dll(MATLABNetNative.dll),Readme.txt,若在圖 3 中勾選了 Enable .NET remoting了,還應包括2個文件:I項目名.dll(IMATLABNet.dll),I項目名 Native.dll(IMATLABNetNative.dll)。
④打包與發布
為了使編譯獲得的.NET程序集能在沒有安裝MATLAB軟件的計算機或服務器上運行,發布程序時需與MATLAB組件運行環境(MCR)一起打包,當然,如果已經安裝有MCR的計算機或本地計算機可以直接復制使用。MCR全稱是 MATLAB Compiler Runtime,是一個由MATLAB共享類庫構成的執行引擎,它能夠使MATLAB文件在沒有安裝MATLAB的機器上運行。在MATLAB中輸入命令“mcr”或者“mcrinstaller”后獲得下面信息:

第一行是說明當前MCR安裝程序為WIN64位,版本號為7.10,第二行為其保存路徑;第三、四、五行說明MCR其他平臺的安裝程序位置,可忽略;第六、七行為當前可用的MCR完整路徑。
在Deployment Tool窗體中點擊 settings..按鈕,在出現的工程項目設置窗體中選擇Packaging選項,勾選Include MATLAB Compiler Runtime(MCR),然后依次設置當前MCR保存路徑、打包后的安裝文件名,見圖4,最后OK按鈕,回到Deployment Tool窗體后,點擊Package the project按鈕,完成MATLAB工程項目的打包工作。

圖4 打包設置界面
把打包獲得的安裝程序復制到目標計算機上運行,設置好安裝路徑并安裝,即可完成MATLAB.NET程序集的發布。
(1)建立工程項目
啟動Micsoft Visual Studio后建立新建Visual Basic應用程序窗體程序,把項目名稱改為平面坐標轉換。把Form1窗體設置成圖5形式。

圖5 軟件運行界面
(2)Visual Basic調用MATLAB程序集
①添加引用
找到MCR安裝目錄和發布的程序集安裝目錄,分別添加引用 Mwarray.dll和 MatrixNet.dll,若是使用網絡連接的本地計算機,那么選擇IMwarray.dll和IMatrixNet.dll,另外還需要配置好服務器端,在這里就不加細述。
②導入命名空間
為應用程序添加一個模塊module1,并在該模塊的模塊代碼頭部添加下列代碼:

③MATLAB函數的調用
MatrixNet即我們引用打包編譯的MatrixNet.dll后獲得的命名空間,前面提到過M文件里面的函數將作為Functions類的方法存在,我們需要定義一個新的Functions類并經過初始化才能調用這些方法:

④Mwarray類型數組與MWNumericArray類型數組
MathWorks.MATLAB.NET.Arrays命名空間提供從其他任何兼容CLS(Common Language Specification)語言訪問MATLAB中數組的功能,這些類支持數組格式化、類型的特定索引和錯誤處理的功能。MATLAB函數的輸入參數和返回值都是Mwarray型數組,但是Visual Basic并不能操作這種類型的數組,故MATLAB又定義了一些中間類型數組,其中MWNumericArray類型數組是數值型數組,可以在Visual Basic中進行數值運算操作。例如在平面坐標轉換參數計算的系數矩陣A,它是一個4×4維的方陣,如果直接定義為Mwarray型,我們在實際中很難對它的維數進行定義和更改,也無法轉換成雙精度類型進行計算,因此我們定義它為MWNumericArray,但是這個 MWNumericArray類型數組又不是MATLAB函數的標準數組,也無法操作它的維數和元素。因此我們還是需要定義一個Mwarray類型的數組c(),然后通過前面定義了一個返回m×n階的零矩陣的mwarray矩陣進行初始化:c=MatrixLib.NewWmarray(1,4,4),然后把這個數組克隆給 A,A=c(0).Clone,A就變成4×4的零矩陣,也可以被MATLAB的函數所接受,最后c()矩陣不需要了,我們要把他釋放掉以節約空間:c(0).Dispose()。強調一點,不能直接這樣寫A=c(0),否則就是把數組A的地址指向了數組c(0)的地址,假若同時初始化幾個同樣的數組,這些數組都會指向同一個地址,那么這些數組其實就是同一個數組,其中一個數組改變,那么其他數組都改變,要避免出現這種情況。具體代碼如下:

這樣就可以完成一個4*4階的MWNumericArray矩陣的定義和初始化,且現在這個矩陣也能被MATLAB函數所接受。
⑤Form1窗體代碼



程序運行結果如圖5所示。
本文的編程環境為 Visual Studio 2010、MATLAB R2009a和.NET3.5,事實證明基于.NET的Visual Basic調用MATLAB函數脫離MATLAB運行環境的混合編程是可行的,在軟件開發中,開發人員不再需要耗費時間在編寫數值分析、矩陣計算、科學數據可視化等函數上,甚至也不需要了解很深的這方面的知識,把這一切都交給MATLAB去做,大大提高了程序編寫和科研學習的效率。由于本文主要研究如何進行混合編程,因此本文的坐標轉換參數的計算僅計算簡單的2個公共點的情況,若多于2個公共點,系數陣不能求逆,需要采用最小二乘法進行平差計算及殘差計算、剔除不合格公共點、精度評定等。另外MATLAB的符號運算能力也很強,在公式推導時可以加快推導速度,但是在這里由于篇幅有限就不多加敘述。
[1]孔祥元,郭際明,劉宗泉.大地測量學基礎[M].武漢:武漢大學出版社,2001.
[2]武漢測繪科技大學測量平差研究室.測量平差基礎[M].武漢:武漢大學出版社,1996.
[3]楊永健.基于.NET平臺的MATLAB應用程序集成研究[J].軟件導刊,2009.
[4]董維國.深入淺出MATLAB7.X混合編程[M].北京:機械工業出版社,2005.
[5]洪一新,吳燦銘.Visual Basic 2008程序設計完全自學教程[M].北京:清華大學出版社,2009.
[6]馬莉.MATLAB語言實用教程[M].北京:清華大學出版社,2010.