9 Matlab 矩阵

在第一次介绍 Matlab 的时候就说过 Matlab 这个名字的由来,显然,它的主打优势就是矩阵操作。很多同学的线性代数基础不太扎实,一听矩阵就头皮发麻。我们在这里只关心矩阵这样一种特殊的数据存储形态,它本身的数学意义,不做探讨。

为了简化起见,我们在这里把矩阵看作是一个 NM 列的一种有序结构。你可以想象一下阅兵式上的那些兵哥哥们排成的方队。兵哥哥的整个方队,你可以看作是一个矩阵,方队中的每一个兵哥哥,是矩阵中的元素

《9 Matlab 矩阵》 是不是帅你一脸?(来源见水印)

Matlab 为了将矩阵与其他数据类型区分开来,用[]把矩阵中的元素括起来。所以,也可以这么说,用[]括起来的东西,都是矩阵。

这里的 NM 可以取任意值,有同学可能也觉得比较困惑,NM 取 0 时,有什么意义,又有什么用?这是一个空矩阵,它就是一个矩阵,只是里面没有元素。实验一下:

>> a = ones(0)
a =
    []

大家help一下ones就明白上面这个命令的意思了。

在程序设计中经常先创建一个空矩阵,再将运算过程中得到的结果往这个空矩阵里面塞。

矩阵同一行的元素之间用空格或逗号,分隔,行与行之间用分号;分隔。看一个例子:

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

前面我们也说过矩阵可以存储几乎所有的数据类型,比如元素是矩阵的矩阵,不同数据类型的元素混在一起的矩阵等等。另外,一个字符串其实也是一个矩阵,有兴趣的同学可以自己查阅相关的资料。

矩阵操作

1 创建矩阵

最直接的方法当然是逐个写出矩阵中的元素。有些特殊的矩阵可以使用Matlab提供的函数直接创建。例如:

>> ones (3, 4)
ans = 
    1  1  1  1
    1  1  1  1
    1  1  1  1
>> zeros (2)
ans = 
    0  0
    0  0
>> a = [1, 2, 3]
a = 
    1  2  3
>> b = [1; 2; 3]
b =
    1
    2
    3
>> rand(2)
ans = 
    0.8147    0.1270
    0.9058    0.9134    

ones, zeros, rand这几个函数的功能,大家自己help一下就能了解了。

2 引用矩阵元素

直接看例子:

>> a = [1, 3, 5, 7; 9, 11, 13, 15; 17, 19, 21, 23]
a = 
    1   3   5   7
    9  11  13  15
    17  19  21  23
>> a (2, 4) 
ans = 
    15

这就好比你不知道这家伙的名字,但是你知道他排在方队第二行第四列,所以你喊“第二行,第四列的那个家伙,你妈妈喊你回家吃饭了”,这就是引用矩阵元素最直接的方法。上例就是取第二行第四列的元素

注意,这里的第二行第四列,数字“2”与“4”,也称索引(index),要用()括起来,不要与矩阵的[]弄混。行索引与列索引用,分隔。

取第三行第二到第四列的所有元素

>> a(3, 2: 4)
ans = 
    11 13 15

又出现了一个新符号:,它的完整用法是start: step: end,意思就是从起点每隔一个步长到终点。

不指定 start 与 end 的值的话,就默认取指定范围内的头与尾。在这个三行四列的矩阵中,对于行来说,start默认值为1,end的默认值为3。

不指定step值的话就取默认值1。

本例中,3的意思是第三行,2: 4的意思是从2到4,步长为1,也即第2、3、4三列。

:的使用比较多,经常用于循环,也常常用于创建矩阵。例如,我们创建一个矩阵,矩阵中元素是1到16中的所有奇数。可以这样写:

>> b = [1:2:16]
b = 
    1  3  5  7  9  11  13  15

取第2行所有列的数据

>> a(2, :)
ans = 
    9 11 13 15    

取第3列所有行的数据

>> a(:,3)
ans = 
    5
    13
    21

请结合例子,仔细体会:的用法。

取最后一行,例数第二列的数据

>> a(end, end-1)
ans  = 
     21

有时候,我们不知道也不想知道矩阵的大小,只想取它的最后行的数据,可以使用end关键字。显然,end是最后一列,那end-1就是倒数第二列。

特别地,对于只有一行(行向量)或只有一列(列向量)的矩阵来说,可以直接使用a(n)这样的形式来获得第n个元素,大家可以自己试一下。

顺便插播一个东西:行向量与列向量可以通过'操作符相互转化:

>> [1,2,3]'
ans = 
    1
    2
    3
>> [1;2;3]'
ans = 
    1 2 3

对于引用矩阵元素的操作,还有一个比较灵活的用法:结合逻辑表达式进行逻辑索引

假设有矩阵r如下

>> r = rand(5)
r =
    0.6324    0.9649    0.8003    0.9595    0.6787
    0.0975    0.1576    0.1419    0.6557    0.7577
    0.2785    0.9706    0.4218    0.0357    0.7431
    0.5469    0.9572    0.9157    0.8491    0.3922
    0.9575    0.4854    0.7922    0.9340    0.6555

取矩阵r中所有大于0.5的值:

>> r1 = r(r > 0.5)
r1 =
    0.6324
    0.5469
    0.9575
    0.9649
    0.9706
    0.9572
    0.8003
    0.9157
    0.7922
    0.9595
    0.6557
    0.8491
    0.9340
    0.6787
    0.7577
    0.7431
    0.6555

为了搞清楚这个命令到底做了什么工作,我们先看看r > 0.5是什么。

>> r > 0.5
ans =
  5×5 logical 数组
   1   1   1   1   1
   0   0   0   1   1
   0   1   0   0   1
   1   1   1   1   0
   1   0   1   1   1

这样一来,我们就很容易看出r1 = r(r > 0.5)是分两步走的:先通过r > 0.5获得了每个元素是否满足条件的逻辑值(逻辑数组)。r1 = r(r > 0.5)将每个符合条件的元素提取出来并赋值给r1

逻辑数组有很多灵活的用法。比如,假设有一个逻辑数组logi(通过logical函数转换得到)以及另外一个数组x如下:

>> logi = logical ( [1,0,1;0,0,1;1,0,0])
logi =
  3×3 logical 数组
   1   0   1
   0   0   1
   1   0   0
>> x = [1,2,3;5,6,7;4,8,9]
x =
     1     2     3
     5     6     7
     4     8     9

我们看看x(logi)的输出是什么

>> x(logi)
ans =
     1
     4
     3
     7

它把x矩阵中对应于logi矩阵中元素值为true位置的元素输出为结果。
改变矩阵元素的值

这个比较简单,想改变哪一个元素的值,就把这个值先索引出来,然后直接用赋值操作就可以了。举例如下:

>> a(2,3) = 0
a = 
     1     3     5     7
     9    11     0    15
     17    19    21    23

也可以采用逻辑索引的方式进行批量操作:

>> x = rand(4)
x =
    0.1712    0.0462    0.3171    0.3816
    0.7060    0.0971    0.9502    0.7655
    0.0318    0.8235    0.0344    0.7952
    0.2769    0.6948    0.4387    0.1869
>> x(x > 0.5) = 1
x =
    0.1712    0.0462    0.3171    0.3816
    1.0000    0.0971    1.0000    1.0000
    0.0318    1.0000    0.0344    1.0000
    0.2769    1.0000    0.4387    0.1869

删除矩阵的行或列

矩阵的“矩”是“方”的意思,所以矩阵的构成上有一个特殊的要求,行与行或者列与列的元素个数要相等。所以对于一个矩阵的删除与增加元素操作来讲,只能增加或删除完整的一行或一列。删除操作一般使用赋空矩阵来完成。

例如,删除第二行

>> a(2, :) = []
a = 
  1   3   5   7
  17  19  21  23

增加矩阵行或列
这种操作在 Matlab 中也被称为矩阵连接。举例说明:

>> a = [1:2:7; 17:2:23]
a = 
  1   3   5   7
  17  19  21  23
>> b = [2:2:8]
b = 
  2 4 6 8
>> d = [2;4]
d = 
  2
  4
>> [a, d]
ans =
     1     3     5     7     2
    17    19    21    23     4
>> con =  [a;b]
con =
     1     3     5     7
    17    19    21    23
     2     4     6     8
>> con = [con(1,:); b; con(2:end, :)]
con =
     1     3     5     7
     2     4     6     8
    17    19    21    23
     2     4     6     8

肯定有很多小伙伴要晕了。

先说[a,d],看变量a与变量d之间,用的是,,记得我们前面说过行内元素之间用,分隔,行与行之间用;分隔。所以这里的意思就是把矩阵a与矩阵d在行上“连接”。

我们分别写一下矩阵a与矩阵d,观察下这个“连接”。

      1   3   5   7    |  2  
      17  19  21  23   |  4  

竖线左边的是矩阵a,竖线右边的是矩阵d,再结合输出结果,应该明白怎么回事了吧。[a; b]也是类似的,只不过是变成了增加行。

如果你试一下[a,b]或者[a;d],你会发现输出错误。想一想,为什么会出现这样的情况?

那如果不是在行末或列末添加,而是要在中间某行之后插入新的一行怎么做?最后一个命令做的就是这件事情。

[con(1,:); b; con(2:end, :)]在这个[]里面,;分隔了三个部分。

con(1,:)是矩阵con中的第一行,通过;将矩阵b增加到第一行之后,接着又将矩阵con剩下的行增加进去便完成了整个插入行的操作。

插入列也是类似的操作,不再赘述。

    原文作者:花生_毛豆
    原文地址: https://www.jianshu.com/p/4a15bdbd7370
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞