4.3 Logische Operatoren

Die Symbole &, |, and ~ stehen für die logischen Operatoren and, or, and not. Sind die Operanden Felder, wirken alle Befehle elementweise. Der Wert 0 representiert das logische FALSE (F), und alles was nicht Null ist, representiert das logische TRUE (T). Die Funktion xor(A,B) implementiert das ''exklusive oder''. Die Wahrheitstabellen für diese Funktionen sind in 4.5 zusammengestellt.

Wenn einer der Operanden ein Skalar ist und der andere eine Matrix, dann wird der Skalar auf die Größe des Feldes expandiert. Die logischen Operatoren verhalten sich dabei gleich wie die Vergleichsoperatoren. Das Ergebnis der Operation ist wieder ein Feld der gleichen Größe.


Table 4.5: Logische Operatoren
INPUT and or xor not
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

Die Priorität der logischen Operatoren ist folgendermaßen geregelt:

Die ''Links vor Rechts'' Ausführungspriorität in MATLAB macht a|b&c zum Gleichen wie (a|b)&c. In den meisten Programmiersprachen ist a|b&c jedoch das Gleiche wie a|(b&c). Dort hat & eine höhere Priorität als |. Es ist daher in jedem Fall gut, mit Klammern die notwendige Abfolge zu regeln.

Eine Besonderheit stellen die beiden logischen Operatoren && und ||, die man als logische Operatoren mit short circuit bezeichnet. Dabei wird z.B. beim Befehl
x = (b ~= 0) && (a/b > 18.5)
der zweite Teil mit der Divison nicht mehr ausgeführt, wenn b gleich 0 ist. Dies ist nämlich nicht mehr notwendig, da das Ergebnis unabhängig vom zweiten Teil das Resultat FALSE liefern muss. Man spart sich damit in diesem Fall die Warnung, dass durch Null dividiert wird.

Besonders praktisch ist dieses Feature, wenn eine Variable zum Zeitpunkt der Berechnung nicht existiert. Wenn also a nicht als Variable existiert (exist), liefert der Befehl
~exist('a','var') | isempty(a)
die Fehlermitteilung Undefined function or variable 'a', da der zweite Befehl (isempty) nicht ausgeführt werden kann. Verwendet man hingegen
~exist('a','var') || isempty(a)
kann die Zeile auch in diesem Fall ausgewertet werden und liefert den Wert 1 (TRUE), wenn a nicht existiert oder ein leeres Feld ist.

Die Verwendung von && und || stellt also sicher, dass jene Teile des logischen Konstrukts nicht mehr ausgeführt werden, wenn sie das Ergebnis nicht mehr beeinflussen können.

Bei der Verwendung von Vergleichsoperatoren und logischen Operatoren in Steuerkonstrukten, wie z.B. if-Strukturen, ist zur Entscheidung natürlich nur ein skalarer logischer Wert möglich. Einen solchen kann man aus logischen Arrays durch die Befehle:

any(M) oder any(M,DIM):
Ist TRUE, wenn ein Element ungleich Null ist.
all(M) oder all(M,DIM):
Ist TRUE, wenn alle Elemente ungleich Null sind.

Wenn die Befehle any(M) und all(M) auf Felder angewandt werden, verhalten sie sich analog zu anderen Befehlen (wie z.B. sum(M)) und führen die Operation entlang der ersten von Eins verschiedenen Dimension aus. Das Ergebnis ist dann in der Regel kein Skalar.

Die Ergebnisse von Vergleichsoperationen und logischen Operarationen können für die logische Indizierung, 3.6.1, verwendet werden.

Ist man nur an den Positionen interessiert, kann man mit I = find(L) die linearen Indices, bzw. mit [m,n] = find(L) die 2-dim Indices erhalten, für die die Bedingung in L erfüllt ist.

Beispiel mit find, ind2sub und sub2ind:

  m = reshape([1:12],3,4);       m = [ 1     4     7    10
                                       2     5     8    11
                                       3     6     9    12 ]

  l = m>3 & m<8;                 l = [ 0     1     1     0
                                       0     1     0     0
                                       0     1     0     0 ]

  i = find(l);                   i = [ 4;    5;    6;    7 ]

  [si,sj] = find(l);            si = [ 1;    2;    3;    1 ]
                                sj = [ 2;    2;    2;    3 ]

  Umrechnung: [si,sj] = ind2sub(size(m),i);
                    i = sub2ind(size(m),si,sj);

Beispiel mit any und all:

  m = reshape([1:12],3,4);            m = [ 1     4     7    10
                                            2     5     8    11
                                            3     6     9    12 ]

  l = m>=2 & m<=11;                   l = [ 0     1     1     1
                                            1     1     1     1
                                            1     1     1     0 ]

  an1 = any(l)                      an1 = [ 1     1     1     1 ]
  al1 = all(l);                     al1 = [ 0     1     1     0 ]

  an2 = any(l,2); al2 = all(l,2);   an2 = [ 1         al2 = [ 0
                                            1                 1
                                            1 ]               0 ]

  an = any(l(:));                   an = 1                
  al = all(l(:));                   al = 0

Winfried Kernbichler 2005-04-26