
2.2 基本矩阵操作
2.2.1 矩阵和数组的概念及其区别
对矩阵的基本操作,主要有矩阵的构造、矩阵大小及结构的改变、矩阵下标引用、矩阵信息的获取等。对于这些操作,MATLAB中都有固定指令或相应的库函数与之相对应。
在数学上,定义由个数
排成的
行
列的数表

为m行n列矩阵,并用大写黑体字母表示它。
只有一行的矩阵

称为行向量。
同理,只有一列的矩阵

称为列向量。
矩阵最早来自方程组的系数及常数所构成的方阵,这一概念由19世纪英国数学家凯利首先提出。数组是在程序设计中,为了处理方便,把具有相同类型的若干变量按有序的形式组织起来的一种形式。这些按序排列的同类数据元素的集合称为数组。
在MATLAB中,一个数组可以分解为多个数组元素,这些数组元素可以是基本数据类型或构造类型。因此,按数组元素的类型不同,数组又可分为数值数组、字符数组、单元数组、结构数组等。
由此可见,矩阵和数组在MATLAB中存在很多方面的区别,主要有以下几个方面:
● 矩阵是数学上的概念,而数组是计算机程序设计领域的概念。
● 作为一种变换或者映射运算符的体现,矩阵运算有着明确而严格的数学规则;而数组运算是MATLAB软件定义的规则,其目的是使数据管理方便,操作简单,命令形式自然,执行计算有效。
两者间的联系主要体现在:在MATLAB中,矩阵是以数组的形式存在的。因此,一维数组相当于向量,二维数组相当于矩阵,所以矩阵是数组的子集。
2.2.2 矩阵的构造
矩阵的构造方式有两种,一种与单元数组相似,可以对变量直接进行赋值;另一种是使用MATLAB中提供的构造特殊矩阵的函数,如表2-12所示。
表2-12 特殊矩阵的构造函数

续表

1.建立简单矩阵
简单矩阵采用矩阵构造符号——方括号“[]”,将矩阵元素置于方括号内,同行元素之间用空格或逗号隔开,行与行之间用分号“;”隔开,格式如下:

例2-31:简单矩阵构造示例。
分别构造一个二维矩阵、一个行向量、一个列向量。在命令行窗口中依次输入:

程序运行过程中的输出如下:

2.建立特殊矩阵
特殊矩阵是指非零元素或零元素的分布有一定规律的矩阵,常见的特殊矩阵有对称矩阵、三角矩阵和对角矩阵等。
例2-32:特殊矩阵构造示例。
在命令行窗口中输入:

输出结果:

在命令行窗口中输入:

输出结果:

3.向量、标量和空矩阵
通常情况下,矩阵包含m行n列,即m×n。当m和n取一些特殊值时,得到的矩阵具有一些特殊的性质。
(1)向量。
当m=1或n=1,即1×n或m×1时,建立的矩阵称为向量。例如输入:

得到结果:

(2)标量。
当m=n=1时,建立的矩阵称为标量。任意以1×1的矩阵形式表示的单个实数、复数都是标量。
例2-33:在MATLAB中,标量有两种表示方法。例如,在命令行窗口中依次输入:

得到结果:

通过上述示例可知,单个实数或复数在MATLAB中都是以矩阵的形式存储的;在MATLAB中,单个数据或由单个数据构造的矩阵都是标量。
(3)空矩阵。
当m=n=0,或者m=0,或者n=0,即0×0、0×n、m×0时,创建的矩阵称为空矩阵。空矩阵可以通过赋值语句建立。例如输入:

得到结果:

而再建立一个0矩阵,可以输入:

得到结果:

空矩阵和0矩阵的本质区别在于:空矩阵内没有任何元素,因此不占用任何存储空间;而0矩阵表示该矩阵中的所有元素全部为0,需要占用一定的存储空间。
2.2.3 矩阵大小及结构的改变
根据运算时的不同情况和需要,矩阵大小及结构的改变方式主要有旋转矩阵、改变矩阵维度、删除矩阵元素等。MATLAB中提供的具体此类函数如表2-13所示。
表2-13 矩阵旋转与改变维度的函数

续表

例2-34:矩阵的旋转与维度的改变。
在命令行窗口中输入:

输出结果:

2.2.4 矩阵下标引用
在MATLAB中,普通二维数组元素的数字索引分为双下标索引和单下标索引。双下标索引是通过一个二元数组对来对应元素在矩阵中的行列位置,例如A(2,3)表示矩阵A中第2行第3列的元素。单下标索引的方式是采用列元素优先的原则,对m行n列的矩阵按列排序进行重组,成为一维数组,再取新的一维数组中的元素位置对应的值作为元素在原矩阵中的单下标。例如对于4×4的矩阵,A(7)表示矩阵A中第3行第2列的元素,而A(13)表示矩阵A中第1行第4列的元素。
1.矩阵下标访问单个矩阵元素
常用的矩阵索引表达式如表2-14所示。
表2-14 常用的矩阵索引表达式

例2-35:矩阵下标引用示例。
在命令行窗口中输入:

输出结果:

2.线性引用矩阵元素
矩阵中某一元素的单下标索引值和双下标索引值之间,可以通过MATLAB内部函数进行转换,其句法形式为:

其功能为将双下标索引值转换为单下标索引值,其中siz是一个包含两个元素的数组,代表了转换矩阵的行列数,一般可以直接用size(A)表示;i与j分别是双下标索引中的行、列值;IND是转换后的单下标索引值。

其功能为将单下标索引值转换为双下标索引值,各变量意义同上。
例2-36:矩阵元素单双下标索引值转换示例。
在命令行窗口中输入:

输出结果:

3.访问多个矩阵元素
设A=magic(4),如果需要计算第4列元素的和,按照前面介绍的方法则可以用以下表达式来实现:
A(1,4)+A(2,4)+A(3,4)+A(4,4)
在下标表达式中,可以用冒号来表示矩阵的多个元素。例如,A(1:k,j)表示矩阵第j列的前k个元素。利用冒号,计算第4列元素的和可以用更为简洁的式子,代码设置如下:

还有更简洁的方法,因为冒号本身可以表示一列或一行的所有元素,所以上式还可以写为:

在MATLAB中提供了一个关键字end,用于表示该维中的最后一个元素,所以上式还可以改写成:

实际上还可以用冒号来表示非相邻的多个元素,例如下面的代码:

由上述语句得到如下输出结果:

2.2.5 矩阵信息的获取
矩阵的信息主要包括矩阵结构、矩阵大小、矩阵维度、矩阵的数据类型及矩阵占用的内存等。
1.矩阵结构
矩阵的结构是指矩阵子元素的排列方式。MATLAB提供了各种测试函数,如表2-15所示。
表2-15 矩阵结构测试函数

这类函数的返回值是逻辑类型的数据。返回值为“1”表示该矩阵是某一特定类型的矩阵;返回值为“0”表示该矩阵不是该特定类型的矩阵。
例2-37:矩阵数据结构判断函数的使用方法示例。
利用zeros函数生成一个4×4、元素全为0的矩阵A,并判断矩阵A的数据结构。首先在命令行窗口中输入:

得到:

再利用表2-15中的各函数判断矩阵A的数据结构,依次输入的代码和结果分别如下:

2.矩阵大小
矩阵的形状信息反映了矩阵的大小,通常又包括以下几个方面的内容:
● 矩阵的维数。
● 矩阵各维(如最长维、用户指定的维)的长度。
● 矩阵元素的个数。
针对上述3个方面的信息,相应地,MATLAB提供了4个函数,分别用于获取矩阵形状的相关信息,如表2-16所示。
表2-16 矩阵形状信息的查询函数

例2-38:矩阵形状信息查询函数的使用示例。
下面程序利用eye函数建立一个5×3的矩阵,利用ndims函数获取矩阵A的维数信息,输入的程序代码和得到的结果如下:

下面利用ndims函数获取矩阵A的维数信息。

利用length函数获取矩阵A最长维的长度。

利用size函数获取矩阵A各维的长度。

由上述size函数的应用可知:①size函数的返回值可以是分开显示的单个实数变量,也可以是一个行向量;②在size函数的输入参数中增加维度参数可以获取指定维度的长度,其中“1”表示行,“2”表示列。
使用numel函数(numel是number of elements的简写)可以获取矩阵A中元素的个数。例如,输入:

得到的结果如下:

例2-39:数值与矩阵的算术运算示例。
在命令行窗口中输入:

输出结果:

3.矩阵维度
对于空矩阵、标量矩阵、一维矩阵和二维矩阵,MATLAB都将其作为普通二维数组对待。特别需要注意的是,用[]产生的空矩阵是作为二维矩阵的,但是在高维矩阵中也有空矩阵的概念,此时空矩阵则具有多个维度。
MATLAB中提供了ndims函数计算矩阵维度。
例2-40:计算矩阵维度示例。
在命令行窗口中输入:

输出结果:

4.矩阵的数据类型
矩阵作为MATLAB的内部数据存储和运算结构,其元素可以是各种各样的数据类型(具体见2.1节),对应不同数据类型的元素,可以是数值、字符串、元胞、结构体等。MATLAB中提供了一系列关于数据类型的测试函数,如表2-17所示。
表2-17 矩阵数据类型的测试函数

这类函数的返回值也是逻辑类型的数据。返回值为“1”表示是某一特定的数据类型;返回值为“0”表示不是该特定的数据类型。
例2-41:矩阵元素的数据类型的判断示例。
在命令行窗口中依次输入:

得到的结果为:

建立一个字符串矩阵B并进行判断,程序代码如下所示:

得到的结果为:

例2-42:矩阵的数据类型示例。
在命令行窗口中输入:

输出结果:

例2-43:将矩阵A中的实数和复数分开为一个具有实数和复数的矩阵示例。
在命令行窗口中输入:

输出结果:

5.矩阵占用的内存
了解矩阵的内存占用情况,对于优化MATLAB代码性能是十分重要的。使用者可以通过whos命令查看当前工作区中指定变量的所有信息,包括变量名、矩阵大小、内存占用和数据类型等。
例2-44:查看矩阵占用的内存示例。
在命令行窗口中输入:

输出结果:

在命令行窗口中输入:

输出结果:

2.2.6 矩阵的保存和加载
设有矩阵,现用户希望将元素1修改成-1,并将5、6、8、9这几个矩阵元素以0替代,之后在原始矩阵的最后添加一行,使得新的矩阵A满足某方面的使用要求。因此,用户首先要通过一定的途径让MATLAB找到元素“1”及元素区域“5、6、8、9”,接着对这些矩阵元素的值进行修改,最后增加一行。上述几个方面构成了矩阵元素的基本操作。
本节将介绍矩阵在MATLAB中的存储方式,接着介绍矩阵元素的寻址方法,最后介绍矩阵元素的赋值及扩展与删除。
本节的重点在于让用户理解MATLAB存储矩阵的方法,进而掌握矩阵元素的寻址方法。
1.矩阵在MATLAB中的存储方式
设有矩阵,用户可以通过在MATLAB的命令行窗口中直接输入矩阵元素来创建此矩阵:

命令行窗口输出如下信息:

事实上,MATLAB并不是按照其命令行输出的格式将矩阵A存储在内存空间中的。我们可以把内存空间想象成一列网格,如下所示。

MATLAB将矩阵元素按列优先排列的原则依次放置在相应的格子内,因此,可以将其看成一个长列向量,即

例如,矩阵第2行第2列的元素“4”,实际上位于存储空间第5个格子的位置上。由此,MATLAB采用了两种矩阵元素寻址方法:①矩阵下标寻址;②线性寻址。
2.矩阵元素的寻址方法
1)矩阵下标寻址
在MATLAB中,使用A(i,j)来表示一个矩阵A从左上角数起第i行、第j列的元素,这就是矩阵下标寻址方法。这种方法和线性代数中矩阵元素的引用方法一致,通俗易懂。以下分别介绍利用矩阵下标寻址方法访问矩阵中的单个元素和元素区域。
(1)单个矩阵元素的访问。
当使用双下标访问二维矩阵中的某个元素时,必须同时指定该元素所在的行号和列号,访问格式为:

其中,numRow和numColumn分别代表行号和列号。
例2-45:单个矩阵元素的访问示例。
利用rand函数创建一个4×3的0~1均匀分布的随机数矩阵A并访问其中的元素。在命令行窗口中依次输入:

得到的结果为:

(2)矩阵元素区域的访问。
访问矩阵的多个元素,可以是某一行、某一列或者其中的部分元素,也可以是矩阵中的某一块区域。在MATLAB中,元素区域的访问需要用冒号“:”来表示矩阵中的多个元素,具体的访问格式如下。
● A(1:m,n):表示访问第n列的第一个元素至第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并进行访问。在命令行窗口中依次输入:

得到的结果为:

2)线性寻址
线性寻址的原理来自MATLAB将矩阵元素存储在内存空间的存储方法。与矩阵下标寻址相比,线性寻址只需要单一下标即可实现矩阵中任意位置元素的访问。线性寻址的下标是通过矩阵的双下标换算得到的。
一般,设A是一个m×n的矩阵,位于第i行、第j列的元素A(i,j)的单一下标为A((j-1)·m+i)。
例2-47:线性寻址示例。
建立3阶希尔伯特矩阵A,并进行线性寻址访问。在命令行窗口中依次输入:

得到的结果如下:

3.矩阵元素的赋值
MATLAB使用赋值语句对矩阵元素进行赋值,基本语法如下。
● A(i,j)=value:等号左侧为矩阵中的某个元素;等号右侧为值。
● A=[]:删除矩阵中的所有元素。
例2-48:矩阵元素的赋值示例。
利用magic函数建立一个4阶的魔幻矩阵M,并进行复制操作。在命令行窗口中依次输入:

得到的结果为:

4.矩阵元素的扩展与删除
增加或删除矩阵元素最常用的方法是使用赋值语句。
例2-49:对于矩阵,如果现在要增加一行,则应在命令行窗口中输入:

得到的结果为:

此外,MATLAB提供了多个函数进行矩阵合并操作,从而实现将多个矩阵合并成一个矩阵。这些函数如表2-18所示。
表2-18 矩阵合并函数

例2-50:矩阵合并函数示例。
(1)设有矩阵A=、矩阵B=
、矩阵C=
,利用cat函数分别对矩阵A、B及矩阵A、C进行合并操作,函数中的输入参数DIM分别取DIM=1及DIM=2。
在命令行窗口中首先输入:

得到矩阵A、B、C。然后使用cat函数对矩阵A、B进行合并操作。

得到结果:

如果合并错误,如:

则得到结果:

使用cat函数对矩阵A、C进行合并操作,输入如下:

得到结果:

为了探究矩阵A、B按列合并及矩阵A、C按行合并发生错误的原因,将合并后的矩阵列出来:

可以看出,由于两个矩阵在某个维度上的长度不一致,从而导致新的矩阵出现残缺。
因此,cat及其相关的函数在将两个矩阵按某个维度进行合并操作时,原始的两个矩阵要在某一个维度上具有相同的长度,否则MATLAB在进行计算时就会发生错误。
(2)使用blkdiag函数构造块对角化矩阵。例如在命令行窗口中输入:

得到结果:
