对矩阵的基本操作,主要有矩阵的构建、矩阵维度与矩阵大小的改变、矩阵的索引、矩阵属性信息的获取、矩阵结构的改变等。对于这些操作,MATLAB中都有固定指令或相应的库函数与之相对应。
在数学上,定义由 m × n 个数 排成的 m 行 n 列的数表
为 m 行 n 列矩阵,并用大写黑体字母表示它。
只有一行的矩阵
称为行向量。
同理,只有一列的矩阵
称为列向量。
矩阵最早来自于方程组的系数及常数所构成的方阵,这一概念由 19 世纪英国数学家凯利首先提出。
数组是在程序设计中,为了处理方便,把具有相同类型的若干变量按有序的形式组织起来的一种形式。这些按序排列的同类数据元素的集合称为数组。
在MATLAB中,一个数组可以分解为多个数组元素,这些数组元素可以是基本数据类型或是构造类型。因此按数组元素的类型不同,数组又可分为数值数组、字符数组、单元数组、结构数组等各种类别。
由此可见,矩阵和数组在MATLAB中存在很多方面的区别,主要有以下方面。
●矩阵是数学上的概念,而数组是计算机程序设计领域的概念。
作为一种变换或者映射算符的体现,矩阵运算有着明确而严格的数学规则。而数组运算是MATLAB软件定义的规则,其目的是为了使数据管理方便,操作简单,命令形式自然,执行计算有效。
两者间联系主要体现在:在MATLAB中,矩阵是以数组的形式存在的。因此,一维数组相当于向量,二维数组相当于矩阵,所以矩阵是数组的子集。
矩阵的构建方式有两种,一种与单元数组相似,可以对变量直接进行赋值,另一种是MATLAB中提供构建特殊矩阵的指令,如表 2-12 所示。
表 2-12 特殊矩阵的构建函数
续表
简单矩阵采用矩阵构造符号——方括号“[]”,将矩阵元素置于方括号内,同行元素之间用空格或逗号来隔开;行与行之间用分号“;”隔开,格式如下。
●matrixName = [element11,element12,element13;element21,element22,element23]
●matrixName = [element11 element12 element13;element21 element22 element23]
例2-31,简单矩阵构造示例。分别构造一个二维矩阵、一个行向量、一个列向量。
在命令窗口依次输入下列命令:
程序运行过程中的输出如下:
特殊矩阵是指非零元素或零元素的分布有一定规律的矩阵。常见的有对称矩阵、三角矩阵和对角矩阵等。
例 2-32,矩阵构造示例。
在命令窗口输入:
输出结果如下:
在命令窗口输入:
输出结果如下:
通常情况下,矩阵包含 m 行和 n 列,即 m × n 。当 m 和 n 取一些特殊值时,得到的矩阵具有一些特殊的性质。
(1)向量。
当 m =1 或 n =1,即 1× n 或 m ×1 时,建立的矩阵称为向量。例如输入:
得到结果如下:
(2)标量。
当 m = n =1 时,此时建立的矩阵称为标量,任意以 1×1 的矩阵形式表示的单个实数、复数,都是标量。
例 2-33,在MATLAB中,标量有两种表示方法。
例如依次输入:
得到结果如下:
x = 10.000000000000000 + 2.000000000000000i
shape = 1 1
y = 10.000000000000000 + 2.000000000000000i
shape = 1 1
ans = 1
通过上述示例,我们可以知道:单个实数或者复数在MATLAB中都是以矩阵的形式存储的;在MATLAB中,单个数据或由单个数据构造的矩阵都是标量。
(3)空矩阵。
当 m = n =0,或者 m =0,或者 n =0,即 0×0,0× n , m ×0 时,创建的矩阵称为空矩阵。空矩阵可以通过赋值语句建立。例如输入:
得到结果如下:
而再建立一个 0 矩阵,可以输入:
得到结果如下:
空矩阵和 0 矩阵的本质区别在于:空矩阵内没有任何元素,因此不占用任何的存储空间;而 0 矩阵表示该矩阵中的所有元素全部为 0,需要占用一定的存储空间。
根据运算时的不同情况和需要,矩阵大小和结构的改变,主要的方式有旋转矩阵、改变矩阵维度、删除矩阵元素等,MATLAB中提供的具体此类函数如表 2-13 所示。
表 2-13 矩阵旋转与改变维度的函数
续表
例 2-34,矩阵的旋转与维度的改变。
在命令窗口输入:
Randoma = randn( 1,4 ), Randomb = randn( 2 ), Randoma = reshape( Randoma, 2, 2 ),Randoma = fliplr( Randoma ), Randoma = rot90( Randoma ), Randomc = cat( 2, Randoma,Randomb ),
输出结果如下:
在MATLAB中,普通二维数组元素的数字索引分为双下标索引和单下标索引。双下标索引是通过一个二元数组对来对应元素在矩阵中的行列位置,例如 A (2,3)表示矩阵 A 中第 2行第 3 列的元素。单下标索引的方式是采用列元素优先的原则,对 m 行 n 列的矩阵按列排序进行重组,成为一位数组,再取新的一维数组中的元素位置对应的值作为元素在原矩阵中的单下标,例如对于 4×4 的矩阵, A (7)表示矩阵 A 中第 3 行第 2 列的元素,而 A (13)表示矩阵 A 中第 1 行第 4 列的元素。
常用的矩阵索引表达式如表 2-14 所示。
表 2-14 矩阵的索引表达式
例 2-35,矩阵下标的引用示例。
在命令窗口输入:
Matrix = magic( 6 ) , Submatrix = Matrix( 2:3, 3:6 ), Array = Matrix( [7:10 26:31] )
输出结果如下:
矩阵中某一元素的单下标索引值和双下标索引值之间,可以通过MATLAB内部函数进行转换,其句法形式为
IND = sub2ind(siz, i, j)
其功能为将双下标索引值转换为单下标索引值,其中siz是一个包含两个元素的数组,代表了转换矩阵的行列数,一般可以直接用size(A)表示, i 与 j 分别是双下表索引中的行列值,IND是转换后的单下标索引值。
[I J] = ind2sub(siz, ind)
其功能为将单下标索引值转换为双下标索引值,各变量意义同上。
例 2-36,矩阵元素单双下标索引值转换示例。
在命令窗口输入:
Matrix = magic( 3 ); IND = sub2ind( size( Matrix ), 2,3), [I J]=ind2sub( size( Matrix ), 7)
输出结果如下:
IND = 8
I = 1
J = 3
设 A =magic(4),如果需要计算第 4 列元素的和,按照前面介绍的方法可以用下式来实现:
A (1,4) + A (2,4) + A (3,4) + A (4,4)
在下标表达式里,可以用冒号来表示矩阵的多个元素。例如, A (1: k , j )表示矩阵第 j 列的前 k 个元素。利用冒号,第 4 列元素的和可以用更为简洁的式子,代码设置如下:
sum(A(1:4, 4))
还有更简洁的方法,因为冒号本身可以表示一列或者一行的所有元素,所以上式还可以写为
sum(A(:,4))
在MATLAB中提供了一个关键字end,用于表示该维中的最后一个元素。所以上式还可以改写成
sum(A(:,end))
实际上还可以用冒号来表示非相邻的多个元素,例如下面的代码:
A=1:10
B=A(1:3:10)
由上述语句得到输出结果如下:
A=1 2 3 4 5 6 7 8 9 10
B=1 4 7 10
矩阵的信息主要包括矩阵结构、矩阵大小、矩阵维度、矩阵的数据类型及内存占用等。
矩阵的结构是指矩阵子元素的排列方式。MATLAB提供了各种测试函数,如表 2-15所示。
表 2-15 矩阵结构测试函数
这类函数的返回值是逻辑类型的数据。返回值为“1”表示该矩阵是某一特定类型的矩阵;返回值为“0”表示该矩阵不是该特定类型的矩阵。
例 2-37,矩阵数据结构判断函数的使用方法示例。利用zeros函数生成一个 4×4、元素全为 0 的矩阵 A ,并判断矩阵 A 的数据结构。首先输入:
A = zeros(4,4)
得到:
A =
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
再利用表 2-15 中的各函数判断矩阵 A 的数据结构,依次输入的代码和结果分别如下:
矩阵的形状信息,反映了矩阵的大小,通常又包括以下几个方面的内容。
●矩阵的维数。
●矩阵各维(例如最长维、用户指定的维)的长度。
●矩阵元素的个数。
针对上述 3 个方面的信息,相应地,MATLAB提供了 4 个函数,分别获取矩阵形状的相关信息,如表 2-16 所示。
表 2-16 矩阵形状信息的查询函数
例 2-38,矩阵形状信息查询函数的使用示例。下面程序利用eye函数建立一个 5×3 的矩阵,利用ndims函数获得矩阵 A 的维数信息,输入的程序和得到的输出结果依次如下:
A = eye(5,3)
A =
1 0 0
0 1 0
0 0 1
0 0 0
0 0 0
下面,利用ndims函数获得矩阵A的维数信息。
ndims(A)
ans = 2
利用length函数获取矩阵A最长维的长度。
length(A)
ans = 5
利用size函数获取矩阵A各维的长度。
[m,n] = size(A)
m = 5
n = 3
d = size(A)
d = 5 3
e1 = size(A,1)
e1 = 5
e2 = size(A,2)
e2 = 3
由上述size函数的应用可知:①size函数的返回值可以是分开显示的单个实数变量,也可以是一个行向量;②在size函数的输入参数中增加维度参数可以获取指定维度的长度,其中“1”表示行,“2”表示列。
使用numel函数(numel是number of elements的简写)可以获取矩阵 A 中元素的个数。例如,输入:
f = numel(A)
得到的结果如下:
f = 15
例 2-39,数值与矩阵的算术运算示例。
在命令窗口输入:
A = []; B = 1:4; C = [1:4; 5:8];
S1= size(A), S2= size(B), S3= length(B), S4= size(C), S5= length(C), S6= numel(C)
输出结果如下:
S1 = 0 0
S2 = 1 4
S3 = 4
S4 = 2 4
S5 = 4
S6 = 8
对于空矩阵、标量矩阵、一维矩阵和二维矩阵,MATLAB都将其作为普通二维数组对待。特别需要注意的是,用[]产生的空矩阵是作为二维矩阵的,但是在高维矩阵中也有空矩阵的概念,此时空矩阵则具有多个维度。
MATLAB中提供了ndims函数计算矩阵维度。
例 2-40,矩阵维度示例。
在命令窗口输入:
A = []; B = 5; C = 1:3; D = magic(2); E(:,:,2) = [1 2; 3 4];
Ndims = [ndims(A) ndims(B) ndims(C) ndims(D) ndims(E)]
输出结果如下:
Ndims = 2 2 2 2 3
矩阵作为MATLAB的内部数据存储和运算结构,其元素可以是各种各样的数据类型(具体见 2.1 节数据类型),对应不同数据类型的元素,可以是数值、字符串、元胞、结构体等,MATLAB中提供了一系列关于数据类型的测试函数,如表 2-17 所示。
表 2-17 矩阵数据类型的测试函数
这类函数的返回值也是逻辑类型的数据。返回值为“1”表示是某一特定的数据类型;返回值为“0”表示不是该特定的数据类型。
例 2-41,矩阵元素的数据类型的判断示例。
程序如下所示:
A = [2 3;10 7]
isnumeric(A)
isfloat(A)
islogical(A)
得到的结果如下:
A = 2 3
10 7
ans = 1
ans = 1
ans = 0
建立一个字符串矩阵B并进行判断,程序如下所示:
B = ['MATLAB';'course']
isstruct(B)
ischar(B)
得到的结果如下:
B = MATLAB
course
ans = 0
ans = 1
例2-42,矩阵的数据类型示例。
在命令窗口输入:
Mat = magic(2);
TrueorFalse = [isnumeric(Mat) isinteger(Mat) isreal(Mat) isfloat(Mat)]
输出结果如下:
TrueorFalse =
1 0 1 1
例2-43,将矩阵 A 中的实数和复数分开为一个具有实数和复数的矩阵示例。
在命令窗口中输入:
命令窗口中的输出结果如下所示:
real_array =
2.0000 6.5000 3.5000 6.0000
complex_array =
0 + 3.0000i 4.0000 + 2.0000i
了解矩阵的内存占用情况,对于优化MATLAB代码性能是十分重要的。使用者可以通过whos命令查看当前工作区中的指定变量的所有信息,包括变量名,矩阵大小,内存占用和数据类型等。
例 2-44,查看矩阵占用的内存示例。
在命令窗口输入:
Matrix = rand(2)
输出结果如下:
Matrix =
0.2551 0.6991
0.5060 0.8909
在命令窗口输入:
whos Matrix
输出结果如下:
设有矩阵
现用户希望将元素 1 修改成-1,并将 5、6、8、9 这几个矩阵元素以 0 来替代,之后在原始矩阵的最后添加一行,使得新的矩阵 A 满足某方面的使用要求。因此,用户首先要通过一定的途径让MATLAB找到元素“1”及元素区域“5、6、8、9”,接着将这些矩阵元素的值修改,最后增加一行。上述几个方面构成了矩阵元素的基本操作。
本节将介绍矩阵在MATLAB中的存储方式,接着介绍矩阵元素的寻址方法,最后介绍矩阵元素的赋值及扩展。
本节的重点在于让用户理解MATLAB存储矩阵的方法,进而掌握矩阵元素的寻址方法。
设有矩阵 A = ,用户可以通过在MATLAB的命令窗口内直接输入矩阵元素来创建此矩阵:
A = [1 0 -1;2 4 9;-5 3 0]
命令窗口输出如下信息:
A =
1 0 -1
2 4 9
-5 3 0
事实上,MATLAB并不是按照其命令行输出的格式将矩阵 A 存储在内存空间中的。我们可以把内存空间想象成一列网格
而MATLAB就是将矩阵元素按列优先排列的原则依次放置在相应的格子内。因此,可以看成是一个长列向量,即
例如,矩阵第 2 行第 2 列的元素“4”,实际上位于存储空间的第 5 个格子的位置上。由此,MATLAB采用了两种元素寻址方式:①矩阵下标寻址;②线性寻址。
(1)矩阵下标寻址方法。
在MATLAB中,使用 A ( i , j )来表示一个矩阵 A 从左上角数起的第 i 行、第 j 列上的元素,这就是矩阵下标寻址方法。这种方法和线性代数中矩阵元素的引用方法一致,通俗易懂。以下分别介绍利用矩阵下标寻址方法访问矩阵中的单个元素和元素区域。
①单元素的寻访。
当使用双下标访问一个二维矩阵中的某个元素时,必须同时指定该元素所在的行号和列号,访问格式为:
●A(numRow,numColumn)
其中,numRow和numColumn分别代表行号和列号。
例 2-45,单个矩阵元素的访问示例。利用rand函数创建一个 4×3 的 0~1 均匀分布的随机数矩阵 A 并访问其中元素。
输入的程序如下:
A = rand(4,3)
x = A(2,2)
y = A(4,3)
得到的结果如下:
A =
0.957166948242946 0.421761282626275 0.655740699156587
0.485375648722841 0.915735525189067 0.035711678574190
0.800280468888800 0.792207329559554 0.849129305868777
0.141886338627215 0.959492426392903 0.933993247757551
x = 0.915735525189067
y = 0.933993247757551
②矩阵元素区域的寻访。
访问矩阵的多个元素,可以是某一行、某一列或者是其中的部分元素,也可以是矩阵中的某一块区域。在MATLAB中,元素区域的访问需要用到冒号“:”来表示矩阵中的多个元素,具体的访问格式如下。
●A(1:m,n):表示访问第 n 列的第 1 个元素至第 m 个元素。
●A(m,:) :表示访问第 m 行的所有元素。
●A(i:j,m:n) :表示访问从第 i 行至第 j 行,从第 m 列至第 n 列的矩阵区域。
●A(i:inc1:j,m:inc2:n) :表示访问从第 i 行至第 j 行,行间隔为inc1 行;从第 m 列至第 n 列,列间隔为inc2 的非相邻的多个矩阵元素。
例 2-46,矩阵元素区域的访问。利用randn函数创建一个 10×8 的 0~1 正态分布随机矩阵 X ,并进行访问。
输入程序如下:
X = randn(10,8)
A = X(2,:)
B = X(3:8,2:6)
得到的结果如下:
(2)线性寻址。
线性寻址的原理来自于MATLAB将矩阵元素存储在内存空间的存储方法。与矩阵下标寻址相比,只需要单一下标即可实现矩阵中任意位置元素的寻访。线性寻址的下标是通过矩阵的双下标换算得到的。
一般地,设 A 是一个 m × n 的矩阵,位于第 i 行、第 j 列上的元素 A ( i,j) 的单一下标为 A (( j- 1)· m+ i )。
例 2-47,线性寻址示例。建立 3 阶希尔伯特矩阵 A ,并进行线性寻址访问,程序如下:
A = hilb(3)
A(2,3) % 采用矩阵下标寻址的方法访问第 2 行第 3 列的元素
A(8)
得到的结果如下:
A =
1.0000 0.5000 0.3333
0.5000 0.3333 0.2500
0.3333 0.2500 0.2000
ans = 0.2500
ans = 0.2500
(3)矩阵元素的赋值。
MATLAB使用赋值语句对矩阵元素进行赋值,基本语法如下。
●A(i,j) = value :等号左侧为矩阵中的某个元素;右侧为值。
●A = []:删除矩阵中的所有元素。
例 2-48,矩阵元素的赋值示例。利用magic函数建立一个 4 阶的魔幻矩阵 M ,并进行复制操作。
输入的命令如下:
M = magic(4)
M(2,1)=-2
M(3:4,3:4)=0
M = []
whos M % 调用whos函数查看矩阵M的详细信息
得到的结果如下:
(4)矩阵元素的扩展与删除。
增加或删除矩阵元素最常用的办法是使用赋值语句。
例 2-49,对于矩阵 A = ,如果现在要增加一行,则应在命令窗口内输入:
A = [1 1;2 2]
A(3,:) = 3 % 整行赋值
A(4,1) = 4;A(4,2) = 5 % 单个矩阵元素赋值的办法增加新元素
A(2,:) = [] % 使用空矩阵[]删除矩阵中的整行或整列
得到的结果如下:
A =
1 1
2 2
A =
1 1
2 2
3 3
A =
1 1
2 2
3 3
4 5
A =
1 1
3 3
4 5
此外,MATLAB提供了多个函数进行矩阵合并操作,从而实现将多个矩阵合并成一个矩阵。这些函数详见表 2-18。
表 2-18 矩阵合并函数
例 2-50,矩阵合并函数示例。
①设有矩阵 A = 、矩阵 B= 1 、矩阵 C= ,利用cat函数分别对矩阵 A 、 B 及矩阵 A 、 C 进行合并操作,函数中的输入参数 DIM 分别取 DIM= 1 及 DIM= 2。
首先输入:
A = [2 0 -1;1 3 2];
B = [1 7 -1;4 2 3;2 0 1];
C = [1 0 1 0;-1 2 0 1];
得到矩阵 A 、 B 、 C 。使用cat函数对矩阵 A 、 B 进行合并操作。
MAB1 = cat(1,A,B) % 将矩阵A、B按行合并
得到结果如下:
MAB1 =
2 0 -1
1 3 2
1 7 -1
4 2 3
2 0 1
如果合并错误,如
MAB2 = cat(2,A,B) % 将矩阵A、B按列合并
MAC1 = cat(1,A,C) % 将矩阵A、B按行合并
得到结果如下:
Error using cat
CAT arguments dimensions are not consistent.
使用cat函数对矩阵 A 、 C 进行合并操作,输入如下:
MAC2 = cat(2,A,C) % 将矩阵A、C按列合并
得到结果如下:
MAC2 =
2 0 -1 1 0 1 0
1 3 2 -1 2 0 1
为了探究矩阵 A 、 B 按列合并及矩阵 A 、 C 按列合并发生错误的原因,将合并后的矩阵列出来,如下所示。
可以看出,由于两个矩阵在某个维度上的长度不一致,导致新的矩阵出现残缺。
因此,cat及其相关的函数在将两个矩阵按某个维度进行合并操作时,一定要满足原始的 2 个矩阵要在某一个维度上具有相同的长度,否则MATLAB在进行计算时会发生错误。
②使用blkdiag函数构造块对角化矩阵。例如输入:
A = [1 1;2 2];B=[3 3;4 4];C=[5 5;6 6];
Y = blkdiag(A,B,C)
得到
Y =
1 1 0 0 0 0
2 2 0 0 0 0
0 0 3 3 0 0
0 0 4 4 0 0
0 0 0 0 5 5
0 0 0 0 6 6