第5章 关系和逻辑运算
除了传统的数学运算,MATLAB支持关系和逻辑运算。如果你已经有了一些编程经验,就会对这些运算熟悉。这些操作符和函数的目的是提供求解真/假命题的答案。一个重要的应用是控制基于真/假命题的一系列MATLAB命令(通常在M文件中)的流程,或执行次序。
作为所有关系和逻辑表达式的输入,MATLAB把任何非零数值当作真,把零当作假。所有关系和逻辑表达式的输出,对于真,输出为1;对于假,输出为零。
5.1 关系操作符
MATLAB关系操作符包括所有常用的比较。
表5.1
关系操作符
说明
<
小于
< =
小于或等于
>
大于
> =
大于或等于
= =
等于
~ =
不等于
MATLAB关系操作符能用来比较两个同样大小的数组,或用来比较一个数组和一个标量。在后一种情况,标量和数组中的每一个元素相比较,结果与数组大小一样。下面给出几个示例:
? A=1:9,B=9-A
A =
1 2 3 4 5 6 7 8 9
B =
8 7 6 5 4 3 2 1 0
? tf=A>4
tf =
0 0 0 0 1 1 1 1 1
找出A中大于4的元素。0出现在A<=4的地方,1出现在A>4的地方。
? tf=(A= =B)
tf =
0 0 0 0 0 0 0 0 0
找出A中的元素等于B中的元素。注意,=和= =意味着两种不同的事:= = 比较两个变量,当它们相等时返回1,当它们不相等时返回0;在另一方面,= 被用来将运算的结果赋给一个变量。
? tf=B-(A>2)
tf =
8 7 5 4 3 2 1 0 -1
找出A>2,并从B中减去所求得的结果向量。这个例子说明,由于逻辑运算的输出是1和0的数组,它们也能用在数学运算中。
? B=B+(B==0)*eps
B =
Columns 1 through 7
8.0000 7.0000 6.0000 5.0000 4.0000 3.0000 2.0000
Columns 8 through 9
1.0000 0.0000
这是一个演示,表明如何用特殊的MATLAB数eps来代替在一个数组中的零元素,eps近似为2.2e-16。这种特殊的表达式在避免被0除时是很有用的。
? x=(-3:3)/3
x =
-1.0000 -0.6667 -0.3333 0 0.3333 0.6667 1.0000
? sin(x)./x
Warning,Divide by zero
ans =
0.8415 0.9276 0.9816 NaN 0.9816 0.9276 0.8415
由于第四个数据是0,计算函数sin(x)/x时给出了一个警告。由于sin(0)/0是没定义的,在该处MATLAB结果返回NaN。用eps替代0以后,再试一次,
? x=x+(x==0)*eps;
? sin(x)./x
ans =
0.8415 0.9276 0.9816 1.0000 0.9816 0.9276 0.8415
现在sin(x)/x在x=0处给出了正确的极限。
5.2 逻辑操作符
逻辑操作符提供了一种组合或否定关系表达式。MATLAB逻辑操作符包括:
表5.2
逻辑操作符
说明
&
与
|
或
~
非
逻辑操作符用法的一些例子有:
? A=1:9;B=9-A;
? tf=A>4
tf =
0 0 0 0 1 1 1 1 1
找出A大于4。
? tf=~(A>4)
tf =
1 1 1 1 0 0 0 0 0
对上面的结果取非,也就是1替换0,0替换1。
? tf=(A>2)&(A<6)
tf =
0 0 1 1 1 0 0 0 0
在A大于2‘与’A小于6处返回1。
最后,上面的功能易于产生数组来表示不连续信号,或由多段其他信号所组成的信号。基本想法是,把数组中要保持的那些值与1相乘,所有其他值与0相乘。例如,
? x=linspace(0,10,100); % create data
? y=sin(x) ; % compute sine
? z=(y>=0).*y ; % set negative values of sin(x) to zero
? z=z+0.5*(y<0) ; % where sin(x) is negative add 1/2
? z=(x<=8).*z ; % set values past x=8 to zero
? plot(x,z)
? xlabel(' x '),ylabel(' z=f(x) '),title(' A Discontinuous Signal ')

图5.1 不连续信号
5.3 关系与逻辑函数
除了上面的关系与逻辑操作符,MATLAB提供了大量的其他关系与逻辑函数,包括:
表5.3
其 他 关 系 与 逻 辑 函 数
xor(x,y)
异或运算。x或y非零(真)返回1,x和y都是零(假)或都是非零(真)返回0。
any(x)
如果在一个向量x中,任何元素是非零,返回1;矩阵x中的每一列有非零元素,返回1。
all(x)
如果在一个向量x中,所有元素非零,返回1;矩阵x中的每一列所有元素非零,返回1。
除了这些函数,MATLAB还提供了大量的函数,测试特殊值或条件的存在,返回逻辑值。
表5.4
测 试 函 数
finite
元素有限,返回真值。
isempty
参量为空,返回真值。
isglobal
参量是一个全局变量,返回真值。
ishold
当前绘图保持状态是‘ON’,返回真值。
isieee
计算机执行IEEE算术运算,返回真值。
isinf
元素无穷大,返回真值。
isletter
元素为字母,返回真值。
isnan
元素为不定值,返回真值。
isreal
参量无虚部,返回真值。
isspace
元素为空格字符,返回真值。
isstr
参量为一个字符串,返回真值。
isstudent
MATLAB为学生版,返回真值。
isunix
计算机为UNIX系统,返回真值。
isvms
计算机为VMS系统,返回真值。
5.4 NaNs和空矩阵
NaNs和空矩阵([ ])要求在MATLAB中作特殊处理,特别是用在逻辑或关系表达式里。根据IEEE数学标准,对NaNs的几乎所有运算都得出NaNs。例如,
? a=[1 2 nan inf nan] % note,in use,NaN can be lowercase
a =
1 2 NaN Inf NaN
? b=2*a
b =
2 4 NaN Inf NaN
? c=sqrt(a)
c =
1.0000 1.4142 NaN Inf NaN
? d = (a= =nan)
d =
0 0 0 0 0
? f = (a~ =nan)
f =
1 1 1 1 1
上面的第一和第二计算式对NaN输入给出NaN结果。然而,最后两个计算式产生有点令人惊讶的结果。当NaN与NaN相比较时,(a= =nan)产生全部为0或假的结果,同时(a~ =nan)产生全部1或真值。于是,单个NaNs相互不相等。由于NaNs的这种特性,MATLAB有一个内置逻辑函数寻找NaNs。
? g=isnan(a)
g =
0 0 1 0 1
这个函数用find命令能找出NaNs的下标值。例如,
? i=find(isnan(a)) % find indices of NaNs
i =
3 5
? a(i)=zeros(size(i)) % changes NaNs in a to zeros
a =
1 2 0 Inf 0
当NaNs数学上由IEEE标准充分定义时,空矩阵由MATLAB的生成器确定,并有它自己的特性。空矩阵是简单的,它们是MATLAB大小为零的变量。
? size([ ])
ans =
0 0
当没有其它合适的结果时,在MATLAB中的许多函数返回空矩阵。或许最普通的例子是函数find:
? x=(1:5)-3 % new data
x =
-2 -1 0 1 2
? y=find(x>2)
y =
[ ]
在这个例子里,x没有包含大于2的值,所以没有返回下标。为了测试空结果,MATLAB提供了逻辑函数isempty。
? isempty(y)
ans =
1
在MATLAB里,空矩阵不等于任何非零矩阵(或标量)。这个事实由下面例子给出:
? y=[ ];
? a=(y==0)
a =
0
这说明一个空矩阵不等于一个标量,因此,
?find(y= =0)
ans =
[ ]
也就是说没有返回下标。同样地,
b=(y~=0)
b =
1
一个空矩阵不等于一个标量。但
? j=find(y~=0)
j =
1
尽管y大小为零,现在有一个下标值!上面最后的一个例子是MATLAB中一个非文本变化,由于版本3.5先于版本4.0,一个空矩阵与一个非空矩阵比较返回一个空矩阵。‘这个新的解释通常导致产生问题,因为y(find(y~=0))不存在。’例如,
? y(find(y~=0))
Index exceeds matrix dimensions.
这里MATLAB报告一个错误,因为下标超出了空矩阵y的维数。
NaNs和空矩阵的特性概括在表5.5中。
表5.5
NaNs 和 空 矩 阵
数据
a=[1 2 nan inf nan]
表达式
结果
2*a
[2 4 NaN  NaN]
(a= =nan)
[0 0 0 0 0]
(a~ =nan)
[1 1 1 1 1]
isnan(a)
[0 0 1 0 1]
y=find(a= =0)
y=[ ]
isempty(y)
1
(y= =0)
0
find(y= =0)
[ ]
(y~ =0)
1
j=find(y~ =0)
j=1
y(j)
Error! y(j) does not exist.