分享

矩阵和数组(1)

 小温爱怡宝 2023-07-22 发布于江西

矩阵和数组

本章的目标是:

  • 介绍创建和操作矩阵的方法。
  • 介绍矩阵运算。
  • 介绍字符串和处理它们的工具。
  • 通过以下例子演示矩阵的一些用法:
    1. 人口动态变化。
    2. 马尔可夫过程。
    3. 线性方程。
  • 介绍MATLAB的稀疏矩阵工具。

正如我们已经看到的,MATLAB这个名字代表矩阵实验室,因为MATLAB系统是专门为处理以矩阵(二维数组)形式排列的数据而设计的。在本章中,“矩阵”一词有两个不同的含义:

  1. 按行和列排列数据的一种方式,比如,表
  2. 一种数学对象,为其定义了特定的数学运算,如“矩阵”乘法。

本章(在第6.1、6.2和6.3节中)将从第一种意义上的矩阵开始,总结和扩展我们在第二章所学到的知识。然后我们继续简单地看一下矩阵的数学运算。在后面的章节中,我们将看到这些操作如何应用于许多不同的领域,如线性方程系统、种群动力学和马尔可夫过程。

  • 6.1矩阵

    • 6.1.1具体示例

    • 6.1.2创建矩阵

    • 6.1.3下标

    • 6.1.4转置

    • 6.1.5冒号操作符

6.1矩阵

6.1.1具体示例

>> c = [3 12 1017 18 357 10 24];
x = [4 0 06 6 00 3 5];
>> total = c .* x

total =

    12     0     0
   102   108     0
     0    30   120

>> sum(total)

ans =

   114   138   120

在这段代码中,首先定义了两个矩阵cx,其中c是一个3x3的矩阵,x是一个3x3的矩阵。接下来,代码使用逐元素乘法运算符.*对这两个矩阵进行逐元素相乘,得到一个新的矩阵total,其中每个元素都是对应位置上c和x的元素相乘的结果。

最后,代码使用sum函数对total矩阵进行求和,得到一个包含三个元素的行向量,其中每个元素表示total矩阵在对应列上的元素之和。具体来说,sum(total)将对total矩阵的每一列进行求和,得到一个1x3的行向量,其中第一个元素是total矩阵第一列的元素之和,第二个元素是total矩阵第二列的元素之和,第三个元素是total矩阵第三列的元素之和。在这个例子中,sum(total)的结果是[114 138 120],表示total矩阵在第一列上的元素之和是114,在第二列上的元素之和是138,在第三列上的元素之和是120。

>> sum(sum( total ))

ans =

   372

接下来,代码再次使用sum函数对这个行向量进行求和,得到一个标量值,表示total矩阵所有元素之和。具体来说,sum(sum(total))将对total矩阵的所有元素进行求和,得到一个标量值,其中第一次sum函数对total矩阵的每一列进行求和,得到一个1x3的行向量,第二次sum函数对这个行向量进行求和,得到一个标量值。在这个例子中,sum(sum(total))的结果是372,表示total矩阵所有元素之和是372。

6.1.2创建矩阵

在输入矩阵时使用分号表示行结束。较大的矩阵可以由较小的矩阵构造而成,

a = [1 23 4];
x = [5 6];
a = [a; x]

a =

     1     2
     3     4
     5     6

具体来说,如果要输入一个3x3的矩阵,可以使用以下语句:

A = [1 2 34 5 67 8 9];

其中,分号表示行结束,每个分号后面的数字表示该行对应位置上的元素。这个语句将创建一个名为A的3x3矩阵,其中第一行是[1 2 3],第二行是[4 5 6],第三行是[7 8 9]。

较大的矩阵可以由较小的矩阵构造而成。例如,可以使用以下语句构造一个4x4的矩阵B,其中前三行和前三列与矩阵A相同,最后一行和最后一列都是0:

B = [A zeros(3,1); zeros(1,30];

其中,zeros函数用于创建一个指定大小的全0矩阵。这个语句将创建一个名为B的4x4矩阵,其中前三行和前三列与矩阵A相同,最后一行和最后一列都是0。具体来说,B的第一行到第三行和第一列到第三列与矩阵A相同,最后一行和最后一列都是0,因此B的第四行是[0 0 0 0],第四列是[0; 0; 0; 0]。

6.1.3下标

a =

     1     2
     3     4
     5     6

矩阵的单个元素用两个下标引用,第一个下标用于行,第二个下标用于列,例如,a(3,2)的返回值为6。

另外一种不太常见的情况是,可以使用单个下标。在这种情况下,你可以把矩阵想象成一列一列地“展开”。所以上面例子中的a(5)返回4。

如果您引用的下标超出了范围,例如上面a的a(3,3),则会得到错误消息。但是,如果给下标超出范围的元素赋值,则矩阵将被放大以容纳新元素,例如:a(3,3) = 7将在A中添加第三列,除A(3,3)为7以外, 该列其他的所有数都为0.

6.1.4转置

>> a = [1:34:6]
b = a'

a =

     1     2     3
     4     5     6


b =

     1     4
     2     5
     3     6

转置运算符'(撇号)将行转换为列,反之亦然

6.1.5冒号操作符

冒号运算符非常强大,提供了处理矩阵的非常有效的方法,例如,如果a是矩阵

>> a =[1 2 3;4 5 6;7 8 9]

a =

     1     2     3
     4     5     6
     7     8     9

返回第二行和第三行,第一列和第二列 :

>> a(2:3,1:2)

ans =

     4     5
     7     8

在MATLAB中,a(2:3,1:2)表示对矩阵a的第2到第3行和第1到第2列进行切片操作,得到一个2x2的子矩阵。具体来说,这个语句将返回一个2x2的矩阵,其中第一行是a矩阵的第2行第1列和第2列的元素,第二行是a矩阵的第3行第1列和第2列的元素。注意,MATLAB中的索引从1开始,因此a(2:3,1:2)实际上是指矩阵a的第2行到第3行和第1列到第2列。

>> a(3,:)

ans =

     7     8     9

在MATLAB中,a(3,:)表示对矩阵a的第3行进行切片操作,得到一个包含该行所有元素的行向量。具体来说,这个语句将返回一个1xn的行向量,其中n是矩阵a的列数,包含a矩阵的第3行所有元素。注意,冒号表示对整个维度进行切片操作,因此a(3,:)实际上是指矩阵a的第3行的所有元素。

>> a(1:2,2:3) = ones(2)
%将由第一、第二行和第二、第三列组成的2 × 2子矩阵替换为1的方阵
a =

     1     1     1
     4     1     1
     7     8     9

a(1:2,2:3) = ones(2)表示将矩阵a的第1到第2行、第2到第3列的元素赋值为1。具体来说,这个语句将返回一个修改后的矩阵a,其中第一行第二列和第二行第二、第三列的元素都被赋值为1,而其他元素保持不变。因此,修改后的矩阵a为:

a =

     1     1     1
     4     1     1
     7     8     9

从本质上讲,在上面的例子中发生的事情是冒号操作符被用来创建向量下标。但是,冒号本身代替下标表示相应行或列的所有元素。所以a(3,:)表示第三行中的所有元素

这个功能可以用来构建表格,例如,假设我们想要一个包含0°到180°之间每隔30°的角度对应的正弦和余弦值的表格trig。下面的语句可以实现这个目标:

>> x = [0:30:180]';
trig(:,1) = x;
trig(:,2) = sin(pi/180*x);
trig(:,3) = cos(pi/180*x);
>> trig

trig =

         0         0    1.0000
   30.0000    0.5000    0.8660
   60.0000    0.8660    0.5000
   90.0000    1.0000    0.0000
  120.0000    0.8660   -0.5000
  150.0000    0.5000   -0.8660
  180.0000    0.0000   -1.0000

接着上面的

a =

     1     1     1
     4     1     1
     7     8     9

可以使用矢量下标来获得更复杂的效果

b = ones(3,4);
a(:,[1 3]) = b(:,[4 2])

这个操作用b的第四列和第二列替换a的第一列和第三列(a和b必须具有相同的行数)

首先创建一个3行4列的矩阵b,其中所有元素都被赋值为1。具体来说,这个语句将返回一个修改后的矩阵a,其中第一列和第三列的元素被替换为矩阵b的第4列和第2列的元素,而其他元素保持不变。注意,方括号内的数字表示要选择的列的索引,因此[1 3]表示选择矩阵a的第1列和第3列,[4 2]表示选择矩阵b的第4列和第2列。

得到的结果

冒号运算符在高斯消元(一种数值数学技术)中执行的行操作非常理想。在高斯消元中,我们需要对矩阵的行进行一系列操作,例如交换行、将一行乘以一个常数、将一行加到另一行上等等。冒号运算符可以用来选择矩阵的特定行,例如a(1,:)表示选择矩阵a的第一行。通过使用冒号运算符,我们可以轻松地执行这些行操作,例如a([2 1],:)表示交换矩阵a的第一行和第二行。

>> a =[1 -1 2;2 1 -1;3 0 1]

a =

     1    -1     2
     2     1    -1
     3     0     1

>>a(2,:) = a(2,:) - a(2,1)*a(1,:)
%从第二行减去第一行乘以第二行中的第一个元素

a =

     1    -1     2
     0     3    -5
     3     0     1

在MATLAB中,a(2,:) = a(2,:) - a(2,1)*a(1,:)表示将矩阵a的第二行减去矩阵a的第一行乘以a(2,1)后的结果,然后将这个结果赋值给矩阵a的第二行。具体来说,这个语句将返回一个修改后的矩阵a,其中第二行的元素被更新为原来的第二行减去原来的第一行乘以a(2,1)后的结果。这个操作通常用于高斯消元中的行变换,可以将矩阵转化为上三角矩阵。


关键字end指数组的最后一行或最后一列,例如,如果r是行向量,则语句sum(r(3:end))表示计算向量r的第三个元素到最后一个元素的总和。

假设向量r为[1 2 3 4 5],那么r(3:end)将选择向量r的第三个元素到最后一个元素,即[3 4 5]。然后,sum函数将计算这个子集的总和,即3+4+5=12。因此,sum(r(3:end))将返回12。


冒号操作符也可以用作单个下标,在这种情况下,它在赋值操作的右侧或左侧的行为是不同的。在赋值操作的右侧,a(:)给出由列串成的一个长列向量的所有元素,例如,

a =

     1    -1     2
     0     3    -5
     3     0     1

>> b = a(:)

b =

     1
     0
     3
    -1
     3
     0
     2
    -5
     1

然而,在赋值操作的左边,a(:)会重塑一个矩阵。其中矩阵a必须已经存在。那么a(:)表示与a具有相同维数(形状)的矩阵,但是从右边取了新的内容。 换句话说,右边的矩阵被重塑成左边的a的形状。

>> b =[1 2 3;4 5 6]

b =

     1     2     3
     4     5     6

>> a =[0 0;0 0;0 0]

a =

     0     0
     0     0
     0     0

>> a(:) = b

a =

     1     5
     4     3
     2     6

b的内容被串成一长列,然后输送到a的每一列

a =
%已知
     1     5
     4     3
     2     6
%再对a进行操作
>> a(:) = 1:6

a =

     1     4
     2     5
     3     6

a(:) = 1:6表示将向量[1 2 3 4 5 6]的元素赋值给矩阵a的所有元素(按照列,一列一列往里面输入)。具体来说,这个语句将返回一个修改后的矩阵a,其中所有元素都被赋值为向量[1 2 3 4 5 6]的元素。


无论冒号操作符出现在赋值操作的右侧还是左侧,赋值操作两侧的矩阵或子矩阵都具有相同的形状(下面的特殊情况除外)。

作为一种特殊情况,可以使用单个冒号下标将矩阵中的所有元素替换为标量,例如:

a =

     1     4
     2     5
     3     6

>> a(:) = -1

a =

    -1    -1
    -1    -1
    -1    -1

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多