diff --git a/documents/eaz/eaz.pdf b/documents/eaz/eaz.pdf index e73c408..2be1441 100644 Binary files a/documents/eaz/eaz.pdf and b/documents/eaz/eaz.pdf differ diff --git a/documents/eaz/eaz.tex b/documents/eaz/eaz.tex index 3ab4321..f4614db 100644 --- a/documents/eaz/eaz.tex +++ b/documents/eaz/eaz.tex @@ -223,7 +223,35 @@ Will man die Elementarteiler einer Matrix $M$ berechnen, so gilt: \end{itemize} \section*{Weiteres} -In alten Klausuren begegnen uns desöfteren Ringe der Form $Z[\sqrt{d}]$. +Finden von Zerlegungen von Elementen im Ring $\mathbb{Z}[\sqrt{d}] := \Set{a + b \sqrt{d} | a, b \in \mathbb{Z}}$: + +Es sei +\begin{align*} + |\cdot|:\mathbb{Z}[\sqrt{d}] &\rightarrow \mathbb{R}_0^+\\ + |x + y \cdot \sqrt{d}| &:= \sqrt{x^2 + y^2 |d|} +\end{align*} + +und + +\begin{align*} + N: \mathbb{Z}[\sqrt{d}] &\rightarrow \mathbb{N}_0\\ + N(z) &:= |z|^2 +\end{align*} +und die Konjugation: +\[\overline{x+ y \sqrt{d}} = \begin{cases}x - y \sqrt{d} &\text{, falls } d < 0\\x + y \sqrt{d} &\text{, falls } x \geq 0\end{cases}\] + +Die Konjugation ist multiplikativ: +\[\overline{wz} = \overline{w} \cdot \overline{z}\] + +Außerdem gilt: +\begin{align*} + N(\pi) &= x^2+y^2 |d|\\ + &= (x+y\sqrt{d}) \cdot (x+\frac{d}{|d|}y\sqrt{d})\\ + &= \pi \cdot \overline{\pi} +\end{align*} + + +In alten Klausuren begegnen uns desöfteren Ringe der Form . In diesem Zusammenhang begegnet uns die Normabbildung. (Ein Beispiel, das in der Vorlesung gesehen wurde, waren die gauß'schen Zahlen.) diff --git a/source-code/Pseudocode/SolveLinearCongruences/Makefile b/source-code/Pseudocode/SolveLinearCongruences/Makefile new file mode 100644 index 0000000..00bfb75 --- /dev/null +++ b/source-code/Pseudocode/SolveLinearCongruences/Makefile @@ -0,0 +1,36 @@ +SOURCE = SolveLinearCongruences +DELAY = 80 +DENSITY = 300 +WIDTH = 500 + +make: + pdflatex $(SOURCE).tex -output-format=pdf + pdflatex $(SOURCE).tex -output-format=pdf + make clean + +clean: + rm -rf $(TARGET) *.class *.html *.log *.aux *.data *.gnuplot + +gif: + pdfcrop $(SOURCE).pdf + convert -verbose -delay $(DELAY) -loop 0 -density $(DENSITY) $(SOURCE)-crop.pdf $(SOURCE).gif + make clean + +png: + make + make svg + inkscape $(SOURCE).svg -w $(WIDTH) --export-png=$(SOURCE).png + +transparentGif: + convert $(SOURCE).pdf -transparent white result.gif + make clean + +svg: + make + #inkscape $(SOURCE).pdf --export-plain-svg=$(SOURCE).svg + pdf2svg $(SOURCE).pdf $(SOURCE).svg + # Necessary, as pdf2svg does not always create valid svgs: + inkscape $(SOURCE).svg --export-plain-svg=$(SOURCE).svg + rsvg-convert -a -w $(WIDTH) -f svg $(SOURCE).svg -o $(SOURCE)2.svg + inkscape $(SOURCE)2.svg --export-plain-svg=$(SOURCE).svg + rm $(SOURCE)2.svg diff --git a/source-code/Pseudocode/SolveLinearCongruences/Readme.md b/source-code/Pseudocode/SolveLinearCongruences/Readme.md new file mode 100644 index 0000000..360fff8 --- /dev/null +++ b/source-code/Pseudocode/SolveLinearCongruences/Readme.md @@ -0,0 +1,3 @@ +Compiled example +---------------- +![Example](SolveLinearCongruences.png) diff --git a/source-code/Pseudocode/SolveLinearCongruences/SolveLinearCongruences.png b/source-code/Pseudocode/SolveLinearCongruences/SolveLinearCongruences.png new file mode 100644 index 0000000..7cb9a95 Binary files /dev/null and b/source-code/Pseudocode/SolveLinearCongruences/SolveLinearCongruences.png differ diff --git a/source-code/Pseudocode/SolveLinearCongruences/SolveLinearCongruences.tex b/source-code/Pseudocode/SolveLinearCongruences/SolveLinearCongruences.tex new file mode 100644 index 0000000..98f4fd0 --- /dev/null +++ b/source-code/Pseudocode/SolveLinearCongruences/SolveLinearCongruences.tex @@ -0,0 +1,46 @@ +\documentclass{article} +\usepackage[pdftex,active,tightpage]{preview} +\setlength\PreviewBorder{2mm} + +\usepackage[utf8]{inputenc} % this is needed for umlauts +\usepackage[ngerman]{babel} % this is needed for umlauts +\usepackage[T1]{fontenc} % this is needed for correct output of umlauts in pdf +\usepackage{amssymb,amsmath,amsfonts} % nice math rendering +\usepackage{braket} % needed for \Set +\usepackage{algorithm,algpseudocode} + +\usepackage{tikz} +\usetikzlibrary{decorations.pathreplacing,calc} +\newcommand{\tikzmark}[1]{\tikz[overlay,remember picture] \node (#1) {};} +\newcommand*{\AddNote}[4]{% + \begin{tikzpicture}[overlay, remember picture] + \draw [decoration={brace,amplitude=0.5em},decorate,very thick] + ($(#3)!(#1.north)!($(#3)-(0,1)$)$) -- + ($(#3)!(#2.south)!($(#3)-(0,1)$)$) + node [align=center, text width=2.5cm, pos=0.5, anchor=west] {#4}; + \end{tikzpicture} +}% + +\begin{document} +\begin{preview} + \begin{algorithm}[H] + \begin{algorithmic} + \Require $R \in \mathbb{Z}^n, P \in (\mathbb{N}_{\geq 1})^n, n \in \mathbb{N}_{\geq 1}$, where \\ + $R$ is a vector with all rests $r_i$ and\\ + $P$ is a vector with all modulos $p_i$ such that\\ + ($x \equiv r_i \mod p_i$) and $\left(i \neq j \Rightarrow \Call{gcd}{p_i, p_j} = 1 \right)$ + \\ + \State $M \gets \prod_{p \in P} p$ + + \For{$i \in \{1, \dots, n\}$} + \State $M_i \gets \frac{M}{p_i} $ + \State $y_i \gets \Call{getMultiplicativeInverse}{M_i, R_i}$ + \EndFor + \\ + \State \Return $(\sum_{i=1}^n R_i y_i M_i, M)$ + \end{algorithmic} + \caption{Solve a system of linear congruences} + \label{alg:solveCongruences} + \end{algorithm} +\end{preview} +\end{document} diff --git a/source-code/Pseudocode/SolveLinearCongruences/solveLinearCongruences.py b/source-code/Pseudocode/SolveLinearCongruences/solveLinearCongruences.py new file mode 100644 index 0000000..4758821 --- /dev/null +++ b/source-code/Pseudocode/SolveLinearCongruences/solveLinearCongruences.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +def ExtendedEuclideanAlgorithm(a, b): + """ + Calculates gcd(a,b) and a linear combination such that + gcd(a,b) = a*x + b*y + + As a side effect: + If gcd(a,b) = 1 = a*x + b*y + Then x is multiplicative inverse of a modulo b. + """ + aO, bO = a, b + + x=lasty=0 + y=lastx=1 + while (b!=0): + q= a/b + a, b = b, a%b + x, lastx = lastx-q*x, x + y, lasty = lasty-q*y, y + + return { + "x": lastx, + "y": lasty, + "gcd": aO * lastx + bO * lasty + } + +def solveLinearCongruenceEquations(rests, modulos): + """ + Solve a system of linear congruences. + + >>> solveLinearCongruenceEquations([4, 12, 14], [19, 37, 43]) + {'congruence class': 22804, 'modulo': 30229} + """ + assert len(rests) == len(modulos) + x = 0 + M = reduce(lambda x, y: x*y, modulos) + + for mi, resti in zip(modulos, rests): + Mi = M / mi + s = ExtendedEuclideanAlgorithm(Mi, mi)["x"] + e = s * Mi + x += resti * e + return {"congruence class": ((x % M) + M) % M, "modulo": M} + +if __name__ == "__main__": + import doctest + doctest.testmod()