数组和矩阵

在MATLAB中,所有数据都用数组或矩阵形式进行保存。本节主要介绍构造数组和矩阵的方法。[大谦MATLAB,dqmatlab点com]

注意:数组和矩阵属于数据结构的范畴,而非数据类型。请读者在概念上区分开来。

数组

在MATLAB中构造数组的方法很简单,只需要用空格或逗号间隔数组元素,然后用方括号括起来就行了。如

code.matlab
x=[0 2 3 6 7 8]

就构造了一个有6个元素的数组x。

除直接构造外,还有一些常用的构造方法,下面介绍其中的两种方法,即增量法和linspace函数法。

1.用增量法构造数组

利用MATLAB提供的冒号运算符(first:last)可以生成1n的矩阵,即数组。数组中的元素按顺序从first一直到last。默认序列是以增量方式生成的,后面的数比它前面的第一个数大1。

【例2-7】在命令窗口中输入

code.matlab
A = 10:15
A =
    10    11    12    13    14    15

数组不必由正整数组成,也可以包括负值和小数。如

code.matlab
A = -2.5:2.5
A =
   -2.5000   -1.5000   -0.5000    0.5000    1.5000    2.5000

在默认情况下,MATLAB创建序列时增量总是为1,即使最后的值不是整数也行。如

code.matlab
A = 1:6.3
A =
     1     2     3     4     5     6

同样,冒号运算符生成的默认序列总是增序排列的(而不是减序排列的)。下面试图生成减序排列的数值序列,结果失败。

code.matlab
A = 9:1
A =
   空矩阵: 10

实际上,在使用冒号运算符时可以指定增量步长值。可以使用(first:step:last)的格式。比如创建一个10~50增量为5的数值序列:

code.matlab
A = 10:5:50
A =
    10    15    20    25    30    35    40    45    50

增量也可以是小数,比如,在下面的例子中增量为0.2:

code.matlab
A = 3:0.2:3.8
A =
    3.0000    3.2000    3.4000    3.6000    3.8000

当指定增量为负时,创建减序数值序列:

code.matlab
A = 9:-1:1
A =
    9    8    7    6    5    4    3    2    1

2.用linspace函数法构造数组

用linspace函数法构造数组,需要指定首尾值和元素的总个数。其基本形式是:

code.matlab
x=linspace(first,last,num)

其中,first、last和num分别为x数组的首尾元素和元素个数。

【例2-8】在命令窗口中输入

code.matlab
x=linspace(0,10,5)
x =
         0    2.5000    5.0000    7.5000   10.0000

矩阵

在MATLAB中,二维数组被称为矩阵。下面介绍几种创建矩阵的方法。

1.简单的创建方法

MATLAB中创建矩阵最简单的方法是使用矩阵创建符号[]。在方括号内输入多个元素可以创建矩阵的一个行。用逗号或空格把每个元素间隔开:

code.matlab
row = [E1, E2, ..., Em]          row = [E1 E2 ... Em]

【例2-9】输入下面的代码,创建一个包含5个元素的行:

code.matlab
A = [12 62 93 -8 22];

如果想另起一行,则可以用分号终止当前行:

code.matlab
A = [row1; row2; ...; rown]

下面创建一个3行5列的数值矩阵。注意,所有的行必须具有相同的元素个数:

code.matlab
A = [12 62 93 -8 22; 16 2 87 43 91; -4 17 -72 95 6]
A =
    12    62    93    -8    22
    16     2    87    43    91
    -4    17   -72    95     6

2.构造特殊矩阵

MATLAB中提供了多个创建不同矩阵的函数,如表2-4所示。利用这些函数可以构造各种特殊矩阵。

表2-4 构造特殊矩阵的函数

函 数 功 能
ones 创建一个所有元素都为1的矩阵
zeros 创建一个所有元素都为0的矩阵
eye 创建对角线元素为1,其他元素为0的矩阵
accumarray 将输入矩阵的元素分配到输出矩阵中的指定位置
diag 根据矢量创建对角矩阵
magic 创建一个方形矩阵,其中行、列和对角线上元素的和相等
rand 创建一个矩阵或数组,其中的元素为服从均匀分布的随机数
randn 创建一个矩阵或数组,其中的元素为服从正态分布的随机数
randperm 创建一个矢量(1n的矩阵)

表2-4中所列的大部分函数返回double型的矩阵。另外,可以用ones,zeros和eye函数很容易地生成任何数值类型的基本数组。

要做到这一点,需要将MATLAB数据类型名称作为最后一个变量。

【例2-10】在命令窗口中输入

code.matlab
A = zeros(4, 6, 'uint32')
A =
        0        0        0        0        0        0
        0        0        0        0        0        0
        0        0        0        0        0        0
        0        0        0        0        0        0

【例2-11】下面创建一个55魔方矩阵:

code.matlab
A = magic(5)
A =
    17    24     1     8    15
    23     5     7    14    16
     4     6    13    20    22
    10    12    19    21     3
    11    18    25     2     9

注意:矩阵中的每一行、每一列和每个主对角线上的数值加起来都等于65。

【例2-12】下面创建元素为服从均匀分布的随机数的矩阵或数组,将每个元素乘以20:

code.matlab
A = rand(5) * 20
A =
    3.8686   13.9580    9.9310   13.2046   14.5423
   13.6445    7.5675   17.9954    6.8394    6.1858
    6.0553   17.2002   16.4326    5.7945   16.7699
   10.8335   17.0731   12.8982    6.8239   11.3614
    3.0175   11.8713   16.3595   10.6816    7.4083

【例2-13】下面根据矢量元素创建对角矩阵。可以将矢量元素放在矩阵的主对角线上,或者放在主对角线的上方或下方,如下所示,其中-1表示将矢量元素放在主对角线下方:

code.matlab
A = [12 62 93 -8 22];
B = diag(A, -1)
B =
     0     0     0     0     0     0
    12     0     0     0     0     0
     0    62     0     0     0     0
     0     0    93     0     0     0
     0     0     0    -8     0     0
     0     0     0     0    22     0

3.聚合矩阵

矩阵聚合是通过连接一个或多个矩阵来形成新的矩阵。符号[ ]不仅是矩阵构造符,还是MATLAB聚合运算符。表达式C=[A B]在水平方向上聚合矩阵A和B,表达式C=[A;B]在垂直方向上聚合它们。

【例2-14】通过在垂直方向上聚合矩阵A和B来构造新矩阵C:

code.matlab
A = ones(2, 5) * 6;        % 25的矩阵,元素为6
B = rand(3, 5);           % 35的矩阵,元素为随机数
C = [A; B]              % 垂向聚合A和B
C =
    6.0000    6.0000    6.0000    6.0000    6.0000
    6.0000    6.0000    6.0000    6.0000    6.0000
    0.6154    0.7382    0.9355    0.8936    0.8132
    0.7919    0.1763    0.9169    0.0579    0.0099
    0.9218    0.4057    0.4103    0.3529    0.1389

可以用聚合的方法创建矩阵甚至多维数组,但不能生成不规则的形状(必须是矩形)。如果是在水平方向上生成矩阵,则每个子矩阵必须具有相同的行数;如果是在垂直方向上生成矩阵,则每个子矩阵必须具有相同的列数。

图2-2所示的为两个具有相同高度的矩阵在水平方向上组合成一个新的矩阵。

Document Image

图2-2 聚合具有相同高度的矩阵

图2-3所示的为水平组合两个具有不同高度的矩阵的情况。但是MATLAB不允许这样做。

Document Image

图2-3 聚合不同高度的矩阵

利用表2-5中所示的函数可以将多个矩阵组合成一个新的矩阵。

表2-5 聚合矩阵的函数

函 数 描 述
cat 沿指定的维聚合矩阵
horzcat 水平方向聚合矩阵
vertcat 垂直方向聚合矩阵
repmat 通过复制和叠置矩阵来创建新矩阵
blkdiag 用已有矩阵创建块对角矩阵

下面几个例子演示了表2-5中函数的使用。

使用cat,horzcat和vertcat函数可以代替[ ]符号实现矩阵的聚合。

【例2-15】下面的两条语句都可以实现命令C=[A;B]所得到的效果:

code.matlab
C = cat(1, A, B);       % 沿第一维聚合
C = vertcat(A, B);      % 垂直方向聚合

用repmat函数可以利用已有矩阵的多个副本来创建矩阵。命令repmat(M, v, h)将矩阵M在垂直方向上复制v次,在水平方向上复制h次。

【例2-16】下面将已有矩阵A复制到新矩阵B中。

code.matlab
A = [8 1 6; 3 5 7; 4 9 2]
A =
   8   1   6
   3   5   7
   4   9   2
B = repmat(A, 2, 4)
B =
   8   1   6   8   1   6   8   1   6   8   1   6
   3   5   7   3   5   7   3   5   7   3   5   7
   4   9   2   4   9   2   4   9   2   4   9   2
   8   1   6   8   1   6   8   1   6   8   1   6
   3   5   7   3   5   7   3   5   7   3   5   7
   4   9   2   4   9   2   4   9   2   4   9   2

【例2-17】下面用blkdiag函数创建块对角矩阵。

code.matlab
A = magic(3);
B = [-; -4 -4 -2];
C = eye(2) * 8;
D = blkdiag(A, B, C)
D =
   8   1   6   0   0   0   0   0
   3   5   7   0   0   0   0   0
   4   9   2   0   0   0   0   0
   0   0     -9    0   0
   0   0     -2    0   0
   0   0   0   0   0   0   8   0
   0   0   0   0   0   0   0   8

4.组合不同类型的数据

在聚合矩阵时,如果矩阵的数据类型不同,则MATLAB会自动对某些元素进行类型转换,而生成的矩阵具有相同的类型。

在用一个高精度的矩阵和一个低精度的矩阵聚合新矩阵时,新矩阵是低精度型的。例如,在聚合double型和single型的矩阵时,总是生成single型的矩阵。MATLAB会先将double型元素转换为single型。

【例2-18】如果用空矩阵参与矩聚合阵,则空矩阵将被忽略:

code.matlab
A = [5.36; 7.01; []; 9.44]
A =
    5.3600
    7.0100
    9.4400

【例2-19】下面是几个不同类型矩阵聚合的例子。

single型和double型矩阵聚合

code.matlab
x = [single(4.5) single(-2.8) pi 5.73*10^300]
x =
    4.5000   -2.8000    3.1416       Inf
class(x)              % 显示x的数据类型
ans =
   single

integer型和double型矩阵聚合

code.matlab
x = [int8(21) int8(-22) int8(23) pi 45/6]
x =
    21   -22    23     3     8
class(x)
ans =
   int8

字符型和double型矩阵聚合

code.matlab
x = ['A' 'B' 'C' 68 69 70]
x =
   ABCDEF
class(x)
ans =
   char

逻辑型和double型矩阵聚合

code.matlab
x = [true false false pi sqrt(7)]
x =
    1.0000         0         0    3.1416    2.6458
class(x)
ans =
   double

5.获取矩阵的元素

利用编号和索引,可以获取MATLAB矩阵的元素。

要引用矩阵中的特殊元素,可以用下面的语法指定它的行号和列号,其中A是矩阵变量。按先行后列的顺序指定。

code.matlab
A(row, column)

【例2-20】下面获取矩阵中的元素。

对于44的魔方矩阵A

code.matlab
A = magic(4)
A =
    16     2     3    13
     5    11    10     8
     9     7     6    12
     4    14    15     1

下面获取第4行第2列处的元素

code.matlab
A(4, 2)
ans =
    14

在MATLAB中,可以用单个编号引用矩阵中的元素。在MATLAB中保存矩阵中的数据时,不是按照它们显示在MATLAB命令窗口中的形状保存,而是作为单一元素列保存的。这个元素列又是由矩阵中的所有列组成的,后一列元素按先后顺序被添加到前一列元素的最后。所以,矩阵A

code.matlab
A = [2 6 9; 4 2 8; 3 0 1]
A =
     2     6     9
     4     2     8
     3     5     1

在内存中是按下面的序列保存的:

code.matlab
2, 4, 3, 6, 2, 5, 9, 8, 1

矩阵A中第3行第2列的元素可以看作实际保存序列中的第6个元素。要获取这个元素,可以使用标准语法A(3,2)或使用A(6)。当使用线性索引方式时,如果矩阵大小为[d1 d2],即d1行d2列,则位置(i,j)处的元素在保存序列中的位置为

code.matlab
(j-1) * d1 + i

比如上面矩阵A的大小为[3 3],则位置(3,2)处的元素在保存序列中的位置为(2-1)3+3,即6。

如果已知行-列编号但是想用线性索引,则可以用sub2ind函数进行转换。

【例2-21】将上述矩阵A的行列索引(3,2)转换为线性索引6:

code.matlab
A = [2 6 9; 4 2 8; 3 0 1];
linearindex = sub2ind(size(A), 3, 2)
linearindex =
     6

同样,用ind2sub函数根据线性索引值获取行-列索引值。

【例2-22】在命令窗口中输入

code.matlab
[row col] = ind2sub(size(A), 6)
row =
     3
col =
     2

【例2-23】假设A是一个44的矩阵,下面利用行-列索引方式求得第4列元素的和。

code.matlab
A = magic(4);
A(1,4) + A(2,4) + A(3,4) + A(4,4)

可以用冒号运算符和sum函数获得上面第二行语句的运行结果:

code.matlab
sum(A(1:4,4))

【例2-24】下面将矩阵B中的元素每间隔两个元素处的值改为-10。

code.matlab
B = A;
B(1:3:16) = -10
B =
   -10     2     3   -10
     5    11   -10     8
     9   -10     6    12
   -10    14    15   -10

利用end关键字可以指定矩阵某维的最后一个元素。此方法适用于不知道矩阵有多少行或多少列的情况。例如,可以用下面的语句进行值的替换:

code.matlab
B(1:3:end) = -10

利用冒号可以引用矩阵某行或列的所有元素。使用下面的语句,可以计算44的魔方矩阵A中所有元素的和。

code.matlab
sum(A(:, 2))
ans =
    34

将冒号用作线性索引,可以引用整个矩阵中的所有元素。下面的语句显示矩阵A中的所有元素,并按列序返回它们。

code.matlab
A(:)
ans =
    16
     5
     9
     4
     .
     .
     .
    12
     1

6.获取与矩阵有关的信息

表2-6中的函数可以返回关于矩阵形状和大小的信息。

表2-6 返回矩阵信息的函数

函 数 功 能
length 返回最长维的长度
ndims 返回维数
numel 返回元素个数
size 返回每一维的长度

【例2-25】下面演示表2-6中部分函数的应用例子。

code.matlab
A = rand(5) * 10;
A(4:5, :) = []
A =
    9.5013    7.6210    6.1543    4.0571    0.5789
    2.3114    4.5647    7.9194    9.3547    3.5287
    6.0684    0.1850    9.2181    9.1690    8.1317

% 计算矩阵A中所有元素值的均值

code.matlab
sum(A(:))/numel(A)
ans =
    5.8909

% 查找矩阵中大小为5~7的元素

code.matlab
if ndims(A) ~= 2
   return
end
[rows cols] = size(A);
for m = 1:rows
   for n = 1:cols
      x = A(m, n);
      if x >= 5 && x <= 7
         disp(sprintf('A(%d, %d) = %5.2f', m, n, A(m,n)))
      end
   end
end

返回结果:

code.matlab
A(1, 3) = 6.15
A(3, 1) = 6.07

注意:这里用到了流程控制语句,关于流程控制的详细说明,请参见第3章内容。

表2-7中的函数用于检查矩阵中的元素是否属于指定的数据类型。

表2-7 检查数据类型的函数

函 数 功 能
isa 确定输入数据是否属于给定类型
iscell 确定输入数据是否属于单元数组
iscellstr 确定输入数据是否属于字符串单元数组
ischar 确定输入数据是否属于字符串
isfloat 确定输入数据是否属于浮点数组
isinteger 确定输入数据是否属于整型数组
islogical 确定输入数据是否属于逻辑数组
isnumeric 确定输入数据是否属于数值数组
isreal 确定输入数据是否属于实型值数组
isstruct 确定输入数据是否属于结构数组

【例2-26】从矢量中找出数值型元素。

code.matlab
A = [5+7i 8/7 4.23 39j pi 9-2i];
for m = 1:numel(A)
   if isnumeric(A(m)) && isreal(A(m))
      disp(A(m))
   end
end

返回值为:

code.matlab
1.1429
4.2300
3.1416

表2-8中的函数可以检查矩阵中的元素是否为指定的数据结构。

表2-8 检查数据结构的函数

函 数 功 能
isempty 确定输入数据是否为空
isscalar 确定输入数据是否为标量
issparse 确定输入数据是否为稀疏矩阵
isvector 确定输入数据是否为矢量

多维数组

可以使用与创建二维矩阵相同的方式创建多维数组。另外,MATLAB中还提供了一个特别的聚合函数用来生成多维数组。

1.用索引生成多维数组

创建多维数组的方法之一是先创建一个二维数组,然后扩展它。

【例2-27】用索引生成多维数组。

在命令窗口中输入:

code.matlab
A = [5 7 8; 0 1 9; 4 3 6];

A是一个33的数值,即它的行维和列维都是3。给A添加第三维。

code.matlab
A(:,:,2) = [1 0 4; 3 5 6; 9 8 7]

可通过增大多维数组的索引值来扩展多维数组,如:

code.matlab
A(:,:,3) = 5;
A(:,:,3)
ans =
     5     5     5
     5     5     5
     5     5     5

下面把A扩展成一个3332的四维数组。输入:

code.matlab
A(:,:,1,2) = [1 2 3; 4 5 6; 7 8 9];
A(:,:,2,2) = [9 8 7; 6 5 4; 3 2 1];
A(:,:,3,2) = [1 0 1; 1 1 0; 0 1 1];

2.用MATLAB函数生成多维数组

可以使用与创建二维数组相同的方式(如使用randn、ones和zeros函数等)生成多维数组。其中提供的每个变量表示生成的数组中对应维的大小。

【例2-28】创建一个元素为正态分布随机数的432的数组。

在命令窗口中输入

code.matlab
B = randn(4,3,2)

要生成一个元素均为同一个常数的数组,使用repmat函数。

【例2-29】如:

code.matlab
B = repmat(5,[3 4 2])
B(:,:,1) =
     5     5     5     5
     5     5     5     5
     5     5     5     5
B(:,:,2) =
     5     5     5     5
     5     5     5     5
     5     5     5     5

注意:通过将数组的任何维设置为空数组的形式,可以使该维的大小为0。

3.用cat函数生成多维数组

cat函数是创建多维数组的一种简单方式,它按指定的维数将多个数组聚合到一起。其语法格式为:

code.matlab
B = cat(dim,A1,A2…)

其中A1, A2等是进行聚合的数组,dim是维数。

【例2-30】下面用cat函数创建一个新的数组B:

code.matlab
B = cat(3,[2 8; 0 5],[1 3; 7 9])
B(:,:,1) =
     2     8
     0     5
B(:,:,2) =
     1     3
     7     9

cat函数接受任何原有数据和新数据。另外,可以嵌套调用cat函数。

【例2-31】下面创建一个四维数组。

code.matlab
A = cat(3,[9 2; 6 5],[7 1; 8 4]);
B = cat(3,[3 5; 0 1],[5 6; 2 1]);
D = cat(4,A,B,cat(3,[1 2; 3 4],[4 3;2 1]))
D(:,:,1,1) =
     9     2
     6     5
D(:,:,2,1) =
     7     1
     8     4
D(:,:,1,2) =
     3     5
     0     1
D(:,:,2,2) =
     5     6
     2     1
D(:,:,1,3) =
     1     2
     3     4
D(:,:,2,3) =
     4     3
     2     1