1、第六章 数据阵列类型与结构,6.1 多维阵列 6.2 结构阵列 6.3 单元阵列 6.4 复杂矩阵结构 6.5 多维阵列、结构阵列和单元阵列函数 习题,6.1 多 维 阵 列,6.1.1 多维阵列多维阵列是二维矩阵的推广。矩阵有二维:行和列,利用两个下标可访问矩阵元素,第一个下标表示行号,第二个下标表示列号。多维阵列应使用三个以上的下标来访问,以三维阵列为例,它有三个下标,第一个表示行号,第二个表示列号,第三个表示页号。图6.1表示一个443的多维阵列结构。例如,访问阵列A的第二页第三行第四列的元素,则可以采用A(3, 4, 2)。,图6.1 443的多维阵列结构,6.1.2 建立多维阵列建立
2、多维阵列与建立矩阵的方法类似。但MATLAB还为建立多维阵列提供了专门的函数。建立多维阵列可采用四种方法: 利用下标建立多维阵列。 利用MATLAB函数产生多维阵列。 利用cat函数建立多维阵列。 用户自己编写M文件产生多维阵列。,1利用下标建立多维阵列建立多维阵列可从产生二维矩阵出发,扩展其维数,从而得到多维阵列。例如,先产生一个矩阵A=5 7 2; 0 1 2; 3 4 2;这时A只是一个33的矩阵,实际上也可看作是331的阵列,因此再输入,A(:, :, 2)=2 7 3; 4 2 8; 2 0 3 A(:,:,1) =5 7 20 1 23 4 2 A(:,:,2) =2 7 34 2
3、 82 0 3 这说明我们已经产生了一个332的多维矩阵A。,如果要扩展维的所有元素均相同,则可用标量来输入。例如: A(:,:,3)=6; A(:,:,3) ans =6 6 66 6 66 6 6,进一步扩展维数可得到4维阵列: A(:,:,1,2)=eye(3); A(:,:,2,2)=5*eye(3); A(:,:,3,2)=10*eye(3); size(A) ans =3 3 3 2 这说明得到的矩阵A为3332维。,2利用MATLAB函数产生多维阵列利用MATLAB的函数(如rand、randn、ones、zeros等)都可直接产生多维阵列,在函数调用时可指定每一维的尺寸。例如,
4、为产生10032维的正态分布随机数R,可输入R=randn(100, 3, 2);为产生各元素相同的多维阵列,可采用ones函数,也可采用repmat函数,如输入 A=5*ones(3, 4, 2); B=repmat(5, 3 4 2); 这两个多维阵列是相同的,即A=B。,3利用cat函数建立多维阵列利用cat函数建立多维阵列是方便的,任何两个维数适当的阵列可按指定维进行连接,从而可以产生更高维阵列。例如输入A=2 8; 0 5; B=1 8; 2 4;当它们沿着第三维以上的维进行连接时,可得到多维阵列,如输入:,C=cat(3,A,B); D=cat(4,A,B); size(C) an
5、s =2 2 2 size(D) ans =2 2 1 2 这说明得到的C为222维,而D为2212维。,当某一维的尺寸为1时,则称这一维为单点维,比如D中第三维为单点维。cat函数还可以嵌套调用。例如继续输入:E=cat(3,C,cat(3,11 12;13 14,5 6;7 8);这时产生的E为224维。,4用户自定义M文件产生多维阵列对于任意指定的多维阵列,用户都可以编写专门的M文件来产生,这样可避免在设计中过多地在程序中输入数据。在实际记录每天、每月、每年测量的有关数据时,也可以编写M文件将它们组合成多维阵列,从而提供给设计者使用。,6.1.3 多维阵列信息利用MATLAB函数和命令可
6、以获得多维阵列的信息,ndims函数可获得多维阵列的维数,size函数可得到阵列各维的尺寸,whos命令可得到阵列的存储和格式。例如,继续上面产生的阵列,输入:, whosName Size Bytes ClassA 22 32 double arrayB 22 32 double arrayC 222 64 double arrayD 4-D 64 double arrayE 224 128 double arrayans 14 32 double array Grand total is 44 elements using 352 bytes size(E) ans =2 2 4 ndim
7、s(E) ans =3,6.1.4 多维阵列的使用许多应用于二维矩阵的概念和技术也可以应用于多维阵列,主要有 下标访问技术。 阵列重新排列。 阵列的序列变换。 为说明这几种技术,先产生一多维随机整数阵列:d=fix(20*randn(10,5,3);这一阵列为1053维,而且其元素取值为整数。,1下标访问技术访问多维阵列中的元素应采用各维的下标,例如,访问第2页(3,2)位置上的元素可采用d(3,2,2)。而且在下标中可以采用向量,表示多个元素,例如,取第3页(2,1)、(2,3)和(2,4)上的元素时,可输入 d(2, 1 3 4,3) ans=13 24 17,冒号(:)操作符在向量和矩阵
8、操作中起着重要作用,同样在多维阵列中,也可以利用冒号来使用多维阵列。例如: x1=d(:,3,2) x1 =31-102431-41,582721-15-5 说明取出d中第2页第3列的所有元素。同样 x2=d(2:3,1:2,1) x2 =-41 -10-14 -18 说明取出d中第1页由2、3行,1、2列构成的22矩阵。,同样在赋值号左边也可以使用冒号,如d(1,:,2)=1:5 表示用1、2、5取代第2页第1行上的5个元素。,2阵列重新排列我们还可以在建立多维阵列之后改变其尺寸和维数。其方法是直接在多维阵列中添加或删除元素有可能改变阵列的尺寸和维数,也可以利用reshape函数,在保持所有
9、元素个数和内容的前提下,改变其尺寸和维数。例如:, M=cat(3,fix(15*rand(3,4),fix(10*rand(3,4) M(:,:,1) =2 9 0 133 4 11 62 2 6 6 M(:,:,2) =8 6 6 55 8 3 72 0 8 4,则输入: N=reshape(M,4,6) N =2 4 6 8 8 83 2 13 5 0 52 0 6 2 6 79 11 6 6 3 4可以看出,reshape函数是按列方式操作的。又如对上面产生d,有下列合法指令: y1=reshape(d,6 25) y2=reshape(d,5 3 10) y3=reshape(d,2
10、 5 3 5),应注意, prod(size(d)=prod(size(y1)=prod(size(y2)=prod(size(y3),这一点也是采用reshape函数的基本要求。利用squeeze函数可以删除多维阵列中的单点维,例如: b=repmat(6,4 3 1 3); c=squeeze(b); size(b) ans =4 3 1 3 size(c) ans =4 3 3但应注意,squeeze对二维阵列(即矩阵)不起作用。,3阵列的序列变换permute函数可改变多维阵列中指定维的次序,例如,对于前面产生的M阵列,有 M1=permute(M,2 1 3) M1(:,:,1) =
11、2 3 29 4 20 11 613 6 6 M1(:,:,2) =8 5 26 8 06 3 85 7 4,在命令中,2表示原M阵列的第二维,l、3分别表示M阵列的第一、三维,这一命令说明将M阵列的第一维与第二维交换,也就完成了每页上二维阵列的转置,又如: A=randn(5, 4, 3, 2); B=permute(A, 2 4 3 1); size(B) ans =4 2 3 5实际上,可以将多维阵列的序列变换看作是二维阵列(矩阵)转置的扩展。在序列变换中也可直接确定出元素之间的位置关系,在上例中A(4,2,1,2)=B(2,2,1,4)。,6.1.5 多维阵列计算1面向向量的函数对这一
12、类函数(如sum,mean等)通常总是在第一个非单点维上操作,而且大多数函数允许指定操作的维。但是也有例外,比如cross函数(求两个向量的外积)缺省时在第一个长度为3的维上进行操作。,2面向元素的函数按元素对元素的操作函数,如三角函数、指数函数等,可按对二维阵列的操作方式对多维阵列进行处理。例如,设x为mnp维阵列,则y=sin(x)也为mnp维阵列,而且其每个元素分别是x中相应元素的正弦值,即y(i,j,k)=sin(x(i,j,k)。同样,算术、逻辑和关系操作符也可按元素对元素的方式对多维阵列进行处理,其结果阵列的维数和尺寸与输入相同。但如果操作数中有一个为标量,另一个为阵列,则在标量与
13、阵列的所有元素之间应用指定的操作符。,3面向矩阵的函数面向矩阵的函数(如线性代数函数和矩阵函数),不能应用于多维阵列,给这些函数提供多维阵列会导致一个错误。例如: A=randn(4,4,5); eig(A) ? Error using = eig Input arguments must be 2-D.,这说明eig函数不能应用于多维阵列。但我们可从多维阵列中取出一部分,以作为这类函数的输入,只要维数、尺寸适当,也是完全可以的。例如: eig(A(:,:,3) ans =-0.2439 0.7981 + 2.0230i0.7981 - 2.0230i2.7431,6.1.6 多维阵列的数据组
14、织多维阵列可表示两类数据: 表示成二维数据的平面或页,这样可将这些页当作矩阵处理。 表示成多变量或多维数据,例如要表示一个房间中栅格点上的温度或气压,则应用四维阵列表示。现在考虑RGB图像数据,它是一个三维阵列,其组织结构如图6.2所示。这样要访问RGB的整个平面时,可输入red_plane=RGB(:,:,1);,访问三个平面上的一块子区域,可输入subimage=RGB(15:25,50:85,:);相应某一点(如(4,3)的红、绿、蓝三色强度分别为RGB(4,3,1),RGB(4,3,2),RGB(4,3,3)。每一点上的颜色可根据三色原理进行计算:Color=0.30*RGB(:,:,
15、1)+0.59*RGB(:,:,2)+0.11*RGB(:,:,3),图6.2 RGB图像数据阵列的组织,6.2 结 构 阵 列,6.2.1 建立结构阵列 建立结构阵列有两种方式: 使用赋值语句。 使用struct函数。,1利用赋值语句建立结构阵列利用赋值语句可对结构阵列的各个域进行赋值,注意结构名与域名之间用句点分隔,例如,为建立表示患者病情的结构,可输入 patient.name=John Doe; patient.billing=127.00; patient.test=79 75 73;180 178 177.5;220 210 205;,这时就建立起了一个具有三个域的结构patien
16、t,当输入 patient patient = name: John Doebilling: 127test: 3x3 double size(patient) ans = 1 1,这表明patient中包含有一个结构元素。我们很容易在已有结构中添加新的结构元素: patient(2).name=Ann Lane; patient(2).billing=28.50; patient(2).test=68 70 68;118 118 119;172 170 169; 这时再输入 patient patient = 1x2 struct array with fields:namebilling
17、test,MATLAB约定,当结构中包含两个以上的结构元素时,输入阵列名时不再显示出各个元素的值,而是显示阵列的结构信息。当结构中仅包含一个结构元素时,则输入阵列名时可显示出各个元素的值。利用fieldnames函数可直接得到结构的域名,如可输入 n=fieldnames(patient) n = namebillingtest,在扩展结构时,MATLAB会对未指定值的域填入空阵列,以确保 结构阵列中的所有元素具有相同数量的域。 所有的域具有相同的域名。例如再输入patient(3).name=Alan Johnson;,这时虽然尚未输入第三个结构元素的billing和test域,但它们已经存
18、在,其内容为空阵列,可输入: patient(3) ans= name:Alan Johnson billing: test:,假设我们在输入patient(3).billing时写错了域名: patient(3).biling=95.8; patient(3).test=37 38 36; 119 121 120; 165 166 159; 这时 patient patient = 1x3 struct array with fields:namebillingtestbiling,说明,这时patient中有三个结构元素,每个元素有四个域,实际上,前两个元素的biling域为空,第三个元素
19、的billing域也为空。为解决这种错误,可用rmfield函数删除错误的域名:patient=rmfield(patient,biling);patient(3).billing=95.8,2利用struct函数建立结构阵列利用struct函数可方便地建立结构阵列,例如,将前面产生的patient结构改成patient1=struct(name,John Doe,billing,127,.test,79 75 73; 180 178 177.5; 220 210 205);这时可产生一个结构元素的结构阵列patient1。利用单元阵列还可以一次输入多个结构元素,例如输入, n=John Do
20、e Ann Lane Alan Johnson 这是一个单元阵列 n = John Doe Ann Lane Alan Johnson b=127 28.5 95.8; t1=79 75 73; 180 178 177.5; 220 210 205; t2=68 70 68; 118 118 119; 172 170 169; t3=37 38 36; 119 121 120; 165 166 159; patient2=struct(name,n,billing,b,test,t1 t2 t3); patient2 patient2 = 13 struct array with fields
21、:namebilling test,6.2.2 结构阵列数据的使用在结构阵列中,利用结构名后的括号指示第n个结构元素,利用句点引出的域名指示相应的域,因此有 str=patmnt(2).name str=Ann Lane n1=patient(1).test(3,2) n1=210,这样每次只能得到结构中一个域的赋值,如果要得到多个域的赋值,则可采用循环,例如: for i=1:length(patient) disp(patient(i).name); end 则执行后可得 John Doe Ann Lane Alan Johnson,访问结构阵列中的元素可采用下标,例如: second=p
22、atient(2) second=name: Ann Lane billing: 28.5000 test: 3x3 double 利用getfield函数可方便地得到域值,如输入 str=getfield(patient,2,name) str=Ann Lane V=getfield(patient,1,test,2:3,1:2) V=180 178220 210,另外,利用setfield可改变结构的域值,例如: patient=setfield(patient,1,test,2,1,185); V1=getfield(patient,1,test,2:3,1:2) V1=185 1782
23、20 210 注意V与V1的区别,这说明了setfield函数所起的作用。,6.2.3 结构阵列应用于函数和操作符与普通阵列一样,MATLAB的函数和操作符可以应用于结构阵列中的域和域元素,例如,为求出patient(2)中test阵列的列均值,可输入 mean(patient(2).test) ans=119.3333 119.3333 118.6667,有时可采用多种方法来完成指定的功能,例如,要计算patient中各病人的费用之和,这时可利用循环来计算: total=0; for i=1:length(patient) total=total+patient(i).billing end
24、 disp(total)251.3000,为简化操作,MATLAB可对结构阵列中同名域的数据进行直接处理,例如,上述操作可简化为 total=sum(patient.billing) total=251.3000,6.2.4 结构阵列的数据组织结构阵列数据的组织方式,应该以方便使用、意义直观为基本出发点。例如,对一个独立存储的三个128128的RGB阵列,RED、GREEN和BLUE如图6.3所示,要用它们构成结构阵列至少有两种方法:平面组织和元素对元素组织,如图6.4所示。,图6.3 独立存储的RGB数据,图6.4 两种结构阵列的组织方法,1平面组织在平面组织方式下,结构的每个域是整个图像平
25、面,因此这种结构的建立可通过下列命令完成: A.r=RED; A.g=GREEN; A.b=BLUE;这样定义的结构可容易提取红、绿、蓝这三个平面的数据,以供滤波、变换及显示之用。例如,获得红色全平面数据可输入red_plane = A.r;,平面组织方式还有一个优点,它很容易扩展到更多的平面或者多个图像,比如在本例中,如果存在多个图像,则可将它们组织到A(2)、A(3)等结构中。平面组织的缺点是,在访问平面的子集时比较麻烦。例如,要访问图像的子集,应分别输入 red_sub=A.r(2:12;13:30); grn_sub=A.g(2:12;13:30); blue_sub=A.b(2:12
26、;13:30);,2元素对元素组织元素对元素组织可方便地访问数据的子集,但为建立这种结构,应采用循环程序: for i=1:size(RED,1) for j=1:size(RED,2) B(i,j).r=RED(i,j); B(i,j).g=GREEN(i,j); B(i,j).b=BLUE(i,j); end end,这时访问子集比较容易: B_sub=B(2:12,13:30); 但访问整个平面的数据又显得麻烦: red_plane=zeros(128,128); for i=1: (128*128) red_plane(i)=B(i).r; end,6.2.5 结构嵌套在结构阵列中,其
27、域值可以是另一个已定义过的结构,这称之为结构嵌套。这种结构嵌套给我们提供了灵活的思维空间,可以设计出复杂的结构,甚至可用来设计简单的数 据库。这里以一个示例来说明嵌套结构阵列的建立与使用。先利用struct建立嵌套结构阵列的一个元素,然后利用赋值语句进行扩展,如输入,A=struct(data,3 4 7;8 0 1,nest, struct(testnum,Test 1,xdata,4 2 8,ydata,7 1 6); A(2).data=9 3 2;7 6 5; A(2).nest.testnum=Test 2; A(2).nest.xdata=3 4 2; A(2).nest.ydat
28、a=5 0 9,图6.5 嵌套结构阵列, A(1).data ans =3 4 78 0 1 A(2).nest ans = testnum: Test 2xdata: 3 4 2ydata: 5 0 9 A(2).nest.testnum ans = Test 2 A(2).nest.ydata(1,3) ans =9,6.2.6 设计举例,利用结构阵列可方便地构造简单的数据库。现根据某校某教研室三位教师的教学情况构成结构阵列,其教学情况如表6.1所示。,表6.1 教师教学情况,从图中可以看出,结构阵列中除了应给出教师的基本信息(姓名、出生日期、职称和学位)外,还应给出每位教师承担教学的情况
29、,并且约定每位教师一年的课程至多为三门,每门课程又给出课程名称、学时、学分和学生人数等信息。根据这种结构上的要求,可选用嵌套结构来实现教学情况的记录。MATLAB程序为,Teacher(3)=struct(name,张智胜,bdate,571219,profp,教授,degree,博士, CourA,A,CourB,B,CourC,C);这时得到了教师情况的结构阵列Teacher。为计算各位教师的工作量可输入 for i=1:length(Teacher) w=Teacher(i).CourA.time+Teacher(i).CourB.time+Teacher(i).CourC.time;d
30、isp(strcat(Teacher(i).name,全年工作量为) num2str(w) end,执行后可以统计出每位教师的年工作量如下: 王国庆全年工作量为196 陈立新全年工作量为186 张智胜全年工作量为82 为查询陈立新教师的上课情况,可输入 disp(Teacher(2) disp(Teacher(2).CourA) disp(Teacher(2).CourB) disp(Teacher(2).CourC),执行后得到 name: 陈立新 bdate: 620317 profp: 副教授 degree: 硕士 CourA: 1x1 struct CourB: 1x1 struct
31、CourC: 1x1 struct,Cname: 微机原理 time: 90 core: 6 stu: 51 Cname: 计算机通信 time: 36 core: 2 stu: 45 Cname: 线性代数 time: 60 core: 4 stu: 86,6.3 单 元 阵 列,MATLAB允许将不同类型的阵列组合成一种新的阵列,这一阵列称之为单元阵列。单元阵列中的每个单元可以是标量、向量、矩阵、多维阵列、字符阵列、结构阵列等,从而构成一个复杂的存储结构。图6.6是单元阵列的一个示例。,图6.6 单元阵列示例,示例中的单元阵列的尺寸为23,但每个单元的类型不尽相同,其中cell 1,2为结
32、构阵列,cell 2,3为另一个单元阵列。,6.3.1 建立单元阵列 建立单元阵列有两种方法: 使用赋值语句。 使用cell函数预分配阵列,然后再对单元赋值。,1利用赋值语句建立单元阵列利用赋值语句可对一个单元阵列进行赋值,与一般阵列赋值时使用方括号不同,它应使用花括号,花括号可出现在赋值号右边,也可以出现在左边。例如,建立22单元阵列A,可输入 A(1,1)=1 4 3; 0 5 8; 7 2 9; A(1,2)=Anne Smith; A(2,1)=3+7i; A(2,2)= -pi:pi/10:pi;,为得到同样的单元阵列A,也可以输入 A1,1=1 4 3; 0 5 8; 7 2 9;
33、 A1,2=Anne Smith; A2,1=3+7i; A2,2=-pi:pi/10:pi;,应该注意,在建立单元阵列之前应确保不存在同名的数值阵列。如果在建立单元阵列时已存在同名阵列,则MATLAB试图“混合”单元阵列与数值阵列,从而导致错误。类似地,如果已存在单元阵列,则在对该同名阵列简单赋值时并不能清除单元阵列。 显示单元阵列可直接输入阵列名,也可采用celldisp和cellplot函数。例如:, A A = 3x3 double Anne Smith 3.0000+7.0000i 1x21 double celldisp(A),A1,1 =1 4 30 5 87 2 9 A2,1
34、=3.0000 + 7.0000i A1,2 = Anne Smith A2,2 =Columns 1 through 8 -3.1416 -2.8274 -2.5133 -2.1991 -1.8850 -1.5708 -1.2566 -0.9425 Columns 9 through 16 -0.6283 -0.3142 0 0.3142 0.6283 0.9425 1.2566 1.5708Columns 17 through 21 1.8850 2.1991 2.5133 2.8274 3.1416,如果输入 cellplot(A) 则可显示出如图6.7所示的图形。,2利用cell函数定
35、义单元阵列cell函数可预分配单元阵列,但其内容为空阵列。例如,建立23的单元阵列,可输入B=cell(2,3);然后利用赋值语句可以给各个单元赋值,如输入, B(1,3)=1:4; B(2,2)=rand(3,3); B B = 1x4 double 3x3 double ,图6.7 单元阵列显示,6.3.2 单元阵列数据的使用 利用单元阵列的下标可访问单元阵列元素。例如: N1,1=1 2; 4 5; N1,2=Name; N2,1=2-4i; N2,2=7; 则可有 C C = Name d=N1,1(2,2) d =5,我们还可以从已定义的单元阵列中取出一部分构成新的单元阵列,比如在上
36、面的基础上再输入, N3,1=No1; N3,2=No2; N3,3=No3; N N = 2x2 double Name 2.0000 -4.0000i 7 No1 No2 No3,这表示N为33单元阵列,未输入的单元为空阵列。如果输入 M=N(1:3,1:2) M = 2x2 double Name2.0000-4.0000i 7No1 No2这说明M是取N中的(1:3, 1:2)的元素构成的新的单元阵列。,单元阵列中元素的删除与其它阵列类似,例如,为删除N的第3列,可输入N(:,3)=;这时得到的N与M相同。为删除N中(2,3)的元素,应输入N2,3=;注意这两种格式在使用花括号和圆括号
37、上的细微区别。,利用reshape函数也可以改变单元阵列的结构,例如: A=cell(3,4); size(A) ans =3 4 B=reshape(A,6,2); size(B) ans =6 2,6.3.3 利用单元阵列取代变量列表单元阵列可以取代函数输入、函数输出、显示操作和阵列构造(方括号和花括号内)中的变量列表。如果在花括号内采用冒号操作符指示多个单元,则相当于指示多个独立的单元内容,例如,T1:5指示单元阵列T中第1个到第5个元素。例如考虑C阵列 c(1)=1 2 3; c(2)=2 5 9; c(3)=0:2:10; c(4)= -4 8 2; c(5)=4;,为求出向量c(1
38、)和c(2)的卷积,可输入 d=conv(c1:2) d =2 9 25 33 27 显示出向量c(2),c(3),c(4) c2:4 ans =2 5 9 ans =0 2 4 6 8 10 ans =-4 8 2,构造新的数值阵列B B=c1;c2;c4 B =1 2 32 5 9-4 8 2 求矩阵B的特征向量和特征值 D1:2=eig(B) D = 3x3 double 3x3 double,显示出特征向量和特征值 D1 ans =-0.1592 -0.7915 0.2958-0.6645 -0.4628 0.79450.7301 0.3993 0.5304 D2 ans =-4.40
39、90 0 00 0.6561 00 0 11.7529,6.3.4 单元阵列应用于函数和操作符 利用下标可将函数和操作符应用于单元阵列。例如: A1,1=pascal(3); A1,2=randn(4,4); A1,3=0:0.1:1; A1,4=1 2;7 3; 求A1,1的和值 M1=sum(A1,1) M1 =3 6 10,通过循环可对所有单元进行处理,例如计算各单元的均值 for i=1:length(A) Mi=mean(A1,i); end celldisp(M) M1 =1.0000 2.0000 3.3333 M2 =-0.4213 0.2990 0.2603 0.3931 M
40、3 = 0.5000 M4 =3.0000 2.5000,利用各种操作符对单元阵列进行处理,例如为求出A1, 2中其值落在-0.5, 0.5区间的元素,可输入 L=abs(A1,2)=0.5 L =1 0 1 00 0 1 01 0 1 11 1 0 1,6.3.5 单元阵列的数据组织单元阵列对组织具有不同尺寸或类型的数据是非常有用的,它比结构更具有包容性,它可应用于 利用一条语句访问多个数据域。 利用逗号间隔的变量表访问数据子集。 不具备固定的域名。 从结构中删除域名。,在上述这四种应用中,很难利用结构来实现,但利用单元阵列却能很好地解决。例如,假定你在实验中获得了这样一些数据: 测量值阵列
41、(34)。 技术名称(由15个字符构成)。 过去五次实验的测量值(345)。 对这一问题,可用结构(TEST)表示: TEST. measure TEST. name TEST. pastm,也可以用单元阵列表示。但当经常访问的是前两个域时,使用单元阵列就显得更加方便,而且可在一条赋值语句中完成访问操作,即对单元阵列的访问 newdata, name=deal(TEST1:2);而对结构阵列的访问:newdata=TEST.measure;name=TEST.name;在函数中经常使用的变量varargin和varargout是单元阵列应用的两个示例,它们可替代以逗号间隔的变量列表。例如,对于
42、33的数值矩阵A=0 1 2; 4 0 7; 3 1 2;,利用normest函数可计算出A的2范数估值及其迭代计算的次数,其输出可直接赋值给单元变量: B1:2=normest(A) B = 8.8826 4 其中B1为A的2范数,B2为迭代计算次数。,6.3.6 嵌套单元阵列一个单元阵列中可以包含另一个单元阵列,甚至可包含单元阵列的阵列,这称之为单元阵列的嵌套。利用花括号、cell函数及赋值语句可建立嵌套的单元阵列。 建立嵌套的单元阵列可以使用花括号,例如输入 A(1,1)=magic(5); A(1,2)=第二层 1 2;3 4 ; -pi pi 第三层 17;,这样就建立了嵌套单元阵列
43、,我们可查看其结构 A A = 5x5 double 2x2 cell 这说明在A1,2上为一个22的单元阵列, 再显示其结构 A1,2 ans = 第二层 2x2 double1x2 double 1x2 cell ,发现在A1,22,2上仍为单元阵列 A1,22,2 ans = 第三层 17 因此建立的阵列A为三层嵌套的单元阵列。,利用cell函数也可以建立嵌套的单元阵列,例如: B=cell(1,2); B(1,2)=cell(2,2); B(1,1)=magic(5); B1,2(1,1)=第二层; B1,2(1,2)=1 2;3 4; B1,2(2,1)= -pi pi; B1,2(
44、2,2)=第三层 17; 这时得到的B阵列与A一样,也是三层嵌套的单元阵列。,6.3.7 单元阵列与数值阵列之间的变换 单元阵列与数值阵列之间的变换应采用循环程序。 num=15*randn(4,3,5); N=prod(size(num); c=cell(1,N); for i=1:Nci=num(i); end c=reshape(c,size(num);,通过显示数值阵列num和单元阵列c的相应单元的内容来确定转换的有效性:, num(:,:,3) ans =-10.3766 -21.6145 12.234312.8700 8.5672 10.678618.8100 -5.9983 19
45、.3537-23.9059 10.3500 10.0290 c(:,:,3) ans = -10.3766 -21.6145 12.2343 12.8700 8.5672 10.6786 18.8100 5.9983 19.3537-23.9059 10.3500 10.0290,另外,还可以采用num2cell函数进行从数值到单元阵列的变换: c1=num2cell(num,1 2); c13 ans =-10.3766 -21.6145 12.234312.8700 8.5672 10.678618.8100 -5.9983 19.3537-23.9059 10.3500 10.0290,
46、相反,也可以将单元阵列变换成数值阵列: m,n,p=size(num); for k=1:pfor i=1:mfor j=1:nnum1(i,j,k)=c1k(i,j);endend end num1(:,:,3) ans =-10.3766 -21.6145 12.234312.8700 8.5672 10.678618.8100 -5.9983 19.3537-23.9059 10.3500 10.0290,6.4 复杂矩阵结构,6.4.1 多维单元阵列与数值阵列类似,多维单元阵列是二维单元阵列模型的扩展,这可利用cat函数连接产生。例如,下列程序产生了一个简单的三维单元阵列C:,A1,1=1 2;4 5; A1,2=Name; A2,1=2-4i; A2,2=7; B1,1=Name2; B1,2=3; B2,1=0:1:3; B2,2=4 5; C=cat(3,A,B) size(C) ans =2 2 2,