@c -----------------------------------------------------------------------------
@c File        : Number.de.texi
@c License     : GNU General Public License (GPL)
@c Language    : German
@c Original    : Number.texi revision 1.35
@c Translation : Dr. Dieter Kaiser
@c Date        : 06.01.2011
@c Revision    : 26.02.2011
@c 
@c This file is part of Maxima -- GPL CAS based on DOE-MACSYMA
@c -----------------------------------------------------------------------------

@menu
* Funktionen und Variablen der Zahlentheorie::
@end menu

@c -----------------------------------------------------------------------------
@node Funktionen und Variablen der Zahlentheorie, , Zahlentheorie, Zahlentheorie
@section Funktionen und Variablen der Zahlentheorie

@c --- 23.11.2010 DK -----------------------------------------------------------
@anchor{bern}
@deffn {Funktion} bern (@var{n})

@c Returns the @var{n}'th Bernoulli number for integer @var{n}.
@c WELL, ACTUALLY bern SIMPLIFIES, LIKE FACTORIAL -- DO WE WANT TO GET INTO THAT
@c OR JUST PRETEND IT'S "RETURNED" ???
@c Bernoulli numbers equal to zero are suppressed if @code{zerobern} is 
@c @code{false}.

Gibt die @var{n}-te Bernoulli-Zahl der ganzen Zahl @var{n} zur@"uck. Hat die
Optionsvariable @code{zerobern} den Wert @code{false}, werden Bernoulli-Zahlen
unterdr@"uckt, die Null sind.

Siehe auch @mrefdot{burn}

@example
(%i1) zerobern: true$
@group
(%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
@end group
(%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
@end example
@end deffn

@c --- 23.11.2010 DK -----------------------------------------------------------
@anchor{bernpoly}
@deffn {Funktion} bernpoly (@var{x}, @var{n})

@c Returns the @var{n}'th Bernoulli polynomial in the variable @var{x}.

Gibt das @var{n}-te Bernoulli-Polynom in der Variablen @var{x} zur@"uck.
@end deffn

@c TODO: DIE FUNKTION ZETA KANN INZWISCHEN IN BELIEBIGER GENAUIGKEIT RECHNEN.

@c --- 23.11.2010 DK -----------------------------------------------------------
@anchor{bfzeta}
@deffn {Function} bfzeta (@var{s}, @var{n})

@c Returns the Riemann zeta function for the argument @var{s}. The return value 
@c is a big float (bfloat); @var{n} is the number of digits in the return value.

Die Riemannsche Zeta-Funktion f@"ur das Argument @var{s}, die wie folgt 
definiert ist:

@tex
$$\zeta\left(s\right)=\sum_{k=1}^{\infty }{{{1}\over{k^{s}}}}$$
@end tex
@ifnottex
@example
                 inf
                 ====
                 \     1
     zeta(s) =    >    --
                 /      s
                 ====  k
                 k = 1
@end example
@end ifnottex

@code{bfzeta} gibt einen Wert als gro@ss{}e Gleitkommazahl zur@"uck.  Die Anzahl 
der Stellen wird durch das Argument @var{n} angegeben.

Anstatt der Funktion @code{bfzeta} ist die Funktion @mref{zeta} zu bevorzugen,
die sowohl f@"ur reelle und komplexe Gleitkommazahlen und Gleitkommazahlen mit
eine beliebigen Genauigkeit die Riemannsche Zeta-Funktion berechnen kann.
@end deffn

@c --- 23.11.2010 DK -----------------------------------------------------------
@anchor{bfhzeta}
@deffn {Funktion} bfhzeta (@var{s}, @var{h}, @var{n})

@c Returns the Hurwitz zeta function for the arguments @var{s} and @var{h}.
@c The return value is a big float (bfloat); @var{n} is the number of digits in 
@c the return value.

@c The Hurwitz zeta function is defined as

Die Hurwitzsche Zeta-Funktion f@"ur die Argumente @var{s} und @var{h}, die wie
folgt definiert ist:

@tex
$$\zeta \left(s,h\right) = \sum_{k=0}^\infty {1 \over \left(k+h\right)^{s}}$$
@end tex
@ifnottex
@example
                        inf
                        ====
                        \        1
         zeta (s,h)  =   >    --------
                        /            s
                        ====  (k + h)
                        k = 0
@end example
@end ifnottex

@code{bfhzeta} gibt einen Wert als gro@ss{}e Gleitkommazahl zur@"uck.  Die 
Anzahl der Stellen wird durch das Argument @var{n} angegeben.

@c @code{load ("bffac")} loads this function.
@end deffn

@c --- 27.11.2010 DK -----------------------------------------------------------
@anchor{burn}
@deffn {Funktion} burn (@var{n})

@c Returns a rational number, which is an approximation of the @var{n}'th 
@c Bernoulli number for integer @var{n}. @code{burn} exploits the observation 
@c that (rational) Bernoulli numbers can be approximated by (transcendental) 
@c zetas with tolerable efficiency:

Gibt eine rational Zahl zur@"uck, die eine N@"aherung f@"ur die @var{n}-te 
Bernoulli Zahl f@"ur die ganze Zahl @var{n} ist.  @code{burn} berechnet eine 
N@"aherung als gro@ss{}e Gleitkommatzahl mit der folgenden Beziehung:

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

@c @code{burn} may be more efficient than @code{bern} for large, isolated 
@c @var{n} as @code{bern} computes all the Bernoulli numbers up to index @var{n}
@c before returning. @code{burn} invokes the approximation for even integers 
@c @var{n} > 255. For odd integers and @var{n} <= 255 the function @code{bern} 
@c is called.

@code{burn} kann effizienter als die Funktion @code{bern} f@"ur gro@ss{}e, 
einzelne ganze Zahlen @var{n} sein, da @code{bern} zun@"achst alle Bernoulli 
Zahlen bis @var{n} berechnet.  @code{burn} ruft f@"ur ungerade ganze Zahlen und 
Zahlen die kleiner oder gleich 255 die Funktion @code{bern} auf.

@c @code{load ("bffac")} loads this function. See also @code{bern}.

Das Kommando @code{load("bffac")} l@"adt die Funktion.  Siehe auch @mrefdot{bern}
@end deffn

@c --- 27.03.2012 VN -----------------------------------------------------------
@anchor{chinese}
@deffn {Funktion} chinese ([@var{r_1}, @dots{}, @var{r_n}], [@var{m_1}, @dots{}, @var{m_n}])

L@"ost die simultanen Kongruenzen @code{x = r_1 mod m_1}, @dots{}, @code{x = r_n mod m_n}.
Die Reste @var{r_n} und die Moduli @var{m_n} m@"ussen ganze Zahlen sein, 
die Moduli zus@"atzlich positiv und paarweise teilerfremd.

@example
(%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
@end example
@end deffn

@c --- 23.11.2010 DK -----------------------------------------------------------
@anchor{divsum}
@deffn  {Funktion} divsum (@var{n}, @var{k})
@deffnx {Funktion} divsum (@var{n})

@c @code{divsum (@var{n}, @var{k})} returns the sum of the divisors of @var{n}
@c raised to the @var{k}'th power.

@code{divsum(@var{n}, @var{k})} potenziert die Teiler des Argumentes @var{n} 
mit dem Argument @var{k} und gibt die Summe als Ergebnis zur@"uck.

@c @code{divsum (@var{n})} returns the sum of the divisors of @var{n}.

@code{divsum(@var{n})} gibt die Summe der Teiler der Zahl @var{n} zur@"uck.

@example
(%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
@end example
@end deffn

@c --- 27.11.2010 DK -----------------------------------------------------------
@anchor{euler}
@deffn {Funktion} euler (@var{n})

@c Returns the @var{n}'th Euler number for nonnegative integer @var{n}.

Gibt die @var{n}-te Eulersche Zahl f@"ur eine nichtnegative ganze Zahl @var{n}
zur@"uck.

@c For the Euler-Mascheroni constant, see @code{%gamma}.

F@"ur die Euler-Mascheroni Konstante siehe @mrefdot{%gamma}

Beispiele:

@example
(%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]
@end example
@end deffn

@c --- 27.07.2013 VvN ----------------------------------------------------------
@anchor{factors_only}
@defvr {Optionsvariable} factors_only
Standardwert: @code{false}

Hat @code{factors_only} den Standardwert @code{false}, werden von der 
Funktion @mref{ifactors} zusammen mit den berechneten Primfaktoren auch deren 
Multiplizit@"aten angegeben. Hat @code{factors_only} den Wert @code{true}, 
werden nur die Primfaktoren zur@"uck gegeben.

Beispiel: Siehe @mref{ifactors}.
@end defvr

@c --- 27.07.2013 VvN ----------------------------------------------------------
@anchor{fib}
@deffn {Funktion} fib (@var{n})

Gibt die @var{n}-te Fibonacci-Zahl zur@"uck.  Die Fibonacci-Folge ist rekursiv 
definiert:

@example
   fib(0) = 0
   fib(1) = 1
   fib(n) = fib(n-1) + fib(n-2)
@end example

F@"ur negative ganze Zahlen kann die Fibonacci-Folge wie folgt erweitert werden:

@example
                   n + 1
   fib(- n) = (- 1)      fib(n)
@end example 

@c After calling @code{fib}, @code{prevfib} is equal to @code{fib(@var{x} - 1)},
@c the Fibonacci number preceding the last one computed.

@c TODO: PREVFIB HAT KEINEN EINTRAG.

Nach einem Aufruf der Funktion @code{fib(n)}, enth@"alt die Systemvariable 
@code{prevfib} die zur Zahl @code{n} vorhergehende Fibonacci-Zahl.

@example
(%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]
@end example
@end deffn

@c --- 23.11.2010 DK -----------------------------------------------------------
@anchor{fibtophi}
@deffn {Funktion} fibtophi (@var{expr})

@c Expresses Fibonacci numbers in @var{expr} in terms of the constant 
@c @code{%phi}, which is @code{(1 + sqrt(5))/2}, approximately 1.61803399.

Fibonacci-Zahlen im Ausdruck @var{expr} werden durch die Goldene Zahl 
@code{%phi} ausgedr@"uckt.  Siehe @mrefdot{%phi}

Beispiele:

@example
(%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
@end example
@end deffn

@c --- 23.03.2013 VN -----------------------------------------------------------
@anchor{ifactors}
@deffn {Funktion} ifactors (@var{n})

Faktorisiert eine positive ganze Zahl @var{n}.  Sind @code{n = p1^e1 * ... * pk^nk} die
Faktoren der ganzen Zahl @var{n}, dann gibt @code{ifactor} das Ergebnis
@code{[[p1, e1], ..., [pk, ek]]} zur@"uck.

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

Die R@"uckgabe von ifactors wird von der Optionsvariablen @mref{factors_only}  
beeinflusst. 
Werden lediglich die Primfaktoren ohne ihre Multiplizit@"at ben@"otigt, 
gen@"ugt es hierf@"ur, @code{factors_only : true} zu setzen.

@example
(%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]
@end example
@end deffn

@c --- 23.03.2013 VN -----------------------------------------------------------
@anchor{igcdex}
@deffn {Funktion} igcdex (@var{n}, @var{k})

@c Gibt die Liste @code{[@var{a}, @var{b}, @var{u}]} zur@"uck, in der @var{u} der 
Gibt die Liste @code{[a, b, u]} zur@"uck, in der @code{u} der 
gr@"o@ss{}te gemeinsame Teiler von @var{n} und @var{k} ist und in der zus@"atzlich 
@c gilt, dass @code{@var{u} = @var{a} * @var{n} + @var{b} * @var{k}}. 
gilt, dass @code{u = a * @var{n} + b * @var{k}}. 

@code{igcdex} verwendet den Euklidischen Algorithmus.  Siehe auch @mref{gcdex}.

Die Eingabe @code{load("gcdex")} l@"adt diese Funktion.

Beispiele:

@example
(%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]
@end example
@end deffn

@c --- 23.11.2010 DK -----------------------------------------------------------
@anchor{inrt}
@deffn {Funktion} inrt (@var{x}, @var{n})

@c Returns the integer @var{n}'th root of the absolute value of @var{x}.

Gibt die ganzzahlige @var{n}-te Wurzel des Betrags von @var{x} zur@"uck.

@example
(%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]
@end example
@end deffn

@c --- 27.03.2012 VN -----------------------------------------------------------
@anchor{inv_mod}
@deffn {Funktion} inv_mod (@var{n}, @var{m})

Berechnet das modulare Inverse von @var{n} zum Modul @var{m}.  Das Argument
@var{n} muss eine ganze Zahl und der Modul @var{p} eine positive ganze Zahl 
sein.  @code{inv_mod(n, m)} gibt @code{false} zur@"uck, wenn das modulare Inverse
nicht existiert.  Das modulare Inverse existiert, wenn @var{n} teilerfremd zum 
Modul @var{m} ist.

Siehe auch die Funktionen @mref{power_mod} und @mrefdot{mod}

Beispiele:

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

@c --- 20.10.2010 DK -----------------------------------------------------------
@anchor{isqrt}
@deffn {Funktion} isqrt (@var{x})

@c Returns the "integer square root" of the absolute value of @var{x}, which is 
@c an integer.

Gibt die ganzzahlige Wurzel des Betrages von @var{x} zur@"uck, wenn @var{x} eine
ganze Zahl ist.  Andernfalls wird eine Substantivform zur@"uckgegeben.
@end deffn

@c --- 27.11.2010 DK -----------------------------------------------------------
@anchor{jacobi}
@deffn {Funktion} jacobi (@var{p}, @var{q})

@c Returns the Jacobi symbol of @var{p} and @var{q}.

Berechnet das Jacobi-Symbol f@"ur die Argumente @var{p} und @var{q}.

@example
(%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]
@end example
@end deffn

@c --- 27.03.2012 VN -----------------------------------------------------------
@anchor{lcm}
@deffn {Funktion} lcm (@var{expr_1}, @dots{}, @var{expr_n})

@c Returns the least common multiple of its arguments. The arguments may be 
@c general expressions as well as integers.

Gibt das kleinste gemeinsame Vielfache der Argumente zur@"uck.  Die Argumente 
k@"onnen ganze Zahlen und allgemeine Ausdr@"ucke sein.

@c @code{load ("functs")} loads this function.

Mit dem Kommando @code{load("functs")} wird die Funktion geladen.
@end deffn

@c --- 27.07.2013 VvN ----------------------------------------------------------
@anchor{lucas}
@deffn {Funktion} lucas (@var{n})

Gibt die @var{n}-te Lucas-Zahl zur@"uck.  Die Lucas-Folge ist rekursiv 
definiert:

@example
   lucas(0) = 0
   lucas(1) = 1
   lucas(n) = lucas(n-1) + lucas(n-2)
@end example

F@"ur negative ganze Zahlen kann die Lucas-Folge wie folgt erweitert werden:

@example
                     -n
   lucas(- n) = (- 1)   lucas(n)
@end example 

@example
(%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]
@end example

Nach einem Aufruf von @code{lucas} enth@"alt die globale Variable 
@code{next_lucas} den Nachfolger der zuletzt zur@"ck gegebenen Lucas-Zahl.
Das Beispiel zeigt, wie Fibonacci-Zahlen mit Hilfe von @code{lucas} 
und @code{next_lucas} berechnet werden k@"onnen.

@example
(%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]
@end example
@end deffn

@c --- 23.03.2013 VN -----------------------------------------------------------
@anchor{mod}
@deffn {Funktion} mod (@var{x}, @var{p})

@c If @var{x} and @var{y} are real numbers and @var{y} is nonzero, return 
@c @code{@var{x} - @var{y} * floor(@var{x} / @var{y})}. Further for all real 
@c @var{x}, we have @code{mod (@var{x}, 0) = @var{x}}. For a discussion of the 
@c definition @code{mod (@var{x}, 0) = @var{x}}, see Section 3.4, of 
@c "Concrete Mathematics," by Graham, Knuth, and Patashnik. The function 
@c @code{mod (@var{x}, 1)} is a sawtooth function with period 1 with 
@c @code{mod (1, 1) = 0} and @code{mod (0, 1) = 0}.

Berechnet den Divisionsrest @code{x mod y} des Arguments @var{x} zum Modul @var{y}. 
@var{x} und @var{y} k@"onnen ganze Zahlen, rationale Zahlen, Gleitkommazahlen 
oder allgemeine Ausdr@"ucke sein.

Sind @var{x} und @var{y} reelle Zahlen und ist @var{y} ungleich Null, gibt 
@code{mod(@var{x}, @var{y})} das Ergebnis von @code{@var{x} - @var{y} * 
floor(@var{x} / @var{y})} zur@"uck.  Weiterhin gilt f@"ur alle reellen Zahlen
@code{mod(@var{x}, 0) = @var{x}}.  F@"ur eine Diskussion dieser Definition siehe
Kapitel 3.4, "Concrete Mathematics" von Graham, Knuth, and Patashnik.  Die 
Funktion @code{mod(@var{x}, 1)} ist eine S@"agezahnfunktion mit der Periode 1 
mit @code{mod(1, 1) = 0} und @code{mod(0, 1) = 0}.

@c To find the principal argument (a number in the interval @code{(-%pi, %pi]}) 
@c of a complex number, use the function @code{@var{x} |-> %pi - mod (%pi - 
@c @var{x}, 2*%pi)}, where @var{x} is an argument.

Der Hauptwert einer komplexen Zahl, die im Intervall @code{(-%pi, %pi)} liegt,
kann mit @code{%pi - mod(%pi - @var{x}, 2*%pi)} bestimmt werden, wobei @var{x}
die komplexe Zahl ist.

@c When @var{x} and @var{y} are constant expressions (@code{10 * %pi}, for 
@c example), @code{mod} uses the same big float evaluation scheme that 
@c @code{floor} and @code{ceiling} uses. Again, it's possible, although 
@c unlikely, that @code{mod} could return an erroneous value in such cases.

Sind @var{x} und @var{y} konstante Ausdr@"ucke, wie zum Beispiel @code{10 * %pi},
verwendet @code{mod} dasselbe @mref{bfloat}-Auswertungsschema wie @code{floor} 
und @code{ceiling}. Diese Umwandlung kann, wenn auch unwahrscheinlich, 
zu Fehlern f@"uhren.

@c For nonnumerical arguments @var{x} or @var{y}, @code{mod} knows several 
@c simplification rules:

F@"ur nicht numerische Argumente @var{x} oder @var{y} kennt @code{mod}
verschiedene Vereinfachungen.

Siehe auch die Funktionen @mref{power_mod} und @mrefdot{inv_mod}

Beispiele:

Zeige f@"ur zwei gro@ss{}e ganze Zahlen, dass f@"ur das modulare Rechnen die 
Regel @code{mod(a+b, m) = mod(mod(a, m) + mod(b, m), m)} gilt.

@example
(%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
@end example

Vereinfachung f@"ur nicht numerische Argumente.

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

@c --- 27.11.2010 DK -----------------------------------------------------------
@anchor{next_prime}
@deffn {Funktion} next_prime (@var{n})

@c Returns the smallest prime bigger than @var{n}.

Gibt die kleinste Primzahl zur@"uck, die der Zahl @var{n} folgt.

@example
(%i1) next_prime(27);
(%o1)                       29
@end example
@end deffn

@c --- 27.03.2012 VN -----------------------------------------------------------
@anchor{power_mod}
@deffn {Funktion} power_mod (@var{a}, @var{n}, @var{m})

Verwendet einen modularen Algorithmus, um @code{a^n mod m} zu berechnen. 
Die Argumente @var{a} und @var{n} m@"ussen ganze Zahlen und der Modul @var{m} 
eine positive ganze Zahl sein.  Ist @var{n} negativ, wird @mref{inv_mod} zur 
Berechnung des modularen Inversen aufgerufen.

@code{power_mod (@var{a}, @var{n}, @var{m})} ist @"aquivalent zu 
@code{mod(a^n, m)}.  Der Algorithmus von @code{power_mod} ist jedoch 
insbesondere f@"ur gro@ss{}e ganze Zahlen wesentlich effizienter.

Siehe auch die Funktionen @mref{inv_mod} und @mrefdot{mod}

Beispiele:

@code{power_mod(a, n, m)} ist @"aquivalent zu @code{mod(a^n, m}.  Das modulare
Inverse wird mit der Funktion @code{inv_mod} berechnet.

@example
(%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
@end example

F@"ur gro@ss{}e ganze Zahlen ist @code{power_mod} effizienter.  Der folgende 
Wert kann in keiner vern@"unftigen Zeit mit @code{mod(a^n, m)} berechnet
werden.

@example
(%i1) power_mod(123456789, 123456789, 987654321);
(%o1)                       598987215
@end example
@end deffn

@c --- 27.03.2012 VN -----------------------------------------------------------
@anchor{primep}
@deffn {Funktion} primep (@var{n})

F@"uhrt einen Primzahltest f@"ur das Argument @var{n} durch.  Liefert
@code{primep} das Ergebnis @code{false}, ist @var{n} keine Primzahl.  Ist das
Ergebnis @code{true}, ist @var{n} mit sehr gro@ss{}er Wahrscheinlichkeit eine 
Primzahl.

F@"ur ganze Zahlen @var{n} kleiner als 3317044064679887385961981 wird eine deterministische
Variante des Miller-Rabin-Tests angewandt.  Hat in diesem Fall @code{primep} den Wert
@code{true}, dann ist @var{n} mit Sicherheit eine Primzahl.

F@"ur ganze Zahlen @var{n} gr@"o@ss{}er 3317044064679887385961981 f@"uhrt @code{primep}
@mref{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 @var{n} einen Miller-Rabin-Test besteht, ist kleiner
als 1/4.  Mit dem Standardwert 25 @code{primpe_number_of_tests} sinkt diese 
Wahrscheinlichkeit damit unter einen Wert von 10^-15.
@end deffn

@c --- 23.03.2013 VN -----------------------------------------------------------
@anchor{primep_number_of_tests}
@defvr {Optionsvariable} primep_number_of_tests
Standardwert: 25

@c Number of Miller-Rabin's tests used in @code{primep}.

Die Anzahl der Pseudo-Primzahl-Tests nach Miller-Rabin in der Funktion 
@mref{primep}.
@end defvr

@c --- 13.06.2015 VN -----------------------------------------------------------
@anchor{primes}
@deffn {Funktion} primes (@var{start}, @var{end})

Gibt eine Liste mit allen Primzahlen von @var{start} bis @var{end} zur@"uck.

@example
(%i1) primes(3, 7);
(%o1)                     [3, 5, 7]
@end example
@end deffn

@c --- 27.11.2010 DK -----------------------------------------------------------
@anchor{prev_prime}
@deffn {Funktion} prev_prime (@var{n})

@c Returns the greatest prime smaller than @var{n}.

Gibt die gr@"o@ss{}te Primzahl zur@"uck, die kleiner als die Zahl @var{n} ist.

@example
(%i1) prev_prime(27);
(%o1)                       23
@end example
@end deffn

@c --- 27.11.2010 DK -----------------------------------------------------------
@anchor{qunit}
@deffn {Funktion} qunit (@var{n})

@c Returns the principal unit of the real quadratic number field 
@c @code{sqrt (@var{n})} where @var{n} is an integer, i.e., the element whose 
@c norm is unity. This amounts to solving Pell's equation 
@c @code{a^2 - @var{n} b^2 = 1}.

Findet f@"ur das Argument @var{n} L@"osungen der Pellschen Gleichung 
@code{a^2 - @var{n} b^2 = 1}.

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

@c --- 27.03.2012 VN -----------------------------------------------------------
@anchor{totient}
@deffn {Funktion} totient (@var{n})

Gibt die Anzahl der ganzen Zahlen zur@"uck, die kleiner oder gleich @var{n}
und teilerfremd zu @var{n} sind.
@end deffn

@c --- 27.03.2012 VN -----------------------------------------------------------
@anchor{zerobern}
@defvr {Optionsvariable} zerobern
Standardwert: @code{true}

@c When @code{zerobern} is @code{false}, @code{bern} excludes the Bernoulli 
@c numbers and @code{euler} excludes the Euler numbers which are equal to zero.
@c See @code{bern} and @code{euler}.

Hat @code{zerobern} den Wert @code{false}, werden von den Funktionen @code{bern}
diejenigen Bernoulli-Zahlen und von @code{euler} diejenigen Euler-Zahlen 
ausgeschlossen, die gleich Null sind.  Siehe @mref{bern} und @mrefdot{euler}
@end defvr

@c --- 23.03.2013 VN -----------------------------------------------------------
@anchor{zeta}
@deffn {Funktion} zeta (@var{n})

@c Returns the Riemann zeta function. If @var{n} is a negative integer, 0, or a 
@c positive even integer, the Riemann zeta function simplifies to an exact 
@c value. For a positive even integer the option variable @code{zeta%pi} has to 
@c be @code{true} in addition (See @code{zeta%pi}). For a floating point or 
@c bigfloat number the Riemann zeta function is evaluated numerically. Maxima 
@c returns a noun form @code{zeta (@var{n})} for all other arguments, including 
@c rational noninteger, and complex arguments, or for even integers, if 
@c @code{zeta%pi} has the value @code{false}.

Die Riemannsche Zeta-Funktion f@"ur @var{s}, die wie folgt definiert ist:

@tex
$$\zeta\left(s\right)=\sum_{k=1}^{\infty }{{{1}\over{k^{s}}}}$$
@end tex
@ifnottex
@example
                 inf
                 ====
                 \     1
     zeta(s) =    >    --
                 /      s
                 ====  k
                 k = 1
@end example
@end ifnottex

F@"ur negative ganze Zahlen @var{n}, Null und positive gerade ganze Zahlen 
wird @code{zeta} zu einem exakten Ergebnis vereinfacht.  
Damit diese Vereinfachung f@"ur positive ganze Zahlen ausgef@"uhrt wird, 
muss die Optionsvariable @code{zeta%pi} den Wert @code{true} haben.  
Siehe @mref{zeta%pi}. F@"ur einfache und beliebig genaue Gleitkommazahlen 
(Typ @code{bfloat}) hat @code{zeta} ein numerisches Ergebnis.  
F@"ur alle anderen Argumente einschlie@ss{}lich der komplexen und 
rationalen Zahlen gibt @code{zeta} eine Substantivform zur@"uck.  Hat die 
Optionsvariable @code{zeta%pi} den Wert @code{false}, gibt @code{zeta} auch 
f@"ur gerade ganze Zahlen eine Substantivform zur@"uck.

@c @code{zeta(1)} is undefined, but Maxima knows the limit 
@c @code{limit(zeta(x), x, 1)} from above and below.

@code{zeta(1)} ist nicht definiert.  Maxima kennt jedoch die einseitigen
Grenzwerte @code{limit(zeta(x), x, 1, plus} und 
@code{limit(zeta(x), x, 1, minus}.

@c The Riemann zeta function distributes over lists, matrices, and equations.

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

@c See also @code{bfzeta} and @code{zeta%pi}.

Siehe auch @mref{bfzeta} und @mrefdot{zeta%pi}

Beispiele:

@example
(%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
@end example
@end deffn

@c --- 27.11.2010 DK -----------------------------------------------------------
@anchor{zeta%pi}
@defvr {Optionsvariable} zeta%pi
Standardwert: @code{true}

@c When @code{zeta%pi} is @code{true}, @code{zeta} returns an expression 
@c proportional to @code{%pi^n} for even integer @code{n}. Otherwise, 
@c @code{zeta} returns a noun form @code{zeta (n)} for even integer @code{n}.

Hat @code{zeta%pi} den Wert @code{true}, vereinfacht die Funktion @code{zeta(n)}
f@"ur gerade ganzen Zahlen @var{n} zu einem Ergebnis, das proportional zu 
@code{%pi^n} ist.  Ansonsten ist das Ergebnis von @code{zeta} eine 
Substantivform f@"ur gerade ganze Zahlen.

Beispiele:

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

@c --- 27.07.2013 VvN ----------------------------------------------------------
@anchor{zn_add_table}
@deffn {Funktion} zn_add_table (@var{n}) 

zeigt eine Additionstabelle von allen Elementen in (Z/@var{n}Z).

Siehe auch @mref{zn_mult_table}, @mref{zn_power_table}.
@end deffn

@c -----------------------------------------------------------------------------
@anchor{zn_characteristic_factors}
@deffn {Funktion} zn_characteristic_factors (@var{n}) 

Gibt eine Liste mit den charakteristischen Faktoren des Totienten von @var{n} zur@"uck.

Mit Hilfe der charakteristischen Faktoren kann eine modulo @var{n} multiplikative Gruppe 
als direktes Produkt zyklischer Untergruppen dargestellt werden. 

Ist die Gruppe selbst zyklisch, dann enth@"alt die Liste nur den Totienten 
und mit @code{zn_primroot} kann ein Generator berechnet werden. 
Zerf@"allt der Totient in mehrere charakteristische Faktoren, 
k@"onnen Generatoren der entsprechenden Untergruppen mit @code{zn_factor_generators} 
ermittelt werden.

Jeder der @code{r} Faktoren in der Liste teilt die weiter rechts stehenden Faktoren. 
Fuer den letzten Faktor @code{f_r} gilt daher @code{a^f_r = 1 (mod n)} 
f@"ur alle @code{a} teilerfremd zu @var{n}. 
Dieser Faktor ist auch als Carmichael Funktion bzw. Carmichael Lambda bekannt.

F@"ur @code{n > 2} ist @code{totient(n)/2^r} die Anzahl der quadratischen Reste 
in der Gruppe und jeder dieser Reste hat @code{2^r} Wurzeln.

Siehe auch @mref{totient}, @mref{zn_primroot}, @mref{zn_factor_generators}.

Beispiele:

Die multiplikative Gruppe modulo @code{14} ist zyklisch und ihre @code{6} Elemente 
lassen sich durch eine Primitivwurzel erzeugen.

@example
(%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]
@end example

Die multiplikative Gruppe modulo @code{15} ist nicht zyklisch und ihre @code{8} Elemente 
lassen sich mit Hilfe zweier Faktorgeneratoren erzeugen.

@example
(%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]
@end example

F@"ur den letzten charakteristischen Faktor @code{4} gilt 
@code{a^4 = 1 (mod 15)} fuer alle @code{a} in @code{M15}. 

@code{M15} hat @code{2} charakteristische Faktoren und daher die @code{8/2^2} 
quadratischen Reste @code{1} und @code{4}, und diese haben jeweils @code{2^2} Wurzeln.

@example
(%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]]
@end example
@end deffn

@c -----------------------------------------------------------------------------
@anchor{zn_carmichael_lambda}
@deffn {Funktion} zn_carmichael_lambda (@var{n}) 

Gibt @code{1} zur@"uck, wenn @var{n} gleich @code{1} ist und andernfalls 
den gr@"o@ss{}ten charakteristischen Faktor des Totienten von @var{n}. 

F@"ur Erl@"auterungen und Beispiele siehe @mref{zn_characteristic_factors}.

@end deffn

@c --- 27.07.2013 VvN ----------------------------------------------------------
@anchor{zn_determinant}
@deffn {Funktion} zn_determinant (@var{matrix}, @var{p}) 

verwendet die Technik der LR-Dekomposition, um die Determinante der 
Matrix @var{matrix} @"uber (Z/@var{p}Z) zu berechnen, wobei @var{p} 
eine Primzahl sein muss. 

Ist die Determinante nicht von Null verschieden, kann es sein, dass die 
LR-Dekomposition nicht m@"oglich ist. @code{zn_determinant} berechnet 
diesem Fall die Determinante nicht-modular und reduziert im Nachhinein.

Siehe auch @mref{zn_invert_by_lu}.

Beispiel:

@example
(%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
@end example
@end deffn

@c -----------------------------------------------------------------------------
@anchor{zn_factor_generators}
@deffn {Funktion} zn_factor_generators (@var{n}) 

Gibt eine Liste mit Faktorgeneratoren zur@"uck, die zu den charakteristischen 
Faktoren des Totienten von @var{n} passen. 

F@"ur Erl@"auterungen und Beispiele siehe @mref{zn_characteristic_factors}.

@end deffn

@c --- 27.07.2013 VvN ----------------------------------------------------------
@anchor{zn_invert_by_lu}
@deffn {Funktion} zn_invert_by_lu (@var{matrix}, @var{p}) 

verwendet die Technik der LR-Dekomposition, um ein modulares Inverses der 
Matrix @var{matrix} @"uber (Z/@var{p}Z) zu berechnen. Voraussetzung ist, 
dass @var{matrix} invertierbar und @var{p} eine Primzahl ist. 
Sollte @var{matrix} nicht invertierbar sein, gibt @code{zn_invert_by_lu} 
@code{false} zur@"ck.

Siehe auch @mref{zn_determinant}.

Beispiele:

@example
(%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 ]
@end example
@end deffn

@c --- 03.01.2020 VN -----------------------------------------------------------
@anchor{zn_log}
@deffn {Funktion} zn_log (@var{a}, @var{g}, @var{n}) 
@deffnx {Funktion} zn_log (@var{a}, @var{g}, @var{n}, [[@var{p1}, @var{e1}], @dots{}, [@var{pk}, @var{ek}]])

Berechnet den diskreten Logarithmus.  Sei (Z/@var{n}Z)* eine zyklische Gruppe, 
@var{g} eine Primitivwurzel modulo @var{n} oder der Generator einer Untergruppe 
von (Z/@var{n}Z)* und @var{a} ein Element dieser Gruppe.
Dann berechnet @code{zn_log (a, g, n)} eine L@"osung der Kongruenz 
@code{g^x = a mod n}.  Man beachte, dass @code{zn_log} nicht terminiert, 
falls @var{a} keine Potenz von @var{g} modulo @var{n} ist.


Der verwendete Algorithmus ben@"otigt die Primfaktorzerlegung von @code{zn_order(g)} 
bzw. des Totienten von @var{n}. 
Da diese Berechnung ebenfalls zeitaufw@"andig ist, kann es eventuell sinnvoll 
sein, die Primfaktoren von @code{zn_order(g)} vorab zu berechnen und @code{zn_log} als 
viertes Argument zu @"ubergeben. Die Form muss dabei der R@"uckgabe von 
@code{ifactors(totient(n))} mit der Standardeinstellung @code{false} der 
Optionsvariable @code{factors_only} entsprechen. 
Verglichen mit der Laufzeit f@"ur 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@"ur den diskreten Logarithmus verwendet. Die Laufzeit von @code{zn_log} 
h@"angt im Wesentlichen von der Bitl@"ange des gr@"o@ss{}ten Primfaktors des 
Totienten von @var{n} ab. 

Siehe auch @mref{zn_primroot}, @mref{zn_order}, @mref{ifactors}, @mref{totient}.

Beispiele:

@code{zn_log (a, g, n)} findet eine L@"osung der Kongruenz @code{g^x = a mod n}.

@example
(%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
@end example

Das optionale vierte Argument muss der R@"uckgabe von @code{ifactors(totient(n))} 
entsprechen. 
Die Laufzeit h@"angt im Wesentlichen von der Bitl@"ange des gr@"o@ss{}ten
Primfaktors von @code{zn_order(g)} ab.

@example
(%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
@end example
@end deffn

@c -----------------------------------------------------------------------------
@anchor{zn_mult_table}
@deffn {Funktion} zn_mult_table (@var{n}) 
@deffnx {Funktion} zn_mult_table (@var{n}, @var{gcd})

Ohne das optionale Argument @var{gcd} zeigt @code{zn_mult_table(n)} 
eine Multiplikationstabelle von allen Elementen in (Z/@var{n}Z)*, 
d.h. von allen zu @var{n} teilerfremden Elementen.

Das optionale zweite Argument @var{gcd} erlaubt es, eine bestimmte Untermenge 
von (Z/@var{n}Z) auszuw@"ahlen. 
Ist @var{gcd} eine nat@"urliche Zahl, enth@"alt die Multiplikationstabelle 
alle Restklassen @code{x} mit @code{gcd(x,n) = }@var{gcd}. 
Zur besseren Lesbarkeit werden Zeilen- und Spaltenk@"opfe hinzugef@"ugt. 
Falls notwendig, lassen sich diese mit @code{submatrix(1, tabelle, 1)} 
wieder einfach entfernen. 

Wird @var{gcd} auf @code{all} gesetzt, wird die Tabelle f@"ur s@"amtliche 
von Null verschiedene Elemente in (Z/@var{n}Z) ausgegeben.

Das zweite Beispiel unten zeigt einen alternativen Weg, f@"ur Untergruppen 
eine Multiplikationstabelle zu erzeugen.

Siehe auch @mref{zn_add_table}, @mref{zn_power_table}.

Beispiele:

Die Standardtabelle zeigt alle Elemente aus (Z/@var{n}Z)* und erlaubt, 
grundlegende Eigenschaften von modularen Multiplikationsgruppen zu zeigen und 
zu studieren. Z.B. stehen in der Hauptdiagonale s@"amtliche quadratische Reste, 
jede Zeile und Spalte enth@"alt alle Elemente, die Tabelle ist symmetrisch, etc..

Wird @var{gcd} auf @code{all} gesetzt, wird die Tabelle f@"ur s@"amtliche 
von Null verschiedene Elemente in (Z/@var{n}Z) ausgegeben.

@example
(%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 ]
@end example

Ist @var{gcd} eine Zahl, wird zur besseren Lesbarkeit ein Zeilen- und Spaltenkopf 
hinzugef@"ugt.

Ist die mit @var{gcd} ausgew@"ahlte Teilmenge eine Gruppe, gibt es einen 
alternativen Weg, die Multiplikationstabelle zu erzeugen.
Die Isomorphie zu einer Gruppe mit @code{1} als Identit@"at l@"asst sich nutzen, 
um eine leicht lesbare Tabelle zu erhalten. Die Abbildung gelingt mit dem CRT.

In der so erzeugten zweiten Version der Tabelle @code{T36_4} steht genau wie 
bei @code{T9} die Identit@"at, hier @code{28}, in der linken oberen Ecke. 


@example
(%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 ]
@end example
@end deffn

@c -----------------------------------------------------------------------------
@anchor{zn_nth_root}
@deffn {Funktion} zn_nth_root (@var{x}, @var{n}, @var{m}) 
@deffnx {Funktion} zn_nth_root (@var{x}, @var{n}, @var{m}, [[@var{p1}, @var{e1}], @dots{}, [@var{pk}, @var{ek}]])

Gibt eine Liste mit allen @var{n}-ten Wurzeln von @var{x} aus der multiplikativen 
Untergruppe von (Z/@var{m}Z) zur@"uck, in der sich @var{x} befindet, 
oder @code{false}, falls @var{x} keine @var{n}-te Potenz modulo @var{m} oder 
kein Element einer multiplikativen Untergruppe von (Z/@var{m}Z) ist.

@var{x} ist Element einer multiplikativen Untergruppe modulo @var{m}, wenn der 
gr@"o@ss{}te gemeinsame Teiler @code{g = gcd(x,m)} zu @code{m/g} teilerfremd ist.

@code{zn_nth_root} basiert auf einem Algorithmus von Adleman, Manders und Miller 
und S@"atzen @"uber modulare Multiplikationsgruppen von Daniel Shanks.

Der Algorithmus ben@"otigt eine Primfaktorzerlegung des Modulus @var{m}. 
Es kann eventuell sinnvoll sein, diese Zerlegung vorab zu berechnen und 
als viertes Argument zu @"ubergeben. Die Form muss dabei der R@"uckgabe von 
@code{ifactors(m)} mit der Standardeinstellung @code{false} der 
Optionsvariable @code{factors_only} entsprechen. 

Beispiele:

Eine Potenztabelle der multiplikativen Gruppe modulo @code{14} 
gefolgt von einer Liste mit Listen von @var{n}-ten Wurzeln der @code{1}, 
wobei @var{n} von @code{1} bis @code{6} variiert.

@example
(%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]]
@end example

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

Die Restklasse @code{3} ist kein Element in irgend einer multiplikativen 
Untergruppe von (Z/63Z) und wird daher nicht als dritte Wurzel von @code{27} 
zur@"uck gegeben.

Hier zeigt @code{zn_power_table} alle Reste @code{x} in (Z/63Z) 
mit @code{gcd(x,63) = 9}. Diese Untergruppe ist isomorph zu (Z/7Z)* 
und seine Identit@"at @code{36} wird mit Hilfe des CRT berechnet.

@example
(%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
@end example

Im folgenden RSA-@"ahnlichen Beispiel, in dem der Modulus @code{N} quadratfrei ist, 
d.h. in paarweise verschiedene Primfaktoren zerf@"allt, 
ist jedes @code{x} von @code{0} bis @code{N-1}
in einer multiplikativen Untergruppe enthalten.

Zur Entschl@"usselung wird die @code{e}-te Wurzel berechnet. 
@code{e} ist teilerfremd zu @code{N} und die @code{e}-te Wurzel ist deshalb 
eindeutig. @code{zn_nth_root} wendet hier effektiv den als CRT-RSA 
bekannten Algorithmus an.
(Man beachte, dass @code{flatten} Klammern entfernt und keine L@"osungen.)

@example
(%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
@end example

Im folgenden Beispiel ist die Faktorisierung des Modulus bekannt und wird 
als viertes Argument @"ubergeben.

@example
(%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]
@end example
@end deffn

@c --- 29.03.2012 VN -----------------------------------------------------------
@anchor{zn_order}
@deffn {Funktion} zn_order (@var{x}, @var{n}) 
@deffnx {Funktion} zn_order (@var{x}, @var{n}, [[@var{p1}, @var{e1}], @dots{}, [@var{pk}, @var{ek}]])

Ist @var{x} eine Einheit in der endlichen Gruppe (Z/@var{n}Z)*, so berechnet 
@code{zn_order} die Ordnung dieses Elements.  Andernfalls gibt @code{zn_order} 
@code{false} zur@"uck.  @var{x} ist eine Einheit modulo @var{n}, falls @var{x} 
teilerfremd zu @var{n} ist.

Der verwendete Algorithmus ben@"otigt die Primfaktorzerlegung des Totienten von @var{n}. 
Da diese Berechnung manchmal recht zeitaufw@"andig ist, kann es eventuell sinnvoll 
sein, die Primfaktoren des Totienten vorab zu berechnen und @code{zn_order} als 
drittes Argument zu @"ubergeben. Die Form muss dabei der R@"uckgabe von 
@code{ifactors(totient(n))} mit der Standardeinstellung @code{false} der 
Optionsvariable @code{factors_only} entsprechen. 

Siehe auch @mref{zn_primroot}, @mref{ifactors}, @mref{totient}.

Beispiele:

@code{zn_order} berechnet die Ordnung einer Einheit @var{x} aus (Z/@var{n}Z)*.

@example
(%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
@end example

Das optionale dritte Argument muss der R@"uckgabe von @code{ifactors(totient(n))} 
entsprechen. 

@example
(%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]
@end example
@end deffn

@c -----------------------------------------------------------------------------
@anchor{zn_power_table}
@deffn {Funktion} zn_power_table (@var{n}) 
@deffnx {Funktion} zn_power_table (@var{n}, @var{gcd})
@deffnx {Funktion} zn_power_table (@var{n}, @var{gcd}, @var{max_exp})

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

Das optionale zweite Argument @var{gcd} erlaubt es, eine bestimmte Untermenge 
von (Z/@var{n}Z) auszuw@"ahlen. 
Ist @var{gcd} eine nat@"urliche Zahl, werden Potenzen von allen Restklassen 
@code{x} mit @code{gcd(x,n) = }@var{gcd} zur@"uck gegeben, 
d.h. @var{gcd} ist standardm@"a@ss{}ig @code{1}.
Wird @var{gcd} auf @code{all} gesetzt, wird die Tabelle f@"ur s@"amtliche 
Elemente in (Z/@var{n}Z) ausgegeben.

Wird das optionale dritte Argument @var{max_exp} angegeben, variiert der 
Exponent zwischen @code{1} und @var{max_exp}.

Siehe auch @mref{zn_add_table}, @mref{zn_mult_table}.

Beispiele:

Die Standardeinstellung @var{gcd}@code{ = 1} erlaubt es, grundlegende S@"atze, 
wie die von Fermat and Euler, zu zeigen und zu betrachten.

Das Argument @var{gcd} erlaubt es, bestimmte Teilmengen von (Z/@var{n}Z) 
auszuw@"ahlen und multiplikative Untergruppen und Isomorphismen zu untersuchen. 

Z.B. sind die Gruppen @code{G10} und @code{G10_2} unter der Multiplikation 
beide isomorph zu @code{G5}. @code{1} ist die Identit@"at in @code{G5}. 
So sind @code{1} bzw. @code{6} die Identit@"aten in @code{G10} bzw. @code{G10_2}. 
Entsprechende Zuordnungen ergeben sich bei den Primitivwurzeln, n-ten Wurzeln, etc..

@example
(%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]
@end example

Wird @var{gcd} auf @code{all} gesetzt, wird die Tabelle f@"ur s@"amtliche 
Elemente in (Z/@var{n}Z) ausgegeben.

Das dritte Argument @var{max_exp} erlaubt, den h@"ochsten Exponenten zu w@"ahlen.  
Die folgende Tabelle zeigt ein kleines RSA-Beispiel.

@example
(%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 ]
@end example
@end deffn

@c --- 29.03.2012 VN -----------------------------------------------------------
@anchor{zn_primroot}
@deffn {Funktion} zn_primroot (@var{n}) 
@deffnx {Funktion} zn_primroot (@var{n}, [[@var{p1}, @var{e1}], @dots{}, [@var{pk}, @var{ek}]])

Ist die multiplikative Gruppe (Z/@var{n}Z)* zyklisch, berechnet @code{zn_primroot} 
die kleinste Primitivwurzel modulo @var{n}.  Dies ist der Fall, wenn @var{n} gleich 
@code{2}, @code{4}, @code{p^k} oder @code{2*p^k} ist, wobei @code{p} ungerade und 
prim und @code{k} eine nat@"urliche Zahl ist.  @code{zn_primroot} 
f@"uhrt einen entsprechenden Pr@"atest durch, wenn die Optionsvariable 
@mref{zn_primroot_pretest} (Standardwert: @code{false}) @code{true} gesetzt wurde.
In jedem Fall wird die Suche durch die obere Schranke @mref{zn_primroot_limit} begrenzt.

Ist (Z/@var{n}Z)* nicht zyklisch oder kann bis @code{zn_primroot_limit} 
keine Primitivwurzel modulo @var{n} gefunden werden, gibt @code{zn_primroot} 
@code{false} zur@"uck. 

Der verwendete Algorithmus ben@"otigt die Primfaktorzerlegung des Totienten von @var{n}. 
Diese Berechnung kann zeitaufw@"andig sein und es kann daher eventuell sinnvoll 
sein, die Primfaktoren des Totienten vorab zu berechnen und @code{zn_primroot} 
als zus@"atzliches Argument zu @"ubergeben. Die Form muss dabei der R@"uckgabe  
von @code{ifactors(totient(n))} mit der Standardeinstellung @code{false} der 
Optionsvariable @code{factors_only} entsprechen. 

Siehe auch @mref{zn_primroot_p}, @mref{zn_order}, @mref{ifactors}, @mref{totient}.

Beispiele:

@code{zn_primroot} berechnet die kleinste Primitivwurzel modulo @var{n} oder gibt 
@code{false} zur@"uck.

@example
(%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
@end example

Das optionale zweite Argument muss der R@"uckgabe von @code{ifactors(totient(n))} 
entsprechen. 

@example
(%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
@end example
@end deffn

@c --- 23.03.2013 VN -----------------------------------------------------------
@anchor{zn_primroot_limit}
@defvr {Optionsvariable} zn_primroot_limit
Standardwert: @code{1000} 

Definiert die obere Schranke f@"ur die Suche von @mref{zn_primroot} nach einer 
Primitivwurzel.  Wurde die Optionsvariable @mref{zn_primroot_verbose}
(Standardwert: @code{false}) @code{true} gesetzt, wird beim Erreichen von 
@code{zn_primroot_limit} ein entsprechender Hinweis ausgegeben.
@end defvr

@c --- 29.03.2012 VN -----------------------------------------------------------
@anchor{zn_primroot_p}
@deffn {Funktion} zn_primroot_p (@var{x}, @var{n}) 
@deffnx {Funktion} zn_primroot_p (@var{x}, @var{n}, [[@var{p1}, @var{e1}], @dots{}, [@var{pk}, @var{ek}]])

Testet, ob @var{x} eine Primitivwurzel in der multiplikativen Gruppe (Z/@var{n}Z)* 
ist. 

Der verwendete Algorithmus ben@"otigt die Primfaktorzerlegung des Totienten von  
@var{n}.  Wird dieser Test nacheinander auf mehrere Zahlen angewandt, 
kann es sinnvoll sein, die Primfaktoren des Totienten vorab zu berechnen 
und @code{zn_primroot_p} als zus@"atzliches drittes Argument zu @"ubergeben. 
Die Form muss dabei der R@"uckgabe von @code{ifactors(totient(n))} mit der 
Standardeinstellung @code{false} der Optionsvariable @code{factors_only} 
entsprechen. 

Siehe auch @mref{zn_primroot}, @mref{zn_order}, @mref{ifactors}, @mref{totient}.

Beispiele:

@code{zn_primroot_p} als Pr@"adikatfunktion.

@example
(%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]
@end example

Das optionale dritte Argument muss der R@"uckgabe von @code{ifactors(totient(n))} 
entsprechen. 

@example
(%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]]
@end example
@end deffn

@c --- 23.03.2013 VN -----------------------------------------------------------
@anchor{zn_primroot_pretest}
@defvr {Optionsvariable} zn_primroot_pretest
Standardwert: @code{false} 

Eine multiplikative Gruppe (Z/@code{n}Z)* ist zyklisch, wenn @code{n} gleich 
@code{2}, @code{4}, @code{p^k} oder @code{2*p^k} ist, wobei @code{p} prim und 
gr@"o@ss{}er @code{2} und @code{k} eine nat@"urliche Zahl ist. 

@code{zn_primroot_pretest} entscheidet dar@"uber, ob @mref{zn_primroot} vor 
der Berechnung der kleinsten Primitivwurzel in (Z/@code{n}Z)* @"uberpr@"uft, 
ob auf @code{n} @"uberhaupt einer der oben genannten F@"alle zutrifft.  Nur wenn  
@code{zn_primroot_pretest} @code{true} ist, wird dieser Pr@"atest ausgef@"uhrt.
@end defvr

@c --- 23.03.2013 VN -----------------------------------------------------------
@anchor{zn_primroot_verbose}
@defvr {Optionsvariable} zn_primroot_verbose
Standardwert: @code{false} 

Entscheidet, ob @mref{zn_primroot} beim Erreichen von @mref{zn_primroot_limit}
einen Hinweis ausgibt.
@end defvr

@c --- End of file Number.de.texi

