做者 Lemniscatejava
這個是我寫的一篇關於MATLAB課程的做業,做業已提交。因此,ChenGuangda老師看到了請不要覺得個人做業是從網上抄的,哈哈。程序員
MATLAB做爲一款功能強大、效率高、交互性好的可視化高級計算機語言,在數值計算、自動控制、數字信號處理、圖形處理、仿真、神經網絡、小波分析等各個領域有着普遍的應用。雖然MATLAB是一個徹底獨立的編程和數據運算的集成環境使用它能夠很方便地作不少工做,可是,不少時候僅僅依靠MATLAB環境仍是不能很好地完成工做,例如一個大的項目中須要使用到MATLAB中很容易實現並且頗有些的功能時,若是這個時候使用特定語言開發,將會是一個費時費力的事情,並且穩定性、效率方面都不如MATLAB好;或者,其餘語言編寫的優秀程序,若是想在MATLAB中使用,就要重寫M文件,形成了人力和物力的浪費,因此MATLAB和其餘程序之間的數據交換就顯得十分必要,MATLAB程序接口的出現,就解決了這些問題,經過接口與其餘編程環境交互,各取所長,充分發揮MATLAB計算的優勢,而避開MATLAB效率低的問題。web
MATLAB提供了多種編程語言的接口,經過微軟的組建對象模型(Component Object Model,COM)完成外部程序、客戶端和服務端之間的通信和數據共享,這些功能的實現都是使用了MATLAB的應用程序接口(Application Program Interface,API)來實現的。算法
下圖是MATLAB提供的接口。編程
由上節可見MATLAB的編程接口是至關豐富的,這裏就.NET方式討論,使用.NET的接口有以下幾個優勢:數組
代碼安全。做爲託管代碼,不會出現指針帶來的問題,這就保證了程序的穩定性安全
容錯機制。C#中具備異常處理方法,所以即便程序在運行中出現了錯誤,也能從故障中快速恢復,或者提供較好的擺脫異常的方法,而不是像其餘程序那樣形成程序崩潰。服務器
面向對象。經過將函數打包爲一個類的方法,實現了完整的面向對象編程,方便了代碼的閱讀和管理,並可以實現面向對象中的重載、繼承、多態等功能。網絡
.NET的定義,根據微軟官方的描述:架構
.NET is a "revolutionary new platform, built on open Internet protocols and standards, with tools and services that meld computing and communications in new ways"。.NET 是微軟公司的一組軟件技術,用來鏈接信息、人、系統和各類設備。它經過使用 Web Services 技術來得到軟件的高度集成。除了將小型的、分散的、構建模塊應用互相鏈接起來,還將 Internet 上的更大應用鏈接起來。微軟總裁兼首席執行官Steve Ballmer把它定義爲:.NET表明一個集合,一個環境,一個能夠做爲平臺支持下一代Internet的可編程結構。
.NET的核心部分是.NET Framework,這是一組框架,是.NET的核心支持庫,.NET Framework提供CLR(公共語言運行時)提供了對各類程序的支持,一般將在CLR的控制下運行的代碼,稱爲託管代碼(managed code)。使用.NET開發的程序須要在.NET Framework下才能運行,就像VB的程序須要VB運行庫,java程序須要JVM(Java虛擬機)同樣。下圖是.NET Framework的架構:
首先須要明白的是,NET Framework只是一個平臺,並非一種具體的編程語言,實際開發過程當中須要有一種具體的語言和對應的工具,根據微軟的構想,在推出.NET架構的同時,仍是推出了一款專門針對該平臺的語言——C#,該語言是純粹面向對象的,並能最大化地釋放.NET平臺的優點,實現了軟件的安全、快速開發。另外,根據上圖可知,使用的開發工具是Visual Studio.NET,微軟旗艦級的開發工具Visual Studio也升級到了2010版,該開發工具是一套可視化的編程環境,其強大的功能,如自動代碼、智能感知、錯誤高亮、代碼重構等功能,使程序開發起來事半功倍。
如前面所說,混合編程有一個很顯著的問題,就是最終的程序以何種方式實現。這涉及到了兩種實現方。首先,能夠將.NET程序在MATLAB中運行,這個時候MATLAB是宿主程序,而.NET程序以一種插件的方式存在,共享MATLAB的內存空間;另外一種方式是將NATLAB程序編譯爲託管代碼,而後在C#的程序中調用,這個時候就脫離了MATLAB的環境,能夠造成獨立的軟件。
這種方式是以MATLAB爲主程序,.NET程序以插件的方式爲MATLAB調用,該方法對MATLAB的要求很簡單,基本不須要作任何改動。事實上MATLAB自然的提供了對.NET程序的支持。
經過使用這種方式,能夠實現:1..NET中類的實例。2.經過使用類成員操做.NET程序。固然,這種方法和通常的面向對象仍是有一些侷限性,例如不能訪問子類,不能將.NET對象保存到MAT文件中,也不能使用控制檯輸入、輸出等。
事實上,使用這種方式開發的人員,更多的是.NET程序員,他們無需關心MATLAB是如何實現的,也用不着和MATLAB打交道,只須要在編程中可以將本身的接口暴露給MATLAB便可,固然了電腦上必須安裝.NET Framework才能實現。
下面是一個簡單的例子:
例如在MATLAB的命令窗口中輸入:
>> dt=System.DateTime(2011,5,11)
運行結果爲:
dt =
System.DateTime
Package: System
Properties:
Date: [1x1 System.DateTime]
Day: 11
DayOfWeek: [1x1 System.DayOfWeek]
DayOfYear: 131
Hour: 0
Kind: [1x1 System.DateTimeKind]
Millisecond: 0
Minute: 0
Month: 5
Now: [1x1 System.DateTime]
UtcNow: [1x1 System.DateTime]
Second: 0
Ticks: 634406688000000000
TimeOfDay: [1x1 System.TimeSpan]
Today: [1x1 System.DateTime]
Year: 2011
MinValue: [1x1 System.DateTime]
MaxValue: [1x1 System.DateTime]
Methods, Superclasses
爲何是這個結果?首先,MATLAB在啓動的時候會自動加載程序集System.dll(另外一個是mscorlib.dll),該程序集是.NET中很是重要的文件之一,提供了基本類型、數學計算等功能。而DateTime就是其中的一個結構體,該結構體主要用於描述時間。使用該結構體建立了一個實例dt,而後調用的構造函數是DateTime(year,month,day),MATLAB顯示關於該實例的基本信息,並在最後還提供顯示該結構體方法和超類的連接。
若是再輸入:
>> dt.Year
則顯示:
ans =
2011
這裏就訪問了.NET代碼中的屬性。事實上,MATLAB提供了專門的函數查看託管類的屬性和方法。
例如輸入:
>> properties System.DateTime
和
>> methods System.DateTime
就能夠查看一個結構體或者類支持的方法和屬性。
雖然.NET提供了大量的類和方法,可是並不能知足實際工做中的須要,有時須要本身開發一些自定義的類,使用Visual Studio.NET將會很輕鬆地實現開發。
在VS中新建一個類庫的項目,在Class1.cs中輸入以下內容:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
namespace ToMATLAB
{
public class XDClass
{
//這是一個不帶返回值的方法
public void Message()
{
MessageBox.Show("Here is Dot Net~");
}
//這是一個屬性
public string Help
{
get
{
return "I am a Property of Class XDClass";
}
}
//這是一個帶返回值的方法,利用海倫公式計算三角形面積
public double TriangleArea(double a,double b,double c)
{
double max = a;
if (max < b) max = b;
if (max < c) max = c;
if (2 * max >= a + b + c)
return -1;//不構成三角形
else
{
double p = (a + b + c) / 2;
return Math.Sqrt(p * (p - a) * (p - b) * (p - c));
}
}
}
}
而後按F6編譯生成一個名爲ToMATLAB.dll文件,該文件就是被MATLAB加載的.NET程序集。而後在MATLAB的Command Window中輸入:
>> asmInfo = NET.addAssembly('C:\Users\Castor\Desktop\ToMATLAB.dll')
效果以下:
asmInfo =
NET.Assembly handle
Package: NET
Properties for class NET.Assembly:
AssemblyHandle
Classes
Structures
Enums
GenericTypes
Interfaces
Delegates
NET.addAssembly函數加載一個.NET的程序集,即編譯生成的動態連接庫文件,加載完成後能夠經過Properties函數或者methods函數查看其屬性和方法。運行以下:
>> properties ToMATLAB.XDClass
Properties for class ToMATLAB.XDClass:
Help
>> methods ToMATLAB.XDClass
Methods for class ToMATLAB.XDClass:
Equals Message XDClass eq ge le notify
GetHashCode ToString addlistener findobj gt lt
GetType TriangleArea delete findprop isvalid ne
可見MATLAB可以識別咱們編寫的方法和屬性,下面測試一下屬性和方法:
>> xd=ToMATLAB.XDClass()
xd =
ToMATLAB.XDClass handle
Package: ToMATLAB
Properties:
Help: [1x1 System.String]
Methods, Events, Superclasses
>> xd.Help
ans =
I am a Property of Class XDClass
>> xd.Message
>> xd.Message
xd.Message
>> xd.TriangleArea(3,4,5)
ans =
6
>> xd.TriangleArea(3,4,1)
ans =
-1
當運行到Message的時候,會出現一個對話框:
這是使用了.NET中的MessageBox.Show方法的緣由,另外要注意的是,該對話框是有模式的對話框,這個時候編譯器會掛起,雖然在Command Window下能夠輸入命令,可是卻不能被編譯器解釋,這是模式對話框的一個顯著特色。最後調用了xd實例的方法,利用海倫公式計算一個三角形的面積,當提供的三個參數不能構成三角形的時候,計算結果爲-1,其實這個時候應該理解爲錯誤代碼,顯然面積應該是一個正數,經過檢查該值能夠判斷方法是否正確運行。
相比前一種方式,這種方法實施起來顯得有些複雜,可是可擴展更大,這種方式能夠徹底脫離MATLAB環境,實現軟件的快速開發。
在實施這一混合編程以前,須要先介紹獨立於MATLAB的程序一些基本問題的。
MCR的全稱是MATLAB Compiler Runtime,即MATLAB編譯器運行時。根據MathWorks公司的定義:
The MATLAB Compiler Runtime (MCR) is an execution engine made up of the same shared libraries MATLAB uses to enable the execution of MATLAB files on systems without an installed version of MATLAB.
可見MCR是一個由MATLAB共享類庫構成的執行引擎,他可以使MATLAB文件在沒有MATLAB的機器上運行。這一點和.NET Framework相對於.NET程序同樣,即爲程序的運行提供了底層支持。當發佈程序的時候,須要將MCR也打包進來,不然沒有MATLAB的機器上程序不能執行,如同.NET程序不能在沒有.NET Framework的機器上運行同樣。MCR隨MATLAB軟件一同發佈,能夠在MATLAB中輸入命令「mcr」或者「mcrinstaller」獲取其保存路徑:
>> mcr
The WIN32 MCR Installer, version 7.14, is:
D:\MATLAB\toolbox\compiler\deploy\win32\MCRInstaller.exe
MCR installers for other platforms are located in:
D:\MATLAB\toolbox\compiler\deploy\<ARCH>
<ARCH> is the value of COMPUTER('arch') on the target machine.
Full list of available MCR installers:
D:\MATLAB\toolbox\compiler\deploy\win32\MCRInstaller.exe
For more information, read your local MCR Installer help.
Or see the online documentation at The MathWorks' web site. (Page may load slowly.)
根據上面的運行結果,可知該文件的完整路徑是:
D:\MATLAB\toolbox\compiler\deploy\win32\MCRInstaller.exe。
MCR包含了文件MWArray.dll,該文件中的API承擔了用戶程序和MCR之間數據交換的任務,所以,每個獨立文件都須要包含對該文件的引用,不然程序就不能使用MATLAB中的函數,爲使用該文件,須要先安裝MCR,該文件在安裝完MCR後位於:installation_folder\toolbox\dotnetbuilder\bin\architecture\framework_version
另外,該文件中有兩個重要的命名空間,MathWorks.MATLAB.NET.Arrays和MathWorks.MATLAB.NET.Utility,Arrays命名空間下的類提供從其餘任何兼容CLS(Common Language Specification) 語言訪問MATLAB中數組的功能,這些類支持數組格式化、類型的特定索引和錯誤處理的功能。而Utility命名空間下的類提供了對MWArray類架構和MATLAB公共運行時的託管API的通用支持。
4.3.混合編程的實施
爲了將MATLAB中的程序做爲組件提供給其餘.NET程序使用,須要作兩方面的工做:
1.將M文件打包爲與.NET兼容的程序集
2.在外部程序中添加對程序集的引用
首先是將M文件打包爲程序集。MATLAB將函數做爲某個類中的方法,經過對類的操做實現對函數的調用。首先準備好函數,這些函數須要保存在M文件中,例如MATLAB中的函數SVD很強大,而咱們不想本身重寫,或者對幻方比較感興趣,也不知道具體如何事實,可是在MATLAB下面只要一個函數就能解決,這些功能對外部程序就頗有用,下面是這兩個M文件:
%函數1.矩陣的SVD分解
function [u,s,v]=XDSVD(A)
[u,s,v]=svd(A);
end
%函數2.生成幻方矩陣
function m=XDMagic(n)
m=magic(n);
end
假設這兩個文件分別保存爲XDSVD.m和XDMagic.m,下面將其打包爲.NET兼容的組件。這就須要使用deploytool命令:
在MATLAB的命令窗口中輸入:
>> deploytool
將出現以下對話框,設置好項目名,並指定目標組件的形式是 .NET Assembly ,而後肯定。
這個時候XDMagic和XDSVD函數將做爲Functions類的方法而存在,這個時候就能夠點擊開始編譯了,不過在編譯以前,還須要說說Package標籤下的一些細節。
編譯完成以後或生成一個和項目同名的文件夾,其中最重要的文件就是distrib文件夾下的Castor.dll,該文件就是提供給其餘.NET程序調用的類庫。經過反編譯程序能夠查看它的成員方法,以下圖:
接下來的工做就是如何在外部程序中使用該程序集。仍是以C#爲例,建立一個Windows窗口程序。添加必須的控件,而後添加對MWArray.dll和Castor.dll的引用以及加入須要的命名空間。
程序界面以下:
核心代碼以下:
private void button1_Click(object sender, EventArgs e)
{
Functions f = new Functions();
MWNumericArray na = null;
MWArray[] arr1 = null;
MWArray[] arr2 = null;
int i = Convert.ToInt16(textBox2.Text);
arr1 = f.XDMagic(1, i);
try
{
arr2 = f.XDSVD(3, arr1[0]);//返回三個數組
MessageBox.Show(arr2[0].ToString(), "矩陣U:");
MessageBox.Show(arr2[1].ToString(), "矩陣S:");
MessageBox.Show(arr2[2].ToString(), "矩陣V:");
}
catch (Exception exc)
{
MessageBox.Show("出現異常,緣由是:" + exc.Message, "錯誤", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void button2_Click(object sender, EventArgs e)
{
Functions f = new Functions();
MWNumericArray na = null;
MWArray[] ansArray = null;
int i = Convert.ToInt16(textBox2.Text);
ansArray=f.XDMagic(1,i);
na = (MWNumericArray)ansArray[0];//只有一個數組返回
MessageBox.Show(na.ToString());
}
程序運行效果以下(假設輸入的參數是5):
幻方:
矩陣U、S、V分別以下:
經過對MATLAB混合編程環境的論述和實例講解,闡述了.NET和MATLAB交互使用的方法,縮短了項目開發的週期,提升了算法的準確度,具備很重要的實踐意義。
轉自 http://379910987.blog.163.com/blog/static/3352379720116151449673/?suggestedreading&wumii