Matlab 数据类型与.NET 数据类型转换
by-GalaxyGap 2012-12-11
用 Matlab 写算法还是有很多优势的,具体表现在以下几个方面:1)Matlab
的内部函数是用 C 语言写的,虽然 M 语言是解释性语言,但调用内部函数进行
计算还是很快的。2)一般我们写算法都会涉及到很多基本的数学操作,比如说矩
阵相乘、矩阵求逆、求特征值、满足特定分布的随机数生成、基本统计量的计算
等等。这些基本的数学操作可以说是我们算法的基本组成部分,我们可以使用任
何一种语言编写函数一一实现这些基本的数学操作,然后由这些最基本的数学操
作构建我们更复杂的算法。但是我们有没有必要这么做呢?显然没有!因为这些
基本的数学操作虽然原理我们都懂,自己亲自动手实现也不会太难,但它太耗时,
我们自己写出来的东西可能也不稳健!耗时这个很好理解了,即使是一个很简单
的矩阵求逆我们也要写一大段的代码,费劲心思去进行流程设计和步骤分解,编
写代码的时候也要小心翼翼地处理各种细节。可以说从最底层开始写算法是非常
费神的,等你算法写好了,估计也已经累得半死,然后项目也早过期了。更严重
的是自己写出来的基本模块没有一些数学软件提供的模块那么稳健,可能存在某
些漏洞或 bug,这样程序调试起来又更费力气。可以说从最底层写算法是一件吃
力不讨好的事情。相反若在某些数学软件的平台上写算法,我们的工作就会省去
一大半,而且写出来的算法也更稳健。比如说在 Matlab 上我们要实现矩阵求逆,
只需要调用一个函数便可得到结果。而且这个函数应该是比较稳健的,不会出什
么意外。更重要的是,Matlab 平台不仅仅是提供了一些最基本的数学操作,还
在此基础上实现了一些更高级的模块,比如说求解线性方程组、曲线拟合、积分
微分等。这些更高级的模块也都可以成为我们算法的组成部分。也即是我们的算
法可以在更粗的粒度上来构建,而不局限于从基本的数学操作上开始构建。3)
Matlab 支持将 M 文件编译成其他平台能够使用的组件或者说模块,也即是
Matlab 能够和其他平台通信,只需要安装一个 200 多兆的 MCR 即可。
当然什么东西都不是十全十美的,用 Matlab 写算法也有它的缺点,特别是
当我们想把 Matlab 中写的算法应用到其他平台上时,它的缺点就体现得更明显。
1)首先是速度的问题,也许我们的算法直接在 Matlab 平台上运行的时候速度是
很快的,但应用到其他平台上的时候就很慢了,这是因为 Matlab 和其他平台通
信的时候耗时比较多,尤其是和.NET 通信的时候。2)其次 Matlab 和其他平台通
信的时候涉及到数据转换,因为不同平台的数据类型一般不相同。这种数据类型
的转换有时候比较复杂,不便于不同平台下的程序员交流。比如说一个熟悉
Matlab 平台的算法程序员把算法写好并编译成.NET 程序集之后交给一个不熟悉Matlab 环境的.NET 程序员去用这个算法。在这种情况下,也许 Matlab 程序员很
清楚他的算法需要什么样的数据作为输入,然后输出了什么样的数据,但.NET
程序员却未必对这一算法的输入输出了解得那么清楚了。没有搞清楚输入输出想
要应用这一算法就有点勉为其难。因此 Matlab 与.NET 之间的数据交换就显得尤
为重要,只有能理解两个平台的数据类型以及他们之间的转换过程才能顺利地将
两个平台结合在一起。本文以下就专门讨论 Matlab 平台与.NET 平台的数据交换
过程。开始之前先提醒一下:Matlab 平台与.NET 平台的数据交换全是由
MathWorks.MATLAB.NET.Arrays 这一命名空间下的类和接口实现的。这是一个由
Matlab 为支持.NET 平台开发的.NET 中的方法集。因此我们要想搞清楚这两个平
台之间是如何通信的,除了对两个平台的数据类型由足够的了解之外,还要深谙
这个命名空间下的各种方法的作用。
Matlab 中的 M 文件编译成.NET 可用的程序集
我们首先从 Matlab 这边开始,看看在 Matlab 这边写好的函数是怎样一步步
变成.NET 中可用的函数。假设我们在 Matlab 中写好了这样一个简单函数:
function y = Sum(x)
y = sum(x);
关于 sum 这个 Matlab 内部函数的作用,大家可以在 Matlab 的 help 中查到,
这里就不具体说了。只需要看看在 Matlab 中它的输入输出即可。比如说输入这
样一个矩阵(我们知道 Matlab 中所有的数据类型都是以矩阵的形式表示的,即
使是一个单一值,Matlab 中也把它表示成 1×1 的矩阵):
data = [1 2 3;4 5 6; 7 8 9; 10 11 12];
data =
1 2 3
4 5 6
7 8 9
10 11 12
可以看到这是一个 4×3 的矩阵。调用 Sum 函数之后得到的结果为:
y = Sum(data)
y =
22 26 30
这个时候 y 已经是一个 1×3 的矩阵了。我们再用 Sum 处理一下这个 y 得到的结
果是:
Sum(y) ans =
78
可以看到就这么一个简单的函数在 Matlab 中它的输入输出可是变化多多。它可
以接受一个多行多列的矩阵,然后针对每一列求和(第一次调用 Sum)得到一个
一行多列的矩阵;也可以接受一个一行 n 列的矩阵,然后针对该行求和得到一个
一行一列的矩阵。这对于看惯了固定输入类型的.NET 程序员来说看着确实别扭,
起码我是这样的。当然这实际上一种重载了,.NET 中也能实现,只是在.NET 中
每一个重载函数我们都会显式地写出来,用的时候也会有提示,而 Matlab 中却
是一个函数搞定。大有一种:参数你随便传,我看情况处理,但我是怎么处理的
不明显告诉你,我把它放在内心里。说白了,它的重载函数都隐藏起来了。
好,现在我们把这个函数编译成.NET 中能调用的程序集。编译的过程如下: