搜档网
当前位置:搜档网 › Matlab数据类型与.NET数据类型转换

Matlab数据类型与.NET数据类型转换

Matlab数据类型与.NET数据类型转换
Matlab数据类型与.NET数据类型转换

Matlab数据类型与.NET数据类型转换

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平台的数据交换全是由https://www.sodocs.net/doc/fa14578984.html,.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中能调用的程序集。编译的过程如下:1在Matlab的Command Window中运行deploytool命令调出编译和打包界面,将工程名字改成SumComp,类型选择.NET Assembly。

2在Build标签下单击Class选项中的Add Class,把Class1改成SumClass,单击Add File把前面写好的M文件Sum.m添加到该类下。

3找到Settings(Matlab 2012b版本的可以单击右上角那个齿轮,在弹出的菜单中选择Settings),打开Project Settings对话框,并在.NET标签下选择Microsoft Framework为4.0(这一步因人而异了,看你接下来用哪一版本的VS平台做测试,我的是VS2010,对应的.NET Framework是4.0,其他的只要选择对应的Framework 就行了。这一步是为了将Matlab编译生成的程序集的.NET Framework版本与你测试程序的.NET Framework版本对应起来,不对应的话是生成的程序集在引用的时候会出错的。)

4点击编译,生成.NET可以引用的程序集。这一步完成之后该工程会在工程文件夹下生成两个子文件夹distrib和src,打开distrib文件夹可以看到四个文件,这就是生成的程序集。可以查看那个readme.txt文件以了解每个文件的作用,我们接下来在测试程序中需要引用的就是那个SumComp.dll。

到这里Matlab中的函数就转化成了.NET中可以引用的程序集了。Matlab中的Sum 函数就包含在了Sumcomp.dll及其相关的文件里。这以程序集包含了一个SumClass类,类内包含着一个叫Sum的函数,命名空间是SumComp。接下来就可以在.NET的测试程序中使用这个函数了。

在.NET中测试Matlab数据类型与.NET数据类型的交换

1首先在VS中新建一个控制台应用程序,添加MWArray组件引用(这一组件如果顺利地被你的VS识别了的话,在你添加引用的时候会存在于.NET标签下,你

直接添加引用即可;若这个标签下没有,则自己定位到C:\Program Files\MATLAB\R2012b\toolbox\dotnetbuilder\bin\win32\v2.0\MWArray.dll,将该dll 添加到引用即可)。这一组件即是前面说的Matlab为支持.NET而开发的一套数据交换接口。

2其次还要添加刚刚生成的组件引用,也即定位到distrib文件夹下添加对SumComp.dll的引用,或者你把这个文件下的所有文件拷贝到当前工程的目录下,再对SumComp.dll添加引用。

3接下来使用命名空间,在测试程序的using区域内添加以下两个using:

using SumComp;

using https://www.sodocs.net/doc/fa14578984.html,.Arrays;

好,以上这些步骤都完成之后可以开始测试Matlab与.NET之间的数据交换了。

不过在测试之前先别忙,我们先来看看Matlab编译生成的组件SumComp.dll 帮我们把Matlab中的数据转换到了哪一步。SumComp.dll这个组件是Matlab的最后产物,后面的事情就交给.NET了,所以很有必要先研究下这个SumComp.dll 所包含的方法到底是个什么样的形式,其输入输出参数都是些什么。双击引用中的SumComp可以打开对象浏览器,我们可以一级级定位到最后SumClass包含的函数,在这里我们可以看到编译之后的Sum函数的庐山真面目,这里Matlab一共生成了5个Sum的重载函数!从一个M文件中的Sum函数变成5个.NET里的Sum的重载函数,是不是有点出乎意料!这五个重载函数分列如下:

①public void Sum(int numArgsOut, ref https://www.sodocs.net/doc/fa14578984.html,.Arrays.MWArray[]argsOut, https://www.sodocs.net/doc/fa14578984.html,.Arrays.MWArray[]argsIn)

SumComp.SumClass的成员

②public https://www.sodocs.net/doc/fa14578984.html,.Arrays.MWArray[]Sum(int numArgsOut,

https://www.sodocs.net/doc/fa14578984.html,.Arrays.MWArray x)

SumComp.SumClass的成员

③public https://www.sodocs.net/doc/fa14578984.html,.Arrays.MWArray[]Sum(int numArgsOut)

SumComp.SumClass的成员

④public https://www.sodocs.net/doc/fa14578984.html,.Arrays.MWArray

Sum(https://www.sodocs.net/doc/fa14578984.html,.Arrays.MWArray x)

SumComp.SumClass的成员

⑤public https://www.sodocs.net/doc/fa14578984.html,.Arrays.MWArray Sum()

SumComp.SumClass的成员

看到了吧,几乎大部分参数都是WMArray类型的,也即WMArray这种数据类型是Matlab数据类型和.NET数据类型相互转换的中间数据类型!而且Matlab 并不是一对一地把一个函数编译成了另一个相同形式的函数,而是编译成了多个重载函数以供用户以不同的调用方式调用。但我们现在有一个疑问就是:是否针

对每种特定的输入,每个重载函数都可以调用,并且能实现同样的结果。后一点非常重要,因为相同的输入,调用同样功能的函数,必须要得到相同的输出。

首先我们来看看是不是针对各种各样的输入,每个函数都可以调用。回答显然是否定的。因为我们可以看到第五个重载函数没有输入参数,只有输出参数,显然在我们想输入数据的时候,是不能够通过调用第五个函数来实现的。第五个函数看起来并没有任何作用,我们不清楚它到底从哪里引用数据,然后输出结果。接下来我们就来一一测试剩下的4个重载函数。在Main函数中编写以下代码:double[,] data = {{1,2,3},{4,5,6},{7,8,9},{10,11,12}};

MWNumericArray dataArray = new MWNumericArray(data);

MWNumericArray resultArray;

SumClass mySum = new SumClass ();

resultArray = (MWNumericArray)mySum.Sum(dataArray);

double[,] result =(double[,]) resultArray.ToArray();

for(int i = 0; i

for (int j = 0; j < result.GetLength(1); j++)

{

Console.WriteLine("result[{0},{1}] = {2}", i, j, result[i, j]);

}

Console.WriteLine("Press enter to finish");

Console.ReadLine();

我们一步步调试这段代码。首先定义并初始化一个.NET中的二维数组data,该二维数组的维度是4×3,这个数组将作为我们求和函数的输入。然后我们要把这个.NET中的二维数组转化成MWArray的中间类型,因为Matlab生成的函数接收的是MWArray类型的数据,MWArray是Matlab与.NET进行数据交换的中间类型。这里我们定义的是MWNumericArray类型,它是从MWArray派生的类型,在传递参数的时候同样可用。之后很关键的一个问题就是如何把double[,]转换成MWNumericArray了,这里非常简单,只需要在实例化MWNumericArray的时候将data作为MWNumericArray构造函数的参数就行了。这一个类的构造函数非常强大,有54个重载构造函数,几乎可以把你在.NET中的任何数值型数据类型转成在Matlab中与该数据类型结构相似的数据类型。比如说这里传递的是一个

4×3的二维数组,经过这样一个转化之后,相当于dataArray也代表了一个Matlab 中的4×3的数组。然后再定义一个MWNumericArray类型的resultArray变量来接收结果。接下来实例化SumClass并调用Sum函数。需要注意的是这里调用的Sum函数是和我们在Matlab中写的Sum函数形式最相近的那个,也即是一个输入参数一个输出参数,输入参数包含输入数据,输出参数包含结果数据。这个函数就是上面所列函数的第四个。另外函数调用之后返回的结果是MWArray类型的,但我们知道返回的结果肯定是数值型的,所以前面我们定义的是

MWNumericArray来接收它。MWArray是MWNumericArray的基类,从MWArray到MWNumericArray的转换是向下cast(还是向上?搞不清楚了,反正从基类到派生类的cast需要显式转换,反之可以进行隐式转换),所以要进行显式转换。获得Sum函数的结果后,还要倒过来把中间类型的结果转换到.NET平台上的结果,也即是把MWNumericArray类型的结果转成double[,]的结果。这一步也很简单,直接调用MWNumericArray的ToArray方法。这个方法有两个重载,第一个不用输入任何参数;第二个需要指定是输出MWNumericArray所含数据的实部还是虚部。因为我们的输入数据不是复数,所以只需调用第一个重载就够了。最后打印出结果:

result[0,0] = 22

result[0,1] = 26

result[0,2] = 30

Press enter to finish

可以看到最后的输出结果和Matlab中的输出结果是一致的,都是一个1×3的矩阵。

以上是对整一个数据转换流程的说明,Matlab与.NET的数据交换基本上都是按照这个流程在走的,只是中间还有一些细节的东西需要交代。

1输入数据的维度问题

1)若输入一维数组

//输一维数组,调用标准Sum函数

double[] data = new double[]{1,2,3,4,5,6,7,8,9,10};

MWNumericArray dataArray = new MWNumericArray(data);

MWNumericArray resultArray;

SumClass mySum = new SumClass();

resultArray = (MWNumericArray)mySum.Sum(dataArray);

double[,] result = (double[,])resultArray.ToArray();

for (int i = 0; i < result.GetLength(0); i++)

for (int j = 0; j < result.GetLength(1); j++)

{

Console.WriteLine("result[{0},{1}] = {2}", i, j, result[i, j]);

}

Console.WriteLine("Press enter to finish");

Console.ReadLine();

此时dataArray是1×10的数据,见图1,也即.NET中的一维数组被转换成了Matlab中的行向量。我们知道在Matlab中对行向量使用sum函数最后会得到一个值,到这个值在Matlab中实际上是一个1×1的矩阵,所以我们可以预计结果

变量resultArray也应该是1×1的矩阵,事实也确实如此,见图2:

图1 一维数组被转换成MWNumericArray之后的维度

图2 一维数组作为输入产生的结果数据的维度

最后的输出结果如下:

result[0,0] = 55

Press enter to finish

2)若输入高维数组

在.NET平台上我们对高维数组的使用比较少,但在Matlab中使用得还是比较频繁的,所以这里给出一个.NET中的三维数组如何传递给Matlab的例子:///输入三维数组,调用标准Sum函数

double[,,] data = new double[,,]{{{1,2,3},{4,5,6}},{{7,8,9},{10,11,12}} };

MWNumericArray dataArray = new MWNumericArray(data);

MWNumericArray resultArray;

SumClass mySum = new SumClass();

resultArray = (MWNumericArray)mySum.Sum(dataArray);

double[,,] result = (double[,,])resultArray.ToArray();

for (int i = 0; i < result.GetLength(0); i++)

for (int j = 0; j < result.GetLength(1); j++)

for (int k = 0; k < result.GetLength(2);k++ )

{

Console.WriteLine("result[{0},{1},{2}] = {3}", i, j, k, result[i, j, k]);

}

Console.WriteLine("Press enter to finish");

Console.ReadLine();

三维数组data初始化之后在.NET中的表示是这样的,见图3

图 3 三维数组data[2,2,3]在.NET中的表示形式

在.NET中,二维的情况下,我一般认为行代表第二维,列代表第一维,也即行是高维,列是低维,当然你也可以把它反过来。但要记住的是GetLength(0)方法返回的是行数,GetLength(1)返回的是列数,二行三列的数组表示形式是这样的data[2,3]。在三维的情况下,仍然将最低维(第一维)认为是列所在的维,第二维是行所在的维,再往上才是第三维。所以三个维度从高往低分别为2,2,3的高维数组在.NET中的表示形式是data[2,2,3]。这个时候GetLength(0)获得的是第三维的维度,GetLength(1)获得的是第二维的,而GetLength(2)获得的才是第一维的。三维数组可以看成是多个同样结构的二维数组拼在一起。更高维的数组以此类推。在Matlab中高维数组的表示和.NET中不同。将.NET中的data[2,2,3]转换成MWNumericArray类型的dataArray后,其表示形式如图4所示。Length(0)获得的是行数,length(1)获得的是列数,length(2)获得的才是第三维的维度。

图4 data[2,2,3]转换成MWNumericArray类型后的变量dataArray

调用Sum函数返回的结果resultArray,见图5。可以看到Matlab中的sum函数是沿着列维作用的,也即是将每一列值加起来。最后仍然返回一个三维矩阵,只不过维度已经变成1,3,2了(Matlab中的表示形式,第一维的维度是1,第二维3,第三维2,可以理解为2个一行三列矩阵的拼接)。

图5 求和之后返回的MWNumericArray类型的结果变量resultArray

最后将MWNumericArray类型表示的三维矩阵转换成.NET中的三维数组,如图6所示。输出结果如下:

result[0,0,0] = 5

result[0,0,1] = 7

result[0,0,2] = 9

result[1,0,0] = 17

result[1,0,1] = 19

result[1,0,2] = 21

Press enter to finish

图6 求和并转换之后的结果数组result

2其他Sum重载函数的测试

1)调用第一个重载函数

第一个重载函数原型:

public void Sum(int numArgsOut, ref https://www.sodocs.net/doc/fa14578984.html,.Arrays.MWArray[]argsOut, https://www.sodocs.net/doc/fa14578984.html,.Arrays.MWArray[]argsIn)

//输入三维数组,调用第一个重载函数

double[, ,] data = new double[,,] { { { 1, 2, 3 }, { 4, 5, 6 } }, { { 7, 8, 9 }, { 10, 11, 12 } } };

MWArray[] argin = new MWNumericArray[1];

argin[0] = new MWNumericArray (data);

MWArray[] argout = new MWNumericArray[1];

SumClass mySum = new SumClass();

mySum.Sum(1, ref argout,argin);

double[, ,] result = (double[, ,])argout[0].ToArray();

for (int i = 0; i < result.GetLength(0); i++)

for (int j = 0; j < result.GetLength(1); j++)

for (int k = 0; k < result.GetLength(2); k++)

{

Console.WriteLine("result[{0},{1},{2}] = {3}", i, j, k, result[i, j, k]);

}

Console.WriteLine("Press enter to finish");

Console.ReadLine();

这种调用方式是以引用传参的方式调用的,三个输入参数的类型分别是int, MWArray[], MWArray[].第一个参数表示输出参数的个数,第二个参数是引用参数,

用来保存输出值的,最后一个参数传入待处理的数据。注意到后两个参数是MWArray类型的数据,是否可以将多个待求和的数组一次性传入最后得到一个同维的MWArray类型的结果数组呢?我试了一下,发现这样做行不通,代码示例如下,有兴趣的朋友可以自己试一下:

//输入三维数组,调用第一个重载函数

double[, ,] data = new double[,,] { { { 1, 2, 3 }, { 4, 5, 6 } }, { { 7, 8, 9 }, { 10, 11, 12 } } };

MWArray[] argin = new MWNumericArray[2];

argin[0] = new MWNumericArray (data);

double[,] data2 = new double[,] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 }, { 10, 11, 12 } };

argin[1] = new MWNumericArray(data2);

MWArray[] argout = new MWNumericArray[2];

SumClass mySum = new SumClass();

mySum.Sum(2, ref argout,argin);

double[, ,] result = (double[, ,])argout[0].ToArray();

for (int i = 0; i < result.GetLength(0); i++)

for (int j = 0; j < result.GetLength(1); j++)

for (int k = 0; k < result.GetLength(2); k++)

{

Console.WriteLine("result[{0},{1},{2}] = {3}", i, j, k, result[i, j, k]);

}

double[,] result2 = (double[,])argout[1].ToArray();

for (int i = 0; i < result2.GetLength(0); i++)

for (int j = 0; j < result2.GetLength(1); j++)

{

Console.WriteLine("result2[{0},{1}] = {3}", i, j, result2[i, j]);

}

Console.WriteLine("Press enter to finish");

Console.ReadLine();

这段代码调了很久都没调成功,试着把argin[0]和argin[1]改成同结构的数组,行不通;试着把Sum函数的第一个参数改成1,也行不通。都是在调用Sum函数的时候出现”Too many input parameters”的错误。不知道增加这个输出参数个数到底是什么意思,放在这里有什么用。暂且放在这吧。

2)调用第二个函数

第二个重载函数原型:

public https://www.sodocs.net/doc/fa14578984.html,.Arrays.MWArray[]Sum(int numArgsOut, https://www.sodocs.net/doc/fa14578984.html,.Arrays.MWArray x)

这一个重载函数其实是第一个和第四个的综合。将输出参数放在了外面,同时又在输入参数中加了一个输出参数个数numArgsOut。测试代码和第一个重载函数的测试代码类似:

//输入三维数组,调用第二个重载函数

double[, ,] data = new double[,,] { { { 1, 2, 3 }, { 4, 5, 6 } }, { { 7, 8, 9 }, { 10, 11, 12 } } };

MWNumericArray argin = new MWNumericArray(data);

MWArray[] argout = new MWNumericArray[1];

SumClass mySum = new SumClass();

argout = mySum.Sum(1, argin);

double[, ,] result = (double[, ,])argout[0].ToArray();

for (int i = 0; i < result.GetLength(0); i++)

for (int j = 0; j < result.GetLength(1); j++)

for (int k = 0; k < result.GetLength(2); k++)

{

Console.WriteLine("result[{0},{1},{2}] = {3}", i, j, k, result[i, j, k]);

}

Console.WriteLine("Press enter to finish");

Console.ReadLine();

第三个重载函数和第五个重载函数一样,无解,不知道从哪里输入数据。

3其他注意事项

有关MWNumericArray数据类型以及其他由MWArray派生的其他数据类型向.NET平台数据类型的转换大家还可以去查看这些类提供的一些方法。比如说MWNumericArray的ToVector方法还可以将Matlab中的矩阵转成.NET中的一维数组,NumberofDimensions获得维度数,NumberofElements获得元素个数等等。总结

关于Matlab与.NET数据类型转换,首先要求我们对两边的数据类型都有清楚的了解。MWArray及其派生类可以代表Matlab中各种各样的数据类型,比如说一个MWNumericArray类型的变量可以表示一个数值(1×1)、一个一维数组(1×n)、一个多维数组(m×n或m×n×p……等)。这样向.NET中的数据类型转换时最保险的方法就是在.NET平台上定义一个和MWArray类所包含的潜在数据类型结构相同的变量。这样转换一般才不会出问题。

在Matlab把M文件编译成.NET中可调用的组件之后,最好再将这些组件在.NET平台上再封装一层,将中间类型的参数全部变成.NET的数据类型参数,以供不熟悉Matlab与.NET数据交换的.NET程序员使用。

在这么多重载函数中,最好使用和M文件中定义的函数形式相同的那个函数(我习惯把它叫做标准函数),其他重载函数尽量少用或不用,以免没搞清楚这些函数的输入输出造成函数调用失败或得到错误结果。

matlab数据类型及转换

Matlab中有15种基本数据类型,主要是整型、浮点、逻辑、字符、日期和时间、结构数组、单元格数组以及函数句柄等。 1、整型:(int8;uint8;int16;uint16;int32;uint32;int64;uint64)通过intmax(class)和intmin(class) 函数返回该类整型的最大值和最小值,例如intmax(‘int8’)=127; 2、浮点:(single;double) 浮点数:REALMAX('double')和REALMAX('single')分别返回双精度浮点和单精度浮点的最大值,REALMIN('double')和REALMIN ('single')分别返回双精度浮点和单精度浮点的最小值。 3、逻辑:(logical) Logical:下例是逻辑索引在矩阵操作中的应用,将5*5矩阵中大于0.5的元素设定为0: A = rand(5); A(A>0.5)=0; 4、字符:(char) Matlab中的输入字符需使用单引号。字符串存储为字符数组,每个元素占用一个ASCII字符。如日期字符:DateString=’9/16/2001’ 实际上是一个1行9列向量。构成矩阵或向量的行字符串长度必须相同。可以使用char函数构建字符数组,使用strcat函数连接字符。 例如,命令name = ['abc' ; 'abcd'] 将触发错误警告,因为两个字符串的长度不等,此时可以通过空字符凑齐如:name = ['abc ' ; 'abcd'],更简单的办法是使用char函数:char(‘abc’,’abcd’),Matlab自动填充空字符以使长度相等,因此字符串矩阵的列纬总是等于最长字符串的字符数. 例如size(char(‘abc’,’abcd’))返回结果[2,4],即字符串’abc’实际存在的是’abc ’,此时如需提取矩阵中的某一字符元素,需要使用deblank函数移除空格如name =char(‘abc’,’abcd’); deblank(name(1,:))。 此外,Matlab同时提供一种更灵活的单元格数组方法,使用函数cellstr可以将字符串数组转换为单元格数组: data= char(‘abc’,’abcd’) length(data(1,:)) ->? 4 cdata=cellstr(data) length(cdata{1}) ->?3 常用的字符操作函数 blanks(n) 返回n个空字符 deblank(s) 移除字符串尾部包含的空字符 (string) 将字符串作为命令执行 findstr(s1,s2) 搜索字符串 ischar(s) 判断是否字符串 isletter(s) 判断是否字母 lower(s) 转换小写 upper(s) 转换大写 strcmp(s1,s2) 比较字符串是否相同 strncmp(s1,s2,n) 比较字符串中的前n个字符是否相同 strrep(s1,s2,s3) 将s1中的字符s2替换为s3 5、日期和时间 Matlab提供三种日期格式:日期字符串如’1996-10-02’,日期序列数如729300(0000年1月1日为1)以及日期向量如1996 10 2 0 0 0,依次为年月日时分秒。 常用的日期操作函数

matlab图像数据类型转换

uint 8:无符号的8位(8bit)整型数据(unit 都是存储型) int :整型数据 1、在MATLAB中,数值一般都采用double型(64位)存储和运算. 2、为了节省存储空间,MATLAB为图像提供了特殊的数据类型uint8(8位无符号整数),以此方式存储的图像称为8位型像。 3、函数image能够直接显示8位图像,但8位型数据和double型数据在image中意义不一样, 4、对于索引图像,数据矩阵中的值指定该像素的颜色种类在色图矩阵中的行数。当数据矩阵中的值为0时,表示用色图矩阵中第一行表示的颜色绘制;当数据矩阵中的值为1时,表示用色图矩阵中的第二行表示的颜色绘制该像素,数据与色图矩阵中的行数总是相差1。所以,索引图像double型和uint8型在显示方法上没有什么不同,只是8位数据矩阵的值和颜色种类之间有一个偏差1。调用格式均为image(x); colormap(map); 5、对于灰度图像,uint8表示范围[0,255],double型表示范围[0,1]。可见,double型和uint8型灰度图像不一样,二者转换格式为: I8=uint8 (round (I64*255)); !!double转换成uint 8 I64=double (I8)/255; !!!uint转换成double 反之,imread根据文件中的图像种类作不同的处理。当文件中的图像为灰度图像时,imread 把图像存入一个8位矩阵中,把色图矩阵转换为双精度矩阵,矩阵中每个元素值在[0,1]内;当为RGB图像时,imread把数据存入到一个8位RGB矩阵中。!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! MATLAB中读入图像的数据类型是uint8,而在矩阵中使用的数据类型是double 因此 I2=im2double(I1) :把图像数组I1转换成double精度类型; 如果不转换,在对uint8进行加减时会产生溢出 图像数据类型转换函数 默认情况下,matlab将图象中的数据存储为double型,即64位浮点数;matlab还支持无符号整型(uint8和uint16);uint型的优势在于节省空间,涉及运算时要转换成double型。 im2double():将图象数组转换成double精度类型 im2uint8():将图象数组转换成unit8类型 im2uint16():将图象数组转换成unit16类型 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 默认情况下,matlab将图像中的数据存储为double型,即64位浮点数;matlab还支持无符号整型(uint8和uint16);uint型的优势在于节省空间,涉及运算时要转换成double型。 但是,问题的真正的解释其实应该是这样的。首先是在数据类型转换时候uint8和im2uint8的区别,uint的操作仅仅是将一个double类型的小数点后面的部分去掉;但是im2uint8是将输入中所有小于0的数设置为0,而将输入中所有大于1的数值设置为255,再将所有其他值乘以255。 图像数据在进行计算前要转化为double类型的,这样可以保证图像数据运算的精

MATLAB模块介绍$

MATLAB 模块介绍 -------- 数学 & 金融 u Curve Fitting Toolbox Curve Fitting Toolbox 扩展MATLAB 环境,集成数据管理,拟合,显示,检验和输入分析过程等功能。所有能通过GUI 使用的功能都可以通过命令行来进行。

u Database Toolbox ——与关系数据库交换数据 Database Toolbox提供了同任何支持ODBC/JDBC标准的数据库进行数据交换的能力。利用在工具箱中集成的Visual Query Builder工具,无需学习任何SQL语句就可以实现在数据库中查寻数据的功能。这样MATLAB就能够对存储在数据库中的数据进行各种各样的复杂分析。在MATLAB环境中,也可以使用SQL命令来进行如下操作: 对数据库数据进行读、写操作;应用简单或复杂的条件查询数据库中的内容。 特点: ?与支持ODBC/JDBC 数据库建立连接,包括Oracle 、Sybase SQL Server ,Sybase SQL Anywhere ,Microsoft SQL Sever ,Microsoft Access ,Informix Ingres 等。?支持SQL 语句,可以在MATLAB 环境下直接执行SQL 查询命令 ?动态数据调入:可以根据需要使用SQL 在MATLAB 中获取数据,本工具箱对某一种类型的数据库进行大量或小量的查询 ?数据类型保持:在MATLAB 中对数据的调入或调出操作都能保持原有的数据类型 ?多个对话能力,采用本工具箱可在MATLAB 中从一个数据库中调入数据,对那些数据进行分析,然后输出到另一个数据库中 ?处理大量数据的能力:采用本工具箱你可以一次或分几次处理大量的数据,这样能让你根据任务高效地进行数据处理 ?连续状态的数据库联接:一旦和某个数据库的联接建立起来后,数据库一直是打开的,除非你在MATLAB 中执行关闭语句。这提高了数据库的读取速度,减少了不必要的命令来调入、输出数据。 ?无需了解SQL 也能够对数据库数据进行查询。 功能: Database Toolbox 可以与流行的数据库交互数据,其中包括Oracle ,Sybase ,Microsoft SQL Server 及Informix 等。工具箱还允许在单个MATLAB 进程中对多个数据库进行操作,同时支持对大量数据处理。工具箱中包含的Visual Query Builder ,即使不知道SQL ,也能可视化地与数据库打交道。 u Financial Derivatives Toolbox Financial Derivatives Toolbox 用于分析金融衍生工具和投资。 特点 ?提供各种利息率模型 ?提供七种金融工具一系列计算的函数

MATLAB与C#数据类型转换

以下是本人编程中总结的一些思路,拿出来与大家共享。不对之处,请留言说明。 版本:Matlab R2007b,Visual Studio2005 C++/C#数据类型到M类型 此方向转换十分简单。 如果C++/C#数据不是数组, ?直接将值传递给已经初始化的MWArray数组中的成员 ?直接将数据类型赋值给已经初始化的MWNumericArray变量。 ?直接将字符串类赋值给已经初始化的MWCharArray变量。 如果是数组类型: ?直接赋值给MWNumericArray变量; ?赋值给MWArray变量,则在前面加上类型转换如:(MWNumericArray)进行强制转换。 总之,MWArray是总类型,其它的以MW开头,以Array结尾的变量类型都可以直接对它进行赋值或取值。 M类型到C++/C#数据类型 MWArray M类型,它是M文件的编译后内部的标准类型,一切C++/C#类型都要最终转换成此类型,方可作为参数调用M语言函数。 MWCharArray M的字符串类型,使用它可以将M中的字符类型转换成C++/C#的字符串类型。 MWNumericArray MWNumericArray是MWArray与C#等语言的转换中间类型。 常用的转换函数: ①public Array ToArray(MWArrayComponent component); 将M类型转换成C#的Array类型,然后可以直接转换成其它类型的数组。 ②public byte ToScalarByte();

将M类型转换成C#的字节类型; ③public double ToScalarDouble(); 将M类型转换成C#的双精度类型; double temp=((MWNumericArray)(mwArgout[0])).ToScalarDouble(); ④public float ToScalarFloat(); 将M类型转换成C#的单精度类型; ⑤public int ToScalarInteger(); 将M类型转换成C#的整型类型; ⑥public long ToScalarLong(); 将M类型转换成C#的长整C/C++/C#数据型类型; ⑦public short ToScalarShort(); 将M类型转换成C#的短整型类型; ⑧public override string ToString(); 将M类型转换成C#的字符串类型;string arror=mwArgout[2].ToString(); ⑨public Array ToVector(MWArrayComponent component); 将M类型转换成C#的Array类型,然后可以直接转换成其它类型的数组。 下面使用调试过的代码示例表述①⑨两个函数的区别: ① double[,]Temp1=new double[1,3]; Temp1=(double[,])((MWNumericArray)mwArgout[1]).ToArray(MWArrayComponent.Real);⑨ double[]s1=new double[2]; s1=(double[])((MWNumericArray)mwArgout[1]).ToVector(MWArrayComponent.Real);

MATLAB数据输入和输出

数据输入和输出 一、概述 二、使用输入向导(Import Wizard) 从菜单File->Import Data打开Import Wizard;或者命令窗口输入函数uiimport。 从剪贴板开始Import Wizard:Edit->Paste to workspace。 三、保存和加载MAT文件 MA T文件是双精度、二进制、MA TLAB格式的文件。 输出到MA T文件:save filename [var1 var2 …] [str*];可以通过[var1 var2 …]选择性保存变量;也可以使用通配符“*”。 查看MA T文件中的变量:whos –file 文件名。 存放结构数组的某个字段:加上“-struct”选项。 在已经存在的MA T文件上添加数据:-append选项。 禁止压缩和Unicode字符编码文件,在save语句中加入“-v6”或者File->Preferences-> General->MA T-Files->MA T-File save options->Ensure backward compatibility(-v6)。save语句默认为数据压缩。 选择输出格式:“-ascii”、“-tabs”、“-double”“-v4”。 从MA T文件输入数据:load函数。 四、输入文本数据 各种输入函数的数据定界符: textscan和textread性能比较:前者有更好的性能,特别是读大文件时;使用前者首先要

打开文件,最后要关闭文件,可从文件任意位置读;前者只输出一个单元数组,不必给每个被读字段指定一个输出参数;前者有更多的数据转换选项和更多的用户设置选项。 五、输出文本数据 六、输入/输出标准图像文件 七、输入/输出音频和视频数据 八、输入/输出电子表数据 九、低级文件输入/输出函数

matlab数据类型和转换

matlab数据类型和转换 Matlab中有15种基本数据类型,主要是整型、浮点、逻辑、字符、日期和时间、结构数组、单元格数组以及函数句柄等。 1、整型:(int8;uint8;int16;uint16;int32;uint32;int64;uint64)通过intmax(class)和intmin(class) 函数返回该类整型的最大值和最小值,例如intmax(‘int8’)=127; 2、浮点:(single;double) 浮点数:REALMAX('double')和REALMAX('single')分别返回双精度浮点和单精度浮点的最大值,REALMIN('double')和REALMIN ('single')分别返回双精度浮点和单精度浮点的最小值。 3、逻辑:(logical) Logical:下例是逻辑索引在矩阵操作中的应用,将5*5矩阵中大于0.5的元素设定为0: A = rand(5); A(A>0.5)=0; 4、字符:(char) Matlab中的输入字符需使用单引号。字符串存储为字符数组,每个元素占用一个ASCII字符。如日期字符:Date String=’9/16/2001’ 实际上是一个1行9列向量。构成矩阵或向量的行字符串长度必须相同。可以使用char函数构建字符数组,使用strcat函数连接字符。 例如,命令 name = ['abc' ; 'abcd'] 将触发错误警告,因为两个字符串的长度不等,此时可以通过空字符凑齐如:name = ['abc ' ; 'abcd'],更简单的办法是使用char函数:char(‘abc’,’abcd’),Matlab自动填充空字符以使长度相等,因此字符串矩阵的列纬总是等于最长字符串的字符数. 例如s ize(char(‘abc’,’abcd’))返回结果[2,4],即字符串’abc’实际存在的是’abc ’,此时如需提取矩阵中的某一字符元素,需要使用deblank 函数移除空格如name =char(‘abc’,’abcd’); deblank(name(1,:))。 此外,Matlab同时提供一种更灵活的单元格数组方法,使用函数cellstr 可以将字符串数组转换为单元格数组: data= char(‘abc’,’abcd’) length(data(1,:)) ->? 4 cdata=cellstr(data) length(cdata{1}) ->?3 常用的字符操作函数 blanks(n) 返回n个空字符 deblank(s) 移除字符串尾部包含的空字符 (string) 将字符串作为命令执行 findstr(s1,s2) 搜索字符串 ischar(s) 判断是否字符串 isletter(s) 判断是否字母 lower(s) 转换小写 upper(s) 转换大写 strcmp(s1,s2) 比较字符串是否相同

table-matlab-中table数据类型-创建-调用-访问

table-matlab-中table数据类型-创建-调用-访问

MATLAB table数据结构 目录: ?关于作者 ?table简介 o为什么需要table数据结构 o通过导入数据构造table对象 o调用table构造函数来构造table对象 o通过转换函数构造table对象 ?访问table中的数据 MATLAB常用基本数据类型有:整型,浮点型,字符型,函数句柄,元胞数组和结构体数组。除了这些基本数据类型,MATLAB还有很多其它的数据类型不为人熟悉,这些数据类型在编程中也非常有用。MATLAB高级数据类型系列旨在向大家介绍它们:比如containers.Map, tables,enumeration和time series等等,它们为什么有用,用来解决什么问题,并且怎样在科学工程计算中怎么使用。上篇我们提到了映射表结构(containers.Map )。本篇将介绍另一中新的MATLAB数据类型--table。 table简介 为什么需要table数据结构 MathWorks在MATLAB R2013b中引入了一种新的数据结构叫做table。table类似统计工具箱中的dataset,其引入的目的就是用来取代dataset的数据类型。因为表状的数据在工程计算中越来越长久,有了table类型,MATLAB用户就可以不用购买统计工具箱,也能使用表状的数据结构了。table本质上来说是一种可以存放各种数据类型的容器,比如下面表Table.1中的数据,其中既有

字符型,又有数值类型,其中第一行作为表头:Symbol,Name,Market,Cap,IPO, Year是各列的名字。 Table.1 NASDAQ股票名称表 Symbol Name Market Cap IPO Year AAPL Apple Inc$742.63B1980 AMZN https://www.sodocs.net/doc/fa14578984.html,, Inc $173.33B1997 MSFT Microsoft Corporation $346.9B1986 在conatiners.Map的章节中,我们介绍了MATLAB的基本数据类型(比如数组,原胞数组和结构体)在表达某些复杂数据类型时的局限性。这里不再一一赘述,读者只需要认识到:数组的局限性在于不能用来存放数值以外的数据,而使用元胞读取和索引内容时有种种不方便,比如无法区分该数据中的表头和其余的行数据。事实上,如果数据存放在如下的CSV文件中,并且用importdata 直接读取表Table.2中的CSV文件。 "Symbol","Name","Market Cap","IPO Year" "AAPL","Apple Inc","$742.63B",1980 "AMZN","https://www.sodocs.net/doc/fa14578984.html, Inc","$173.33B",1997 "MSFT","Microsoft Corporation","$346.9B",1986 Table.2 Nasdaq 的 csv 原始数据 读入之后数据将会被分成数值和非数值部分: 1.% 用importdata直接读入CSV文件 2.>> nasdaq = importdata('nasdaq.csv') 3.nasdaq = % 结果存在struct中 4. data: [3x1 double] 5. textdata: {4x4 cell} 6.>> nasdaq.data % csv中的数值部分 7.ans =

Matlab数据类型及基本输入输出

Matlab数据类型及基本输入输出 1、数据类型,声明及赋初值 matlab中存储的数据类型(class)有以下几种: 而实际上matlab不需要对变量做声明,当它发现一个新的变量名时,将默认将其为双精度 浮点类型(double)并分配内存空间。(这比C和Fortran方便了许多,但在完成大运算量的 程序时就显得浪费存储空间了) 当需要把变量a从double转为其他类型的时候,比如要转为int16型,可以使用以下命令: a=int16(a) 当需要创建一个字符型变量x并对其赋初值时,用以下格式:x='字符串'; 注意: (1)在命令后加“;”表示不在command window中显示结果,而对上例来说如果不加“;” 则会显示所赋字符串内容。 (2)所有的命令必须在英文输入状态下,如果使用中文输入状态下全角的“;”,将被处 理为非法字符。 其中logical,cell和structure为逻辑,元胞和构架数组类型,将在后面的数组部分提到 ;function handle为函数句柄类型,将在后面的“M脚本文件和M 函数文件、函数句柄”部 分提到;java类供JA V A API应用程序接口使用,本文不进行说明。最后说明一下,matlab也支持复数操作,赋值的时候直接输入即可,比如:a=1+2i; 2、基本输入输出 输入:v=input('message') %将用户输入的内容赋给变

量v v=input('message','s') %将用户输入的内容作为字符串赋给变量v keyboard %用户可以从键盘输入任意多个指令 v=yesinput('prompt',default,possib) %prompt为文字提示,default为缺省设置“值”,possib为设置值的范围。 %该指令无法在notebook中运行。 输出:disp(a) %显示变量a的内容,另一种显示变量内容的方法是输入变量名,但是这样显示的结果带有 “a=”。

Matlab数据类型与.NET数据类型转换

Matlab数据类型与.NET数据类型转换 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程序集之后交给一个不熟悉

相关主题