概述
上一节的内容中,我们介绍了索引的使用方法。索引的目的是为了取出矩阵中的一部分元素,因此我们知道通过元素在矩阵中的位置我们可以实现索引。在本节中,我们将介绍MATLAB中的逻辑变量以及通过逻辑变量索引的方法。
MATLAB中存在一种logical(逻辑)类型用于表示逻辑上的真和假。在其他程序语言中,这样的一种类型也叫做bool型变量。这一种变量本身只有两种值,分别为true和false。规定false对应数值0,true对应其他值(特别地,使用时可以用任意非零值代表true,但存储时会自动转为1代表true,这样的好处是只需要占用一个比特的空间)。
逻辑变量
logical变量只存在两种值true(真)或者false(假),规定分别用数字1和0存储。以逻辑值组成的矩阵称为逻辑矩阵。一般有以下几种创建逻辑矩阵的方法,各有用处。
方法一:直接赋值法
直接用true,false直接赋值到一个矩阵,缺点操作复杂,一般不考虑这种方法。
x = [true false] % 正确实例
A = [1 0] % 错误实例
whos
输出值
x =
1 0
A =
1 0
% 尽管两个语句的输出一样
% 但是通过whos命令可以看到变量的类型不一样
% 可以看到只有用true,false直接赋值才能创建逻辑矩阵
% 一般不考虑这种方法
Name Size Bytes Class Attributes
A 1x2 16 double
x 1x2 2 logical
方法二:logical函数法
logical函数是将数值或矩阵转换为逻辑值的函数。遵循的转换规则为:非零值为逻辑1,零值为逻辑0。这种方法将一个矩阵非零值对应转为逻辑矩阵中的1。可以用作非零值的逻辑索引。
函数法
% logical
A = [1 0 3;0 5 6];
x1 = logical(1)
whos
% 对于传入的数值或矩阵
% 非零值为逻辑1,零值为逻辑0
x2 = logical(0)
x3 = logical(2)
x4 = logical(A)
% 生成的逻辑矩阵作为索引,可以取出矩阵中对应位置为true的元素
x5 = A(logical(A))
命令行输出
% logical
x1 =
1
% 观察两个变量的类型(Class)和比特数(Bytes)
% A属于double类型(占用48比特)
% x1属于logical类型(占用1比特)
Name Size Bytes Class Attributes
A 2x3 48 double
x1 1x1 1 logical
x2 =
0
x3 =
1
x4 =
1 0 1
0 1 1
% 形如A(logical(A))可以取出A中的非零元素
x5 =
1
5
3
6
方法三:借用逻辑表达式(命题)
命题就是判断一个事件的陈述句。对于数值来说一个判断的陈述句通过关系运算符连接。
MATLAB的关系运算符共6个:等于(==),不等于(~=),大于等于(>=),大于(>),小于等于(<=),小于(<)。
这种方法创建逻辑矩阵最为常见,能够很高效地创建对应的逻辑矩阵,同时进行逻辑运算并作为索引
逻辑表达式
% 逻辑表达式
A = [1 0 3;0 5 6];
x1 = (3 == 2)
x2 = (3 ~= 2)
x3 = (3 >= 2)
x4 = (3 > 2)
x5 = (3 <= 2)
x6 = (3 < 2)
% 特别地,对矩阵使用关系运算符返回一个相应的逻辑矩阵
x7 = (A < 4)
% 返回的矩阵是逻辑矩阵,又可以作为索引,取出矩阵中满足判断条件的元素
x8 = A(A < 4)
命令行输出
% 逻辑表达式
% 对于仅由数值构成的逻辑表达式,返回该表达式的真假性
x1 =
0
x2 =
1
x3 =
1
x4 =
1
x5 =
0
x6 =
0
% 对于由矩阵构成的逻辑表达式,返回和该矩阵等大小的逻辑矩阵
% 逻辑矩阵的值是矩阵相应位置元素的判断情况
x7 =
1 1 1
1 0 0
% 第一行全行,第二行1个元素大于4,满足判断记为1,其他值记为0
% 这里的A(A < 4)就对应取出A中小于4的元素
x8 =
1
0
0
3
逻辑表达式的运算
对于逻辑值之间的运算,可以实现逻辑表达式的复合运算,这时可以实现联合条件的逻辑索引。有四种运算:逻辑与(&,&&),逻辑或(|,||),逻辑异或(xor函数)和逻辑非(~)。这四种逻辑运算服从以下的真值表。
逻辑真值表
A | B | A&B | A|B | xor(A,B) | ~A |
---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 1 |
0 | 1 | 0 | 1 | 1 | 1 |
1 | 0 | 0 | 1 | 1 | 0 |
1 | 1 | 1 | 1 | 0 | 0 |
应用实例
A = [1 0 3;0 5 6];
x1 = A((A < 4)&(A > 2))
x2 = A((A < 4)|(A > 2))
x3 = A(xor((A < 4),(A > 2)))
x4 = A(~(A < 4))
% &&和||是&和|的变体
% 只能用于标量,不能用于矩阵,但速度更快
x5 = (3 > 4)&&(3 > 2)
x6 = (3 > 2)||(3 > 4)
命令行输出
% & 与
x1 =
3
% | 或
x2 =
1
0
0
5
3
6
% xor函数 异或
x3 =
1
0
0
5
6
% ~ 取非,取反
x4 =
5
6
% && 适用于标量的与(利用逻辑与的特性加速运算)
% (如果第一个值为0,立即判断该值为0)
x5 =
0
% || 适用于标量的或(利用逻辑或的特性加速运算)
% (如果第一个值为1,立即判断该值为1)
x6 =
1
find函数——逻辑索引的辅助工具
find函数是将逻辑矩阵索引直接转换为直接索引(下标位置)的函数。我们有时候作出了判断,但是却需要直接索引的信息,这时可以利用find函数进行转换;另一个用处是,找到前n个满足条件的索引
% find函数
A = [2 5 4 0 0 6];
x1 = A > 2
x2 = find(A > 2)
B = [2 5 4;0 0 6];
% 按列产生线性地址索引
x3 = find(B > 2)
x4 = B(find(B > 2))
% 满足条件的前两个值的索引
x5 = find(B > 2,2)
命令行输出
% find函数
% 逻辑索引
x1 =
0 1 1 0 0 1
% 线性地址索引
x2 =
2 3 6
% 根据这个输出,可以发现,按列产生线性地址索引
x3 =
3
5
6
% 因为是线性地址索引,B(find(B > 2))依然有效,结果与B(B > 2)一样
x4 =
5
4
6
% 满足条件的前两个值的索引
x5 =
3
5
重在应用
以下是逻辑数组的三种基本应用,根据判断条件进行,逻辑索引查找,替换和删除。
1.一组数据[1 2 4 6 7 8 9 0 4 5 3 2 4 2 2 3 4 2 3],依次找出其中在区间[2,6]中的数。
% 查找
A = [1 2 4 6 7 8 9 0 4 5 3 2 4 2 2 3 4 2 3];
2.一组数据[1 2 4 6 7 8 9 0 4 5 3 2 4 2 2 3 4 2 3],依次将其中在区间[2,6]中的数替换为10。
% 替换
A = [1 2 4 6 7 8 9 0 4 5 3 2 4 2 2 3 4 2 3];
3.一组数据[1 2 4 6 7 8 9 0 4 5 3 2 4 2 2 3 4 2 3],删除其中在区间[2,6]中的数。
% 删除(要求在矩阵A中改变值)
A = [1 2 4 6 7 8 9 0 4 5 3 2 4 2 2 3 4 2 3];
参考思路
1.一组数据[1 2 4 6 7 8 9 0 4 5 3 2 4 2 2 3 4 2 3],依次找出其中在区间[2,6]中的数。
% 查找
A = [1 2 4 6 7 8 9 0 4 5 3 2 4 2 2 3 4 2 3];
B = A((A>=2)&(A<=6))
2.一组数据[1 2 4 6 7 8 9 0 4 5 3 2 4 2 2 3 4 2 3],依次将其中在区间[2,6]中的数替换为10。
% 替换
A = [1 2 4 6 7 8 9 0 4 5 3 2 4 2 2 3 4 2 3];
A((A>=2)&(A<=6)) = 10
3.一组数据[1 2 4 6 7 8 9 0 4 5 3 2 4 2 2 3 4 2 3],删除其中在区间[2,6]中的数。
% 删除
A = [1 2 4 6 7 8 9 0 4 5 3 2 4 2 2 3 4 2 3];
A=A(~( (A>=2) & (A<=6) ))
小结
本节内容不多,但是逻辑索引比起线性地址的等间距索引索引的产生要更加普遍,所以,希望读者熟练掌握这三种基本应用。