为什么matlab的数组那么强,关于matlab数组操作的讨论

matlab是靠它灵活数组操作发的家,但是数组操作也是初学者最难理解的matlab特色之一,因为在其他语言中(如C、pascal)不存在对等的语法和语义。在5.x版中新增添的多维数组(N-D数组),进一步扩展了matlab的功能,迎合了许多多维的科学计算。但matlab中的很多函数只支持对向量和矩阵的操作,因此迫切要求我们掌握多维到一二维之间升降维数的命令。

一、matlab环境中对数据的物理存放形式

在matlab中数据的逻辑形式可以表现出多维,但物理上在内存中的形式却是很简单按列存放的。这就说明为什么有一些函数只对列向量操作,而一些计算密集的函数,对矩阵的方向很敏感(如图像处理工具箱)。这些函数对于非列向量的输入要重新排序成列向量的形式。

对于一个矩阵,在内存中的单元存放顺序是:第一列的单元,第二列单元,。。。最后一列。

u =

0.9501 0.4860 0.4565

0.2311 0.8913 0.0185

0.6068 0.7621 0.8214

u(:)

ans =

0.9501

0.2311

0.6068

0.4860

0.8913

0.7621

0.4565

0.0185

0.8214

对于多维的数组,则是把第二维以后的维数作为数据平面(plane)来看,存放的顺序是:第一个plane中的矩阵,第二个plane中的矩阵。。。

u=[1,2;3,4];

u(:,:,2)=[5,6;7,8];

u(:,:,1) =

1 2

3 4

u(:,:,2) =

5 6

7 8

?u(:)

ans =

1

3

2

4

5

7

6

8

可以从单元的逻辑下标算出它所在的物理位置,相反的计算也是一定的。如维数[d1,d2,d3]的三维数组中的一个单元(a,b,c)的物理位置是(a-1)*d2*d3+(b-1)*d3+c。

二、数组的下标

在matlab中的数组下标是很灵活的,可以进行维间的合并和扩展,维内的抽取和扩展。

1、维内的抽取

抽取的下标的数值要在被抽取数组维的大小以内,不能小于1或大于维的实际长度d。表示抽取下标的序列可以是任何数组形式,但matlab会自动将其转换为一列向量,如前面所描述的一样。该抽取下标序列可以有重复的数值,这样被抽取出来的序列值就会重复出现。这是一个很有用的操作,比如说已有一个表面上顶点的坐标的数组,现在要构造一个三角面的序列来表示该表面,这里就要从顶点数组中抽取数值,而且要重复,因为通常三个三角面要公用一个顶点。

u([2,1,1],:,:)

ans(:,:,1) =

3 4

1 2

1 2

ans(:,:,2) =

7 8

5 6

5 6

u(:,[2,1;2 2],:)

ans(:,:,1) =

2 2 1 2

4 4 3 4

ans(:,:,2) =

6 6 5 6

8 8 7 8

2、维内的扩展

在c或pascal之类的通用的算法语言中,要使数组动态增加或减少某些维的长度是很困难的事情,这里涉及的操作包括重新申请一个内存块,拷贝原有的数据(要重新计算地址),释放原有的块。而在matlab中它屏蔽了这些烦人的工作,对用户是透明的。

在第一维(行)扩展,扩展只能在维末进行。

u(3,:,:)=[10,11;12,13]

u(:,:,1) =

1 2

3 4

10 12

u(:,:,2) =

5 6

7 8

11 13

在第一维删除一行,可以删除该维的中间部分

u(3,:,:)=[]

u(:,:,1) =

1 2

3 4

u(:,:,2) =

5 6

7 8

3、维间的抽取

matlab试图对你输入的多维数组的下标进行匹配。

如果你给的下标数目小于实际该数组的维数,而且最后一个下标非“:”号,则matlab则会将后面的维都以下标为1以来处理。

u(:,1)

ans =

1

3

如果最后一个下标为“:”,则将该维以及后面的维展成一维的向量,看看下面的例子。

u(:,:)

ans =

1 2 5 6

3 4 7 8

u(1,:)

ans =

1 2 5 6

三、多维数组维间处理的几个函数

1、最重要的函数应当是reshape,它的功能是将数据从一种空间形式转换为另一种,但又一个前提即这两个空间要能够匹配,它们所表示的点一样多。设一个空间Di,另一个空间Xi,如果D1*D2*D3……Dn=X1*X2*X3……*Xm则它们之间是匹配的,可以转化

将u变为1*2*4的空间

t=reshape(u,1,2,4)

t(:,:,1) =

1 3

t(:,:,2) =

2 4

t(:,:,3) =

5 7

t(:,:,4) =

6 8

我们要注意的是,重构后数据的物理存储顺序没有变化,变得只是访问的下标。

t(:)

ans =

1

3

2

4

5

7

6

8

以上是实际的存储次序,和前面的一样。

2、size函数告诉我们输入的数组单元的维数和维的长度。

size(t)

ans =

1 2 4

3、ndims函数实际上可以写成length(size(x))

4、cat函数连接两个多维数组,但要注意cat只能让你在一个维上连接,a、b两个多维数组在除了要连接的维上可以长度不同外,其他各维的尺寸必须一致。

x=[0,0; 0 0];

cat(3,x,u)

ans(:,:,1) =

0 0

0 0

ans(:,:,2) =

1 2

3 4

ans(:,:,3) =

5 6

7 8

cat(2,x,u) %2*2和2*1的无法连起来

?? Error using ==> cat

CAT arguments dimensions are not consistent.

5、permute函数改变维的次序。

h=permute(u,[3,2,1]) %将原来的第三维变为第一维,而原来的第一维改成第三维

h(:,:,1) =

1 2

5 6

h(:,:,2) =

3 4

7 8

h(:)

ans =

1

5

2

6

3

7

4

8

我们注意到数据的物理存储次序发生了变化。

6、ipermute函数是permute的逆运算,其实只不过是的书写和阅读比较容易而已,把permute中的order参数改一改也能实现改功能,如果用type

impermute你就可以看到permute函数的调用。

7、shiftdim和permute差不多,但它是能循环移动维数。请注意它还有去奇异维(即该维的长度为1)的功能,这和squeeze函数一样,不同的是只去开头的奇异维。

8、squeeze函数将多维数组中的奇异维去掉,请注意这样的操作不减少该数组空间上的单元的数目。squeeze操作在求导,差分等运算之前做预处理是很有必要的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值