1.6 Lineare Codes existieren

In Kapitel 1.2 haben wir einen Code C{0,1}n mit Abstand Δ(C)d+1 und Größe 2n/Φ(n,d) konstruiert, indem wir "greedily" ein Codewort nach dem anderen hinzugefügt haben und in jedem Schritt alle "zu nahen" Wörter y{0,1}n gelöscht haben. Der Nachteil dieser Konstruktion war ihre algorithmische Ineffizienz: die Laufzeit stand in Zusammenhang mit 2n, der Zahl aller möglichen Wörter. Wir wollen aber, dass die Zeit zum codieren polynomiell in der Blocklänge n ist.

In diesem Teilkapitel zeigen wir die überraschende Tatsache, dass wir die untere Schranke von 2n/Φ(n,d) mit linearen Codes fast erreichen können. Und müssen uns dabei nicht einmal besonders anstrengen. Es reicht, die Matrix G zufällig zu wählen.

Theorem 1.6.1 Sei ϵ>0 und nN. Sei

k:=(1log2Φ(n,d)nϵ)n

Wir bilden eine Matrix GF2n×k, indem wir jeden Eintrag zufällig aus {0,1} wählen. Dann gilt

Pr[Δ(G)d+1]12ϵn .

Falls Δ(G)d+1 gilt, dann ist G (präziser: die durch G definierte lineare Abbildung) injektiv und somit |img(G)|=2k. Der durch G definierte lineare Code hat also Rate k/n.

Beweis. Sei uF2k{0} ein beliebiger Vektor. Als erstes werden wir sehen, dass Gu gleichverteilt in F2n ist.

Behauptung. Sei uF2k{0}. Dann ist Gu gleichverteilt in F2n. Das heißt: für jedes xF2n gilt

PrG[Gu=x]=2n .

Beweis. Sei l[k] der größte Index mit ul=1. Dieser existiert, weil ja u0 nach Annahme. Wir schreiben G als G=[g1,,gk], wobei jede Spalte gjF2n zufällig gewählt ist. Es gilt nun

Gu=i=1kgiui=(i=1l1uigi)+ulgl=(i=1l1uigi)+gl

Wir stellen uns nun vor, dass wir G bilden, indem wir die Spalten nacheinander zufällig wählen. Nachdem wir g1,,gl1 gewählt haben, pausieren wir. Ob nun Gu=x gilt oder nicht, hängt nur noch von der Wahl von gl ab. In der Tat:

Gu=x(i=1l1uigi)+gl=xgl=x(i=1l1uigi) .

Die rechte Seite ist nun, da wir g1,,gl1 bereits gewählt haben, ein fester Vektor in F2n. Somit ist die Wahrscheinlichkeit, dass gl genau dieser Vektor wird, genau 2n.

Im Weiteren Verlauf werden wir Übungsaufgabe 1.5.1 verwenden: es gilt Δ(G)d genau dann, wenn es ein Urwort u0 gibt mit |Gu|d. Wir müssen nun zeigen, dass dies unwahrscheinlich ist. Sei Eu das "schlechte" Ereignis, dass |Gu|d ist. Da Gu gleichverteilt über F2n ist und es insgesamt Φ(n,d) viele Vektoren yF2n mit |y|d gibt, gilt

Pr[Eu]=Φ(n,d)2n .

Sei nun E:=uF2kEu. Das ist das Ereignis, dass es überhaupt ein uF2k{0} gibt mit |Gu|d. Dass also Δ(G)d. Es gilt per "Union Bound":

Pr[E]=Pr[uF2kEu]uF2kPr[Eu]=2kΦ(n,d)2n

Aus unserer Wahl k:=(1log2Φ(n,d)nϵ)n folgt also

Pr[E]2kΦ(n,d)2n(2nΦ(n,d)12ϵn)Φ(n,d)2n=2ϵn , wie behauptet.

Wir sind nun unserem Ziel näher gekommen: ein solcher Code für d=δn hat Abstand mindestens δn und Rate 1H(δ)ϵ. Die Codierungsfunktion lässt sich als Matrix GF2n×k darstellen und somit in O(nk) berechnen. Für festes 0<δ<1/2 ist dads O(n2). Können wir jetzt das Thema abhaken und nach Hause gehen? Naja, nicht ganz. Der so konstruierte Code hat immer noch einige Nachteile:

  1. Es ist immer unangenehm, von Zufall abhängig zu sein. Eine vollständig deterministische Konstruktion ist wünschenswert.
  2. Die Codierung (und bereits die Darstellung) benötigt O(n2) Platz. Wir hätten gerne eine Komplexität, die näher an O(n) ist.
  3. Es ist gar nicht klar, wie man aus einem korrumpierten Codewort y das "richtige" Codewort x rekonstruiert; wie man den Code also effizient decodiert.