8 多维数组
在实际应用的过程中,经常需要构造多于二维的数组,我们将多于二维的数组统称为多维数组。
对于二维数组,人们习惯于把数组的第1维称为“行”,把第2维称为“列”,我们将第3维称为“页”。
由于更多维的数组的显示并不直观,所以本节以三维数组为例来介绍多维数组的使用。
8.1 多维数组的创建
创建多维数组最常用的方法有以下4种。
(1)直接通过“全下标”元素赋值的方式创建多维数组。
(2)由若干同样尺寸的二维数组组合成多维数组。
(3)由函数ones、zeros、rand、randn等直接创建特殊多维数组。
(4)借助cat、repmat、reshape等函数构建多维数组。
【例2-26】 采用“全下标”元素赋值方式创建多维数组示例。
>> A(3,3,3)=1 % 创建3*3*3数组,未赋值元素默认设置为0
A(:,:,1) =
0 0 0
0 0 0
0 0 0
A(:,:,2) =
0 0 0
0 0 0
0 0 0
A(:,:,3) =
0 0 0
0 0 0
0 0 1
>> B(3,4,:)=1:4 %创建3*4*4数组
B(:,:,1) =
0 0 0 0
0 0 0 0
0 0 0 1
B(:,:,2) =
0 0 0 0
0 0 0 0
0 0 0 2
B(:,:,3) =
0 0 0 0
0 0 0 0
0 0 0 3
B(:,:,4) =
0 0 0 0
0 0 0 0
0 0 0 4
【例2-27】 由二维数组合成多维数组示例。
>> clear
>> A(:,:,1)=magic(4); % 创建数组A第1页的数据
>> A(:,:,2)=ones(4); % 创建数组A第2页的数据
>> A(:,:,3)=zeros(4) % 创建数组A第3页的数据
A(:,:,1) =
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
A(:,:,2) =
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
A(:,:,3) =
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
【例2-28】 由函数rand直接创建特殊多维数组示例。
>> rand('state', 0); %设置随机种子,便于读者验证
>> B=rand(3,4,3)
B(:,:,1) =
0.9501 0.4860 0.4565 0.4447
0.2311 0.8913 0.0185 0.6154
0.6068 0.7621 0.8214 0.7919
B(:,:,2) =
0.9218 0.4057 0.4103 0.3529
0.7382 0.9355 0.8936 0.8132
0.1763 0.9169 0.0579 0.0099
B(:,:,3) =
0.1389 0.6038 0.0153 0.9318
0.2028 0.2722 0.7468 0.4660
0.1987 0.1988 0.4451 0.4186
【例2-29】 借助cat函数构建多维数组示例。
>>B=cat(3,ones(2,3),ones(2,3)*2,ones(2,3)*3)
B(:,:,1) =
1 1 1
1 1 1
B(:,:,2) =
2 2 2
2 2 2
B(:,:,3) =
3 3 3
3 3 3
cat指令第1个输入变量填写的数字“表示扩展方向的维号”。本例第1个输入变量是3,表示“沿第3维方向扩展”。为了对比下面我们分别演示使用cat函数沿其他方向进行扩展的情况。
>>B=cat(2,ones(2,3),ones(2,3)*2,ones(2,3)*3) % 沿第2维方向扩展
B =
1 1 1 2 2 2 3 3 3
1 1 1 2 2 2 3 3 3
>>B=cat(1,ones(2,3),ones(2,3)*2,ones(2,3)*3) % 沿第1维方向扩展
B =
1 1 1
1 1 1
2 2 2
2 2 2
3 3 3
3 3 3
>>B=cat(4,ones(2,3),ones(2,3)*2,ones(2,3)*3) % 沿第4维方向扩展
B(:,:,1,1) =
1 1 1
1 1 1
B(:,:,1,2) =
2 2 2
2 2 2
B(:,:,1,3) =
3 3 3
3 3 3
【例2-30】 借助repmat函数构建多维数组示例。
>> repmat([1,2;3,4;5,6],[1,2,3])
ans(:,:,1) =
1 2 1 2
3 4 3 4
5 6 5 6
ans(:,:,2) =
1 2 1 2
3 4 3 4
5 6 5 6
ans(:,:,3) =
1 2 1 2
3 4 3 4
5 6 5 6
repmat函数的第1个输入变量是构成多维数组的源数组。第2个输入变量是指定向各维方向上扩展的源数组个数。本例中输入变量[1,2,3]是指将源数组在行方向上扩展为1个,在列方向上扩展为2个,在页方向上扩展为3个。
【例2-31】 借助reshape函数构建多维数组示例。
>> A=reshape(1:60,5,4,3)
A(:,:,1) =
1 6 11 16
2 7 12 17
3 8 13 18
4 9 14 19
5 10 15 20
A(:,:,2) =
21 26 31 36
22 27 32 37
23 28 33 38
24 29 34 39
25 30 35 40
A(:,:,3) =
41 46 51 56
42 47 52 57
43 48 53 58
44 49 54 59
45 50 55 60
>> B=reshape(A,4,5,3)
B(:,:,1) =
1 5 9 13 17
2 6 10 14 18
3 7 11 15 19
4 8 12 16 20
B(:,:,2) =
21 25 29 33 37
22 26 30 34 38
23 27 31 35 39
24 28 32 36 40
B(:,:,3) =
41 45 49 53 57
42 46 50 54 58
43 47 51 55 59
44 48 52 56 60
reshape的第1个输入变量是源数组,第2、3、4个输入变量是要生成的数组的行数、列数和页数。将要生成的数组必须和源数组的元素的个数相同。重组时,元素排列遵循“单下标”编号规则:第1页的第1列接该页的第2列,直至第1页最后一列。在第1页排列结束后,开始排列第2页的第1列,依次类推,直至所有的元素排列结束。
8.2 多维数组的寻访与重构
1.多维数组的寻访
多维数组的寻访和二维数组一样,可以使用“全下标”、“单下标”和“逻辑下标”来寻访。“全下标”和“逻辑下标”两种形式与二维数组相同,是以非常直观的形式来表现的,这里不再赘述。而多维数组的“单下标”就比较复杂一点。本小节对此进行介绍。
多维数组的“单下标”其实就是二维数组“单下标”的扩展,换句话说,二维数组的“单下标”编排方式是“单下标”的一种简单形式。用语言表示就是:将数组“全下标”格式中的各维按照出现的先后顺序依次循环,直至将所有的数据编排成为一列。
【例2-32】 多维数组“单下标”排列示例。
>> a=ones(2,2,2,2) %创建全为1的2*2*2*2四维数组a
a(:,:,1,1) =
1 1
1 1
a(:,:,2,1) =
1 1
1 1
a(:,:,1,2) =
1 1
1 1
a(:,:,2,2) =
1 1
1 1
>> a(1:16)=1:16 % 按照单下标形式为数组a赋值
a(:,:,1,1) =
1 3
2 4
a(:,:,2,1) =
5 7
6 8
a(:,:,1,2) =
9 11
10 12
a(:,:,2,2) =
13 15
14 16
从得到结果中的数组a被赋值以后的各元素分布,可以看出多维数组是如何按照“全下标”的各维顺序来存储数据的。
2.多维数组的重构
除了前面介绍的可以用来进行多维数组的重构函数cat、repmat和reshape之外,还有其他一些函数可用来进行多维数组的重构,详见表2-10。
表2-10 多维数组重构函数
函数形式函数功能函数形式函数功能
permute广义非共轭转置flipdim以指定维交换对称位置上的元素
ipermute广义反转置,permute的反操作shiftdim维移动函数
【例2-33】 多维数组元素对称交换函数flipdim使用示例。
>> A=reshape(1:18,2,3,3) %创建演示三维数组
A(:,:,1) =
1 3 5
2 4 6
A(:,:,2) =
7 9 11
8 10 12
A(:,:,3) =
13 15 17
14 16 18
>> B=flipdim(A,1) % 以第1维进行对称变换
B(:,:,1) =
2 4 6
1 3 5
B(:,:,2) =
8 10 12
7 9 11
B(:,:,3) =
14 16 18
13 15 17
>> C=flipdim(A,3) % 以第3维进行对称变换
C(:,:,1) =
13 15 17
14 16 18
C(:,:,2) =
7 9 11
8 10 12
C(:,:,3) =
1 3 5
2 4 6
从本例可以看出,函数flipdim(A,k)中的输入变量k就是指进行对称变换的维。另外flipdim(A,k)函数也可用于二维数组,读者可以自行验证。
【例2-34】 多维数组元素维移动函数shiftdim使用示例。
本例在上例所建立的三维数组A上进行演示。
>> D=shiftdim(A,1) % 将各维向左移动1位,使2*3*3数组变成3*3*2数组
D(:,:,1) =
1 7 13
3 9 15
5 11 17
D(:,:,2) =
2 8 14
4 10 16
6 12 18
>> E=shiftdim(A,2) % 将各维向左移动2位,使2*3*3数组变成3*2*3数组
E(:,:,1) =
1 2
7 8
13 14
E(:,:,2) =
3 4
9 10
15 16
E(:,:,3) =
5 6
11 12
17 18
运算D=shiftdim(A,1)实现以下操作:D(j,k,i)=A(i,j,k),i, j, k分别是指各维的下标。对于三维数组,D=shiftdim(A,3)的操作就等同于简单的D=A。
【例2-35】 多维数组元素广义非共轭函数permute使用示例。
本例在上例所建立的三维数组A上进行演示。
>> F=permute(A,[3 2 1])
F(:,:,1) =
1 3 5
7 9 11
13 15 17
F(:,:,2) =
2 4 6
8 10 12
14 16 18
>> G=permute(A,[3 1 2])
G(:,:,1) =
1 2
7 8
13 14
G(:,:,2) =
3 4
9 10
15 16
G(:,:,3) =
5 6
11 12
17 18
运算F=permute(A, [3 2 1])实现以下操作:F(k,j,i)=A(i,j,k),i, j, k分别是指各维的下标。函数permute就是函数shiftdim的特殊形式,它可以任意指定维的移动顺序。
网友评论