做者 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