Browse Category: Mathematik

Kurvendiskussion

Bei der Kurvendiskussion geht es darum, eine mathematische Funktion zu untersuchen. D.h. das Verhalten zu verstehen. Dazu gibt es eine Menge von Eigenschaften, die von besonderem Interesse sind. Beispielsweise sind die Extremwerte von Interesse. Aber es gibt noch andere Aspekte, die man betrachtet (oder diskutiert). Dazu zählen üblicherweise folgende Eigenschaften:

  • Definitionsmenge
  • Nullstellen
  • Schnittpunkte mit der Y-Achse
  • Symmetrie Verhalten (Punkt- oder Achsen-Symetrie)
  • Verhalten im Unendlichen (Grenzwert-Betrachtungen)
  • Extremwerte (Hoch- und Tief-Punkte)
  • Wendepunkte
  • Graph der Funktion
  • Monotonie Betrachtung (Steigend oder Fallend)
  • Krümmungsverhalten
  • Wertemenge

Wie man diese Eigenschaften bestimmen kann und anhand welcher Kriterien man das Verhalten dann beschreibt, erfolgt immer nach dem gleichen Schema. Und durch Anwendung verschiedener mathematischen Methoden. Beispielsweise die Bestimmung der Ableitung, das Integrieren oder das Lösen von Gleichungen. Daher bietet sich dieses Thema sehr gut an für Tests. und Prüfungen.

Im folgenden Beitrag wird an einem Beispiel eine vollständige Kurvendiskussion durchgeführt und beispielhaft die Methodik erklärt, die sich dann auf beliebte andere Funktionen übertragen lässt. Das Beispiel soll folgende Funktion sein:

    \[y = x^4 -x^3-3x^2+5x -2\]

Die Definitionsmenge

Die Definitionsmenge gibt an, welche Werte (Zahlen) man in die Funktion (für das x) einsetzen darf. Alle diese Zahlen, die man für x einsetzen darf, sind dann die Definitionsmenge.

Den Definitionsbereich einer Funktion oder eines Terms bestimmt man, indem man untersucht, ob einzelne Teile des (Funktions)terms für bestimmte Zahlenbereiche nicht definiert sind. Zahlen aus diesen Bereichen muss man aus der Definitionsmenge herausnehmen.

In unserem Beispiel finden wir keine Einschränkungen, somit kann die Definitionsmenge wie folgt angegeben werden:

    \[\mathbb{D} = \{ -\infty < x < +\infty \}\]

Bestimmung der Nullstellen

Die Nullstellen einer Funktion f(x) sind die Stellen an denen f(x)=0 gilt. Oder geometrisch gesehen die Schnittpunkte des Graphen der Funktion f(x) mit der x-Achse.

D.h. man bestimmt die Nullstellen einer Funktion dadurch das man sie gleich Null setzt und durch verschiedenste Verfahren, dann die x-Werte bestimmt, an denen die Bedingung erfüllt ist. Mögliche Verfahren sind hier die Mitternachtsformel, das Horner-Schema oder auch die Linearfaktor-Zerlegung. Manchmal muss man einfach auch mal durch systematisches Probieren eine erste Nullstelle ermitteln, um dann weiter zu rechnen.

In unserem Beispiel kann man wie folgt vorgehen:

1. Nullstelle durch Probieren:

    \[1^4-1^3-3*1^2++5*1^1-2 = 0  \quad \Rightarrow \quad x_1 = 1\]

2. Nullstelle: Linerafaktor-Abspaltung über das Horner-Schema

Daraus ergibt sich dann folgende Darstellung:

    \[(x-1)^3 (x+2)\]

Somit erhalten wir eine dreifache Nullstelle und eine weitere vierte Nullstelle:

    \[x_1 = x_2 = x_3 = 1 \quad und \quad  x_4 = -2\]

Schnittpunkte mit der Y-Achse

Die Schnittstelle mit der yAchse ist der Punkt wo der Graph die yAchse schneidet. Der x-Wert, an dem die Funktion die yAchse schneidet, ist immer null.

Daher lässt sich der y-Wert genau dadurch bestimmen, in dem der Wert x=0 in die Funktionsgleichung eingesetzt wird.

Bitte nicht mit der Bestimmung der Nullstelle verwechseln, wo der Wert y=0 gesetzt wird.

In unserem Beispiel setzten wir also x=0 in f ein und bestimmen somit f(0):

    \[f(0) = -2\]

Symetrie

Man unterscheidet zwei Arten von Symmetrie: Punktsymmetrie und Achsensymmetrie. Eine Funktion ist punktsymmetrisch, wenn es irgendeinen Punkt gibt, an dem man die Funktion derart spiegeln kann, dass als Spiegelbild wieder die gleiche Funktion rauskommt.

Eine Funktion ist dagegen achsensymmetrisch, wenn es eine Gerade [also eine Achse] gibt, an der man die Funktion derart spiegeln kann, dass als Spiegelbild wieder die gleiche Funktion rauskommt.

Um herauszufinden ob eine Funktion symmetrisch ist gibt es zwei Formeln:

Wenn f(-x) = f(x) gilt, liegt eine Achsensymmetrie zur Y-Achse vor.
Wenn f(-x) = -f(x) gilt, liegt eine Punktsymetrie zum Ursprung vor.

Es gibt allerdings auch bei der Symmetrie-Untersuchung ganzrationalen Funktionen einen Trick. Bei dieser Art von Funktionen schaut man sich nur die Hochzahlen der Variablen an.

Gibt es nur gerade Hochzahlen, ist f(x) symmetrisch zur y-Achse.
Beispiele: f(x) = 2x6–3x4–5                   

Gibt es nur ungerade Hochzahlen, ist f(x) symmetrisch zum Ursprung.
Beispiele: f(x) = 2x5+12x3–2x                 f(x) = 2x-1+x-3–3²x-5+ x³–4x

Gibt es gemischte Hochzahlen, ist f(x) nicht symmetrisch.
Beispiele: f(x) = x3+2x2–3x+4                  f(x) = 2x·(x³+6x²+9x)

In unserem Beispiel handelt es sich um Polynom mit gemischten Hochzahlen, woraus wir ableiten können, dass keine Symmetrie vorliegt.

Verhalten im Unendlichen

Bei dieser Untersuchung prüft man wie sich die Funktion verhält, wenn die X-Werte gegen plus oder minus Unendlich gehen. Dabei kommt es immer auf den Faktor mit der größten Hochzahl an, da dieser das Verhalten am stärksten beeinflusst.

In unserem Beispiel wäre das der Faktor x^4. Möchte man nun wissen, wie das Verhalten im Unendlichen aussieht, setzt man gedanklich eine ganz große negative und eine positive Zahl ein und erkennt, dass durch die geradzahlige Hochzahl in beiden Fällen f(x) \to +\infty strebt.

Extremwerte

Die Bestimmung der Extremwerte gehört zu den wichtigsten Untersuchungen. Als Extremwerte werden die Hochpunkte, Tiefpunkte und Sattelpunkte einer Funktion bezeichnet. Die Berechnung erfolgt immer nach dem geglichen Schema:

  • Ist f'(x) = 0 so liegt ein Extremwert xe vor.
    um was für einen Extremwert es sich handelt ergibt die zweite Ableitung:
  • Ist f“(xe) < 0 liegt ein Hochpunkt vor.
  • Ist f“(xe) > 0 liegt ein Tiefpunkt vor.
  • Ist f“(xe) = 0 steht Überprüfung für Sattelpunkt / Wendepunkt an.

Um also die Extremwerte zu bestimmen, müssen die Ableitungen berechnet werden:

    \[f(x) = x^4 -x^3-3x^2+5x -2\]

    \[f'(x) = 4x^3-3x^2-6x+5\]

    \[f''(x) = 12x^2 - 6x -6\]

Dann müssen die Nullstellen der ersten Ableitung berechnet werden: x_1 = x_2 = 1 und \quad x_3=-5/4 = -1,25

In dem diese Nullstellen als x-Werte in die zweiten Ableitungen eingesetzt werden erhält man:

    \[f''(1) = 0 \quad und  \quad   f''(-1.25) = 20,25\]

So erhält man die Funktionswerte über die dann, auf Grund der obigen Kriterien, ersichtlich wird um welche Art von Extremwert es sich an den berechneten Stellen handelt. In unserem Beispiel haben wir bei x=-1.25 einen Tiefpunkt (weil der Funktionswert f“> 0 ist. Und am Punkt x=1 steht eine weitere Untersuchung auf mögliche Wendepunkte an, da so noch keine Aussage gemacht werden kann.

    \[TP = (f(-1,25);-1,25) \quad = ( -8,54;-1,25)\]

Wendepunkte

Ein Wendepunkt einer Funktion ist der Punkt, an dem der Funktionsgraph sein Krümmungsverhalten verändert. D.h. an diesem Punkt wechselt der Graph entweder von einer Rechts- in eine Linkskurve oder anders herum. Ein Wendepunkt liegt vor, wenn gilt: f’’(x) = 0 und f’’’(x) ≠ 0.

In unserem Beispiel müssen wir die Nullstellen der 2. Ableitung bestimmen, und benötigen dann noch die 3. Ableitung von f(x) um herauszufinden on ein Wendepunkt vorliegt.

    \[f''(x) = 12x^2 - 6x -6 = 0  \quad  \Rightarrow  \quad x_1  = 1 und  \quad x_2  = -0,5\]

    \[f'''(x) = 24x-6\]

Somit erhalten wir durch Einsetzen der gefundenen Nullstellen der zweiten Ableitung für f'''(1) = 18 und f'''(-0,5) = -18 woraus wir erkennen, dass an beiden Punkten ein Wendepunkt vorliegt, da das oben genannte Kriterium f’’(x) = 0 und f’’’(x) ≠ 0 erfüllt ist. Wir halten somit fest:

    \[WP_1 = (f(-0,5);-0,5) = (-5,06 ; -0,5) \qquad WP_2=(f(1);1) = (0;1)\]

Der Graph der Funktion zeichnen

Um den Graph zu zeichnen erstellt man sich am einfachsten eine Wertetabelle beispielsweise von [-3 bis 3] in einem passenden Abstand. Unter Berücksichtigung der bereits ermittelten Werte kann man dann recht schnell in passender Genauigkeit den Graphen zeichnen.

Wertetabelle { x, f(x) }
{-3.0, 64}, {-2.5, 21.43 }, {-2,0}, {-1.5, -7.8 }, {-1., -8.}, {-0.5, -5.1 }, {0, -2.0}, {0.5, -0.31}, {1, 0}, {1.5, 0.4}, {2.0, 4.0}, {2.5, 15.2}, {3.0,40}

Der Graph der Funktion sieht dann wie folgt aus:

Monotonie Verhalten

Das Monotonieverhalten einer Funktion gibt an, in welchem Bereich der Graph der Funktion steigt oder fällt. Daher ist das Monotonieverhalten wie folgt definiert: Die Funktion f ist streng monoton steigend, wenn f'(x) > 0 gilt. Die Funktion f ist streng monoton fallend, wenn f'(x) < 0 gilt.

Wichtig ist hierbei, dass Monotonie nur für die Teile des Definitionsbereiches betrachtet wird, in dem die Funktion stetig ist. Wenn bei einer Funktion Unterbrechungen existieren gibt es an diesen Stellen keine Monotonie. Daher ist es wichtig den Definitionsbereich der Funktion zu kennen.

In unserem Beispiel ist f'(x) = 4x^3-3x^2-6x+5 die in orange eingezeichnete Kurve. Um das Monotonie Verhalten von f(x) (der schwarz eingezeichneten Kurve) zu bestimmen, erstellt man am einfachsten eine Wertetabelle und zeichnet beide Funktionen in ein Diagramm.

Man erkennt am Verlauf sehr gut, in welchen Bereichen der Wert von f'(x) kleiner Null ist und somit deutlich wird, dass f(x) monoton fallend ist. Im obigen Beispiel ist f´(x) im Intervall [- \infty  \to  -5/4] kleiner Null, somit hat die Ausgangsfunktion f(x) hier ein monoton fallendes Verhalten. Was man am Verlauf des Graphen (in schwarz dargestellt) sehr gut erkennen kann.

Ebenso erkennt man, wo der Wert von f'(x) größer Null ist, was gleichbedeutend damit ist, dass die Ausgangsfunktion f(x) monoton steigend ist.

Krümmungsverhalten

Beim Krümmungsverhalten in der Mathematik untersucht man, ob eine Funktion linksgekrümmt oder rechtsgekrümmt ist. In manchmal Fällen kann eine Funktion beide Krümmungen aufweisen. Die Untersuchung kann über die zweite Ableitung durchgeführt werden.

Bei der Rechtskrümmung ist die zweite Ableitung an der Stelle x kleiner Null: f“(x) < 0.
Die Rechtskrümmung wird auch als konkav bezeichnet. 

Bei der Linkskrümmung ist die zweite Ableitung an der Stelle x größer als Null: f“(x) > 0.
Die Linkskrümmung wird auch als konvex bezeichnet. 

Funktion und 2. Ableitung

Dazu zeichnet man sich am einfachsten die 2. Ableitung zusammen mit dem Funktionsgraphen in ein Diagramm, um dadurch ablesen zu können, wie sich die Krümmung verhält. Im obigen Beispiel erkennt man, dass die 2. Ableitung zwischen den beiden Nullstellen negativ ist d.h. eine Rechtskrümmung vorliegt, in allen anderen Bereichen dagegen positiv und somit eine Linkskrümmung aufweist.

Wertemenge

Die Wertemenge gibt an, welche Werte für f(x) rauskommen können, wenn man jede Zahl aus der Definitionsmenge in die Funktion (als x-Werte) eingesetzt hat. Hier muss man also auf Wissen über die Zahlenmengen (Ganze Zahlen, Natürliche Zahlen, etc) zurück greifen.

In unserem Beispiel entspricht der Wertebereich der Menge der Reellen Zahlen. Geschrieben in Menegenschreibweise sieht das Ergebnis dann so aus:

    \[\mathbb{W} = \mathbb{R}\]

Zur Erinnerung man kennt in der Mathematik folgende Zahlenmengen:

Quelle: https://de.serlo.org

Jede Zahlenmenge schließt die vorherigen Zahlen mit ein. So gehören zu den reellen Zahlen die natürlichen, ganzen, rationalen und auch irrationalen Zahlen. Es gilt demnach:

Quelle : www.studyflix.de

Einheiten und wie man sie in Größen umrechnen kann.

Es gibt immer wieder Situationen, wo man Einheiten umrechnen muss. Dabei sind die gängigsten Einheiten wie Meter in Zentimeter umzurechnen ja noch überschaubar, aber wie rechnet man beispielsweise die Einheit Liter pro Quadrat Sekunde in Kubikmeter pro Stunde um?.

Als erstes sollte man sich die grundlegenden physikalischen Einheiten und ihre Größen in Erinnerung rufen. Alle physikalischen Größen werden immer als Potenzprodukte der 7 Basisgrößen (Länge, Masse, Zeit, elektrische Stromstärke, Temperatur, Stoffmenge und Lichtstärke) dargestellt. Dieses Potenzprodukt bezeichnet man als Dimension der jeweiligen Größe. Sie darf nicht mit der Einheit der Größe verwechselt werden und ist unabhängig vom Maßsystem.

EinheitZeichenGrößeEinheitZeichenGröße
Dezid10^{-1}Dekada10^{1}
Zentic10^{-2}Hektoh10^{2}
Millim10^{-3}Kilok10^{3}
Microµ10^{-6}MegaM10^{6}
Nanon10^{-9}GigaG10^{9}
Pikop10^{-12}TeraT10^{12}
Femtof10^{-15}PetaP10^{15}
Attoa10^{-18}ExaE10^{18}
Zeptoz10^{-21}ZettaZ10^{21}
Yoktoy10^{-24}YotaY10^{24}

Um Größen entsprechend umrechnen oder konvertieren zu können, ist neben dem Maßsystem auch gut, wenn man bestimmte weitere Zusammenhänge kennt, die sich nicht zwingend als Potenz-Produkte ableiten lassen. Einige dieser Zusammenhänge sind in der folgenden Tabelle aufgeführt (ohne Anspruch auf Vollständigkeit:

Zeit [t]Basiseinheit ist die Sekunde [s]
60 s = 1 min (Minute)
60 min = 1 h (Stunde) = 3600 s
24 h = 1 Tag = 1440 min = 86400 s
Liter [l]Basiseinheit ist der Liter [l]
1 Liter = 1 dm^3 =10^{-3}m^3
1m^3 = 1000 l
Fläche [A]Basiseinheit ist der Quadratmeter m^2
1 Ar = 100 m^2
1 HAr = 100 Ar = 10^2 \cdot 100 m^2 = 10^4 m^2
Arbeit [W]Basiseinheit ist das Joule [J]
1 J = 1 Nm = 1 kg \cdot m^2\cdot s^{-2}
Leistung [P]Basiseinheit ist das Watt [W]
1 W = 1 kg \cdot m^2\cdot s^{-3}
Masse [m]Basiseinheit ist das Kilogramm [kg]
1 Tonne [t] = 1 000 kg

Umrechnungsbeispiele

Beispiel 1

Es sollen

(1)   \begin{equation*} 4,4 \cdot 10^{-6} \frac {l}{s^2} \quad =  \quad ?\quad \lbrack \frac{m^3}{h} \rbrack\end{equation*}

umgerechnet werden.

Schritt1: Konvertierung der Einheiten mit Basiswissen:

1 m^3 = 1000 Liter daraus folgt 1 l = \frac{1}{1000} m^3

1 h = 3600 s daraus folgt 1s = \frac{1}{3600} h

Eingesetzt ergibt sich dann:

(2)   \begin{equation*} 4,4 \cdot 10^{-6} \dfrac {\dfrac{1}{1000} m^3}{(\dfrac{1}{3600})^2 h}  \quad = \quad 4,4 \cdot 10^{-6} \dfrac {(3600)^2}{1000}}  \quad \lbrack \dfrac{m^3}{h} \rbrack\end{equation*}

Rechnet man dann weiter ergibt sich :

(3)   \begin{equation*} 4,4 \cdot 10^{-6} \dfrac {(12,96)\cdot 10^6}{10^3}}  \quad =  57,024 \cdot 10^{-3} \quad \lbrack \dfrac{m^3}{h} \rbrack \quad =0,057024 \quad \lbrack \dfrac{m^3}{h} \rbrack\end{equation*}

Beispiel 2

Wieviel sind 122 cm/min umgerechnet km/h ?

Auch hier geht man wieder so vor, dass man die gegebenen Einheiten in Bezug zu den gesuchten Einheiten setzt. Also 1km = 1000 m, 1m = 100 cm damit entspricht 1 km = 1000 * 100 cm = 10^5 cm oder 1 cm = \frac{1}{10^5} km.

Analog dazu verfährt man mit der zweiten Größe: 1h = 60 min damit entspricht 1 min = \frac{1}{60} h. Diese Werte werden nun wieder in die EInheitengleichung eingesetzt:

(4)   \begin{equation*} 122  \quad \lbrack \dfrac{cm}{min} \rbrack \quad = 122  \cdot \dfrac{\frac{1}{10^5}}{\frac{1}{60}} \quad \lbrack \dfrac{km}{h} \rbrack  \quad = 122 \cdot \dfrac{60}{10^5}  = \dfrac{7320}{100000} = 0,00732 \quad \lbrack \dfrac{km}{h} \rbrack\end{equation*}

Pure Funktionen oder Lambda-Ausdrücke

Reine oder Pure Funktionen sind auch bekannt als anonyme Funktionen oder auch Lambda-Ausdrücke. Reine Funktionen zeichnen sich insbesondere dadurch aus, dass sie immer das gleiche Ergebnis zurückgeben, wenn sie mit den gleichen Argumenten aufgerufen werden. Dank dieser Eigenschaft, referenzielle Transparenz genannt, ist es für derartige Funktionen nicht möglich, Seiteneffekte zu besitzen. Eine reine Funktion ist also ein rechnerisches Analogon einer mathematischen Funktion.

Eine Pure Function ist demnach eine ganz normale Programmfunktion, die lediglich zwei besondere Eigenschaft hat:

  1. Für die gleichen Eingabeparameter wird stets der gleiche Rückgabewert geliefert
  2. Es existieren keine Side-Effects (Nebenwirkungen)

Durch diese beiden Merkmale ist eine Pure Function vergleichbar mit einer schlichten mathematischen Funktion y = f(x), die für denselben x-Wert immer denselben y-Wert ermittelt.

Das bedeutet in der Praxis, dass die gesamte Programmlogik einer Funktion allein mit den Daten aus den Eingabeparametern arbeitet und als Ergebnis genau ein Rückgabewert entsteht. Während des Funktionsaufrufes entstehen keinerlei Side-Effects, wie beispielsweise das Verändern des Zustandes von Variablen außerhalb der Funktion oder der Eingabeparameter, das Schreiben in die Datenbank bzw. einer Datei oder der Aufruf anderer Funktionen, die selbst Side-Effects besitzen.

Das Konzept der Pure Function lässt sich nicht nur relativ leicht erklären, sondern ermöglicht in der Praxis Software zu schreiben, die vom Entwickler einfach zu verstehen ist, da die einzelnen Funktionen untereinander keine Abhängigkeiten besitzen und für sich allein geschrieben, verstanden und getestet werden können. Dies ist ein riesiger Vorteil. 

Ein Großteil der heute geschriebenen Software folgt jedoch einem anderen Paradigma, dem objektorientierten Modell (OO-Modell), welches genau das Gegenteil propagiert. In der objektorientierten Welt werden Funktionen als Methoden bezeichnet und zusammen mit den dazugehörigen Daten von Objekten (Klassen) gekapselt. Beim Aufruf einer Methode kann diese sowohl auf die übergebenen Eingabeparameter als auch auf die Daten des Objektes selbst zugreifen. Dabei wird bewusst der Zustand eines Objektes über die entsprechenden Methoden manipuliert, es werden also die Daten im Objekt selbst verändert. Zusätzlich werden die Daten eines Objektes als Rückgabewert eines Methodenaufrufes an andere Objekte weitergereicht und unterliegen dort der weiteren Manipulation.

Beispiel von Pure Funktion in der Wolfram Language

Es gibt mehrere gleichwertige Möglichkeiten, reine Funktionen in der Wolfram Language zu schreiben. Die Idee besteht in allen Fällen darin, ein Objekt zu konstruieren, das mit entsprechenden Argumenten eine bestimmte Funktion berechnet. Wenn also beispielsweise fun eine reine Funktion ist, dann wertet fun[a] die Funktion mit dem Argument a aus.

Die Wolfram Language erlaubt die Verwendung sogenannter reiner Funktionen (pure functions). Ihr erstes Argument wird gekennzeichnet durch das „#“ Symbol und deren Ende ist mit dem „&“-Symbol gekennzeichnet.

So wie der Name einer Funktion irrelevant ist, wenn Sie nicht erneut auf die Funktion verweisen möchten, sind auch die Namen von Argumenten in einer reinen Funktion irrelevant. Die Wolfram Language ermöglicht es Ihnen, explizite Namen für die Argumente reiner Funktionen zu vermeiden und stattdessen die Argumente durch die Angabe von „Slot-Nummern“ #n zu spezifizieren. In einer reinen Funktion von Wolfram Language steht #n für das n-te Argument, das man angeben kann. # steht für das erste Argument. . #2 steht für das zweite Argument usw.

Das nachfolgende Beispiel soll dieses Vorgehen veranschaulichen. Es soll eine Funktion definiert werden, die immer 1 addiert:

(#+1)& 

Wenn diese Funktion nun als Kopf eines Ausdrucks angegeben wird, so wird die Funktion auf alle Argumente angewendet:

(#+1)&[50]  --->  51
(#+1)&[{50,60}] ---> 51,61

Das geht natürlich auch mit mehreren Argumenten, wie das nachfolgende Beispiel zeigt:

{#2, 1 + #1, #1 + #2} &[a, b]  ---> {b, 1+a, a+b}

Grundsätzlich lassen sich beliebig viele Argumente definieren. Ab einer bestimmten Anzahl wird es aber doch sehr herausfordernd, noch die Übersicht zu behalten. Reine Funktionen in der Wolfram Language können eine beliebige Anzahl von Argumenten annehmen. Sie können ## verwenden, um alle angegebenen Argumente anzusprechen, und ##n für das n-te und nachfolgende Argumente.

f[##, ##] &[x, y]  ---> f[x,y,x,y]

Reine Funktionen ermöglichen es, Funktionen anzugeben, die auf Argumente angewendet werden können, ohne explizite Namen für die Funktionen definieren zu müssen.

Weitere Beispiele…

#^2& is a short form for a pure function that squares its argument:

Map[#^2 &, a + b + c]


This applies a function that takes the first two elements from each list. By using a pure function, you avoid having to define the function separately:

Map[Take[#, 2] &, {{2, 1, 7}, {4, 1, 5}, {3, 1, 2}}]

Berechnung des Oster-Datums

Das Osterfest (lateinisch »pascha«, von hebräisch »pessach«) ist der höchste christliche Feiertag im Jahr, an welchem der Auferstehung Jesu Christi in besonderer Weise gedacht wird. Nach altem Brauch fällt Ostern immer auf den Sonntag nach dem ersten Frühjahrsvollmond (nach gregorianischem Kalender frühestens der 22. März und spätestens der 25. April), was auf dem Konzil von Nizäa im Jahre 325 endgültig festgelegt wurde.

Daher wurden immer wieder Methoden gesucht, um den genauen Tag zu bestimmen. Hier wird der Algorithmus von Carl Friedrich Gauß vorgestellt.

Methode nach C.F. Gauß

Die Berechnung des Oster-Datums erfolgt nach Regeln, die im Jahre 325 auf dem Konzil von Nicäa beschlossen wurden. Dem zu Folge das Osterfest am ersten Sonntag nach dem Frühlingsvollmond gefeiert werden soll. Fällt aber der erste Frühlingsvollmond auf einen Sonntag, so solle das Osterfest eine Woche später erfolgen. Da der Frühlingsvollmond im gregorianischen Kalender frühestens am 21. März und spätestens am 18. April eines Jahres liegen kann, schwankt der Ostertermin demnach immer zwischen dem 22. März und dem 25. April.

Der Algorithmus von C.F. Gauß besteht aus einer Abfolge von Rechenschritten die im folgenden dargestellt sind:

Ausgangspunkt ist immer eine Jahreszahl „Jahr“ für die das Oster-Datum berechnet werden soll.

Erster Schritt: Bestimmung der erforderlichen Hilfszahlen

M und N seien zwei Hilfszahlen, die sich aus folgendem Algorithmus berechnen:

M = Rest der Division von (15 - p + k - q) : 30 
N = Rest der Divison von (4 + k - q) : 7 
k = Jahreszahl ohne die letzten beiden Ziffern  
p = Ganzzahliger Anteil der Division (13 + 8k) : 25
q = Ganzzahliger Anteil der Division k : 4


Im Gregorianischen Kalender liegen die Werte für die Jahre 1900 bis 2099 immer bei M= 24 und N = 5. Über die obige Rechenformel lassen sich aber auch Werte die vor 19oo liegen bzw. solche die ab 2100 dann Gültigkeit besitzen.

Zweiter Schritt: Berechnung der weiteren Werte

a = Rest der Division Jahr : 19
b = Rest der Division Jahr : 4
c = Rest der Division Jahr : 7
d = Rest der Division (19a + M) : 30
e = Rest der Division (2b + 4c + 6d + N) : 7

Berechnung des Oster-Datums

Ostern ist dann der

Ostern = (22 + d + e)te März, sofern der Wert zwischen 1 und 31 liegt, 
sonst ist 
Ostern = (d + e -9)te April

Es gibt aber wie oben beschrieben einige Randbedingungen zusätzlich zu berücksichtigen:

Ist d = 29 und e = 6,            dann ist Ostern nicht am 26. April sondern am 19. April
Ist d = 28 und e = 6 und a > 10, dann ist Ostern nicht am 25. April sondern am 18. April

Programmtechnische Umsetzung

Damit haben wir alle Schritte zusammen, die sich C.F. Gauß überlegt hat und können nun mit Hilfe beliebiger Programmiersprachen ein Programm erstellen, mit dessen Hilfe das Oster-Datem bestimmt werden kann. In Mathematica (Wolfram Language) könnte das wie folgt berechnet werden:

M=24; Nu=5;

For[Jahr = 1950, Jahr < 1980, Jahr++, a = Mod[Jahr, 19];
 b = Mod[Jahr, 4];
 c = Mod[Jahr, 7];
 d = Mod[(19*a + M), 30];
 e = Mod[(2 b + 4 c + 6 d + Nu), 7];
 
 Ostern1 = (22 + d + e);
 Ostern2 = (d + e - 9);
 
 If[(d == 29 && e == 6), Ostern2 = 19, Ostern2 = (d + e - 9)];
 If[(d == 28 && e == 6 && a > 10), Ostern2 = 18, 
  Ostern2 = (d + e - 9)];
 
 If[(Ostern1 < 1 || Ostern1 <= 31), {Print[Jahr, " Ostern ist am ", 
    Ostern1, ". März"]; Print[]}, Print["Ostern liegt im April"]];
 
 If[(Ostern2 >= 1 ), {Print[Jahr, " Ostern ist am ", Ostern2, 
    ". April"]; Print[]}, {Print["Ostern liegt im März s.o."], 
   Print[]}]]

Das könnte man natürlich noch viel eleganter ausführen, aber für einen ersten Test des Algorithmus müsste die Umsetzung genügen:

1950 Ostern ist am 9. April

1951 Ostern ist am 25. März

1952 Ostern ist am 13. April

1953 Ostern ist am 5. April
 
1954 Ostern ist am 18. April
 
:
:
:

1976 Ostern ist am 18. April

1977 Ostern ist am 10. April

1978 Ostern ist am 26. März
 
1979 Ostern ist am 15. April

Veranschaulichung der Ableitung einer Funktion

Viele Schüler und Studenten tun sich etwas schwer, wenn es darum geht sich die Ableitung einer Funktion vorzustellen. Sie können zwar häufig durch die Anwendung der Ableitungsregeln, die Funktion ableiten, oft ist es aber mehr als nur hilfreich, wenn man auch versteht, was sich hinter dieser elementaren Operation verbirgt. Im folgenden soll mit Hilfe von Mathematica vorgestellt werden, wie die Ableitung-Operation visualisiert werden kann.

Ableiten heisst die Steigung eines Punktes P auf einem Graphen G zu bestimmen. Man lernt auch, dass man sich diesen Vorgang durch Anlegen einer Tangente an diesen Punkt vorstellen kann.

Um das Vorstellungsproblem anschaulich zu machen, schaut man sich am einfachsten eine Funktion und die zugehörige Ableitung-Funktion an.In Mathematica geht das über folgende Anweisungen:

f[x_] := x^3 - 9 x + 5;
Plot[{f[x], f'[x]}, {x, -4, 4}]

Wir sehen in der Graphik in Blau die Ursprungsfunktion und in Orange die Ableitungsfunktion. Dabei wird nun schon sehr deutlich, dass es nicht gerade intuitiv möglich ist, sich die Steigung (oder die Tangente mit der entsprechenden Steigung) auf dem blauen Graphen vorzustellen.

Relativ einfach kann man sich mit Mathematica nun erstmal eine Punkt-Menge auf dem Graphen vorstellen, an denen wir zur Veranschaulichung dann auch die Tangente anlegen werden. Nun aber zuerst zur Punkt-Menge.

Als erstes benötigen wir eine Liste mit Koordinaten der Punkte die wir auf dem Graphen darstellen möchten. Dazu nutzen wir folgenden Funktionsaufruf, der eine Liste über die Table-Funktion von x und zugehörigen f(x) Werten erzeugt:

Punktliste = Table[{x, f[x]}, {x, -4, 4, 0.25}]
Das ergibt dann folgende Liste:
{{-4., -23.}, {-3.75, -13.9844}, {-3.5, -6.375}, {-3.25, -0.078125}, \
{-3., 5.}, {-2.75, 8.95313}, {-2.5, 11.875}, {-2.25, 13.8594}, {-2., 
  15.}, {-1.75, 15.3906}, {-1.5, 15.125}, {-1.25, 14.2969}, {-1., 
  13.}, {-0.75, 11.3281}, {-0.5, 9.375}, {-0.25, 7.23438}, {0., 
  5.}, {0.25, 2.76563}, {0.5, 
  0.625}, {0.75, -1.32813}, {1., -3.}, {1.25, -4.29688}, {1.5, \
-5.125}, {1.75, -5.39063}, {2., -5.}, {2.25, -3.85938}, {2.5, \
-1.875}, {2.75, 1.04688}, {3., 5.}, {3.25, 10.0781}, {3.5, 
  16.375}, {3.75, 23.9844}, {4., 33.}}

Mit der Epilog-Funktion können diese Koordinaten dann als Punkte auf dem Graphen dargestellt werden:

Plot[f[x], {x, -4, 4}, 
 Epilog -> {PointSize[0.015], Hue[1], Map[Point, Punktliste]}]

Nun stellt sich die Frage, wie man für alle diese Punkte eine Tangentengleichung bestimmt werden kann. Ausgangspunkt ist die bekannte Geradengleichung: y = m x + b. Wobei m die Steigung beschreibt und b den y-Achsenabschnitt also den Abstand zur x-Achse bezeichnet.

Allgemein gilt für die Tangente an einem bestimmten Punkt a eines Graphen der Funktion f(x) folgende Gleichung:

    \[y_t(x) = f(a) + f'(a) (x-a)\]

Mit Mathematica lässt sich das problem relativ einfach beschreiben. Man definiert die Ausgangsfunktion f(x) und die allgemeine Tangentengleichung t(x) und den Punkt a und lässt sich das Ganze dann über die Plot-Funktion anzeigen.

Möchte man dies nun für alle Punkte, mit einer kürzeren Tangente darstellen geht man wie folgt vor:

Für unsere Tangentengleichung kennen wir bereits die Steigung m, diese ergibt sich aus der Ableitung f'(x) an einer bestimmten Position x.

Der Parameter b (Y-Achsen-Abschnitt) bestimmen wir über den Funktionswert des Graphen.

Punktliste1 = Table[{x, f[x]}, {x, -4, 4, 0.75}];
Plot[f[x], {x, -4, 4}, 
 Epilog -> {PointSize[0.015], Hue[1], Map[Point, Punktliste1]}]

Die nun fehlende Ziel-Koordinate bestimmen wir über folgende Überlegung: Ausgangs-Koordinate ist der Punkt x_0 und der zugehörige Funktionswert f(x_0). Die Steigung des anzulegenden Pfeils entspricht der Ableitung f'(x_0) damit lässt sich nun die Ziel-Koordinate berechnen in dem man auf der x-Achse ein Stück h dazu addiert und y-Position über die Steigung und den y-Achsen-Abschnitt berechnet.

Tangentenliste = 
 Table[{{x, f[x]}, {(x + 0.25), f[x] + f'[x]*0.9}}, {x, -4, 4, 0.25}]

Mit diesen Informationen sind wir in der Lage die gewünschte Darstellung berechnen zu lassen:

Show[Plot[f[x], {x, -4, 4}, 
  Epilog -> {PointSize[0.015], Hue[1], Map[Point, Punktliste]}], 
 Graphics[Map[Arrow, Tangentenliste]], Plot[f'[x], {x, -4, 4}]]

Eine weitere Möglichkeit…mit Hilfe der Manipulate-Funktion

Manipulate bietet die Möglichkeit bestimmte Parameter zu verändern. Damit lassen sich insbesondere Zusammenhänge sehr einfach visualisieren. Im folgenden soll dies am Beispiel der Tangente sprich der Ableitung an der Sinus-Funktion vorgestellt werden:

f[x_] = Sin[x];
l[x_, a_] := 
 f[a] + f'[a] (x - a) /; 
  a - 1/(Sqrt[1 + (f'[a])^2]) <= x <= a + 1/(Sqrt[1 + (f'[a])^2])
Manipulate[
 Plot[{f[x], l[x, a]}, {x, 0, 2 \[Pi]}, PlotRange -> {-1.5, 1.5}], {a,
   0, 2 \[Pi]}]

Das ergibt dann in Abhängigkeit des Parameters a, der über die Manipulate-Funktion sowohl manuell als auch automatisch verändert werden kann, folgende Ausgabe:

Damit dürfte es möglich sein, die Ableitung einer Funktion in 2 Dimensionen jedem Interessierten näher zu bringen. Hat man das einmal verstanden ist der Weg in die dritte Demission und zu den partiellen Ableitungen nicht mehr weit.

Newton Iteration

Das nach Isaak Newton benannte Verfahren, ist in der Mathematik ein häufig verwendeter Approximations-Algorithmus zur numerischen Lösung von nichtlinearen Gleichungen.

Die grundlegende Idee dieses Verfahrens ist, die Funktion in einem Ausgangspunkt zu linearisieren, d. h. ihre Tangente zu bestimmen, und die Nullstelle der Tangente als verbesserte Näherung der Nullstelle der Funktion zu verwenden.

Die erhaltene Näherung dient dann als Ausgangspunkt für einen weiteren Verbesserungsschritt. Diese Iteration erfolgt solange, bis die Änderung in der Näherungslösung eine festgesetzte Schranke unterschritten hat.

Mathematica Essenzen

Seit ich als Student die ersten Berührungspunkte mit Mathematica bekommen habe, fasziniert mich der dadurch aufgespannte Möglichkeitsraum der funktionalen Programmierung. Ursprünglich als Software für symbolische Mathematik gedacht, ist es heute in der Version 12 ein Softwaresystem für alle denkbaren Anwendungsmöglichkeit, weit über die Mathematik oder Physik hinaus.

Deutsche Dokumentation der Version 2.0 aus dem Jahr 1992

Die Sprache ist immer noch die selbe wie 1988 in der Version 1 und wurde aber zwischenzeitlich ergänzt und überarbeitet und heisst nun Wolfram Language. Das Handbuch gibt es nur noch elektronisch, da es mehrere tausend Seiten umfasst.

Der Umgang ist leider etwas gewöhnungsbedürftig und ich lerne heute immer noch dazu. In den folgenden Abschnitten werde ich meine Einsichten die nicht in den gängigen Büchern stehen versuchen als eine Art lose Blatt Sammlung (Codex) zu dokumentieren.

Darstellung von Funktionen

Mathematica stellt umfassende Funktionen für die Darstellung von Funktionen zur Verfügung. Die zentrale Funktion ist die Plot[]-Funktion. Im nachfolgenden Bild, ist die Grundmenge Funktion und dann die zentralen Einstellungs-Möglichkeiten wie die Darstellung ergänzt werden kann dargestellt:

Elementare Plot-Funktion

Wie man sieht, wird zwar den groben Funktion Verlauf, wichtige Eigenschaften sind aber nicht ersichtlich. Dazu muss man die Darstellung-Bereiche in x- und y-Richtung anpassen und weitere Möglichkeiten einsetzen, um mehr über den Funktionsgraph zu erfahren.

Erweiterte Plot-Funktionen

Mathematica stellt eine Vielzahl von Darstellung-Optionen bereit, die alle in der Online-Dokumentation aufgeführt sind.

Kurvendiskussion

Eine sehr häufig vorkommende Aufgabe ist die Untersuchung einer gegeben Funktion hinsichtlich Ihrer Eigenschaften wie Nullstellen, Extrema, Asymptoten etc. Wie das mit Hilfe von Mathematica gemacht werden kann, wird im folgenden vorgestellt.

Ausgangspunkt sei folgende Funktion und ihr Graph wie im nachfolgenden Bild dargestellt.

Bestimmung der Nullstellen

Um die Nullstellen zu bestimmen, sind die Punkte zu berechnen, an denen der Funktionswert von f(x) = 0 ist. Dazu gibt es zwei vordefinierte Funktionen in Mathematica: Solve und NSolve. NSolve versucht die Funktion mit hilfe numerischer Methoden zu lösen wo hingegen Solve versucht die Funktion aufzulösen, was natürlich mehr Rechenzeit erfordern kann und bisweilen auch nicht möglich ist.

NSolve[f[x] == 0]   ==>  {{x -> -3.24655}, {x -> 0.576888}, {x -> 2.66966}}

Die beiden Funktionen bestimmen sämtliche realen und komplexen Nullstellen eines Polynoms und geben das Ergebnis in Form einer Liste wieder. Also nicht in Form von Variablen denen die Werte bereits zugewiesen wurden. D.h. wir können auf diese Lösungen noch nicht ohne weitere Schritte zugreifen.

Bestimmung der 1. und 2. Ableitungen

Mathematica erlaubt es Ableitungen in Analogie zur händischen Form einfach durch Anfügen eines Ableitungsstrichs zu erzeugen. Formal richtig wäre aber die Benutzung der Funktion D[f[x], x].

f'[x]  ==> -9 + 3 x^2
f''[x] ==> 6x

Mit diesen Vorarbeiten lässt sich die komplette Kurvendiskussion, d.h. die Bestimmung der Nullstelle und der Extremwerte mit wenigen Zeilen berechnen:

Lösungen = {x, f[x]} /. NSolve[f[x] == 0]
{{-3.24655,0.}, {0.576888, -8.88178*10^-16}, {2.66966, -3.55271*10^-15}}

Extrema = {x, f[x]} /. NSolve[f'[x] == 0]
{{-1.73205, 15.3923}, {1.73205, -5.3923}}

Plot[f[x], {x, -4, 4}, 
 Epilog -> {{PointSize[0.02], Red, Map[Point, Lösungen],
    PointSize[0.02], Magenta, Map[Point, Extrema]}}]

Anschliessend sorgt die Plot-Funktion für die visuelle Darstellung:

Darstellung von Funktionen

Hierbei ist es wichtig die Vielzahl der Optionen kennen zu lernen. Anbei eine kleine und wie ich finde nützliche Auswahl:

Plot[-2 + 5 x - 3 x^2 - x^3 + x^4, {x, -6., 6.}]

So sieht der von Mathematica vorgeschlagene Graph als Standard dargestellt. Da hier aber alle wesentlichen zur Kurvendiskussion erfoderlichen Bereiche nicht gut dargestellt sind, stellt sich die Frage wie man das verändern kann. Nachfolgend der gleiche Graph mit einigen Plot-Optionen und den zugehörigen Ableitungen:

Plot[{f[x], f'[x], f''[x]}, {x, -2.2, 2.2}, AspectRatio -> 1, 
 AxesLabel -> {"x", "Y"}, PlotLabel -> {"Funktion f und Ableitungen"},
  PlotStyle -> {Black, Orange, LightGray}, 
 PlotLegends -> {"f", "f'", "f''"}, GridLines -> Automatic]

Gleitende Mittelwerte

Arithmetischer Mittelwert

Der Mittelwert beschreibt den statistischen Durchschnittswert. Für die Ermittlung des Mittelwertes addiert man alle Werte einer Datenmenge und teilt die Summe durch die Anzahl aller Werte.

RandomInteger[{1, 10}, 20] = {9, 8, 8, 7, 1, 7, 2, 4, 1, 5, 9, 3, 5, 4, 4, 5, 8, 10, 3, 9}

Mean[{9, 8, 8, 7, 1, 7, 2, 4, 1, 5, 9, 3, 5, 4, 4, 5, 8, 10, 3, 9}] ==> 28/5 = 5.6

Median

Der Median oder Zentralwert ist der Wert, der genau in der Mitte einer Datenmenge liegt. Die eine Hälfte aller ist immer kleiner, die andere größer als der Median. Bei einer geraden Anzahl von Individualdaten ist der Median die Hälfte der Summe der beiden in der Mitte liegenden Werte.

Median[{1, 2, 3, 4, 5, 6, 7}] ==> 4
oder
Median[{1, 2, 3, 4, 5, 6, 7, 8}] ==> 9/2
oder
Median[{9, 8, 8, 7, 1, 7, 2, 4, 1, 5, 9, 3, 5, 4, 4, 5, 8, 10, 3, 9}] ==> 5

Gleitender Mittelwert

Gleitende Mittelwerte dienen zur Glättung eines gegebenen Datenverlaufes. Die Glättung erfolgt durch das Abschwächen von besonders hohen oder niedrigen Werten. Die geschieht, indem eine neue Datenreihe erstellt wird, die aus den Durchschnitten von gleich großen Datenmengen berechnet werden. Dabei werden die Datenpunkte der Reihe durch den arithmetischen Mittelwert der Nachbarpunkte (oder einer gewichteten Form davon) ersetzt. Im einfachsten Fall geschieht dies durch Mittelung von drei Datenpunkten (der ausgewählte Datenpunkt und seine beiden Nachbarn):

MovingAverage[{a, b, c, d, e, f, g}, 3]
{1/3 (a + b + c), 1/3 (b + c + d), 1/3 (c + d + e), 1/3 (d + e + f), 
 1/3 (e + f + g)}

Beispiel

Ein Unternehmen liefert nachfolgende dargestellte Menge von Umsatzzahlen. Wir berechnen nun den gleitenden Mittelwert 3- Ordnung:

Wie oben beschrieben, nimmt man die n-Datenpunkte im Beispiel ist n=3, berechnet den Mittelwert und ersetzt das erste Datenelement durch diesen Mittelwert. Dann rückt man ein Feld weiter, berechnet wieder den Mittelwert, das ergibt dann den zweiten Eintrag usw.

Damit werden Datenreihen geglättet. Der gleitende Mittelwert wirkt wie ein Dämpfungsfilder, der die größten Ausreisser in der Zahlenreihe glättet.

Wie man das in der Praxis anwenden kann ist sehr anschaulich auf den Seiten von Matthias Busse vorgestellt. Er zeigt wie man einen Datenstrom (simuliert durch einen Strom von Zufallszahlen) glätten kann.

// Über viele Integer Werte einen Mittelwert bilden.
// Nach Matthias Busse Version 1.0

#define anzahlMittelWerte 10
int werte[anzahlMittelWerte]
int zaehlerMittelWerte=0;

void setup() {
  Serial.begin(9600);
}

void loop() {
  int n;
  float f;
  n=random(1,10);
  f= mittelWert(n);
  Serial.println(f);
  delay(100);
}

float mittelWert(int neuerWert) {// neuen Datenwert aufnehmen und Mittelwert zurück geben
   float mittel, summe=0;
   werte[zaehlerMittelWerte] = neuerWert;
   for(int k=0; k < anzahlMittelWerte; k++) 
      summe += werte[k];

  mittel=(float) summe / anzahlMittelWerte; 
  zaehlerMittelWerte++;

  if(zaehlerMittelWerte >= anzahlMittelWerte) 
      zaehlerMittelWerte=0;
  return mittel;
}

Eine etwas andere Lösung findet sich im Arduino Forum:

/*
  Smoothing
  http://www.arduino.cc/en/Tutorial/Smoothing
*/

// Define the number of samples to keep track of. The higher the number, the
// more the readings will be smoothed, but the slower the output will respond to
// the input. Using a constant rather than a normal variable lets us use this
// value to determine the size of the readings array.
const int numReadings = 10;

int readings[numReadings];      // the readings from the analog input
int readIndex = 0;              // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average

int inputPin = A0;

void setup() {
  // initialize serial communication with computer:
  Serial.begin(9600);
  // initialize all the readings to 0:
  for (int thisReading = 0; thisReading < numReadings; thisReading++) {
    readings[thisReading] = 0;
  }
}

void loop() {
  // subtract the last reading:
  total = total - readings[readIndex];
  // read from the sensor:
  readings[readIndex] = random(1,10); ;
  // add the reading to the total:
  total = total + readings[readIndex];
  // advance to the next position in the array:
  readIndex = readIndex + 1;

  // if we're at the end of the array...
  if (readIndex >= numReadings) {
    // ...wrap around to the beginning:
    readIndex = 0;
  }

  // calculate the average:
  average = total / numReadings;
  // send it to the computer as ASCII digits
  Serial.println(average);
  delay(100);        // delay in between reads for stability
}

Das Josephus Problem

Der Legende von Josephus nach, trieben die Römer eine Gruppe von Kriegern in eine Höhle, um diese dann gefangen zu nehmen. Nach der Legende entschieden diese Krieger aber dann sich nicht gefangen nehmen zu lassen, sondern lieber den Heldentod zu sterben d.h. sich gegenseitig umzubringen. In dem jeder seinen nächsten in der Reihe töten sollte. Also der Erste tötet den Zweiten, der Dritte den Vierten usw.
Nun stellt sich natürlich die Frage, sind alle Positionen gleich gut oder gibt es eine günstigste Position?

Um diese Frage zu beleuchten, formulieren wir das Problem etwas weniger kriegerisch um: Dazu stellen uns eine Menge n mit Personen vor, die in einer Reihe stehen und definieren zwei Funktionen:
RotateLeft: Nimmt die erste Person in der Reihe und stellt diese ans Ende der Reihe
Rest: Entfernt die nächste Person in der Reihe

Der Ablauf sieht nun wie folgt aus: Wir starten mit dem Aufruf der Funktion RotateLeft, diese nimmt die erste Person nach dem diese seinen Nachfolger virtuell erschlagen hat von der Liste und setzt sie am Ende ein. Dann folgt der Aufruf der Funktion Rest, diese eliminiert die zweite Person aus der Liste. Dann folgt wieder die Funktion RotateLeft, gefolgt von Rest usw. Dieser Prozess läuft solange bis nur noch eine Person übrig ist.

Mit Hilfe von Mathematica lässt sich dieser Ablauf sehr anschaulich programmieren und nachvollziehbar darstellen. Wir schreiben dazu eine rekursive Funktion mit dem Namen survivor[liste]. Dieser Funktion übergeben wir immer wieder die aktualisierte Liste der Personen.

Survivor[liste_] := 
 Nest[(Rest[RotateLeft[#]]) &, liste, Length[liste] - 1]

Mit Hilfe der Trace-Funktion die wir auf die RotateLeft Funktion anwenden, wird der rekursive Programm-Ablauf deutlicher:

TracePrint[Survivor[Range[20]], RotateLeft]

    RotateLeft
   {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,1}
    RotateLeft
   {4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,1,3}
    RotateLeft
   {6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,1,3,5}
    RotateLeft
   {8,9,10,11,12,13,14,15,16,17,18,19,20,1,3,5,7}
    RotateLeft
   {10,11,12,13,14,15,16,17,18,19,20,1,3,5,7,9}
    RotateLeft
   {12,13,14,15,16,17,18,19,20,1,3,5,7,9,11}
    RotateLeft
   {14,15,16,17,18,19,20,1,3,5,7,9,11,13}
    RotateLeft
   {16,17,18,19,20,1,3,5,7,9,11,13,15}
    RotateLeft
   {18,19,20,1,3,5,7,9,11,13,15,17}
    RotateLeft
   {20,1,3,5,7,9,11,13,15,17,19}
    RotateLeft
   {3,5,7,9,11,13,15,17,19,1}
    RotateLeft
   {7,9,11,13,15,17,19,1,5}
    RotateLeft
   {11,13,15,17,19,1,5,9}
    RotateLeft
   {15,17,19,1,5,9,13}
    RotateLeft
   {19,1,5,9,13,17}
    RotateLeft
   {5,9,13,17,1}
    RotateLeft
   {13,17,1,9}
    RotateLeft
   {1,9,17}
    RotateLeft
   {17,9}
  RotateLeft
   {9}

An diesem Beispiel wird deutlich, was für ein mächtiges Werkzeug Mathematica ist, um sehr komplexe Fragestellungen zu untersuchen.