Miniprojekt 1: Felrättande koder och modellering av data
Miniprojekt 1: Felrättande koder och modellering av data
Miniprojekt 1: Felrättande koder och modellering av data
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
TNA005 VT 2008<br />
Michael Hörnquist 21 januari 2008<br />
<strong>Miniprojekt</strong> 1:<br />
<strong>Felrättande</strong> <strong>koder</strong> <strong>och</strong> <strong>modellering</strong> <strong>av</strong> <strong>data</strong><br />
I den här uppgiften studerar vi en metod för att koda budskap så att man kan upptäcka <strong>och</strong><br />
korrigera fel som uppstår under överföringen. Målet är att hitta en matematisk beskrivning <strong>av</strong> hur<br />
pass effektiv den metod vi utvecklar är.<br />
Eftersom <strong>av</strong>snitten om <strong>koder</strong> saknar direkt stöd i kurslitteraturen kommer den delen <strong>av</strong> den här<br />
texten att bli betydligt längre än för andra miniprojekt. Trots det är den tämligen ytlig, <strong>och</strong><br />
den student som önskar se mer hänvisas till referenslistan. Avsnitten om <strong>modellering</strong> <strong>av</strong> <strong>data</strong> är<br />
betydligt kortare, eftersom ni där hittar det mesta i Jönsson.<br />
Lite om Z 2 <strong>och</strong> moduloräkning<br />
I en binär värld har vi endast två siffror, nämligen 0 (noll) <strong>och</strong> 1 (ett). 1 Låt oss nu ändra de<br />
aritmetiska lagarna för addition <strong>och</strong> multiplikation till att uppfylla<br />
+ 0 1<br />
0 0 1<br />
1 1 0<br />
· 0 1<br />
0 0 0<br />
1 0 1<br />
Det ser lite egendomligt ut att ”1 + 1 = 0”, men det behöver inte vara märkvärdigare än att man<br />
”börjar om” efter ett, pss som klockan börjar om efter kl 12. Klockan räknas modulo 12, <strong>och</strong> här<br />
räknar vi modulo 2. 2 Vår mängd <strong>av</strong> tal, {0, 1}, utrustade med ovanstående räkneregler, kallas för<br />
mängden heltal modulo 2 <strong>och</strong> betecknas Z 2 . 3<br />
Om vi önskar kan vi skapa vektorer där elementen hämtas från mängden Z 2 , exempelvis består<br />
mängden Z 3 2 <strong>av</strong> vektorerna<br />
⎛ ⎞ ⎛ ⎞ ⎛ ⎞ ⎛ ⎞ ⎛ ⎞ ⎛ ⎞ ⎛ ⎞ ⎛ ⎞<br />
⎝ 0 0⎠ , ⎝ 0 0⎠ , ⎝ 0 1⎠ , ⎝ 0 1⎠ , ⎝ 1 0⎠ , ⎝ 1 0⎠ , ⎝ 1 1⎠ <strong>och</strong> ⎝ 1 1⎠ ,<br />
0 1 0 1 0 1 0 1<br />
<strong>och</strong> vi använder samma räkneregler som för Z 2 . En skalärprodukt blir t.ex.<br />
⎛ ⎞ ⎛ ⎞<br />
⎝ 1 0⎠ · ⎝ 1 1⎠ = 1 · 1 + 0 · 1 + 1 · 0 = 1 + 0 + 1 = 0.<br />
1 1<br />
1 Skilj på siffror <strong>och</strong> tal! Ni förutsätts inte vara bekanta med hur man kodar tal i basen två, utan det räcker att<br />
ni inser att det borde gå att göra.<br />
2 De som har läst digitalteknik har måhända vant sig vid att associera tecknet ”+” med den logiska operation<br />
OR. Här står ”+” istället för XOR.<br />
3 Matematiskt kallas en mängd som är sluten under en räkneoperation (t.ex. addition), samt har enhetselement,<br />
invers <strong>och</strong> uppfyller associativa lagen, för en grupp. Vi kommer inte gå in närmare på det här.<br />
1
Felupptäckande <strong>koder</strong><br />
Grunden för felupptäckande <strong>koder</strong> är redundans, dvs att koden innehåller mer information än vad<br />
som skulle behövas om inga fel kunde uppstå. Om vi skall skicka en binär sträng, bestående <strong>av</strong><br />
ettor <strong>och</strong> nollor, så skulle vi få en felupptäckande kod genom att skicka varje tecken två gånger.<br />
Alltså, ’10010’ skulle skickas som ’ 10010<br />
10010 ’. Förvisso skulle fel upptäckas <strong>av</strong> mottagaren, men det<br />
förefaller inte vara ett helt optimalt utnyttjande <strong>av</strong> resurserna.<br />
Ett mycket enkelt sätt att upptäcka enstaka fel är att använda en s.k. paritetsbit. Om vi tänker<br />
oss att det är bokstäver vi vill skicka är det naturligt att använda grupper om fem bitar 4 <strong>och</strong> då<br />
blir paritetsbiten en sjätte bit vi lägger till så att antalet ettor blir ett jämt tal. Notera att det<br />
förutsätter att vi tänker oss bitarna ordnade i block <strong>och</strong> därmed kallas det också för en blockkod.<br />
Om vi låter ’A’ vara 1, ’B’ två, osv, till ’Ö’ 29, <strong>och</strong> sedan omvandlar till binärt kommer ’M’ att<br />
kodas som ’01101’ (=13). Eftersom det är tre ettor i denna sträng, låter vi den sjätte biten också<br />
vara en etta så antalet blir jämt. Koden för ’M’ blir då ’011011’. Vid <strong>av</strong>kodning börjar vi med att<br />
räkna bitar, <strong>och</strong> om endast ett fel har uppstått visar det sig direkt när vi räknar ettor att vi inte<br />
kan lita på det vi tar emot.<br />
Två uppenbara problem är dock att vi inte kan upptäcka om två fel har uppstått (eller överhuvud<br />
taget ett jämt antal), <strong>och</strong> vi har heller ingen aning om vilket tecken det var som <strong>av</strong>sändaren önskade<br />
skicka. Klart dock att det vi har är vida bättre än ingenting.<br />
<strong>Felrättande</strong> <strong>koder</strong><br />
Också för felrättande <strong>koder</strong> är grunden redundans. Om vi skickar mer information än vad som<br />
krävs vid garanterat felfri överföring, så kan vi inte bara upptäcka utan också korrigera fel som<br />
uppstår på vägen. Enklast tänkbara felrättande kod skulle vara att upprepa varje bit tre gånger,<br />
så att (10010) skickas som<br />
⎛ ⎞<br />
10010<br />
⎝10010⎠ .<br />
10010<br />
Förvisso kan enstaka fel båda upptäckas <strong>och</strong> korrigeras med denna kod, men den är fruktansvärt<br />
ineffektiv.<br />
Det är ett mycket stort forskningsområde att undersöka hur man ordnar goda felrättande <strong>koder</strong>.<br />
Den teoretiska grunden lades på 1940-talet <strong>av</strong> Shannon, Hamming, m.fl., men det finns fortfarande<br />
mycket att göra. Den matematiska teori som kommer till användning omfattar bl.a. abstrakt algebra<br />
med Galoisteori <strong>och</strong> diskreta strukturer. Vi skall dock inte gå längre här än att vi klarar oss med<br />
en grundkurs i linjär algebra.<br />
Hamming<strong>koder</strong><br />
En viktig standardkod är den s.k. Hammingkoden, som kan användas för att konstruera <strong>koder</strong> som<br />
upptäcker <strong>och</strong> rättar fel i enskilda bitar i ett block. Idag används den mer sällan i tillämpningar,<br />
men kan ändå komma till nytta för att illustrera viktiga principer inom kodningsteorin.<br />
4 eftersom vi har 29 bokstäver i alfabetet <strong>och</strong> 2 4 < 29 ≤ 2 5<br />
2
Antag nu att vi har en vektor x ∈ Z 4 2 som vi vill koda till en kodvektor så att vi får möjlighet<br />
att upptäcka <strong>och</strong> rätta enstaka fel som kan ha uppstått under överföringen. Det visar sig att vi<br />
kan klara det redan med tre paritetskontroller, svarande mot tre paritetsbitar som vi får lägga till<br />
för att erhålla kodvektorn. Om vi väljer vår generatormatris, som genererar kodvektorn c, genom<br />
att använda så många parvis linjärt oberoende vektorer i Z 3 2 som möjligt, kan vi lyckas med detta.<br />
Tag exempelvis matrisen<br />
⎛<br />
A = ⎝ 1 1 0 1 ⎞<br />
1 0 1 1⎠ .<br />
0 1 1 1<br />
Dess kolonner är parvis linjärt oberoende, <strong>och</strong> även oberoende mot enhetsbasen. Det senare är<br />
väsentligt, då vi önskar att de 4 översta elementen i kodvektorn c skall utgöras <strong>av</strong> vektorn x.<br />
Forma nu generatormatrisen G enligt<br />
G =<br />
( )<br />
E4<br />
, dvs G =<br />
A<br />
⎛ ⎞<br />
1 0 0 0<br />
0 1 0 0<br />
0 0 1 0<br />
0 0 0 1<br />
.<br />
⎜1 1 0 1<br />
⎟<br />
⎝1 0 1 1⎠<br />
0 1 1 1<br />
En kodvektor c formas nu enligt<br />
c = Gx.<br />
Om vi vill skicka x = (0111) t (motsvarande talet ”7”), så får vi alltså kodvektorn<br />
c = G(0111) t = (0111001) t .<br />
De tre paritetskontrollerna kan nu skrivas P c = 0, med matrisen P = (AE 3 ), kallad paritetskontrollmatrisen,<br />
dvs<br />
⎛ ⎞<br />
c 1<br />
⎛<br />
⎞<br />
c 2<br />
⎛ ⎞<br />
1 1 0 1 1 0 0<br />
c 3<br />
0<br />
⎝1 0 1 1 0 1 0⎠<br />
c 4<br />
= ⎝0⎠ .<br />
0 1 1 1 0 0 1<br />
⎜c 5<br />
⎟ 0<br />
⎝c 6<br />
⎠<br />
c 7<br />
Om vår kodade sjua skulle råka bli förvrängd under överföringen till c ′ = (0101001) t , så får vi<br />
P c ′ = (011) t . Uppenbart har ett fel uppstått, men vi kan också se att paritetskontrollen g<strong>av</strong><br />
upphov till en vektor som även återfinns som matrisen P s (eller, likvärdigt, matrisen As) tredje<br />
kolonn. Då kan vi dra slutsatsen att det är den tredje komponenten i kodvektorn som är förvrängd,<br />
<strong>och</strong> den urspungliga information som skickades var (0111).<br />
Ovanstående förefaller nästan magiskt. Låt oss därför formulera följande sats (formuleringen är<br />
tagen ur Poole):<br />
Sats:<br />
Om G = ( )<br />
E k<br />
A är en generatormatris <strong>och</strong> P = (BEn−k ) är en paritetskontrollmatris, så hör P<br />
ihop med G om <strong>och</strong> endast om A = B. Motsvarande binära (n, k)-kod är enkelfelrättande om <strong>och</strong><br />
endast om kolonnerna i P är parvis linjärt oberoende.<br />
Bevis:<br />
Låt P <strong>och</strong> G vara som i förutsättningarna för satsen.<br />
3
Antag först att de är paritetskontrollmatris <strong>och</strong> generatormatris för samma binära (n, k)-kod. För<br />
alla x ∈ Z k 2 gäller då P Gx = 0. Det innebär att<br />
( )<br />
Ek<br />
Bx + Ax = (B + A)x = (BE n−k ) x = P Gx = 0.<br />
A<br />
Eftersom vi räknar modulo 2, så följer att Ax = Bx. Genom att nu välja x = e i (enhetsbasen) för<br />
i = 1, · · · , k får vi att B = A.<br />
Antag sedan att B = A. För ett godtyckligt x ∈ Z k 2 gäller då<br />
( )<br />
Ek<br />
P Gx = (AE n−k ) x = (A + A)x = 0,<br />
A<br />
eftersom A + A alltid måste vara nollmatrisen.<br />
Återstår att visa att koden är enkelfelrättande. Låt x ∈ Z k 2 vara meddelandet, som kodas till<br />
c = Gx ∈ Z n 2 . Antag att vid överföringen uppstår ett fel i komponent i, varvid kodordet blir<br />
c ′ = c + e i . Vid <strong>av</strong>kodningen får vi<br />
P c ′ = P (c + e i ) = P c + P e i = 0 + p i = p i ,<br />
där p i är kolonn i i matrisen P . Eftersom kolonnerna i P är parvis linjärt oberoende är inga <strong>av</strong><br />
dem lika, <strong>och</strong> ingen är nollvektorn. Alltså kan vi identifiera vilken bit som har blivit förvrängd vid<br />
överföringen. VSB.<br />
Koder som konstrueras på detta sätt kallas för (n, k) Hamming<strong>koder</strong>. I exemplet ovan har vi alltså<br />
en (7, 4) Hammingkod. Allmänt gäller för optimala Hammings<strong>koder</strong> att n = 2 n−k − 1, dvs alla<br />
kombinationer <strong>av</strong> n <strong>och</strong> k är inte möjliga (i <strong>och</strong> för sig kan vi alltid konstruera ex.vis en (9, 5)-kod<br />
(dvs fyra paritetsbitar till block med fem bitar), men det blir då ett mindre optimalt utnyttjande<br />
<strong>av</strong> den begränsade överföringskapaciteten). Speciellt om vi önskar koda text så krävs minst sex<br />
bitar (29 bokstäver <strong>och</strong> 10 siffror är ett minimum). Dessvärre finns tydligen ingen Hammingkod<br />
med k = 6, så man måste öka antalet bitar. Vilka är de minsta värden på n <strong>och</strong> k som duger?<br />
Finns det andra sätt att lösa det här problemet?<br />
Modellering <strong>av</strong> <strong>data</strong><br />
Grundfrågan här är hur man utifrån mät<strong>data</strong> kan skatta parametrar, givet att vi vet eller kan gissa<br />
något samband där parametrarna ingår <strong>och</strong> vi kan mäta övriga storheter. Matematiskt handlar det<br />
om att vi löser ekvationssystem där vi har fler ekvationer än obekanta, <strong>och</strong> där ingen exakt lösning<br />
finnes. Praktiskt får vi skilja på på fallet när vi känner funktionsformen från den underliggande<br />
verkligheten <strong>och</strong> exempelvis fysikaliska samband, <strong>och</strong> fallet när vi endast har <strong>data</strong>mängden i sig<br />
utan någon förklaringsmodell.<br />
Känd förklaringsmodell<br />
Betrakta exempelvis hur man mätt strömmen I genom en resistor <strong>och</strong> samtidigt mätt spänningsfallet<br />
U över resistorn ihop med en okänd spänningskälla. Enligt Ohms lag vet vi att kvoten mellan<br />
spänning <strong>och</strong> ström för en resistor är konstant, <strong>och</strong> vi kallar det för resistorns resistans. Om vi<br />
antar att resistorns resistans är R <strong>och</strong> den okända spänningskällan har en spänning V 0 , så måste 5<br />
5 ”Måste” är här ett starkt ord. Givetvis är det en modell vi framställer, <strong>och</strong> i det här fallet försummar vi<br />
spänningskällans inre resistans, att Ohms lag inte är exakt, strömmen genom voltmetern, för att bara nämna några<br />
förbehåll. Allmänt gäller att graden <strong>av</strong> exakthet i modellen måste svara mot vilket användningsområde man tänker<br />
sig för den.<br />
4
varje talpar (U, I) vi mäter uppfylla U = V 0 + RI. Med exakt två mätningar på (U, I) får vi då<br />
väldefinierade värden på R <strong>och</strong> V 0 . Men om vi gör ytterligare en mätning får vi tre ekvationer<br />
som antagligen inte alla kan vara sanna samtidigt. Alltså handlar det här om att bestämma det<br />
värde på parametrarna som ger upphov till ”minsta felet”. Givetvis bör man fortfarande ge akt på<br />
kurvformen för att se att man inte gör något uppenbart orimligt (i det här fallet att anpassa en<br />
rät linje till mät<strong>data</strong>), men det är sällan där problemet ligger.<br />
Okänd förklaringsmodell<br />
När vi inte är bekanta med vilken form <strong>av</strong> ekvation som kan beskriva uppmätta <strong>data</strong> har vi ett<br />
knepigare fall. Här måste vi istället använda oss <strong>av</strong> allmän kunskap om hur olika funktionskurvor<br />
ser ut för att pröva oss fram. Genom att logaritmera den ena eller bägge axlarna kan vi i enklare<br />
fall se om vi bör använda exponential- eller potensfunktioner för att modellera <strong>data</strong>. Andra sätt<br />
kan vara att plotta kvoten <strong>av</strong> y- <strong>och</strong> x-värdena längs y-axeln <strong>och</strong> behålla x-värdena längs x-axeln,<br />
o.s.v. Variationsmöjligheterna är oändliga.<br />
Praktiskt måste man också på något sätt <strong>av</strong>göra när en ekvation är ”tillräckligt bra”. Det är en<br />
fråga för matematisk statistik <strong>och</strong> faller utanför ramen för den här kursen, varför vi enbart kommer<br />
att plotta ekvationerna <strong>och</strong> med ögat <strong>av</strong>göra om det ser rimligt ut. På engelska kallas detta ofta<br />
”Chi by eye” <strong>och</strong> är något som proffs starkt <strong>av</strong>råder från. Inte dessto mindre är det mycket vanligt<br />
förekommande bland såväl ingenjörer som vetenskapare.<br />
Matematisk behandling<br />
Från kursen i linjär algebra antas ni förtrogna med minstakvadratproblem <strong>och</strong> med normalekvationerna<br />
för att lösa sådana. Minns dock att det enbart handlade om linjära system (ibland efter<br />
förprocessande <strong>av</strong> <strong>data</strong>, såsom logaritmering). Kort gick det ut på att om man önskar ”lösa” x i<br />
det överbestämda systemet<br />
Ax = b,<br />
så kan man tolka det som att finna det x som minimerar |Ax − b|. Matrisen A kallas ofta designmatrisen<br />
<strong>och</strong> beskrivs mer ingående i Jönsson. En exakt omformulering <strong>av</strong> minimeringsproblemet<br />
ovan är normalekvationerna<br />
A t Ax = A t b,<br />
som ofta visar sig ha en väldefinierad lösning.<br />
Men. . .<br />
I praktiska problem visar sig dessa normalekvationer otrevligt ofta ha mycket dåliga numeriska<br />
egenskaper. De är störkänsliga såtillvida att små fel i in<strong>data</strong> i A kan ge stora fel i x. Man talar om<br />
att konditionstalet för matrisen A t A är stort (se Jönsson kap. 8.7). I MatLab tar dock den inbyggda<br />
ekvationslösaren hand om eventuella dåliga konditionstal hos A t A <strong>och</strong> väljer en tillräckligt bra<br />
metod för att inte numeriska instabiliteter skall uppstå. 6<br />
Sammanfattning: Lös normalt inte normalekvationerna, åtminstone inte för stora problem. Använd<br />
istället MatLabs inbyggda ekvationslösare, eller konsultera en lärobok i numeriska metoder.<br />
6 En annan mer stabil lösning, som inte bygger på MatLab, är att faktorisera matrisen A i en s.k. singulärvärdesuppdelning<br />
A = UΣV t (se Bar<strong>av</strong>dish).<br />
5
Uppgift<br />
Du har just påbörjat ditt första jobb som civilingenjör, <strong>och</strong> får till uppgift att <strong>av</strong>rapportera till<br />
företagets ledningsgrupp hur pass effektiv Hammingkodning är. Ledningen är primärt intresserad<br />
<strong>av</strong> resultatet, men kräver att det är dokumenterat i god vetenskaplig ordning.<br />
Ni skall ta fram funktionssamband som visar hur effektiv Hammingkoden är <strong>och</strong> illustrera dessa<br />
med grafer. Välj själva den Hammingkod ni anser vara mest intressant att studera, <strong>och</strong> motivera<br />
valet. På x-axeln skall anges brusnivå för överföringskanalen <strong>och</strong> på y-axeln hur stor andel <strong>av</strong> de<br />
överförda tecknen som fortfarande är felaktiga även efter rättning enligt Hamming. 7 Intervallet på<br />
x-axeln anpassas rimligen till den del som kan vara intressant i sammanhanget. Även andra grafer<br />
kan visa sig vara fördelaktiga att inkludera, t.ex. hur stor andel fel som uppstår utan rättning.<br />
De approximativa funktionssamband ni tar fram för de aktuella graferna skall vara baserade på<br />
minstakvadratanpassingar.<br />
Redovisning<br />
Ni skall redovisa arbetet på max två A4-sidor, samt muntligt, enligt kursinformationen. Rapporten<br />
utformas i enlighet med den lathund som finns på kurshemsidan. Vid presentationen skall<br />
ni föreställa er att ni står inför företagsledningen <strong>och</strong> redovisar vad ni kommit fram till. Till oppositionen<br />
blir ni dock studenter igen.<br />
Referenser<br />
Bar<strong>av</strong>dish Linjär algebra, TNA002, G. Bar<strong>av</strong>dish, kompendium utgivet <strong>av</strong> ITN, Linköpings universitet<br />
2007. [Främst kapitel 14.]<br />
Jönsson MATLAB-beräkningar inom teknik <strong>och</strong> naturvetenskap, andra utgåvan, P. Jönsson, Studentlitteratur,<br />
Lund 2006. [Främst kapitel 12.1 – 12.5.]<br />
Poole Linear algebra, D. Poole, Brooks/Cole, 2003. [Tidigare kurslitteratur i kursen i linjär algebra;<br />
innehåller några (bra) sidor om Hamming<strong>koder</strong> samt en hel del om Z 2 .]<br />
7 Med brusnivå <strong>av</strong>ses sannolikheten att en bit byter värde under överföringen. Praktiskt kan man låta en slumptalsgenerator<br />
alstra lika många tal som överföringen har bitar. Dessa tal skall vara likformigt fördelade mellan noll<br />
<strong>och</strong> ett, <strong>och</strong> om värdet understiger brusnivån byter man tecken på motsvarande bit. För enkelhets skull kan ni här<br />
använda det något orealistiska antagandet att bruset, dvs slumptalen, är oberoende <strong>av</strong> varandra.<br />
6