2.4 逻辑运算和逻辑函数
逻辑运算和逻辑函数在计算机语言中是普遍存在的,在MATLAB中包含与、或、非、异或4种基本的逻辑运算。逻辑表达式和逻辑函数的值应该为逻辑“真”或“假”。MATLAB系统在给出逻辑运算的结果时,以“1”代表“真”,以“0”代表“假”;但在判断一个量是否为“真”时,以“0”代表“假”,以任意的非零数代表“真”。MATLAB的逻辑运算也是以矩阵为基本运算单元的。
2.4.1 逻辑运算
符号“&”“|”“~”“xor”分别代表逻辑运算中的与、或、非、异或,它们作用于数组元素。“0”代表逻辑“假”,而任意非零数代表逻辑“真”。逻辑运算的运算法则如下。
● 在逻辑数组中,“0”代表逻辑“假”,“1”代表逻辑“真”。
● 如果两个标量a
和b
参与运算,则逻辑运算的运算规则如表2-1所示。
● 如果两个维数相同的矩阵参与运算,则将A
和B
相同位置上的元素按标量逻辑运算的规则进行计算,结果返回与矩阵A
和B
同样大小的矩阵,其元素由同位置上的A
和B
的元素进行逻辑运算的结果所决定。
● 如果标量a
和矩阵A
参与运算,则将a
和A
中的所有元素进行逻辑运算,返回结果是由0和1组成的与A
具有同样维数的矩阵。
● 在逻辑运算符、关系运算符和计算运算符三者中,逻辑运算符的优先级最低,但是逻辑“非”的优先级最高。
● 在逻辑“与”“或”“非”三者中,“与”的优先级高于“或”的优先级,且都低于“非”的优先级。
● 通过增加“()”可以改变各运算符之间的优先级。
表2-1 逻辑运算的运算规则
例2.14 MATLAB中逻辑运算符的用法。
>> a=[1 2;3 4]
a =
1 2
3 4
>> b=[1 0;0 1]
b =
1 0
0 1
>> a&b %求逻辑“与”的值
ans =
1 0
0 1
>> a|b %求逻辑“或”的值
ans =
1 1
1 1
>> ~b %求逻辑“非”的值
ans =
0 1
1 0
>> xor(a,b) %求逻辑“异或”的值
ans =
0 1
1 0
>> ~a-1>=1
ans =
0 0
0 0
>> a-1>=1&0
ans =
0 0
0 0
>> ~(a-1>=1)
ans =
1 0
0 0
>> ~a-1
ans =
-1 -1
-1 -1
>> 1|0&0
ans =
1
>> 0&0|1
ans =
1
>> and(a,b)
ans =
1 0
0 1
在M文件中,可以用and(A,B)
、or(A,B)
、not(A)
分别进行“与”“或”“非”的操作,亦可以在命令行中直接输入,其结果与用“&”“|”“~”运算所得结果相同。
2.4.2 逻辑函数
MATLAB从3.0版本开始提供逻辑函数,这些函数对交互运算和进行矩阵变换非常有用,可以很方便地查找或替换矩阵中满足一定条件的部分或所有元素。只有在使用过程中认真体会每个函数的具体用法,大家才能在实际应用过程中灵活运用。
1.all()函数:判断是否所有元素都为非零数
如果要获得矩阵或向量中非零元素的位置或个数,可以利用all()函数。此函数对于向量a
(行向量或列向量),如果向量中的每个元素都是非零数,all(a
)返回逻辑“真”,即“1”;如果至少一个元素为零,则返回逻辑“假”,即“0”。对于矩阵A
,all(A
)是作用于列向量上的,即如果矩阵A
的某列的所有元素都是非零数,则返回结果的当前列为逻辑“真”,即“1”;如果至少有一个为零,则返回结果的当前列为逻辑“假”,即“0”。显然,返回结果为与矩阵A
具有同列维的行向量。如果A
是多维矩阵,则all(A
)将是以第1个不是单维的维作为向量进行运算,运算规则同向量运算规则。all(A
,dim
)将指定的第dim
维作为向量进行运算。
例2.15 判断矩阵A
=[0 1 2;3 4 5]的所有元素是否都大于或等于1。
>> all(all(A))
ans =
0
>> A>=1
ans =
0 1 1
1 1 1
>> all(A>=1)
ans =
0 1 1
而对矩阵A
=[0 1 2;3 4 5]再做一次all()的逻辑运算,便可以得到最终的结果0。
从以上分析不难看出,如果A
=[0 1 2;3 4 5],则all(all(A
>=1))=1。
例2.16 举例说明all()函数运算的规则。
>> A=[0 1 2;3 4 5]
A =
0 1 2
3 4 5
>> all(A)
ans =
0 1 1
>> all(A,2)
ans =
0
1
>> c=rand(1,2,3)
c(:,:,1) =
0.8147 0.9058
c(:,:,2) =
0.1270 0.9134
c(:,:,3) =
0.6324 0.0975
>> all(c)
ans(:,:,1) =
1
ans(:,:,2) =
1
ans(:,:,3) =
1
由上例可以看出,三维列向量c
进行all()的逻辑运算时,是将第2维作为向量进行计算的,而不是将第1维作为向量进行计算。
技巧:在M函数中,可以充分利用all()函数的功能,对向量或矩阵进行判断,并根据返回结果做出相应的反应。如下面的一段程序。
if all(all(A>=1))
%存放将要执行的代码
end
2.any()函数:判断是否有一个向量元素为非零数
在矩阵处理中,有时候需要判断矩阵中的元素是否有零或非零数,如在对矩阵进行数组除时,就需要判断作为除数的矩阵是否有零元素,any()函数可以实现这一功能。此函数有3种调用格式:any(a
)、any(A
)、any(A
,dim
)。对于向量a
(行向量或列向量),如果向量中至少有一个元素为非零数,any(a
)返回逻辑“真”,即“1”;而如果所有元素都为零,则返回逻辑“假”,即“0”。对于矩阵A
,any(A
)与all(A
)一样,也是作用于列向量上的,即如果矩阵A
的某列中存在某个元素为非零数,则返回结果的当前列为逻辑“真”,即“1”;如果所有元素都为零,则返回结果的当前列为逻辑“假”,即“0”。如果A
是多维矩阵,则any(A
)将第1个不是单维的维作为向量进行运算,运算规则同向量运算规则。any(A
,dim
)将指定的第dim
维作为向量进行计算。
例2.17 举例说明any()函数运算的规则。
>> A=[0 1 2;0 3 4]
A =
0 1 2
0 3 4
>> any(A)
ans =
0 1 1
>> any(A,2)
ans =
1
1
any()函数的其余规则与all()函数基本相同,在此不赘述。
3.exist()函数:查看变量或函数是否存在
在MATLAB程序设计中,有时候需要知道变量是否已经被定义过,即是否存在于当前内存中,有时候还需要详细了解变量的类型,这时exist()函数就显得非常有用。a=exist('A')
返回变量或者函数的状态或类型,a
值和A
对应的状态或类型如表2-2所示。
表2-2 exist()函数中a值与A对应的状态或类型
如果A存在于MATLAB的搜索路径下,但并不是MATLAB可以识别的非M文件,即非MDL文件、MEX文件时,exist('A')
或exist('A.ext')
将返回2。
在exist('A')
中,A
可以是当前路径下的子目录或相对路径。
如MATLAB的当前路径为D:\Program Files\MATLAB,则输入exist('bin')
便会得到如下内容。
>> exist('bin')
ans =
7
当然也可以检验计算机上的任意一条路径,但必须要输入全部路径。
如下面一段程序。
>> exist('D:\Program Files\MATLAB')
ans =
7
findall.p是toolbox\matlab目录下的一个P文件,输入如下。
>> exist('findall')
ans =
6
>> exist('sin')
ans =
5
flag=exist('A',kind),如果MATLAB找到指定类型kind下的对象A的话,此语句返回逻辑“真”,即flag值为“1”,否则返回逻辑“假”,flag值为“0”。其中,kind参数的取值如下。
● exist('A','var'):仅检查工作空间中的变量。
● exist('A','builtin'):仅检查MATLAB的内置函数。
● exist('A','file'):检查MATLAB搜索路径下的文件和路径。
● exist('A','dir'):仅检查路径。
如下面一段程序。
>> exist('a','var') %
在工作空间的变量中查找变量a
ans =
0 %表明没有找到名为“a”的变量
>> exist('A','var') %在工作空间的变量中查找变量A
ans =
1 %表明找到名为“A”的变量
>> exist('A','builtin') %在内置函数中查找函数A
ans =
0 %表明没有找到名为“A”的函数
4.find()函数:找出向量或矩阵中非零元素的位置标识
在许多情况下,都需要对矩阵中符合某一特定条件的元素的位置进行定位,如将某一矩阵中为零的元素设为1等。如果这个矩阵的元素非常多,手工修改就非常麻烦,而灵活运用find()函数和各种逻辑及关系运算可以实现绝大多数条件下的元素定位。find()函数的基本用法有 k=find(A
)、[i
,j
]=find(A
)、[i
,j
,v
]=find(A
),它是一个很有用的逻辑函数,在对数组元素进行查找、替换和修改变化等操作中占有非常重要的地位,熟练运用该函数可以方便而灵活地对数组进行操作。
k=find(A
):此函数返回由矩阵A
的所有非零元素的位置标识组成的向量。如果没有非零元素则会返回空值。
例2.18 举例说明find()函数的运算规则。
>> a=[0 1;2 3;0 4]
a =
0 1
2 3
0 4
>> find(a) %查找a中的非零元素
ans = %结果显示元素的位置标识是按列进行的,即从1开始
2 %数完第1列再数第2列,依次数下去
4
5
6
>> b(:,:,1)=[0 0;1 2]
b =
0 0
1 2
>> b(:,:,2)=[3 4;5 6]
b(:,:,1) =
0 0
1 2
b(:,:,2) =
3 4
5 6
>> find(b)
ans =
2
4
5
6
7
8
从以上内容不难看出,多维数组的元素位置标识是从低维到高维依次进位的,如对于一个三维数组b
,它的元素b
(1,1,1)、b
(2,1,1)、b
(1,2,1)、b
(2,2,1)、b
(1,1,2)、b
(2,1,2)、b
(1,2,2)、b
(2,2,2)的位置标识依次为1、2、3、4、5、6、7、8。
[i
,j
]=find(A
):此函数返回矩阵A
的非零元素的行和列的位置标识,其中i
代表行标,而j
代表列标。此函数经常用在稀疏矩阵中。在多维矩阵中通常将第1维用i
表示,将其余各维作为第2维,用j
表示。如对于上面的三维数组b
,有如下程序。
>> [i,j]=find(b)
i =
2
2
1
2
1
2
j =
1
2
3
3
4
4
[i
,j
,v
]=find(A
):此函数返回矩阵A
的非零元素的行和列的位置标识,其中i
代表行标,而j
代表列标,同时,将相应的非零元素的值放于列向量v
中,即i
和j
的值与[i
,j
]=find(A
)取值相同,只是增加了非零元素的值这一项,如下面一段程序。
>> [i,j,v]=find(b)
i =
2
2
1
2
1
2
j =
1
2
3
3
4
4
v =
1
2
3
5
4
6
>> a=[-1 -2;-3 -4]
a =
-1 -2
-3 -4
>> find(a<-3) %找出a中小于-3的元素的位置
ans =
4
>> find(a<-2) %找出a中小于-2的元素的位置
ans =
2
4
>> find(a==-1) %找出a中等于-1的元素的位置
ans =
1
>> a(find(a==-4))=-5 %找出a中等于-4的元素并将其换为-5
a =
-1 -2
-3 -5
利用find()函数可以实现部分矩阵的替换。
例2.19 利用find()函数实现部分矩阵的替换。
>> b=[3 4;5 6]
b =
3 4
5 6
>> a(find(a==-3))=b(find(a==-3)) %将矩阵a中等于-3的元素换为矩阵b中相应位置上的元素
a =
-1 -2
5 -5 %原来的-3被替换为5
>> a(find(a==-5))=[] %将矩阵a中等于-5的元素删除
a =
-1 5 -2
技巧:在矩阵运算中通常可以采用这种方法进行矩阵删除,即将矩阵的某个或某行元素直接赋值为零。
如果要删除矩阵b
中的第2行,可以用如下方法实现。
>> b(2,:)=[]
b =
3 4
上面“()”中的“:”为操作符,代表矩阵b
中第2行的所有元素。
5.isfinite()函数:确认矩阵元素是否为有限值
isfinite(A
):如果矩阵A
中的元素为有限值,则此函数在返回矩阵的相应位置上输出1,否则输出0。有限值为具有确定值的数,而NaN、+Inf、-Inf等都被视为无限值。isinf(A
)用于判断矩阵A
的元素是否为无限值,用法与isfinite()函数相同。
NaN称为不确定值,通常由0/0、Inf±Inf、Inf/Inf及NaN与其他任何数进行运算得到;Inf称为无穷大数,可以由任意非零实数除以零得到,而复数除以零会得到NaN数。
例2.20 isfinite()函数的用法。
>> c=[1 2;3 4]
c =
1 2
3 4
>> isfinite(c)
ans =
1 1
1 1
>> d=[1 +inf;nan -inf]
d =
1 Inf
NaN -Inf
>> isfinite(d)
ans =
1 0
0 0
>> isinf(d)
ans =
0 1
0 1
6.isempty()函数:确认矩阵是否为空矩阵
不要把空矩阵、零矩阵及矩阵不存在3个概念混淆。空矩阵说明矩阵存在,但是矩阵没有元素;零矩阵是指矩阵的所有元素都为零;矩阵不存在是指当前的工作空间中没有定义此矩阵变量。isempty(A
)可以判断一个存在的矩阵变量A
是否为空矩阵,如果矩阵变量A
为空矩阵则返回逻辑“真”,否则返回逻辑“假”。零矩阵至少有一维是零,如0×0、0×5、0×3×3等。零矩阵没有任何元素,可以用函数size(A
)来判断,如果其中有一维为零,则A
就是零矩阵。
例2.21 isempty()函数的用法。
>> a=[]
a =
[]
>> size(a)
ans =
0 0
>> b=rand(3,3,3);
>> b(:,:,:)=[]
b =
Empty array: 0-by-3-by-3
>> size(b)
ans =
0 3 3
b
是0×3×3维矩阵,因而a
是零矩阵。
>> isempty(b)
ans =
1
7.isequal()函数:判断对象是否相等
isequal(A
,B
,C
…):如果要判断的所有对象A
,B
,C
…具有相同的类型、大小和内容,对于矩阵来说,就是所有矩阵的维数相同,而且矩阵元素的数值相同。如果满足这样的条件,此函数返回逻辑“真”;反之,只要有一个对象与其他对象不相同,就会返回逻辑“假”。
例2.22 isequal()函数的用法。
>> a=[1 2]
a =
1 2
>> b=[1 2]
b =
1 2
>> c='hello world'
c =
hello world
>> d=[1;2]
d =
1
2
>> isequal(a,d)
ans =
0
>> isequal(a,b)
ans =
1
>> isequal(a,b,c)
ans =
0
8.isnumeric()函数:判断对象是不是数据
isnumeric(A
):如果A
是数据矩阵,如稀疏矩阵、双精度矩阵、复数矩阵等,此函数返回逻辑“真”;反之,如果A
是字符串、结构体矩阵等,则返回逻辑“假”。
例2.23 isnumeric()函数的用法。
>> isnumeric(a)
ans =
1
>> isnumeric(c)
ans =
0
>> e=[1+2i 3+4i]
e =
1.0000 + 2.0000i 3.0000 + 4.0000i
>> isnumeric(e)
ans =
1
还有一些逻辑函数也比较常用,为了保持完整性,将其部分列出,以供参考。
issparse():判断是否为稀疏矩阵。
isstr():判断是否为字符串。
islogical():判断是否为逻辑矩阵。
isfield():判断对象是否为某个结构体矩阵的域。
isstruct():判断是否为结构体。
ishandle():判断是否为图像句柄。