<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="pmathml.xsl"?>
<!DOCTYPE html [
  <!ENTITY rightarrow "&#8594;">
  <!ENTITY Rightarrow "&#8658;">
  <!ENTITY Leftrightarrow "&#8660;">
  <!ENTITY Element "&#8712;">
  <!ENTITY Exists "&#8707;">
  <!ENTITY Sum "&#8721;">
  <!ENTITY setminus "&#8726;">
  <!ENTITY VerticalBar "&#8739;">
  <!ENTITY approx "&#8776;">
  <!ENTITY leq "&#8804;">
  <!ENTITY geq "&#8805;">
  <!ENTITY prec "&#8826;">
  <!ENTITY succ "&#8827;">
  <!ENTITY succeq "&#8829;">
  <!ENTITY preceq "&#8828;">
  <!ENTITY asymp "&#8781;">
  <!ENTITY subseteq "&#8838;">
  <!ENTITY Intersection "&#8898;">
  <!ENTITY Kscr "&#61242;">
  <!ENTITY Ropf "&#8477;">
  <!ENTITY Nopf "&#8469;">
  <!ENTITY Zopf "&#8484;">
  <!ENTITY pm "&#177;">
  <!ENTITY epsi "&#949;">
  <!ENTITY Hscr "&#8459;">
  <!ENTITY Lscr "&#8466;">
  <!ENTITY % htmlDTD PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
  %htmlDTD;
]>

<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Automatische Berechnung von Grenzwerten und Implementierung in Mathematica</title><style type="text/css">
     .mathcell {
       padding-left:2%;
     }
     .mathlabel {
       width:4em;
       float:left;
       padding-top:3px;
       color: #454F99;
       font-size: 10px;
       font-family: Helvetica;
     }
     .mathinput {
       position:relative;
       width:90%;
       margin-top:5px;
       border-width:1px 1px 0px 1px;
       border-style:solid;
       padding:0.5em;
       font-weight: bold;
       font-size: 14px;
       left:4em;
       background-color:#dddddd;
     }
     .mathoutput {
       position:relative;
       width:90%;
       margin-bottom:5px;
       border-width:0px 1px 1px 1px;
       border-style:solid;
       padding:0.5em;
       font-size: 14px;
       left:4em;
       background-color:#dddddd;
     }
     .mathprint {
       position:relative;
       width:90%;
       border-width:0px 1px 0px 1px;
       border-style:solid;
       padding:0.5em;
       font-size: 14px;
       left:4em;
       background-color:#cccccc;
     }
     .mathmessage {
       position:relative;
       width:90%;
       border-width:0px 1px 0px 1px;
       border-style:solid;
       padding:0.5em;
       font-size: 14px;
       left:4em;
       background-color:#ffffff;
     }
     .mathcellblock {
       margin-top:1em;
       margin-bottom:1em;       
     }
     .mmldisplay {
       text-align:center;
       margin-top:0.5em;
       margin-bottom:0.5em;       
     }
   </style></head><body>

<a href="Grundlagen.xml">Zurück</a> - <a href="Inhalt.xml">Inhalt</a> - <a href="index.html">Übersicht</a> - <a href="Paket.xml">Vorwärts</a><br />


<a name="DerMrvLimitAlgorithmus" /><h2>4 Der MrvLimit-Algorithmus</h2>
Nachdem wir nun eine Vorstellung der Wachstumsprozesse im Unendlichen haben und bereits einige
Bruchstücke des Algorithmus kennen, wird es jetzt Zeit, den MrvLimit-Algorithmus vollständig
zu betrachten. Der Fokus wechselt mit diesem Kapitel weg vom mathematischen Hintergrund, hin zu den
Algorithmen und Strategien.<br /><br />

Während wir den Ablauf des Algorithmus Schritt für Schritt beobachten, werden wir auch gleich
überlegen, welche weiteren Funktionen problemlos in das Funktionsmodell übernommen werden können.<br /><br />

Außerdem werden wir einen kritischen Blick darauf werfen, ob die vorkommenden rekursiven Aufrufe des
Algorithmus tatsächlich nicht zu unendlichen Rekursionen führen können. Die entsprechenden Nachweise
sind anspruchsvoll, jedoch zum Verständnis des Algorithmus nicht zwingend erforderlich, lassen sich also
beim ersten Lesen bequem überspringen.

<a name="Transformation2" /><h3>4.1 Transformation</h3>
Wie schon in <a href="Ueberblick.xml#Transformation">Kapitel 2.1</a> dargelegt, ist der Algorithmus darauf spezialisiert, Grenzwertaufgaben
für <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>x</mi>
<mo>&rightarrow;</mo><mn>&infin;</mn>
</math> zu lösen. Zunächst muss die Funktion also geeignet transformiert
werden: Für <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>x</mi>
<mo>&rightarrow;</mo><msup><mrow><msub><mi>x</mi> <mn>0</mn></msub>
</mrow> <mo>+</mo></msup>
</math> ersetze <i>x</i> durch <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msub><mi>x</mi> <mn>0</mn></msub>
<mo>+</mo><mfrac><mrow><mn>1</mn>
</mrow><mrow><mi>x</mi>
</mrow></mfrac>
</math>,
für <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>x</mi>
<mo>&rightarrow;</mo><msup><mrow><msub><mi>x</mi> <mn>0</mn></msub>
</mrow> <mo>-</mo></msup>
</math> ersetze <i>x</i> durch <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msub><mi>x</mi> <mn>0</mn></msub>
<mo>-</mo><mfrac><mrow><mn>1</mn>
</mrow><mrow><mi>x</mi>
</mrow></mfrac>
</math> und
für <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>x</mi>
<mo>&rightarrow;</mo><mo lspace="thinthinmathspace" rspace="0em">-</mo><mn>&infin;</mn>
</math> ersetze <i>x</i> durch <i>-x</i>. <br /><br />
Die Behandlung von
beidseitigen Grenzwerten wird in Computeralgebrasystemen unterschiedlich gehandhabt: Mathematica scheint
bevorzugt Grenzwerte von oben (Direction <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mo>&rightarrow;</mo>

</math> -1) zu berechnen, Maple liefert
<i>undefined</i>, falls der
Grenzwert nicht eindeutig ist. Im reellen Fall bleibt noch die Möglichkeit, beide Grenzwerte
auszugeben, falls sich unterschiedliche Grenzwerte ergeben. Abgesehen von Mathematicas unvorsichtiger
Herangehensweise muss man bei beidseitigen Grenzwerten aber immer beide einseitigen Grenzwerte
ermitteln und vergleichen.


<a name="ErweitertesFunktionsmodell" /><h3>4.2 Erweitertes Funktionsmodell</h3>
Der ursprüngliche Algorithmus beschränkt sich auf exp-log Funktionen, d.h. Konstanten, Potenzen von x,
Grundrechenarten, Exponentialfunktion und Logarithmus. Betrachtet man den Algorithmus aber im Detail,
werden hauptsächlich vier Arten von Funktionen unterschieden: Funktionen mit stetigem Grenzübergang,
Funktionen mit hebbaren polynomiellen Polstellen, Funktionen mit logarithmischen Polstellen
und Funktionen mit nicht hebbaren (essenziellen) Polstellen,
jeweils natürlich auf den Punkt des Grenzüberganges bezogen. Grenzübergänge von stetigen
Funktionen können direkt berechnet werden, hebbare Polstellen werden durch Potenzreihenanalyse
betrachtet. Logarithmische Polstellen werden dabei automatisch von ω-Termen zu <i>x</i>-Termen
abgebaut. Nur die nicht hebbaren Polstellen der Exponentialfunktion werden
algorithmisch erfasst und analysiert.<br /><br />
Daher spricht auch nichts dagegen, weitere Funktionen in das Funktionsmodell aufzunehmen, solange
die Funktionen höchstens hebbare Polstellen besitzen bzw. der Grenzübergang an unkritischen Stellen
der Funktion auftritt und solange die Funktion in eine Potenzreihe entwickelbar ist. <br /><br />
Unter anderem kann so der Funktionsraum um trigonometrische Funktionen und die Gammafunktion
erweitert werden:<br /><br />

<div class="mmldisplay"><math xmlns='http://www.w3.org/1998/Math/MathML' mode='display'>
<mrow><mtable columnalign="left left "><mtr><mtd><mo lspace="0em" rspace="thinmathspace">sin</mo>
<mo>(</mo><mi>x</mi><mo>)</mo><mo>,</mo><mo lspace="0em" rspace="thinmathspace">cos</mo><mo>(</mo><mi>x</mi><mo>)</mo><mo>,</mo><mo lspace="0em" rspace="thinmathspace">tan</mo><mo>(</mo><mi>x</mi><mo>)</mo></mtd> <mtd><mtext>für </mtext>
<mi>x</mi><mo>&Element;</mo><mi>&Ropf;</mi></mtd></mtr> <mtr><mtd><mo lspace="0em" rspace="thinmathspace">arcsin</mo>
<mo>(</mo><mi>x</mi><mo>)</mo><mo>,</mo><mo lspace="0em" rspace="thinmathspace">arccos</mo><mo>(</mo><mi>x</mi><mo>)</mo></mtd> <mtd><mtext>für </mtext>
<mi>x</mi><mo>&Element;</mo><mi>&Ropf;</mi></mtd></mtr> <mtr><mtd><mo lspace="0em" rspace="thinmathspace">arctan</mo>
<mo>(</mo><mi>x</mi><mo>)</mo></mtd> <mtd><mtext>für </mtext>
<mo>-</mo><mn>&infin;</mn><mo>&le;</mo><mi>x</mi><mo>&le;</mo><mo>+</mo><mn>&infin;</mn></mtd></mtr> <mtr><mtd><mi>&Gamma;</mi>
<mo>(</mo><mi>x</mi><mo>)</mo></mtd> <mtd><mtext>für </mtext>
<mi>x</mi><mo>&Element;</mo><mi>&Ropf;</mi></mtd></mtr> <mtr><mtd><msub><mi>&Gamma;</mi> <mi>s</mi></msub>
<mo>(</mo><mi>x</mi><mo>)</mo><mo>=</mo><mo lspace="0em" rspace="thinmathspace">log</mo><mo>(</mo><mi>&Gamma;</mi><mo>(</mo><mi>x</mi><mo>)</mo><mo>)</mo></mtd> <mtd><mtext>für </mtext>
<mn>0</mn><mo>&le;</mo><mi>x</mi><mo>&le;</mo><mo>+</mo><mn>&infin;</mn></mtd></mtr> <mtr><mtd><mi>&psi;</mi>
<mo>(</mo><mi>x</mi><mo>)</mo><mo>=</mo><mi>&Gamma;</mi><mo>'</mo><mo>(</mo><mi>x</mi><mo>)</mo><mo>/</mo><mi>&Gamma;</mi><mo>(</mo><mi>x</mi><mo>)</mo></mtd> <mtd><mtext>für </mtext>
<mo>-</mo><mn>&infin;</mn><mi>&lt;</mi><mi>x</mi><mo>&le;</mo><mo>+</mo><mn>&infin;</mn></mtd></mtr> <mtr><mtd><msup><mi>&psi;</mi> <mrow><mo>(</mo>
<mi>n</mi><mo>)</mo></mrow></msup>
<mo>(</mo><mi>x</mi><mo>)</mo><mo>=</mo><mfrac><mrow><msup><mi>d</mi> <mi>n</mi></msup>
</mrow><mrow><msup><mi>dx</mi> <mi>n</mi></msup>
</mrow></mfrac><mi>&psi;</mi><mo>(</mo><mi>x</mi><mo>)</mo></mtd> <mtd><mtext>für </mtext>
<mo>-</mo><mn>&infin;</mn><mi>&lt;</mi><mi>x</mi><mo>&le;</mo><mo>+</mo><mn>&infin;</mn></mtd></mtr></mtable></mrow>

</math></div>

(Weitere Funktionen werden in <a href="Anhang.xml#gru96">[Gru96]</a> Kapitel 5.1 aufgeführt.)<br /><br />

Falls solche Funktionen in der Grenzwertaufgabe auftreten, muss vor der weiteren Grenzwertberechnung
überprüft werden, ob das Argument der Funktion existiert und die jeweiligen Einschränkungen erfüllt
werden. Das macht man am besten in Form einer Vorverarbeitung.


<a name="Vorverarbeitung" /><h3>4.3 Vorverarbeitung</h3>
Die Vorverarbeitung dient dazu, die Struktur der Funktion zu überprüfen und anzupassen. Nicht
unterstützte Funktionen müssen erkannt werden, bei manchen Funktionen muss das Argument
der Funktion auf Gültigkeit geprüft werden. Der dazu erforderliche rekursive Aufruf des
Grenzwertalgorithmus ist nicht kritisch, da der rekursive Aufruf ja nur mit einem Teilausdruck
der Funktion erfolgt. Unendliche Rekursionen sind so nicht möglich.<br /><br />

Falls ein nicht unterstützter Ausdruck auftritt,
muss die Grenzwertberechnung mit einer entsprechenden Fehlermeldung abgebrochen werden.
Andere Ausdrücke müssen für die weitere Verarbeitung erst in eine geeignete Darstellung transformiert
werden:

<div class="mmldisplay"><math xmlns='http://www.w3.org/1998/Math/MathML' mode='display'>
<mrow><mtable columnalign="right left left left "><mtr><mtd><msup><mi>a</mi> <mi>b</mi></msup>
</mtd> <mtd><mo>&rightarrow;</mo>
</mtd> <mtd><msup><mi>e</mi> <mrow><mo lspace="0em" rspace="thinmathspace">log</mo>
<mo>(</mo><mi>a</mi><mo>)</mo><mo>&sdot;</mo><mi>b</mi></mrow></msup>
</mtd> <mtd><mtext>es sei denn, </mtext>
<mi>a</mi><mo>=</mo><mi>e</mi><mtext> oder <i>b</i> ist konstant.</mtext></mtd></mtr> <mtr><mtd><mi>&Gamma;</mi>
<mo>(</mo><mi>x</mi><mo>)</mo></mtd> <mtd><mo>&rightarrow;</mo>
</mtd> <mtd><msup><mi>e</mi> <mrow><msub><mi>&Gamma;</mi> <mi>s</mi></msub>
<mo>(</mo><mi>x</mi><mo>)</mo></mrow></msup>
</mtd> <mtd><mtext>falls </mtext>
<mi>x</mi><mo>&rightarrow;</mo><mn>&infin;</mn></mtd></mtr></mtable></mrow>

</math></div>
<br /><br />


Gleichzeitig bietet es sich an, redundante Funktions-Schreibweisen, wie z.B. bei den Trigonometrischen
Funktionen, auf die Grundformen zu beschränken:

<div class="mmldisplay"><math xmlns='http://www.w3.org/1998/Math/MathML' mode='display'>
<mrow><mtable columnalign="right left left "><mtr><mtd><mo lspace="0em" rspace="thinmathspace">sec</mo>
<mo>(</mo><mi>x</mi><mo>)</mo></mtd> <mtd><mo>&rightarrow;</mo>
</mtd> <mtd><mn>1</mn>
<mo>/</mo><mo lspace="0em" rspace="thinmathspace">cos</mo><mo>(</mo><mi>x</mi><mo>)</mo></mtd></mtr> <mtr><mtd><mo lspace="0em" rspace="thinmathspace">csc</mo>
<mo>(</mo><mi>x</mi><mo>)</mo></mtd> <mtd><mo>&rightarrow;</mo>
</mtd> <mtd><mn>1</mn>
<mo>/</mo><mo lspace="0em" rspace="thinmathspace">sin</mo><mo>(</mo><mi>x</mi><mo>)</mo></mtd></mtr> <mtr><mtd><mo lspace="0em" rspace="thinmathspace">cot</mo>
<mo>(</mo><mi>x</mi><mo>)</mo></mtd> <mtd><mo>&rightarrow;</mo>
</mtd> <mtd><mn>1</mn>
<mo>/</mo><mo lspace="0em" rspace="thinmathspace">tan</mo><mo>(</mo><mi>x</mi><mo>)</mo></mtd></mtr> <mtr><mtd><mtext>arcsec</mtext>
<mo>(</mo><mi>x</mi><mo>)</mo></mtd> <mtd><mo>&rightarrow;</mo>
</mtd> <mtd><mo lspace="0em" rspace="thinmathspace">arccos</mo>
<mo>(</mo><mn>1</mn><mo>/</mo><mi>x</mi><mo>)</mo></mtd></mtr> <mtr><mtd><mtext>arccsc</mtext>
<mo>(</mo><mi>x</mi><mo>)</mo></mtd> <mtd><mo>&rightarrow;</mo>
</mtd> <mtd><mo lspace="0em" rspace="thinmathspace">arcsin</mo>
<mo>(</mo><mn>1</mn><mo>/</mo><mi>x</mi><mo>)</mo></mtd></mtr> <mtr><mtd><mtext>arccot</mtext>
<mo>(</mo><mi>x</mi><mo>)</mo></mtd> <mtd><mo>&rightarrow;</mo>
</mtd> <mtd><mo lspace="0em" rspace="thinmathspace">arctan</mo>
<mo>(</mo><mn>1</mn><mo>/</mo><mi>x</mi><mo>)</mo></mtd></mtr></mtable></mrow>

</math></div>


Nach der Vorverarbeitung muss sichergestellt sein, dass die Funktion keine unerwarteten Teilausdrücke
mehr enthält. Nur mit einem klar begrenzten Funktionsumfang kann der Algorithmus zuverlässig arbeiten.<br />
Als Folge sind ab hier auch automatische Vereinfachungssysteme der Computeralgebraprogramme mit
äußerster Vorsicht zu benutzen, da so schnell wieder Funktionen auftauchen, die nicht innerhalb des
Modells liegen.<br /><br />

Ein weiterer Fall, den man besser vorab behandelt, sind konstante Funktionen, die nicht von <i>x</i>
abhängen. Der Algorithmus scheitert an Funktionen ohne jedes Wachstum daran, das Wachstum
auf Mindestniveau anzuheben. Da hier aber nichts zu berechnen ist, sollte man die weitere Verarbeitung
frühzeitig abbrechen.<br /><br />
Schlimmer noch sind Funktionen, die in einer ganzen Umgebung um Unendlich identisch Null sind, wie zum Beispiel
<math xmlns='http://www.w3.org/1998/Math/MathML'>
<mn>1</mn>
<mo>-</mo><mo>(</mo><mi>x</mi><mo>-</mo><mi>C</mi><mo>)</mo><mo>/</mo><msqrt><mrow><mo>(</mo>
<mi>x</mi><mo>-</mo><mi>C</mi><msup><mo>)</mo> <mn>2</mn></msup></mrow></msqrt>
</math>, die identisch Null ist für <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>x</mi>
<mi>&gt;</mi><mi>C</mi>
</math>. Solche Funktionen
sind praktisch nicht sicher erkennbar, sprengen aber das Funktionsmodell des Algorithmus und führen
so zu Programmfehlern und Abbrüchen.


<a name="RekursionUndTerminierung" /><h3>4.4 Rekursion und Terminierung</h3>
Immer wieder kommt es im Laufe des Algorithmus zu rekursiven Aufrufen der Grenzwertberechnung. So kann
eine einzige Grenzwertaufgabe durchaus eine Kaskade von mehreren Hundert weiteren Grenzwertberechnungen
auslösen. Wird dabei bei der Berechnung von <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msub><mo lspace="thinmathspace" rspace="thinmathspace">lim</mo> <mrow><mi>x</mi>
<mo>&rightarrow;</mo><mn>&infin;</mn></mrow></msub>
<mi>f</mi><mo>(</mo><mi>x</mi><mo>)</mo>
</math> irgendwann ein
rekursiver Aufruf nötig, der wieder <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>f</mi>
<mo>(</mo><mi>x</mi><mo>)</mo>
</math> oder gewisse Variationen davon enthält,
ist eine unendliche Schleife nicht mehr zu verhindern.<br /><br />

Um sicher zu gehen, dass solche Schleifen nicht auftreten, sollte bei jedem rekursiven Aufruf eine Art
'Fortschritt' bei der Bewältigung der Aufgabe erkennbar sein. In unserem Fall wird der
Fortschritt messbar, indem wir in zwei Schritten die Komplexität einer Funktion berechenbar machen:<br /><br />



<pre>    function ComplexitySet(t : Term)
        if (x not in t)
            return {}
        if (t = x)
            return { x }
        if (t = _f_ + _g_)
            return ComplexitySet(f) ⋃ ComplexitySet(g)
        if (t = _f_ * _g_)
            return ComplexitySet(f) ⋃ ComplexitySet(g)
        if (t = _g_  _c_ and x not in c)
            return ComplexitySet(g)
        if (t = Log(_g_))
            return { Log(g) } ⋃ ComplexitySet(g)
        if (t = e  _g_)
            return { eg } ⋃ ComplexitySet(g)
        if (t = PolyGamma(_n_,_g_))
            return ComplexitySet(g)
        
        if (t = _f_(_g_))
            if (f in { Sin, Cos, Tan, ArcSin, ArcCos,
                       ArcTan, Gamma, LogGamma } )
                return ComplexitySet(g)

    end function

    function Complexity(t : Term)
        return SizeOf(ComplexitySet(t))
    end function</pre>

_t_ dient dabei als Platzhalter für beliebige Teilausdrücke, die in Folge
dann als t referenziert werden. Complexity(t) wird auch kurz als <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>C</mi>
<mo>(</mo><mi>t</mi><mo>)</mo>
</math>
bezeichnet.<br /><br />

Wie man leicht sieht, gilt <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>C</mi>
<mo>(</mo><msup><mi>e</mi> <mi>f</mi></msup><mo>)</mo><mo>=</mo><mi>C</mi><mo>(</mo><mo lspace="0em" rspace="thinmathspace">log</mo><mi>f</mi><mo>)</mo><mo>=</mo><mi>C</mi><mo>(</mo><mi>f</mi><mo>)</mo><mo>+</mo><mn>1</mn>
</math>, wohingegen
für die Grundrechenarten nur gilt:
<math xmlns='http://www.w3.org/1998/Math/MathML'>
<mtext>max</mtext>
<mo>(</mo><mi>C</mi><mo>(</mo><mi>f</mi><mo>)</mo><mo>,</mo><mi>C</mi><mo>(</mo><mi>g</mi><mo>)</mo><mo>)</mo><mo>&le;</mo><mi>C</mi><mo>(</mo><mi>f</mi><mo>+</mo><mi>g</mi><mo>)</mo><mo>=</mo><mi>C</mi><mo>(</mo><mi>f</mi><mo>&sdot;</mo><mi>g</mi><mo>)</mo><mo>&le;</mo><mi>C</mi><mo>(</mo><mi>f</mi><mo>)</mo><mo>+</mo><mi>C</mi><mo>(</mo><mi>g</mi><mo>)</mo>
</math>.<br /><br />

Um unendliche Rekursionen sicher auszuschließen, wird die Forderung aufgestellt, dass bei jedem rekursiven
Aufruf die Komplexität der rekursiv gelösten Aufgabe niedriger ist, als die Komplexität der
ursprünglichen Funktion.<br /><br />

Leider ist auch das nicht haltbar, deshalb werden in <a href="Algorithmus.xml#NochEinmalTerminierung">Kapitel 4.11</a> noch zwei Fälle untersucht,
in denen eine rekursive Berechnung von gleicher Komplexität erforderlich sein kann. Die rekursiven
Aufrufe sind jedoch von ausrechend spezieller Natur, um sicher zu stellen, dass die Komplexität
in späteren rekursiven Aufrufen sinken wird.


<a name="StaerkstesWachstum" /><h3>4.5 Stärkstes Wachstum</h3>
Nun ist der Weg frei, die Funktion auf ihr grobes Wachstumsverhalten zu untersuchen. Wir gehen dabei
analog zu <a href="Grundlagen.xml#Termanalyse">Kapitel 3.4</a> vor.<br /><br />



Bei MrvSet, der Menge aller Teilausdrücke der stärksten Wachstumsklasse,
weichen wir jedoch von der mathematischen Sichtweise in einigen Details ab:

<ul>
<li>Während formal das MrvSet einer konstanten Funktion aus allen
Teilausdrücken besteht, liefert die Implementierung die leere Menge zurück. Da konstante Teilausdrücke keiner
besonderen Aufmerksamkeit bedürfen, ist das eine sinnvolle Vereinfachung.</li>
<li>Wenn das Wachstum eines Ausdrucks ausschließlich durch seine Teilausdrücke bestimmt wird,
wie z.B. bei <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>f</mi>
<mo>+</mo><mi>g</mi>
</math> oder <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>f</mi>
<mo>&sdot;</mo><mi>g</mi>
</math>, genügt es, das Wachstum der Teilausdrücke zu behandeln
und den Gesamtausdruck unverändert zu belassen. Werden später die am stärksten wachsenden Teilausdrücke
ersetzt, ist damit auch der Gesamtausdruck ausreichend behandelt.</li>
</ul>
Sehen wir uns die Funktion MrvSet im Detail an:
<pre>    function MrvSet(t : Term)
        if (x not in t)
            return {}
        if (t = x)
            return { x }
        if (t = _f_ + _g_)
            return MrvMax(MrvSet(f),MrvSet(g))
        if (t = _f_ * _g_)
            return MrvMax(MrvSet(f),MrvSet(g))
        if (t = _g_  _c_ and x not in c)
            return MrvSet(g)
        if (t = Log(_g_))
            return MrvSet(g)
        if (t = e  _g_)
            if (|Limit(g,x→inf)| &lt; inf)
                return MrvSet(g)
            if (Limit(g,x→inf)=+/-inf)
                return MrvMax({ eg },MrvSet(g))
        if (t = PolyGamma(_n_,_g_))
            return MrvSet(g)
        
        if (t = _f_(_g_))
            if (f in { Sin, Cos, Tan, ArcSin, ArcCos,
                       ArcTan, Gamma, LogGamma } )
                return MrvSet(g)

    end function</pre>
_t_ dient dabei wieder als Platzhalter für beliebige Teilausdrücke, die in Folge dann als t referenziert
werden. Die Maximum-Mengenvereinigung MrvMax ist bereits in <a href="Grundlagen.xml#Termanalyse">Kapitel 3.4</a> beschrieben und wird gleich
noch im Detail dargelegt.<br /><br />

Im Falle der Exponentialfunktion wird erstmals ein rekursiver Aufruf des Grenzwertalgorithmus
erforderlich. Da aber der rekursive Aufruf nur mit dem Exponent erfolgt, die
Komplexität also um eins sinkt, ist eine unendliche Rekursion hier nicht zu befürchten.<br /><br />

Die trigonometrischen und anderen Funktionen am Ende benötigen keine besondere Aufmerksamkeit mehr, da
der Grenzübergang nur an unkritischen Stellen der Funktion erfolgt. Kritische Stellen wurden bereits
von der Vorverarbeitung aufgelöst oder abgewiesen.<br /><br />

Für den MrvLimit-Algorithmus ist es von entscheidender Bedeutung zu erkennen, welcher Art die von
MrvSet zurückgelieferten Mengen sind:
<ul>
<li>MrvSet liefert eine Menge von Termen zurück, die alle in der gleichen Wachstumsklasse liegen.</li>
<li>MrvSet(t) liefert nur Teilausdrücke von t zurück.</li>
<li>Die Menge ist leer, oder enthält nur Elemente der Form <i>x</i> oder <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msup><mi>e</mi> <mrow><mi>f</mi>
<mo>(</mo><mi>x</mi><mo>)</mo></mrow></msup>

</math>.</li>
<li>Enthält die Menge Terme der Wachstumsklasse <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>&gamma;</mi>
<mo>(</mo><mi>x</mi><mo>)</mo>
</math>, so enthält sie auch <i>x</i> selbst.</li>
<li>Alle Elemente haben den Grenzwert 0 oder ∞ für <math xmlns="http://www.w3.org/1998/Math/MathML" mode="inline"><mrow><mi>x</mi><mo>→</mo><mi>∞</mi></mrow></math>.</li>
<li>Kein Element ist konstant.</li>
<li>Für <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>x</mi>
<mi>&gt;</mi><mn>0</mn>
</math> sind alle Elemente größer als 0.</li>
</ul>
Auf diese Eigenschaften wird später im Algorithmus aufgebaut.<br /><br />
Es lohnt noch anzumerken, dass die Wachstumsklasse <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>&gamma;</mi>
<mo>(</mo><mi>x</mi><mo>)</mo>
</math> in der Regel, aber nicht immer, als
<math xmlns='http://www.w3.org/1998/Math/MathML'>
<mo>{</mo>
<mi>x</mi><mo>}</mo>
</math> zurückgegeben wird. Andernfalls muss ein Term die Form <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msup><mi>e</mi> <mrow><mi>f</mi>
<mo>(</mo><mi>x</mi><mo>)</mo></mrow></msup>

</math> haben und
dieses <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>f</mi>
<mo>(</mo><mi>x</mi><mo>)</mo>
</math> muss logarithmisch oder langsamer wachsen. Die meisten solchen Terme fallen 
vorher bereits Mathematicas automatischer Vereinfachung zum Opfer.<br /><br />

Es bleibt der Funktionsaufruf von MrvMax zu erklären. 
Da die beiden übergebenen Mengen jeweils nur Elemente einer Wachstumsklasse enthalten, genügt es, je einen
Stellvertreter jeder Menge auszusuchen und deren Wachstum zu vergleichen:
<pre>
    function MrvMax(s1,s2 : Set of Term)
        if (s1 = {})
            return s2
        if (s2 = {})
            return s1
        if (s1[1] = s2[1])
            return Union(s1,s2)

        t1 = Log(s1[1])
        t2 = Log(s2[1])
        if (t1 = Log(e_f_)
            t1 = f
        if (t2 = Log(e_f_)
            t2 = f
</pre><pre>
        if (Limit(t1/t2,x→inf) = inf)
            return s2
        if (Limit(t1/t2,x→inf) = 0)
            return s1

        return Union(s1,s2)
    end function
</pre>

Der Fall der leeren Mengen (d.h. konstanten Terme) wird vorab erledigt. Danach werden die Stellvertreter
beider Mengen anhand von <a href="Grundlagen.xml#th37">Theorem 3.7</a> verglichen. Sind die Stellvertreter vom Typ <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msup><mi>e</mi> <mrow><mi>f</mi>
<mo>(</mo><mi>x</mi><mo>)</mo></mrow></msup>

</math>,
kann <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mo lspace="0em" rspace="thinmathspace">log</mo>
<mo>(</mo><msup><mi>e</mi> <mrow><mi>f</mi>
<mo>(</mo><mi>x</mi><mo>)</mo></mrow></msup><mo>)</mo>
</math> sofort zu <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>f</mi>
<mo>(</mo><mi>x</mi><mo>)</mo>
</math> vereinfacht werden.<br /><br />

Da wieder rekursive Aufrufe der Limit-Funktion auftreten, muss wieder mit Vorsicht vorgegangen werden.
Dazu muss beobachtet werden, in welchen Situationen MrvMax aus MrvSet heraus aufgerufen wird.<br /><br />

Stößt MrvSet auf einen Term der Form <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msup><mi>e</mi> <mrow><mi>g</mi>
<mo>(</mo><mi>x</mi><mo>)</mo></mrow></msup>

</math>, kann es zu einem Aufruf
<math xmlns='http://www.w3.org/1998/Math/MathML'>
<mtext>MrvMax</mtext>
<mo>(</mo><msup><mi>e</mi> <mrow><mi>g</mi>
<mo>(</mo><mi>x</mi><mo>)</mo></mrow></msup><mo>,</mo>
</math> <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mtext>MrvSet</mtext>
<mo>(</mo><mi>g</mi><mo>(</mo><mi>x</mi><mo>)</mo><mo>)</mo><mo>)</mo>
</math> kommen. Das erste Argument kann dabei schlimmstenfalls
die Funktion selbst sein, hat also maximal die Komplexität <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>C</mi>
<mo>(</mo><msup><mi>e</mi> <mrow><mi>g</mi>
<mo>(</mo><mi>x</mi><mo>)</mo></mrow></msup><mo>)</mo>
</math>. Durch die Vereinfachung
sinkt die Komplexität aber auf <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>C</mi>
<mo>(</mo><mi>g</mi><mo>(</mo><mi>x</mi><mo>)</mo><mo>)</mo><mo>=</mo><mi>C</mi><mo>(</mo><msup><mi>e</mi> <mrow><mi>g</mi>
<mo>(</mo><mi>x</mi><mo>)</mo></mrow></msup><mo>)</mo><mo>-</mo><mn>1</mn>
</math>.<br /><br />

Das zweite Argument hat maximal die Komplexität <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>C</mi>
<mo>(</mo><mi>g</mi><mo>(</mo><mi>x</mi><mo>)</mo><mo>)</mo>
</math>, ist aber in jedem Fall ein
Teilausdruck von <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>g</mi>
<mo>(</mo><mi>x</mi><mo>)</mo>
</math>. Die Komplexität des rekursiven Aufrufs ist daher begrenzt
mit <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>C</mi>
<mo>(</mo><msub><mi>t</mi> <mn>1</mn></msub><mo>/</mo><msub><mi>t</mi> <mn>2</mn></msub><mo>)</mo><mo>&le;</mo><mi>C</mi><mo>(</mo><msup><mi>e</mi> <mrow><mi>g</mi>
<mo>(</mo><mi>x</mi><mo>)</mo></mrow></msup><mo>)</mo><mo>-</mo><mn>1</mn>
</math>.<br /><br />

Es bleiben die Aufrufe von MrvMax bei <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>f</mi>
<mo>(</mo><mi>x</mi><mo>)</mo><mo>+</mo><mi>g</mi><mo>(</mo><mi>x</mi><mo>)</mo>
</math> und <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>f</mi>
<mo>(</mo><mi>x</mi><mo>)</mo><mo>&sdot;</mo><mi>g</mi><mo>(</mo><mi>x</mi><mo>)</mo>
</math>.
Schlimmstenfalls ist dabei die ursprüngliche Funktion direkt <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>t</mi>
<mo>=</mo><mi>f</mi><mo>(</mo><mi>x</mi><mo>)</mo><mo>&sdot;</mo><mi>g</mi><mo>(</mo><mi>x</mi><mo>)</mo>
</math>, und der
Wachstumsvergleich findet tatsächlich für die Funktionen <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>f</mi>
<mo>(</mo><mi>x</mi><mo>)</mo>
</math> und
<math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>g</mi>
<mo>(</mo><mi>x</mi><mo>)</mo>
</math> statt. Entsprechendes gilt für <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>f</mi>
<mo>(</mo><mi>x</mi><mo>)</mo><mo>+</mo><mi>g</mi><mo>(</mo><mi>x</mi><mo>)</mo>
</math>.<br /><br />

Der Fall <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>f</mi>
<mo>(</mo><mi>x</mi><mo>)</mo><mo>=</mo><mi>g</mi><mo>(</mo><mi>x</mi><mo>)</mo><mo>=</mo><mi>x</mi>
</math> wird vorab behandelt und führt nicht zu einer Rekursion.
Ist o.B.d.A. <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>g</mi>
<mo>(</mo><mi>x</mi><mo>)</mo><mo>=</mo><mi>x</mi>
</math> und <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>f</mi>
<mo>(</mo><mi>x</mi><mo>)</mo><mo>&ne;</mo><mi>x</mi>
</math>, so bleibt für <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>f</mi>
<mo>(</mo><mi>x</mi><mo>)</mo>
</math>
nur die Form <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>f</mi>
<mo>(</mo><mi>x</mi><mo>)</mo><mo>=</mo><msup><mi>e</mi> <mrow><msub><mi>f</mi> <mn>1</mn></msub>
<mo>(</mo><mi>x</mi><mo>)</mo></mrow></msup>
</math>, und es kommt zum rekursiven Aufruf
<math xmlns='http://www.w3.org/1998/Math/MathML'>
<msub><mo lspace="thinmathspace" rspace="thinmathspace">lim</mo> <mrow><mi>x</mi>
<mo>&rightarrow;</mo><mn>&infin;</mn></mrow></msub>
<mrow><msub><mi>f</mi> <mn>1</mn></msub>
<mo>(</mo><mi>x</mi><mo>)</mo></mrow><mo>/</mo><mrow><mo lspace="0em" rspace="thinmathspace">log</mo>
<mi>x</mi></mrow>
</math>. Die Komplexität dieses Ausdrucks
ist möglicherweise gleich der von <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>f</mi>
<mo>(</mo><mi>x</mi><mo>)</mo><mo>&sdot;</mo><mi>g</mi><mo>(</mo><mi>x</mi><mo>)</mo><mo>=</mo><msup><mi>e</mi> <mrow><msub><mi>f</mi> <mn>1</mn></msub>
<mo>(</mo><mi>x</mi><mo>)</mo></mrow></msup><mo>&sdot;</mo><mi>x</mi>
</math>. Den Beweis, dass der
Grenzwertaufruf <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msub><mo lspace="thinmathspace" rspace="thinmathspace">lim</mo> <mrow><mi>x</mi>
<mo>&rightarrow;</mo><mn>&infin;</mn></mrow></msub>
<mrow><msub><mi>f</mi> <mn>1</mn></msub>
<mo>(</mo><mi>x</mi><mo>)</mo></mrow><mo>/</mo><mrow><mo lspace="0em" rspace="thinmathspace">log</mo>
<mi>x</mi></mrow>
</math> nicht zu einer unendlichen
Rekursion führt, wird auf das <a href="Algorithmus.xml#NochEinmalTerminierung">Kapitel 4.11</a> aufgeschoben.<br /><br />

Ist schließlich <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>f</mi>
<mo>(</mo><mi>x</mi><mo>)</mo><mo>=</mo><msup><mi>e</mi> <mrow><msub><mi>f</mi> <mn>1</mn></msub>
<mo>(</mo><mi>x</mi><mo>)</mo></mrow></msup>
</math> und <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>g</mi>
<mo>(</mo><mi>x</mi><mo>)</mo><mo>=</mo><msup><mi>e</mi> <mrow><msub><mi>g</mi> <mn>1</mn></msub>
<mo>(</mo><mi>x</mi><mo>)</mo></mrow></msup>
</math>, so erfolgt der
rekursive Aufruf <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msub><mo lspace="thinmathspace" rspace="thinmathspace">lim</mo> <mrow><mi>x</mi>
<mo>&rightarrow;</mo><mn>&infin;</mn></mrow></msub>
<mfrac><mrow><msub><mi>f</mi> <mn>1</mn></msub>
<mo>(</mo><mi>x</mi><mo>)</mo></mrow><mrow><msub><mi>g</mi> <mn>1</mn></msub>
<mo>(</mo><mi>x</mi><mo>)</mo></mrow></mfrac>
</math> mit einer garantiert
niedrigeren Komplexität als <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>f</mi>
<mo>(</mo><mi>x</mi><mo>)</mo><mo>&sdot;</mo><mi>g</mi><mo>(</mo><mi>x</mi><mo>)</mo>
</math>, die Komplexität sinkt also.<br /><br />


<a name="AnhebungDerWachstumsklasse" /><h3>4.6 Anhebung der Wachstumsklasse</h3>
Nachdem wir nun das schlimmst mögliche Wachstumsverhalten der Funktion ermittelt haben, wird es Zeit,
sich eines unangenehmen Sonderfalls zu entledigen: Wachstum der Klasse <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>&gamma;</mi>
<mo>(</mo><mi>x</mi><mo>)</mo>
</math>,
d.h. Funktionen, die polynomiell oder langsamer wachsen.<br /><br />

Wie schon im <a href="Ueberblick.xml#BedingungenAnDasWachstum">Kapitel 2.3</a> angeschnitten,
wird solange <i>x</i> durch <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msup><mi>e</mi> <mi>x</mi></msup>

</math> ersetzt, bis das Wachstum der Funktion
nicht mehr in die Klasse <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>&gamma;</mi>
<mo>(</mo><mi>x</mi><mo>)</mo>
</math> fällt. Danach enthält die Funktion garantiert
Teilausdrücke von exponentiellem Wachstum, die klar von Teilausdrücken niedriger Ordnung getrennt
werden können. Als Nebeneffekt werden durch das Anheben Terme mit logarithmischem Wachstum so weit
angehoben, dass sie entweder exponentiell sind oder vorerst von anderen exponentiellen Termen
überschattet werden.<br /><br />

Das Anheben der Wachstumsklasse ist allerdings nicht ohne Folgen. Die Komplexität der Funktion nimmt
durch das Ersetzen von <i>x</i> durch <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msup><mi>e</mi> <mi>x</mi></msup>

</math> zu, deswegen muss sehr vorsichtig auf
eventuelle unendliche Rekursionen geachtet werden! Das MrvSet der angehobenen Funktion erneut zu
berechnen, kann bereits zu einer Schleife führen. Zum Glück ist das jedoch nicht immer erforderlich.
Die Komplexität wird auch in Grenzen gehalten, wenn konsequent jedes Vorkommen
von <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mo lspace="0em" rspace="thinmathspace">log</mo>
<mo>(</mo><mi>x</mi><mo>)</mo>
</math> nicht durch <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mo lspace="0em" rspace="thinmathspace">log</mo>
<mo>(</mo><msup><mi>e</mi> <mi>x</mi></msup><mo>)</mo>
</math>, sondern gleich durch <i>x</i>
ersetzt wird:<br /><br />

<pre>    Ω = MrvSet(f)
    ScaleUp = 0
    while (x in Ω)
        ScaleUp = ScaleUp + 1
        f = Replace(f, Log(x) → x, x → ex)
        Ω = Replace(Ω, Log(x) → x, x → ex)

        for each ω in Ω
            if (ω not in f)
                Ω=Delete(Ω,ω)
        end for

        if (Ω = {})
            Ω = MrvSet(f)
    end while</pre>

Es genügt, auf das Vorkommen von <i>x</i> in Ω zu achten, da das MrvSet der
Klasse <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>&gamma;</mi>
<mo>(</mo><mi>x</mi><mo>)</mo>
</math> immer auch <i>x</i> enthält. ScaleUp zählt mit, wie häufig die Funktion
in eine höhere Klasse angehoben wurde, damit die Ergebnisse später wieder in die ursprüngliche
Klasse abgesenkt werden können. Ist man nur am
schlichten numerischen Ergebnis interessiert und nicht an Asymptoten, kann das 
auch eingespart werden.<br /><br />

Als nächstes werden in f und Ω synchron alle <i>x</i> und <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mo lspace="0em" rspace="thinmathspace">log</mo>
<mo>(</mo><mi>x</mi><mo>)</mo>
</math> Terme durch ihre
angehobenen Varianten ersetzt. Ω ist damit fast schon wieder identisch zum neuen MrvSet(f). Der
einzige Fall, in dem die Ersetzung in f und in Ω unterschiedlich erfolgt, ist ein Auftreten von
<math xmlns='http://www.w3.org/1998/Math/MathML'>
<mo lspace="0em" rspace="thinmathspace">log</mo>
<mo>(</mo><mi>x</mi><mo>)</mo>
</math> in f.<br />
Tritt in f ein Term <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mo lspace="0em" rspace="thinmathspace">log</mo>
<mo>(</mo><mi>x</mi><mo>)</mo>
</math> auf, so ist dessen Repräsentant in Ω der Term <i>x</i>.
Daher wird in Ω die Ersetzung <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>x</mi>
<mo>&rightarrow;</mo><msup><mi>e</mi> <mi>x</mi></msup>
</math> angewendet, und in f wird
<math xmlns='http://www.w3.org/1998/Math/MathML'>
<mo lspace="0em" rspace="thinmathspace">log</mo>
<mo>(</mo><mi>x</mi><mo>)</mo><mo>&rightarrow;</mo><mi>x</mi>
</math> ersetzt. Dadurch enthält Ω ein <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msup><mi>e</mi> <mi>x</mi></msup>

</math>, das
möglicherweise nicht in f vorkommt.<br /><br />

Deswegen wird zunächst erst einmal jedes Element von Ω entfernt, das nicht mehr in f vorkommt.
Ist Ω jetzt nicht leer, so gibt es in f mindestens einen Teilausdruck mit exponentiellem
Wachstum. Alle Teilausdrücke von f mit exponentiellem Wachstum waren vorher mit polynomiellem
Wachstum in Ω vertreten und wurden in Ω und f identisch transformiert. Es gilt also
wieder Ω=MrvSet(f).<br /><br />


Ist Ω dagegen leer, so kann in f nur die Ersetzungsregel <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mo lspace="0em" rspace="thinmathspace">log</mo>
<mo>(</mo><mi>x</mi><mo>)</mo><mo>&rightarrow;</mo><mi>x</mi>
</math>
angewendet worden sein, und f enthält immer noch keinen Term mit exponentiellem Wachstum. Da die
bisherige Wachstumsklasse vollständig eliminiert wurde, muss die nächst niedrigere, bisher
logarithmische Wachstumsklasse erneut ermittelt werden.<br /><br />

Insgesamt ist also nun folgendes passiert:
<ul>
<li>Ist das stärkste Wachstum stärker als polynomiell, so ist die Funktion unverändert geblieben.</li>
<li>Ist das stärkste Wachstum polynomiell gewesen, so wurde genau ein mal die Ersetzung
<math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>x</mi>
<mo>&rightarrow;</mo><msup><mi>e</mi> <mi>x</mi></msup>
</math> durchgeführt. Die Komplexität ist entsprechend maximal um 1 gestiegen.</li>
<li>Ist das stärkste Wachstum logarithmisch gewesen, wurde ein- oder mehrmals
<math xmlns='http://www.w3.org/1998/Math/MathML'>
<mo lspace="0em" rspace="thinmathspace">log</mo>
<mo>(</mo><mi>x</mi><mo>)</mo><mo>&rightarrow;</mo><mi>x</mi>
</math> ersetzt und abschließend
ein mal <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>x</mi>
<mo>&rightarrow;</mo><msup><mi>e</mi> <mi>x</mi></msup>
</math>. Die Komplexität sank dadurch zunächst, stieg aber im letzten
Schritt maximal wieder um 1 an.</li>
</ul>
Der rekursive Aufruf von MrvSet ist zum Glück unkritisch, da die Ersetzungsregel
<math xmlns='http://www.w3.org/1998/Math/MathML'>
<mo lspace="0em" rspace="thinmathspace">log</mo>
<mo>(</mo><mi>x</mi><mo>)</mo><mo>&rightarrow;</mo><mi>x</mi>
</math> die Komplexität von f vorher gesenkt hat.
Bei den noch folgenden rekursiven Aufrufen muss jedoch mit um so mehr Sorgfalt vorgegangen werden,
da mit der schlimmstenfalls um 1 gestiegenen Komplexität kalkuliert werden muss.


<a name="WahlDesRepraesentanten" /><h3>4.7 Wahl des Repräsentanten</h3>
Als nächstes wird ein Repräsentant ω der Menge Ω gewählt, der als Substitutionsvariable
ω und Repräsentant des stärksten Wachstums dienen soll. Dabei gibt es ein später entscheidendes
Kriterium zu berücksichtigen: Kein anderes Mitglied von Ω darf als Teilausdruck innerhalb von
ω auftreten. Wenn also zum Beispiel <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>&Omega;</mi>
<mo>=</mo><mo>{</mo><msup><mi>e</mi> <mrow><mo lspace="thinthinmathspace" rspace="0em">-</mo>
<mi>x</mi></mrow></msup><mo>,</mo><msup><mi>e</mi> <mrow><mi>x</mi>
<mo>+</mo><msup><mi>e</mi> <mrow><mo lspace="thinthinmathspace" rspace="0em">-</mo>
<mi>x</mi></mrow></msup></mrow></msup><mo>}</mo>
</math> ist, so ist
<math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>&omega;</mi>
<mo>=</mo><msup><mi>e</mi> <mrow><mi>x</mi>
<mo>+</mo><msup><mi>e</mi> <mrow><mo lspace="thinthinmathspace" rspace="0em">-</mo>
<mi>x</mi></mrow></msup></mrow></msup>
</math> eine schlechte Wahl, da darin <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msup><mi>e</mi> <mrow><mo lspace="thinthinmathspace" rspace="0em">-</mo>
<mi>x</mi></mrow></msup>

</math> auftritt.
Das Problem kann umgangen werden, wenn man als ω das Element von Ω mit der geringsten
Komplexität auswählt.<br /><br />

Der Vertreter ω muss zusätzlich die Eigenschaft <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msub><mo lspace="thinmathspace" rspace="thinmathspace">lim</mo> <mrow><mi>x</mi>
<mo>&rightarrow;</mo><mn>&infin;</mn></mrow></msub>
<mi>&omega;</mi><mo>=</mo><mn>0</mn>
</math>
erfüllen, damit später die Potenzreihenentwicklung in ω=0 durchgeführt werden kann. Da aber die
Mitglieder von Ω bereits alle in der Form <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msup><mi>e</mi> <mrow><mi>g</mi>
<mo>(</mo><mi>x</mi><mo>)</mo></mrow></msup>

</math> vorliegen und als Grenzwert
nur noch 0 oder ∞ möglich ist (s. <a href="Algorithmus.xml#StaerkstesWachstum">Kapitel 4.5</a>), ist die Forderung 
<math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>&omega;</mi>
<mo>&rightarrow;</mo><mn>0</mn>
</math>
leicht zu erfüllen: Wenn <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msub><mo lspace="thinmathspace" rspace="thinmathspace">lim</mo> <mrow><mi>x</mi>
<mo>&rightarrow;</mo><mn>&infin;</mn></mrow></msub>
<mi>g</mi><mo>(</mo><mi>x</mi><mo>)</mo><mo>=</mo><mn>&infin;</mn>
</math>, dann verwende
<math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>&omega;</mi>
<mo>=</mo><msup><mi>e</mi> <mrow><mo lspace="thinthinmathspace" rspace="0em">-</mo>
<mi>g</mi><mo>(</mo><mi>x</mi><mo>)</mo></mrow></msup>
</math>. Diese Vorzeichenänderung hat keine Auswirkungen auf die Stabilität
des Algorithmus oder die Komplexität der Funktion.<br /><br />

Interessanter ist da schon die Frage, woher man weiß, ob <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msub><mo lspace="thinmathspace" rspace="thinmathspace">lim</mo> <mrow><mi>x</mi>
<mo>&rightarrow;</mo><mn>&infin;</mn></mrow></msub>
<mi>g</mi><mo>(</mo><mi>x</mi><mo>)</mo><mo>=</mo><mn>&infin;</mn>
</math>
gilt. Dafür einen rekursiven Aufruf des Grenzwertalgorithmus starten könnte zu unendlichen
Rekursionen führen.<br /><br />

Zum Glück ist das aber nicht notwendig, denn es kommen nur zwei
'Verursacher' als Quelle für ω in Frage:

<ul>
<li>Der Aufruf von <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mtext>MrvSet</mtext>
<mo>(</mo><mi>x</mi><mo>,</mo><mi>x</mi><mo>)</mo>
</math>, der mittlerweile zu <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msup><mi>e</mi> <mi>x</mi></msup>

</math> 
angehoben wurde.</li>

<li>Der Aufruf von <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mtext>MrvSet</mtext>
<mo>(</mo><msup><mi>e</mi> <mrow><mi>h</mi>
<mo>(</mo><mi>x</mi><mo>)</mo></mrow></msup><mo>,</mo><mi>x</mi><mo>)</mo>
</math> mit einer Funktion
<math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>h</mi>
<mo>(</mo><mi>x</mi><mo>)</mo><mo>&rightarrow;</mo><mo>&pm;</mo><mn>&infin;</mn>
</math>.</li>
</ul>

Im ersten Fall ist das Wachstumsverhalten offensichtlich, im zweiten Fall kann es anhand
des damals sowieso berechneten Grenzwerts von <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>h</mi>
<mo>(</mo><mi>x</mi><mo>)</mo>
</math> ermittelt werden. Es bietet sich
daher an, entweder den Grenzwert von <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>g</mi>
<mo>(</mo><mi>x</mi><mo>)</mo>
</math> durch exaktes Zurückverfolgen zum Ausgangspunkt
zu bestimmen, oder, besser noch, das Wachstumsverhalten von vornherein bei der Bestimmung von Ω
mit zu bestimmen und aufzubewahren.


<a name="UmschreibenDerFunktion" /><h3>4.8 Umschreiben der Funktion</h3>
Nun wird die Funktion so umgeschrieben, dass alle Teilausdrücke des stärksten Wachstums durch ω
repräsentiert werden. Den dafür nötigen Ansatz liefert <a href="Grundlagen.xml#Ersetzung">Kapitel 3.5</a>: Ersetze jedes Vorkommen von
<math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>g</mi>
<mo>&Element;</mo><mi>&Omega;</mi>
</math> in <i>f</i> durch <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>A</mi>
<mo>&sdot;</mo><msup><mi>&omega;</mi> <mi>c</mi></msup>
</math>. Nimmt man
<math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>g</mi>
<mo>=</mo><msup><mi>e</mi> <mi>s</mi></msup>
</math> und <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>&omega;</mi>
<mo>=</mo><msup><mi>e</mi> <mi>t</mi></msup>
</math> an, so ergibt sich die Konstante
<math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>c</mi>
<mo>=</mo><msub><mo lspace="thinmathspace" rspace="thinmathspace">lim</mo> <mrow><mi>x</mi>
<mo>&rightarrow;</mo><mn>&infin;</mn></mrow></msub><mi>s</mi><mo>/</mo><mi>t</mi>
</math> und <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>A</mi>
<mo>=</mo><msup><mi>e</mi> <mrow><mi>s</mi>
<mo>-</mo><mi>ct</mi></mrow></msup>
</math>. Bei der Ersetzung sollte
ω gleich als symbolische Konstante eingesetzt werden und nicht wieder durch den Term ersetzt
werden, den ω repräsentiert.<br /><br />

Nach der Ersetzung muss sichergestellt sein, dass <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mtext>MrvSet</mtext>
<mo>(</mo><mi>f</mi><mo>)</mo><mo>=</mo><mo>{</mo><mi>&omega;</mi><mo>}</mo>
</math> gilt. Um das zu
garantieren, müssen alle Vorkommen von Ω in f ersetzt werden, und durch die Ersetzung
dürfen keine neuen Terme eingeführt werden, die in die gleiche Wachstumsklasse fallen.<br /><br />

Alle Vorkommen von
Elementen von Ω werden direkt ersetzt, als Quelle für neue Vorkommen kommt daher nur der
Ausdruck <i>A</i> in Frage. <i>A</i> selbst hat nachweislich eine niedrigere Wachstumsklasse, es
bleiben aber noch Teilausdrücke von A zu berücksichtigen. Diese bestehen wiederum aus Teilausdrücken
von ω und von <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>g</mi>
<mo>&Element;</mo><mi>&Omega;</mi>
</math>. Es geht also darum, wann die Elemente von Ω
selbst wiederum Teilausdrücke enthalten, die ebenfalls in Ω sind.<br /><br />

Ordnet man die Elemente von Ω nach ihrer Komplexität, wird die Situation überschaubar: Elemente
von höherer Komplexität können nur Elemente niedrigerer Komplexität als Teilausdrücke enthalten.
Ersetzt man nun zuerst die Elemente hoher Komplexität, so werden in den nachfolgenden Ersetzungen
ebenfalls alle neu eingeführten kritischen Teilausdrücke niedrigerer Komplexität mit ersetzt.
Hat man ω als das Element mit niedrigster Komplexität gewählt, so kann auch der von ω
abstammende Teil in <i>A</i> keine neuen kritischen Teilausdrücke mehr einführen, was andernfalls
zu rekursiven Ersetzungsschleifen führen könnte.<br /><br />

Eine weitere Quelle von Problemen sind Term-Optimierungen. Vereinfacht man <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>A</mi>
<mo>=</mo><msup><mi>e</mi> <mrow><mi>s</mi>
<mo>-</mo><mi>ct</mi></mrow></msup>
</math>
unvorsichtigerweise zu <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>A</mi>
<mo>=</mo><msup><mi>e</mi> <mi>s</mi></msup><mo>&sdot;</mo><msup><mi>e</mi> <mrow><mo lspace="thinthinmathspace" rspace="0em">-</mo>
<mi>ct</mi></mrow></msup>
</math>, ist man fast wieder am Ausgangspunkt angekommen,
und der Algorithmus scheitert. Je nach Computeralgebrasystem muss man daher sicher stellen, dass
auf automatische Optimierungen weitgehend verzichtet wird.<br /><br />

Schließlich bleibt der rekursive Aufruf des Grenzwertalgorithmus. Die Gefahr einer unendlichen
Rekursion ist auch hier wieder gegeben. Im <a href="Algorithmus.xml#AlternativerAnsatz">Kapitel 4.12</a> wird ein Trick
aufgezeigt, mit dem der rekursive Aufruf komplett vermieden werden kann.<br /><br />

Da diese Arbeit nicht auf diesen Trick zurück greift, hier der Beweis, dass auch
der rekursive Aufruf terminiert: Berechnet wird der Grenzwert <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>c</mi>
<mo>=</mo><msub><mo lspace="thinmathspace" rspace="thinmathspace">lim</mo> <mrow><mi>x</mi>
<mo>&rightarrow;</mo><mn>&infin;</mn></mrow></msub><mi>s</mi><mo>/</mo><mi>t</mi>
</math>,
ausgehend von den Ausdrücken <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msup><mi>e</mi> <mi>s</mi></msup>

</math> und <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msup><mi>e</mi> <mi>t</mi></msup>

</math> bzw. <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msup><mi>e</mi> <mrow><mo lspace="thinthinmathspace" rspace="0em">-</mo>
<mi>t</mi></mrow></msup>

</math>
aus Ω und damit Teilausdrücken von f. Falls die Wachstumsklasse nicht angehoben wurde, treten
<math xmlns='http://www.w3.org/1998/Math/MathML'>
<msup><mi>e</mi> <mi>s</mi></msup>

</math> und <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msup><mi>e</mi> <mrow><mo>&pm;</mo>
<mi>t</mi></mrow></msup>

</math> direkt im ursprünglichen <i>f</i> auf, und
<math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>s</mi>
<mo>/</mo><mi>t</mi>
</math> hat eine um mindestens 1 niedrigere Komplexität.<br /><br />

Es bleibt der Fall, dass mindestens ein mal die Wachstumsklasse angehoben wurde. Solange dabei
nur <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mo lspace="0em" rspace="thinmathspace">log</mo>
<mi>x</mi><mo>&rightarrow;</mo><mi>x</mi>
</math> ersetzt wurde, kann die Komplexität höchstens gesunken
sein. Beim letzten Anheben wurde aber genau ein mal <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>x</mi>
<mo>&rightarrow;</mo><msup><mi>e</mi> <mi>x</mi></msup>
</math> ersetzt, wodurch
die Komplexität wieder um eins stieg.<br /><br />

Da nun auch garantiert <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msup><mi>e</mi> <mi>x</mi></msup>
<mo>&Element;</mo><mi>&Omega;</mi>
</math> ist, liegt <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>t</mi>
<mo>=</mo><mo lspace="thinthinmathspace" rspace="0em">-</mo><mi>x</mi>
</math> bereits fest,
und es gilt <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>C</mi>
<mo>(</mo><mi>s</mi><mo>)</mo><mo>=</mo><mi>C</mi><mo>(</mo><mi>s</mi><mo>/</mo><mi>t</mi><mo>)</mo>
</math>, was schlimmstenfalls gleich der Komplexität der ursprünglichen
Funktion <i>f</i> ist.<br /><br />

Außerdem muss <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msup><mi>e</mi> <mi>x</mi></msup>

</math> in <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msup><mi>e</mi> <mi>s</mi></msup>

</math> enthalten sein, d.h. entweder
ist <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>s</mi>
<mo>=</mo><mi>x</mi>
</math>, oder <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msup><mi>e</mi> <mi>x</mi></msup>

</math> ist in <i>s</i> enthalten. Im ersten Fall
ergibt sich (bei geeigneter Optimierung) <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mrow><mi>s</mi>
<mo>/</mo><mi>t</mi></mrow>
<mo>=</mo><mrow><mi>x</mi>
<mo>/</mo><mo>(</mo><mo lspace="thinthinmathspace" rspace="0em">-</mo><mi>x</mi><mo>)</mo></mrow><mo>=</mo><mrow><mo lspace="thinthinmathspace" rspace="0em">-</mo>
<mn>1</mn></mrow>
</math>, wodurch keine
rekursiven Probleme entstehen. Andernfalls bleibt ein Grenzwertaufruf
<math xmlns='http://www.w3.org/1998/Math/MathML'>
<msub><mo lspace="thinmathspace" rspace="thinmathspace">lim</mo> <mrow><mi>x</mi>
<mo>&rightarrow;</mo><mn>&infin;</mn></mrow></msub>
<mi>s</mi><mo>/</mo><mrow><mo lspace="thinthinmathspace" rspace="0em">-</mo>
<mi>x</mi></mrow>
</math>, wobei <i>s</i> den Teilausdruck <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msup><mi>e</mi> <mi>x</mi></msup>

</math>
enthält. Dass dieser Aufruf nicht zu einer unendlichen Rekursion führt, wird
im <a href="Algorithmus.xml#NochEinmalTerminierung">Kapitel 4.11</a> gezeigt.



<a name="Potenzreihe" /><h3>4.9 Potenzreihe</h3>
Die Hauptarbeit des Algorithmus ist damit geschafft. Die Funktion wurde in eine Darstellung überführt,
bei der die Teilausdrücke größter Wachstumsklasse nur in der Gestalt des Symbols ω auftreten,
und alle anderen auftretenden Terme einer niedrigeren Klasse angehören.<br /><br />

ω hat die nötige Eigenschaft <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>&omega;</mi>
<mo>&rightarrow;</mo><mn>0</mn>
</math> für <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>x</mi>
<mo>&rightarrow;</mo><mn>&infin;</mn>
</math>,
also können die Anfangsterme einer generalisierten Potenzreihe für <i>f</i> in <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>&omega;</mi>
<mo>=</mo><msup><mn>0</mn> <mo>+</mo></msup>
</math>
ermittelt werden. Das "Wie" würde den Rahmen dieser Diplomarbeit endgültig sprengen und sei daher anderen
überlassen. So viel sei gesagt, es gibt Algorithmen, die in unserem Fall die abgebrochene Potenzreihe
garantiert finden.<br /><br />

Der Algorithmus sollte eine abgebrochene Potenzreihendarstellung für <i>f</i> liefern, mit der Gestalt
<math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>f</mi>
<mo>=</mo><msub><mi>a</mi> <mn>0</mn></msub><mo>&sdot;</mo><msup><mi>&omega;</mi> <mrow><msub><mi>e</mi> <mn>0</mn></msub>
</mrow></msup><mo>+</mo><mi>O</mi><mo>[</mo><msup><mi>&omega;</mi> <mrow><msub><mi>e</mi> <mn>1</mn></msub>
</mrow></msup><mo>]</mo>
</math>, mit einem reellen Exponenten
<math xmlns='http://www.w3.org/1998/Math/MathML'>
<msub><mi>e</mi> <mn>0</mn></msub>
<mi>&lt;</mi><msub><mi>e</mi> <mn>1</mn></msub>
</math> und einem Faktor <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msub><mi>a</mi> <mn>0</mn></msub>
<mo>&ne;</mo><mn>0</mn>
</math>,
der konstant oder von niedrigerer Wachstumsklasse als ω ist und der eine niedrigere Komplexität
als die ursprüngliche Funktion <i>f</i> hat.<br /><br />

Ein Hinweis muss der Potenzreihenentwicklung noch auf den Weg gegeben werden. Falls im Laufe der
Potenzreihenentwicklung die Singularitäten <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mo lspace="0em" rspace="thinmathspace">log</mo>
<mi>&omega;</mi>
</math> oder
<math xmlns='http://www.w3.org/1998/Math/MathML'>
<mo lspace="0em" rspace="thinmathspace">log</mo>
<mn>1</mn><mo>/</mo><mi>&omega;</mi>
</math> auftreten, so können diese direkt vereinfacht werden: Sie gehören einer
niedrigeren Wachstumsklasse an und liefern keinen Beitrag zu dieser Potenzreihe.
Da ω immer die Form <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>&omega;</mi>
<mo>=</mo><msup><mi>e</mi> <mi>t</mi></msup>
</math> hat, ist es ein leichtes,
die Beziehungen <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mo lspace="0em" rspace="thinmathspace">log</mo>
<mi>&omega;</mi><mo>=</mo><mi>t</mi>
</math> und <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mo lspace="0em" rspace="thinmathspace">log</mo>
<mn>1</mn><mo>/</mo><mi>&omega;</mi><mo>=</mo><mrow><mo lspace="thinthinmathspace" rspace="0em">-</mo>
<mi>t</mi></mrow>
</math> aufzustellen
und die auftretenden Singularitäten aufzulösen.<br /><br />

Umgekehrt kann es je nach Algorithmus vorkommen, dass Terme der Form ω oder
<math xmlns='http://www.w3.org/1998/Math/MathML'>
<mn>1</mn>
<mo>/</mo><mi>&omega;</mi>
</math> in ihrer nach <i>x</i> aufgelösten Form auftreten. Diese sollten dann
von ihrer Darstellung mittels <i>x</i> zurück transformiert werden zur Darstellung mit ω,
damit der Algorithmus sie bei der Potenzreihenentwicklung korrekt berücksichtigt.


<a name="Ergebnisanalyse" /><h3>4.10 Ergebnisanalyse</h3>
Es bleibt nur noch wenig zu tun. Als nächstes sollte die Anhebung der Wachstumsklasse
aus <a href="Algorithmus.xml#AnhebungDerWachstumsklasse">Kapitel 4.6</a> rückgängig gemacht
werden, indem genau so oft wie damals die umgekehrte Ersetzung <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msup><mi>e</mi> <mi>x</mi></msup>
<mo>&rightarrow;</mo><mi>x</mi>
</math>,
<math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>x</mi>
<mo>&rightarrow;</mo><mo lspace="0em" rspace="thinmathspace">log</mo><mi>x</mi>
</math> auf ω und auf <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msub><mi>a</mi> <mn>0</mn></msub>

</math> angewendet wird.
Wie schon gesagt, falls man nur an dem numerischen Ergebnis interessiert ist, kann dieser Schritt auch
entfallen.<br /><br />

Nach der Potenzreihenentwicklung sind die Wachstumskomponenten der Klasse <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>&gamma;</mi>
<mo>(</mo><mi>&omega;</mi><mo>)</mo>
</math>
konzentriert in Termen <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msup><mi>&omega;</mi> <mrow><msub><mi>e</mi> <mi>k</mi></msub>
</mrow></msup>

</math> mit <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msub><mi>e</mi> <mi>k</mi></msub>
<mo>&ne;</mo><mn>0</mn>
</math>, alle Komponenten
niedrigerer Wachstumsklassen konzentrieren sich auf die Faktoren <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msub><mi>a</mi> <mi>k</mi></msub>

</math>.
Daher gilt: Ist <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msub><mi>e</mi> <mn>0</mn></msub>
<mi>&gt;</mi><mn>0</mn>
</math>, so dominiert <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>&omega;</mi>
<mo>&rightarrow;</mo><mn>0</mn>
</math> alle anderen Terme,
der Grenzwert ist also 0. Ist <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msub><mi>e</mi> <mn>0</mn></msub>
<mi>&lt;</mi><mn>0</mn>
</math>, so dominiert <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mn>1</mn>
<mo>/</mo><mi>&omega;</mi><mo>&rightarrow;</mo><mn>&infin;</mn>
</math>
alle anderen Terme, das Ergebnis ist <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mtext>Sign</mtext>
<mo>(</mo><msub><mo lspace="thinmathspace" rspace="thinmathspace">lim</mo> <mrow><mi>x</mi>
<mo>&rightarrow;</mo><mn>&infin;</mn></mrow></msub><msub><mi>a</mi> <mn>0</mn></msub><mo>)</mo><mo>&sdot;</mo><mn>&infin;</mn>
</math>.
 Ist hingegen
<math xmlns='http://www.w3.org/1998/Math/MathML'>
<msub><mi>e</mi> <mn>0</mn></msub>
<mo>=</mo><mn>0</mn>
</math>, so heben sich alle Wachstumskomponenten der Klasse <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>&gamma;</mi>
<mo>(</mo><mi>&omega;</mi><mo>)</mo>
</math>
für <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>x</mi>
<mo>&rightarrow;</mo><mn>&infin;</mn>
</math> gegenseitig auf, und der Grenzwert ist
<math xmlns='http://www.w3.org/1998/Math/MathML'>
<msub><mo lspace="thinmathspace" rspace="thinmathspace">lim</mo> <mrow><mi>x</mi>
<mo>&rightarrow;</mo><mn>&infin;</mn></mrow></msub>
<msub><mi>a</mi> <mn>0</mn></msub>
</math>.<br /><br />

Eventuell ist also ein rekursiver Grenzwertaufruf für <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msub><mo lspace="thinmathspace" rspace="thinmathspace">lim</mo> <mrow><mi>x</mi>
<mo>&rightarrow;</mo><mn>&infin;</mn></mrow></msub>
<msub><mi>a</mi> <mn>0</mn></msub>
</math>
erforderlich. Da aber die Komplexität durch die Potenzreihenentwicklung gesunken ist, bereitet
der rekursive Aufruf in der nächst niedrigeren Wachstumsklasse keine Probleme. Außerdem wird durch
jede Potenzreihenentwicklung eine vollständige Wachstumsklasse abgebaut, so lange, bis alle
Wachstumsklassen aufgelöst sind und <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msub><mi>a</mi> <mn>0</mn></msub>

</math> nicht mehr
von <i>x</i> abhängt. Da der ursprüngliche Funktionsausdruck
endliche Komplexität hat, können nur endlich viele Wachstumsklassen auftreten, der Algorithmus
terminiert also.<br /><br />

Als zusätzliches Bonbon kann der Algorithmus auch eine Asymptote zur Funktion bestimmen, die alle
Wachstumsklassen geordnet aufführt: Protokolliert man die Ergebnisse der Potenzreihenentwicklungen
<math xmlns='http://www.w3.org/1998/Math/MathML'>
<msub><mi>a</mi> <mrow><mo>(</mo>
<mn>0</mn><mo>,</mo><mi>i</mi><mo>)</mo></mrow></msub>
<msup><mrow><msub><mi>&omega;</mi> <mi>i</mi></msub>
</mrow> <mrow><msub><mi>e</mi> <mrow><mo>(</mo>
<mn>0</mn><mo>,</mo><mi>i</mi><mo>)</mo></mrow></msub>
</mrow></msup>
</math>, so ergibt sich am Ende folgende Asymptote:

<div class="mmldisplay"><math xmlns='http://www.w3.org/1998/Math/MathML' mode='display'>
<mi>A</mi>
<mo>(</mo><mi>x</mi><mo>)</mo><mo>=</mo><msub><mi>a</mi> <mrow><mo>(</mo>
<mn>0</mn><mo>,</mo><mi>n</mi><mo>)</mo></mrow></msub><mo>&sdot;</mo><msup><mrow><msub><mi>&omega;</mi> <mrow><mi>n</mi>
<mo>-</mo><mn>1</mn></mrow></msub>
</mrow> <mrow><msub><mi>e</mi> <mrow><mo>(</mo>
<mn>0</mn><mo>,</mo><mi>n</mi><mo>-</mo><mn>1</mn><mo>)</mo></mrow></msub>
</mrow></msup><mo>&sdot;</mo><msup><mrow><msub><mi>&omega;</mi> <mrow><mi>n</mi>
<mo>-</mo><mn>2</mn></mrow></msub>
</mrow> <mrow><msub><mi>e</mi> <mrow><mo>(</mo>
<mn>0</mn><mo>,</mo><mi>n</mi><mo>-</mo><mn>2</mn><mo>)</mo></mrow></msub>
</mrow></msup><mo>&sdot;</mo><mo>&sdot; &sdot; &sdot;</mo><mo>&sdot;</mo><msup><mrow><msub><mi>&omega;</mi> <mn>1</mn></msub>
</mrow> <mrow><msub><mi>e</mi> <mrow><mo>(</mo>
<mn>0</mn><mo>,</mo><mn>1</mn><mo>)</mo></mrow></msub>
</mrow></msup>
</math></div>

Alle <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msub><mi>&omega;</mi> <mi>i</mi></msub>

</math> streben gegen Null, sind positiv, haben für zunehmendes <i>i</i> eine fallende
Wachstumsklasse, und der erste Term mit <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msub><mi>e</mi> <mrow><mo>(</mo>
<mn>0</mn><mo>,</mo><mi>i</mi><mo>)</mo></mrow></msub>
<mo>&ne;</mo><mn>0</mn>
</math> ist dominant. Außerdem gilt
<math xmlns='http://www.w3.org/1998/Math/MathML'>
<msub><mo lspace="thinmathspace" rspace="thinmathspace">lim</mo> <mrow><mi>x</mi>
<mo>&rightarrow;</mo><mn>&infin;</mn></mrow></msub>
<mi>f</mi><mo>(</mo><mi>x</mi><mo>)</mo><mo>/</mo><mi>A</mi><mo>(</mo><mi>x</mi><mo>)</mo><mo>=</mo><mn>1</mn>
</math>. Der Algorithmus kann auch solange fortgesetzt
werden, dass <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msub><mi>a</mi> <mrow><mo>(</mo>
<mn>0</mn><mo>,</mo><mi>n</mi><mo>)</mo></mrow></msub>

</math> immer konstant ist. War der ursprüngliche Grenzwert nicht von der
Form <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>x</mi>
<mo>&rightarrow;</mo><mn>&infin;</mn>
</math>, so muss natürlich auch hier noch eine Rücktransformation
durchgeführt werden.


<a name="NochEinmalTerminierung" /><h3>4.11 Noch einmal Terminierung</h3>
Zwischenzeitlich hatten wir in zwei Fällen einen rekursiven Aufruf zugelassen, obwohl die Komplexität
des rekursiven Aufrufs schlimmstenfalls gleich der der ursprünglichen Funktion war. Um trotzdem sicher
zu stellen, dass
es nicht zu einer unendlichen Rekursion kommen kann, müssen wir nun zeigen, dass die nächsten rekursiven
Aufrufe nicht wieder auf eine solche Ausnahme hinaus laufen.<br /><br />

Im ersten Fall aus <a href="Algorithmus.xml#StaerkstesWachstum">Kapitel 4.5</a> gilt es zu beweisen, dass <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msub><mo lspace="thinmathspace" rspace="thinmathspace">lim</mo> <mrow><mi>x</mi>
<mo>&rightarrow;</mo><mn>&infin;</mn></mrow></msub>
<mrow><msub><mi>f</mi> <mn>1</mn></msub>
<mo>(</mo><mi>x</mi><mo>)</mo></mrow><mo>/</mo><mrow><mo lspace="0em" rspace="thinmathspace">log</mo>
<mi>x</mi></mrow>
</math> sicher
terminiert, wobei dieser Grenzwert bei der Bestimmung des MrvSet von <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>f</mi>
<mo>(</mo><mi>x</mi><mo>)</mo><mo>&sdot;</mo><mi>g</mi><mo>(</mo><mi>x</mi><mo>)</mo>
</math> entstand
mit <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msup><mi>e</mi> <mrow><msub><mi>f</mi> <mn>1</mn></msub>
<mo>(</mo><mi>x</mi><mo>)</mo></mrow></msup>
<mo>&Element;</mo><mtext>MrvSet</mtext><mo>(</mo><mi>f</mi><mo>(</mo><mi>x</mi><mo>)</mo><mo>)</mo>
</math> und <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>x</mi>
<mo>&Element;</mo><mtext>MrvSet</mtext><mo>(</mo><mi>g</mi><mo>(</mo><mi>x</mi><mo>)</mo><mo>)</mo>
</math>.<br /><br />

Beim rekursiven Aufruf kommt es bei der Bestimmung des MrvSet wieder zu einer solchen Situation,
bei der <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mtext>MrvSet</mtext>
<mo>(</mo><msub><mi>f</mi> <mn>1</mn></msub><mo>(</mo><mi>x</mi><mo>)</mo><mo>)</mo>
</math> mit <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mtext>MrvSet</mtext>
<mo>(</mo><mo lspace="0em" rspace="thinmathspace">log</mo><mi>x</mi><mo>)</mo><mo>=</mo><mo>{</mo><mi>x</mi><mo>}</mo>
</math>
 verglichen wird. Stellt
sich dabei heraus, dass <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msup><mi>e</mi> <mrow><msub><mi>f</mi> <mn>2</mn></msub>
<mo>(</mo><mi>x</mi><mo>)</mo></mrow></msup>
<mo>&Element;</mo><mtext>MrvSet</mtext><mo>(</mo><msub><mi>f</mi> <mn>1</mn></msub><mo>(</mo><mi>x</mi><mo>)</mo><mo>)</mo>
</math> ist, kommt es erneut zu einem
rekursiven Aufruf ähnlicher Art. In diesem Aufruf wird aber durch den Wegfall des
Logarithmus die Komplexität um eins sinken, der nächste rekursive Aufruf findet also wieder
mit verringerter Komplexität statt.<br /><br />

Im zweiten Fall aus <a href="Algorithmus.xml#UmschreibenDerFunktion">Kapitel 4.8</a> geht es um den Grenzwert <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>c</mi>
<mo>=</mo><msub><mo lspace="thinmathspace" rspace="thinmathspace">lim</mo> <mrow><mi>x</mi>
<mo>&rightarrow;</mo><mn>&infin;</mn></mrow></msub><mi>s</mi><mo>(</mo><msup><mi>e</mi> <mi>x</mi></msup><mo>)</mo><mo>/</mo><mrow><mo lspace="thinthinmathspace" rspace="0em">-</mo>
<mi>x</mi></mrow>
</math>.
Er entstand aus der Umschreibung eines Terms <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msup><mi>e</mi> <mrow><mi>s</mi>
<mo>(</mo><msup><mi>e</mi> <mi>x</mi></msup><mo>)</mo></mrow></msup>

</math> in die Form
<math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>A</mi>
<mo>&sdot;</mo><mo>(</mo><msup><mi>e</mi> <mrow><mo lspace="thinthinmathspace" rspace="0em">-</mo>
<mi>x</mi></mrow></msup><msup><mo>)</mo> <mi>c</mi></msup>
</math>. Durch die Anhebung der Wachstumsklasse war für problemlose rekursive
Aufrufe mindestens <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>C</mi>
<mo>(</mo><mi>s</mi><mo>(</mo><msup><mi>e</mi> <mi>x</mi></msup><mo>)</mo><mo>/</mo><mrow><mo lspace="thinthinmathspace" rspace="0em">-</mo>
<mi>x</mi></mrow><mo>)</mo><mi>&lt;</mi><mi>C</mi><mo>(</mo><msup><mi>e</mi> <mrow><mi>s</mi>
<mo>(</mo><mi>x</mi><mo>)</mo></mrow></msup><mo>)</mo>
</math> erforderlich.<br /><br />

Bei der MrvSet-Bestimmung wird diesmal jedoch der Teilausdruck <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msup><mi>e</mi> <mi>x</mi></msup>

</math> sofort dominant 
hervortreten, eine weitere Anhebung der Wachstumsklasse ist nicht erforderlich. Dadurch ist eine direkte
Schleife hier ebenfalls nicht möglich.<br /><br />

Eine Kopplung der beiden Ausnahmen ist noch denkbar, wenn Terme gleicher Komplexität abwechselnd
durch die erste Ausnahme und die zweite Ausnahme in tiefere rekursive Aufrufe gelangen.
Um auch dies auszuschließen, muss der Aufruf <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>s</mi>
<mo>(</mo><msup><mi>e</mi> <mi>x</mi></msup><mo>)</mo><mo>/</mo><mrow><mo lspace="thinthinmathspace" rspace="0em">-</mo>
<mi>x</mi></mrow>
</math> der zweiten Ausnahme 
in den MrvSet-Aufruf der ersten Ausnahme verfolgt werden.
Tatsächlich kann es zu einem weiteren rekursiven Aufruf gleicher Komplexität kommen, wenn
<math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>s</mi>
<mo>(</mo><msup><mi>e</mi> <mi>x</mi></msup><mo>)</mo>
</math> auch darstellbar ist als <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msup><mi>e</mi> <mrow><msub><mi>s</mi> <mn>1</mn></msub>
<mo>(</mo><mi>x</mi><mo>)</mo></mrow></msup>

</math>, so dass es beim MrvSet
zum problematischen Aufruf mit <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msub><mi>s</mi> <mn>1</mn></msub>
<mo>(</mo><mi>x</mi><mo>)</mo><mo>/</mo><mrow><mo lspace="0em" rspace="thinmathspace">log</mo>
<mi>x</mi></mrow>
</math> kommen kann.
Die Schleife wird durchbrochen, wenn <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msub><mi>s</mi> <mn>1</mn></msub>
<mo>(</mo><mi>x</mi><mo>)</mo>
</math> noch immer <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msup><mi>e</mi> <mi>x</mi></msup>

</math>
enthält, da so keine Anhebung der Wachstumsklasse erforderlich ist, und es nicht wieder zu 
Ausnahme 2 kommen kann. Andernfalls muss <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msub><mi>s</mi> <mn>1</mn></msub>
<mo>(</mo><mi>x</mi><mo>)</mo><mo>=</mo><mi>x</mi>
</math> sein, der
rekursive Aufruf in MrvSet ist damit <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>x</mi>
<mo>/</mo><mo lspace="0em" rspace="thinmathspace">log</mo><mi>x</mi>
</math>, was zur angehobenen Form
<math xmlns='http://www.w3.org/1998/Math/MathML'>
<msup><mi>e</mi> <mi>x</mi></msup>
<mo>/</mo><mi>x</mi>
</math> führt. ω wird als <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msup><mi>e</mi> <mrow><mo lspace="thinthinmathspace" rspace="0em">-</mo>
<mi>x</mi></mrow></msup>

</math> gewählt, und der einzige bezüglich
Ausnahme 2 interessante Grenzwertaufruf ist <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>c</mi>
<mo>=</mo><msub><mo lspace="thinmathspace" rspace="thinmathspace">lim</mo> <mrow><mi>x</mi>
<mo>&rightarrow;</mo><mn>&infin;</mn></mrow></msub><mi>x</mi><mo>/</mo><mrow><mo lspace="thinthinmathspace" rspace="0em">-</mo>
<mi>x</mi></mrow>
</math>, der aber
schon im <a href="Algorithmus.xml#UmschreibenDerFunktion">Kapitel 4.8</a> als unkritisch erkannt wurde.



<a name="AlternativerAnsatz" /><h3>4.12 Alternativer Ansatz</h3>
Bei der Konstante <i>c</i> aus <a href="Algorithmus.xml#UmschreibenDerFunktion">Kapitel 4.8</a> handelt es sich um das Wachstumsverhältnis
<math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>R</mi>
<mo>(</mo><mi>g</mi><mo>,</mo><mi>&omega;</mi><mo>)</mo>
</math> aus <a href="Grundlagen.xml#def36">Definition 3.6</a>. Berechnet wurden solche Verhältnisse
bereits bei der Konstruktion von Ω mittels MrvMax. Bewahrt man diese Ergebnisse
zusammen mit Ω auf, so kann daraus das Wachstumsverhältnis aller Terme in Ω relativ 
zu ω bestimmt werden.<br /><br />

Am einfachsten verfährt man dabei so: Die erste Funktion <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>&omega;</mi>
<mo>=</mo><mi>&Omega;</mi><mo>[</mo><mn>1</mn><mo>]</mo>
</math> 
jedes MrvSet dient als Referenz und ihr wird die Zahl r=1 zugeordnet. Wann immer eine Funktion <i>g</i>
mittels MrvMax in die Menge aufgenommen wird, wird dessen relatives Wachstumsverhältnis 
<math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>r</mi>
<mo>=</mo><mi>R</mi><mo>(</mo><mi>g</mi><mo>,</mo><mi>&omega;</mi><mo>)</mo>
</math> für den Klassenvergleich bereits berechnet und kann dann zusammen mit der 
Funktion <i>g</i> im MrvSet aufbewahrt werden.<br /><br />

Soll eine andere Funktion <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msub><mi>&omega;</mi> <mn>2</mn></msub>

</math> die erste Funktion ω ersetzen, so sind alle gespeicherten 
Verhältnisse anzupassen mit Hilfe der Regel <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msub><mi>r</mi> <mrow><mi>neu</mi>
</mrow></msub>
<mo>=</mo><msub><mi>r</mi> <mrow><mi>alt</mi>
</mrow></msub><mo>&sdot;</mo><mi>R</mi><mo>(</mo><mi>&omega;</mi><mo>,</mo><msub><mi>&omega;</mi> <mn>2</mn></msub><mo>)</mo>
</math>.
Wie schon im Anschluss an <a href="Grundlagen.xml#th37">Theorem 3.7</a> gesehen, gilt ja 
<math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>R</mi>
<mo>(</mo><mi>g</mi><mo>,</mo><msub><mi>&omega;</mi> <mn>2</mn></msub><mo>)</mo><mo>=</mo><mi>R</mi><mo>(</mo><mi>g</mi><mo>,</mo><mi>&omega;</mi><mo>)</mo><mo>&sdot;</mo><mi>R</mi><mo>(</mo><mi>&omega;</mi><mo>,</mo><msub><mi>&omega;</mi> <mn>2</mn></msub><mo>)</mo>
</math>.
Normalerweise ist auch dieses Wachstumsverhältnis bekannt, ein weiterer Grenzwertaufruf ist nicht nötig.<br /><br />

Entsprechend muss im Fall der Vereinigung bei MrvMax eine der beiden Mengen an die 
Referenz der anderen Menge angepasst werden, indem zum Beispiel in <math xmlns='http://www.w3.org/1998/Math/MathML'>
<msub><mi>&Omega;</mi> <mn>2</mn></msub>

</math> 
jedes Wachstumsverhältnis mit <math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>R</mi>
<mo>(</mo><msub><mi>&Omega;</mi> <mn>2</mn></msub><mo>[</mo><mn>1</mn><mo>]</mo><mo>,</mo><msub><mi>&Omega;</mi> <mn>1</mn></msub><mo>[</mo><mn>1</mn><mo>]</mo><mo>)</mo>
</math> multipliziert wird.<br /><br />

Die Anhebung der Wachstumsklasse hat auf das Wachstumsverhältnis genauso wenig einen Einfluss, 
wie auf den Grenzwert der Funktion selbst, hier ist also nichts zu beachten. Schließlich
bleibt noch die endgültige Wahl von ω. Diese ist genauso zu behandeln, wie auch die bisherigen 
Wechsel der Referenzfunktion. Sollte das Wachstumsverhalten von ω durch Ersetzung 
<math xmlns='http://www.w3.org/1998/Math/MathML'>
<mi>&omega;</mi>
<mo>&rightarrow;</mo><mn>1</mn><mo>/</mo><mi>&omega;</mi>
</math> gedreht worden sein, ergibt sich daraus eine weitere 
Multiplikation für alle Wachstumsverhältnisse mit -1.<br /><br />

Der Lohn der Mühe ist, dass bei der Ersetzung im <a href="Algorithmus.xml#UmschreibenDerFunktion">Kapitel 4.8</a>
das Wachstumsverhältnis <i>c</i> bereits bekannt ist
und nicht durch einen weiteren rekursiven Aufruf ermittelt werden muss. Dadurch treten in
der Hauptschleife des Algorithmus rekursive Aufrufe nur noch bei der Bestimmung
von Ω sowie bei der Parameterprüfung am Anfang auf.
Insbesondere treten aber nach der Anhebung der Wachstumsklasse keine rekursiven Aufrufe
mehr auf, was die Beweisführung weiter vereinfacht.<br /><br />

In der weiteren Diplomarbeit wird dieser alternative Ansatz jedoch nicht impementiert. 





<br /><a href="Grundlagen.xml">Zurück</a> - <a href="Inhalt.xml">Inhalt</a> - <a href="index.html">Übersicht</a> - <a href="Paket.xml">Vorwärts</a>
</body></html>