This is maxima.info, produced by makeinfo version 5.1 from maxima.texi.


File: maxima.info,  Node: Paket atensor,  Prev: Paket ctensor,  Up: Tensoren

20.4 Paket ATENSOR
==================

* Menu:

* Einführung in atensor::
* Funktionen und Variablen für atensor::


File: maxima.info,  Node: Einführung in atensor,  Next: Funktionen und Variablen für atensor,  Prev: Paket atensor,  Up: Paket atensor

20.4.1 Einführung in ATENSOR
----------------------------

Das Paket ‘atensor’ erlaubt das algebraische Rechnen mit Tensoren.  Mit
dem Kommando ‘load("atensor")’ wird das Paket geladen.  Um das Paket zu
initialisieren, wird die Funktion ‘init_atensor’ ausgeführt.

Im wesentlichen enthält das Paket ‘atensor’ Regeln für die Vereinfachung
von Ausdrücken mit dem ‘dot-Operator’ Operator ‘"."’.  ‘atensor’ kennt
verschiedene Algebren.  Mit der Funktion ‘init_atensor’ werden die
Regeln einer Algebra initialisiert.

Um die Möglichkeiten des Paketes ‘atensor’ zu zeigen, wird im Folgenden
die Algebra der Quaternionen als eine Clifford-Algebra Cl(0,2) mit zwei
Basisvektoren definiert.  Die drei imaginären Einheiten ‘i’, ‘j’ und ‘k’
werden durch die zwei Vektoren ‘v[1]’ und ‘v[2]’ sowie das Produkt ‘v[1]
. v[2]’ dargestellt:

         i = v     j = v     k = v  . v
              1         2         1    2

Das Paket ‘atensor’ hat eine vordefinierte Algebra der Quaternionen.
Hier wird die Algebra der Quaterinonen als Clifford-Algebra Cl(0,2)
definiert und die Multiplikationstabelle der Basisvektoren konstruiert.

     (%i1) load("atensor")$

     (%i2) init_atensor(clifford,0,0,2);
     (%o2)                         done
     (%i3) atensimp(v[1].v[1]);
     (%o3)                          - 1
     (%i4) atensimp((v[1].v[2]).(v[1].v[2]));
     (%o4)                          - 1
     (%i5) q:zeromatrix(4,4);
                              [ 0  0  0  0 ]
                              [            ]
                              [ 0  0  0  0 ]
     (%o5)                    [            ]
                              [ 0  0  0  0 ]
                              [            ]
                              [ 0  0  0  0 ]
     (%i6) q[1,1]:1;
     (%o6)                           1
     (%i7) for i thru adim do q[1,i+1]:q[i+1,1]:v[i];
     (%o7)                         done
     (%i8) q[1,4]:q[4,1]:v[1].v[2];
     (%o8)                        v  . v
                                   1    2
     (%i9) for i from 2 thru 4 do
               for j from 2 thru 4 do
                   q[i,j]:atensimp(q[i,1].q[1,j]);
     (%o9)                         done
     (%i10) q;
                 [    1        v         v      v  . v  ]
                 [              1         2      1    2 ]
                 [                                      ]
                 [   v         - 1     v  . v    - v    ]
                 [    1                 1    2      2   ]
     (%o10)      [                                      ]
                 [   v      - v  . v     - 1      v     ]
                 [    2        1    2              1    ]
                 [                                      ]
                 [ v  . v      v        - v       - 1   ]
                 [  1    2      2          1            ]

Indizierte Symbole mit dem Namen, der in der Optionsvariablen ‘asymbol’
abgelegt ist, werden von ‘atensor’ als Basisvektoren erkannt.  Dabei
läuft der Index von ‘1’ bis ‘adim’.  Für indizierte Symbole werden die
Bilinearformen ‘sf’, ‘af’ und ‘av’ ausgewertet.  Die Auswertung ersetzt
die Bilinearform ‘fun(v[i].v[j])’, durch das Matrixelement ‘aform[i,j]’,
wobei ‘v’ einen Basisvektor bezeichnet und ‘fun’ einer der
Bilinearformen ‘sf’ oder ‘af’ ist.  Ist ‘fun’ die Bilinearform ‘av’,
dann wird ‘v[aform[i,j]]’ für ‘av(v[i],v[j])’ substituiert.  Siehe auch
die Optionsvariable ‘aform’.

Die Bilinearformen ‘sf’, ‘af’ und ‘av’ können vom Nutzer neu definiert
werden, um eine gewünschte Algebra zu definieren.

Wird das Paket ‘atensor’ geladen, werden die folgenden Schalter auf die
angegebenen Werte gesetzt:

     dotscrules  : true
     dotdistrib  : true
     dotexptsimp : false

Wird das symbolische Rechnen in einer nicht-assoziativen Algebra
gewünscht, kann auch noch der Schalter ‘dotassoc’ auf den Wert ‘false’
gesetzt werden.  In diesem Fall kann jedoch die Funktion ‘atensimp’
nicht immer eine gewünschte Vereinfachung erzielen.


File: maxima.info,  Node: Funktionen und Variablen für atensor,  Prev: Einführung in atensor,  Up: Paket atensor

20.4.2 Funktionen und Variablen für ATENSOR
-------------------------------------------

 -- Funktion: init_atensor (<alg_type>, <opt_dims>)
 -- Funktion: init_atensor (<alg_type>)

     Initialisiert das Paket ‘atensor’ mit der angegebenen Algebra
     <alg_type>.  Das Argument <alg_type> kann einen der folgenden Werte
     haben:

     ‘universal’
          Eine allgemeine Algebra, für die keine Vertauschungsregeln
          definiert sind.

     ‘grassmann’
          Eine Graßmann-Algebra, für die die Vertauschungsregel ‘u.v +
          v.u = 0’ definiert ist.

     ‘clifford’
          Eine Clifford-Algebra, die durch die Vertauschungsregel ‘u.v +
          v.u = -2*sf(u,v)’ definiert ist.  Die Bilinearform ‘sf’ ist
          eine symmetrische Funktion, die einen skalaren Wert als
          Ergebnis hat.  Das Argument <opt_dims> kann bis zu drei
          positive ganze Zahlen sein, die die positiven, entarteten und
          negativen Dimensionen der Algebra bezeichnen.  Die Dimension
          ‘adim’ und die Matrix ‘aform’ werden entsprechend der
          angegebenen Argumente <opt_dims> initialisiert.  Sind keine
          Argumente <opt_dims> vorhanden, wird die Dimension ‘adim’ zu
          Null initialisiert und keine Matrix ‘aform’ definiert.

     ‘symmetric’
          Eine symmetrische Algebra, die durch die Vertauschungsregel
          ‘u.v - v.u = 0’ definiert ist.

     ‘symplectic’
          Eine symplektische Algebra, die durch die Vertauschungsregel
          ‘u.v - v.u = 2*af(u,v)’ definiert ist.  Die Bilinearform ‘af’
          ist eine antisymmetrische Funktion, die einen skalaren Wert
          als Ergebnis hat.  Das Argument <opt_dims> kann bis zu zwei
          positive ganze Zahlen enthalten, die die nicht-degenerierten
          und degenerierten Dimensionen der Algebra bezeichnen.  Die
          Dimension ‘adim’ und die Matrix ‘aform’ werden entsprechend
          der angegebenen Argumente <opt_dims> initialisiert.  Sind
          keine Argumente <opt_dims> vorhanden, wird die Dimension
          ‘adim’ zu Null initialisiert und keine Matrix ‘aform’
          definiert.

     ‘lie_envelop’
          Eine einhüllende Lie-Algebra, die durch die Vertauschungsregel
          ‘u.v - v.u = 2*av(u,v)’ definiert ist, wobei die Bilinearform
          ‘av’ eine antisymmetrische Funktion ist.  Das Argument
          <opt_dims> kann eine positive ganze Zahl sein, welche die
          Dimension der Lie-Algebra angibt.  Die Dimension ‘adim’ und
          die Matrix ‘aform’ werden entsprechend des Argumentes
          <opt_dims> initialisiert.  Ist kein Argument <opt_dims>
          vorhanden, wird die Dimension ‘adim’ zu Null initialisiert und
          keine Matrix ‘aform’ definiert.

     Die Funktion ‘init_atensor’ kennt weiterhin einige vordefinierte
     Algebren:

     ‘complex’
          Die Algebra der komplexen Zahlen, die als eine
          Clifford-Algebra Cl(0,1) definiert wird.  Das Kommando
          ‘init_atensor(complex)’ ist äquivalent zum Kommando
          ‘init_atensor(clifford, 0, 0, 1)’.

     ‘quaternion’
          Die Algebra der Quaternionen, die als eine Clifford-Algebra
          vom Typ Cl(0,2) definiert wird.  Das Kommando
          ‘init_atensor(quaternion)’ ist äquivalent zum Kommando
          ‘init_atensor(clifford, 0, 0, 2)’.

     ‘pauli’
          Die Algebra der Pauli-Matrizen, die als eine Clifford-Algebra
          Cl(3,0) definiert wird.  Das Kommando ‘init_atensor(pauli)’
          ist äquivalent zum Kommando ‘init_atensor(clifford, 3)’.

     ‘dirac’
          Die Algebra der Dirac-Matrizen, die als eine Clifford-Algebra
          Cl(3,0,1) definiert wird.  Das Kommando ‘init_atensor(dirac)’
          ist äquivalent zum Kommando ‘init_atensor(clifford, 3, 0, 1)’.

 -- Funktion: atensimp (<expr>)

     Vereinfacht einen Ausdruck <expr> entsprechend der Regeln für die
     Algebra, die mit der Funktion ‘init_atensor’ festgelegt ist.  Die
     Regeln werden rekursiv auf den Ausdruck angewendet.  Dabei werden
     auch Bilinearformen ‘sf’, ‘af’ und ‘av’ ausgewertet.

     Beispiele:

     Die folgenden Beispiele zeigen das Rechnen mit der Algebra der
     Quaternionen.

          (%i1) load("atensor")$

          (%i2) init_atensor(quaternion);
          (%o2)                         done
          (%i3) atensimp(v[1].v[1]);
          (%o3)                          - 1
          (%i4) atensimp(v[2].v[2]);
          (%o4)                          - 1
          (%i5) atensimp((v[1].v[2]) . (v[1].v[2]));
          (%o5)                          - 1
          (%i6) expand((2*v[1]+3*v[2])^^2);
          (%o6) 9 (v  . v ) + 6 (v  . v ) + 6 (v  . v ) + 4 (v  . v )
                    2    2        2    1        1    2        1    1
          (%i7) atensimp(%);
          (%o7)                         - 13

 -- Optionsvariable: alg_type
     Standardwert: ‘universal’

     Der Typ der Algebra, die bei der Vereinfachung von Ausdrücken mit
     der Funktion ‘atensimp’ angewendet wird.  Die Algebra wird von der
     Funktion ‘init_atensor’ initialisiert.  Mögliche Algebren sind
     ‘universal’, ‘grassmann’, ‘clifford’, ‘symmetric’, ‘symplectic’ und
     ‘lie_envelop’.  Siehe für eine ausführliche Erläuterung der
     Algebren die Funktion ‘init_atensor’.

 -- Optionsvariable: adim
     Standardwert: ‘0’

     Die Dimension der Algebra, die bei der Vereinfachung von Ausdrücken
     mit der Funktion ‘atensimp’ angewendet wird.  Die Dimension wird
     von der Funktion ‘init_atensor’ initialisiert.  Ein indiziertes
     Symbol mit dem Bezeichner ‘asymbol’ ist dann ein Basisvektor, wenn
     der Index kleiner oder gleich der Dimension ‘adim’ ist.

     Beispiel:

     Die Dirac-Algebra hat die Dimension ‘4’ und ‘v[4]’ ist ein
     Basisvektor.

          (%i1) load("atensor")$

          (%i2) init_atensor(dirac);
          (%o2)                         done
          (%i3) adim;
          (%o3)                           4
          (%i4) abasep(v[4]);
          (%o4)                         true

 -- Optionsvariable: aform
     Standardwert: ‘ident(3)’

     Matrix mit den Werten der Bilinearformen ‘sf’, ‘af’ und ‘av’.  Der
     Standardwert ist die dreidimensionale Einheitsmatrix.

     Beispiel:

     Das Beispiel zeigt die Matrix ‘aform’ für eine Lie-Algebra mit drei
     Dimensionen und die Ergebnisse der Bilinearform ‘av’ für diese
     Algebra.

          (%i1) load("atensor")$

          (%i2) init_atensor(lie_envelop, 3);
          (%o2)                         done
          (%i3) aform;
                                  [  0    3   - 2 ]
                                  [               ]
          (%o3)                   [ - 3   0    1  ]
                                  [               ]
                                  [  2   - 1   0  ]
          (%i4) av(v[1], v[2]);
          (%o4)                          v
                                          3
          (%i5) av(v[1], v[3]);
          (%o5)                         - v
                                           2

 -- Optionsvariable: asymbol
     Standardwert: ‘v’

     Enthält das Symbol, das einen Basisvektor des Paketes ‘atensor’
     bezeichnet.  Mit der Funktion ‘abasep’ kann getestet werde, ob ein
     indiziertes Symbol einen Basisvektor der Algebra bezeichnet.

     Beispiel:

     In diesem Beispiel wird ‘asymbol’ auf den Wert ‘x’ gesetzt.

          (%i1) load("atensor")$

          (%i2) init_atensor(symmetric, 2);
          (%o2)                         done
          (%i3) asymbol;
          (%o3)                           v
          (%i4) abasep(v[2]);
          (%o4)                         true
          (%i5) asymbol: x;
          (%o5)                           x
          (%i6) abasep(x[2]);
          (%o6)                         true

 -- Funktion: sf (<u>, <v>)

     Eine symmetrische Bilinearform, die bei der Vereinfachung von
     Ausdrücken mit der Funktion ‘atensimp’ angewendet wird.  Die
     Funktion kann vom Nutzer durch eine neue Funktion ersetzt werden.
     Die Standardimplementation prüft mit der Funktion ‘abasep’, ob die
     Argumente <u> und <v> Basisvektoren sind und setzt für diesen Fall
     den entsprechen Wert der Matrix ‘aform’ ein.

 -- Funktion: af (<u>, <v>)

     Eine antisymmetrische Bilinearform, die bei der Vereinfachung von
     Ausdrücken mit der Funktion ‘atensimp’ angewendet wird.  Die
     Funktion kann vom Nutzer durch eine neue Funktion ersetzt werden.
     Die Standardimplementation prüft mit der Funktion ‘abasep’, ob die
     Argumente <u> und <v> Basisvektoren sind und setzt für diesen Fall
     den entsprechenden Wert der Matrix ‘aform’ ein.

 -- Funktion: av (<u>, <v>)

     Eine antisymmetrische Bilinearform, die bei der Vereinfachung von
     Ausdrücken mit der Funktion ‘atensimp’ angewendet wird.  Die
     Funktion kann vom Nutzer durch eine neue Funktion ersetzt werden.
     Die Standardimplementation prüft mit der Funktion ‘abasep’, ob die
     Argumente <u> und <v> Basisvektoren sind und setzt für diesen Fall
     den entsprechenden Wert ‘v[aform[i,j]]’ der Matrix ‘aform’ ein.

     Beispiel:

          (%i1) load("atensor")$
          (%i2) adim: 3;
          (%o2)                           3
          (%i3) aform:matrix([0,3,-2],[-3,0,1],[2,-1,0]);
                                  [  0    3   - 2 ]
                                  [               ]
          (%o3)                   [ - 3   0    1  ]
                                  [               ]
                                  [  2   - 1   0  ]
          (%i4) asymbol: x;
          (%o4)                           x
          (%i5) av(x[1], x[2]);
          (%o5)                          x
                                          3
          (%i6) av(x[1], x[3]);
          (%o6)                         - x
                                           2

 -- Funktion: abasep (<v>)

     Prüft, ob das Argument <v> ein Basisvektor ist.  Ein Basisvektor
     ist ein indiziertes Symbol mit dem Symbol ‘asymbol’ als Bezeichner
     und einem Index im Bereich von ‘1’ bis ‘adim’.

     Beispiel:

          (%i1) load("atensor")$
          (%i2) asymbol: x$
          (%i3) adim:3$
          (%i4) abasep(x[1]);
          (%o4)                         true
          (%i5) abasep(x[3]);
          (%o5)                         true
          (%i6) abasep(x[4]);
          (%o6)                         false


File: maxima.info,  Node: Zahlentheorie,  Next: Spezielle Funktionen,  Prev: Tensoren,  Up: Top

21 Zahlentheorie
****************

* Menu:

* Funktionen und Variablen der Zahlentheorie::


File: maxima.info,  Node: Funktionen und Variablen der Zahlentheorie,  Prev: Zahlentheorie,  Up: Zahlentheorie

21.1 Funktionen und Variablen der Zahlentheorie
===============================================

 -- Funktion: bern (<n>)

     Gibt die <n>-te Bernoulli-Zahl der ganzen Zahl <n> zurück.  Hat die
     Optionsvariable ‘zerobern’ den Wert ‘false’, werden
     Bernoulli-Zahlen unterdrückt, die Null sind.

     Siehe auch ‘burn’.

          (%i1) zerobern: true$
          (%i2) map (bern, [0, 1, 2, 3, 4, 5, 6, 7, 8]);
                            1  1       1      1        1
          (%o2)       [1, - -, -, 0, - --, 0, --, 0, - --]
                            2  6       30     42       30
          (%i3) zerobern: false$
          (%i4) map (bern, [0, 1, 2, 3, 4, 5, 6, 7, 8]);
                      1  1    1   5     691   7    3617  43867
          (%o4) [1, - -, -, - --, --, - ----, -, - ----, -----]
                      2  6    30  66    2730  6    510    798

 -- Funktion: bernpoly (<x>, <n>)

     Gibt das <n>-te Bernoulli-Polynom in der Variablen <x> zurück.

 -- Function: bfzeta (<s>, <n>)

     Die Riemannsche Zeta-Funktion für das Argument <s>, die wie folgt
     definiert ist:

                           inf
                           ====
                           \     1
               zeta(s) =    >    --
                           /      s
                           ====  k
                           k = 1

     ‘bfzeta’ gibt einen Wert als große Gleitkommazahl zurück.  Die
     Anzahl der Stellen wird durch das Argument <n> angegeben.

     Anstatt der Funktion ‘bfzeta’ ist die Funktion ‘zeta’ zu
     bevorzugen, die sowohl für reelle und komplexe Gleitkommazahlen und
     Gleitkommazahlen mit eine beliebigen Genauigkeit die Riemannsche
     Zeta-Funktion berechnen kann.

 -- Funktion: bfhzeta (<s>, <h>, <n>)

     Die Hurwitzsche Zeta-Funktion für die Argumente <s> und <h>, die
     wie folgt definiert ist:

                                  inf
                                  ====
                                  \        1
                   zeta (s,h)  =   >    --------
                                  /            s
                                  ====  (k + h)
                                  k = 0

     ‘bfhzeta’ gibt einen Wert als große Gleitkommazahl zurück.  Die
     Anzahl der Stellen wird durch das Argument <n> angegeben.

 -- Funktion: burn (<n>)

     Gibt eine rational Zahl zurück, die eine Näherung für die <n>-te
     Bernoulli Zahl für die ganze Zahl <n> ist.  ‘burn’ berechnet eine
     Näherung als große Gleitkommatzahl mit der folgenden Beziehung:

                             n - 1  1 - 2 n
                        (- 1)      2        zeta(2 n) (2 n)!
               B(2 n) = ------------------------------------
                                          2 n
                                       %pi

     ‘burn’ kann effizienter als die Funktion ‘bern’ für große, einzelne
     ganze Zahlen <n> sein, da ‘bern’ zunächst alle Bernoulli Zahlen bis
     <n> berechnet.  ‘burn’ ruft für ungerade ganze Zahlen und Zahlen
     die kleiner oder gleich 255 die Funktion ‘bern’ auf.

     Das Kommando ‘load("bffac")’ lädt die Funktion.  Siehe auch ‘bern’.

 -- Funktion: chinese ([<r_1>, …, <r_n>], [<m_1>, …, <m_n>])

     Löst die simultanen Kongruenzen ‘x = r_1 mod m_1’, …, ‘x = r_n mod
     m_n’.  Die Reste <r_n> und die Moduli <m_n> müssen ganze Zahlen
     sein, die Moduli zusätzlich positiv und paarweise teilerfremd.

          (%i1) mods : [1000, 1001, 1003, 1007];
          (%o1)                   [1000, 1001, 1003, 1007]
          (%i2) lreduce('gcd, mods);
          (%o2)                               1
          (%i3) x : random(apply("*", mods));
          (%o3)                         685124877004
          (%i4) rems : map(lambda([z], mod(x, z)), mods);
          (%o4)                       [4, 568, 54, 624]
          (%i5) chinese(rems, mods);
          (%o5)                         685124877004
          (%i6) chinese([1, 2], [3, n]);
          (%o6)                    chinese([1, 2], [3, n])
          (%i7) %, n = 4;
          (%o7)                              10

 -- Funktion: divsum (<n>, <k>)
 -- Funktion: divsum (<n>)

     ‘divsum(<n>, <k>)’ potenziert die Teiler des Argumentes <n> mit dem
     Argument <k> und gibt die Summe als Ergebnis zurück.

     ‘divsum(<n>)’ gibt die Summe der Teiler der Zahl <n> zurück.

          (%i1) divsum (12);
          (%o1)                          28
          (%i2) 1 + 2 + 3 + 4 + 6 + 12;
          (%o2)                          28
          (%i3) divsum (12, 2);
          (%o3)                          210
          (%i4) 1^2 + 2^2 + 3^2 + 4^2 + 6^2 + 12^2;
          (%o4)                          210

 -- Funktion: euler (<n>)

     Gibt die <n>-te Eulersche Zahl für eine nichtnegative ganze Zahl
     <n> zurück.

     Für die Euler-Mascheroni Konstante siehe ‘%gamma’.

     Beispiele:

          (%i1) map (euler, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
          (%o1)    [1, 0, - 1, 0, 5, 0, - 61, 0, 1385, 0, - 50521]

 -- Optionsvariable: factors_only
     Standardwert: ‘false’

     Hat ‘factors_only’ den Standardwert ‘false’, werden von der
     Funktion ‘ifactors’ zusammen mit den berechneten Primfaktoren auch
     deren Multiplizitäten angegeben.  Hat ‘factors_only’ den Wert
     ‘true’, werden nur die Primfaktoren zurück gegeben.

     Beispiel: Siehe ‘ifactors’.

 -- Funktion: fib (<n>)

     Gibt die <n>-te Fibonacci-Zahl zurück.  Die Fibonacci-Folge ist
     rekursiv definiert:

             fib(0) = 0
             fib(1) = 1
             fib(n) = fib(n-1) + fib(n-2)

     Für negative ganze Zahlen kann die Fibonacci-Folge wie folgt
     erweitert werden:

                             n + 1
             fib(- n) = (- 1)      fib(n)

     Nach einem Aufruf der Funktion ‘fib(n)’, enthält die Systemvariable
     ‘prevfib’ die zur Zahl ‘n’ vorhergehende Fibonacci-Zahl.

          (%i1) map (fib, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
          (%o1)         [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

 -- Funktion: fibtophi (<expr>)

     Fibonacci-Zahlen im Ausdruck <expr> werden durch die Goldene Zahl
     ‘%phi’ ausgedrückt.  Siehe ‘%phi’.

     Beispiele:

          (%i1) fibtophi (fib (n));
                                     n             n
                                 %phi  - (1 - %phi)
          (%o1)                  -------------------
                                     2 %phi - 1
          (%i2) fib (n-1) + fib (n) - fib (n+1);
          (%o2)          - fib(n + 1) + fib(n) + fib(n - 1)
          (%i3) fibtophi (%);
                      n + 1             n + 1       n             n
                  %phi      - (1 - %phi)        %phi  - (1 - %phi)
          (%o3) - --------------------------- + -------------------
                          2 %phi - 1                2 %phi - 1
                                                    n - 1             n - 1
                                                %phi      - (1 - %phi)
                                              + ---------------------------
                                                        2 %phi - 1
          (%i4) ratsimp (%);
          (%o4)                           0

 -- Funktion: ifactors (<n>)

     Faktorisiert eine positive ganze Zahl <n>.  Sind ‘n = p1^e1 * ... *
     pk^nk’ die Faktoren der ganzen Zahl <n>, dann gibt ‘ifactor’ das
     Ergebnis ‘[[p1, e1], ..., [pk, ek]]’ zurück.

     Für die Faktorisierung kommen Probedivisionen mit Primzahlen bis
     9973, Pollards Rho- und p-1-Methode oder Elliptischen Kurven zum
     Einsatz.

     Die Rückgabe von ifactors wird von der Optionsvariablen
     ‘factors_only’ beeinflusst.  Werden lediglich die Primfaktoren ohne
     ihre Multiplizität benötigt, genügt es hierfür, ‘factors_only :
     true’ zu setzen.

          (%i1) ifactors(51575319651600);
          (%o1)     [[2, 4], [3, 2], [5, 2], [1583, 1], [9050207, 1]]
          (%i2) apply("*", map(lambda([u], u[1]^u[2]), %));
          (%o2)                        51575319651600
          (%i3) ifactors(51575319651600), factors_only : true;
          (%o3)                   [2, 3, 5, 1583, 9050207]

 -- Funktion: igcdex (<n>, <k>)

     Gibt die Liste ‘[a, b, u]’ zurück, in der ‘u’ der größte gemeinsame
     Teiler von <n> und <k> ist und in der zusätzlich gilt, dass ‘u = a
     * <n> + b * <k>’.

     ‘igcdex’ verwendet den Euklidischen Algorithmus.  Siehe auch
     ‘gcdex’.

     Die Eingabe ‘load("gcdex")’ lädt diese Funktion.

     Beispiele:

          (%i1) load("gcdex")$

          (%i2) igcdex(30, 18);
          (%o2)                      [- 1, 2, 6]
          (%i3) igcdex(1526757668, 7835626735736);
          (%o3)            [845922341123, - 164826435, 4]
          (%i4) igcdex(fib(20), fib(21));
          (%o4)                   [4181, - 2584, 1]

 -- Funktion: inrt (<x>, <n>)

     Gibt die ganzzahlige <n>-te Wurzel des Betrags von <x> zurück.

          (%i1) l: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]$
          (%i2) map (lambda ([a], inrt (10^a, 3)), l);
          (%o2) [2, 4, 10, 21, 46, 100, 215, 464, 1000, 2154, 4641, 10000]

 -- Funktion: inv_mod (<n>, <m>)

     Berechnet das modulare Inverse von <n> zum Modul <m>.  Das Argument
     <n> muss eine ganze Zahl und der Modul <p> eine positive ganze Zahl
     sein.  ‘inv_mod(n, m)’ gibt ‘false’ zurück, wenn das modulare
     Inverse nicht existiert.  Das modulare Inverse existiert, wenn <n>
     teilerfremd zum Modul <m> ist.

     Siehe auch die Funktionen ‘power_mod’ und ‘mod’.

     Beispiele:

          (%i1) inv_mod(3, 41);
          (%o1)                           14
          (%i2) ratsimp(3^-1), modulus = 41;
          (%o2)                           14
          (%i3) inv_mod(3, 42);
          (%o3)                          false

 -- Funktion: isqrt (<x>)

     Gibt die ganzzahlige Wurzel des Betrages von <x> zurück, wenn <x>
     eine ganze Zahl ist.  Andernfalls wird eine Substantivform
     zurückgegeben.

 -- Funktion: jacobi (<p>, <q>)

     Berechnet das Jacobi-Symbol für die Argumente <p> und <q>.

          (%i1) l: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]$
          (%i2) map (lambda ([a], jacobi (a, 9)), l);
          (%o2)         [1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0]

 -- Funktion: lcm (<expr_1>, …, <expr_n>)

     Gibt das kleinste gemeinsame Vielfache der Argumente zurück.  Die
     Argumente können ganze Zahlen und allgemeine Ausdrücke sein.

     Mit dem Kommando ‘load("functs")’ wird die Funktion geladen.

 -- Funktion: lucas (<n>)

     Gibt die <n>-te Lucas-Zahl zurück.  Die Lucas-Folge ist rekursiv
     definiert:

             lucas(0) = 0
             lucas(1) = 1
             lucas(n) = lucas(n-1) + lucas(n-2)

     Für negative ganze Zahlen kann die Lucas-Folge wie folgt erweitert
     werden:

                               -n
             lucas(- n) = (- 1)   lucas(n)

          (%i1) map (lucas, [-4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8]);
          (%o1)             [7, - 4, 3, - 1, 2, 1, 3, 4, 7, 11, 18, 29, 47]

     Nach einem Aufruf von ‘lucas’ enthält die globale Variable
     ‘next_lucas’ den Nachfolger der zuletzt zurc̈k gegebenen
     Lucas-Zahl.  Das Beispiel zeigt, wie Fibonacci-Zahlen mit Hilfe von
     ‘lucas’ und ‘next_lucas’ berechnet werden können.

          (%i1) fib_via_lucas(n) :=
                   block([lucas : lucas(n)],
                   signum(n) * (2*next_lucas - lucas)/5 )$
          (%i2) map (fib_via_lucas, [-4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8]);
          (%o2)             [- 3, 2, - 1, 1, 0, 1, 1, 2, 3, 5, 8, 13, 21]

 -- Funktion: mod (<x>, <p>)

     Berechnet den Divisionsrest ‘x mod y’ des Arguments <x> zum Modul
     <y>.  <x> und <y> können ganze Zahlen, rationale Zahlen,
     Gleitkommazahlen oder allgemeine Ausdrücke sein.

     Sind <x> und <y> reelle Zahlen und ist <y> ungleich Null, gibt
     ‘mod(<x>, <y>)’ das Ergebnis von ‘<x> - <y> * floor(<x> / <y>)’
     zurück.  Weiterhin gilt für alle reellen Zahlen ‘mod(<x>, 0) =
     <x>’.  Für eine Diskussion dieser Definition siehe Kapitel 3.4,
     "Concrete Mathematics" von Graham, Knuth, and Patashnik.  Die
     Funktion ‘mod(<x>, 1)’ ist eine Sägezahnfunktion mit der Periode 1
     mit ‘mod(1, 1) = 0’ und ‘mod(0, 1) = 0’.

     Der Hauptwert einer komplexen Zahl, die im Intervall ‘(-%pi, %pi)’
     liegt, kann mit ‘%pi - mod(%pi - <x>, 2*%pi)’ bestimmt werden,
     wobei <x> die komplexe Zahl ist.

     Sind <x> und <y> konstante Ausdrücke, wie zum Beispiel ‘10 * %pi’,
     verwendet ‘mod’ dasselbe ‘bfloat’-Auswertungsschema wie ‘floor’ und
     ‘ceiling’.  Diese Umwandlung kann, wenn auch unwahrscheinlich, zu
     Fehlern führen.

     Für nicht numerische Argumente <x> oder <y> kennt ‘mod’
     verschiedene Vereinfachungen.

     Siehe auch die Funktionen ‘power_mod’ und ‘inv_mod’.

     Beispiele:

     Zeige für zwei große ganze Zahlen, dass für das modulare Rechnen
     die Regel ‘mod(a+b, m) = mod(mod(a, m) + mod(b, m), m)’ gilt.

          (%i1) a : random(10^20) + 10^19;
          (%o1)                 72588919020045581148
          (%i2) b : random(10^20) + 10^19;
          (%o2)                 35463666253140008825
          (%i3) m : random(10^20) + 10^19;
          (%o3)                 39127433614020247557
          (%i4) mod(a+b, m);
          (%o4)                 29797718045145094859
          (%i5) mod(mod(a, m) + mod(b, m), m);
          (%o5)                 29797718045145094859

     Vereinfachung für nicht numerische Argumente.

          (%i1) mod (x, 0);
          (%o1)                           x
          (%i2) mod (a*x, a*y);
          (%o2)                      a mod(x, y)
          (%i3) mod (0, x);
          (%o3)                           0

 -- Funktion: next_prime (<n>)

     Gibt die kleinste Primzahl zurück, die der Zahl <n> folgt.

          (%i1) next_prime(27);
          (%o1)                       29

 -- Funktion: power_mod (<a>, <n>, <m>)

     Verwendet einen modularen Algorithmus, um ‘a^n mod m’ zu berechnen.
     Die Argumente <a> und <n> müssen ganze Zahlen und der Modul <m>
     eine positive ganze Zahl sein.  Ist <n> negativ, wird ‘inv_mod’ zur
     Berechnung des modularen Inversen aufgerufen.

     ‘power_mod (<a>, <n>, <m>)’ ist äquivalent zu ‘mod(a^n, m)’.  Der
     Algorithmus von ‘power_mod’ ist jedoch insbesondere für große ganze
     Zahlen wesentlich effizienter.

     Siehe auch die Funktionen ‘inv_mod’ und ‘mod’.

     Beispiele:

     ‘power_mod(a, n, m)’ ist äquivalent zu ‘mod(a^n, m’.  Das modulare
     Inverse wird mit der Funktion ‘inv_mod’ berechnet.

          (%i1) power_mod(3, 15, 5);
          (%o1)                          2
          (%i2) mod(3^15, 5);
          (%o2)                          2
          (%i3) power_mod(2, -1, 5);
          (%o3)                          3
          (%i4) inv_mod(2, 5);
          (%o4)                          3

     Für große ganze Zahlen ist ‘power_mod’ effizienter.  Der folgende
     Wert kann in keiner vernünftigen Zeit mit ‘mod(a^n, m)’ berechnet
     werden.

          (%i1) power_mod(123456789, 123456789, 987654321);
          (%o1)                       598987215

 -- Funktion: primep (<n>)

     Führt einen Primzahltest für das Argument <n> durch.  Liefert
     ‘primep’ das Ergebnis ‘false’, ist <n> keine Primzahl.  Ist das
     Ergebnis ‘true’, ist <n> mit sehr großer Wahrscheinlichkeit eine
     Primzahl.

     Für ganze Zahlen <n> kleiner als 341550071728321 wird eine
     deterministische Variante des Miller-Rabin-Tests angewandt.  Hat in
     diesem Fall ‘primep’ den Wert ‘true’, dann ist <n> mit Sicherheit
     eine Primzahl.

     Für ganze Zahlen <n> größer 341550071728321 führt ‘primep’
     ‘primep_number_of_tests’ Pseudo-Primzahl-Tests nach Miller-Rabin
     und einen Pseudo-Primzahl-Test nach Lucas durch.  Die
     Wahrscheinlichkeit, dass eine zusammen gesetzte Zahl <n> einen
     Miller-Rabin-Test besteht, ist kleiner als 1/4.  Mit dem
     Standardwert 25 ‘primpe_number_of_tests’ sinkt diese
     Wahrscheinlichkeit damit unter einen Wert von 10^-15.

 -- Optionsvariable: primep_number_of_tests
     Standardwert: 25

     Die Anzahl der Pseudo-Primzahl-Tests nach Miller-Rabin in der
     Funktion ‘primep’.

 -- Funktion: primes (<start>, <end>)

     Gibt eine Liste mit allen Primzahlen von <start> bis <end> zurück.

          (%i1) primes(3, 7);
          (%o1)                     [3, 5, 7]

 -- Funktion: prev_prime (<n>)

     Gibt die größte Primzahl zurück, die kleiner als die Zahl <n> ist.

          (%i1) prev_prime(27);
          (%o1)                       23

 -- Funktion: qunit (<n>)

     Findet für das Argument <n> Lösungen der Pellschen Gleichung ‘a^2 -
     <n> b^2 = 1’.

          (%i1) qunit (17);
          (%o1)                     sqrt(17) + 4
          (%i2) expand (% * (sqrt(17) - 4));
          (%o2)                           1

 -- Funktion: totient (<n>)

     Gibt die Anzahl der ganzen Zahlen zurück, die kleiner oder gleich
     <n> und teilerfremd zu <n> sind.

 -- Optionsvariable: zerobern
     Standardwert: ‘true’

     Hat ‘zerobern’ den Wert ‘false’, werden von den Funktionen ‘bern’
     diejenigen Bernoulli-Zahlen und von ‘euler’ diejenigen Euler-Zahlen
     ausgeschlossen, die gleich Null sind.  Siehe ‘bern’ und ‘euler’.

 -- Funktion: zeta (<n>)

     Die Riemannsche Zeta-Funktion für <s>, die wie folgt definiert ist:

                           inf
                           ====
                           \     1
               zeta(s) =    >    --
                           /      s
                           ====  k
                           k = 1

     Für negative ganze Zahlen <n>, Null und positive gerade ganze
     Zahlen wird ‘zeta’ zu einem exakten Ergebnis vereinfacht.  Damit
     diese Vereinfachung für positive ganze Zahlen ausgeführt wird, muss
     die Optionsvariable ‘zeta%pi’ den Wert ‘true’ haben.  Siehe
     ‘zeta%pi’.  Für einfache und beliebig genaue Gleitkommazahlen (Typ
     ‘bfloat’) hat ‘zeta’ ein numerisches Ergebnis.  Für alle anderen
     Argumente einschließlich der komplexen und rationalen Zahlen gibt
     ‘zeta’ eine Substantivform zurück.  Hat die Optionsvariable
     ‘zeta%pi’ den Wert ‘false’, gibt ‘zeta’ auch für gerade ganze
     Zahlen eine Substantivform zurück.

     ‘zeta(1)’ ist nicht definiert.  Maxima kennt jedoch die einseitigen
     Grenzwerte ‘limit(zeta(x), x, 1, plus’ und ‘limit(zeta(x), x, 1,
     minus’.

     Die Riemannsche Zeta-Funktion wird auf die Argumente von Listen,
     Matrizen und Gleichungen angewendet, wenn die Optionsvariable
     ‘distribute_over’ den Wert ‘true’ hat.

     Siehe auch ‘bfzeta’ und ‘zeta%pi’.

     Beispiele:

          (%i1) zeta([-2,-1,0,0.5,2,3,1+%i]);
                                                       2
                      1     1                       %pi
          (%o1) [0, - --, - -, - 1.460354508809586, ----, zeta(3),
                      12    2                        6
                                                              zeta(%i + 1)]
          (%i2) limit(zeta(x),x,1,plus);
          (%o2)                          inf
          (%i3) limit(zeta(x),x,1,minus);
          (%o3)                         minf

 -- Optionsvariable: zeta%pi
     Standardwert: ‘true’

     Hat ‘zeta%pi’ den Wert ‘true’, vereinfacht die Funktion ‘zeta(n)’
     für gerade ganzen Zahlen <n> zu einem Ergebnis, das proportional zu
     ‘%pi^n’ ist.  Ansonsten ist das Ergebnis von ‘zeta’ eine
     Substantivform für gerade ganze Zahlen.

     Beispiele:

          (%i1) zeta%pi: true$
          (%i2) zeta (4);
                                           4
                                        %pi
          (%o2)                         ----
                                         90
          (%i3) zeta%pi: false$
          (%i4) zeta (4);
          (%o4)                        zeta(4)

 -- Funktion: zn_add_table (<n>)

     zeigt eine Additionstabelle von allen Elementen in (Z/<n>Z).

     Siehe auch ‘zn_mult_table’, ‘zn_power_table’.

 -- Funktion: zn_characteristic_factors (<n>)

     Gibt eine Liste mit den charakteristischen Faktoren des Totienten
     von <n> zurück.

     Mit Hilfe der charakteristischen Faktoren kann eine modulo <n>
     multiplikative Gruppe als direktes Produkt zyklischer Untergruppen
     dargestellt werden.

     Ist die Gruppe selbst zyklisch, dann enthält die Liste nur den
     Totienten und mit ‘zn_primroot’ kann ein Generator berechnet
     werden.  Zerfällt der Totient in mehrere charakteristische
     Faktoren, können Generatoren der entsprechenden Untergruppen mit
     ‘zn_factor_generators’ ermittelt werden.

     Jeder der ‘r’ Faktoren in der Liste teilt die weiter rechts
     stehenden Faktoren.  Fuer den letzten Faktor ‘f_r’ gilt daher
     ‘a^f_r = 1 (mod n)’ für alle ‘a’ teilerfremd zu <n>.  Dieser Faktor
     ist auch als Carmichael Funktion bzw.  Carmichael Lambda bekannt.

     Für ‘n > 2’ ist ‘totient(n)/2^r’ die Anzahl der quadratischen Reste
     in der Gruppe und jeder dieser Reste hat ‘2^r’ Wurzeln.

     Siehe auch ‘totient’, ‘zn_primroot’, ‘zn_factor_generators’.

     Beispiele:

     Die multiplikative Gruppe modulo ‘14’ ist zyklisch und ihre ‘6’
     Elemente lassen sich durch eine Primitivwurzel erzeugen.

          (%i1) [zn_characteristic_factors(14), phi: totient(14)];
          (%o1)                              [[6], 6]
          (%i2) [zn_factor_generators(14), g: zn_primroot(14)];
          (%o2)                              [[3], 3]
          (%i3) M14: makelist(power_mod(g,i,14), i,0,phi-1);
          (%o3)                         [1, 3, 9, 13, 11, 5]

     Die multiplikative Gruppe modulo ‘15’ ist nicht zyklisch und ihre
     ‘8’ Elemente lassen sich mit Hilfe zweier Faktorgeneratoren
     erzeugen.

          (%i1) [[f1,f2]: zn_characteristic_factors(15), totient(15)];
          (%o1)                             [[2, 4], 8]
          (%i2) [[g1,g2]: zn_factor_generators(15), zn_primroot(15)];
          (%o2)                           [[11, 7], false]
          (%i3) UG1: makelist(power_mod(g1,i,15), i,0,f1-1);
          (%o3)                               [1, 11]
          (%i4) UG2: makelist(power_mod(g2,i,15), i,0,f2-1);
          (%o4)                            [1, 7, 4, 13]
          (%i5) M15: create_list(mod(i*j,15), i,UG1, j,UG2);
          (%o5)                      [1, 7, 4, 13, 11, 2, 14, 8]

     Für den letzten charakteristischen Faktor ‘4’ gilt ‘a^4 = 1 (mod
     15)’ fuer alle ‘a’ in ‘M15’.

     ‘M15’ hat ‘2’ charakteristische Faktoren und daher die ‘8/2^2’
     quadratischen Reste ‘1’ und ‘4’, und diese haben jeweils ‘2^2’
     Wurzeln.

          (%i6) zn_power_table(15);
                                         [ 1   1  1   1 ]
                                         [              ]
                                         [ 2   4  8   1 ]
                                         [              ]
                                         [ 4   1  4   1 ]
                                         [              ]
                                         [ 7   4  13  1 ]
          (%o6)                          [              ]
                                         [ 8   4  2   1 ]
                                         [              ]
                                         [ 11  1  11  1 ]
                                         [              ]
                                         [ 13  4  7   1 ]
                                         [              ]
                                         [ 14  1  14  1 ]
          (%i7) map(lambda([i], zn_nth_root(i,2,15)), [1,4]);
          (%o7)                   [[1, 4, 11, 14], [2, 7, 8, 13]]

 -- Funktion: zn_carmichael_lambda (<n>)

     Gibt ‘1’ zurück, wenn <n> gleich ‘1’ ist und andernfalls den
     größten charakteristischen Faktor des Totienten von <n>.

     Für Erläuterungen und Beispiele siehe ‘zn_characteristic_factors’.

 -- Funktion: zn_determinant (<matrix>, <p>)

     verwendet die Technik der LR-Dekomposition, um die Determinante der
     Matrix <matrix> über (Z/<p>Z) zu berechnen, wobei <p> eine Primzahl
     sein muss.

     Ist die Determinante nicht von Null verschieden, kann es sein, dass
     die LR-Dekomposition nicht möglich ist.  ‘zn_determinant’ berechnet
     diesem Fall die Determinante nicht-modular und reduziert im
     Nachhinein.

     Siehe auch ‘zn_invert_by_lu’.

     Beispiel:

          (%i1) m : matrix([1,3],[2,4]);
                                          [ 1  3 ]
          (%o1)                           [      ]
                                          [ 2  4 ]
          (%i2) zn_determinant(m, 5);
          (%o2)                               3
          (%i3) m : matrix([2,4,1],[3,1,4],[4,3,2]);
                                         [ 2  4  1 ]
                                         [         ]
          (%o3)                          [ 3  1  4 ]
                                         [         ]
                                         [ 4  3  2 ]
          (%i4) zn_determinant(m, 5);
          (%o4)                               0

 -- Funktion: zn_factor_generators (<n>)

     Gibt eine Liste mit Faktorgeneratoren zurück, die zu den
     charakteristischen Faktoren des Totienten von <n> passen.

     Für Erläuterungen und Beispiele siehe ‘zn_characteristic_factors’.

 -- Funktion: zn_invert_by_lu (<matrix>, <p>)

     verwendet die Technik der LR-Dekomposition, um ein modulares
     Inverses der Matrix <matrix> über (Z/<p>Z) zu berechnen.
     Voraussetzung ist, dass <matrix> invertierbar und <p> eine Primzahl
     ist.  Sollte <matrix> nicht invertierbar sein, gibt
     ‘zn_invert_by_lu’ ‘false’ zurc̈k.

     Siehe auch ‘zn_determinant’.

     Beispiele:

          (%i1) m : matrix([1,3],[2,4]);
                                          [ 1  3 ]
          (%o1)                           [      ]
                                          [ 2  4 ]
          (%i2) zn_determinant(m, 5);
          (%o2)                               3
          (%i3) mi : zn_invert_by_lu(m, 5);
                                          [ 3  4 ]
          (%o3)                           [      ]
                                          [ 1  2 ]
          (%i4) matrixmap(lambda([a], mod(a, 5)), m . mi);
                                          [ 1  0 ]
          (%o4)                           [      ]
                                          [ 0  1 ]

 -- Funktion: zn_log (<a>, <g>, <n>)
 -- Funktion: zn_log (<a>, <g>, <n>, [[<p1>, <e1>], …, [<pk>, <ek>]])

     Berechnet den diskreten Logarithmus.  Sei (Z/<n>Z)* eine zyklische
     Gruppe, <g> eine Primitivwurzel modulo <n> oder der Generator einer
     Untergruppe von (Z/<n>Z)* und <a> ein Element dieser Gruppe.  Dann
     berechnet ‘zn_log (a, g, n)’ eine Lösung der Kongruenz ‘g^x = a mod
     n’.  Man beachte, dass ‘zn_log’ nicht terminiert, falls <a> keine
     Potenz von <g> modulo <n> ist.

     Der verwendete Algorithmus benötigt die Primfaktorzerlegung von
     ‘zn_order(g)’ bzw.  des Totienten von <n>.  Da diese Berechnung
     ebenfalls zeitaufwändig ist, kann es eventuell sinnvoll sein, die
     Primfaktoren von ‘zn_order(g)’ vorab zu berechnen und ‘zn_log’ als
     viertes Argument zu übergeben.  Die Form muss dabei der Rückgabe
     von ‘ifactors(totient(n))’ mit der Standardeinstellung ‘false’ der
     Optionsvariable ‘factors_only’ entsprechen.  Verglichen mit der
     Laufzeit für die Berechnung des Logarithmus hat dies jedoch nur
     einen recht kleinen Effekt.

     Als Algorithmus wird die Pohlig-Hellman-Reduktion und das
     Rho-Verfahren von Pollard für den diskreten Logarithmus verwendet.
     Die Laufzeit von ‘zn_log’ hängt im Wesentlichen von der Bitlänge
     des größten Primfaktors des Totienten von <n> ab.

     Siehe auch ‘zn_primroot’, ‘zn_order’, ‘ifactors’, ‘totient’.

     Beispiele:

     ‘zn_log (a, g, n)’ findet eine Lösung der Kongruenz ‘g^x = a mod
     n’.

          (%i1) n : 22$
          (%i2) g : zn_primroot(n);
          (%o2)                               7
          (%i3) ord_7 : zn_order(7, n);
          (%o3)                              10
          (%i4) powers_7 : makelist(power_mod(g, x, n), x, 0, ord_7 - 1);
          (%o4)              [1, 7, 5, 13, 3, 21, 15, 17, 9, 19]
          (%i5) zn_log(9, g, n);
          (%o5)                               8
          (%i6) map(lambda([x], zn_log(x, g, n)), powers_7);
          (%o6)                [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
          (%i7) ord_5 : zn_order(5, n);
          (%o7)                               5
          (%i8) powers_5 : makelist(power_mod(5,x,n), x, 0, ord_5 - 1);
          (%o8)                       [1, 5, 3, 15, 9]
          (%i9) zn_log(9, 5, n);
          (%o9)                               4

     Das optionale vierte Argument muss der Rückgabe von
     ‘ifactors(totient(n))’ entsprechen.  Die Laufzeit hängt im
     Wesentlichen von der Bitlänge des größten Primfaktors von
     ‘zn_order(g)’ ab.

          (%i1) (p : 2^127-1, primep(p));
          (%o1)                             true
          (%i2) ifs : ifactors(p - 1)$
          (%i3) g : zn_primroot(p, ifs);
          (%o3)                              43
          (%i4) a : power_mod(g, 4711, p)$
          (%i5) zn_log(a, g, p, ifs);
          (%o5)                             4711
          (%i6) f_max : last(ifs);
          (%o6)                       [77158673929, 1]
          (%i7) ord_5 : zn_order(5,p,ifs)$
          (%i8) (p - 1)/ord_5;
          (%o8)                              73
          (%i9) ifs_5 : ifactors(ord_5)$
          (%i10) a : power_mod(5, 4711, p)$
          (%i11) zn_log(a, 5, p, ifs_5);
          (%o11)                            4711

 -- Funktion: zn_mult_table (<n>)
 -- Funktion: zn_mult_table (<n>, <gcd>)

     Ohne das optionale Argument <gcd> zeigt ‘zn_mult_table(n)’ eine
     Multiplikationstabelle von allen Elementen in (Z/<n>Z)*, d.h.  von
     allen zu <n> teilerfremden Elementen.

     Das optionale zweite Argument <gcd> erlaubt es, eine bestimmte
     Untermenge von (Z/<n>Z) auszuwählen.  Ist <gcd> eine natürliche
     Zahl, enthält die Multiplikationstabelle alle Restklassen ‘x’ mit
     ‘gcd(x,n) = ’<gcd>.  Zur besseren Lesbarkeit werden Zeilen- und
     Spaltenköpfe hinzugefügt.  Falls notwendig, lassen sich diese mit
     ‘submatrix(1, tabelle, 1)’ wieder einfach entfernen.

     Wird <gcd> auf ‘all’ gesetzt, wird die Tabelle für sämtliche von
     Null verschiedene Elemente in (Z/<n>Z) ausgegeben.

     Das zweite Beispiel unten zeigt einen alternativen Weg, für
     Untergruppen eine Multiplikationstabelle zu erzeugen.

     Siehe auch ‘zn_add_table’, ‘zn_power_table’.

     Beispiele:

     Die Standardtabelle zeigt alle Elemente aus (Z/<n>Z)* und erlaubt,
     grundlegende Eigenschaften von modularen Multiplikationsgruppen zu
     zeigen und zu studieren.  Z.B. stehen in der Hauptdiagonale
     sämtliche quadratische Reste, jede Zeile und Spalte enthält alle
     Elemente, die Tabelle ist symmetrisch, etc..

     Wird <gcd> auf ‘all’ gesetzt, wird die Tabelle für sämtliche von
     Null verschiedene Elemente in (Z/<n>Z) ausgegeben.

          (%i1) zn_mult_table(8);
                                          [ 1  3  5  7 ]
                                          [            ]
                                          [ 3  1  7  5 ]
          (%o1)                           [            ]
                                          [ 5  7  1  3 ]
                                          [            ]
                                          [ 7  5  3  1 ]
          (%i2) zn_mult_table(8, all);
                                      [ 1  2  3  4  5  6  7 ]
                                      [                     ]
                                      [ 2  4  6  0  2  4  6 ]
                                      [                     ]
                                      [ 3  6  1  4  7  2  5 ]
                                      [                     ]
          (%o2)                       [ 4  0  4  0  4  0  4 ]
                                      [                     ]
                                      [ 5  2  7  4  1  6  3 ]
                                      [                     ]
                                      [ 6  4  2  0  6  4  2 ]
                                      [                     ]
                                      [ 7  6  5  4  3  2  1 ]

     Ist <gcd> eine Zahl, wird zur besseren Lesbarkeit ein Zeilen- und
     Spaltenkopf hinzugefügt.

     Ist die mit <gcd> ausgewählte Teilmenge eine Gruppe, gibt es einen
     alternativen Weg, die Multiplikationstabelle zu erzeugen.  Die
     Isomorphie zu einer Gruppe mit ‘1’ als Identität lässt sich nutzen,
     um eine leicht lesbare Tabelle zu erhalten.  Die Abbildung gelingt
     mit dem CRT.

     In der so erzeugten zweiten Version der Tabelle ‘T36_4’ steht genau
     wie bei ‘T9’ die Identität, hier ‘28’, in der linken oberen Ecke.

          (%i1) T36_4: zn_mult_table(36,4);
                                  [ *   4   8   16  20  28  32 ]
                                  [                            ]
                                  [ 4   16  32  28  8   4   20 ]
                                  [                            ]
                                  [ 8   32  28  20  16  8   4  ]
                                  [                            ]
          (%o1)                   [ 16  28  20  4   32  16  8  ]
                                  [                            ]
                                  [ 20  8   16  32  4   20  28 ]
                                  [                            ]
                                  [ 28  4   8   16  20  28  32 ]
                                  [                            ]
                                  [ 32  20  4   8   28  32  16 ]
          (%i2) T9: zn_mult_table(36/4);
                                       [ 1  2  4  5  7  8 ]
                                       [                  ]
                                       [ 2  4  8  1  5  7 ]
                                       [                  ]
                                       [ 4  8  7  2  1  5 ]
          (%o2)                        [                  ]
                                       [ 5  1  2  7  8  4 ]
                                       [                  ]
                                       [ 7  5  1  8  4  2 ]
                                       [                  ]
                                       [ 8  7  5  4  2  1 ]
          (%i3) T36_4: matrixmap(lambda([x], chinese([0,x],[4,9])), T9);
                                    [ 28  20  4   32  16  8  ]
                                    [                        ]
                                    [ 20  4   8   28  32  16 ]
                                    [                        ]
                                    [ 4   8   16  20  28  32 ]
          (%o3)                     [                        ]
                                    [ 32  28  20  16  8   4  ]
                                    [                        ]
                                    [ 16  32  28  8   4   20 ]
                                    [                        ]
                                    [ 8   16  32  4   20  28 ]

 -- Funktion: zn_nth_root (<x>, <n>, <m>)
 -- Funktion: zn_nth_root (<x>, <n>, <m>, [[<p1>, <e1>], …, [<pk>,
          <ek>]])

     Gibt eine Liste mit allen <n>-ten Wurzeln von <x> aus der
     multiplikativen Untergruppe von (Z/<m>Z) zurück, in der sich <x>
     befindet, oder ‘false’, falls <x> keine <n>-te Potenz modulo <m>
     oder kein Element einer multiplikativen Untergruppe von (Z/<m>Z)
     ist.

     <x> ist Element einer multiplikativen Untergruppe modulo <m>, wenn
     der größte gemeinsame Teiler ‘g = gcd(x,m)’ zu ‘m/g’ teilerfremd
     ist.

     ‘zn_nth_root’ basiert auf einem Algorithmus von Adleman, Manders
     und Miller und Sätzen über modulare Multiplikationsgruppen von
     Daniel Shanks.

     Der Algorithmus benötigt eine Primfaktorzerlegung des Modulus <m>.
     Es kann eventuell sinnvoll sein, diese Zerlegung vorab zu berechnen
     und als viertes Argument zu übergeben.  Die Form muss dabei der
     Rückgabe von ‘ifactors(m)’ mit der Standardeinstellung ‘false’ der
     Optionsvariable ‘factors_only’ entsprechen.

     Beispiele:

     Eine Potenztabelle der multiplikativen Gruppe modulo ‘14’ gefolgt
     von einer Liste mit Listen von <n>-ten Wurzeln der ‘1’, wobei <n>
     von ‘1’ bis ‘6’ variiert.

          (%i1) zn_power_table(14);
                                   [ 1   1   1   1   1   1 ]
                                   [                       ]
                                   [ 3   9   13  11  5   1 ]
                                   [                       ]
                                   [ 5   11  13  9   3   1 ]
          (%o1)                    [                       ]
                                   [ 9   11  1   9   11  1 ]
                                   [                       ]
                                   [ 11  9   1   11  9   1 ]
                                   [                       ]
                                   [ 13  1   13  1   13  1 ]
          (%i2) makelist(zn_nth_root(1,n,14), n,1,6);
          (%o2)  [[1], [1, 13], [1, 9, 11], [1, 13], [1], [1, 3, 5, 9, 11, 13]]

     Im folgenden Beispiel ist <x> nicht zu <m> teilerfremd, aber es ist
     Element einer multiplikativen Untergruppe von (Z/<m>Z) und jede
     <n>-te Wurzel ist aus der selben Untergruppe.

     Die Restklasse ‘3’ ist kein Element in irgend einer multiplikativen
     Untergruppe von (Z/63Z) und wird daher nicht als dritte Wurzel von
     ‘27’ zurück gegeben.

     Hier zeigt ‘zn_power_table’ alle Reste ‘x’ in (Z/63Z) mit
     ‘gcd(x,63) = 9’.  Diese Untergruppe ist isomorph zu (Z/7Z)* und
     seine Identität ‘36’ wird mit Hilfe des CRT berechnet.

          (%i1) m: 7*9$

          (%i2) zn_power_table(m,9);
                                   [ 9   18  36  9   18  36 ]
                                   [                        ]
                                   [ 18  9   36  18  9   36 ]
                                   [                        ]
                                   [ 27  36  27  36  27  36 ]
          (%o2)                    [                        ]
                                   [ 36  36  36  36  36  36 ]
                                   [                        ]
                                   [ 45  9   27  18  54  36 ]
                                   [                        ]
                                   [ 54  18  27  9   45  36 ]
          (%i3) zn_nth_root(27,3,m);
          (%o3)                           [27, 45, 54]
          (%i4) id7:1$  id63_9: chinese([id7,0],[7,9]);
          (%o5)                                36

     Im folgenden RSA-ähnlichen Beispiel, in dem der Modulus ‘N’
     quadratfrei ist, d.h.  in paarweise verschiedene Primfaktoren
     zerfällt, ist jedes ‘x’ von ‘0’ bis ‘N-1’ in einer multiplikativen
     Untergruppe enthalten.

     Zur Entschlüsselung wird die ‘e’-te Wurzel berechnet.  ‘e’ ist
     teilerfremd zu ‘N’ und die ‘e’-te Wurzel ist deshalb eindeutig.
     ‘zn_nth_root’ wendet hier effektiv den als CRT-RSA bekannten
     Algorithmus an.  (Man beachte, dass ‘flatten’ Klammern entfernt und
     keine Lösungen.)

          (%i1) [p,q,e]: [5,7,17]$  N: p*q$

          (%i3) xs: makelist(x,x,0,N-1)$

          (%i4) ys: map(lambda([x],power_mod(x,e,N)),xs)$

          (%i5) zs: flatten(map(lambda([y], zn_nth_root(y,e,N)), ys))$

          (%i6) is(zs = xs);
          (%o6)                             true

     Im folgenden Beispiel ist die Faktorisierung des Modulus bekannt
     und wird als viertes Argument übergeben.

          (%i1) p: 2^107-1$  q: 2^127-1$  N: p*q$

          (%i4) ibase: obase: 16$

          (%i5) msg: 11223344556677889900aabbccddeeff$

          (%i6) enc: power_mod(msg, 10001, N);
          (%o6)    1a8db7892ae588bdc2be25dd5107a425001fe9c82161abc673241c8b383
          (%i7) zn_nth_root(enc, 10001, N, [[p,1],[q,1]]);
          (%o7)               [11223344556677889900aabbccddeeff]

 -- Funktion: zn_order (<x>, <n>)
 -- Funktion: zn_order (<x>, <n>, [[<p1>, <e1>], …, [<pk>, <ek>]])

     Ist <x> eine Einheit in der endlichen Gruppe (Z/<n>Z)*, so
     berechnet ‘zn_order’ die Ordnung dieses Elements.  Andernfalls gibt
     ‘zn_order’ ‘false’ zurück.  <x> ist eine Einheit modulo <n>, falls
     <x> teilerfremd zu <n> ist.

     Der verwendete Algorithmus benötigt die Primfaktorzerlegung des
     Totienten von <n>.  Da diese Berechnung manchmal recht
     zeitaufwändig ist, kann es eventuell sinnvoll sein, die
     Primfaktoren des Totienten vorab zu berechnen und ‘zn_order’ als
     drittes Argument zu übergeben.  Die Form muss dabei der Rückgabe
     von ‘ifactors(totient(n))’ mit der Standardeinstellung ‘false’ der
     Optionsvariable ‘factors_only’ entsprechen.

     Siehe auch ‘zn_primroot’, ‘ifactors’, ‘totient’.

     Beispiele:

     ‘zn_order’ berechnet die Ordnung einer Einheit <x> aus (Z/<n>Z)*.

          (%i1) n : 22$
          (%i2) g : zn_primroot(n);
          (%o2)                               7
          (%i3) units_22 : sublist(makelist(i,i,1,21), lambda([x], gcd(x, n) = 1));
          (%o3)              [1, 3, 5, 7, 9, 13, 15, 17, 19, 21]
          (%i4) (ord_7 : zn_order(7, n)) = totient(n);
          (%o4)                            10 = 10
          (%i5) powers_7 : makelist(power_mod(g,i,n), i,0,ord_7 - 1);
          (%o5)              [1, 7, 5, 13, 3, 21, 15, 17, 9, 19]
          (%i6) map(lambda([x], zn_order(x, n)), powers_7);
          (%o6)              [1, 10, 5, 10, 5, 2, 5, 10, 5, 10]
          (%i7) map(lambda([x], ord_7/gcd(x, ord_7)), makelist(i, i,0,ord_7 - 1));
          (%o7)              [1, 10, 5, 10, 5, 2, 5, 10, 5, 10]
          (%i8) totient(totient(n));
          (%o8)                               4

     Das optionale dritte Argument muss der Rückgabe von
     ‘ifactors(totient(n))’ entsprechen.

          (%i1) (p : 2^142 + 217, primep(p));
          (%o1)                             true
          (%i2) ifs : ifactors( totient(p) )$
          (%i3) g : zn_primroot(p, ifs);
          (%o3)                               3
          (%i4) is( (ord_3 : zn_order(g, p, ifs)) = totient(p) );
          (%o4)                             true
          (%i5) map(lambda([x], ord_3/zn_order(x, p, ifs)), makelist(i,i,2,15));
          (%o5)        [22, 1, 44, 10, 5, 2, 22, 2, 8, 2, 1, 1, 20, 1]

 -- Funktion: zn_power_table (<n>)
 -- Funktion: zn_power_table (<n>, <gcd>)
 -- Funktion: zn_power_table (<n>, <gcd>, <max_exp>)

     Ohne ein optionales Argument zeigt ‘zn_power_table(n)’ eine
     Potenzierungstabelle von allen Elementen in (Z/<n>Z)*, d.h.  von
     allen zu <n> teilerfremden Elementen.  Der Exponent variiert dabei
     jeweils zwischen ‘1’ und dem größten charakteristischen Faktor des
     Totienten von <n> (auch bekannt als Carmichael Funktion bzw.
     Carmichael Lambda), so dass die Tabelle rechts mit einer Spalte von
     Einsen endet.

     Das optionale zweite Argument <gcd> erlaubt es, eine bestimmte
     Untermenge von (Z/<n>Z) auszuwählen.  Ist <gcd> eine natürliche
     Zahl, werden Potenzen von allen Restklassen ‘x’ mit ‘gcd(x,n) =
     ’<gcd> zurück gegeben, d.h.  <gcd> ist standardmäßig ‘1’.  Wird
     <gcd> auf ‘all’ gesetzt, wird die Tabelle für sämtliche Elemente in
     (Z/<n>Z) ausgegeben.

     Wird das optionale dritte Argument <max_exp> angegeben, variiert
     der Exponent zwischen ‘1’ und <max_exp>.

     Siehe auch ‘zn_add_table’, ‘zn_mult_table’.

     Beispiele:

     Die Standardeinstellung <gcd>‘ = 1’ erlaubt es, grundlegende Sätze,
     wie die von Fermat and Euler, zu zeigen und zu betrachten.

     Das Argument <gcd> erlaubt es, bestimmte Teilmengen von (Z/<n>Z)
     auszuwählen und multiplikative Untergruppen und Isomorphismen zu
     untersuchen.

     Z.B. sind die Gruppen ‘G10’ und ‘G10_2’ unter der Multiplikation
     beide isomorph zu ‘G5’.  ‘1’ ist die Identität in ‘G5’.  So sind
     ‘1’ bzw.  ‘6’ die Identitäten in ‘G10’ bzw.  ‘G10_2’.
     Entsprechende Zuordnungen ergeben sich bei den Primitivwurzeln,
     n-ten Wurzeln, etc..

          (%i1) zn_power_table(10);
                                        [ 1  1  1  1 ]
                                        [            ]
                                        [ 3  9  7  1 ]
          (%o1)                         [            ]
                                        [ 7  9  3  1 ]
                                        [            ]
                                        [ 9  1  9  1 ]
          (%i2) zn_power_table(10,2);
                                        [ 2  4  8  6 ]
                                        [            ]
                                        [ 4  6  4  6 ]
          (%o2)                         [            ]
                                        [ 6  6  6  6 ]
                                        [            ]
                                        [ 8  4  2  6 ]
          (%i3) zn_power_table(10,5);
          (%o3)                         [ 5  5  5  5 ]
          (%i4) zn_power_table(10,10);
          (%o4)                         [ 0  0  0  0 ]
          (%i5) G5: [1,2,3,4];
          (%o6)                          [1, 2, 3, 4]
          (%i6) G10_2: map(lambda([x], chinese([0,x],[2,5])), G5);
          (%o6)                          [6, 2, 8, 4]
          (%i7) G10: map(lambda([x], power_mod(3, zn_log(x,2,5), 10)), G5);
          (%o7)                          [1, 3, 7, 9]

     Wird <gcd> auf ‘all’ gesetzt, wird die Tabelle für sämtliche
     Elemente in (Z/<n>Z) ausgegeben.

     Das dritte Argument <max_exp> erlaubt, den höchsten Exponenten zu
     wählen.  Die folgende Tabelle zeigt ein kleines RSA-Beispiel.

          (%i1) N:2*5$ phi:totient(N)$ e:7$ d:inv_mod(e,phi)$

          (%i5) zn_power_table(N, all, e*d);
                 [ 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 ]
                 [                                                               ]
                 [ 1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1 ]
                 [                                                               ]
                 [ 2  4  8  6  2  4  8  6  2  4  8  6  2  4  8  6  2  4  8  6  2 ]
                 [                                                               ]
                 [ 3  9  7  1  3  9  7  1  3  9  7  1  3  9  7  1  3  9  7  1  3 ]
                 [                                                               ]
                 [ 4  6  4  6  4  6  4  6  4  6  4  6  4  6  4  6  4  6  4  6  4 ]
          (%o5)  [                                                               ]
                 [ 5  5  5  5  5  5  5  5  5  5  5  5  5  5  5  5  5  5  5  5  5 ]
                 [                                                               ]
                 [ 6  6  6  6  6  6  6  6  6  6  6  6  6  6  6  6  6  6  6  6  6 ]
                 [                                                               ]
                 [ 7  9  3  1  7  9  3  1  7  9  3  1  7  9  3  1  7  9  3  1  7 ]
                 [                                                               ]
                 [ 8  4  2  6  8  4  2  6  8  4  2  6  8  4  2  6  8  4  2  6  8 ]
                 [                                                               ]
                 [ 9  1  9  1  9  1  9  1  9  1  9  1  9  1  9  1  9  1  9  1  9 ]

 -- Funktion: zn_primroot (<n>)
 -- Funktion: zn_primroot (<n>, [[<p1>, <e1>], …, [<pk>, <ek>]])

     Ist die multiplikative Gruppe (Z/<n>Z)* zyklisch, berechnet
     ‘zn_primroot’ die kleinste Primitivwurzel modulo <n>.  Dies ist der
     Fall, wenn <n> gleich ‘2’, ‘4’, ‘p^k’ oder ‘2*p^k’ ist, wobei ‘p’
     ungerade und prim und ‘k’ eine natürliche Zahl ist.  ‘zn_primroot’
     führt einen entsprechenden Prätest durch, wenn die Optionsvariable
     ‘zn_primroot_pretest’ (Standardwert: ‘false’) ‘true’ gesetzt wurde.
     In jedem Fall wird die Suche durch die obere Schranke
     ‘zn_primroot_limit’ begrenzt.

     Ist (Z/<n>Z)* nicht zyklisch oder kann bis ‘zn_primroot_limit’
     keine Primitivwurzel modulo <n> gefunden werden, gibt ‘zn_primroot’
     ‘false’ zurück.

     Der verwendete Algorithmus benötigt die Primfaktorzerlegung des
     Totienten von <n>.  Diese Berechnung kann zeitaufwändig sein und es
     kann daher eventuell sinnvoll sein, die Primfaktoren des Totienten
     vorab zu berechnen und ‘zn_primroot’ als zusätzliches Argument zu
     übergeben.  Die Form muss dabei der Rückgabe von
     ‘ifactors(totient(n))’ mit der Standardeinstellung ‘false’ der
     Optionsvariable ‘factors_only’ entsprechen.

     Siehe auch ‘zn_primroot_p’, ‘zn_order’, ‘ifactors’, ‘totient’.

     Beispiele:

     ‘zn_primroot’ berechnet die kleinste Primitivwurzel modulo <n> oder
     gibt ‘false’ zurück.

          (%i1) n : 14$
          (%i2) g : zn_primroot(n);
          (%o2)                               3
          (%i3) zn_order(g, n) = totient(n);
          (%o3)                             6 = 6
          (%i4) n : 15$
          (%i5) zn_primroot(n);
          (%o5)                             false

     Das optionale zweite Argument muss der Rückgabe von
     ‘ifactors(totient(n))’ entsprechen.

          (%i1) (p : 2^142 + 217, primep(p));
          (%o1)                             true
          (%i2) ifs : ifactors( totient(p) )$
          (%i3) g : zn_primroot(p, ifs);
          (%o3)                               3
          (%i4) [time(%o2), time(%o3)];
          (%o4)                    [[15.556972], [0.004]]
          (%i5) is(zn_order(g, p, ifs) = p - 1);
          (%o5)                             true
          (%i6) n : 2^142 + 216$
          (%i7) ifs : ifactors(totient(n))$
          (%i8) zn_primroot(n, ifs),
                zn_primroot_limit : 200, zn_primroot_verbose : true;
          `zn_primroot' stopped at zn_primroot_limit = 200
          (%o8)                             false

 -- Optionsvariable: zn_primroot_limit
     Standardwert: ‘1000’

     Definiert die obere Schranke für die Suche von ‘zn_primroot’ nach
     einer Primitivwurzel.  Wurde die Optionsvariable
     ‘zn_primroot_verbose’ (Standardwert: ‘false’) ‘true’ gesetzt, wird
     beim Erreichen von ‘zn_primroot_limit’ ein entsprechender Hinweis
     ausgegeben.

 -- Funktion: zn_primroot_p (<x>, <n>)
 -- Funktion: zn_primroot_p (<x>, <n>, [[<p1>, <e1>], …, [<pk>, <ek>]])

     Testet, ob <x> eine Primitivwurzel in der multiplikativen Gruppe
     (Z/<n>Z)* ist.

     Der verwendete Algorithmus benötigt die Primfaktorzerlegung des
     Totienten von <n>.  Wird dieser Test nacheinander auf mehrere
     Zahlen angewandt, kann es sinnvoll sein, die Primfaktoren des
     Totienten vorab zu berechnen und ‘zn_primroot_p’ als zusätzliches
     drittes Argument zu übergeben.  Die Form muss dabei der Rückgabe
     von ‘ifactors(totient(n))’ mit der Standardeinstellung ‘false’ der
     Optionsvariable ‘factors_only’ entsprechen.

     Siehe auch ‘zn_primroot’, ‘zn_order’, ‘ifactors’, ‘totient’.

     Beispiele:

     ‘zn_primroot_p’ als Prädikatfunktion.

          (%i1) n : 14$
          (%i2) units_14 : sublist(makelist(i,i,1,13), lambda([i], gcd(i, n) = 1));
          (%o2)                     [1, 3, 5, 9, 11, 13]
          (%i3) zn_primroot_p(13, n);
          (%o3)                            false
          (%i4) sublist(units_14, lambda([x], zn_primroot_p(x, n)));
          (%o4)                            [3, 5]
          (%i5) map(lambda([x], zn_order(x, n)), units_14);
          (%o5)                      [1, 6, 6, 3, 3, 2]

     Das optionale dritte Argument muss der Rückgabe von
     ‘ifactors(totient(n))’ entsprechen.

          (%i1) (p : 2^142 + 217, primep(p));
          (%o1)                             true
          (%i2) ifs : ifactors( totient(p) )$
          (%i3) sublist(makelist(i,i,1,50), lambda([x], zn_primroot_p(x, p, ifs)));
          (%o3)      [3, 12, 13, 15, 21, 24, 26, 27, 29, 33, 38, 42, 48]
          (%i4) [time(%o2), time(%o3)];
          (%o4)                   [[7.748484], [0.036002]]

 -- Optionsvariable: zn_primroot_pretest
     Standardwert: ‘false’

     Eine multiplikative Gruppe (Z/‘n’Z)* ist zyklisch, wenn ‘n’ gleich
     ‘2’, ‘4’, ‘p^k’ oder ‘2*p^k’ ist, wobei ‘p’ prim und größer ‘2’ und
     ‘k’ eine natürliche Zahl ist.

     ‘zn_primroot_pretest’ entscheidet darüber, ob ‘zn_primroot’ vor der
     Berechnung der kleinsten Primitivwurzel in (Z/‘n’Z)* überprüft, ob
     auf ‘n’ überhaupt einer der oben genannten Fälle zutrifft.  Nur
     wenn ‘zn_primroot_pretest’ ‘true’ ist, wird dieser Prätest
     ausgeführt.

 -- Optionsvariable: zn_primroot_verbose
     Standardwert: ‘false’

     Entscheidet, ob ‘zn_primroot’ beim Erreichen von
     ‘zn_primroot_limit’ einen Hinweis ausgibt.


File: maxima.info,  Node: Spezielle Funktionen,  Next: Fourier-Transformationen,  Prev: Zahlentheorie,  Up: Top

22 Spezielle Funktionen
***********************

* Menu:

* Einführung für spezielle Funktionen::
* Bessel-Funktionen und verwandte Funktionen::
* Gammafunktionen und verwandte Funktionen::
* Exponentielle Integrale::
* Fehlerfunktionen::
* Elliptische Funktionen und Integrale::
* Hypergeometrische Funktionen::
* Weitere spezielle Funktionen::


File: maxima.info,  Node: Einführung für spezielle Funktionen,  Next: Bessel-Funktionen und verwandte Funktionen,  Prev: Spezielle Funktionen,  Up: Spezielle Funktionen

22.1 Einführung für spezielle Funktionen
========================================

Spezielle Funktionen haben die folgenden Notationen:

     bessel_j (v, z)                Bessel-Funktion der 1. Art
     bessel_y (v, z)                Bessel-Funktion der 2. Art
     bessel_i (v, z)                Modifizierte Bessel-Funktion der 1. Art
     bessel_k (v, z)                Modifizierte Bessel-Funktion der 2. Art

     hankel_1 (v, z)                Hankel-Funktion der 1. Art
     hankel_2 (v, z)                Hankel-Funktion der 2. Art

     airy_ai (z)                    Airy-Funktion Ai(z)
     airy_bi (z)                    Airy-Funktion Bi(z)
     airy_dai (z)                   Ableitung der Airy-Funktion Ai(z)
     airy_dbi (z)                   Ableitung der Airy-Funktion Bi(z)

     struve_h (v, z)                Struve-Funktion H[v](z)
     struve_l (v, z)                Struve-Funktion L[v](z)

     %f[p,q] ([], [], z)            Hypergeometrische Funktion
     gamma()                        Gammafunktion
     gamma_incomplete_lower(a, z)   unvollständige Gamma-Funktion der unteren Grenze
     gammaincomplete(a,z)           unvollständige Gamma-Funktion
     hypergeometric(l1, l2, z)      Hypergeometrische Funktion

     %m[u,k] (z)                    Whittaker-Funktion der 1. Art
     %w[u,k] (z)                    Whittaker-Funktion der 2. Art

     erf (z)                        Fehlerfunktion
     erfc (z)                       Komplementäre Fehlerfunktion
     erfi (z)                       imaginäre Fehlerfunktion

     expintegral_e (v,z)            Exponentielles Integral E
     expintegral_e1 (z)             Exponentielles Integral E1
     expintegral_ei (z)             Exponentielles integral Ei
     expintegral_li (z)             Logarithmisches Integral Li
     expintegral_si (z)             Exponentielles Integral Si
     expintegral_ci (z)             Exponentielles Integral Ci
     expintegral_shi (z)            Exponentielles Integral Shi
     expintegral_chi (z)            Exponentielles Integral Chi

     parabolic_cylinder_d (v,z)     Parabolische Zylinderfunktion D


File: maxima.info,  Node: Bessel-Funktionen und verwandte Funktionen,  Next: Gammafunktionen und verwandte Funktionen,  Prev: Einführung für spezielle Funktionen,  Up: Spezielle Funktionen

22.2 Bessel-Funktionen und verwandte Funktionen
===============================================

* Menu:

* Bessel-Funktionen::
* Hankel-Funktionen::
* Airy-Funktionen::
* Struve-Funktionen::


File: maxima.info,  Node: Bessel-Funktionen,  Next: Hankel-Funktionen,  Prev: Bessel-Funktionen und verwandte Funktionen,  Up: Bessel-Funktionen und verwandte Funktionen

22.2.1 Bessel-Funktionen
------------------------

 -- Funktion: bessel_j (<v>, <z>)

     Die Bessel-Funktion der ersten Art der Ordnung v mit dem Argument
     z.  ‘bessel_j’ ist definiert als

                         inf
                         ====             k
                         \           (- 1)           z 2 k + v
                J (z) =   >    -------------------  (-)
                 v       /     k! gamma(v + k + 1)   2
                         ====
                         k = 0

     Die Reihenentwicklung wird nicht für die numerische Berechnung
     genutzt.

     Die Bessel-Funktion ‘bessel_j’ ist für das numerische und
     symbolische Rechnen geeignet.

     Maxima berechnet ‘bessel_j’ numerisch für reelle und komplexe
     Gleitkommazahlen als Argumente für v und z.  Mit der Funktion
     ‘float’ oder der Optionsvariablen ‘numer’ kann die numerische
     Auswertung erzwungen werden, wenn die Argumente ganze oder
     rationale Zahlen sind.  Die numerische Berechnung für große
     Gleitkommazahlen ist nicht implementiert.  In diesem Fall gibt
     Maxima eine Substantivform zurück.

     ‘bessel_j’ hat die folgenden Eigenschaften, die mit mit der
     Funktion ‘properties’ angezeigt werden und auf das symbolische
     Rechnen Einfluss haben:

     ‘conjugate function’
          ‘bessel_j’ hat Spiegelsymmetrie, wenn das Argument <z> keine
          negative reelle Zahl ist.  Die Spiegelsymmetrie wird zum
          Beispiel von der Funktion ‘conjugate’ für die Vereinfachung
          eines Ausdrucks genutzt.
     ‘complex characteristic’
          Maxima kennt den Realteil und den Imaginärteil von ‘bessel_j’
          für spezielle Argumente v und z.
     ‘limit function’
          Maxima kennt spezielle Grenzwerte der Funktion ‘bessel_j’.
     ‘integral’
          Maxima kennt das Integral der Funktion ‘bessel_j’ für die
          Integrationsvariable z.
     ‘gradef’
          Maxima kennt die Ableitungen der Funktion ‘bessel_j’ nach den
          Argumenten v und z.

     Die Vereinfachung der Bessel-Funktion ‘bessel_j’ wird von den
     folgenden Optionsvariablen kontrolliert:

     ‘distribute_over’
          Hat die Optionsvariable ‘distribute_over’ den Wert ‘true’ und
          sind die Argumente von ‘bessel_j’ eine Matrix, Liste oder
          Gleichung wird die Funktion auf die Elemente oder beiden
          Seiten der Gleichung angewendet.  Der Standardwert ist ‘true’.
     ‘besselexpand’
          Hat die Optionsvariable ‘besselexpand’ den Wert ‘true’, wird
          ‘bessel_j’ mit einer halbzahligen Ordnung v als Sinus- und
          Kosinusfunktionen entwickelt.
     ‘bessel_reduce’
          Hat die Optionsvariable ‘bessel_reduce’ den Wert ‘true’, wird
          ‘bessel_j’ mit einer ganzzahligen Ordnung n nach
          Bessel-Funktionen ‘bessel_j’ mit der niedrigsten Ordnung ‘0’
          und ‘1’ entwickelt.
     ‘hypergeometric_representation’
          Hat die Optionsvariable ‘hypergeometric_representation’ den
          Wert ‘true’, dann wird ‘bessel_j’ als hypergeometrische
          Funktion dargestellt.

     Weiterhin kennt Maxima die geraden und ungeraden
     Symmetrieeigenschaften von ‘bessel_j’.  Für eine ganze Zahl n
     vereinfacht daher ‘bessel_j(-n, z)’ zu ‘(-1)^n bessel_j(n, z)’.

     Maxima kennt noch die Funktion ‘spherical_bessel_j’, die im Paket
     ‘orthopoly’ definiert ist.  Siehe auch die anderen
     Bessel-Funktionen ‘bessel_y’, ‘bessel_i’ und ‘bessel_k’ sowie die
     weiteren mit den Bessel-Funktionen verwandten Funktionen wie die
     Hankel-Funktionen in *note Hankel-Funktionen::, Airy-Funktionen in
     *note Airy-Funktionen:: und Struve-Funktionen in *note
     Struve-Funktionen::.

     Beispiele:

     Numerisches Rechnen mit der Bessel-Funktion.  Für große
     Gleitkommazahlen ist die numerische Berechnung nicht implementiert.

          (%i1) bessel_j(1,[0.5, 0.5+%i]);
          (%o1) [.2422684576748739, .5124137767280905 %i
                                                       + .3392601907198862]
          (%i2) bessel_j(1,[0.5b0, 0.5b0+%i]);
          (%o2)    [bessel_j(1, 5.0b-1), bessel_j(1, %i + 5.0b-1)]

     Vereinfachungen der Bessel-Funktion mit den Optionsvariablen
     ‘besselexpand’ und ‘bessel_reduce’.

          (%i3) bessel_j(1/2,x), besselexpand:true;
                                   sqrt(2) sin(x)
          (%o3)                   -----------------
                                  sqrt(%pi) sqrt(x)
          (%i4) bessel_j(3,x), bessel_reduce:true;
                   2 bessel_j(1, x)
                4 (---------------- - bessel_j(0, x))
                          x
          (%o4) ------------------------------------- - bessel_j(1, x)
                                  x

     Ableitungen und Integrale der Bessel-Funktion.  Das letzte Beispiel
     zeigt die Laplace-Transformation der Bessel-Funktion mit der
     Funktion ‘laplace’.

          (%i5) diff(bessel_j(2,x), x);
                           bessel_j(1, x) - bessel_j(3, x)
          (%o5)            -------------------------------
                                          2
          (%i6) diff(bessel_j(v,x), x);
                       bessel_j(v - 1, x) - bessel_j(v + 1, x)
          (%o6)        ---------------------------------------
                                          2
          (%i7) integrate(bessel_j(v,x), x);
          (%o7)
                                                         2
                              v   1    v   3            x    - v - 1  v + 1
              hypergeometric([- + -], [- + -, v + 1], - --) 2        x
                              2   2    2   2            4
              -------------------------------------------------------------
                                   v   1
                                  (- + -) gamma(v + 1)
                                   2   2
          (%i8) laplace(bessel_j(2,t), t, s);
                                          1       2
                                (1 - sqrt(-- + 1))  s
                                           2
                                          s
          (%o8)                 ---------------------
                                         1
                                    sqrt(-- + 1)
                                          2
                                         s

     Bessel-Funktionen als Lösung einer linearen Differentialgleichung
     zweiter Ordnung.

          (%i1) depends(y, x);
          (%o1)                        [y(x)]
          (%i2) declare(n, integer);
          (%o2)                         done
          (%i3) 'diff(y, x, 2)*x^2 + 'diff(y, x)*x + y*(x^2-n^2) = 0;
                                          2
                               2    2    d y  2   dy
          (%o3)            y (x  - n ) + --- x  + -- x = 0
                                           2      dx
                                         dx
          (%i4) ode2(%, y, x);
          (%o4)      y = %k2 bessel_y(n, x) + %k1 bessel_j(n, x)

 -- Funktion: bessel_y (<v>, <z>)

     Die Bessel-Funktion der zweiten Art der Ordnung v mit dem Argument
     z.  ‘bessel_y’ ist definiert als

                        cos(%pi v) J (z) - J   (z)
                                    v       - v
                Y (z) = --------------------------
                 v              sin(%pi v)

     für den Fall, dass v keine ganze Zahl ist.  Ist v eine ganze Zahl
     n, dann wird die Bessel-Funktion ‘bessel_y’ wie folgt als ein
     Grenzwert definiert

                Y (z) = limit  Y (z)
                 n      v -> n  v

     Die Bessel-Funktion ‘bessel_y’ ist für das numerische und
     symbolische Rechnen geeignet.

     Maxima berechnet ‘bessel_y’ numerisch für reelle und komplexe
     Gleitkommazahlen als Argumente für v und z.  Mit der Funktion
     ‘float’ oder der Optionsvariablen ‘numer’ kann die numerische
     Auswertung erzwungen werden, wenn die Argumente ganze oder
     rationale Zahlen sind.  Die numerische Berechnung für große
     Gleitkommazahlen ist nicht implementiert.  In diesem Fall gibt
     Maxima eine Substantivform zurück.

     ‘bessel_y’ hat die folgenden Eigenschaften, die mit mit der
     Funktion ‘properties’ angezeigt werden und auf das symbolische
     Rechnen Einfluss haben:

     ‘conjugate function’
          ‘bessel_y’ hat Spiegelsymmetrie, wenn das Argument <z> keine
          negative reelle Zahl ist.  Die Spiegelsymmetrie wird zum
          Beispiel von der Funktion ‘conjugate’ für die Vereinfachung
          eines Ausdrucks genutzt.
     ‘complex characteristic’
          Maxima kennt den Realteil und den Imaginärteil von ‘bessel_y’
          für spezielle Argumente v und z.
     ‘limit function’
          Maxima kennt spezielle Grenzwerte der Funktion ‘bessel_y’.
     ‘integral’
          Maxima kennt das Integral der Funktion ‘bessel_y’ für die
          Integrationsvariable z.
     ‘gradef’
          Maxima kennt die Ableitungen der Funktion ‘bessel_y’ nach den
          Argumenten v und z.

     Die Vereinfachung der Bessel-Funktion ‘bessel_y’ wird von den
     folgenden Optionsvariablen kontrolliert:

     ‘distribute_over’
          Hat die Optionsvariable ‘distribute_over’ den Wert ‘true’ und
          sind die Argumente von ‘bessel_y’ eine Matrix, Liste oder
          Gleichung wird die Funktion auf die Elemente oder beiden
          Seiten der Gleichung angewendet.  Der Standardwert ist ‘true’.
     ‘besselexpand’
          Hat die Optionsvariable ‘besselexpand’ den Wert ‘true’, wird
          ‘bessel_y’ mit einer halbzahligen Ordnung v als Sinus- und
          Kosinusfunktionen entwickelt.
     ‘bessel_reduce’
          Hat die Optionsvariable ‘bessel_reduce’ den Wert ‘true’, wird
          ‘bessel_y’ mit einer ganzzahligen Ordnung n nach
          Bessel-Funktionen ‘bessel_y’ mit der niedrigsten Ordnung ‘0’
          und ‘1’ entwickelt.
     ‘hypergeometric_representation’
          Hat die Optionsvariable ‘hypergeometric_representation’ den
          Wert ‘true’, dann wird ‘bessel_y’ als hypergeometrische
          Funktion dargestellt.  Es ist zu beachten, dass die
          hypergeometrische Funktion nur für eine nicht ganzzahlige
          Ordnung v gültig ist.

     Weiterhin kennt Maxima die geraden und ungeraden
     Symmetrieeigenschaften von ‘bessel_y’.  Für eine ganze Zahl n
     vereinfacht daher ‘bessel_y(-n, z)’ zu ‘(-1)^n bessel_y(n, z)’.

     Maxima kennt noch die Funktion ‘spherical_bessel_y’, die im Paket
     ‘orthopoly’ definiert ist.  Siehe auch die anderen
     Bessel-Funktionen ‘bessel_j’, ‘bessel_i’ und ‘bessel_k’ sowie die
     weiteren mit den Bessel-Funktionen verwandten Funktionen wie die
     Hankel-Funktionen in *note Hankel-Funktionen::, Airy-Funktionen in
     *note Airy-Funktionen:: und Struve-Funktionen in *note
     Struve-Funktionen::.

     Siehe die Funktion ‘bessel_j’ für Beispiele mit Bessel-Funktionen.

 -- Funktion: bessel_i (<v>, <z>)

     Die modifizierte Bessel-Funktion der ersten Art der Ordnung v mit
     dem Argument v.  ‘bessel_i’ ist definiert als

                         inf
                         ====
                         \              1            z 2 k + v
                I (z) =   >    -------------------  (-)
                 v       /     k! gamma(v + k + 1)   2
                         ====
                         k = 0

     Die Reihenentwicklung wird nicht für die numerische Berechnung
     genutzt.

     Die Bessel-Funktion ‘bessel_i’ ist für das numerische und
     symbolische Rechnen geeignet.

     Maxima berechnet ‘bessel_i’ numerisch für reelle und komplexe
     Gleitkommazahlen als Argumente für v und z.  Mit der Funktion
     ‘float’ oder der Optionsvariablen ‘numer’ kann die numerische
     Auswertung erzwungen werden, wenn die Argumente ganze oder
     rationale Zahlen sind.  Die numerische Berechnung für große
     Gleitkommazahlen ist nicht implementiert.  In diesem Fall gibt
     Maxima eine Substantivform zurück.

     ‘bessel_i’ hat die folgenden Eigenschaften, die mit mit der
     Funktion ‘properties’ angezeigt werden und auf das symbolische
     Rechnen Einfluss haben:

     ‘conjugate function’
          ‘bessel_i’ hat Spiegelsymmetrie, wenn das Argument <z> keine
          negative reelle Zahl ist.  Die Spiegelsymmetrie wird zum
          Beispiel von der Funktion ‘conjugate’ für die Vereinfachung
          eines Ausdrucks genutzt.
     ‘complex characteristic’
          Maxima kennt den Realteil und den Imaginärteil von ‘bessel_i’
          für spezielle Argumente v und z.
     ‘limit function’
          Maxima kennt spezielle Grenzwerte der Funktion ‘bessel_i’.
     ‘integral’
          Maxima kennt das Integral der Funktion ‘bessel_i’ für die
          Integrationsvariable z.
     ‘gradef’
          Maxima kennt die Ableitungen der Funktion ‘bessel_i’ nach den
          Argumenten v und z.

     Die Vereinfachung der Bessel-Funktion ‘bessel_i’ wird von den
     folgenden Optionsvariablen kontrolliert:

     ‘distribute_over’
          Hat die Optionsvariable ‘distribute_over’ den Wert ‘true’ und
          sind die Argumente von ‘bessel_i’ eine Matrix, Liste oder
          Gleichung wird die Funktion auf die Elemente oder beiden
          Seiten der Gleichung angewendet.  Der Standardwert ist ‘true’.
     ‘besselexpand’
          Hat die Optionsvariable ‘besselexpand’ den Wert ‘true’, wird
          ‘bessel_i’ mit einer halbzahligen Ordnung v als
          Hyperbelfunktionen entwickelt.
     ‘bessel_reduce’
          Hat die Optionsvariable ‘bessel_reduce’ den Wert ‘true’, wird
          ‘bessel_i’ mit einer ganzzahligen Ordnung n nach
          Bessel-Funktionen ‘bessel_i’ mit der niedrigsten Ordnung ‘0’
          und ‘1’ entwickelt.
     ‘hypergeometric_representation’
          Hat die Optionsvariable ‘hypergeometric_representation’ den
          Wert ‘true’, dann wird ‘bessel_i’ als hypergeometrische
          Funktion dargestellt.

     Weiterhin kennt Maxima die geraden und ungeraden
     Symmetrieeigenschaften von ‘bessel_i’.  Für eine ganze Zahl n
     vereinfacht daher ‘bessel_i(-n, z)’ zu ‘bessel_i(n, z)’.

     Siehe auch die anderen Bessel-Funktionen ‘bessel_j’, ‘bessel_y’ und
     ‘bessel_k’ sowie die weiteren mit den Bessel-Funktionen verwandten
     Funktionen wie die Hankel-Funktionen in *note Hankel-Funktionen::,
     Airy-Funktionen in *note Airy-Funktionen:: und Struve-Funktionen in
     *note Struve-Funktionen::.

     Siehe die Funktion ‘bessel_j’ für Beispiele mit Bessel-Funktionen.

 -- Funktion: bessel_k (<v>, <z>)

     Die modifizierte Bessel-Funktion der zweiten Art der Ordnung v mit
     dem Argument z.  ‘bessel_k’ ist definiert als

                        %pi csc(%pi u) (I   (z) - I (z))
                                         - v       u
                K (z) = --------------------------------
                 v                     2

     für den Fall, dass v keine ganze Zahl ist.  Ist v eine ganze Zahl
     n, dann wird die Bessel-Funktion ‘bessel_k’ wie folgt als Grenzwert
     definiert

          (%o5) K (z) = limit  K (z)
                 n      v -> n  v

     Die Bessel-Funktion ‘bessel_k’ ist für das numerische und
     symbolische Rechnen geeignet.

     Maxima berechnet ‘bessel_k’ numerisch für reelle und komplexe
     Gleitkommazahlen als Argumente für v und z.  Mit der Funktion
     ‘float’ oder der Optionsvariablen ‘numer’ kann die numerische
     Auswertung erzwungen werden, wenn die Argumente ganze oder
     rationale Zahlen sind.  Die numerische Berechnung für große
     Gleitkommazahlen ist nicht implementiert.  In diesem Fall gibt
     Maxima eine Substantivform zurück.

     ‘bessel_k’ hat die folgenden Eigenschaften, die mit mit der
     Funktion ‘properties’ angezeigt werden und auf das symbolische
     Rechnen Einfluss haben:

     ‘conjugate function’
          ‘bessel_k’ hat Spiegelsymmetrie, wenn das Argument <z> keine
          negative reelle Zahl ist.  Die Spiegelsymmetrie wird zum
          Beispiel von der Funktion ‘conjugate’ für die Vereinfachung
          eines Ausdrucks genutzt.
     ‘complex characteristic’
          Maxima kennt den Realteil und den Imaginärteil von ‘bessel_k’
          für spezielle Argumente v und z.
     ‘limit function’
          Maxima kennt spezielle Grenzwerte der Funktion ‘bessel_k’.
     ‘integral’
          Maxima kennt das Integral der Funktion ‘bessel_k’ für die
          Integrationsvariable z.
     ‘gradef’
          Maxima kennt die Ableitungen der Funktion ‘bessel_k’ nach den
          Argumenten v und z.

     Die Vereinfachung der Bessel-Funktion ‘bessel_k’ wird von den
     folgenden Optionsvariablen kontrolliert:

     ‘distribute_over’
          Hat die Optionsvariable ‘distribute_over’ den Wert ‘true’ und
          sind die Argumente von ‘bessel_k’ eine Matrix, Liste oder
          Gleichung wird die Funktion auf die Elemente oder beiden
          Seiten der Gleichung angewendet.  Der Standardwert ist ‘true’.
     ‘besselexpand’
          Hat die Optionsvariable ‘besselexpand’ den Wert ‘true’, wird
          ‘bessel_k’ mit einer halbzahligen Ordnung v als
          Exponentialfunktion entwickelt.
     ‘bessel_reduce’
          Hat die Optionsvariable ‘bessel_reduce’ den Wert ‘true’, wird
          ‘bessel_k’ mit einer ganzzahligen Ordnung n nach
          Bessel-Funktionen ‘bessel_k’ mit der niedrigsten Ordnung ‘0’
          und ‘1’ entwickelt.
     ‘hypergeometric_representation’
          Hat die Optionsvariable ‘hypergeometric_representation’ den
          Wert ‘true’, dann wird ‘bessel_k’ als hypergeometrische
          Funktion dargestellt.  Es ist zu beachten, dass die
          hypergeometrische Funktion nur für eine nicht ganzzahlige
          Ordnung v gültig ist.

     Weiterhin kennt Maxima die geraden und ungeraden
     Symmetrieeigenschaften von ‘bessel_k’.  Für eine ganze Zahl n
     vereinfacht daher ‘bessel_k(-n, z)’ zu ‘bessel_y(n, z)’.

     Siehe auch die anderen Bessel-Funktionen ‘bessel_j’, ‘bessel_y’ und
     ‘bessel_i’ sowie die weiteren mit den Bessel-Funktionen verwandten
     Funktionen wie die Hankel-Funktionen in *note Hankel-Funktionen::,
     Airy-Funktionen in *note Airy-Funktionen:: und Struve-Funktionen in
     *note Struve-Funktionen::.

     Siehe die Funktion ‘bessel_j’ für Beispiele mit Bessel-Funktionen.

 -- Optionsvariable: bessel_reduce
     Standardwert: ‘false’

     Hat die Optionsvariable ‘bessel_reduce’ den Wert ‘true’, werden
     Bessel-Funktionen mit einer ganzzahligen Ordnung n nach
     Bessel-Funktionen mit der niedrigsten Ordnung 0 und 1 entwickelt.

 -- Optionsvariable: besselexpand
     Standardwert: ‘false’

     Hat die Optionsvariable ‘besselexpand’ den Wert ‘true’, werden
     Bessel-Funktion mit einer halbzahligen Ordnung v als Sinus-,
     Kosinus-, Hyperbel- oder Exponentialfunktionen entwickelt.  Die
     Optionsvariable ‘besselexpand’ kontrolliert auch die Entwicklung
     der Hankel-Funktionen ‘hankel_1’ und ‘hankel_2’ sowie der
     Struve-Funktionen ‘struve_h’ und ‘struve_l’.

     Beispiele:

          (%i1) besselexpand: false$

          (%i2) bessel_j(3/2, z);
                                            3
          (%o2)                    bessel_j(-, z)
                                            2
          (%i3) besselexpand: true$

          (%i4) bessel_j(3/2, z);
                                           sin(z)   cos(z)
                          sqrt(2) sqrt(z) (------ - ------)
                                              2       z
                                             z
          (%o4)           ---------------------------------
                                      sqrt(%pi)

     Weitere Beispiele für die Entwicklungen der Funktionen ‘bessel_k’
     und ‘struve_h’.

          (%i5) bessel_k(3/2, z);
                                          1        - z
                               sqrt(%pi) (- + 1) %e
                                          z
          (%o5)                -----------------------
                                   sqrt(2) sqrt(z)

          (%i6) struve_h(3/2, z);
                                                     2
                            2 z sin(z) + 2 cos(z) - z  - 2
          (%o6)           - ------------------------------
                                                   3/2
                                sqrt(2) sqrt(%pi) z

 -- Funktion: scaled_bessel_i (<v>, <z>)

     Die skalierte modifizierte Bessel-Funktion der ersten Art der
     Ordnung v mit dem Argument z.  Diese ist definiert als

                                                          - abs(z)
                scaled_bessel_i(v, z) = bessel_i(v, z) %e

     ‘scaled_bessel_i’ liefert ein numerisches Ergebnis, wenn die
     Argumente v und z Zahlen sind.  Die Funktion kann geeignet sein,
     wenn ‘bessel_i’ für große Argumente z numerisch berechnet werden
     soll.  Ganze, rationale oder große Gleitkommazahlen werden in
     Gleitkommazahlen mit doppelter Genauigkeit umgewandelt.  Sind die
     Argumente keine Zahlen, wird ein vereinfachter Ausdruck mit der
     Funktion ‘bessel_i’ zurückgegeben.

     ‘scaled_bessel_i’ ist eine Verbfunktion, die nicht für das
     symbolische Rechnen geeignet ist.  Für das symbolische Rechnen ist
     die Funktion ‘bessel_i’ zu verwenden.

     Beispiele:

          (%i1) scaled_bessel_i(1, 50);
          (%o1)                  .05599312389289544
          (%i2) scaled_bessel_i(1/2, 50);
          (%o2)                  .05641895835477567
          (%i3) scaled_bessel_i(v, x);
                                               - abs(x)
          (%o3)               bessel_i(v, x) %e

 -- Funktion: scaled_bessel_i0 (<z>)

     Entspricht ‘scaled_bessel_i(0,z)’.  Siehe ‘scaled_bessel_i’.

 -- Funktion: scaled_bessel_i1 (<z>)

     Entspricht ‘scaled_bessel_i(1,z)’.  Siehe ‘scaled_bessel_i’.


File: maxima.info,  Node: Hankel-Funktionen,  Next: Airy-Funktionen,  Prev: Bessel-Funktionen,  Up: Bessel-Funktionen und verwandte Funktionen

22.2.2 Hankel-Funktionen
------------------------

 -- Funktion: hankel_1 (<v>, <z>)

     Die Hankel-Funktion der ersten Art der Ordnung v mit dem Argument
     z.  Siehe A & S 9.1.3.  ‘hankel_1’ ist definiert als

                H1 (z) = J (z) + %i Y (z)
                  v       v          v

     Die Hankel-Funktion ‘hankel_1’ ist für das numerische und
     symbolische Rechnen geeignet.

     Maxima berechnet ‘hankel_1’ numerisch für reelle und komplexe
     Gleitkommazahlen als Argumente für v und z.  Mit der Funktion
     ‘float’ oder der Optionsvariablen ‘numer’ kann die numerische
     Auswertung erzwungen werden, wenn die Argumente Zahlen sind.  Die
     numerische Berechnung für große Gleitkommazahlen ist nicht
     implementiert.  In diesem Fall gibt Maxima eine Substantivform
     zurück.

     Hat die Optionsvariable ‘besselexpand’ den Wert ‘true’, werden
     Hankel-Funktionen ‘hankel_1’ mit einer halbzahligen Ordnung v als
     Sinus- und Kosinusfunktionen entwickelt.

     Maxima kennt die Ableitung der Hankel-Funktion ‘hankel_1’ nach dem
     zweiten Argument ‘z’.

     Siehe auch die Funktion ‘hankel_2’ sowie die Bessel-Funktionen in
     *note Bessel-Funktionen::.

     Beispiele:

     Numerische Berechnung.

          (%i1) hankel_1(1, 0.5);
          (%o1)       .2422684576748738 - 1.471472392670243 %i
          (%i2) hankel_1(1, 0.5+%i);
          (%o2)      - .2558287994862166 %i - 0.239575601883016

     Für eine komplex Ordnung kann Maxima keinen numerischen Wert
     berechnet.  Das Ergebnis ist eine Substantivform.

          (%i3) hankel_1(%i, 0.5+%i);
          (%o3)                hankel_1(%i, %i + 0.5)

     Entwicklung der Hankel-Funktion ‘hankel_1’, wenn die
     Optionsvariable ‘besselexpand’ den Wert ‘true’ hat.

          (%i4) hankel_1(1/2, z), besselexpand:true;
                         sqrt(2) sin(z) - sqrt(2) %i cos(z)
          (%o4)          ----------------------------------
                                 sqrt(%pi) sqrt(z)

     Ableitung der Hankel-Funktion ‘hankel_1’ nach dem Argument <z>.
     Die Ableitung nach der Ordnung <v> ist nicht implementiert.  Maxima
     gibt eine Substantivform zurück.

          (%i5)  diff(hankel_1(v,z), z);
                       hankel_1(v - 1, z) - hankel_1(v + 1, z)
          (%o5)        ---------------------------------------
                                          2
          (%i6)  diff(hankel_1(v,z), v);
                                 d
          (%o6)                  -- (hankel_1(v, z))
                                 dv

 -- Funktion: hankel_2 (<v>, <z>)

     Die Hankel-Funktion der zweiten Art der Ordnung v mit dem Argument
     z.  Siehe A & S 9.1.4.  ‘hankel_2’ ist definiert als

                H2 (z) = J (z) - %i Y (z)
                  v       v          v

     Die Hankel-Funktion ‘hankel_2’ ist für das numerische und
     symbolische Rechnen geeignet.

     Maxima berechnet ‘hankel_2’ numerisch für reelle und komplexe
     Gleitkommazahlen als Argumente für v und z.  Mit der Funktion
     ‘float’ oder der Optionsvariablen ‘numer’ kann die numerische
     Auswertung erzwungen werden, wenn die Argumente Zahlen sind.  Die
     numerische Berechnung für große Gleitkommazahlen ist nicht
     implementiert.  In diesem Fall gibt Maxima eine Substantivform
     zurück.

     Hat die Optionsvariable ‘besselexpand’ den Wert ‘true’, werden
     Hankel-Funktionen ‘hankel_2’ mit einer halbzahligen Ordnung v als
     Sinus- und Kosinusfunktionen entwickelt.

     Maxima kennt die Ableitung der Hankel-Funktion ‘hankel_2’ nach dem
     zweiten Argument ‘z’.

     Für Beispiele siehe ‘hankel_1’.  Siehe auch die Bessel-Funktionen
     in *note Bessel-Funktionen::.


File: maxima.info,  Node: Airy-Funktionen,  Next: Struve-Funktionen,  Prev: Hankel-Funktionen,  Up: Bessel-Funktionen und verwandte Funktionen

22.2.3 Airy-Funktionen
----------------------

Die Airy-Funktionen Ai(z) und Bi(z) sind definiert in Abramowitz und
Stegun, Handbook of Mathematical Functions, Kapitel 10.4.  Die
Funktionen ‘y = Ai(z)’ und ‘y = Bi(z)’ sind zwei linear unabhängige
Lösungen der Airy-Differentialgleichung.

            2
           d y
           --- - y z = 0
             2
           dz

 -- Funktion: airy_ai (<z>)

     Die Airy-Funktion Ai(z) (A & S 10.4.2).

     Die Airy-Funktion ‘airy_ai’ ist für das symbolische und numerische
     Rechnen geeignet.  Ist das Argument ‘z’ eine reelle oder komplexe
     Gleitkommazahl, wird ‘airy_ai’ numerisch berechnet.  Mit der
     Optionsvariablen ‘numer’ oder der Funktion ‘float’ kann die
     numerische Berechnung erzwungen werden, wenn das Argument eine
     ganze oder rationale Zahl ist.  Die numerische Berechnung für große
     Gleitkommazahlen ist nicht implementiert.

     Maxima kennt den speziellen Wert für das Argument ‘0’.

     Ist das Argument eine Liste, Matrix oder Gleichung wird die
     Funktion ‘airy_ai’ auf die Elemente der Liste oder beide Seiten der
     Gleichung angewendet.  Siehe auch ‘distribute_over’.

     Die Ableitung ‘diff(airy_ai(z), z)’ ist als ‘airy_dai(z)’
     implementiert.  Siehe die Funktion ‘airy_dai’.

     Weiterhin kennt Maxima das Integral der Airy-Funktion ‘airy_ai’.

     Siehe auch die Funktionen ‘airy_bi’ und ‘airy_dbi’.

     Beispiele:

     Numerische Berechnung für Gleitkommazahlen.  Für ganze und
     rationale Zahlen wird eine Substantivform zurückgegeben.  Maxima
     kennt den speziellen Wert für das Argument ‘0’.

          (%i1) airy_ai([0.5, 1.0+%i]);
          (%o1) [.2316936064808335, .06045830837183824
                                                    - .1518895658771814 %i]
          (%i2) airy_ai([1, 1/2]);
                                                   1
          (%o2)               [airy_ai(1), airy_ai(-)]
                                                   2
          (%i3) airy_ai(0);
                                          1
          (%o3)                     -------------
                                     2/3       2
                                    3    gamma(-)
                                               3

     Ableitungen und Integral der Airy-Funktion ‘airy_ai’.

          (%i4) diff(airy_ai(z), z);
          (%o4)                      airy_dai(z)
          (%i5) diff(airy_ai(z), z, 2);
          (%o5)                     z airy_ai(z)
          (%i6) diff(airy_ai(z), z, 3);
          (%o6)              z airy_dai(z) + airy_ai(z)
          (%i7) integrate(airy_ai(z), z);
                                             3
                                1    2  4   z
                hypergeometric([-], [-, -], --) z
                                3    3  3   9
          (%o7) ---------------------------------
                           2/3       2
                          3    gamma(-)
                                     3
                                                                      3
                            1/6       2                  2    4  5   z    2
                           3    gamma(-) hypergeometric([-], [-, -], --) z
                                      3                  3    3  3   9
                         - ------------------------------------------------
                                                4 %pi

 -- Funktion: airy_dai (<z>)

     Die Ableitung der Airy-Funktion ‘airy_ai’.

     Die Ableitung der Airy-Funktion ‘airy_dai’ ist für das symbolische
     und numerische Rechnen geeignet.  Ist das Argument <z> eine reelle
     oder komplexe Gleitkommazahl, wird ‘airy_dai’ numerisch berechnet.
     Mit der Optionsvariablen ‘numer’ oder der Funktion ‘float’ kann die
     numerische Berechnung erzwungen werden, wenn das Argument eine
     ganze oder rationale Zahl ist.  Die numerische Berechnung für große
     Gleitkommazahlen ist nicht implementiert.

     Maxima kennt den speziellen Wert für das Argument ‘0’.

     Ist das Argument eine Liste, Matrix oder Gleichung wird die
     Funktion ‘airy_dai’ auf die Elemente der Liste oder beide Seiten
     der Gleichung angewendet.  Siehe auch ‘distribute_over’.

     Maxima kennt die Ableitung und das Integral der Funktion
     ‘airy_dai’.

     Siehe auch die Airy-Funktionen ‘airy_bi’ und ‘airy_dbi’.

     Für Beispiele siehe die Funktion ‘airy_ai’.

 -- Funktion: airy_bi (<z>)

     Die Airy-Funktion Bi(z) (A & S 10.4.3).

     Die Airy-Funktion ‘airy_bi’ ist für das symbolische und numerische
     Rechnen geeignet.  Ist das Argument ‘z’ eine reelle oder komplexe
     Gleitkommazahl, wird ‘airy_bi’ numerisch berechnet.  Mit der
     Optionsvariablen ‘numer’ oder der Funktion ‘float’ kann die
     numerische Berechnung erzwungen werden, wenn das Argument eine
     ganze oder rationale Zahl ist.  Die numerische Berechnung für große
     Gleitkommazahlen ist nicht implementiert.

     Maxima kennt den speziellen Wert für das Argument ‘0’.

     Ist das Argument eine Liste, Matrix oder Gleichung wird die
     Funktion ‘airy_bi’ auf die Elemente der Liste oder beide Seiten der
     Gleichung angewendet.  Siehe auch ‘distribute_over’.

     Die Ableitung ‘diff(airy_bi(z), z)’ ist als ‘airy_dbi(z)’
     implementiert.  Siehe die Funktion ‘airy_dbi’.

     Weiterhin kennt Maxima das Integral der Airy-Funktion ‘airy_bi’.

     Siehe auch die Funktionen ‘airy_ai’ und ‘airy_dai’.

     Für Beispiele siehe die Funktion ‘airy_ai’.

 -- Funktion: airy_dbi (<z>)

     Die Ableitung der Airy-Funktion ‘airy_bi’.

     Die Ableitung der Airy-Funktion ‘airy_dbi’ ist für das symbolische
     und numerische Rechnen geeignet.  Ist das Argument <z> eine reelle
     oder komplexe Gleitkommazahl, wird ‘airy_dbi’ numerisch berechnet.
     Mit der Optionsvariablen ‘numer’ oder der Funktion ‘float’ kann die
     numerische Berechnung erzwungen werden, wenn das Argument eine
     ganze oder rationale Zahl ist.  Die numerische Berechnung für große
     Gleitkommazahlen ist nicht implementiert.

     Maxima kennt den speziellen Wert für das Argument ‘0’.

     Ist das Argument eine Liste, Matrix oder Gleichung wird die
     Funktion ‘airy_dbi’ auf die Elemente der Liste oder beide Seiten
     der Gleichung angewendet.  Siehe auch ‘distribute_over’.

     Maxima kennt die Ableitung und das Integral der Funktion
     ‘airy_dbi’.

     Siehe auch die Airy-Funktionen ‘airy_ai’ und ‘airy_dai’.

     Für Beispiele siehe die Funktion ‘airy_ai’.


File: maxima.info,  Node: Struve-Funktionen,  Prev: Airy-Funktionen,  Up: Bessel-Funktionen und verwandte Funktionen

22.2.4 Struve-Funktionen
------------------------

 -- Funktion: struve_h (<v>, <z>)

     Die Struve-Funktion H der Ordnung v mit dem Argument z.  Siehe
     Abramowitz und Stegun, Handbook of Mathematical Functions, Kapitel
     12.  Die Definition ist

                                 inf
                                 ====                  k  2 k
                         z v + 1 \                (- 1)  z
                H (z) = (-)       >    ----------------------------------
                 v       2       /      2 k           3                3
                                 ====  2    gamma(k + -) gamma(v + k + -)
                                 k = 0                2                2

     Die Struve-Funktion ‘struve_h’ ist für das numerische und
     symbolische Rechnen geeignet.  Im Unterschied zu den
     Bessel-Funktionen ist jedoch die Implementation der Funktion
     ‘struve_h’ weniger vollständig.

     Maxima berechnet ‘struve_h’ numerisch für reelle und komplexe
     Gleitkommazahlen als Argumente für v und z.  Mit der Funktion
     ‘float’ oder der Optionsvariablen ‘numer’ kann die numerische
     Auswertung erzwungen werden, wenn die Argumente Zahlen sind.  Die
     numerische Berechnung für große Gleitkommazahlen ist nicht
     implementiert.  In diesem Fall gibt Maxima eine Substantivform
     zurück.

     Hat die Optionsvariable ‘besselexpand’ den Wert ‘true’, wird die
     Struve-Funktion ‘struve_h’ mit einer halbzahligen Ordnung v als
     Sinus- und Kosinusfunktionen entwickelt.

     Maxima kennt die Ableitung der Struve-Funktion ‘struve_h’ nach dem
     Argument z.

     Siehe auch die Struve-Funktion ‘struve_l’.

     Beispiele:

          (%i1) struve_h(1, 0.5);
          (%o1)                  .05217374424234107
          (%i2) struve_h(1, 0.5+%i);
          (%o2)       0.233696520211436 %i - .1522134290663428
          (%i3) struve_h(3/2,x), besselexpand: true;
                                                     2
                            2 x sin(x) + 2 cos(x) - x  - 2
          (%o3)           - ------------------------------
                                                   3/2
                                sqrt(2) sqrt(%pi) x
          (%i4) diff(struve_h(v, x), x);
                             v
                            x
          (%o4) (------------------------- - struve_h(v + 1, x)
                            v           3
                 sqrt(%pi) 2  gamma(v + -)
                                        2
                                                    + struve_h(v - 1, x))/2

 -- Funktion: struve_l (<v>, <z>)

     Die modifizierte Struve-Funktion L der Ordnung v mit dem Argument
     z.  Siehe Abramowitz und Stegun, Handbook of Mathematical
     Functions, Kapitel 12.  Die Definition ist

                                 inf
                                 ====                  2 k
                         z v + 1 \                    z
                L (z) = (-)       >    ----------------------------------
                 v       2       /      2 k           3                3
                                 ====  2    gamma(k + -) gamma(v + k + -)
                                 k = 0                2                2

     Die Struve-Funktion ‘struve_l’ ist für das numerische und
     symbolische Rechnen geeignet.  Im Unterschied zu den
     Bessel-Funktionen ist jedoch die Implementation der Funktion
     ‘struve_l’ weniger vollständig.

     Maxima berechnet ‘struve_l’ numerisch für reelle und komplexe
     Gleitkommazahlen als Argumente für v und z.  Mit der Funktion
     ‘float’ oder der Optionsvariablen ‘numer’ kann die numerische
     Auswertung erzwungen werden, wenn die Argumente Zahlen sind.  Die
     numerische Berechnung für große Gleitkommazahlen ist nicht
     implementiert.  In diesem Fall gibt Maxima eine Substantivform
     zurück.

     Hat die Optionsvariable ‘besselexpand’ den Wert ‘true’, wird die
     Struve-Funktion ‘struve_l’ mit einer halbzahligen Ordnung v als
     Sinus- und Kosinusfunktionen entwickelt.

     Maxima kennt die Ableitung der Struve-Funktion ‘struve_l’ nach dem
     Argument z.

     Siehe auch die Struve-Funktion ‘struve_h’.

     Beispiele:

          (%i1) struve_l(1, 0.5);
          (%o1)                  .05394218262352267
          (%i2) struve_l(1, 0.5+%i);
          (%o2)       .1912720461247995 %i - .1646185598117401
          (%i3) struve_l(3/2,x), besselexpand: true;
                                                     2
                          2 x sinh(x) - 2 cosh(x) - x  + 2
          (%o3)           --------------------------------
                                                  3/2
                               sqrt(2) sqrt(%pi) x
          (%i4) diff(struve_l(v, x), x);
                             v
                            x
          (%o4) (------------------------- + struve_l(v + 1, x)
                            v           3
                 sqrt(%pi) 2  gamma(v + -)
                                        2
                                                    + struve_l(v - 1, x))/2


File: maxima.info,  Node: Gammafunktionen und verwandte Funktionen,  Next: Exponentielle Integrale,  Prev: Bessel-Funktionen und verwandte Funktionen,  Up: Spezielle Funktionen

22.3 Gammafunktionen und verwandte Funktionen
=============================================

Die Gammafunktion und die verwandten Funktionen wie die Beta-, Psi- und
die unvollständige Gammafunktion sind definiert in Abramowitz and
Stegun, Handbook of Mathematical Functions, Kapitel 6.

 -- Funktion: bffac (<x>, <fpprec>)

     Berechnet die Fakultät für große Gleitkommazahlen.  Das Argument
     <x> muss eine große Gleitkommazahl sein.  Das zweite Argument
     <fpprec> ist die Anzahl der Stellen, für die die Fakultät berechnet
     wird.  Das Ergebnis ist eine große Gleitkommazahl.

     Für das symbolische Rechnen mit der Fakultät und der Gammafunktion
     siehe die entsprechenden Funktionen ‘factorial’ und ‘gamma’.
     Maxima ruft intern die Funktion ‘bffac’ auf, um die Fakultät
     ‘factorial’ und die Gammafunktion ‘gamma’ für eine große
     Gleitkommazahl numerisch zu berechnen.

     Siehe auch die Funktion ‘cbffac’ für die Berechnung der Fakultät
     für komplexe große Gleitkommazahlen.

     Beispiel:

          (%i1) bffac(10.5b0, 25);
          (%o1)             1.189942308396224845701304b7
          (%i2) fpprec:25$
          (%i3) 10.5b0!;
          (%o3)             1.189942308396224845701303b7

 -- Funktion: bfpsi (<n>, <x>, <fpprec>)
 -- Funktion: bfpsi0 (<x>, <fpprec>)

     ‘bfpsi’ ist die Polygammafunktion für ein reelles Argument <x> und
     einer ganzzahligen Ordnung <n>.  ‘bfpsi0’ ist die Digammafunktion.
     ‘bfpsi0(<x>, <fpprec>)’ ist äquivalent zu ‘bfpsi(0, <x>,
     <fpprec>)’.

     Das Argument <x> der Funktionen ‘bfpsi’ und ‘bfpsi0’ muss eine
     große Gleitkommazahl sein.  Das Argument <fpprec> gibt die Anzahl
     der Stellen an, für die die Funktion berechnet wird.  Das Ergebnis
     ist eine große Gleitkommazahl.

     Für das symbolische Rechnen mit der Polygammafunktion siehe die
     Funktion ‘psi’.  Maxima ruft intern die Funktion ‘bfpsi’ auf, um
     die Polygammafunktion für große Gleitkommazahlen numerisch zu
     berechnen.

     Beispiel:

          (%i1) bfpsi(0, 1, 25);
          (%o1)            - 5.772156649015328606065121b-1
          (%i2) fpprec:25$

          (%i3) psi[0](1.0b0);
          (%o3)            - 5.772156649015328606065121b-1

 -- Funktion: cbffac (<z>, <fpprec>)

     Berechnet die Fakultät für komplexe große Gleitkommazahlen.  Das
     Argument <z> ist eine komplexe große Gleitkommazahl.  Das zweite
     Argument <fpprec> ist die Anzahl der Stellen, für die die Fakultät
     berechnet wird.  Das Ergebnis ist eine komplexe große
     Gleitkommazahl.

     Für das symbolische Rechnen mit der Fakultät und der Gammafunktion
     siehe die entsprechenden Funktionen ‘factorial’ und ‘gamma’.
     Maxima ruft intern die Funktion ‘cbffac’ auf, um die Fakultät
     ‘factorial’ und die Gammafunktion ‘gamma’ für eine komplexe große
     Gleitkommazahl numerisch zu berechnen.

     Siehe auch die Funktion ‘bffac’.

 -- Funktion: gamma (<z>)

     Die Definition der Gammafunktion ist (A & S 6.1.1)

                                 inf
                                /
                                [     z - 1   - t
                     gamma(z) = I    t      %e    dt
                                ]
                                /
                                 0

     Die Gammafunktion ‘gamma’ ist für das numerische und symbolische
     Rechnen geeignet.  Für positive ganze Zahlen und rationale Zahlen
     als Argument <z> wird die Gammafunktion vereinfacht.  Für
     halbzahlige rationale Zahlen ist das Ergebnis der Vereinfachung
     eine rationale Zahl multipliziert mit ‘sqrt(%pi)’.  Die
     Vereinfachung für ganze Zahlen wird von der Optionsvariablen
     ‘factlim’ kontrolliert.  Für ganze Zahlen, die größer als ‘factlim’
     sind, kann es zu einem Überlauf bei der Berechnung der
     Gammafunktion kommen.  Entsprechend wird die Vereinfachung für
     rationale Zahlen von der Optionsvariablen ‘gammalim’ kontrolliert.

     Für negative ganze Zahlen ist die Gammafunktion ‘gamma’ nicht
     definiert.

     Maxima berechnet ‘gamma’ numerisch für reelle und komplexe
     Argumente <z>.  Das Ergebnis ist eine reelle oder komplexe
     Gleitkommazahl.

     ‘gamma’ hat Spiegelsymmetrie.

     Hat die Optionsvariable ‘gamma_expand’ den Wert ‘true’, entwickelt
     Maxima die Gammafunktion für Argumente der Form ‘z+n’ und ‘z-n’,
     wobei <n> eine ganze Zahl ist.

     Maxima kennt die Ableitung der Gammafunktion ‘gamma’.

     Siehe auch die Funktion ‘makegamma’, um Fakultäten und
     Betafunktionen in einem Ausdruck durch die Gammafunktion zu
     ersetzen.

     Die Euler-Mascheroni-Konstante ist ‘%gamma’.

     Beispiele:

     Vereinfachung für ganze Zahlen und rationale Zahlen.

          (%i1) map('gamma,[1,2,3,4,5,6,7,8,9]);
          (%o1)        [1, 1, 2, 6, 24, 120, 720, 5040, 40320]
          (%i2) map('gamma,[1/2,3/2,5/2,7/2]);
                              sqrt(%pi)  3 sqrt(%pi)  15 sqrt(%pi)
          (%o2)   [sqrt(%pi), ---------, -----------, ------------]
                                  2           4            8
          (%i3) map('gamma,[2/3,5/3,7/3]);
                                            2           1
                                    2 gamma(-)  4 gamma(-)
                                2           3           3
          (%o3)          [gamma(-), ----------, ----------]
                                3       3           9

     Numerische Berechnung für reelle und komplexe Argumente.

          (%i4) map('gamma,[2.5,2.5b0]);
          (%o4)     [1.329340388179137, 1.3293403881791370205b0]
          (%i5) map('gamma,[1.0+%i,1.0b0+%i]);
          (%o5) [0.498015668118356 - .1549498283018107 %i,
                    4.9801566811835604272b-1 - 1.5494982830181068513b-1 %i]

     ‘gamma’ hat Spiegelsymmetrie.

          (%i6) declare(z,complex)$
          (%i7) conjugate(gamma(z));
          (%o7)                  gamma(conjugate(z))

     Maxima entwickelt ‘gamma(z+n)’ und ‘gamma(z-n)’, wenn die
     Optionsvariable ‘gamma_expand’ den Wert ‘true’ hat.

          (%i8) gamma_expand:true$

          (%i9) [gamma(z+1),gamma(z-1),gamma(z+2)/gamma(z+1)];
                                         gamma(z)
          (%o9)             [z gamma(z), --------, z + 1]
                                          z - 1

     Die Ableitung der Gammafunktion ‘gamma’.

          (%i10) diff(gamma(z),z);
          (%o10)                  psi (z) gamma(z)
                                     0

 -- Optionsvariable: gamma_expand
     Standardwert: ‘false’

     Kontrolliert die Vereinfachung der Gammafunktion ‘gamma’ und
     verwandte Funktionen wie ‘gamma_incomplete’ für den Fall, dass das
     Argument die Form ‘z+n’ oder ‘z-n’ hat.  Dabei ist ‘z’ ist ein
     beliebiges Argument und ‘n’ ist eine ganze Zahl.

     Siehe die Funktion ‘gamma’ für ein Beispiel.

 -- Funktion: log_gamma (<z>)

     Der Logarithmus der Gammafunktion.

 -- Funktion: gamma_incomplete (<a>, <z>)

     Die unvollständige Gammafunktion (A & S 6.5.2) die definiert ist
     als

                            inf
                           /
                           [     a - 1   - t
                           I    t      %e    dt
                           ]
                           /
                            z

 -- Funktion: gamma_incomplete_regularized (<a>, <z>)

     Regularisierte unvollständige Gammafunktion (A & S 6.5.1)

                         gamma_incomplete(a, z)
                         ----------------------
                                gamma(a)

 -- Funktion: gamma_incomplete_generalized (<a>, <z1>, <z2>)

     Verallgemeinerte unvollständige Gammafunktion

                            z2
                           /
                           [    a - 1   - t
                           I   t      %e    dt
                           ]
                           /
                            z1

 -- Optionsvariable: gammalim
     Standardwert: 1000000

     Kontrolliert die Vereinfachung der Gammafunktion für rationale
     Argumente.  Ist der Betrag des Arguments der Gammafunktion größer
     als ‘gammalim’, wird die Gammafunktion nicht vereinfacht.  Damit
     wird verhindert, dass die Berechnung der Gammafunktion zu einem
     Überlauf führt und mit einem Fehler abbricht.

     Siehe auch die Optionsvariable ‘factlim’, um die Vereinfachung für
     ganze Zahlen zu kontrollieren.

 -- Funktion: makegamma (<expr>)

     Ersetzt Fakultäten sowie Binomial- und Betafunktionen durch die
     Gammafunktion ‘gamma’ im Ausdruck <expr>.

     Siehe auch die Funktion ‘makefact’, um stattdessen Fakultäten in
     den Ausdruck einzusetzen.

     Beispiel:

          (%i1) expr: binomial(a,b)*gamma(b+1)/gamma(a+1);
                             binomial(a, b) gamma(b + 1)
          (%o1)              ---------------------------
                                    gamma(a + 1)
          (%i2) makegamma(expr);
                                         1
          (%o2)                  ------------------
                                 gamma(- b + a + 1)

 -- Funktion: beta (<a>, <b>)

     Die Betafunktion ist definiert als ‘gamma(a) gamma(b)/gamma(a+b)’
     (A & S 6.2.1).

     Maxima vereinfacht die Betafunktion für positive ganze Zahlen <a>
     und <b> sowie rationale Zahlen, deren Summe ‘<a> + <b>’ eine ganze
     Zahl ist.  Hat die Optionsvariable ‘beta_args_sum_to_integer’ den
     Wert ‘true’, vereinfacht Maxima die Betafunktion für allgemeine
     Ausdrücke <a> und <b>, deren Summe eine ganze Zahl ist.

     Ist eines der Argumente <a> oder <b> Null, ist die Betafunktion
     nicht definiert.

     Im allgemeinen ist die Betafunktion nicht definiert für negative
     ganze Zahlen als Argument.  Ausnahme ist der Fall, dass <a = -n>,
     wobei <n> eine positive ganze Zahl und <b> eine positive ganze Zahl
     mit <b <= b> ist.  In diesem Fall kann eine analytische Fortsetzung
     der Betafunktion definiert werden.  Maxima gibt für diesen Fall ein
     Ergebnis zurück.

     Hat die Optionsvariable ‘beta_expand’ den Wert ‘true’, werden
     Ausdrücke wie ‘beta(a+n, b’ und ‘beta(a-n, b)’ oder ‘beta(a, b+n’
     und ‘beta(a, b-n)’ entwickelt.

     Maxima berechnet die Betafunktion für reelle und komplexe
     Gleitkommazahlen numerisch.  Für die numerische Berechnung nutzt
     Maxima die Funktion ‘log_gamma’:

                     - log_gamma(b + a) + log_gamma(b) + log_gamma(a)
                   %e

     Maxima kennt Symmetrieeigenschaften der Betafunktion.  Die
     Betafunktion ist symmetrisch und hat Spiegelsymmetrie.

     Maxima kennt die Ableitung der Betafunktion nach den Argumenten <a>
     und <b>.

     Mit der Funktion ‘makegamma’ kann die Betafunktion durch
     Gammafunktionen ersetzt werden.  Entsprechend ersetzt die Funktion
     ‘makefact’ Betafunktionen in einem Ausdruck durch Fakultäten.

     Beispiele:

     Vereinfachung der Betafunktion, wenn eines der Argumente eine ganze
     Zahl ist.

          (%i1) [beta(2,3),beta(2,1/3),beta(2,a)];
                                         1   9      1
          (%o1)                         [--, -, ---------]
                                         12  4  a (a + 1)

     Vereinfachung der Betafunktion für zwei rationale Argumente, die
     sich zu einer ganzen Zahl summieren.

          (%i2) [beta(1/2,5/2),beta(1/3,2/3),beta(1/4,3/4)];
                                    3 %pi   2 %pi
          (%o2)                    [-----, -------, sqrt(2) %pi]
                                      8    sqrt(3)

     Hat die Optionsvariable ‘beta_args_sum_to_integer’ den Wert ‘true’,
     vereinfacht die Betafunktion für allgemeine Ausdrücke, die sich zu
     einer ganzen Zahl summieren.

          (%i3) beta_args_sum_to_integer:true$
          (%i4) beta(a+1,-a+2);
                                          %pi (a - 1) a
          (%o4)                         ------------------
                                        2 sin(%pi (2 - a))

     Die möglichen Ergebnisse, wenn eines der Argumente eine negative
     ganze Zahl ist.

          (%i5) [beta(-3,1),beta(-3,2),beta(-3,3)];
                                              1  1    1
          (%o5)                            [- -, -, - -]
                                              3  6    3

     Vereinfachungen, wenn die Optionsvariable ‘beta_expand’ den Wert
     ‘true’ hat.

          (%i6) beta_expand:true$
          (%i7) [beta(a+1,b),beta(a-1,b),beta(a+1,b)/beta(a,b+1)];
                              a beta(a, b)  beta(a, b) (b + a - 1)  a
          (%o7)              [------------, ----------------------, -]
                                 b + a              a - 1           b

     Die Betafunktion ist nicht definiert, wenn eines der Argumente Null
     ist.

          (%i7) beta(0,b);
          beta: expected nonzero arguments; found 0, b
           -- an error.  To debug this try debugmode(true);

     Numerische Berechnung der Betafunktion für reelle und komplexe
     Argumente.

          (%i8) beta(2.5,2.3);
          (%o8) .08694748611299981

          (%i9) beta(2.5,1.4+%i);
          (%o9) 0.0640144950796695 - .1502078053286415 %i

          (%i10) beta(2.5b0,2.3b0);
          (%o10) 8.694748611299969b-2

          (%i11) beta(2.5b0,1.4b0+%i);
          (%o11) 6.401449507966944b-2 - 1.502078053286415b-1 %i

     Die Betafunktion ist symmetrisch und hat Spiegelsymmetrie.

          (%i14) beta(a,b)-beta(b,a);
          (%o14)                                 0
          (%i15) declare(a,complex,b,complex)$
          (%i16) conjugate(beta(a,b));
          (%o16)                 beta(conjugate(a), conjugate(b))

     Ableitung der Betafunktion.

          (%i17) diff(beta(a,b),a);
          (%o17)               - beta(a, b) (psi (b + a) - psi (a))
                                                0             0

 -- Funktion: beta_incomplete (<a>, <b>, <z>)

     Die Definition der unvollständigen Betafunktion ist (A & S 6.6.1)

                                 z
                                /
                                [         b - 1  a - 1
                                I  (1 - t)      t      dt
                                ]
                                /
                                 0

     Diese Definition ist möglich für realpart(a)>0 und realpart(b)>0
     sowie abs(z)<1.  Für andere Werte kann die unvollständige
     Betafunktion als eine verallgemeinerte Hypergeometrische Funktion
     definiert werden:

             gamma(a) hypergeometric_generalized([a, 1 - b], [a + 1], z) z

     (Siehe <https://functions.wolfram.com/> für eine Definition der
     unvollständigen Betafunktion.)

     Für negative ganze Zahlen a = -n und positive ganze Zahlen b = m
     mit m <= n kann die unvollständige Betafunktion definiert werden
     als

                                      m - 1           k
                                      ====  (1 - m)  z
                                n - 1 \            k
                               z       >    -----------
                                      /     k! (n - k)
                                      ====
                                      k = 0

     Maxima nutzt diese Definition, um die Funktion ‘beta_incomplete’
     für negative ganzzahlige Argumente <a> zu vereinfachen.

     Für positive ganzzahlige Argumente <a> vereinfacht
     ‘beta_incomplete’ für jedes Argument <b> und <z>.  Entsprechend
     vereinfacht ‘beta_incomplete’ für ein positives ganzzahliges
     Argument <b> mit der Ausnahme, dass <a> eine negative ganze Zahl
     ist.

     Für z=0 und realpart(a) > 0 hat ‘beta_incomplete’ den speziellen
     Wert Null.  Für <z=1> und realpart(b) > 0 vereinfacht
     ‘beta_incomplete’ zu einem Ausdruck mit der Betafunktion ‘beta(a,
     b)’.

     Maxima berechnet ‘beta_incomplete’ numerisch für reelle und
     komplexe Gleitkommazahlen als Argumente.  Für die numerische
     Berechnung nutzt Maxima eine Entwicklung der unvollständigen
     Betafunktion als Kettenbruch.

     Hat die Optionsvariable ‘beta_expand’ den Wert ‘true’, entwickelt
     Maxima Ausdrücke der Form ‘beta_incomplete(a+n, b, z)’ und
     ‘beta_incomplete(a-n, b, z)’, wobei ‘n’ eine ganze Zahl ist.

     Maxima kennt die Ableitungen der unvollständigen Betafunktion nach
     den Variablen <a>, <b> und <z> und das Integral für die
     Integrationsvariable <z>.

     Beispiele:

     Vereinfachung für eine positive ganze Zahl als Argument <a>.

          (%i1) beta_incomplete(2,b,z);
                                                 b
                                      1 - (1 - z)  (b z + 1)
          (%o1)                       ----------------------
                                            b (b + 1)

     Vereinfachung für eine positive ganze Zahl als Argument <b>.

          (%i2) beta_incomplete(a,2,z);
                                                         a
                                        (a (1 - z) + 1) z
          (%o2)                         ------------------
                                            a (a + 1)

     Vereinfachung für positive ganzzahlige Argumente <a> und <b>.

          (%i3) beta_incomplete(3,2,z);
                                                         3
                                        (3 (1 - z) + 1) z
          (%o3)                         ------------------
                                                12

     <a> ist eine negative ganze Zahl mit b <= (-a).  Maxima vereinfacht
     für diesem Fall.

          (%i4) beta_incomplete(-3,1,z);
                                                 1
          (%o4)                              - ----
                                                  3
                                               3 z

     Für die speziellen Werte z=0 und z=1 vereinfacht Maxima.

          (%i5) assume(a>0,b>0)$
          (%i6) beta_incomplete(a,b,0);
          (%o6)                                 0
          (%i7) beta_incomplete(a,b,1);
          (%o7)                            beta(a, b)

     Numerische Berechnung für reelle Argumente.

          (%i8) beta_incomplete(0.25,0.50,0.9);
          (%o8)                          4.594959440269333
          (%i9)  fpprec:25$
          (%i10) beta_incomplete(0.25,0.50,0.9b0);
          (%o10)                    4.594959440269324086971203b0

     Für abs(z) > 1 ist das Ergebnis komplex.

          (%i11) beta_incomplete(0.25,0.50,1.7);
          (%o11)              5.244115108584249 - 1.45518047787844 %i

     Numerische Ergebnisse für komplexe Argumente.

          (%i14) beta_incomplete(0.25+%i,1.0+%i,1.7+%i);
          (%o14)             2.726960675662536 - .3831175704269199 %i
          (%i15) beta_incomplete(1/2,5/4*%i,2.8+%i);
          (%o15)             13.04649635168716 %i - 5.802067956270001
          (%i16)

     Entwicklung, wenn ‘beta_expand’ den Wert ‘true’ hat.

          (%i23) beta_incomplete(a+1,b,z),beta_expand:true;
                                                                 b  a
                             a beta_incomplete(a, b, z)   (1 - z)  z
          (%o23)             -------------------------- - -----------
                                       b + a                 b + a

          (%i24) beta_incomplete(a-1,b,z),beta_expand:true;
                                                                     b  a - 1
                     beta_incomplete(a, b, z) (- b - a + 1)   (1 - z)  z
          (%o24)     -------------------------------------- - ---------------
                                     1 - a                         1 - a

     Ableitung und Integral der unvollständigen Betafunktion.

          (%i34) diff(beta_incomplete(a, b, z), z);
                                        b - 1  a - 1
          (%o34)                 (1 - z)      z
          (%i35) integrate(beta_incomplete(a, b, z), z);
                        b  a
                 (1 - z)  z
          (%o35) ----------- + beta_incomplete(a, b, z) z
                    b + a
                                                 a beta_incomplete(a, b, z)
                                               - --------------------------
                                                           b + a
          (%i36) factor(diff(%, z));
          (%o36)              beta_incomplete(a, b, z)

 -- Funktion: beta_incomplete_regularized (<a>, <b>, <z>)

     Die regularisierte unvollständige Beta Funktion (A & S 6.6.2), die
     definiert ist als

                        beta_incomplete(a, b, z)
                        ------------------------
                               beta(a, b)

     Wie bei der Funktion ‘beta_incomplete’ ist diese Definition nicht
     vollständig.  Siehe <https://functions.wolfram.com> für eine
     vollständige Definition der Funktion.

     ‘beta_incomplete_regularized’ vereinfacht, wenn das Argument <a>
     oder <b> eine positive ganze Zahl ist.  Für Argumente ‘<z> = 0’ und
     ‘realpart(<a>) > 0’ vereinfacht die Funktion
     ‘beta_incomplete_regularized’ zu ‘0’.  Für ‘<z> = 1’ und
     ‘realpart(<b>) > 0’ vereinfacht die Funktion
     ‘beta_incomplete_regularized’ zu ‘1’.

     Maxima berechnet ‘beta_incomplete_regularized’ für reelle und
     komplexe Gleitkommazahlen als Argumente numerisch.

     When ‘beta_expand’ is ‘true’, Maxima expands
     ‘beta_incomplete_regularized’ for arguments a+n or a-n, where n is
     an integer.

     Hat die Optionsvariable ‘beta_expand’ den Wert ‘true’, expandiert
     Maxima ‘beta_incomplete_regularized’ für Argumente a+n oder a-n,
     wobei <n> eine ganze Zahl ist.

     Maxima kennt die Ableitung der Funktion
     ‘beta_incomplete_regularized’ nach den Argumenten <a>, <b> und <z>
     sowie das Integral für das Argument <z>.

     Beispiele:

     Vereinfachung, wenn die Argumente <a> oder <b> ganze Zahlen sind.

          (%i1) beta_incomplete_regularized(2,b,z);
                                          b
          (%o1)                1 - (1 - z)  (b z + 1)
          (%i2) beta_incomplete_regularized(a,2,z);
                                                  a
          (%o2)                  (a (1 - z) + 1) z
          (%i3) beta_incomplete_regularized(3,2,z);
                                                  3
          (%o3)                  (3 (1 - z) + 1) z

     Für die speziellen Werte z=0 und z=1 vereinfacht Maxima.

          (%i4) assume(a>0,b>0)$

          (%i5) beta_incomplete_regularized(a,b,0);
          (%o5)                           0
          (%i6) beta_incomplete_regularized(a,b,1);
          (%o6)                           1

     Numerische Berechnung für reelle und komplexe Argumente.

          (%i7) beta_incomplete_regularized(0.12,0.43,0.9);
          (%o7)                   .9114011367359802
          (%i8) fpprec:32$

          (%i9) beta_incomplete_regularized(0.12,0.43,0.9b0);
          (%o9)         9.1140113673598075519946998779975b-1
          (%i10) beta_incomplete_regularized(1+%i,3/3,1.5*%i);
          (%o10)      .2865367499935405 %i - .1229959633346841
          (%i11) fpprec:20$

          (%i12) beta_incomplete_regularized(1+%i,3/3,1.5b0*%i);
          (%o12) 2.8653674999354036142b-1 %i - 1.2299596333468400163b-1

     Expansion, wenn ‘beta_expand’ den Wert ‘true’ hat.

          (%i13) beta_incomplete_regularized(a+1,b,z);
                                                               b  a
                                                        (1 - z)  z
          (%o13) beta_incomplete_regularized(a, b, z) - ------------
                                                        a beta(a, b)
          (%i14) beta_incomplete_regularized(a-1,b,z);
          (%o14) beta_incomplete_regularized(a, b, z)
                                                               b  a - 1
                                                        (1 - z)  z
                                                   - ----------------------
                                                     beta(a, b) (b + a - 1)

     Die Ableitung und das Integral der Funktion.

          (%i15) diff(beta_incomplete_regularized(a,b,z),z);
                                        b - 1  a - 1
                                 (1 - z)      z
          (%o15)                 -------------------
                                     beta(a, b)
          (%i16) integrate(beta_incomplete_regularized(a,b,z),z);
          (%o16) beta_incomplete_regularized(a, b, z) z
                                                                     b  a
                                                              (1 - z)  z
                    a (beta_incomplete_regularized(a, b, z) - ------------)
                                                              a beta(a, b)
                  - -------------------------------------------------------
                                             b + a

 -- Funktion: beta_incomplete_generalized (<a>, <b>, <z1>, <z2>)

     Die Definition der verallgemeinerten unvollständigen Betafunktion
     ist

                                z2
                               /
                               [          b - 1  a - 1
                               I   (1 - t)      t      dt
                               ]
                               /
                                z1

     Maxima vereinfacht ‘beta_incomplete_refularized’ für positive
     ganzzahlige Argumente <a> und <b>.

     Ist realpart(a)>0 und z1=0 oder z2=0, vereinfacht Maxima
     ‘beta_incomplete_generalized’ zu der Funktion ‘beta_incomplete’.
     Ist realpart(b)>0 und z1=1 oder <z2=1>, vereinfacht Maxima zu einem
     Ausdruck mit der Funktion ‘beta’ und ‘beta_incomplete’.

     Maxima berechnet ‘beta_incomplete_regularized’ numerisch für reelle
     und komplexe Gleitkommazahlen in doppelter und beliebiger
     Genauigkeit.

     Hat die Optionsvariable ‘beta_expand’ den Wert ‘true’, dann
     expandiert Maxima ‘beta_incomplete_generalized’ für Argumente a+n
     und a-n, wobei <n> eine positive ganze Zahl ist.

     Maxima kennt die Ableitung der Funktion
     ‘beta_incomplete_generalized’ nach den Variablen <a>, <b>, <z1> und
     <z2> sowie die Integrale für die Integrationsvariablen <z1> und
     <z2>.

     Beispiele:

     Maxima vereinfacht ‘beta_incomplete_generalized’, wenn <a> und <b>
     positive ganze Zahlen sind.

          (%i1) beta_incomplete_generalized(2,b,z1,z2);
                             b                      b
                     (1 - z1)  (b z1 + 1) - (1 - z2)  (b z2 + 1)
          (%o1)      -------------------------------------------
                                      b (b + 1)
          (%i2) beta_incomplete_generalized(a,2,z1,z2);
                                        a                      a
                     (a (1 - z2) + 1) z2  - (a (1 - z1) + 1) z1
          (%o2)      -------------------------------------------
                                      a (a + 1)
          (%i3) beta_incomplete_generalized(3,2,z1,z2);
                        2      2                       2      2
                (1 - z1)  (3 z1  + 2 z1 + 1) - (1 - z2)  (3 z2  + 2 z2 + 1)
          (%o3) -----------------------------------------------------------
                                            12

     Vereinfachung für die speziellen Werte z1=0, z2=0, z1=1 und z2=1.

          (%i4) assume(a > 0, b > 0)$
          (%i5) beta_incomplete_generalized(a,b,z1,0);
          (%o5)                    - beta_incomplete(a, b, z1)

          (%i6) beta_incomplete_generalized(a,b,0,z2);
          (%o6)                    - beta_incomplete(a, b, z2)

          (%i7) beta_incomplete_generalized(a,b,z1,1);
          (%o7)              beta(a, b) - beta_incomplete(a, b, z1)

          (%i8) beta_incomplete_generalized(a,b,1,z2);
          (%o8)              beta_incomplete(a, b, z2) - beta(a, b)

     Numerische Berechnung für reelle Argumente in doppelter und
     beliebiger Gleitkommagenauigkeit.

          (%i9) beta_incomplete_generalized(1/2,3/2,0.25,0.31);
          (%o9)                        .09638178086368676

          (%i10) fpprec:32$
          (%i10) beta_incomplete_generalized(1/2,3/2,0.25,0.31b0);
          (%o10)               9.6381780863686935309170054689964b-2

     Numerische Berechnung für komplexe Argumente in doppelter und
     beliebiger Gleitkommagenauigkeit.

          (%i11) beta_incomplete_generalized(1/2+%i,3/2+%i,0.25,0.31);
          (%o11)           - .09625463003205376 %i - .003323847735353769
          (%i12) fpprec:20$
          (%i13) beta_incomplete_generalized(1/2+%i,3/2+%i,0.25,0.31b0);
          (%o13)     - 9.6254630032054178691b-2 %i - 3.3238477353543591914b-3

     Expansion für a+n oder a-n und <n> eine positive ganze Zahl, wenn
     ‘beta_expand’ den Wert ‘true’ hat.

          (%i14) beta_expand:true$

          (%i15) beta_incomplete_generalized(a+1,b,z1,z2);
                         b   a           b   a
                 (1 - z1)  z1  - (1 - z2)  z2
          (%o15) -----------------------------
                             b + a
                                a beta_incomplete_generalized(a, b, z1, z2)
                              + -------------------------------------------
                                                   b + a
          (%i16) beta_incomplete_generalized(a-1,b,z1,z2);

                 beta_incomplete_generalized(a, b, z1, z2) (- b - a + 1)
          (%o16) -------------------------------------------------------
                                          1 - a
                                              b   a - 1           b   a - 1
                                      (1 - z2)  z2      - (1 - z1)  z1
                                    - -------------------------------------
                                                      1 - a

     Ableitung nach der Variablen <z1> und die Integrale für die
     Integrationsvariablen <z1> und <z2>.

          (%i17) diff(beta_incomplete_generalized(a,b,z1,z2),z1);
                                         b - 1   a - 1
          (%o17)               - (1 - z1)      z1
          (%i18) integrate(beta_incomplete_generalized(a,b,z1,z2),z1);
          (%o18) beta_incomplete_generalized(a, b, z1, z2) z1
                                            + beta_incomplete(a + 1, b, z1)
          (%i19) integrate(beta_incomplete_generalized(a,b,z1,z2),z2);
          (%o19) beta_incomplete_generalized(a, b, z1, z2) z2
                                            - beta_incomplete(a + 1, b, z2)

 -- Optionsvariable: beta_expand
     Standardwert: ‘false’

     Hat die Optionsvariable ‘beta_expand’ den Wert ‘true’, werden
     ‘beta(a,b)’ und verwandte Funktionen für Argumente a+n oder a-n
     entwickelt, wobei <n> eine positive ganze Zahl ist.

 -- Optionsvariable: beta_args_sum_to_integer
     Standardwert: ‘false’

     Hat die Optionsvariable ‘beta_args_sum_to_integer’ den Wert ‘true’,
     vereinfacht Maxima die Funktion ‘beta(a,b)’, wenn sich die
     Argumente <a> und <b> zu einer ganzen Zahlen summieren.  Siehe auch
     ‘beta’.

 -- Funktion: psi [<n>](<x>)

     Ist definiert als die Ableitung der Funktion ‘log(gamma(<x>))’ der
     Ordnung ‘<n>+1’.  ‘psi[0](<x>)’ ist die erste Ableitung,
     ‘psi[1](<x>)’ ist die zweite Ableitung, usw.

     Maxima kann numerische Werte für reelle Gleitkommazahlen berechnen.
     Weiterhin kann Maxima die Funktion ‘psi’ für rationale Argumente zu
     exakten Werten vereinfachen.  Die Optionsvariablen ‘maxpsiposint’,
     ‘maxpsinegint’, ‘maxpsifracnum’ und ‘maxpsifracdenom’
     kontrollieren, den Wertebereich der Argumente für den die Funktion
     ‘psi’ vereinfacht.

     Die Funktion ‘bfpsi’ des ‘bffac’-Package kann numerische Werte der
     Funktion ‘psi’ berechnen.

 -- Optionsvariable: maxpsiposint
     Standardwert: ‘20’

     Die Optionsvariable ‘maxpsiposint’ kontrolliert die Vereinfachung
     der Funktion ‘psi’ und enthält eine obere positive Schranke.  Ist
     das Argument <x> der Funktion ‘psi’ größer als ‘maxpsiposint’, dann
     versucht Maxima nicht ‘psi[<n>](<x>)’ zu vereinfachen.

     Siehe auch ‘maxpsifracdenom’, ‘maxpsifracnum’ und ‘maxpsinegint’.

     Beispiele:

          (%o1)                          20
          (%i2) psi[0](20);
                                 275295799
          (%o2)                  --------- - %gamma
                                 77597520
          (%i3) maxpsiposint:10;
          (%o3)                          10
          (%i4) psi[0](20);
          (%o4)                       psi (20)
                                         0
          (%i5) psi[0](10);
                                    7129
          (%o5)                     ---- - %gamma
                                    2520

 -- Optionsvariable: maxpsinegint
     Standardwert: ‘-10’

     Die Optionsvariable ‘maxpsinegint’ kontrolliert die Vereinfachung
     der Funktion ‘psi’ und enthält eine untere negative Schranke.  Ist
     das Argument <x> der Funktion ‘psi’ kleiner als ‘maxpsinegint’,
     dann versucht Maxima nicht ‘psi[<n>](<x>)’ zu vereinfachen.

     Siehe auch ‘maxpsifracdenom’, ‘maxpsifracnum’ und ‘maxpsiposint’.

     Beispiele:

          (%i1) maxpsinegint:-10;
          (%o1)                         - 10
          (%i2) psi[0](-3/2);
                                                     8
          (%o2)                - 2 log(2) - %gamma + -
                                                     3
          (%i3) maxpsinegint:-1;
          (%o3)                          - 1
          (%i4) psi[0](-3/2);
                                             3
          (%o4)                       psi (- -)
                                         0   2
          (%i5) psi[0](-1/2);
          (%o5)                - 2 log(2) - %gamma + 2

 -- Optionsvariable: maxpsifracnum
     Standardwert: ‘6’

     Die Optionsvariable ‘maxpsifracnum’ kontrolliert die Vereinfachung
     der Funktion ‘psi’.  Ist das Argument <x> der Funktion ‘psi’ eine
     rationale Zahl kleiner als eins mit ‘p/q’ und ist der Zähler ‘p’
     größer als ‘maxpsifracnum’, dann versucht Maxima nicht
     ‘psi[<n>](<x>)’ zu vereinfachen.

     Siehe auch ‘maxpsifracdenom’, ‘maxpsiposint’ und ‘maxpsinegint’.

     Beispiele:

          (%i1) maxpsifracnum: 6;
          (%o1)                           6
          (%i2) psi[0](5/6);
                      3 log(3)              sqrt(3) %pi
          (%o2)     - -------- - 2 log(2) + ----------- - %gamma
                         2                       2
          (%i3) maxpsifracnum: 3;
          (%o3)                           3
          (%i4) psi[0](5/6);
                                            5
          (%o4)                        psi (-)
                                          0 6

 -- Optionsvariable: maxpsifracdenom
     Standardwert: ‘6’

     Die Optionsvariable ‘maxpsifracdenom’ kontrolliert die
     Vereinfachung der Funktion ‘psi’.  Ist das Argument <x> der
     Funktion ‘psi’ eine rationale Zahl kleiner als eins mit ‘p/q’ und
     ist der Nenner ‘q’ größer als ‘maxpsifracdenom’, dann versucht
     Maxima nicht ‘psi[<n>](<x>)’ zu vereinfachen.

     Siehe auch ‘maxpsifracnum’, ‘maxpsiposint’ und ‘maxpsinegint’.

     Beispiele:

          (%i1) maxpsifracdenom: 6;
          (%o1)                           6
          (%i2) psi[0](1/6);
                      3 log(3)              sqrt(3) %pi
          (%o2)     - -------- - 2 log(2) - ----------- - %gamma
                         2                       2
          (%i3) maxpsifracdenom: 4;
          (%o3)                           4
          (%i4) psi[0](1/6);
                                            1
          (%o4)                        psi (-)
                                          0 6
          (%i5) psi[0](1/5);
                                            1
          (%o5)                        psi (-)
                                          0 5
          (%i6) psi[0](1/4);
                                           %pi
          (%o6)               - 3 log(2) - --- - %gamma
                                            2

 -- Funktion: makefact (<expr>)

     Ersetzt Binomial-, Gamma- und Beta-Funktionen, die im Ausdruck
     <expr> auftreten, durch Fakultäten.

     Siehe auch die Funktion ‘makegamma’.

 -- Funktion: numfactor (<expr>)

     Gibt einen numerischen Faktor des Produktes <expr> zurück.  Ist
     <expr> kein Produkt oder enthält das Produkt keinen numerischen
     Faktor ist die Rückgabe ‘1’.

     Beispiel:

          (%i1) gamma (7/2);
                                    15 sqrt(%pi)
          (%o1)                     ------------
                                         8
          (%i2) numfactor (%);
                                         15
          (%o2)                          --
                                         8


File: maxima.info,  Node: Exponentielle Integrale,  Next: Fehlerfunktionen,  Prev: Gammafunktionen und verwandte Funktionen,  Up: Spezielle Funktionen

22.4 Exponentielle Integrale
============================

Die Exponentiellen Integrale und verwandte Funktionen sind definiert in
Abramowitz und Stegun, Handbook of Mathematical Functions, Kapitel 5.

 -- Funktion: expintegral_e1 (<z>)

     Das Exponentielle Integral ‘E1(z)’ (A&S 5.1.1).

 -- Funktion: expintegral_ei (<z>)

     Das Exponentielle Integral ‘Ei(z)’ (A&S 5.1.2).

 -- Funktion: expintegral_li (<n>,<z>)

     Das Exponentielle Integral ‘Li(z)’ (A&S 5.1.3).

 -- Funktion: expintegral_e (<n>, <z>)

     Das Exponentielle Integral ‘E[n](z)’ (A&S 5.1.4).

 -- Funktion: expintegral_si (<z>)

     Das Exponentielle Integral ‘Si(z)’ (A&S 5.2.1).

 -- Funktion: expintegral_ci (<z>)

     Das Exponentielle Integral ‘Ci(z)’ (A&S 5.2.2).

 -- Funktion: expintegral_shi (<z>)

     Das Exponentielle Integral ‘Shi(z)’ (A&S 5.2.3).

 -- Funktion: expintegral_chi (<z>)

     Das Exponentielle Integral ‘Chi(z)’ (A&S 5.2.4).

 -- Optionsvariable: expintrep
     Standardwert: ‘false’

     Wechselt die Darstellung eines Exponentiellen Integrals in eine der
     anderen Funktionen ‘gamma_incomplete’, ‘expintegral_e1’,
     ‘expintegral_ei’, ‘expintegral_li’, ‘expintegral_si’,
     ‘expintegral_ci’, ‘expintegral_shi’, oder ‘expintegral_chi’.

 -- Optionsvariable: expintexpand
     Standardwert: ‘false’

     Expandiert das Exponentielle Integral ‘E[n](z)’ für halbzahlige,
     gerade Ordnung <n> nach den Funktionen ‘erfc’ und ‘erf’.  sowie für
     positive ganze Zahlen nach der Funktion ‘expintegral_ei’.


File: maxima.info,  Node: Fehlerfunktionen,  Next: Elliptische Funktionen und Integrale,  Prev: Exponentielle Integrale,  Up: Spezielle Funktionen

22.5 Fehlerfunktionen
=====================

Die Fehlerfunktion und verwandte Funktionen sind definiert in Abramowitz
und Stegun, Handbook of Mathematical Functions, Kapitel 7.

 -- Funktion: erf (<z>)

     Die Fehlerfunktion ‘erf(z)’ (A&S 7.1.1).

     Siehe auch die Optionsvariable ‘erfflag’.

 -- Function: erfc (<z>)

     Die komplementäre Fehlerfunktion ‘erfc(z) = 1 - erf(z)’ (A & S
     7.1.2).

 -- Funktion: erfi (<z>)

     Die imaginäre Fehlerfunktion ‘erfi(z) = -%i*erf(%i*z)’.

 -- Funktion: erf_generalized (<z1>, <z2>)

     Die verallgemeinerte Fehlerfunktion Erf(z1, z2).

 -- Funktion: fresnel_c (<z>)

     Das Fresnel-Integral, das definiert ist als (A & S 7.3.1):

                     z
                    /           2
                    [      %pi t
             C(z) = I  cos(------) dt
                    ]        2
                    /
                     0

     Hat die Optionsvariable ‘trigsign’ den Wert ‘true’, vereinfacht
     Maxima ‘fresnel_c(-x)’ zu ‘-fresnel_c(x)’.

     Hat die Optionsvariable ‘%iargs’ den Wert ‘true’, vereinfacht
     Maxima ‘fresnel_c(%i*x)’ zu ‘%i*fresnel_c(x)’.

     Siehe auch die Optionsvariable ‘hypergeometric_representation’, um
     die Fresnelfunktion in eine hypergeometrische Darstellung zu
     transformieren, und die Optionsvariable ‘erf_representation’ für
     eine Darstellung als Fehlerfunktion.

 -- Funktion: fresnel_s (<z>)

     Das Fresnel-Integral, das definiert ist als (A & S 7.3.2):

                     z
                    /           2
                    [      %pi t
             S(z) = I  sin(------) dt
                    ]        2
                    /
                     0

     Hat die Optionsvariable ‘trigsign’ den Wert ‘true’, vereinfacht
     Maxima ‘fresnel_s(-x)’ zu ‘-fresnel_s(x)’.

     Hat die Optionsvariable ‘%iargs’ den Wert ‘true’, vereinfacht
     Maxima ‘fresnel_s(%i*x)’ zu ‘%i*fresnel_s(x)’.

     Siehe auch die Optionsvariable ‘hypergeometric_representation’, um
     die Fresnelfunktion in eine hypergeometrische Darstellung zu
     transformieren, und die Optionsvariable ‘erf_representation’ für
     eine Darstellung als Fehlerfunktion.

 -- Optionsvariable: erf_representation
     Standarwert: ‘false’

     Hat die Optionsvariable ‘erf_representation’ den Wert ‘true’,
     werden die Funktionen ‘erfc’, ‘erfi’, ‘erf_generalized’,
     ‘fresnel_s’ und ‘fresnel_c’ in eine Darstellung mit der Funktion
     ‘erf’ transformiert.

 -- Optionsvariable: hypergeometric_representation
     Standardwert: ‘false’

     Hat die Optionsvariable ‘hypergeometric_representation’ den Wert
     ‘true’, werden die Funktionen ‘fresnel_s’ und ‘fresnel_c’ in eine
     hypergeometrische Funktion transformiert.


File: maxima.info,  Node: Elliptische Funktionen und Integrale,  Next: Hypergeometrische Funktionen,  Prev: Fehlerfunktionen,  Up: Spezielle Funktionen

22.6 Elliptische Funktionen und Integrale
=========================================

* Menu:

* Einführung in Elliptische Funktionen und Integrale::
* Funktionen und Variablen für Elliptische Funktionen::
* Funktionen und Variablen für Elliptische Integrale::


File: maxima.info,  Node: Einführung in Elliptische Funktionen und Integrale,  Next: Funktionen und Variablen für Elliptische Funktionen,  Prev: Elliptische Funktionen und Integrale,  Up: Elliptische Funktionen und Integrale

22.6.1 Einführung in Elliptische Funktionen und Integrale
---------------------------------------------------------

Maxima unterstützt die Jacobischen elliptische Funktionen sowie die
vollständigen und unvollständigen elliptischen Integrale.  Die
Funktionen sind für das symbolische und numerische Rechnen geeignet.
Die Definition der Funktionen und viele ihrer Eigenschaften sind in
Abramowitz and Stegun, Kapitel 16 und 17 enthalten.  Die dort
beschriebenen Definitionen und Beziehungen werden so weit als möglich
verwendet.

Im besonderen nutzen alle elliptischen Funktionen und Integrale den
Parameter m anstatt den Modulus k oder den modularen Winkel \alpha.
Dies ist ein Unterschied zu der Definition von Abramowitz und Stegun.
Es gelten die folgenden Beziehungen: m = k^2 und k = \sin(\alpha)

Die elliptischen Funktionen und Integrale sind zuallererst für das
symbolische Rechnen gedacht.  Daher sind die Ableitungen und Integrale
der Funktionen im wesentlichen in Maxima bekannt.  Maxima unterstützt
jedoch auch die numerische Berechnung, wenn die Argumente
Gleitkommazahlen sind.

Viele bekannte Eigenschaften der Elliptischen Funktionen und Integrale
sind noch nicht in Maxima implementiert.

Einige Beispiele für elliptische Funktionen.

     (%i1) jacobi_sn (u, m);
     (%o1)                    jacobi_sn(u, m)
     (%i2) jacobi_sn (u, 1);
     (%o2)                        tanh(u)
     (%i3) jacobi_sn (u, 0);
     (%o3)                        sin(u)
     (%i4) diff (jacobi_sn (u, m), u);
     (%o4)            jacobi_cn(u, m) jacobi_dn(u, m)
     (%i5) diff (jacobi_sn (u, m), m);
     (%o5) jacobi_cn(u, m) jacobi_dn(u, m)

           elliptic_e(asin(jacobi_sn(u, m)), m)
      (u - ------------------------------------)/(2 m)
                          1 - m

                 2
        jacobi_cn (u, m) jacobi_sn(u, m)
      + --------------------------------
                   2 (1 - m)

Einige Beispiele für elliptische Integrale.

     (%i1) elliptic_f (phi, m);
     (%o1)                  elliptic_f(phi, m)
     (%i2) elliptic_f (phi, 0);
     (%o2)                          phi
     (%i3) elliptic_f (phi, 1);
                                    phi   %pi
     (%o3)                  log(tan(--- + ---))
                                     2     4
     (%i4) elliptic_e (phi, 1);
     (%o4)                       sin(phi)
     (%i5) elliptic_e (phi, 0);
     (%o5)                          phi
     (%i6) elliptic_kc (1/2);
                                          1
     (%o6)                    elliptic_kc(-)
                                          2
     (%i7) makegamma (%);
                                      2 1
                                 gamma (-)
                                        4
     (%o7)                      -----------
                                4 sqrt(%pi)
     (%i8) diff (elliptic_f (phi, m), phi);
                                     1
     (%o8)                 ---------------------
                                         2
                           sqrt(1 - m sin (phi))
     (%i9) diff (elliptic_f (phi, m), m);
            elliptic_e(phi, m) - (1 - m) elliptic_f(phi, m)
     (%o9) (-----------------------------------------------
                                   m

                                      cos(phi) sin(phi)
                                  - ---------------------)/(2 (1 - m))
                                                  2
                                    sqrt(1 - m sin (phi))

Die Implementierung der elliptischen Funktionen und Integrale wurde von
Raymond Toy geschrieben.  Der Code steht wie Maxima unter der General
Public License (GPL).


File: maxima.info,  Node: Funktionen und Variablen für Elliptische Funktionen,  Next: Funktionen und Variablen für Elliptische Integrale,  Prev: Einführung in Elliptische Funktionen und Integrale,  Up: Elliptische Funktionen und Integrale

22.6.2 Funktionen und Variablen für Elliptische Funktionen
----------------------------------------------------------

 -- Funktion: jacobi_sn (<u>, <m>)

     Die Jacobische elliptische Funktion sn(u,m).

 -- Funktion: jacobi_cn (<u>, <m>)

     Die Jacobische elliptische Funktion cn(u,m).

 -- Funktion: jacobi_dn (<u>, <m>)

     Die Jacobische elliptische Funktion dn(u,m).

 -- Funktion: jacobi_ns (<u>, <m>)

     Die Jacobische elliptische Funktion ns(u,m) = 1/sn(u,m).

 -- Funktion: jacobi_sc (<u>, <m>)

     Die Jacobische elliptische Funktion sc(u,m) = sn(u,m)/cn(u,m).

 -- Funktion: jacobi_sd (<u>, <m>)

     Die Jacobische elliptische Funktion sd(u,m) = sn(u,m)/dn(u,m).

 -- Funktion: jacobi_nc (<u>, <m>)

     Die Jacobische elliptische Funktion nc(u,m) = 1/cn(u,m).

 -- Funktion: jacobi_cs (<u>, <m>)

     Die Jacobische elliptische Funktion cs(u,m) = cn(u,m)/sn(u,m).

 -- Funktion: jacobi_cd (<u>, <m>)

     Die Jacobische elliptische Funktion cd(u,m) = cn(u,m)/dn(u,m).

 -- Funktion: jacobi_nd (<u>, <m>)

     Die Jacobische elliptische Funktion nc(u,m) = 1/cn(u,m).

 -- Funktion: jacobi_ds (<u>, <m>)

     Die Jacobische elliptische Funktion ds(u,m) = dn(u,m)/sn(u,m).

 -- Funktion: jacobi_dc (<u>, <m>)

     Die Jacobische elliptische Funktion dc(u,m) = dn(u,m)/cn(u,m).

 -- Funktion: inverse_jacobi_sn (<u>, <m>)

     Die inverse Jacobische elliptische Funktion sn(u,m).

 -- Funktion: inverse_jacobi_cn (<u>, <m>)

     Die inverse Jacobische elliptische Funktion cn(u,m).

 -- Funktion: inverse_jacobi_dn (<u>, <m>)

     Die inverse Jacobische elliptische Funktion dn(u,m).

 -- Funktion: inverse_jacobi_ns (<u>, <m>)

     Die inverse Jacobische elliptische Funktion ns(u,m).

 -- Funktion: inverse_jacobi_sc (<u>, <m>)

     Die inverse Jacobische elliptische Funktion sc(u,m).

 -- Funktion: inverse_jacobi_sd (<u>, <m>)

     Die inverse Jacobische elliptische Funktion sd(u,m).

 -- Funktion: inverse_jacobi_nc (<u>, <m>)

     Die inverse Jacobische elliptische Funktion nc(u,m).

 -- Funktion: inverse_jacobi_cs (<u>, <m>)

     Die inverse Jacobische elliptische Funktion cs(u,m).

 -- Funktion: inverse_jacobi_cd (<u>, <m>)

     Die inverse Jacobische elliptische Funktion cd(u,m).

 -- Funktion: inverse_jacobi_nd (<u>, <m>)

     Die inverse Jacobische elliptische Funktion nc(u,m).

 -- Funktion: inverse_jacobi_ds (<u>, <m>)

     Die inverse Jacobische elliptische Funktion ds(u,m).

 -- Funktion: inverse_jacobi_dc (<u>, <m>)

     Die inverse Jacobische elliptische Funktion dc(u,m).


File: maxima.info,  Node: Funktionen und Variablen für Elliptische Integrale,  Prev: Funktionen und Variablen für Elliptische Funktionen,  Up: Elliptische Funktionen und Integrale

22.6.3 Funktionen und Variablen für Elliptische Integrale
---------------------------------------------------------

 -- Funktion: elliptic_f (<phi>, <m>)

     Das unvollständige elliptische Integral der ersten Art, das
     definiert ist als

     integrate(1/sqrt(1 - m*sin(x)^2), x, 0, phi)

     Siehe auch ‘elliptic_e’ und ‘elliptic_kc’.

 -- Funktion: elliptic_e (<phi>, <m>)

     Das unvollständige elliptische Integral der zweiten Art, das
     definiert ist als

     elliptic_e(phi, m) = integrate(sqrt(1 - m*sin(x)^2), x, 0, phi)

     Siehe auch ‘elliptic_e’ und ‘elliptic_ec’.

 -- Funktion: elliptic_eu (<u>, <m>)

     Das unvollständige elliptische Integral der zweiten Art, das
     definiert ist als

     integrate(dn(v,m)^2,v,0,u) = integrate(sqrt(1-m*t^2)/sqrt(1-t^2),
     t, 0, tau)

     mit tau = sn(u,m).

     Dieses Integral steht in Beziehung zum elliptischen Integral
     ‘elliptiec_e’

     elliptic_eu(u, m) = elliptic_e(asin(sn(u,m)),m)

     Siehe auch ‘elliptic_e’.

 -- Funktion: elliptic_pi (<n>, <phi>, <m>)

     Das unvollständige elliptische Integral der dritten Art, das
     definiert ist als

     integrate(1/(1-n*sin(x)^2)/sqrt(1 - m*sin(x)^2), x, 0, phi)

     Maxima kennt nur die Ableitung nach der Variablen <phi>.

 -- Funktion: elliptic_kc (<m>)

     Das vollständige elliptische Integral der ersten Art, das definiert
     ist als

     integrate(1/sqrt(1 - m*sin(x)^2), x, 0, %pi/2)

     Für einige spezielle Argumente <m> kennt Maxima Werte mit der
     Gammafunktion ‘gamma’.  Die Werte können mit der Funktion
     ‘makegamma’ berechnet werden.

 -- Funktion: elliptic_ec (<m>)

     Das vollständige elliptische Integral der zweiten Art, das
     definiert ist als

     integrate(sqrt(1 - m*sin(x)^2), x, 0, %pi/2)

     Für einige spezielle Argumente <m> kennt Maxima Werte mit der
     Gammafunktion ‘gamma’.  Die Werte können mit der Funktion
     ‘makegamma’ berechnet werden.


File: maxima.info,  Node: Hypergeometrische Funktionen,  Next: Weitere spezielle Funktionen,  Prev: Elliptische Funktionen und Integrale,  Up: Spezielle Funktionen

22.7 Hypergeometrische Funktionen
=================================

 -- Funktion: %m [<k>, <u>] (<z>)

     Ist die Whittaker M Funktion ‘M[k,u](z) = exp(-z/2) * z^(1/2+u) *
     M(1/2+u-k, 1+2*u, z)’.  Siehe A & S 13.1.32 für die Definition.

 -- Funktion: %w [<k>, <u>] (<z>)

     Ist die Whittaker W Funktion.  Siehe A & S 13.1.33 für die
     Definition.

 -- Funktion: %f [<p>,<q>] (<[a], [b], z>)

     Ist die hypergeometrische Funktion ‘F[p,q](a_1, ..., a_p; b_1,...,
     b_q; z)’.  Das Argument <a> ist eine Liste mit den <p>-Elementen
     <a_i> und das Argument <b> die Liste mit den <q>-Elementen <b_i>.

 -- Funktion: hypergeometric ([<a_1>, …, <a_p>], [<b_1>, … ,<b_q>], z)

     Ist die hypergeometrische Funktion.  Im Unterschied zu den
     Funktionen ‘%f’ und ‘hgfred’, ist die Funktion ‘hypergeometric’
     eine vereinfachende Funktion.  ‘hypergeometric’ unterstützt die
     Berechnung von numerischen Werten für reelle und komplexe
     Gleitkommazahlen in doppelter und mit beliebiger Genauigkeit.  Für
     die Gaußsche hypergeometrische Funktion ist p = 2 und q = 1.  In
     diesem Fall wird auch die numerische Berechnung außerhalb des
     Einheitskreises unterstützt.

     Hat die Optionsvariable ‘expand_hypergeometric’ den Wert ‘true’,
     das ist der Standardwert, und eines der Argumente ‘a_1’, …, ‘a_p’
     ist eine negative ganze Zahl, gibt ‘hypergeometric’ ein Polynom
     zurück.

     Beispiel:

           (%i1)  hypergeometric([],[],x);
           (%o1) %e^x

     Expansion in ein Polynom für eine negative ganze Zahl, wenn die
     Optionsvariable ‘expand_hypergeometric’ den Wert ‘true’ hat.

           (%i2) hypergeometric([-3],[7],x);
           (%o2) hypergeometric([-3],[7],x)

           (%i3) hypergeometric([-3],[7],x), expand_hypergeometric : true;
           (%o3) -x^3/504+3*x^2/56-3*x/7+1

     Numerische Berechnung in doppelter und beliebiger
     Gleitkommagenauigkeit.

          (%i4) hypergeometric([5.1],[7.1 + %i],0.42);
          (%o4)       1.346250786375334 - 0.0559061414208204 %i
          (%i5) hypergeometric([5,6],[8], 5.7 - %i);
          (%o5)     .007375824009774946 - .001049813688578674 %i
          (%i6) hypergeometric([5,6],[8], 5.7b0 - %i), fpprec : 30;
          (%o6) 7.37582400977494674506442010824b-3
                                    - 1.04981368857867315858055393376b-3 %i

 -- Funktion: parabolic_cylinder_d (<v>, <z>)

     Die parabolische Zylinderfunktion ‘parabolic_cylinder_d(v,z)’.

     Die parabolischen Zylinderfunktionen sind in Abramowitz and Stegun,
     Handbook of Mathematical Functions, Kapitel 19 definiert.

     Die parabolischen Zylinderfunktionen können als Ergebnis der
     Funktion ‘hgfred’ auftreten.  Maxima kennt keine weiteren
     Eigenschaften.


File: maxima.info,  Node: Weitere spezielle Funktionen,  Prev: Hypergeometrische Funktionen,  Up: Spezielle Funktionen

22.8 Weitere spezielle Funktionen
=================================

 -- Funktion: li [<s>] (<z>)

     Ist der Polylogarithmus der Ordnung <s> mit dem Argument <z>.  Der
     Polylogarithmus wird durch die folgende Reihe definiert werden:

                                           inf
                                           ====   k
                                           \     z
                                  Li (z) =  >    --
                                    s      /      s
                                           ====  k
                                           k = 1

     Für <s=1> geht der Polylogarithmus in die gewöhnliche
     Logarithmusfunktion über und man erhält ‘-log(1-z)’.  Für <s=2>
     oder <s=3> spricht man vom Dilogarithmus oder Trilogarithmus.

     Maxima vereinfacht für <s=1> sofort zum gewöhnlichen Logarithmus.
     Für negative ganze Zahlen <s> einschließlich der Null vereinfacht
     Maxima den Polylogarithmus zu einer rationalen Funktion.

     Ist <s=2> oder <s=3> und das Argument <z> eine Gleitkommazahl,
     vereinfacht Maxima den Di- oder Trilogarithmus zu einer
     Gleitkommazahl.

     Beispiele:

          (%i1) assume (x > 0);
          (%o1)                        [x > 0]
          (%i2) integrate ((log (1 - t)) / t, t, 0, x);
          (%o2)                       - li (x)
                                          2
          (%i3) li [2] (7);
          (%o3)                        li (7)
                                         2
          (%i4) li [2] (7), numer;
          (%o4)        1.24827317833392 - 6.113257021832577 %i
          (%i5) li [3] (7);
          (%o5)                        li (7)
                                         3
          (%i6) li [2] (7), numer;
          (%o6)        1.24827317833392 - 6.113257021832577 %i
          (%i7) L : makelist (i / 4.0, i, 0, 8);
          (%o7)   [0.0, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0]
          (%i8) map (lambda ([x], li [2] (x)), L);
          (%o8) [0, .2676526384986274, .5822405249432515,
          .9784693966661848, 1.64493407, 2.190177004178597
           - .7010261407036192 %i, 2.374395264042415
           - 1.273806203464065 %i, 2.448686757245154
           - 1.758084846201883 %i, 2.467401098097648
           - 2.177586087815347 %i]
          (%i9) map (lambda ([x], li [3] (x)), L);
          (%o9) [0, .2584613953442624, 0.537213192678042,
          .8444258046482203, 1.2020569, 1.642866878950322
           - .07821473130035025 %i, 2.060877505514697
           - .2582419849982037 %i, 2.433418896388322
           - .4919260182322965 %i, 2.762071904015935
           - .7546938285978846 %i]

 -- Funktion: specint (exp(- s*<t>) * <expr>, <t>)

     Berechnet die Laplace-Transformation des Ausdrucks <expr> für die
     Integrationsvariable <t>.  <s> ist der Parameter der
     Laplace-Transformation.  Der Integrand <expr> kann spezielle
     Funktionen der Mathematik enthalten.

     Die folgenden speziellen Funktionen können als Integrand auftreten:
     die unvollständige Gammafunkion ‘gamma_incomplete’, die
     Fehlerfunktionen ‘erf’ und ‘erfc’, nicht jedoch die Funktion
     ‘erfi’, die jedoch in eine andere Fehlerfunktion transformiert
     werden kann, die Exponentiellen Integrale wie zum Beispiel
     ‘expintegral_e1’, die Bessel-Funktionen wie zum Beispiel
     ‘bessel_j’, einschließlich der Produkte von Bessel-Funktionen,
     Hankel-Funktionen wie zum Beispiel ‘hankel_1’, Hermite ‘hermite’
     und Laguerre Polynome ‘laguerre’.  Weiterhin kann ‘specint’
     Integranden mit der Hypergeometrische Funktion ‘%f[p,q]([],[],z)’,
     die Whittaker Funktion der ersten Art ‘%m[u,k](z)’ und die der
     zweiten Art ‘%w[u,k](z)’ integrieren.

     Das Ergebnis kann spezielle Funktionen und die Hypergeometrische
     Funktion enthalten.

     Kann die Funktion ‘laplace’ keine Laplace-Transformation finden,
     wird ‘specint’ aufgerufen.  Da die Funktion ‘laplace’ einige
     allgemeine Regeln kennt, um die Laplace-Transformation zu finden,
     ist es von Vorteil die Laplace-Transformation mit der Funktion
     ‘laplace’ zu berechnen.

     ‘demo(hypgeo)’ zeigt einige Beispiele für Laplace-Transformationen
     mit der Funktion ‘specint’.

     Beispiele:

          (%i1) assume (p > 0, a > 0)$
          (%i2) specint (t^(1/2) * exp(-a*t/4) * exp(-p*t), t);
                                     sqrt(%pi)
          (%o2)                     ------------
                                           a 3/2
                                    2 (p + -)
                                           4
          (%i3) specint (t^(1/2) * bessel_j(1, 2 * a^(1/2) * t^(1/2))
                        * exp(-p*t), t);
                                             - a/p
                                   sqrt(a) %e
          (%o3)                    ---------------
                                          2
                                         p

     Beispiel mit Exponentiellen Integralen.

          (%i4) assume(s>0,a>0,s-a>0)$
          (%i5) ratsimp(specint(%e^(a*t)
                                *(log(a)+expintegral_e1(a*t))*%e^(-s*t),t));
                                       log(s)
          (%o5)                        ------
                                       s - a
          (%i6) logarc:true$
          (%i7) gamma_expand:true$

          radcan(specint((cos(t)*expintegral_si(t)
                               -sin(t)*expintegral_ci(t))*%e^(-s*t),t));
                                       log(s)
          (%o8)                        ------
                                        2
                                       s  + 1
          ratsimp(specint((2*t*log(a)+2/a*sin(a*t)
                                -2*t*expintegral_ci(a*t))*%e^(-s*t),t));
                                         2    2
                                    log(s  + a )
          (%o9)                     ------------
                                          2
                                         s

     Entwicklung der unvollständigen Gammafunktion und Wechsel in eine
     Darstellung mit dem Exponentiellen Integral ‘expintegral_e1’.

          (%i10) assume(s>0)$
          (%i11) specint(1/sqrt(%pi*t)*unit_step(t-k)*%e^(-s*t),t);
                                                      1
                                      gamma_incomplete(-, k s)
                                                      2
          (%o11)                      ------------------------
                                         sqrt(%pi) sqrt(s)

          (%i12) gamma_expand:true$
          (%i13) specint(1/sqrt(%pi*t)*unit_step(t-k)*%e^(-s*t),t);
                                        erfc(sqrt(k) sqrt(s))
          (%o13)                        ---------------------
                                               sqrt(s)

          (%i14) expintrep:expintegral_e1$
          (%i15) ratsimp(specint(1/(t+a)^2*%e^(-s*t),t));
                                        a s
                                  a s %e    expintegral_e1(a s) - 1
          (%o15)                - ---------------------------------
                                                  a

 -- Funktion: hgfred (<a>, <b>, <z>)

     Vereinfacht die Hypergeometrische Funktion zu einfacheren
     Funktionen, wie Polynome und spezielle Funktionen.  Die
     Hypergeometrische Funktion ist die verallgemeinerte geometrische
     Reihe und ist wie folgt definiert:

             F    (a_1, ... a_p; b_1, ..., b_q; z) =
              p, q

                       inf      p                    q                k
                       ====   /===\ gamma(k + a )  /===\   gamma(b ) z
                       \       ! !             i    ! !           j
                     =  >      ! !  -------------   ! !  ----------------
                       /       ! !    gamma(a )     ! !  k! gamma(k + b )
                       ====   i = 1          i     j = 1               j
                       k = 0

     Die Argumente <a> und <b> sind Listen mit den Parametern der
     Hypergeometrischen Funktion ‘a_1’, …, ‘a_p’ sowie ‘b_1’, …, ‘b_p’.
     Die Liste <a> enthält die ‘p’-Elemente <a_i> und die Liste <b>
     enthält die <q>-Elemente <b_i>.

     Kann ‘hgfred’ die Hypergeomentrische Funktion nicht vereinfachen,
     wird eine Substantivform ‘%f[p,q]([a], [b], z)’ zurückgegeben.

     Beispiele:

          (%i1) assume(not(equal(z,0)));
          (%o1)                          [notequal(z, 0)]
          (%i2) hgfred([v+1/2],[2*v+1],2*%i*z);

                               v/2                               %i z
                              4    bessel_j(v, z) gamma(v + 1) %e
          (%o2)               ---------------------------------------
                                                 v
                                                z
          (%i3) hgfred([1,1],[2],z);

                                             log(1 - z)
          (%o3)                            - ----------
                                                 z
          (%i4) hgfred([a,a+1/2],[3/2],z^2);

                                         1 - 2 a          1 - 2 a
                                  (z + 1)        - (1 - z)
          (%o4)                   -------------------------------
                                           2 (1 - 2 a) z

 -- Funktion: lambert_w (<z>)

     Der Hauptzweig der Lambert W Funktion, die Lösung von ‘z = W(z) *
     exp(W(z))’.

 -- Funktion: nzeta (<z>)

     Die Plasma Dispersion Funktion ‘nzeta(z) =
     %i*sqrt(%pi)*exp(-z^2)*(1-erf(-%i*z))’.

 -- Funktion: nzetar (<z>)

     Gibt ‘realpart(nzeta(z))’ zurück.

 -- Funktion: nzetai (<z>)

     Gibt ‘imagpart(nzeta(z))’ zurück.

 -- Funktion: %s [<u>,<v>] (<z>)

     Lommels kleine Funktion ‘s[u,v](z)’.  Siehe Gradshteyn & Ryzhik
     8.570.1.


File: maxima.info,  Node: Fourier-Transformationen,  Next: Muster und Regeln,  Prev: Spezielle Funktionen,  Up: Top

23 Fourier-Transformationen
***************************

* Menu:

* Einführung in die schnelle Fourier-Transformation::
* Funktionen und Variablen für die schnelle Fourier-Transformation::
* Einführung in Fourierreihen::
* Funktionen und Variablen für Fourierreihen::


File: maxima.info,  Node: Einführung in die schnelle Fourier-Transformation,  Next: Funktionen und Variablen für die schnelle Fourier-Transformation,  Prev: Fourier-Transformationen,  Up: Fourier-Transformationen

23.1 Einführung in die schnelle Fourier-Transformation
======================================================

Das Paket ‘fft’ enthält Funktionen für die numerische Berechnung der
schnellen Fourier Transformation (FFT - "Fast Fourier Transform").


File: maxima.info,  Node: Funktionen und Variablen für die schnelle Fourier-Transformation,  Next: Einführung in Fourierreihen,  Prev: Einführung in die schnelle Fourier-Transformation,  Up: Fourier-Transformationen

23.2 Funktionen und Variablen für die schnelle Fourier-Transformation
=====================================================================

 -- Funktion: polartorect (<r>, <t>)

     Transformiert komplexe Zahlen der Form ‘r %e^(%i t)’ in die
     Standardform ‘a + b %i’.  <r> ist der Betrag der komplexen Zahl und
     <t> die Phase.  Die Argumente <r> und <t> sind eindimensionale
     Arrays derselben Größe.  Die Größe der Arrays muss eine Potenz von
     2 sein.

     Die Werte der originalen Arrays werden durch den Realteil ‘a = r
     cos(t)’ und den Imaginärteil ‘b = r sin(t)’ ersetzt.

     ‘polartorect’ ist die inverse Funktion zu ‘recttopolar’.  Das
     Kommando ‘load("fft")’ lädt die Funktion.

 -- Funktion: recttopolar (<a>, <b>)

     Transformiert komplexe Zahlen der Form ‘a + b %i’ in die Polarform
     ‘r %e^(%i t)’.  <a> ist der Realteil und <b> der Imaginärteil der
     komplexen Zahl.  Die Argumente <a> und <b> sind eindimensionale
     Arrays derselben Größe.  Die Größe der Arrays muss eine Potenz von
     2 sein.

     Die Werte der originalen Arrays werden durch den Betrag ‘r =
     sqrt(a^2 + b^2’ und die Phase ‘t = atan2(b, a)’ ersetzt.  Die Phase
     ist ein Winkel in dem Bereich ‘-%pi’ bis ‘%pi’.

     ‘recttoploar’ ist die inverse Funktion zu ‘polartorect’.  Das
     Kommando ‘load("fft")’ lädt die Funktion.

 -- Funktion: inverse_fft (<y>)

     Berechnet die inverse schnelle Fourier-Transformation.  Das
     Argument <y> ist eine Liste oder ein Array mit den Daten, die zu
     transformieren sind.  Die Anzahl der Daten muss eine Potenz von 2
     sein.  Die Elemente müssen Zahlen (ganze, rationale,
     Gleitkommazahlen oder große Gleitkommazahlen) oder numerische
     Konstanten sein.  Weiterhin können die Elemente komplexe Zahlen ‘a
     + b*%i’ sein, wobei der Realteil und der Imaginärteil wiederum
     Zahlen oder numerische Konstanten sein müssen.

     ‘inverse_fft’ gibt ein neues Objekt vom selben Typ wie <y> zurück.
     Die Ergebnisse sind immer Gleitkommazahlen oder komplexe Zahlen ‘a
     + %i*b’, wobei ‘a’ und ‘b’ Gleitkommazahlen sind.

     Die inverse diskrete Fourier-Transformation ist wie folgt
     definiert.  Wenn ‘x’ das Ergebnis der inversen
     Fourier-Transformation ist, dann gilt für ‘j’ von 0 bis ‘n-1’

          x[j] = sum(y[k] exp(2 %i %pi j k / n), k, 0, n - 1)

     Mit dem Kommando ‘load("fft")’ wird die Funktion geladen.  Siehe
     auch ‘fft’ für die schnelle Fourier-Transformation.

     Beispiele:

     Reelle Daten.

          (%i1) load ("fft") $
          (%i2) fpprintprec : 4 $
          (%i3) L : [1, 2, 3, 4, -1, -2, -3, -4] $
          (%i4) L1 : inverse_fft (L);
          (%o4) [0.0, 14.49 %i - .8284, 0.0, 2.485 %i + 4.828, 0.0,
                                 4.828 - 2.485 %i, 0.0, - 14.49 %i - .8284]
          (%i5) L2 : fft (L1);
          (%o5) [1.0, 2.0 - 2.168L-19 %i, 3.0 - 7.525L-20 %i,
          4.0 - 4.256L-19 %i, - 1.0, 2.168L-19 %i - 2.0,
          7.525L-20 %i - 3.0, 4.256L-19 %i - 4.0]
          (%i6) lmax (abs (L2 - L));
          (%o6)                       3.545L-16

     Komplexe Daten.

          (%i1) load ("fft") $
          (%i2) fpprintprec : 4 $
          (%i3) L : [1, 1 + %i, 1 - %i, -1, -1, 1 - %i, 1 + %i, 1] $
          (%i4) L1 : inverse_fft (L);
          (%o4) [4.0, 2.711L-19 %i + 4.0, 2.0 %i - 2.0,
          - 2.828 %i - 2.828, 0.0, 5.421L-20 %i + 4.0, - 2.0 %i - 2.0,
          2.828 %i + 2.828]
          (%i5) L2 : fft (L1);
          (%o5) [4.066E-20 %i + 1.0, 1.0 %i + 1.0, 1.0 - 1.0 %i,
          1.55L-19 %i - 1.0, - 4.066E-20 %i - 1.0, 1.0 - 1.0 %i,
          1.0 %i + 1.0, 1.0 - 7.368L-20 %i]
          (%i6) lmax (abs (L2 - L));
          (%o6)                       6.841L-17

 -- Funktion: fft (<x>)

     Berechnet die schnelle Fourier-Transformation.  Das Argument <x>
     ist eine Liste oder ein Array mit den Daten, die zu transformieren
     sind.  Die Anzahl der Elemente muss eine Potenz von 2 sein.  Die
     Elemente müssen Zahlen (ganze, rationale, Gleitkommazahlen oder
     große Gleitkommazahlen) oder numerische Konstanten sein.  Weiterhin
     können die Elemente komplexe Zahlen ‘a + b*%i’ sein, wobei der
     Realteil und der Imaginärteil wiederum Zahlen oder numerische
     Konstanten sein müssen.

     ‘inverse_fft’ gibt ein neues Objekt vom selben Typ wie <x> zurück.
     Die Ergebnisse sind immer Gleitkommazahlen oder komplexe Zahlen ‘a
     + %i*b’, wobei ‘a’ und ‘b’ Gleitkommazahlen sind.

     Die diskrete Fourier-Transformation ist wie folgt definiert.  Wenn
     ‘y’ das Ergebnis der Fourier-Transformation ist, dann gilt für ‘k’
     von 0 bis ‘n-1’

          y[k] = (1/n) sum(x[j] exp(-2 %i %pi j k / n), j, 0, n - 1)

     Sind die Daten <x> reelle Zahlen, dann werden die reellen
     Koeffizienten <a> und <b> so berechnet, dass gilt

          x[j] = sum (a[k] * cos (2*%pi*j*k / n)
                    + b[k] * sin (2*%pi*j*k / n), k, 0, n/2)

     wobei

          a[0] = realpart (y[0])
          b[0] = 0

     und für <k> von 1 bis ‘n/2-1’

          a[k] = realpart (y[k] + y[n - k])
          b[k] = imagpart (y[n - k] - y[k])

     sowie

          a[n/2] = realpart (y[n/2])
          b[n/2] = 0

     Das Kommando ‘load("fft")’ lädt die Funktion.  Siehe auch
     ‘inverse_fft’ für die inverse schnelle Fourier-Transformation.

     Beispiele:

     Reelle Daten.

          (%i1) load ("fft") $
          (%i2) fpprintprec : 4 $
          (%i3) L : [1, 2, 3, 4, -1, -2, -3, -4] $
          (%i4) L1 : fft (L);
          (%o4) [0.0, - 1.811 %i - .1036, 0.0, .6036 - .3107 %i, 0.0,
                                   .3107 %i + .6036, 0.0, 1.811 %i - .1036]
          (%i5) L2 : inverse_fft (L1);
          (%o5) [1.0, 2.168L-19 %i + 2.0, 7.525L-20 %i + 3.0,
          4.256L-19 %i + 4.0, - 1.0, - 2.168L-19 %i - 2.0,
          - 7.525L-20 %i - 3.0, - 4.256L-19 %i - 4.0]
          (%i6) lmax (abs (L2 - L));
          (%o6)                       3.545L-16

     Komplexe Daten.

          (%i1) load ("fft") $
          (%i2) fpprintprec : 4 $
          (%i3) L : [1, 1 + %i, 1 - %i, -1, -1, 1 - %i, 1 + %i, 1] $
          (%i4) L1 : fft (L);
          (%o4) [0.5, .3536 %i + .3536, - 0.25 %i - 0.25,
          0.5 - 6.776L-21 %i, 0.0, - .3536 %i - .3536, 0.25 %i - 0.25,
          0.5 - 3.388L-20 %i]
          (%i5) L2 : inverse_fft (L1);
          (%o5) [1.0 - 4.066E-20 %i, 1.0 %i + 1.0, 1.0 - 1.0 %i,
          - 1.008L-19 %i - 1.0, 4.066E-20 %i - 1.0, 1.0 - 1.0 %i,
          1.0 %i + 1.0, 1.947L-20 %i + 1.0]
          (%i6) lmax (abs (L2 - L));
          (%o6)                       6.83L-17

     Berechnung der Sinus- und Kosinus-Koeffizienten.

          (%i1) load ("fft") $
          (%i2) fpprintprec : 4 $
          (%i3) L : [1, 2, 3, 4, 5, 6, 7, 8] $
          (%i4) n : length (L) $
          (%i5) x : make_array (any, n) $
          (%i6) fillarray (x, L) $
          (%i7) y : fft (x) $
          (%i8) a : make_array (any, n/2 + 1) $
          (%i9) b : make_array (any, n/2 + 1) $
          (%i10) a[0] : realpart (y[0]) $
          (%i11) b[0] : 0 $
          (%i12) for k : 1 thru n/2 - 1 do
             (a[k] : realpart (y[k] + y[n - k]),
              b[k] : imagpart (y[n - k] - y[k]));
          (%o12)                        done
          (%i13) a[n/2] : y[n/2] $
          (%i14) b[n/2] : 0 $
          (%i15) listarray (a);
          (%o15)          [4.5, - 1.0, - 1.0, - 1.0, - 0.5]
          (%i16) listarray (b);
          (%o16)           [0, - 2.414, - 1.0, - .4142, 0]
          (%i17) f(j) := sum (a[k] * cos (2*%pi*j*k / n) + b[k]
                                   * sin (2*%pi*j*k / n), k, 0, n/2) $
          (%i18) makelist (float (f (j)), j, 0, n - 1);
          (%o18)      [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]

 -- Funktion: horner (<expr>, <x>)
 -- Funktion: horner (<expr>)

     Formt ein Polynom <expr> in das Horner-Schema um.  Mit <x> wird die
     Variable angegeben, für die das Horner-Schema zu bilden ist.  Wird
     das Argument <x> nicht angegeben, wird die Hauptvariable des
     kanonischen Ausdrucks <expr> für die Bildung des Horner-Schemas
     genutzt.

     Das Horner-Schema kann die Stabilität der numerischen Berechnung
     eines Ausdrucks verbessern.

     Beispiel:

          (%i1) expr: 1e-155*x^2 - 5.5*x + 5.2e155;
                                     2
          (%o1)            1.0E-155 x  - 5.5 x + 5.2E+155
          (%i2) expr2: horner (%, x), keepfloat: true;
          (%o2)            (1.0E-155 x - 5.5) x + 5.2E+155
          (%i3) ev (expr, x=1e155);
          Maxima encountered a Lisp error:

           floating point overflow

          Automatically continuing.
          To reenable the Lisp debugger set *debugger-hook* to nil.
          (%i4) ev (expr2, x=1e155);
          (%o4)                       7.0E+154

 -- Funktion: find_root (<expr>, <x>, <a>, <b>)
 -- Funktion: find_root (<f>, <a>, <b>)
 -- Optionsvariable: find_root_error
 -- Optionsvariable: find_root_abs
 -- Optionsvariable: find_root_rel

     Findet die Nullstellen eines Ausdrucks <expr> oder einer Funktion
     <f> in dem Intervall ‘[<a>, <b>]’.  Der Ausdruck <expr> kann eine
     Gleichung sein.  In diesem Fall sucht die Funktion ‘find_root’ die
     Nullstellen für den Ausdruck ‘lhs(<expr>) - rhs(<expr>)’.

     Kann Maxima den Ausdruck <expr> oder die Funktion <f> in dem
     Intervall ‘[<a>, <b>]’ für alle Werte auswerten und ist der
     Ausdruck <expr> oder die Funktion <f> in dem Intervall stetig, dann
     ist sicher, dass ‘find_root’ die Nullstelle oder zumindest eine
     Nullstelle findet, wenn mehrere Nullstellen vorhanden sind.

     ‘find_root’ beginnt mit einer binären Suche der Nullstelle.
     Erscheint die Funktion als glatt genug, wendet Maxima einen
     Algorithmus mit einer linearen Interpolation für die Suche der
     Nullstelle an.

     Die Genauigkeit der Nullstellensuche wird von den Optionsvariablen
     ‘find_root_abs’ und ‘find_root_rel’ kontrolliert.  ‘find_root’
     endet, wenn die Auswertung der Funktion ein Ergebnis hat, das
     kleiner als ‘find_root_abs’ ist oder wenn aufeinander folgende
     Auswertungen Ergebnisse <x_0> und <x_1> haben, die sich voneinander
     weniger als ‘find_root_rel * max(abs(x_0), abs(x_1))’
     unterscheiden.  Der Standardwert der Optionsvariablen
     ‘find_root_abs’ und ‘find_root_rel’ ist Null.

     ‘find_root’ erwartet, dass die Funktion an den Endpunkten des
     Intervalls für die Nullstellensuche ein unterschiedliches
     Vorzeichen hat.  Hat die Funktion an den Endpunkten des Intervalls
     dasselbe Vorzeichen, wird das Verhalten der Funktion ‘find_root’
     von der Optionsvariablen ‘find_root_error’ kontrolliert.  Hat
     ‘find_root_error’ den Wert ‘true’, wird eine Fehlermeldung
     ausgegeben.  Ansonsten wird von ‘find_root’ der Wert von
     ‘find_root_error’ als Ergebnis zurückgegeben.  Der Standardwert von
     ‘find_root_error’ ist ‘true’.

     Kann die Funktion <f> bei der Nullstellensuche nicht zu einer Zahl
     ausgewertet werden, gibt ‘find_root’ ein teilweise ausgewertetes
     Ergebnis zurück.

     Die Reihenfolge der Grenzen des Intervalls <a> und <b> wird
     ignoriert.  ‘find_root’ sucht die Nullstellen immer in dem
     Intervall ‘[min(<a>, <b>), max(<a>, <b>)]’.

     Beispiele:

          (%i1) f(x) := sin(x) - x/2;
                                                  x
          (%o1)                  f(x) := sin(x) - -
                                                  2
          (%i2) find_root (sin(x) - x/2, x, 0.1, %pi);
          (%o2)                   1.895494267033981
          (%i3) find_root (sin(x) = x/2, x, 0.1, %pi);
          (%o3)                   1.895494267033981
          (%i4) find_root (f(x), x, 0.1, %pi);
          (%o4)                   1.895494267033981
          (%i5) find_root (f, 0.1, %pi);
          (%o5)                   1.895494267033981
          (%i6) find_root (exp(x) = y, x, 0, 100);
                                      x
          (%o6)           find_root(%e  = y, x, 0.0, 100.0)
          (%i7) find_root (exp(x) = y, x, 0, 100), y = 10;
          (%o7)                   2.302585092994046
          (%i8) log (10.0);
          (%o8)                   2.302585092994046


File: maxima.info,  Node: Einführung in Fourierreihen,  Next: Funktionen und Variablen für Fourierreihen,  Prev: Funktionen und Variablen für die schnelle Fourier-Transformation,  Up: Fourier-Transformationen

23.3 Einführung in Fourierreihen
================================

Das Paket ‘fourie’ enthält Funktionen für die symbolische Berechnungen
von Fourierreihen.  Weiterhin enthält das Paket Funktionen, um
Fourierkoeffizienten zu berechnen und einige weitere Funktionen.


File: maxima.info,  Node: Funktionen und Variablen für Fourierreihen,  Prev: Einführung in Fourierreihen,  Up: Fourier-Transformationen

23.4 Funktionen und Variablen für Fourierreihen
===============================================

 -- Funktion: equalp (<x>, <y>)

     Gibt ‘true’ zurück, wenn ‘equal(<x>, <y>)’ das Ergebnis ‘true’ hat.
     Ansonsten ist das Ergebnis ‘false’.

 -- Funktion: remfun (<f>, <expr>)
 -- Funktion: remfun (<f>, <expr>, <x>)

     ‘remfun(<f>, <expr>’ ersetzt ‘<f>(<arg>)’ durch <arg> im Ausdruck
     <expr>.

     ‘remfun(<f>, <expr>, <x>)’ ersetzt ‘<f> (<arg>)’ durch <arg> im
     Ausdruck <expr> nur dann, wenn <arg> die Variable <x> enthält.

 -- Funktion: funp (<f>, <expr>)
 -- Funktion: funp (<f>, <expr>, <x>)

     ‘funp(<f>, <expr>)’ hat das Ergebnis ‘true’, wenn der Ausdruck
     <expr> die Funktion <f> enthält.

     ‘funp(<f>, <expr>, <x>)’ hat das Ergebnis ‘true’, wenn der Ausdruck
     <expr> die Funktion <f> enthält und die Variable <x> ein Argument
     der Funktion <f> ist.

 -- Funktion: absint (<f>, <x>, <halfplane>)
 -- Funktion: absint (<f>, <x>)
 -- Funktion: absint (<f>, <x>, <a>, <b>)

     ‘absint(<f>, <x>, <halfplane>)’ gibt das unbestimmte Integral der
     Funktion <f> für die Variable <x> zurück.  Das Integral wird in der
     angegebenen Halbebene ‘pos’, ‘neg’ oder für beide Halbebenen mit
     ‘both’ berechnet.  Der Integrand kann die Betragsfunktion
     enthalten: ‘abs(x)’, ‘abs(sin(x))’, ‘abs(a) * exp(-abs(b) *
     abs(x))’.

     ‘absint(<f>, <x>)’ ist äquivalent zu ‘absint(<f>, <x>, pos)’.

     ‘absint(<f>, <x>, <a>, <b>)’ gibt das bestimmte Integral der
     Funktion <f> für die Variable <x> in den Grenzen <a> und <b>
     zurück.  Der Integrand kann die Betragsfunktion enthalten.

 -- Funktion: fourier (<f>, <x>, <l>)

     Berechnet die Fourier-Koeffizienten ‘a[0]’, ‘a[n]’ und ‘b[n]’ der
     Funktion ‘<f>(<x>)’ für das Intervall ‘[-l, l]’.  Die Fourierreihe
     ist definiert als:

                   inf
                   ====
                   \             %pi n x           %pi n x
            f(x) =  >    (b  sin(-------) + a  cos(-------))
                   /       n        l        n        l
                   ====
                   n = 0

     Die Koeffizienten der Fourierreihe werden folgendermaßen berechnet:

                               l
                              /
                          - 1 [
                a  = 1/2 l    I    f(x) dx
                 0            ]
                              /
                               - l

                           l
                          /
                      - 1 [                  - 1
                a  = l    I    f(x) cos(%pi l    n x) dx
                 n        ]
                          /
                           - l

                            l
                           /
                      - 1 [                  - 1
                b  = l    I    f(x) sin(%pi l    n x) dx
                 n        ]
                          /
                           - l

     ‘fourier’ weist die Fourier-Koeffizienten Zwischenmarken zu.  Die
     Zwischenmarken werden als eine Liste zurückgegeben.

     Der Index der Summe ist immer das Symbol <n>.  Sinus- und
     Kosinusfunktionen mit ganzzahligen Vielfachen von ‘%pi’ werden
     nicht automatisch vereinfacht.  Dies kann mit der Funktion
     ‘foursimp’ erreicht werden, der als Argument die Liste der
     Fourier-Koeffizienten übergeben wird.

     Mit der Funktion ‘fourexpand’ kann die Fourierreihe aus den
     Fourier-Koeffizienten konstruiert werden.  Siehe auch die Funktion
     ‘totalfourier’.

     Mit den Funktionen ‘fourcos’ und ‘foursin’ werden jeweils die
     Koeffizienten der Kosinus- und Sinus-Entwicklung berechnet.

     Beispiel:

          (%i1) load("fourie")$

          (%i2) fourier(x, x, 1);
          (%t2)                        a  = 0
                                        0

          (%t3)                        a  = 0
                                        n

                                  sin(%pi n)   cos(%pi n)
          (%t4)           b  = 2 (---------- - ----------)
                           n          2  2       %pi n
                                   %pi  n

          (%o4)                    [%t2, %t3, %t4]
          (%i5) foursimp(%);
          (%t5)                        a  = 0
                                        0

          (%t6)                        a  = 0
                                        n

                                                 n
                                          2 (- 1)
          (%t7)                    b  = - --------
                                    n      %pi n

          (%o7)                    [%t5, %t6, %t7]
          (%i8) fourexpand(%, x, 1, inf);
                                inf
                                ====       n
                                \     (- 1)  sin(%pi n x)
                              2  >    -------------------
                                /              n
                                ====
                                n = 1
          (%o8)             - ---------------------------
                                          %pi

 -- Funktion: foursimp (<l>)

     ‘foursimp’ wird auf das Ergebnis der Funktion ‘fourier’ angewendet,
     um Sinus- und Kosinus-Funktionen zu vereinfachen, die ganzzahlige
     Vielfache von ‘%pi’ enthalten.  Das Argument <l> ist eine Liste mit
     den Koeffizienten der Fourierreihe, für die die Vereinfachung
     ausgeführt werden soll.

     ‘sin(n %pi)’ wird zu ‘0’ vereinfacht, wenn die Optionsvariable
     ‘sinnpiflag’ den Wert ‘true’ hat, und ‘cos(n %pi)’ wird zu
     ‘(-1)^n’, wenn die Optionsvariable ‘cosnpiflag’ den Wert ‘true’
     hat.

     Siehe die Funktion ‘fourier’ für ein Beispiel.

 -- Optionsvariable: sinnpiflag
     Standardwert: ‘true’

     Kontrolliert die Vereinfachung der Sinus-Funktion durch die
     Funktion ‘foursimp’.  Siehe die Funktion ‘foursimp’.

 -- Optionsvariable: cosnpiflag
     Standardwert: ‘true’

     Kontrolliert die Vereinfachung der Kosinus-Funktion durch die
     Funktion ‘foursimp’.  Siehe die Funktion ‘foursimp’.

 -- Funktion: fourexpand (<l>, <x>, <p>, <limit>)

     Konstruiert aus der Liste der Fourier-Koeffizienten <l> eine
     Fourierreihe mit <limit> Termen.  Das Argument <limit> kann ‘inf’
     sein.  Die Argumente <x> und <p> haben dieselbe Bedeutung wie für
     die Funktion ‘fourier’.

     Siehe die Funktion ‘fourier’ für ein Beispiel.

 -- Funktion: fourcos (<f>, <x>, <p>)

     Gibt die Kosinus-Koeffizienten einer Fourierreihe für die Funktion
     ‘<f>(<x>)’ zurück, die auf dem Intervall ‘[0, <p>]’ definiert ist.

 -- Funktion: foursin (<f>, <x>, <p>)

     Gibt die Sinus-Koeffizienten einer Fourierreihe für die Funktion
     ‘<f>(<x>)’ zurück, die auf dem Intervall ‘[0, <p>]’ definiert ist.

 -- Funktion: totalfourier (<f>, <x>, <l>)

     Gibt die Fourierreihe der Funktion <f(x)> für das Intervall ‘[<-l>,
     <l>]’ zurück.  Das Ergebnis wird berechnet, indem die nacheinander
     die Funktionen ‘foursimp’ und ‘fourexpand’ auf das Ergebnis der
     Funktion ‘fourier’ angewendet werden.

     Beispiel:

          (%i1) load("fourie")$

          (%i2) totalfourier(x, x, 1);
          (%t2)                        a  = 0
                                        0

          (%t3)                        a  = 0
                                        n

                                  sin(%pi n)   cos(%pi n)
          (%t4)           b  = 2 (---------- - ----------)
                           n          2  2       %pi n
                                   %pi  n

          (%t5)                        a  = 0
                                        0

          (%t6)                        a  = 0
                                        n
                                                 n
                                          2 (- 1)
          (%t7)                    b  = - --------
                                    n      %pi n
                                inf
                                ====       n
                                \     (- 1)  sin(%pi n x)
                              2  >    -------------------
                                /              n
                                ====
                                n = 1
          (%o7)             - ---------------------------
                                          %pi

 -- Funktion: fourint (<f>, <x>)

     Konstruiert eine Liste der Fourierintegral-Koeffizienten der
     Funktion ‘<f>(<x>)’, die auf dem Intervall ‘[minf, inf]’ definiert
     ist.

 -- Funktion: fourintcos (<f>, <x>)

     Gibt die Koeffizienten des Kosinus-Fourierintegrals der Funktion
     ‘<f>(<x>)’ zurück, die auf dem Intervall ‘[0, inf]’ definiert ist.

 -- Funktion: fourintsin (<f>, <x>)

     Gibt die Koeffizienten des Sinus-Fourierintegrals der Funktion
     ‘<f>(<x>)’ zurück, die auf dem Intervall ‘[0, inf]’ definiert ist.


File: maxima.info,  Node: Muster und Regeln,  Next: Funktionsdefinitionen,  Prev: Fourier-Transformationen,  Up: Top

24 Muster und Regeln
********************

* Menu:

* Einführung in Muster und Regeln::
* Funktionen und Variablen für Muster und Regeln::


File: maxima.info,  Node: Einführung in Muster und Regeln,  Next: Funktionen und Variablen für Muster und Regeln,  Prev: Muster und Regeln,  Up: Muster und Regeln

24.1 Einführung in Muster und Regeln
====================================

Dieses Kapitel beschreibt nutzerdefinierte Muster und Regeln für die
Vereinfachung von Ausdrücken.  Es gibt zwei verschiedene Gruppen von
Funktionen, die einen unterschiedlichen Musterabgleich implementieren.
Die eine Gruppe enthält die Funktionen ‘tellsimp’, ‘tellsimpafter’,
‘defmatch’, ‘defrule’, ‘apply1’, ‘applyb1’ und ‘apply2’.  In der anderen
Gruppe sind die Funktionen ‘let’ und ‘letsimp’ enthalten.  Beide
Methoden verwenden Mustervariablen, die mit der Funktion ‘matchdeclare’
definiert werden.

Regeln, die mit den Funktionen ‘tellsimp’ und ‘tellsimpafter’ definiert
werden, werden von Maxima automatisch bei der Vereinfachung von
Ausdrücken angewendet.  Regeln, die mit den Funktionen ‘defmatch’,
‘defrule’ oder ‘let’ definiert werden, werden durch den Aufruf einer
Funktion auf einen Ausdruck angewendet.

Maxima kennt weitere Methoden wie die Definition von minimalen Polynomen
mit der Funktion ‘tellrat’, um Einfluss auf die Vereinfachung von
Polynomen zu nehmen, oder Funktionen der kommutativen und
nicht-kommutativen Algebra, die in dem Paket *note affine:: definiert
sind.


File: maxima.info,  Node: Funktionen und Variablen für Muster und Regeln,  Prev: Einführung in Muster und Regeln,  Up: Muster und Regeln

24.2 Funktionen und Variablen für Muster und Regeln
===================================================

 -- Optionsvariable: announce_rules_firing
     Standardwert: ‘false’

     Hat die Optionsvariable ‘announce_rules_firing’ den Wert ‘true’ und
     wird mit den Funktionen ‘tellsimp’ oder ‘tellsimpafter’ eine Regel
     definiert, dann wird immer dann eine Meldung ausgegeben, wenn die
     Regel angewendet wird.  ‘announce_rules_firing’ hat keinen Einfluss
     auf Regeln, die bereits definiert sind.  Die Meldung von Regeln
     kann auch nicht durch das Setzen von ‘announce_rules_firing’ auf
     den Wert ‘false’ abgeschaltet werden.

     Diese Optionsvariable ist nützlich, wenn die Anwendung von
     nutzerdefinierten Regeln für die Fehlersuche kontrolliert werden
     soll.

     Beispiel:

          (%i1) announce_rules_firing:true;
          (%o1)                         true
          (%i2) tellsimpafter(tan(x), sin(x)/cos(x));
          (%o2)                 [tanrule1, simp-%tan]
          (%i3) tan(x);

          By tanrule1 , tan(x) --> sin(x)/cos(x)
                                       sin(x)
          (%o3)                        ------
                                       cos(x)

 -- Funktion: apply1 (<expr>, <rule_1>, …, <rule_n>)

     Wendet die Regel <rule_1> auf den Ausdruck <expr> solange an, bis
     sich das Ergebnis nicht mehr ändert.  Die Regel wird zuerst auf der
     obersten Ebene des Ausdrucks und dann nacheinander von links nach
     rechts auf die Teilausdrücke angewendet.  Ist <expr_1> das Ergebnis
     der Anwendung der Regel <rule_1>, dann wird die Regel <rule_2> auf
     gleiche Weise auf den Ausdruck <expr_1> angewendet.  Zuletzt wird
     die Regel <rule_n> angewendet.  Das letzte Ergebnis wird
     zurückgegeben.

     Die Optionsvariable ‘maxapplydepth’ enthält die größte
     Verschachtelungstiefe, für die die Funktionen ‘apply1’ und ‘apply2’
     auf einen Ausdruck angewendet werden.

     Siehe auch die Funktionen ‘applyb1’ und ‘apply2’, um Regeln auf
     einen Ausdruck anzuwenden, die mit der Funktion ‘defrule’ definiert
     sind.

     Beispiele:

          (%i1) defrule(trig1, tan(x), sin(x)/cos(x));
                                                sin(x)
          (%o1)               trig1 : tan(x) -> ------
                                                cos(x)
          (%i2) defrule(trig2, cot(x), 1/tan(x));
                                                  1
          (%o2)               trig2 : cot(x) -> ------
                                                tan(x)
          (%i3) apply1(cot(x), trig1, trig2);
                                         1
          (%o3)                        ------
                                       tan(x)
          (%i4) apply1(cot(x), trig2, trig1);
                                       cos(x)
          (%o4)                        ------
                                       sin(x)

     Die folgenden Beispiele zeigen, wie mit der Optionsvariablen
     ‘maxapplydepth’ die Tiefe kontrolliert wird, in der eine Regel auf
     die Teilausdrücke angewendet wird.

          (%i1) expr: tan(x)+exp(a+2*tan(x));
                                          2 tan(x) + a
          (%o1)                tan(x) + %e
          (%i2) defrule(trig, tan(x), sin(x)/cos(x));
                                                sin(x)
          (%o2)                trig : tan(x) -> ------
                                                cos(x)
          (%i3) maxapplydepth: 1;
          (%o3)                           1
          (%i4) apply1(expr, trig);
                               sin(x)     2 tan(x) + a
          (%o4)                ------ + %e
                               cos(x)
          (%i5) maxapplydepth: 4;
          (%o5)                           4
          (%i6) apply1(expr, trig);
                                          2 sin(x)
                                          -------- + a
                               sin(x)      cos(x)
          (%o6)                ------ + %e
                               cos(x)

 -- Funktion: apply2 (<expr>, <rule_1>, …, <rule_n>)

     Zunächst werden nacheinander die Regeln <rule_1>, <rule_2>, … auf
     den Ausdruck <expr> angewendet.  Schlägt die Anwendung aller Regeln
     fehl, werden die Regeln nacheinander auf die Teilausdrücke des
     Argumentes <expr> angewendet.  Kann eine der Regeln erfolgreich
     angewendet werden, wird die Anwendung aller Regeln auf den
     Teilausdruck wiederholt.

     Im Unterschied zur Funktion ‘apply1’ werden von der Funktion
     ‘apply2’ immer alle Regeln angewendet.  Sind jedoch die Regeln, die
     als Argumente übergeben werden, zirkulär definiert, so führt Maxima
     eine Endlosschleife aus.  Siehe dazu auch das Beispiel unten.

     Die Optionsvariable ‘maxapplydepth’ enthält die größte
     Verschachtelungstiefe, für die die Funktionen ‘apply1’ und ‘apply2’
     auf einen Ausdruck angewendet werden.

     Siehe auch die Funktionen ‘apply1’ und ‘applyb1’, um Regeln auf
     einen Ausdruck anzuwenden, die mit der Funktion ‘defrule’ definiert
     sind.

     Beispiele:

     Im Unterschied zur Funktion ‘apply1’ ist in diesem Fall das
     Ergebnis immer ‘sin(x)/cos(x)’, da alle Regeln wiederholt auf einen
     Teilausdruck angewendet werden, wenn sich der Ausdruck für eine
     Regel ändert.

          (%i1) defrule(trig1, tan(x), sin(x)/cos(x));
                                                sin(x)
          (%o1)               trig1 : tan(x) -> ------
                                                cos(x)
          (%i2) defrule(trig2, cot(x), 1/tan(x));
                                                  1
          (%o2)               trig2 : cot(x) -> ------
                                                tan(x)
          (%i3) apply2(cot(x), trig1, trig2);
                                       cos(x)
          (%o3)                        ------
                                       sin(x)
          (%i4) apply2(cot(x), trig2, trig1);
                                       cos(x)
          (%o4)                        ------
                                       sin(x)

     Das folgende Beispiel zeigt eine zirkuläre Definition der Regeln
     ‘trig1’ und ‘trig2’.  Mit der Funktion ‘apply1’ hängt das Ergebnis
     von der Reihenfolge der Anwendung der Regeln ab.  Die Anwendung der
     Funktion ‘apply2’ führt für dieses Beispiel zu einer
     Endlosschleife.

          (%i1) defrule(trig1, tan(x), sin(x)/cos(x));
                                                sin(x)
          (%o1)               trig1 : tan(x) -> ------
                                                cos(x)
          (%i2) defrule(trig2, sin(x)/cos(x), tan(x));
                                      sin(x)
          (%o2)               trig2 : ------ -> tan(x)
                                      cos(x)
          (%i3) expr: tan(x) + exp(sin(x)/cos(x));
                                             sin(x)
                                             ------
                                             cos(x)
          (%o3)                   tan(x) + %e
          (%i4) apply1(expr, trig1, trig2);
                                             tan(x)
          (%o4)                   tan(x) + %e
          (%i5) apply1(expr, trig2, trig1);
                                             sin(x)
                                             ------
                                  sin(x)     cos(x)
          (%o5)                   ------ + %e
                                  cos(x)

 -- Funktion: applyb1 (<expr>, <rule_1>, …, <rule_n>)

     Wendet die Regel <rule_1> auf den tiefsten Teilausdruck in der
     Baumstruktur eines Ausdrucks an.  Schlägt die Anwendung fehl, wird
     der Teilausdruck eine Ebene höher betrachtet, bis <rule_1> auf die
     oberste Ebene des Ausdrucks <expr> angewendet wird.  Danach wird
     auf gleiche Weise die Regel <rule_2> auf den Ausdruck <expr>
     angewendet.  Nachdem die letzte Regel <rule_n> angewendet wurde,
     wird das Ergebnis zurückgegeben.

     ‘applyb1’ ist vergleichbar mit ‘apply1’ mit dem Unterschied, dass
     die Regeln Bottom-Up angewendet werden.

     Die Optionsvariable ‘maxapplyheight’ enthält den Wert der größten
     Verschachtelungstiefe, für die ‘applyb1’ angewendet wird.

     Siehe auch die Funktionen ‘apply1’ und ‘apply2’, um Regeln auf
     einen Ausdruck anzuwenden, die mit der Funktion ‘defrule’ definiert
     sind.

     Beispiel:

     Das folgende Beispiel zeigt, wie die Regel ‘trig’ zuerst auf die
     unterste Ebene des Ausdrucks angewendet wird.  Dazu wird die
     Optionsvariable ‘maxapplyheight’ zunächst auf den Wert ‘1’ gesetzt
     und dann auf den Wert ‘4’ erhöht.

          (%i1) matchdeclare(x, true);
          (%o1)                         done
          (%i2) defrule(trig, tan(x), sin(x)/cos(x));
                                                sin(x)
          (%o2)                trig : tan(x) -> ------
                                                cos(x)
          (%i3) expr: exp(a+2*tan(b+exp(tan(x))));
                                        tan(x)
                                2 tan(%e       + b) + a
          (%o3)               %e
          (%i4) maxapplyheight: 1;
          (%o4)                           1
          (%i5) applyb1(expr, trig);
                                        sin(x)
                                        ------
                                        cos(x)
                                2 tan(%e       + b) + a
          (%o5)               %e
          (%i6) maxapplyheight: 4;
          (%o6)                           4
          (%i7) applyb1(expr, trig);
                                        sin(x)
                                        ------
                                        cos(x)
                                2 sin(%e       + b)
                                ------------------- + a
                                       sin(x)
                                       ------
                                       cos(x)
                                 cos(%e       + b)
          (%o7)               %e

 -- Funktion: clear_rules ()

     Führt das Kommando ‘kill(rules)’ aus und setzt die internen Zähler
     für die Benennung der Regeln für die Addition, die Multiplikation
     und die Exponentiation auf den Anfangswert zurück.  Mit dem
     Kommando ‘kill(rules)’ werden alle Regeln entfernt, ohne dass die
     internen Zähler zurückgesetzt werden.  Siehe auch die Funktion
     ‘kill’.

     Beispiel:

          (%i1) tellsimpafter(a+b, add(a,b));
          (%o1)                   [+rule1, simplus]
          (%i2) tellsimpafter(a*b, mul(a,b));
          (%o2)                  [*rule1, simptimes]
          (%i3) tellsimpafter(a^b, expt(a,b));
          (%o3)                  [^rule1, simpexpt]
          (%i4) rules;
          (%o4)               [+rule1, *rule1, ^rule1]
          (%i5) clear_rules();
          (%o5)                         done
          (%i6) rules;
          (%o6)                          []

     Das folgende Beispiel zeigt einen Programmfehler von Maxima.  Die
     Funktion ‘trigsimp’ ist mit Hilfe von Regeln implementiert.  Die
     Regeln werden automatisch beim ersten Aufruf der Funktion
     ‘trigsimp’ geladen und in die Liste ‘rules’ eingetragen.  Werden
     die Regeln mit der Funktion ‘clear_rules’ oder ‘kill’ gelöscht,
     führt der nächste Aufruf der Funktion ‘trigsimp’ zu einem Fehler.

          (%i1) trigsimp(sin(x)^2+cos(x)^2);
          (%o1)                           1
          (%i2) rules;
          (%o2) [trigrule1, trigrule2, trigrule3, trigrule4, htrigrule1,
                                        htrigrule2, htrigrule3, htrigrule4]
          (%i3) disprule(trigrule1, trigrule2, trigrule3, trigrule4)$
                                                  sin(a)
          (%t3)             trigrule1 : tan(a) -> ------
                                                  cos(a)

                                                    1
          (%t4)             trigrule2 : sec(a) -> ------
                                                  cos(a)

                                                    1
          (%t5)             trigrule3 : csc(a) -> ------
                                                  sin(a)

                                                  cos(a)
          (%t6)             trigrule4 : cot(a) -> ------
                                                  sin(a)

          (%i7) clear_rules();
          (%o7)                         done
          (%i8) rules;
          (%o8)                          []
          (%i9) trigsimp(sin(x)^2+cos(x)^2);

          apply1: no such rule: trigrule1
          #0: trigsimp(x=sin(x)^2+cos(x)^2)(trgsmp.mac line 71)
           -- an error. To debug this try: debugmode(true);

 -- Optionsvariable: current_let_rule_package
     Standardwert: ‘default_let_rule_package’

     Die Optionsvariable ‘current_let_rule_package’ enthält den Namen
     des aktuellen Regelpaketes, das von den Funktionen ‘let’,
     ‘letrules’, ‘letsimp’ und ‘remlet’ verwendet wird.  Der
     Optionsvariablen kann jedes mit der Funktion ‘let’ definierte
     Regelpaket zugewiesen werden.

     Wird das Kommando ‘letsimp(expr, rule_pkg_name)’ ausgeführt, dann
     wird für das aktuelle Kommando das Paket ‘rule_pkg_name’ verwendet.
     Der Wert der Variablen ‘current_let_rule_package’ wird nicht
     geändert.

     Siehe auch die Optionsvariable ‘default_let_rule_package’.

 -- Optionsvariable: default_let_rule_package
     Standardwert: ‘default_let_rule_package’

     Die Optionsvariable ‘default_let_rule_package’ bezeichnet das
     Regelpaket, das verwendet wird, wenn kein Regelpaket mit der
     Funktion ‘let’ explizit definiert und der Wert der Optionsvariablen
     ‘current_let_rule_package’ nicht geändert wurde.

 -- Funktion: defmatch (<progname>, <pattern>, <x_1>, …, <x_n>)
 -- Funktion: defmatch (<progname>, <pattern>)

     Definiert eine Aussagefunktion ‘<progname>(<expr>)’ oder
     ‘<progname>(<expr>, <x_1>, ..., <x_n>)’, die einen Ausdruck <expr>
     testet, um zu prüfen, ob dieser das Muster <pattern> enthält.

     Das Argument <pattern> ist ein Ausdruck mit den Musterargumenten
     <x_1>, …, <x_n>.  Die Musterargumente können entfallen.  Der
     Ausdruck kann weiterhin Mustervariablen enthalten, die mit der
     Funktion ‘matchdeclare’ definiert sind.  Alle anderen Variablen und
     Bezeichner entsprechen sich selbst bei einem Musterabgleich.

     Das erste Argument der Aussagefunktion <progname> ist ein Ausdruck
     <expr>, für den geprüft wird, ob das Muster <pattern> enthalten
     ist.  Die weiteren Argumente der Funktion ‘progname’ sind die
     Variablen, die den Musterargumenten <x_1>, …, <x_n> des Musters
     <pattern> entsprechen.

     Ist der Musterabgleich erfolgreich, gibt die Aussagefunktion
     <progname> eine Liste mit Gleichungen zurück.  Die linken Seiten
     der Gleichungen sind die Musterargumente und Mustervariablen und
     die rechten Seiten sind die Teilausdrücke, für die der
     Musterabgleich eine Übereinstimmung gefunden hat.  Die erhaltenen
     Ergebnisse des Musterabgleichs werden den mit ‘matchdeclare’
     definierten Mustervariablen, jedoch nicht den Musterargumenten der
     Funktion ‘defmatch’ zugewiesen.  Ist der Musterabgleich nicht
     erfolgreich, ist die Rückgabe ‘false’.

     Ein Muster, das keine Musterargumente oder Mustervariablen enthält,
     hat den Rückgabewert ‘true’, wenn der Musterabgleich erfolgreich
     ist.

     Die Aussagefunktion ‘progname’ wird in die Informationsliste
     ‘rules’ eingetragen.

     Siehe auch die Funktionen ‘matchdeclare’, ‘defrule’, ‘tellsimp’ und
     ‘tellsimpafter’.

     Beispiele:

     Definition einer Funktion ‘linearp(expr, x)’, die prüft, ob ein
     Ausdruck <expr> die Form ‘a*x+b’ hat, wobei ‘a’ und ‘b’ die
     Variable <x> nicht enthalten und ‘a’ von Null verschieden ist.  Die
     Definition enthält das Musterargument <x>, so dass die Linearität
     des Ausdrucks für eine beliebige Variable getestet werden kann.
     Den Mustervariablen ‘a’ und ‘b’ werden die Teilausdrücke des
     Musterabgleichs zugewiesen, nicht jedoch dem Musterargument ‘x’.

          (%i1) matchdeclare (a, lambda ([e], e#0 and freeof(x, e)),
                              b, freeof(x));
          (%o1)                         done
          (%i2) defmatch (linearp, a*x + b, x);
          (%o2)                        linearp
          (%i3) linearp (3*z + (y + 1)*z + y^2, z);
                                   2
          (%o3)              [b = y , a = y + 4, x = z]
          (%i4) a;
          (%o4)                         y + 4
          (%i5) b;
                                          2
          (%o5)                          y
          (%i6) x;
          (%o6)                           x

     Wie im letzten Beispiel wird eine Aussagefunktion definiert, die
     prüft, ob ein Ausdruck <expr> linear ist.  In diesem Fall wird kein
     Musterargument angegeben.  Der Musterabgleich kann nur feststellen,
     ob ein Ausdruck linear in der Variablen <x> ist.  Eine andere
     Variable ist nicht möglich.

          (%i1) matchdeclare (a, lambda ([e], e#0 and freeof(x, e)), b,
                              freeof(x));
          (%o1)                         done
          (%i2) defmatch (linearp, a*x + b);
          (%o2)                        linearp
          (%i3) linearp (3*z + (y + 1)*z + y^2);
          (%o3)                         false
          (%i4) linearp (3*x + (y + 1)*x + y^2);
                                       2
          (%o4)                  [b = y , a = y + 4]

     Definition eine Aussagefunktion ‘checklimits(expr)’, die prüft, ob
     ein Ausdruck <expr> ein bestimmtes Integral ist.

          (%i1) matchdeclare ([a, f], true);
          (%o1)                         done
          (%i2) constinterval (l, h) := constantp (h - l);
          (%o2)        constinterval(l, h) := constantp(h - l)
          (%i3) matchdeclare (b, constinterval (a));
          (%o3)                         done
          (%i4) matchdeclare (x, atom);
          (%o4)                         done
          (%i5) simp : false;
          (%o5)                         false
          (%i6) defmatch (checklimits, 'integrate (f, x, a, b));
          (%o6)                      checklimits
          (%i7) simp : true;
          (%o7)                         true
          (%i8) 'integrate (sin(t), t, %pi + x, 2*%pi + x);
                                 x + 2 %pi
                                /
                                [
          (%o8)                 I          sin(t) dt
                                ]
                                /
                                 x + %pi
          (%i9) checklimits (%);
          (%o9)    [b = x + 2 %pi, a = x + %pi, x = t, f = sin(t)]

 -- Funktion: defrule (<rulename>, <pattern>, <replacement>)

     Definiert eine Regel, um das Muster <pattern> durch den Ausdruck
     <replacement> zu ersetzen.  Wird die Regel mit dem Namen <rulename>
     mit den Funktionen ‘apply1’, ‘apply2’ oder ‘applyb1’ auf einen
     Ausdruck angewendet, werden alle Teilausdrücke, die dem Muster
     <pattern> entsprechen, durch den Ausdruck <replacement> ersetzt.
     Sind Mustervariablen vorhanden, die durch den Musterabgleich einen
     Wert erhalten haben, werden die Werte eingesetzt und der Ausdruck
     wird vereinfacht.

     Die Regel <rulename> kann als eine Funktion aufgefasst werden, die
     einen Ausdruck durch Anwendung eines Musterabgleichs transformiert.
     Die Regel kann wie ein Funktionsaufruf auf einen Ausdruck
     angewendet werden.

     Schlägt der Musterabgleich fehl, gibt die Regel den Wert ‘false’
     zurück.

     Die Regel wird in die Informationsliste ‘rules’ eingetragen.

     Beispiele:

     Es wird eine Regel ‘trig’ definiert, die den Ausdruck ‘sin(x)^2’
     nach ‘1-cos(x)^2’ transformiert.  Diese Definition funktioniert
     nur, wenn das Argument der Sinusfunktion das Symbol ‘x’ ist.

          (%i1) defrule(trig, sin(x)^2, 1-cos(x)^2);
                                      2              2
          (%o1)             trig : sin (x) -> 1 - cos (x)
          (%i2) trig(sin(x)^2);
                                            2
          (%o2)                      1 - cos (x)
          (%i3) trig(sin(y)^2);
          (%o3)                         false

     In diesem Beispiel wird zunächst mit der Funktion ‘matchdeclare’
     eine Mustervariable ‘a’ definiert, der jeder Ausdruck zugewiesen
     werden kann und die als Argument der Regel verwendet wird.  Jetzt
     kann das Argument der Sinusfunktion ein beliebiger Ausdruck sein.

          (%i1) matchdeclare(a, true);
          (%o1)                         done
          (%i2) defrule(trig, sin(a)^2, 1-cos(a)^2);
                                      2              2
          (%o2)             trig : sin (a) -> 1 - cos (a)
          (%i3) trig(sin(x)^2);
                                            2
          (%o3)                      1 - cos (x)
          (%i4) trig(sin(exp(x))^2);
                                           2   x
          (%o4)                     1 - cos (%e )

     Die Regel kann mit der Funktion ‘apply1’ auf Ausdrücke angewendet
     werden, wobei Teilausdrücke, die das Muster enthalten transformiert
     werden.

          (%i5) trig(exp(sin(x)^2));
          (%o5)                         false
          (%i6) apply1(exp(sin(x)^2), trig);
                                             2
                                      1 - cos (x)
          (%o6)                     %e

 -- Funktion: disprule (<rulename_1>, …, <rulename_n>)
 -- Funktion: disprule (all)

     Zeigt die Regeln mit den Namen <rulename_1>, …, <rulename_n> an,
     die mit den Funktionen ‘defrule’, ‘tellsimp’ oder ‘tellsimpafter’
     definiert sind, oder ein Muster, das mit der Funktion ‘defmatch’
     definiert ist.  Die Regeln werden mit einer Zwischenmarke ‘%t’
     angezeigt.

     Mit dem Kommando ‘disprule(all)’ werden alle Regeln und Muster
     angezeigt, die der Nutzer definiert hat und in der
     Informationsliste ‘rules’ enthalten sind.

     ‘disprule’ wertet die Argumente nicht aus.  Der Rückgabewert ist
     eine Liste mit den Zwischenmarken, denen eine Regel zugewiesen
     wurde.

     Siehe auch die Funktion ‘letrules’, die die Regeln anzeigt, die mit
     der Funktion ‘let’ definiert sind.

     Beispiele:

          (%i1) tellsimpafter (foo (x, y), bar (x) + baz (y));
          (%o1)                   [foorule1, false]
          (%i2) tellsimpafter (x + y, special_add (x, y));
          (%o2)                   [+rule1, simplus]
          (%i3) defmatch (quux, mumble (x));
          (%o3)                         quux
          (%i4) disprule (foorule1, "+rule1", quux);
          (%t4)        foorule1 : foo(x, y) -> baz(y) + bar(x)

          (%t5)          +rule1 : y + x -> special_add(x, y)

          (%t6)                quux : mumble(x) -> []

          (%o6)                    [%t4, %t5, %t6]
          (%i6) ''%;
          (%o6) [foorule1 : foo(x, y) -> baz(y) + bar(x),
               +rule1 : y + x -> special_add(x, y), quux : mumble(x) -> []]

 -- Funktion: let (<prod>, <repl>)
 -- Funktion: let (<prod>, <repl>, <predname>, <arg_1>, …, <arg_n>)
 -- Funktion: let ([<prod>, <repl>, <predname>, <arg_1>, …, <arg_n>],
          <package_name>)

     Definiert eine Regel, die mit der Funktion ‘letsimp’ auf einen
     Ausdruck angewendet werden kann, so dass <prod> durch <repl>
     ersetzt wird.  Das Argument <prod> ist ein Produkt von positiven
     oder negativen Potenzen der folgenden Terme:

        • Atome, nach denen die Funktion ‘letsimp’ wörtlich sucht, wenn
          diese keine Mustervariablen sind, die mit Funktion
          ‘matchdeclare’ definiert sind, sowie Atome, die
          Mustervariablen sind.  In diesem Fall führt die Funktion
          ‘letsimp’ einen Musterabgleich für die Atome durch, auf die
          die mit der Funktion ‘matchdeclare’ zugeordnete
          Aussagefunktion zutrifft.

        • Terme wie ‘sin(x)’, ‘n!’ oder ‘f(x,y)’: wie für Atome sucht
          die Funktion ‘letsimp’ nach wörtlichen Übereinstimmungen,
          außer wenn die Argumente der Terme Mustervariablen sind, die
          mit der Funktion ‘matchdeclare’ definiert sind.  In diesem
          Fall wird ein Musterabgleich ausgeführt.

     Ein Term mit einer positiven Potenz stimmt mit einem Ausdruck nur
     dann überein, wenn dieser mindestens dieselbe Potenz hat.
     Entsprechend gilt für einen Term mit einer negativen Potenz, dass
     dieser dann mit einem Ausdruck übereinstimmt, wenn dieser
     mindestens dieselbe negative Potenz hat.  Für negative Potenzen
     wird eine Übereinstimmung nur dann gefunden, wenn die
     Optionsvariable ‘letrat’ den Wert ‘true’ hat.

     Hat die Funktion ‘let’ eine Aussagefunktion <predname> als Argument
     mit den Argumenten <arg_1>, …, <arg_n>, wird eine Übereinstimmung
     dann festgestellt, wenn der Ausdruck ‘predname(arg_1', ...,
     arg_n')’ das Ergebnis ‘true’ hat.  Dabei sind die Argumente
     <arg_i’> die Werte aus dem Musterabgleich.  Die Argumente <arg_i>
     können die Namen von Variablen oder Termen sein, die im Ausdruck
     <pred> auftreten.  <repl> kann ein beliebiger rationaler Ausdruck
     sein.  Treten irgendwelche der Symbole oder Argumente aus <prod> im
     Argument <repl> auf, wird die entsprechende Substitution
     ausgeführt.

     Die Optionsvariable ‘letrat’ kontrolliert die Vereinfachung von
     Quotienten durch ‘letsimp’.  Hat ‘letrat’ den Wert ‘false’, werden
     der Zähler und der Nenner eines Bruches einzeln vereinfacht.  Der
     Bruch als ganzes wird dagegen nicht vereinfacht.  Hat die
     Optionsvariable ‘letrat’ den Wert ‘true’, werden nacheinander der
     Zähler, der Nenner und dann der Bruch vereinfacht.

     Die Funktion ‘letsimp’ kann mit verschiedenen Regelpaketen
     arbeiten.  Jedes Regelpaket kann eine beliebige Anzahl an Regeln
     enthalten.  Das Kommando ‘let([<prod>, <repl>, <predname>, <arg_1>,
     ..., <arg_n>], <package_name>)’ fügt die Regel <predname> dem Paket
     <package_name> hinzu.

     Die Optionsvariable ‘current_let_rule_package’ enthält den Namen
     des Regelpaketes, das aktuell von der Funktion ‘letsimp’ verwendet
     wird.  Der Optionsvariablen kann jedes mit dem Kommando ‘let’
     definierte Regelpaket zugewiesen werden.  Wird mit ‘letsimp(<expr>,
     <package_name>)’ ein Regelpaket als Argument übergeben, wird dieses
     anstatt dem in ‘current_let_rule_package’ enthaltene Regelpaket für
     die Vereinfachung verwendet.  Wenn nicht anders spezifiziert, hat
     ‘current_let_rule_package’ den Standardwert
     ‘default_let_rule_package’.

     Die Informationsliste ‘let_rule_packages’ enthält die definierten
     Regelpakete.  Mit der Funktion ‘letrules’ können alle definierten
     Regeln oder Regeln einzelner Pakete angezeigt werden.

     Beispiele:

     Die Funktion ‘isintegerp’ prüft auch, ob Variablen oder Ausdrücke
     eine ganze Zahl repräsentieren.  Es wird eine Regel definiert, die
     dann angewendet wird, wenn das Argument eine ganze Zahl
     repräsentiert.

          (%i1) isintegerp(x) := featurep(x, integer)$

          (%i2) let(tan(x), sin(x)/cos(x), isintegerp, x);
          (%o2) tan(x) --> sin(x)/cos(x) where isintegerp(x)

          (%i3) letsimp(tan(x));
          (%o3) tan(x)

          (%i4) declare(x, integer)$

          (%i5) letsimp(tan(x));
          (%o5) sin(x)/cos(x)
          (%i6) letsimp(tan(1));
          (%o6) tan(1)

     Weitere Beispiele:

          (%i1) matchdeclare ([a, a1, a2], true)$
          (%i2) oneless (x, y) := is (x = y-1)$
          (%i3) let (a1*a2!, a1!, oneless, a2, a1);
          (%o3)         a1 a2! --> a1! where oneless(a2, a1)
          (%i4) letrat: true$
          (%i5) let (a1!/a1, (a1-1)!);
                                  a1!
          (%o5)                   --- --> (a1 - 1)!
                                  a1
          (%i6) letsimp (n*m!*(n-1)!/m);
          (%o6)                      (m - 1)! n!
          (%i7) let (sin(a)^2, 1 - cos(a)^2);
                                  2               2
          (%o7)                sin (a) --> 1 - cos (a)
          (%i8) letsimp (sin(x)^4);
                                  4           2
          (%o8)                cos (x) - 2 cos (x) + 1

 -- Optionsvariable: let_rule_packages
     Standardwert: ‘[default_let_rule_package]’

     ‘let_rule_packages’ ist eine Informationsliste mit den vom Nutzer
     mit der Funktion ‘let’ definierten Regelpaketen.

 -- Optionsvariable: letrat
     Standardwert: ‘false’

     Hat die Optionsvariable ‘letrat’ den Wert ‘false’, werden von der
     Funktion ‘letsimp’ der Zähler und der Nenner eines Bruches einzeln
     vereinfacht.  Der Bruch als ganzes wird dagegen nicht vereinfacht.

     Hat die Optionsvariable ‘letrat’ den Wert ‘true’, werden
     nacheinander der Zähler, der Nenner und dann der Bruch vereinfacht.

     Beispiele:

          (%i1) matchdeclare (n, true)$
          (%i2) let (n!/n, (n-1)!);
                                   n!
          (%o2)                    -- --> (n - 1)!
                                   n
          (%i3) letrat: false$
          (%i4) letsimp (a!/a);
                                         a!
          (%o4)                          --
                                         a
          (%i5) letrat: true$
          (%i6) letsimp (a!/a);
          (%o6)                       (a - 1)!

 -- Funktion: letrules ()
 -- Funktion: letrules (<package_name>)

     Zeigt die Regeln eines Regelpaketes an.  Das Kommando ‘letrules()’
     zeigt die Regeln des aktuellen Regelpaketes an, das durch die
     Optionsvariable ‘current_let_rule_package’ bezeichnet wird.  Das
     Kommando ‘letrules(<package_name>)’ zeigt die Regeln des Paketes
     <package_name> an.

     Wenn der Optionsvariablen ‘current_let_rule_package’ kein Name
     eines Paketes zugewiesen wurde, enthält es den Standardwert
     ‘default_let_rule_package’.

     Siehe auch die Funktion ‘disprule’, um Regeln anzuzeigen, die mit
     den Funktionen ‘tellsimp’, ‘tellsimpafter’ und ‘defrule’ definiert
     wurden.

     Beispiel:

     Im folgenden Beispiel werden einem Paket mit dem Namen ‘trigrules’
     zwei Regeln hinzugefügt.  Die Regeln werden mit dem Kommando
     ‘letrules(trigrules)’ angezeigt.  Wird das Paket zum aktuellen
     Paket erklärt, indem es der Variablen ‘current_let_rule_package’
     zugewiesen wird, dann werden die Regeln auch mit dem Kommando
     ‘letrules()’ angezeigt.

          (%i1) let([sin(x)^2, 1-cos(x)^2], trigrules);
                                  2               2
          (%o1)                sin (x) --> 1 - cos (x)
          (%i2) let([tan(x), sin(x)/cos(x)], trigrules);
                                             sin(x)
          (%o2)                   tan(x) --> ------
                                             cos(x)
          (%i3) letrules(trigrules);
                                             sin(x)
                                  tan(x) --> ------
                                             cos(x)

                                  2               2
                               sin (x) --> 1 - cos (x)

          (%o3)                         done
          (%i4) letrules();
          (%o4)                         done
          (%i5) current_let_rule_package: trigrules;
          (%o5)                       trigrules
          (%i6) letrules();
                                             sin(x)
                                  tan(x) --> ------
                                             cos(x)

                                  2               2
                               sin (x) --> 1 - cos (x)

          (%o6)                         done

 -- Funktion: letsimp (<expr>)
 -- Funktion: letsimp (<expr>, <package_name>)
 -- Funktion: letsimp (<expr>, <package_name_1>, …, <package_name_n>)

     Wendet die Regeln, die mit der Funktion ‘let’ definiert sind,
     solange an, bis sich das Argument <expr> nicht mehr ändert.
     ‘letsimp(<expr>)’ wendet die aktuellen Regeln an, die mit der
     Optionsvariablen ‘current_let_rule_package’ bezeichnet werden.

     ‘letsimp(<expr>, <package_name>)’ wendet die Regeln des Argumentes
     <package_name> an.  Die Optionsvariable ‘current_let_rule_package’
     ändert ihren Wert nicht.  Es können auch mehrere Regelpakete
     <package_name_1>, …, <package_name_n> angegeben werden.

     Die Optionsvariable ‘letrat’ kontrolliert die Vereinfachung von
     Quotienten durch ‘letsimp’.  Hat ‘letrat’ den Wert ‘false’, werden
     der Zähler und der Nenner eines Bruches einzeln vereinfacht.  Der
     Bruch als ganzes wird dagegen nicht vereinfacht.  Hat die
     Optionsvariable ‘letrat’ den Wert ‘true’, werden nacheinander der
     Zähler, der Nenner und dann der Bruch vereinfacht.

 -- Funktion: matchdeclare (<a_1>, <pred_1>, …, <a_n>, <pred_n>)

     Mit der Funktion ‘matchdeclare’ werden Mustervariablen definiert.
     ‘matchdeclare’ ordnet eine Aussagefunktion <pred_k> einer Variable
     oder eine Liste von Variablen <a_k> zu, so dass <a_k> bei einem
     Musterabgleich mit Ausdrücken übereinstimmt, für die die Aussage
     ein anderes Ergebnis als ‘false’ hat.

     Eine Aussagefunktion <pred_i> kann durch den Namen einer Funktion,
     einen Lambda-Ausdruck, einen Funktionsaufruf, einen
     Lambda-Ausdruck, dem das letzte Argument fehlt, oder die Werte
     ‘true’ oder ‘all’ bezeichnet werden.  Ist die Aussagefunktion ein
     Funktionsaufruf oder ein Lambda-Aufruf, dann wird der zu testende
     Ausdruck der Liste der Argumente hinzugefügt.  Die Argumente werden
     ausgewertet, wenn der Musterabgleich ausgeführt wird.  Ist die
     Aussage der Name einer Funktion oder ein Lambda-Ausdruck, ist die
     zu testende Aussage das einzige Argument.  Die Aussagefunktion
     braucht noch nicht definiert zu sein, wenn mit ‘matchdeclare’ eine
     Mustervariable definiert wird, da die Aussagefunktion erst
     aufgerufen wird, wenn ein Musterabgleich durchgeführt wird.

     Eine Aussagefunktion kann einen logischen Ausdruck oder die Werte
     ‘true’ oder ‘false’ zurückgeben.  Logische Ausdrücke werden von der
     Funktion ‘is’ ausgewertet, wenn die Regel angewendet wird.  Daher
     ist es nicht notwendig, dass die Aussagefunktion selbst die
     Funktion ‘is’ aufruft.

     Wenn für einen Ausdruck eine Übereinstimmung bei einem
     Musterabgleich gefunden wird, wird der Mustervariablen der Ausdruck
     zugewiesen.  Jedoch nicht für Mustervariablen, die Argumente der
     Addition ‘+’ oder Multiplikation ‘*’ sind.  Diese Operatoren werden
     besonders behandelt.  Andere Maxima oder vom Nutzer definierte
     N-ary-Operatoren werden dagegen wie normale Funktionen behandelt.

     Im Falle der Addition und der Multiplikation kann der
     Mustervariablen ein einzelner Term zugewiesen werden, für den der
     Musterabgleich zu einer Überstimmung führt, oder auch eine Summe
     oder ein Produkt von Termen.  Die mehrfache Übereinstimmung hat
     Vorrang.  Aussagefunktionen werden in der Reihenfolge ausgewertet,
     in der die der Aussagefunktion zugeordneten Mustervariablen im
     Muster auftreten.  Führt der Musterabgleich für einen Term zu einer
     Übereinstimmung mit mehreren Aussagefunktionen, dann wird der Term
     der Mustervariablen zugeordnet für den die erste Aussagefunktion
     zutrifft.  Jede Aussagefunktion wird zunächst auf alle Argumente
     einer Summe oder eines Produktes angewendet, bevor die nächste
     Aussagefunktion ausgewertet wird.  Wird für die Zahlen 0 oder 1
     eine Übereinstimmung gefunden und es sind keine weiteren Terme
     vorhanden, wird der Mustervariablen 0 oder 1 zugewiesen.

     Der Algorithmus, um Muster abzugleichen, die die Addition oder die
     Multiplikation als Operanden enthalten, kann von der Anordnung der
     Terme im Muster oder im zu prüfenden Ausdruck abhängen.  Solange
     sich jedoch die einzelnen Aussagefunktionen gegeneinander
     ausschließen, wird das Ergebnis nicht von der Reihenfolge der
     Argumente beeinflußt.

     Der Aufruf von ‘matchdeclare’ für eine Variable <a> überschreibt
     eine vorhergehende Definition für diese Variable.  Wird eine Regel
     definiert, ist die letzte mit ‘matchdeclare’ definierte Zuordnung
     zu einer Aussagefunktion wirksam.  Der erneute Aufruf von
     ‘matchdeclare’ für eine Variable hat keinen Einfluss auf bereits
     vorhandene Regeln.

     Das Kommando ‘propvars(matchdeclare)’ gibt eine Liste der Variablen
     zurück, die mit ‘matchdeclare’ als Mustervariable definiert sind.
     ‘printprops(<a>, matchdeclare)’ gibt die der Variable <a>
     zugeordnete Aussagefunktion zurück.  ‘printprops(all,
     matchdeclare)’ gibt die Aussagefunktionen aller Mustervariablen
     zurück.  Mit dem Kommando ‘remove(<a>, matchdeclare)’ wird die
     Definition von <a> als Mustervariable entfernt.  Siehe auch die
     Funktionen ‘propvars’, ‘printprops’ und ‘remove’.

     Mit den Funktionen ‘defmatch’, ‘defrule’, ‘tellsimp’,
     ‘tellsimpafter’ und ‘let’ werden Regeln definiert, die für
     Ausdrücke einen Musterabgleich ausführen, wobei die Mustervariablen
     mit den Werten belegt werden, für die eine Übereinstimmung gefunden
     wird.

     ‘matchdeclare’ wertet die Argumente nicht aus.  ‘matchdeclare’ gibt
     immer ‘done’ als Ergebnis zurück.

     Beispiele:

     Eine Aussagefunktion kann mit dem Namen einer Funktion, einem
     Lambda-Ausdruck, einem Funktionsaufruf, einem Lambda-Ausdruck, dem
     das letzte Argument fehlt, oder den Werten ‘true’ oder ‘all’
     bezeichnet werden.

          (%i1) matchdeclare (aa, integerp);
          (%o1)                         done
          (%i2) matchdeclare (bb, lambda ([x], x > 0));
          (%o2)                         done
          (%i3) matchdeclare (cc, freeof (%e, %pi, %i));
          (%o3)                         done
          (%i4) matchdeclare (dd, lambda ([x, y], gcd (x, y) = 1) (1728));
          (%o4)                         done
          (%i5) matchdeclare (ee, true);
          (%o5)                         done
          (%i6) matchdeclare (ff, all);
          (%o6)                         done

     Wird für einen Ausdruck beim Musterabgleich eine Übereinstimmung
     gefunden, wird dieser der Mustervariablen zugewiesen.

          (%i1) matchdeclare (aa, integerp, bb, atom);
          (%o1)                         done
          (%i2) defrule (r1, bb^aa, ["integer" = aa, "atom" = bb]);
                              aa
          (%o2)        r1 : bb   -> [integer = aa, atom = bb]
          (%i3) r1 (%pi^8);
          (%o3)               [integer = 8, atom = %pi]

     Im Falle der Addition und Multiplikation kann der Mustervariablen
     ein einzelner Term zugewiesen werden, welcher mit der Aussage
     übereinstimmt, aber auch eine Summe oder ein Produkt solcher
     Ausdrücke.

          (%i1) matchdeclare (aa, atom, bb, lambda ([x], not atom(x)));
          (%o1)                         done
          (%i2) defrule (r1, aa + bb, ["all atoms" = aa, "all nonatoms" =
                         bb]);
          bb + aa partitions `sum'
          (%o2)  r1 : bb + aa -> [all atoms = aa, all nonatoms = bb]
          (%i3) r1 (8 + a*b + sin(x));
          (%o3)     [all atoms = 8, all nonatoms = sin(x) + a b]
          (%i4) defrule (r2, aa * bb, ["all atoms" = aa, "all nonatoms" =
                         bb]);
          bb aa partitions `product'
          (%o4)   r2 : aa bb -> [all atoms = aa, all nonatoms = bb]
          (%i5) r2 (8 * (a + b) * sin(x));
          (%o5)    [all atoms = 8, all nonatoms = (b + a) sin(x)]

     Wird nach Übereinstimmungen für die Argumente der Operatoren ‘+’
     oder ‘*’ gesucht und schließen sich die Aussagefunktionen
     gegeneinander aus, ist das Ergebnis unabhängig von der Anordnung
     der Terme.

          (%i1) matchdeclare (aa, atom, bb, lambda ([x], not atom(x)));
          (%o1)                         done
          (%i2) defrule (r1, aa + bb, ["all atoms" = aa, "all nonatoms" =
                         bb]);
          bb + aa partitions `sum'
          (%o2)  r1 : bb + aa -> [all atoms = aa, all nonatoms = bb]
          (%i3) r1 (8 + a*b + %pi + sin(x) - c + 2^n);
                                                               n
          (%o3) [all atoms = %pi + 8, all nonatoms = sin(x) + 2  - c + a b]
          (%i4) defrule (r2, aa * bb, ["all atoms" = aa, "all nonatoms" =
                         bb]);
          bb aa partitions `product'
          (%o4)   r2 : aa bb -> [all atoms = aa, all nonatoms = bb]
          (%i5) r2 (8 * (a + b) * %pi * sin(x) / c * 2^n);
                                                            n
                                                   (b + a) 2  sin(x)
          (%o5) [all atoms = 8 %pi, all nonatoms = -----------------]
                                                           c

     Die Funktionen ‘propvars’ und ‘printprops’ geben Informationen über
     Mustervariablen aus.

          (%i1) matchdeclare ([aa, bb, cc], atom, [dd, ee], integerp);
          (%o1)                         done
          (%i2) matchdeclare (ff, floatnump, gg, lambda ([x], x > 100));
          (%o2)                         done
          (%i3) propvars (matchdeclare);
          (%o3)             [aa, bb, cc, dd, ee, ff, gg]
          (%i4) printprops (ee, matchdeclare);
          (%o4)                    [integerp(ee)]
          (%i5) printprops (gg, matchdeclare);
          (%o5)              [lambda([x], x > 100, gg)]
          (%i6) printprops (all, matchdeclare);
          (%o6) [lambda([x], x > 100, gg), floatnump(ff), integerp(ee),
                                integerp(dd), atom(cc), atom(bb), atom(aa)]

 -- Optionsvariable: maxapplydepth
     Standardwert: 10000

     ‘maxapplydepth’ ist die maximale Verschachtelungstiefe für die die
     Funktionen ‘apply1’ und ‘apply2’ auf die Baumstruktur eines
     Ausdrucks angewendet werden.

 -- Optionsvariable: maxapplyheight
     Standardwert: 10000

     ‘maxapplyheight’ ist die maximale Verschachtelungstiefe für die die
     Funktion ‘applyb1’ Bottom-up auf die Baumstruktur eines Ausdrucks
     angewendet wird.

 -- Funktion: remlet (<prod>, <package_name>)
 -- Funktion: remlet ()
 -- Funktion: remlet (all)
 -- Funktion: remlet (all, <package_name>)

     Entfernt die Regel <prod> –> <repl>, die zuletzt mit der Funktion
     ‘let’ definiert wurde.  Wird mit dem Argument <package_name> ein
     Paket angegeben, wird die Regeln aus dem entsprechenden Paket
     entfernt.

     ‘remlet()’ und ‘remlet(all)’ entfernen alle Regeln aus dem
     aktuellen Paket, das mit ‘current_let_rule_package’ bezeichnet ist.
     Wird der Name eines Regelpaketes als Argument angegeben, werden
     zusätzlich die Regeln dieses Paketes entfernt.

     Soll eine vorhandene Regel durch eine neue Definition ersetzt
     werden, muss die Regel nicht zuvor mit ‘remlet’ entfernt werden.
     Die neue Definition überschreibt eine vorhandene Regel.  Wurde eine
     vorhandene Regel überschrieben und wird die letzte Regel entfernt,
     dann ist die vorhergehende Regel wieder aktiv.

     Siehe auch die Funktion ‘remrule’, um Regeln zu entfernen, die mit
     den Funktionen ‘tellsimp’ oder ‘tellsimpafter’ definiert sind.

 -- Funktion: remrule (<op>, <rulename>)
 -- Funktion: remrule (<op>, all)

     Entfernt Regeln, die mit den Funktionen ‘tellsimp’ oder
     ‘tellsimpafter’ definiert sind.

     ‘remrule(<op>, <rulename>)’ entfernt die Regel mit dem Namen
     <rulename> vom Operator <op>.  Ist der Operator <op> ein
     Maxima-Operator oder ein nutzerdefinierter Operator, der mit
     Funktionen wie ‘infix’ oder ‘prefix’ definiert wurde, muss der Name
     des Operators <op> als eine Zeichenkette in Anführungszeichen
     angegeben werden.

     ‘remrule(<op>, all)’ entfernt alle Regeln des Operators <op>.

     Siehe auch die Funktion ‘remlet’, um Regeln zu entfernen, die mit
     der Funktion ‘let’ definiert sind.

     Beispiele:

          (%i1) tellsimp (foo (aa, bb), bb - aa);
          (%o1)                   [foorule1, false]
          (%i2) tellsimpafter (aa + bb, special_add (aa, bb));
          (%o2)                   [+rule1, simplus]
          (%i3) infix ("@@");
          (%o3)                          @@
          (%i4) tellsimp (aa @@ bb, bb/aa);
          (%o4)                   [@@rule1, false]
          (%i5) tellsimpafter (quux (%pi, %e), %pi - %e);
          (%o5)                  [quuxrule1, false]
          (%i6) tellsimpafter (quux (%e, %pi), %pi + %e);
          (%o6)             [quuxrule2, quuxrule1, false]
          (%i7) [foo (aa, bb), aa + bb, aa @@ bb, quux (%pi, %e),
                 quux (%e, %pi)];
                                               bb
          (%o7) [bb - aa, special_add(aa, bb), --, %pi - %e, %pi + %e]
                                               aa
          (%i8) remrule (foo, foorule1);
          (%o8)                          foo
          (%i9) remrule ("+", ?\+rule1);
          (%o9)                           +
          (%i10) remrule ("@@", ?\@\@rule1);
          (%o10)                         @@
          (%i11) remrule (quux, all);
          (%o11)                        quux
          (%i12) [foo (aa, bb), aa + bb, aa @@ bb, quux (%pi, %e),
                  quux (%e, %pi)];
          (%o12) [foo(aa, bb), bb + aa, aa @@ bb, quux(%pi, %e),
                                                   quux(%e, %pi)]

 -- Systemvariable: rules
     Standardwert: ‘[]’

     ‘rules’ ist eine Informationsliste, die die vom Nutzer mit den
     Funktionen ‘tellsimp’, ‘tellsimpafter’, ‘defmatch’ oder ‘defrule’
     definierten Regeln enthält.

     Regeln, die mit der Funktion ‘let’ definiert sind, sind nicht in
     der Liste ‘rules’ enthalten.  Diese Regeln werden in Paketen
     organisiert, die in der Systemvariablen ‘let_rule_packages’
     aufgelistet und mit der Funktion ‘letrules’ angezeigt werden.

     Siehe auch die Systemvariable ‘infolists’.

 -- Funktion: tellsimp (<pattern>, <replacement>)

     ‘tellsimp’ ist vergleichbar mit der Funktion ‘tellsimpafter’, wobei
     mit ‘tellsimp’ Regeln für die Vereinfachung von Ausdrücken
     definiert werden, die noch vor den Regeln angewendet werden, die
     intern in Maxima bekannt sind.

     ‘tellsimp’ wird daher eingesetzt, wenn Maxima Regeln für die
     Vereinfachung des Ausdruckes kennt, es jedoch notwendig ist, noch
     vor Anwendung dieser Regeln den Ausdruck auf eine andere Art zu
     modifizieren.  Für den Fall das Maxima den Ausdruck nicht
     ausreichend vereinfacht, kann es besser sein, eine Regel mit der
     Funktion ‘tellsimpafter’ zu definieren.

     Das Argument <pattern> kann keine Summe, kein Produkt, keine
     einzelne Variable und keine Zahl sein.

     Regeln die mit ‘tellsimp’ definiert werden, werden in die
     Informationsliste ‘rules’ aufgenommen.

     Beispiele:

          (%i1) matchdeclare (x, freeof (%i));
          (%o1)                         done
          (%i2) %iargs: false$
          (%i3) tellsimp (sin(%i*x), %i*sinh(x));
          (%o3)                 [sinrule1, simp-%sin]
          (%i4) trigexpand (sin (%i*y + x));
          (%o4)         sin(x) cos(%i y) + %i cos(x) sinh(y)
          (%i5) %iargs:true$
          (%i6) errcatch(0^0);
           0
          0  has been generated
          (%o6)                          []
          (%i7) ev (tellsimp (0^0, 1), simp: false);
          (%o7)                  [^rule1, simpexpt]
          (%i8) 0^0;
          (%o8)                           1
          (%i9) remrule ("^", %th(2)[1]);
          (%o9)                           ^
          (%i10) tellsimp (sin(x)^2, 1 - cos(x)^2);
          (%o10)                 [^rule2, simpexpt]
          (%i11) (1 + sin(x))^2;
                                                2
          (%o11)                    (sin(x) + 1)
          (%i12) expand (%);
                                             2
          (%o12)               2 sin(x) - cos (x) + 2
          (%i13) sin(x)^2;
                                            2
          (%o13)                     1 - cos (x)
          (%i14) kill (rules);
          (%o14)                        done
          (%i15) matchdeclare (a, true);
          (%o15)                        done
          (%i16) tellsimp (sin(a)^2, 1 - cos(a)^2);
          (%o16)                 [^rule3, simpexpt]
          (%i17) sin(y)^2;
                                            2
          (%o17)                     1 - cos (y)

 -- Funktion: tellsimpafter (<pattern>, <replacement>)

     Definiert eine Regel für die Vereinfachung eines Ausdrucks, die
     nach Anwendung der Regeln angewendet wird, die Maxima intern kennt.
     <pattern> ist ein Ausdruck, der Mustervariablen enthält, die mit
     der Funktion ‘matchdeclare’ definiert sind und weitere Symbole und
     Operatoren, für die die wörtliche Übereinstimmung bei einem
     Musterabgleich angenommen wird.  <replacement> wird in den Ausdruck
     substituiert, wenn der Musterabgleich das Muster <pattern> im
     Ausdruck findet.  Den Mustervariablen in <replacement> werden die
     Werte des Musterabgleichs zugewiesen.

     Das Muster <pattern> kann ein beliebiger Ausdruck sein, in dem der
     Hauptoperator keine Mustervariable ist.  Die neue Regel wird nach
     dem Hauptoperator des Musters benannt und diesem zugeordnet.  Der
     Name von Funktionen, mit einer unten beschriebenen Ausnahme, Listen
     und Arrays können in <pattern> nicht als eine Mustervariable
     auftreten.  Daher können Ausdrücke wie ‘aa(x)’ oder ‘bb[y]’ nicht
     als Muster verwendet werden, wenn ‘aa’ oder ‘bb’ Mustervariablen
     sind.  Die Namen von Funktionen, Listen und Arrays, welche
     Mustervariablen sind, können dann in dem Muster <pattern>
     auftreten, wenn sie nicht der Hauptoperator sind.

     Es gibt eine Ausnahme der oben genannten Einschränkung für die
     Verwendung von Funktionsnamen.  Der Name einer indizierten Funktion
     wie ‘aa[x](y)’ kann eine Mustervariable sein, da der Hauptoperator
     nicht ‘aa’ ist, sondern das interne Symbol ‘mqapply’.  Dies ist
     eine Konsequenz der internen Darstellung einer indizierten
     Funktion.

     Regeln für die Vereinfachung werden nach der Auswertung eines
     Ausdrucks angewendet, sofern die Auswertung, zum Beispiel mit dem
     Schalter ‘noeval’, nicht unterdrückt wurde.  Regeln, die mit
     ‘tellsimpafter’ definiert sind, werden nach den internen Regeln und
     in der Reihenfolge angewendet, in der sie definiert sind.  Die
     Regeln für die Vereinfachung werden zunächst für Teilausdrücke und
     zuletzt für den ganzen Ausdruck angewendet.  Es kann notwendig
     sein, Regeln für die Vereinfachung mehrfach zum Beispiel mit dem
     Quote-Quote-Operator ‘''’ oder dem Auswertungsschalter ‘infeval’
     anzuwenden, um zu erreichen, dass alle Regeln angewendet werden.

     Mustervariable werden als lokale Variablen in Regeln für die
     Vereinfachung behandelt.  Sobald eine Regel definiert ist,
     beeinflusst die Zuweisung eines Wertes an die Mustervariable nicht
     die Regel und die Variable wird nicht von der Regel beeinflusst.
     Die Zuweisung an eine Mustervariable, die aufgrund eines
     erfolgreichen Musterabgleichs vorgenommen wird, beeinflusst nicht
     den aktuellen Wert der Variablen.  Jedoch sind die Eigenschaften
     der Mustervariablen, wie sie zum Beispiel auch mit der Funktion
     ‘put’ definiert werden können, global in Maxima.

     Eine mit ‘tellsimpafter’ definierte Regel wird nach dem
     Hauptoperator des Musters <pattern> benannt.  Regeln für
     Maxima-Operatoren und für Funktionen, die mit ‘infix’, ‘prefix’,
     ‘postfix’, ‘matchfix’ und ‘nofix’ als Operator definiert sind,
     haben einen Lisp-Bezeichner als Namen.  Alle anderen Regeln
     erhalten einen Maxima-Bezeichner als Namen.

     ‘tellsimpafter’ wertet die Argumente nicht aus.  ‘tellsimpafter’
     gibt eine Liste der Regeln zurück, die für den Hauptoperator des
     Musters <pattern> definiert sind.

     Siehe auch die Funktionen ‘matchdeclare’, ‘defmatch’, ‘defrule’,
     ‘tellsimp’, ‘remrule’ und ‘clear_rules’.

     Beispiele:

     Das Muster <pattern> kann ein beliebiger Ausdruck sein, in dem der
     Hauptoperator keine Mustervariable ist.

          (%i1) matchdeclare (aa, atom, [ll, mm], listp, xx, true)$
          (%i2) tellsimpafter (sin (ll), map (sin, ll));
          (%o2)                 [sinrule1, simp-%sin]
          (%i3) sin ([1/6, 1/4, 1/3, 1/2, 1]*%pi);
                              1  sqrt(2)  sqrt(3)
          (%o3)              [-, -------, -------, 1, 0]
                              2     2        2
          (%i4) tellsimpafter (ll^mm, map ("^", ll, mm));
          (%o4)                  [^rule1, simpexpt]
          (%i5) [a, b, c]^[1, 2, 3];
                                          2   3
          (%o5)                      [a, b , c ]
          (%i6) tellsimpafter (foo (aa (xx)), aa (foo (xx)));
          (%o6)                   [foorule1, false]
          (%i7) foo (bar (u - v));
          (%o7)                    bar(foo(u - v))

     Regeln werden in der Reihenfolge angewendet, in der sie definiert
     sind.  Treffen zwei Regeln bei einem Musterabgleich zu, wird die
     zuerst definierte Regel angewendet.

          (%i1) matchdeclare (aa, integerp);
          (%o1)                         done
          (%i2) tellsimpafter (foo (aa), bar_1 (aa));
          (%o2)                   [foorule1, false]
          (%i3) tellsimpafter (foo (aa), bar_2 (aa));
          (%o3)              [foorule2, foorule1, false]
          (%i4) foo (42);
          (%o4)                       bar_1(42)

     Mustervariable werden als lokale Variable beim Musterabgleich der
     mit der Funktion ‘tellsimpafter’ definierten Regel behandelt.  Im
     Unterschied dazu werden von Regeln, die mit ‘defmatch’ definiert
     sind, Mustervariable als globale Variable behandelt.

          (%i1) matchdeclare (aa, integerp, bb, atom);
          (%o1)                         done
          (%i2) tellsimpafter (foo(aa, bb), bar('aa=aa, 'bb=bb));
          (%o2)                   [foorule1, false]
          (%i3) bb: 12345;
          (%o3)                         12345
          (%i4) foo (42, %e);
          (%o4)                 bar(aa = 42, bb = %e)
          (%i5) bb;
          (%o5)                         12345

     Die Eigenschaften von Mustervariablen sind global, auch wenn die
     Werte lokal sind.  In diesem Beispiel wird eine Eigenschaft für die
     Zuweisung an eine Variable mit der Funktion ‘define_variable’
     definiert.  Die Eigenschaft des Symbols ‘bb’ ist global in Maxima.

          (%i1) matchdeclare (aa, integerp, bb, atom);
          (%o1)                         done
          (%i2) tellsimpafter (foo(aa, bb), bar('aa=aa, 'bb=bb));
          (%o2)                   [foorule1, false]
          (%i3) foo (42, %e);
          (%o3)                 bar(aa = 42, bb = %e)
          (%i4) define_variable (bb, true, boolean);
          (%o4)                         true
          (%i5) foo (42, %e);
          Error: bb was declared mode boolean, has value: %e
           -- an error.  Quitting.  To debug this try debugmode(true);

     Regeln werden nach dem Hauptoperator benannt.  Die Namen der Regeln
     für Maxima-Funktionen und nutzerdefinierte Operatoren sind
     Lisp-Bezeichner.  Alle anderen Namen sind Maxima-Bezeichner.

          (%i1) tellsimpafter (foo (%pi + %e), 3*%pi);
          (%o1)                   [foorule1, false]
          (%i2) tellsimpafter (foo (%pi * %e), 17*%e);
          (%o2)              [foorule2, foorule1, false]
          (%i3) tellsimpafter (foo (%i ^ %e), -42*%i);
          (%o3)         [foorule3, foorule2, foorule1, false]
          (%i4) tellsimpafter (foo (9) + foo (13), quux (22));
          (%o4)                   [+rule1, simplus]
          (%i5) tellsimpafter (foo (9) * foo (13), blurf (22));
          (%o5)                  [*rule1, simptimes]
          (%i6) tellsimpafter (foo (9) ^ foo (13), mumble (22));
          (%o6)                  [^rule1, simpexpt]
          (%i7) rules;
          (%o7) [foorule1, foorule2, foorule3, +rule1, *rule1, ^rule1]
          (%i8) foorule_name: first (%o1);
          (%o8)                       foorule1
          (%i9) plusrule_name: first (%o4);
          (%o9)                        +rule1
          (%i10) remrule (foo, foorule1);
          (%o10)                         foo
          (%i11) remrule ("^", ?\^rule1);
          (%o11)                          ^
          (%i12) rules;
          (%o12)        [foorule2, foorule3, +rule1, *rule1]

     Ein ausgearbeitetes Beispiel der nicht-kommutativen Multiplikation.

          (%i1) gt (i, j) := integerp(j) and i < j;
          (%o1)           gt(i, j) := integerp(j) and i < j
          (%i2) matchdeclare (i, integerp, j, gt(i));
          (%o2)                         done
          (%i3) tellsimpafter (s[i]^^2, 1);
          (%o3)                 [^^rule1, simpncexpt]
          (%i4) tellsimpafter (s[i] . s[j], -s[j] . s[i]);
          (%o4)                   [.rule1, simpnct]
          (%i5) s[1] . (s[1] + s[2]);
          (%o5)                    s  . (s  + s )
                                    1     2    1
          (%i6) expand (%);
          (%o6)                      1 - s  . s
                                          2    1
          (%i7) factor (expand (sum (s[i], i, 0, 9)^^5));
          (%o7) 100 (s  + s  + s  + s  + s  + s  + s  + s  + s  + s )
                      9    8    7    6    5    4    3    2    1    0


File: maxima.info,  Node: Funktionsdefinitionen,  Next: Laufzeitumgebung,  Prev: Muster und Regeln,  Up: Top

25 Funktionsdefinitionen
************************

* Menu:

* Funktionen::
* Makros::
* Funktionen und Variablen für Funktionsdefinitionen::


File: maxima.info,  Node: Funktionen,  Next: Makros,  Prev: Funktionsdefinitionen,  Up: Funktionsdefinitionen

25.1 Funktionen
===============

25.1.1 Gewöhnliche Funktionen
-----------------------------

Eine Maxima-Funktion wird mit dem Operator ‘:=’ oder der Funktion
‘define’ definiert.  Im folgenden wird die Funktion ‘f’ mit dem Operator
‘:=’ definiert:

     f(x) := sin(x)

Funktionen, die mit der Funktion ‘lambda’ definiert werden, sind anonyme
Funktionen, die keinen Namen haben.  Diese werden auch
‘lambda’-Ausdrücke genannt:

     lambda ([i, j], ...)

Anonyme Funktionen können überall dort verwendet werden, wo eine
Funktion als Argument erwartet wird.  Das folgende Beispiel gibt eine
Liste zurück, bei der jedes Element der Liste ‘L’ mit 1 addiert wird:

     map (lambda ([i], i+1), L)

Ist das letzte oder einzige Argument einer Funktion eine Liste mit einem
Element, kann eine variable Anzahl an Argumenten an die Funktion
übergeben werden:

     (%i1) f ([u]) := u;
     (%o1)                      f([u]) := u
     (%i2) f (1, 2, 3, 4);
     (%o2)                     [1, 2, 3, 4]
     (%i3) f (a, b, [u]) := [a, b, u];
     (%o3)               f(a, b, [u]) := [a, b, u]
     (%i4) f (1, 2, 3, 4, 5, 6);
     (%o4)                 [1, 2, [3, 4, 5, 6]]

Die rechte Seite einer Funktionsdefinition ist ein Ausdruck.  Mehrere
Ausdrücke werden durch Kommata getrennt und mit Klammern umgeben.  Das
Ergebnis der Funktion ist der Wert des letzten Ausdrucks ‘exprn’:

     f(x) := (expr1, expr2, ...., exprn);

Ein Rücksprung mit der Anweisung ‘return’ aus einer Funktion ist
möglich, wenn die Definition der Funktion in einen Block eingefügt wird.
Ein Block wird mit der ‘block’-Anweisung definiert.  Das folgende
Beispiel hat entweder den Wert ‘a’ oder den Wert des Ausdrucks <exprn>
als Ergebnis:

     block ([], expr1, ..., if (a > 10) then return(a), ..., exprn)

Das erste paar Klammern ‘[]’ in einem Block enthält die Definition von
lokalen Variablen wie zum Beispiel ‘[a: 3, b, c: []]’.  Die Variablen
sind außerhalb des Blocks nicht sichtbar.  Die Werte von globalen
Variablen werden von den lokalen Werten überschrieben.  Außerhalb des
Blocks haben die Variablen, wenn vorhanden, wieder ihre alten Werte.
Die Zuweisung der Werte an die lokalen Variablen wird parallel
ausgeführt.

Im folgenden Beispiel wird der Wert der globalen Variablen <a> der
lokalen Variablen <a> zugewiesen.  Änderungen von <a> im Block wirken
sich nicht auf den globalen Wert der Variablen aus.

     block ([a: a], expr1, ... a: a+3, ..., exprn)

Die Anweisung ‘block ([x], ...)’ bewirkt, dass ‘x’ als lokale Variable
ohne einen Wert verwendet werden kann.

Die Argumente einer Funktion werden in gleicher Weise wie lokal
definierte Variable behandelt.  Die folgende Definition

     f(x) := (expr1, ..., exprn);

mit

     f(1);

hat denselben Effekt wie der folgende Block:

     block ([x: 1], expr1, ..., exprn)

Soll die rechte Seite einer Funktionsdefinition ausgewertet werden, kann
die Funktionen ‘define’ für die Definition der Funktion verwendet
werden.  Mit der Funktion ‘buildq’ kann die Definition einer Funktion
konstruiert werden, wobei die Auswertung gezielt kontrolliert werden
kann.

25.1.2 Array-Funktionen
-----------------------

Eine Array-Funktion speichert bei dem ersten Aufruf den Funktionswert zu
dem Argument.  Wird die Array-Funktion mit demselben Argument
aufgerufen, wird der gespeicherte Wert zurückgeben, ohne diesen neu zu
berechnen.  Dies wird auch Memoisation genannt.

Beispiel:

Das folgende Beispiel zeigt die Definition einer Array-Funktion ‘f’, die
die Fakultät einer Zahl faktorisiert.  Im ersten Aufruf der Funktion mit
dem Argument ‘25000’ wird eine Rechenzeit von etwa 24 Sekunden benötigt.
Der zweite Aufruf mit demselben Argument gibt sofort den abgespeicherten
Wert zurück.

     (%i1) f[x]:=factor(x!);
     (%o1)                   f  := factor(x!)
                              x
     (%i2) showtime:true;
     Evaluation took 0.0000 seconds (0.0000 elapsed) using 0 bytes.
     (%o2)                         true
     (%i3) f[25000]$
     Evaluation took 23.9250 seconds (26.0790 elapsed) using 3829.778 MB.
     (%i4) f[25000]$
     Evaluation took 0.0000 seconds (0.0000 elapsed) using 0 bytes.

Die Namen der Array-Funktionen werden in die Informationsliste ‘arrays’
und nicht in die Liste ‘functions’ eingetragen.  ‘arrayinfo’ gibt eine
Liste der Argumente zurück, für die Werte gespeichert sind und
‘listarray’ gibt die Werte zurück.  Die Funktionen ‘dispfun’ und
‘fundef’ geben die Definition der Array-Funktion zurück.

Beispiele:

Mit dem obigen Beispiel werden die folgenden Ergebnisse ausgegeben.

     (%i5) arrays;
     (%o5)                          [f]
     (%i6) arrayinfo(f);
     (%o6)                 [hashed, 1, [25000]]
     (%i7) dispfun(f);
     (%t7)                   f  := factor(x!)
                              x
     (%o7)                         [%t7]

‘arraymake’ erzeugt den Aufruf einer Array-Funktion.  Dies ist analog zu
der Funktion ‘funmake’ für gewöhnliche Funktionen.  ‘arrayapply’ wendet
eine Array-Funktion auf die Argumente an.  Dies entspricht der Funktion
‘apply’ für gewöhnliche Funktionen.  Die Funktion ‘map’ hat keine
Entsprechung für Array-Funktionen.  Vergleichbare Konstruktionen sind
‘map(lambda([<x>], <a>[<x>]), <L>)’ oder ‘makelist(<a>[<x>], <x>, <L>)’,
wobei <L> eine Liste ist.

‘remarray’ entfernt die Definition einer Array-Funktion einschließlich
der gespeicherten Werte.  Dies entspricht ‘remfunction’ für gewöhnliche
Funktionen.

‘kill(<a>[<x>])’ entfernt den für das Argument <x> gespeicherten Wert
einer Array-Funktion <a>.  Beim nächsten Aufruf von <a> mit dem Argument
<x> wird der Funktionswert neu berechnet.  Es gibt keine Möglichkeit,
alle gespeicherten Werte zu löschen, ohne dass die Definition der
Funktion entfernt wird.  Die Kommandos ‘kill(<a>)’ und ‘remarray(<a>)’
löschen alle Werte einschließlich der Definition der Funktion.


File: maxima.info,  Node: Makros,  Next: Funktionen und Variablen für Funktionsdefinitionen,  Prev: Funktionen,  Up: Funktionsdefinitionen

25.2 Makros
===========

 -- Funktion: buildq (<L>, <expr>)

     Die Variablen der Liste <L> werden in den Ausdruck <expr>
     substituiert.  Die Substitution wird parallel ausgeführt.  Das
     Ergebnis der Substitution wird vereinfacht, aber nicht ausgewertet.

     Die Elemente der Liste <L> sind Symbole oder Zuweisungen der Form
     ‘<symbol>: <value>’.  Die Zuweisungen werden parallel ausgewertet.
     Der Wert einer Variablen auf der rechten Seite einer Zuweisung ist
     der globale Wert in dem Kontext in dem ‘buildq’ aufgerufen wird und
     nicht der lokale Wert einer vorhergehenden Zuweisung.  Erhält eine
     Variable keinen Wert, dann behält die Variable den globalen Wert.

     Dann werden die in der Liste <L> enthaltenen Variablen parallel in
     den Ausdruck <expr> substituiert.

     Enthält <expr> Ausdrücke der Form ‘splice(<x>)’, muss die Variable
     <x> eine Liste sein.  Die Liste wird in den Ausdruck eingefügt.
     Siehe auch ‘splice’.

     Variablen in in dem Ausdruck <expr>, die nicht in <L> enthalten
     sind, werden nicht durch einen Wert ersetzt, auch wenn es eine
     globale Variable mit demselben Namen gibt, da der Ausdruck nicht
     ausgewertet wird.

     Beispiele:

     Der Variablen ‘a’ wird der Wert zugewiesen.  Die Variable ‘b’
     erhält den globalen Wert.  Die Variable ‘c’ hat keinen Wert.  Das
     Ergebnis ist ein nicht ausgewerteter Ausdruck.  Die Auswertung wird
     mit dem Quote-Quote-Operator ‘''’ erzwungen.

          (%i1) (a: 17, b: 29, c: 1729)$
          (%i2) buildq ([a: x, b], a + b + c);
          (%o2)                      x + c + 29
          (%i3) ''%;
          (%o3)                       x + 1758

     ‘e’ ist eine Liste, die einmal als Argument der Funktion ‘foo’
     vorliegt und zum anderen in die Argumentliste der Funktion ‘bar’
     eingefügt wird.

          (%i1) buildq ([e: [a, b, c]], foo (x, e, y));
          (%o1)                 foo(x, [a, b, c], y)
          (%i2) buildq ([e: [a, b, c]], bar (x, splice (e), y));
          (%o2)                  bar(x, a, b, c, y)

     Das Ergebnis wird nach der Substitution vereinfacht, ansonsten
     hätten die beiden folgenden Beispiele dasselbe Ergebnis.

          (%i1) buildq ([e: [a, b, c]], splice (e) + splice (e));
          (%o1)                    2 c + 2 b + 2 a
          (%i2) buildq ([e: [a, b, c]], 2 * splice (e));
          (%o2)                        2 a b c

     Die Variablen der Liste <L> erhalten ihren Wert parallel, ansonsten
     wäre das erste Ergebnis ‘foo(b,b)’.  Substitutionen werden parallel
     ausgeführt.  Im Gegensatz dazu werden die Substitutionen mit der
     Funktion ‘subst’ nacheinander ausgeführt.

          (%i1) buildq ([a: b, b: a], foo (a, b));
          (%o1)                       foo(b, a)
          (%i2) buildq ([u: v, v: w, w: x, x: y, y: z, z: u],
                        bar (u, v, w, x, y, z));
          (%o2)                 bar(v, w, x, y, z, u)
          (%i3) subst ([u=v, v=w, w=x, x=y, y=z, z=u],
                       bar (u, v, w, x, y, z));
          (%o3)                 bar(u, u, u, u, u, u)

     Konstruktion einer Liste mit Gleichungen mit Variablen oder
     Ausdrücken auf der linken Seite und deren Werten auf der rechten
     Seite.  Die Funktion ‘macroexpand’ expandiert das Makro
     ‘show_values’.

          (%i1) show_values ([L]) ::= buildq ([L], map ("=", 'L, L))$
          (%i2) (a: 17, b: 29, c: 1729)$
          (%i3) show_values (a, b, c - a - b);
          (%o3)          [a = 17, b = 29, c - b - a = 1683]
          (%i4) macroexpand (show_values (a, b, c - a - b));
          (%o4)    map(=, '([a, b, c - b - a]), [a, b, c - b - a])

     Konstruktion einer Funktion.

          (%i1) curry (f, [a]) :=
                  buildq ([f, a], lambda ([[x]], apply (f, append (a, x))))$
          (%i2) by3 : curry ("*", 3);
          (%o2)        lambda([[x]], apply(*, append([3], x)))
          (%i3) by3 (a + b);
          (%o3)                       3 (b + a)

 -- Funktion: macroexpand (<expr>)

     Ist das Argument <expr> ein Makro, wird das Makro expandiert, ohne
     dass es ausgewertet wird.  Ansonsten wird <expr> zurückgegeben.

     Ist die Expansion des Makros selbst ein Makro, wird dieses Makro
     wiederholt expandiert.

     ‘macroexpand’ wertet das Argument <expr> nicht aus.  Hat die
     Expansion des Makros Seiteneffekte, dann werden diese ausgeführt.

     Siehe auch ‘::=’ und ‘macroexpand1’.

     Beispiele:

          (%i1) g (x) ::= x / 99;
                                              x
          (%o1)                      g(x) ::= --
                                              99
          (%i2) h (x) ::= buildq ([x], g (x - a));
          (%o2)            h(x) ::= buildq([x], g(x - a))
          (%i3) a: 1234;
          (%o3)                         1234
          (%i4) macroexpand (h (y));
                                        y - a
          (%o4)                         -----
                                         99
          (%i5) h (y);
                                      y - 1234
          (%o5)                       --------
                                         99

 -- Funktion: macroexpand1 (<expr>)

     Gibt die Makro-Expansion von <expr> zurück, ohne das Ergebnis
     auszuwerten.  Ist <expr> keine Makro-Funktion gibt ‘macroexpand1’
     das Argument <expr> zurück.

     ‘macroexpand1’ wertet das Argument nicht aus.  Hat die Expansion
     des Makros Seiteneffekte, dann werden diese ausgeführt.

     Enthält die Expansion <expr> wiederum Makros, werden diese im
     Unterschied zur Funktion ‘macroexpand’ nicht expandiert.

     Siehe auch ‘::=’ und ‘macroexpand’.

     Beispiele:

          (%i1) g (x) ::= x / 99;
                                              x
          (%o1)                      g(x) ::= --
                                              99
          (%i2) h (x) ::= buildq ([x], g (x - a))$
          (%i3) a: 1234;
          (%o3)                         1234
          (%i4) macroexpand1 (h (y));
          (%o4)                       g(y - a)
          (%i5) h (y);
                                      y - 1234
          (%o5)                       --------
                                         99

 -- Optionsvariable: macroexpansion
     Standardwert: ‘false’

     ‘macroexpansion’ kontrolliert die Expansion von Makros.

     ‘false’
          Die Expansion des Makros wird nicht für die aufrufende
          Funktion ersetzt.

     ‘expand’
          Wird die Makro-Funktion das erste Mal ausgewertet, wird die
          Expansion des Makros gespeichert.  Weitere Aufrufe werten das
          Makro nicht erneut aus.  Seiteneffekte, wie Zuweisungen an
          globale Variablen, werden nur bei der ersten Auswertung
          wirksam.  Die Expansion des Makros beeinflusst nicht andere
          Ausdrücke, die das Makro ebenfalls aufrufen.

     ‘displace’
          Wird die Makro-Funktion das erste mal ausgewertet, wird die
          Expansion des Makros in den aufrufenden Ausdruck eingesetzt.
          Weitere Aufrufe werten das Makro nicht erneut aus.
          Seiteneffekte, wie Zuweisungen an globale Variablen, werden
          nur bei der ersten Auswertung wirksam.  Die Expansion des
          Makros beeinflusst nicht andere Ausdrücke, die das Makro
          ebenfalls aufrufen.

     Beispiele:

     Hat ‘macroexpansion’ den Wert ‘false’, wird eine Makro-Funktion
     jedes mal aufgerufen, wenn der aufrufende Ausdruck ausgewertet
     wird.  Der aufrufende Ausdruck wird nicht modifiziert.

          (%i1) f (x) := h (x) / g (x);
                                            h(x)
          (%o1)                     f(x) := ----
                                            g(x)
          (%i2) g (x) ::= block (print ("x + 99 is equal to", x),
                                 return (x + 99));
          (%o2) g(x) ::= block(print("x + 99 is equal to", x),
                                                            return(x + 99))
          (%i3) h (x) ::= block (print ("x - 99 is equal to", x),
                                 return (x - 99));
          (%o3) h(x) ::= block(print("x - 99 is equal to", x),
                                                            return(x - 99))
          (%i4) macroexpansion: false;
          (%o4)                         false
          (%i5) f (a * b);
          x - 99 is equal to x
          x + 99 is equal to x
                                      a b - 99
          (%o5)                       --------
                                      a b + 99
          (%i6) dispfun (f);
                                            h(x)
          (%t6)                     f(x) := ----
                                            g(x)

          (%o6)                         done
          (%i7) f (a * b);
          x - 99 is equal to x
          x + 99 is equal to x
                                      a b - 99
          (%o7)                       --------
                                      a b + 99

     Hat ‘macroexpansion’ den Wert ‘expand’, wird eine Makro-Funktion
     nur einmal aufgerufen.  Der aufrufende Ausdruck wird nicht
     modifiziert.

          (%i1) f (x) := h (x) / g (x);
                                            h(x)
          (%o1)                     f(x) := ----
                                            g(x)
          (%i2) g (x) ::= block (print ("x + 99 is equal to", x),
                                 return (x + 99));
          (%o2) g(x) ::= block(print("x + 99 is equal to", x),
                                                            return(x + 99))
          (%i3) h (x) ::= block (print ("x - 99 is equal to", x),
                                 return (x - 99));
          (%o3) h(x) ::= block(print("x - 99 is equal to", x),
                                                            return(x - 99))
          (%i4) macroexpansion: expand;
          (%o4)                        expand
          (%i5) f (a * b);
          x - 99 is equal to x
          x + 99 is equal to x
                                      a b - 99
          (%o5)                       --------
                                      a b + 99
          (%i6) dispfun (f);
                                            h(x)
          (%t6)                     f(x) := ----
                                            g(x)

          (%o6)                         done
          (%i7) f (a * b);
                                      a b - 99
          (%o7)                       --------
                                      a b + 99

     Hat ‘macroexpansion’ den Wert ‘displace’, wird eine Makro-Funktion
     nur einmal aufgerufen.  Der aufrufende Ausdruck wird modifiziert.

          (%i1) f (x) := h (x) / g (x);
                                            h(x)
          (%o1)                     f(x) := ----
                                            g(x)
          (%i2) g (x) ::= block (print ("x + 99 is equal to", x),
                                 return (x + 99));
          (%o2) g(x) ::= block(print("x + 99 is equal to", x),
                                                            return(x + 99))
          (%i3) h (x) ::= block (print ("x - 99 is equal to", x),
                                 return (x - 99));
          (%o3) h(x) ::= block(print("x - 99 is equal to", x),
                                                            return(x - 99))
          (%i4) macroexpansion: displace;
          (%o4)                       displace
          (%i5) f (a * b);
          x - 99 is equal to x
          x + 99 is equal to x
                                      a b - 99
          (%o5)                       --------
                                      a b + 99
          (%i6) dispfun (f);
                                           x - 99
          (%t6)                    f(x) := ------
                                           x + 99

          (%o6)                         done
          (%i7) f (a * b);
                                      a b - 99
          (%o7)                       --------
                                      a b + 99

 -- Systemvariable: macros
     Standardwert: ‘[]’

     Die Systemvariable ‘macros’ ist eine Informationsliste, die die vom
     Nutzer mit dem Operator ‘::=’ definierten Makros enthält.  Wird das
     Makro mit einer der Funktionen ‘kill’, ‘remove’ oder ‘remfunction’
     gelöscht, wird der Eintrag aus der Informationsliste entfernt.
     Siehe auch die Systemvariable ‘infolists’.

 -- Funktion: splice (<a>)

     Die Funktion ‘splice’ kann nur im Zusammenhang mit der Funktion
     ‘buildq’ verwendet werden.  Das Argument <a> bezeichnet eine Liste,
     die an Stelle von ‘splice(a)’ in einen Ausdruck eingefügt wird.
     <a> kann nicht selbst eine Liste oder ein Ausdruck sein, der zu
     einer Liste auswertet.

     Beispiele:

          (%i1) buildq ([x: [1, %pi, z - y]], foo (splice (x)) / length (x));
                                 foo(1, %pi, z - y)
          (%o1)                -----------------------
                               length([1, %pi, z - y])
          (%i2) buildq ([x: [1, %pi]], "/" (splice (x)));
                                          1
          (%o2)                          ---
                                         %pi
          (%i3) matchfix ("<>", "<>");
          (%o3)                          <>
          (%i4) buildq ([x: [1, %pi, z - y]], "<>" (splice (x)));
          (%o4)                   <>1, %pi, z - y<>


File: maxima.info,  Node: Funktionen und Variablen für Funktionsdefinitionen,  Prev: Makros,  Up: Funktionsdefinitionen

25.3 Funktionen und Variablen für Funktionsdefinitionen
=======================================================

 -- Funktion: apply (<F>, [<x_1>, …, <x_n>])

     Konstruiert den Ausdruck ‘<F>(<arg_1>, ..., <arg_n>)’ und wertet
     diesen aus.

     ‘apply’ versucht nicht Array-Funktionen von gewöhnlichen Funktionen
     zu unterscheiden.  Ist <F> der Name eine Array-Funktion, wertet
     ‘apply’ den Ausdruck ‘<F>(...)’ aus.  ‘arrayapply’ entspricht der
     Funktion ‘apply’, wenn <F> eine Array-Funktion ist.

     Beispiele:

     ‘apply’ wertet die Argumente aus.  In diesem Beispiel wird die
     Funktion ‘min’ auf die Liste ‘L’ angewendet.

          (%i1) L : [1, 5, -10.2, 4, 3];
          (%o1)                 [1, 5, - 10.2, 4, 3]
          (%i2) apply (min, L);
          (%o2)                        - 10.2

     ‘apply’ wertet die Argumente auch dann aus, wenn die Funktion ‘F’
     die Auswertung ihrer Argumente unterdrückt.

          (%i1) F (x) := x / 1729;
                                             x
          (%o1)                     F(x) := ----
                                            1729
          (%i2) fname : F;
          (%o2)                           F
          (%i3) dispfun (F);
                                             x
          (%t3)                     F(x) := ----
                                            1729

          (%o3)                         [%t3]
          (%i4) dispfun (fname);
          fname is not the name of a user function.
           -- an error.  Quitting.  To debug this try debugmode(true);
          (%i5) apply (dispfun, [fname]);
                                             x
          (%t5)                     F(x) := ----
                                            1729

          (%o5)                         [%t5]

     ‘apply’ wertet den Namen der Funktion <F> aus.  Mit dem
     Quote-Operator ‘'’ wird die Auswertung unterdrückt.  ‘demoivre’ ist
     der Name einer globalen Optionsvariable und einer Funktion.

          (%i1) demoivre;
          (%o1)                         false
          (%i2) demoivre (exp (%i * x));
          (%o2)                  %i sin(x) + cos(x)
          (%i3) apply (demoivre, [exp (%i * x)]);
          demoivre evaluates to false
          Improper name or value in functional position.
           -- an error.  Quitting.  To debug this try debugmode(true);
          (%i4) apply ('demoivre, [exp (%i * x)]);
          (%o4)                  %i sin(x) + cos(x)

 -- Funktion: define (<f>(<x_1>, …, <x_n>), <expr>)
 -- Funktion: define (<f>[<x_1>, …, <x_n>], <expr>)
 -- Funktion: define (funmake (<f>, [<x_1>, …, <x_n>]), <expr>)
 -- Funktion: define (arraymake (<f>, [<x_1>, …, <x_n>]), <expr>)
 -- Funktion: define (ev (<expr_1>), <expr_2>)

     Definiert eine Funktion mit dem Namen <f> und den Argumenten <x1>,
     …, <x_n> und der Funktionsdefinition <expr>.  ‘define’ wertet das
     zweite Argument immer aus.

     Ist das letzte oder einzige Argument <x_n> eine Liste mit einem
     Element, dann akzeptiert die Funktion eine variable Anzahl an
     Argumenten.  Die Argumente der Funktion werden nacheinander den
     Variablen <x_1>, …, <x_(n-1)> zugewiesen.  Sind weitere Argumente
     vorhanden, werden diese als Liste der Variablen <x_n> zugewiesen.

     Ist das erste Argument der Funktion ‘define’ ein Ausdruck der Form
     ‘<f>(<x_1>, ..., <x_n>)’ oder ‘<f>[<x_1>, ..., <x_n>]’ werden die
     Argumente der Funktion ausgewertet, aber nicht die Funktion <f>
     selbst.  <f> wird auch dann nicht ausgewertet, wenn es bereits eine
     Funktion mit dem Namen <f> gibt.

     Das erste Argument wird dann ausgewertet, wenn es ein Ausdruck mit
     den Funktionen ‘funmake’, ‘arraymake’ oder ‘ev’ ist.

     Alle Funktionsdefinitionen treten in demselben Namensraum auf.  Die
     Definition einer Funktion ‘g’ innerhalb einer Funktion ‘f’ führt
     nicht automatisch zu einer lokalen Definition.  Um eine lokale
     Funktion zu erhalten, kann ‘lokal(g)’ innerhalb der Funktion ‘f’
     ausgeführt werden.  Siehe auch ‘local’.

     Ist eines der Argumente <x_k> nach der Auswertung ein quotiertes
     Symbol, wertet die mit ‘define’ definierte Funktion das Argument
     nicht aus.  Alle weiteren Argumente der Funktion werden
     ausgewertet.

     Siehe auch ‘:=’ und ‘::=’.

     Beispiele:

     ‘define’ wertet das zweite Argument aus.

          (%i1) expr : cos(y) - sin(x);
          (%o1)                    cos(y) - sin(x)
          (%i2) define (F1 (x, y), expr);
          (%o2)              F1(x, y) := cos(y) - sin(x)
          (%i3) F1 (a, b);
          (%o3)                    cos(b) - sin(a)
          (%i4) F2 (x, y) := expr;
          (%o4)                   F2(x, y) := expr
          (%i5) F2 (a, b);
          (%o5)                    cos(y) - sin(x)

     Mit ‘define’ können gewöhnliche Maxima-Funktionen und
     Array-Funktionen definiert werden.

          (%i1) define (G1 (x, y), x.y - y.x);
          (%o1)               G1(x, y) := x . y - y . x
          (%i2) define (G2 [x, y], x.y - y.x);
          (%o2)                G2     := x . y - y . x
                                 x, y

     Ist das letzte oder einzige Argument <x_n> eine Liste mit einem
     Element, akzeptiert die mit ‘define’ definierte Funktion eine
     variable Anzahl an Argumenten.

          (%i1) define (H ([L]), '(apply ("+", L)));
          (%o1)                H([L]) := apply("+", L)
          (%i2) H (a, b, c);
          (%o2)                       c + b + a

     Ist das erste Argument ein Ausdruck mit den Funktionen ‘funmake’,
     ‘arraymake’ oder ‘ev’ wird das Argument ausgewertet.

          (%i1) [F : I, u : x];
          (%o1)                        [I, x]
          (%i2) funmake (F, [u]);
          (%o2)                         I(x)
          (%i3) define (funmake (F, [u]), cos(u) + 1);
          (%o3)                  I(x) := cos(x) + 1
          (%i4) define (arraymake (F, [u]), cos(u) + 1);
          (%o4)                   I  := cos(x) + 1
                                   x
          (%i5) define (foo (x, y), bar (y, x));
          (%o5)                foo(x, y) := bar(y, x)
          (%i6) define (ev (foo (x, y)), sin(x) - cos(y));
          (%o6)             bar(y, x) := sin(x) - cos(y)

 -- Funktion: define_variable (<name>, <default_value>, <mode>)

     Definiert eine globale Variable in der Maxima-Umgebung.
     ‘define_variable’ ist nützlich für das Schreiben von Paketen, die
     häufig übersetzt oder kompiliert werden.  ‘define_variable’ führt
     die folgenden Schritte aus:

       1. ‘mode_declare(<name>, <mode>)’ deklariert den Typ der
          Variablen <name> für den Übersetzer.  Siehe ‘mode_declare’ für
          eine Liste der möglichen Typen.

       2. Hat die Variable keinen Wert, wird der Variablen der Wert
          <default_value> zugewiesen.

       3. ‘declare(<name>, special)’ deklariert die Variable als
          Special.

       4. Ordnet der Variablen <name> eine Testfunktion zu, um
          sicherzustellen, dass der Variablen nur Werte zugewiesen
          werden können.

     Einer mit ‘define_variable’ definierten Variablen, die einen
     anderen Typ als ‘any’ erhalten hat, kann die Eigenschaft
     ‘value_check’ zugewiesen werden.  Die ‘value_check’-Eigenschaft ist
     eine Aussagefunktion mit einer Variablen oder ein Lambda-Ausdruck,
     die aufgerufen werden, wenn der Variablen ein Wert zugewiesen
     werden soll.  Das Argument der ‘value_check’-Funktion ist der Wert,
     den die Variable erhalten soll.

     ‘define_variable’ wertet ‘default_value’ aus.  Die Argumente ‘name’
     und ‘mode’ werden nicht ausgewertet.  ‘define_variable’ gibt den
     aktuellen Wert der Variable ‘name’ zurück.  Dieser ist
     ‘default_value’, wenn der Variablen bisher kein Wert zugewiesen
     wurde.

     Beispiele:

     ‘foo’ ist eine boolesche Variable mit dem Wert ‘true’.

          (%i1) define_variable (foo, true, boolean);
          (%o1)                         true
          (%i2) foo;
          (%o2)                         true
          (%i3) foo: false;
          (%o3)                         false
          (%i4) foo: %pi;
          Error: foo was declared mode boolean, has value: %pi
           -- an error.  Quitting.  To debug this try debugmode(true);
          (%i5) foo;
          (%o5)                         false

     ‘bar’ ist eine Variable mit dem Typ einer ganzen Zahl, die eine
     Primzahl sein muss.

          (%i1) define_variable (bar, 2, integer);
          (%o1)                           2
          (%i2) qput (bar, prime_test, value_check);
          (%o2)                      prime_test
          (%i3) prime_test (y) := if not primep(y) then
                                     error (y, "is not prime.");
          (%o3) prime_test(y) := if not primep(y)

                                             then error(y, "is not prime.")
          (%i4) bar: 1439;
          (%o4)                         1439
          (%i5) bar: 1440;
          1440 is not prime.
          #0: prime_test(y=1440)
           -- an error.  Quitting.  To debug this try debugmode(true);
          (%i6) bar;
          (%o6)                         1439

     ‘baz_quux’ ist eine Variable, der kein Wert zugewiesen werden kann.
     Der Typ ‘any_check’ ist vergleichbar mit ‘any’.  Aber ‘any_check’
     ruft im Gegensatz zu ‘any’ den ‘value_check’-Mechanismus auf.

          (%i1) define_variable (baz_quux, 'baz_quux, any_check);
          (%o1)                       baz_quux
          (%i2) F: lambda ([y], if y # 'baz_quux then
                           error ("Cannot assign to `baz_quux'."));
          (%o2) lambda([y], if y # 'baz_quux

                                  then error(Cannot assign to `baz_quux'.))
          (%i3) qput (baz_quux, ''F, value_check);
          (%o3) lambda([y], if y # 'baz_quux

                                  then error(Cannot assign to `baz_quux'.))
          (%i4) baz_quux: 'baz_quux;
          (%o4)                       baz_quux
          (%i5) baz_quux: sqrt(2);
          Cannot assign to `baz_quux'.
          #0: lambda([y],if y # 'baz_quux then
                           error("Cannot assign to `baz_quux'."))(y=sqrt(2))
           -- an error.  Quitting.  To debug this try debugmode(true);
          (%i6) baz_quux;
          (%o6)                       baz_quux

 -- Funktion: dispfun (<f_1>, …, <f_n>)
 -- Funktion: dispfun (all)

     Zeigt die Definitionen der nutzerdefinierten Funktionen <f_1>, …,
     <f_n> an.  Die Argumente können gewöhnliche Funktionen, Makros,
     Array-Funktionen oder indizierte Funktionen sein.

     ‘dispfun(all)’ zeigt die Definitionen aller nutzerdefinierten
     Funktionen an, die in den Informationslisten ‘functions’, ‘arrays’
     oder ‘macros’ enthalten sind.

     ‘dispfun’ erzeugt Zwischenmarken ‘%t’ für jede einzelne
     anzuzeigende Funktion und weist die Funktionsdefinitionen den
     Zwischenmarken zu.  Im Gegensatz dazu, zeigt die Funktion ‘fundef’
     die Funktionsdefinition ohne Zwischenmarken an.

     ‘dispfun’ wertet die Argumente nicht aus.  ‘dispfun’ gibt eine
     Liste mit den Zwischenmarken zurück, die zu den angezeigten
     Funktionen gehören.

     Beispiele:

          (%i1) m(x, y) ::= x^(-y);
                                               - y
          (%o1)                   m(x, y) ::= x
          (%i2) f(x, y) :=  x^(-y);
                                               - y
          (%o2)                    f(x, y) := x
          (%i3) g[x, y] :=  x^(-y);
                                              - y
          (%o3)                     g     := x
                                     x, y
          (%i4) h[x](y) :=  x^(-y);
                                              - y
          (%o4)                     h (y) := x
                                     x
          (%i5) i[8](y) :=  8^(-y);
                                              - y
          (%o5)                     i (y) := 8
                                     8
          (%i6) dispfun (m, f, g, h, h[5], h[10], i[8]);
                                               - y
          (%t6)                   m(x, y) ::= x

                                               - y
          (%t7)                    f(x, y) := x

                                              - y
          (%t8)                     g     := x
                                     x, y

                                              - y
          (%t9)                     h (y) := x
                                     x

                                              1
          (%t10)                     h (y) := --
                                      5        y
                                              5

                                               1
          (%t11)                    h  (y) := ---
                                     10         y
                                              10

                                              - y
          (%t12)                    i (y) := 8
                                     8

          (%o12)       [%t6, %t7, %t8, %t9, %t10, %t11, %t12]
          (%i12) ''%;
                               - y              - y            - y
          (%o12) [m(x, y) ::= x   , f(x, y) := x   , g     := x   ,
                                                      x, y
                            - y           1              1             - y
                  h (y) := x   , h (y) := --, h  (y) := ---, i (y) := 8   ]
                   x              5        y   10         y   8
                                          5             10

 -- Funktion: fullmap (<f>, <expr_1>, …)

     Die Funktion ‘fullmap’ ist vergleichbar mit der Funktion ‘map’.  Im
     Unterschied zu der Funktion ‘map’ kann ‘fullmap’ auf verschachtelte
     Ausdrücke angewendet werden.

     Intern wird ‘fullmap’ von Maxima für die Vereinfachung von Matrizen
     aufgerufen.  Daher können bei der Vereinfachung von Matrizen
     Fehlermeldungen im Zusammenhang mit ‘fullmap’ auftreten, ohne dass
     die Funktion direkt aufgerufen wurde.

     Beispiele:

          (%i1) a + b * c;
          (%o1)                        b c + a
          (%i2) fullmap (g, %);
          (%o2)                   g(b) g(c) + g(a)
          (%i3) map (g, %th(2));
          (%o3)                     g(b c) + g(a)

 -- Funktion: fullmapl (<f>, <list_1>, …)

     Die Funktion ‘fullmapl’ ist vergleichbar mit ‘fullmap’.  ‘fullmapl’
     kann jedoch nur auf Matrizen und Listen angewendet werden kann.

     Beispiele:

          (%i1) fullmapl ("+", [3, [4, 5]], [[a, 1], [0, -1.5]]);
          (%o1)                [[a + 3, 4], [4, 3.5]]

 -- Systemvariable: functions
     Standardwert: ‘[]’

     ‘functions’ ist eine Informationsliste, die die vom Nutzer mit dem
     Operator ‘:=’ oder der Funktion ‘define’ definierten Funktionen
     enthält.  Siehe auch die Systemvariable ‘infolists’.

     Array-Funktionen und indizierte Funktionen werden nicht in die
     Informationsliste ‘functions’, sondern in die Informationsliste
     ‘arrays’ eingetragen.

     Beispiele:

          (%i1) F_1 (x) := x - 100;
          (%o1)                   F_1(x) := x - 100
          (%i2) F_2 (x, y) := x / y;
                                                x
          (%o2)                    F_2(x, y) := -
                                                y
          (%i3) define (F_3 (x), sqrt (x));
          (%o3)                   F_3(x) := sqrt(x)
          (%i4) G_1 [x] := x - 100;
          (%o4)                    G_1  := x - 100
                                      x
          (%i5) G_2 [x, y] := x / y;
                                               x
          (%o5)                     G_2     := -
                                       x, y    y
          (%i6) define (G_3 [x], sqrt (x));
          (%o6)                    G_3  := sqrt(x)
                                      x
          (%i7) H_1 [x] (y) := x^y;
                                                y
          (%o7)                     H_1 (y) := x
                                       x
          (%i8) functions;
          (%o8)              [F_1(x), F_2(x, y), F_3(x)]
          (%i9) arrays;
          (%o9)                 [G_1, G_2, G_3, H_1]

 -- Funktion: fundef (<f>)

     Gibt die Definition der Funktion <f> zurück.

     Das Argument <f> kann eine gewöhnliche Funktion, eine
     Makro-Funktion, eine Array-Funktion oder eine indizierte Funktion
     sein.

     ‘fundef’ wertet das Argument aus.  Siehe auch ‘dispfun’.

 -- Funktion: funmake (<F>, [<arg_1>, …, <arg_n>])

     Gibt den Ausdruck ‘<F>(<arg_1>, ..., <arg_n>)’ zurück.  Die
     Rückgabe wird vereinfacht, aber nicht ausgewertet.  Die Funktion
     <F> wird also nicht aufgerufen, auch wenn diese existiert.

     ‘funmake’ versucht nicht, Array-Funktionen von gewöhnlichen
     Funktionen zu unterscheiden.  Ist <F> der Name einer
     Array-Funktion, dann gibt ‘funmake’ einen Ausdruck der Form
     ‘<F>(...)’ zurück.  Für Array-Funktionen kann die Funktion
     ‘arraymake’ verwendet werden.

     ‘funmake’ wertet die Argumente aus.

     Beispiele:

     ‘funmake’ angewendet auf eine gewöhnliche Funktion.

          (%i1) F (x, y) := y^2 - x^2;
                                             2    2
          (%o1)                  F(x, y) := y  - x
          (%i2) funmake (F, [a + 1, b + 1]);
          (%o2)                    F(a + 1, b + 1)
          (%i3) ''%;
                                        2          2
          (%o3)                  (b + 1)  - (a + 1)

     ‘funmake’ angewendet auf ein Makro.

          (%i1) G (x) ::= (x - 1)/2;
                                            x - 1
          (%o1)                    G(x) ::= -----
                                              2
          (%i2) funmake (G, [u]);
          (%o2)                         G(u)
          (%i3) ''%;
                                        u - 1
          (%o3)                         -----
                                          2

     ‘funmake’ angewendet auf eine indizierte Funktion.

          (%i1) H [a] (x) := (x - 1)^a;
                                                  a
          (%o1)                   H (x) := (x - 1)
                                   a
          (%i2) funmake (H [n], [%e]);
                                                 n
          (%o2)               lambda([x], (x - 1) )(%e)
          (%i3) ''%;
                                              n
          (%o3)                       (%e - 1)
          (%i4) funmake ('(H [n]), [%e]);
          (%o4)                        H (%e)
                                        n
          (%i5) ''%;
                                              n
          (%o5)                       (%e - 1)

     ‘funmake’ angewendet auf ein Symbol, welches keine Funktion
     repräsentiert.

          (%i1) funmake (A, [u]);
          (%o1)                         A(u)
          (%i2) ''%;
          (%o2)                         A(u)

     ‘funmake’ wertet die Argumente, aber nicht die Rückgabe aus.

          (%i1) det(a,b,c) := b^2 -4*a*c;
                                              2
          (%o1)              det(a, b, c) := b  - 4 a c
          (%i2) (x : 8, y : 10, z : 12);
          (%o2)                          12
          (%i3) f : det;
          (%o3)                          det
          (%i4) funmake (f, [x, y, z]);
          (%o4)                    det(8, 10, 12)
          (%i5) ''%;
          (%o5)                         - 284

     Maxima vereinfacht den Rückgabewert der Funktion ‘funmake’.

          (%i1) funmake (sin, [%pi / 2]);
          (%o1)                           1

 -- Funktion: lambda ([<x_1>, …, <x_m>], <expr_1>, …, <expr_n>)
 -- Funktion: lambda ([[<L>]], <expr_1>, …, <expr_n>)
 -- Funktion: lambda ([<x_1>, …, <x_m>, [<L>]], <expr_1>, …, <expr_n>)

     Definiert einen Lambda-Ausdruck, der auch als anonyme Funktion
     bezeichnet wird, und gibt diesen zurück.  Die Funktion kann
     Argumente <x_1>, …, <x_m> und optionale Argumente <L> haben.  Die
     Rückgabe der Funktion ist das Ergebnis des Ausdrucks <exprn>.  Ein
     Lambda-Ausdruck kann einer Variablen zugewiesen werden und wertet
     wie eine gewöhnliche Funktion aus.  Ein Lambda-Ausdruck kann an
     solchen Stellen verwendet werden, wo der Name einer Funktion
     erwartet wird.

     Wird der Lambda-Ausdruck ausgewertet, werden lokale Variablen
     <x_1>, …, <x_m> erzeugt.  ‘lambda’ kann innerhalb von Blöcken oder
     anderen Lambda-Ausdrücken verwendet werden.  Mit jeder
     ‘block’-Anweisung oder jedem Lambda-Ausdruck werden erneut lokale
     Variablen erzeugt.  Die lokalen Variablen sind jeweils global zu
     jeder eingeschlossenen ‘block’-Anweisung oder zu jedem
     eingeschlossenen Lambda-Ausdruck.  Ist eine Variable innerhalb von
     ‘block’ oder ‘lambda’ nicht lokal, hat sie den Wert der nächst
     höheren Anweisung, die ihr einen Wert gibt oder den globalen Wert
     der Maxima-Umgebung.

     Nachdem die lokalen Variablen erzeugt sind, werden die Ausdrücke
     <expr_1>, …, <expr_n> nacheinander ausgewertet.  Die Systemvariable
     ‘%%’, welche das Ergebnis eines vorhergehendes Ausdrucks enthält,
     kann verwendet werden.  In einem Lambda-Ausdruck können die
     Anweisungen ‘catch’ und ‘throw’ verwendet werden.

     Die ‘return’-Anweisung kann in einem Lambda-Ausdruck nur verwendet
     werden, wenn sie von einer ‘block’-Anweisung eingeschlossen wird.
     Die ‘return’-Anweisung definiert jedoch den Rückgabewert des Blocks
     und nicht des Lambda-Ausdrucks.  Auch die ‘go’-Anweisung kann in
     einem Lambda-Ausdrucks nur in einem Block verwendet werden.

     ‘lambda’ wertet die Argumente nicht aus.

     Beispiele:

     Ein Lambda-Ausdruck kann einer Variablen zugewiesen werden und wie
     eine gewöhnliche Funktion ausgewertet werden.

          (%i1) f: lambda ([x], x^2);
                                                2
          (%o1)                    lambda([x], x )
          (%i2) f(a);
                                          2
          (%o2)                          a

     Ein Lamda-Ausdruck kann an Stellen verwendet werden, wo der Name
     einer Funktion erwartet wird.

          (%i3) lambda ([x], x^2) (a);
                                          2
          (%o3)                          a
          (%i4) apply (lambda ([x], x^2), [a]);
                                          2
          (%o4)                          a
          (%i5) map (lambda ([x], x^2), [a, b, c, d, e]);
                                  2   2   2   2   2
          (%o5)                 [a , b , c , d , e ]

     Die Argumente sind lokale Variablen.  Andere Variablen sind globale
     Variablen.  Globale Variablen werden zu dem Zeitpunkt ausgewertet,
     wenn der Lambda-Ausdruck ausgewertet wird.

          (%i6) a: %pi$
          (%i7) b: %e$
          (%i8) g: lambda ([a], a*b);
          (%o8)                   lambda([a], a b)
          (%i9) b: %gamma$
          (%i10) g(1/2);
                                       %gamma
          (%o10)                       ------
                                         2
          (%i11) g2: lambda ([a], a*''b);
          (%o11)                lambda([a], a %gamma)
          (%i12) b: %e$
          (%i13) g2(1/2);
                                       %gamma
          (%o13)                       ------
                                         2

     Lambda-Ausdrücke können verschachtelt werden.  Lokale Variablen
     eines äußeren Lambda-Ausdrucks sind global zu den enthaltenen
     Lambda-Ausdrücken, außer diese werden wieder als lokal erklärt.

          (%i14) h: lambda ([a, b], h2: lambda ([a], a*b), h2(1/2));
                                                             1
          (%o14)    lambda([a, b], h2 : lambda([a], a b), h2(-))
                                                             2
          (%i15) h(%pi, %gamma);
                                       %gamma
          (%o15)                       ------
                                         2

     Da ‘lambda’ die Argumente nicht auswertet, definiert der unten
     angegebene Ausdruck ‘i’ keine Funktion "multipliziere mit ‘a’".
     Solch eine Funktion kann mit Hilfe der Funktion ‘buildq’ definiert
     werden.

          (%i16) i: lambda ([a], lambda ([x], a*x));
          (%o16)            lambda([a], lambda([x], a x))
          (%i17) i(1/2);
          (%o17)                  lambda([x], a x)
          (%i18) i2: lambda([a], buildq([a: a], lambda([x], a*x)));
          (%o18)    lambda([a], buildq([a : a], lambda([x], a x)))
          (%i19) i2(1/2);
                                               x
          (%o19)                   lambda([x], -)
                                               2
          (%i20) i2(1/2)(%pi);
                                         %pi
          (%o20)                         ---
                                          2

     Ein Lambda-Ausdruck kann eine variable Anzahl an Argumenten haben,
     wenn das letzte Argument eine Liste mit einem Element ist.

          (%i1) f : lambda ([aa, bb, [cc]], aa * cc + bb);
          (%o1)          lambda([aa, bb, [cc]], aa cc + bb)
          (%i2) f (foo, %i, 17, 29, 256);
          (%o2)       [17 foo + %i, 29 foo + %i, 256 foo + %i]
          (%i3) g : lambda ([[aa]], apply ("+", aa));
          (%o3)             lambda([[aa]], apply(+, aa))
          (%i4) g (17, 29, x, y, z, %e);
          (%o4)                  z + y + x + %e + 46

 -- Funktion: map (<f>, <expr_1>, …, <expr_n>)

     Gibt einen Ausdruck zurück, dessen Hauptoperator derselbe ist, wie
     der der Argumente <expr_1>, …, <expr_n> aber dessen Operanden das
     Ergebnis der Anwendung des Operators <f> auf die Teilausdrücke des
     Ausdrucks sind.  <f> ist entweder der Name einer Funktion mit n
     Argumenten oder ein Lambda-Ausdruck mit n Argumenten.

     Hat ‘maperror’ den Wert ‘false’, wird die Anwendung der Funktion
     <f> gestoppt, (1) wenn die Anwendung auf den kürzesten Ausdruck
     <expr_i> beendet ist und die Ausdrücke nicht alle dieselbe Länge
     haben oder (2) wenn die Ausdrücke <expr_i> einen verschiedenen Typ
     haben.  Hat ‘maperror’ den Wert ‘true’ wird in den obigen Fällen
     eine Fehlermeldung ausgegeben.

     Beispiele:

          (%i1) map(f,x+a*y+b*z);
          (%o1)                        f(b z) + f(a y) + f(x)
          (%i2) map(lambda([u],partfrac(u,x)),x+1/(x^3+4*x^2+5*x+2));
                                     1       1        1
          (%o2)                     ----- - ----- + -------- + x
                                   x + 2   x + 1          2
                                                   (x + 1)
          (%i3) map(ratsimp, x/(x^2+x)+(y^2+y)/y);
                                                1
          (%o3)                            y + ----- + 1
                                              x + 1
          (%i4) map("=",[a,b],[-0.5,3]);
          (%o4)                          [a = - 0.5, b = 3]


 -- Funktion: mapatom (<expr>)

     Gibt den Wert ‘true’ zurück, wenn der Ausdruck <expr> von
     Funktionen die auf Argumente angewendete werden, als ein Atom
     betrachtet wird.  Als Atome werden Zahlen, einschließlich
     rationaler Zahlen und großer Gleitkommazahlen, Symbole und
     indizierte Symbole betrachtet.

 -- Optionsvariable: maperror
     Standardwert: ‘true’

     Hat ‘maperror’ den Wert ‘false’, wird die Anwendung der Funktion
     <f> gestoppt, (1) wenn die Anwendung auf den kürzesten Ausdruck
     <expr_i> beendet ist und die Ausdrücke nicht alle dieselbe Länge
     haben oder (2) wenn die Ausdrücke <expr_i> einen verschiedenen Typ
     haben.  Hat ‘maperror’ den Wert ‘true’ wird in den obigen Fällen
     eine Fehlermeldung ausgegeben.

 -- Optionsvariable: mapprint
     Standardwert: ‘true’

     Hat ‘mapprint’ den Wert ‘true’, werden verschiedene Informationen
     von den Funktionen ‘map’, ‘maplist’ und ‘fullmap’ ausgegeben.  Dies
     ist der Fall, wenn die Funktion ‘map’ die Funktion ‘apply’ aufruft
     oder wenn für die Funktion ‘map’ die Argumente eine verschiedene
     Länge haben.

     Hat ‘mapprint’ den Wert ‘false’, werden diese Meldungen
     unterdrückt.

 -- Funktion: maplist (<f>, <expr_1>, …, <expr_n>)

     Wendet die Funktion <f> auf die Ausdrücke <expr_1>, …, <expr_n> an
     und gibt das Ergebnis als eine Liste zurück.  <f> ist der Name
     einer Funktion oder ein lambda-Ausdruck.

     Im Unterschied zu ‘maplist’ gibt die Funktion ‘map’ einen Ausdruck
     zurück, der denselben Hauptoperator wie die Ausdrücke <expr_i> hat.

 -- Funktion: outermap (<f>, <a_1>, …, <a_n>)

     Wendet die Funktion <f> auf jedes Element des äußeren Produktes der
     Argumente <a_1> ‘x’ <a_2> ‘x’ … ‘x’ <a_n> an.

     <f> ist der Name einer Funktion mit n Argumenten oder ein
     Lambda-Ausdruck mit n Argumenten.  Jedes Argument <a_k> kann eine
     Liste oder verschachtelte Liste, eine Matrix oder irgendein anderer
     Ausdruck sein.

     ‘outermap’ wertet die Argumente aus.

     Siehe auch ‘map’, ‘maplist’ und ‘apply’.

     Beispiele:

     Einfaches Beispiel für ‘outermap’.  Die Funktion ‘F’ ist
     undefiniert.

          (%i1) outermap(F, [a, b, c], [1, 2, 3]);
          (%o1) [[F(a, 1), F(a, 2), F(a, 3)], [F(b, 1), F(b, 2), F(b, 3)],
                                               [F(c, 1), F(c, 2), F(c, 3)]]
          (%i2) outermap(F, matrix([a, b],[c, d]), matrix([1, 2],[3, 4]));
                   [ [ F(a, 1)  F(a, 2) ]  [ F(b, 1)  F(b, 2) ] ]
                   [ [                  ]  [                  ] ]
                   [ [ F(a, 3)  F(a, 4) ]  [ F(b, 3)  F(b, 4) ] ]
          (%o2)    [                                            ]
                   [ [ F(c, 1)  F(c, 2) ]  [ F(d, 1)  F(d, 2) ] ]
                   [ [                  ]  [                  ] ]
                   [ [ F(c, 3)  F(c, 4) ]  [ F(d, 3)  F(d, 4) ] ]
          (%i3) outermap (F, [a, b], x, matrix ([1, 2], [3, 4]));
                 [ F(a, x, 1)  F(a, x, 2) ]  [ F(b, x, 1)  F(b, x, 2) ]
          (%o3) [[                        ], [                        ]]
                 [ F(a, x, 3)  F(a, x, 4) ]  [ F(b, x, 3)  F(b, x, 4) ]
          (%i4) outermap (F, [a, b], matrix ([1, 2]), matrix ([x], [y]));
                 [ [ F(a, 1, x) ]  [ F(a, 2, x) ] ]
          (%o4) [[ [            ]  [            ] ],
                 [ [ F(a, 1, y) ]  [ F(a, 2, y) ] ]
                                        [ [ F(b, 1, x) ]  [ F(b, 2, x) ] ]
                                        [ [            ]  [            ] ]]
                                        [ [ F(b, 1, y) ]  [ F(b, 2, y) ] ]
          (%i5) outermap ("+", [a, b, c], [1, 2, 3]);
          (%o5) [[a + 1, a + 2, a + 3], [b + 1, b + 2, b + 3],
                                                     [c + 1, c + 2, c + 3]]

     Das Beispiel zeigt die Rückgabe der Funktion ‘outermap’
     detaillierter.  Das erste, zweite und dritte Argument sind eine
     Matrix, eine Liste und eine Matrix.  Der Rückgabewert ist eine
     Matrix.  Jedes Element der Matrix ist eine Liste und jedes Element
     der Liste ist eine Matrix.

          (%i1) arg_1 :  matrix ([a, b], [c, d]);
                                      [ a  b ]
          (%o1)                       [      ]
                                      [ c  d ]
          (%i2) arg_2 : [11, 22];
          (%o2)                       [11, 22]
          (%i3) arg_3 : matrix ([xx, yy]);
          (%o3)                      [ xx  yy ]
          (%i4) xx_0 : outermap(lambda([x, y, z], x / y + z), arg_1,
                                                             arg_2, arg_3);
                         [  [      a        a  ]  [      a        a  ]  ]
                         [ [[ xx + --  yy + -- ], [ xx + --  yy + -- ]] ]
                         [  [      11       11 ]  [      22       22 ]  ]
          (%o4)  Col 1 = [                                              ]
                         [  [      c        c  ]  [      c        c  ]  ]
                         [ [[ xx + --  yy + -- ], [ xx + --  yy + -- ]] ]
                         [  [      11       11 ]  [      22       22 ]  ]
                           [  [      b        b  ]  [      b        b  ]  ]
                           [ [[ xx + --  yy + -- ], [ xx + --  yy + -- ]] ]
                           [  [      11       11 ]  [      22       22 ]  ]
                   Col 2 = [                                              ]
                           [  [      d        d  ]  [      d        d  ]  ]
                           [ [[ xx + --  yy + -- ], [ xx + --  yy + -- ]] ]
                           [  [      11       11 ]  [      22       22 ]  ]
          (%i5) xx_1 : xx_0 [1][1];
                     [      a        a  ]  [      a        a  ]
          (%o5)     [[ xx + --  yy + -- ], [ xx + --  yy + -- ]]
                     [      11       11 ]  [      22       22 ]
          (%i6) xx_2 : xx_0 [1][1] [1];
                                [      a        a  ]
          (%o6)                 [ xx + --  yy + -- ]
                                [      11       11 ]
          (%i7) xx_3 : xx_0 [1][1] [1] [1][1];
                                            a
          (%o7)                        xx + --
                                            11
          (%i8) [op (arg_1), op (arg_2), op (arg_3)];
          (%o8)                  [matrix, [, matrix]
          (%i9) [op (xx_0), op (xx_1), op (xx_2)];
          (%o9)                  [matrix, [, matrix]

     ‘outermap’ erhält die Struktur der Argumente im Ergebnis.  Die
     Funktion ‘cartesian_product’ erhält die Struktur der Argumente
     nicht.

          (%i1) outermap (F, [a, b, c], [1, 2, 3]);
          (%o1) [[F(a, 1), F(a, 2), F(a, 3)], [F(b, 1), F(b, 2), F(b, 3)],
                                               [F(c, 1), F(c, 2), F(c, 3)]]
          (%i2) setify (flatten (%));
          (%o2) {F(a, 1), F(a, 2), F(a, 3), F(b, 1), F(b, 2), F(b, 3),
                                                 F(c, 1), F(c, 2), F(c, 3)}
          (%i3) map(lambda([L], apply(F, L)),
                               cartesian_product({a, b, c}, {1, 2, 3}));
          (%o3) {F(a, 1), F(a, 2), F(a, 3), F(b, 1), F(b, 2), F(b, 3),
                                                 F(c, 1), F(c, 2), F(c, 3)}
          (%i4) is (equal (%, %th (2)));
          (%o4)                         true

 -- Funktion: remfunction (<f_1>, …, <f_n>)
 -- Funktion: remfunction (all)

     Hebt die Bindung der Symbole <f_1>, …, <f_n> an ihre
     Funktionsdefinitionen auf.  Die Argumente können die Namen von
     Funktionen sein, die mit dem Operator ‘:=’ oder der Funktion
     ‘define’ definiert wurden sowie Makro-Funktionen, die mit dem
     Operator ‘::=’ definiert wurden.

     ‘remfunction(all)’ entfernt alle Bindungen von
     Funktionsdefinitionen.

     ‘remfunction’ gibt eine Liste mit den Symbolen zurück, die von
     ihren Funktionsdefinitionen entbunden wurden.  ‘false’ wird für die
     Symbole zurückgegeben, für die es keine Funktionsdefinition gibt.

     ‘remfunction’ wertet die Argumente nicht aus.

     ‘remfunction’ kann nicht auf Array-Funktionen und indizierte
     Funktionen angewendet werden.  Für diese Funktionen kann ‘remarray’
     verwendet werden.

 -- Funktion: scanmap (<f>, <expr>)
 -- Funktion: scanmap (<f>, <expr>, bottomup)

     Wendet die Funktion <f> rekursiv auf alle Teilausdrücke in <expr>
     an.  Dies kann zum Beispiel verwendet werden, um einen Ausdruck
     vollständig zu faktorisieren.

     Beispiele:

          (%i1) exp:(a^2+2*a+1)*y + x^2$
          (%i2) scanmap(factor,exp);
                                              2      2
          (%o2)                         (a + 1)  y + x

          (%i3) scanmap(factor,expand(exp));
                                     2                  2
          (%o3)                      a  y + 2 a y + y + x

     Ein weiteres Beispiel für die Anwendung einer Funktion auf alle
     Teilausdrücke.

          (%i4) expr : u*v^(a*x+b) + c$
          (%i5) scanmap('f, expr);
                              f(f(f(a) f(x)) + f(b))
          (%o5) f(f(f(u) f(f(v)                      )) + f(c))

     ‘scanmap (<f>, <expr>, bottomup)’ wendet die Funktion <f> Bottom-up
     auf den Ausdruck <expr> an.

          scanmap(f,a*x+b) ->
             f(a*x+b) -> f(f(a*x)+f(b)) -> f(f(f(a)*f(x))+f(b))
          scanmap(f,a*x+b,bottomup) -> f(a)*f(x)+f(b)
              -> f(f(a)*f(x))+f(b) ->
               f(f(f(a)*f(x))+f(b))

