13 if-statements

if-Statements

Die Möglichkeit bestimmte Teile eines Programms nur auszuführen wenn eine Bedingung erfüllt ist, eröffnet nochmal ganz neue Welten der Programmierung! Viele Dinge lassen sich ohne diese Möglichkeit sogar gar nicht verwirklichen.

"if" funktioniert in MATLAB folgendermaßen:

if condition1 == true
   dostuff
elseif condition2 == true
   dootherstuff
else
   dosomethingcompletelydifferent
end

In fast allen anderen Programmiersprachen funktioniert das ganze auch so oder so ähnlich, nur in der Syntax gibt es kleine Unterschiede.

Der wichtigste Teil an dem ganzen ist die Bedinung, die nach dem if steht, denn sie entscheidet darüber, was passiert, und ob überhaupt etwas passiert.
Egal was genau in der Bedingung steht, am Ende muss das ganze immer auf eine 1 (logical true) oder 0 (logical false) hinauslaufen.

Das kann direkt das Ergebnis einer Funktion sein wie z.B.:
isreal(x) 1 wenn x eine reelle Zahl ist, 0 wenn sie einen imaginären Teil hat
strcmp(a,b) 1 wenn a und b der gleiche Text sind, 0 wenn es Unterschiede gibt

Oder es ist das Ergebnis einer logischen Operation. In Matlab gibt es drei logische Operatoren: == , ~= , && , || , also istgleich, istungleich, und, oder.
== ergibt 1 wenn auf beiden Seiten das (genau) gleiche steht
~= ergibt 1 wenn auf beiden Seiten nicht das gleiche steht
&& ergibt 1 wenn die Bedingungen auf beiden Seiten erfüllt sind
|| ergibt 1 wenn mindestens eine der Bedingungen auf beiden Seiten erfüllt ist

Außerdem gibt es natürlich die Vergleichszeichen > größer, < kleiner, >= größergleich und <= kleinergleich.
> 1 wenn links größer rechts
< 1 wenn links kleiner rechts
>= 1 wenn links größer oder gleich rechts
<= 1 wenn links kleiner oder gleich rechts

ACHTUNG!
Bei Berechnungen, in denen Zahlen mit Nachkommastellen vorkommen, ist Vorsicht geboten! Computer besitzen eine endliche Genauigkeit bei Berechnungen mit so genannten floating-point numbers. Dadurch kann es passieren, dass bei einer Rechnung ein unerwartetes Ergebnis steht. Zum Beispiel sollte 0.4 - 0.3 - 0.1 als Ergebnis 0 haben, richtig? Matlab sieht das anders und antwortet mit 2.7756e-17. Ziemlich nah an Null, aber eben nicht ganz.
Also (0.4-0.3-0.1) == 0 wird euch unerfreulicherweise nicht eine 1 liefern.
Alternative Lösung: abs(0.4-0.3-0.1) <= 1e-16 hier überprüft ihr einfach ob das Ergebnis ziemlich nah an Null liegt und gebt euch damit zufrieden.

Genug Theorie, hier sind einige Beispiele:

Keep it simple

Im Bild unten ist im oberen Teil ein Beispiel dafür, wie man es nicht macht. Wenn man mehrere Bedingungen hat, die alle erfüllt sein müssen um in genau einer Berechnung zu resultieren sollte man nicht (!) ganz oft "if" untereinander schreiben, sondern die Bedingungen durch && miteinander verbinden, wie im unteren Teil zu sehen.

Das ginge auch...

Wie oben erwähnt genügt es bei || (oder) wenn eine der Bedinungen erfüllt ist. Hier haben wir zwei Bedingungen:
any(u>0), also irgendeine Zahl im Vektor u soll größer als Null sein -> Nicht erfüllt!
any(u==-5), also irgendeine Zahl im Vektor u soll genau -5 sein -> Erfüllt!
if bekommt eine 1, wird also ausgeführt.

Zwischenergebnisse abspeichern

Hier haben wir eine Schleife, die 10000 mal ein lineares Gleichungssystem löst. Wir möchten nun ein paar Zwischenergebnisse abspeichern, um am Ende sehen zu können, wie sich das so entwickelt hat, aber zehntausendmal brauchen wir das nicht und es würde auch zuviel Speicherplatz verbrauchen.
Stattdessen soll das Ergebnis in jedem 1000ten Schritt abgespeichert haben, sodass wir zum Schluss 10 Zwischenergebnisse haben.
Wir benutzen dazu die Funktion rem() in einer Kondition für if. rem() berechnet den Rest (remainder) einer Division. Wenn das erste Argument ein Vielfaches des zweiten ist, ist der Rest 0. Also schreiben wir rem(i,1000) == 0
Wenn der aktuelle Schritt i ein Vielfaches von 1000 ist, gibt die Funktion 0 aus, das istgleich-Zeichen gibt also eine 1 an das if zurück und wir können den Code zum abspeichern ausführen.

Ränder brauchen Sonderbehandlungen

In diesem Beispiel füllen wir eine Matrix mit irgendwelchen Berechnungen (in diesem Fall der Gradient einer Topographie), aber in der ersten und letzten Zeile sieht die Berechnung anders aus, als für den Rest der Matrix. Wir brauchen also ein if mit einer Bedinung, die überprüft, ob wir gerade einen Punkt an einem Rand betrachten.
Übrigens: ifs in Schleifen fressen unheimlich viel Rechenzeit. In diesem Beispiel war es sogar so schlimm, dass das Skript Stunden gelaufen ist. Man sollte also immer erstmal nachdenken, ob es auch eine Lösung ohne if gibt. Zum Glück gibt es oft tatsächlich eine, man muss halt nur seinen Grips viel mehr anstrengen.

Spezies bestimmen

Hier überprüfen wir, auf welchem Betriebssystem das ganze gerade läuft. Als erstes fragen wir uns, ob es vielleicht Windows sein könnte, wenn es das nicht ist, ist es vielleicht ein Mac (elseif), und wenn es das auch nicht ist, muss es wohl Linux sein, also unix, aber kein mac. Andernfalls ist es wohl eine Kartoffel, auf der wir das Skript gerade ausführen.

Switch - case

Wenn man nur eine Variable betrachtet, die verschiedene Werte annehmen kann, und jenachdem welcher Wert es ist sollen unterschiedliche Dinge passieren, kann man auch ein switch-case Konstrukt verwenden. Es gibt absolut keinen Nachteil darin, das ganze einfach mit if - elseif - elseif - elseif - else - end zu machen, aber so sieht es schöner aus und man kann mit seinen krassen programming-skills angeben.

Wenn man drei Tage lang im Dunkeln saß, keinen anderen Menschen gesehen hat, versucht hat das neue Blatt zu lösen und plötzlich nicht mehr sprechen kann.