Optimala koder. Övre gräns för optimala koder. Gränser. Övre gräns för optimala koder, forts.

Relevanta dokument
Optimala koder. Det existerar förstås flera koder som har samma kodordsmedellängd. Enklaste fallet är att bara byta 0:or mot 1:or.

Källkodning. Egenskaper hos koder. Några exempel

Aritmetisk kodning. F (0) = 0 Exempel: A = {1, 2, 3} k=1. Källkodning fö 5 p.1/12

Krafts olikhet. En momentant avkodbar kod (prefixkod) med kodordslängderna l 1,...,l N existerar om och endast om. 2 l i. 1 i=1

Shannon-Fano-Elias-kodning

Adaptiv aritmetisk kodning

Skurlängdskodning. aaaabbbbbbbccbbbbaaaa. Man beskriver alltså sekvensen med ett annat alfabet än det ursprungliga.

Ordbokskodning. Enkel variant av kodning med variabelt antal insymboler och fixlängds kodord. (Jfr tunstallkodning)

Exempel, minnesfri binär källa. Ordbokskodning. Lempel-Zivkodning. Lempel-Zivkodning, forts.

TSBK04 Datakompression. Övningsuppgifter

TSBK04 Datakompression Övningsuppgifter

FLAC (Free Lossless Audio Coding)

Burrows-Wheelers transform

Träd och koder. Anders Björner KTH

Övning 6 - Tillämpad datalogi 2012

Föreläsning 7. Felrättande koder

En generell prediktiv kodare utnyttjar signalens utseende N steg tillbaka i tiden för kodningen, dvs vi kodar efter den betingade fördelningen

Linjär prediktion. Prediktiv kodning. Linjär prediktion. Prediktiv kodare och avkodare

Lab 3 Kodningsmetoder

Föreläsning 5: Grafer Del 1

Kompression av ljud och bild

Kurslitteratur. Kompression av ljud och bild. Föreläsningar, preliminärt program. Laborationer

BINÄRA TRÄD. (X = pekarvärdet NULL): struct int_bt_node *pivot, *ny; X X X 12 X X 12 X X -3 X X

Detta ger oss att kanalkapaciteten för den ursprungliga kanalen är C = q 1 C 1 + q 2 C C =1 h ( ) 0.30.

Föreläsning 4 Datastrukturer (DAT037)

Datakompression. Harald Nautsch ISY Bildkodning, Linköpings universitet.

Kursinnehåll. Datakompression. Föreläsningar, preliminärt program. Examination

Kurslitteratur. Kompression av ljud och bild. Föreläsningar, preliminärt program. Laborationer. Khalid Sayood, Introduction to Data Compression

Tentamen, Algoritmer och datastrukturer

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 8 Erik Nilsson, Institutionen för Datavetenskap, LiU

Informationsteknologi Tom Smedsaas 19 augusti 2016

Datastrukturer. föreläsning 10. Maps 1

Speciell användning av heltalsvariabler. Heltalsprogrammering. Antingen-eller-villkor: Exempel. Speciell användning av heltalsvariabler

Algoritmer, datastrukturer och komplexitet

Föreläsning 9 Innehåll

Digital- och datorteknik

Föreläsning 5: Dynamisk programmering

Digital- och datorteknik

Föreläsning 4 Datastrukturer (DAT037)

Datastrukturer, algoritmer och programkonstruktion (DVA104, HT 2014) Föreläsning 5

Innehåll. Föreläsning 12. Binärt sökträd. Binära sökträd. Flervägs sökträd. Balanserade binära sökträd. Sökträd Sökning. Sökning och Sökträd

Ett generellt träd är. Antingen det tomma trädet, eller en rekursiv struktur: rot /. \ /... \ t1... tn

Föreläsningsanteckningar F6

Algoritmer, datastrukturer och komplexitet

Övning 6. Komprimering, kryptering, dokumentering & testning

DD1320 Tillämpad datalogi. Lösning (skiss) till tenta 20 okt 2011

Uppgift 1 ( Betyg 3 uppgift )

Datastrukturer i kursen. Föreläsning 8 Innehåll. Träd rekursiv definition. Träd

Lösning till tentamensskrivning i Diskret Matematik för CINTE, CL2 och Media 1, SF1610 och 5B1118, onsdagen den 17 augusti 2011, kl

Inlämningsuppgiften. Föreläsning 9 Innehåll. Träd. Datastrukturer i kursen

Föreläsning 4: Giriga algoritmer. Giriga algoritmer

Grundläggande logik och modellteori

Inom datalogin brukar man använda träd för att beskriva vissa typer av problem. Om man begränsar sig till träd där varje nod förgrenar sig högst två

TSBK35 Kompression av ljud och bild

Informationsteori. Repetition Kanalkapaciteten C. Repetition Källkodhastigheten R 2. Repetition Kanalkodhastigheten R 1. Huffmans algoritm: D-när kod

Föreläsninsanteckningar till föreläsning 3: Entropi

Fredag 10 juni 2016 kl 8 12

Rekursiva algoritmer sortering sökning mönstermatchning

Innehåll. Föreläsning 11. Organisation av Trie. Trie Ytterligare en variant av träd. Vi har tidigare sett: Informell specifikation

Linjärt minne. Sammanhängande minne är ej flexibelt. Effektivt

Föreläsning 13. Dynamisk programmering

Lösningar Datastrukturer TDA

Tentamen Datastrukturer (DAT036/DAT037/DIT960)

Programmering II (ID1019)

Digital- och datorteknik

Föreläsning Datastrukturer (DAT037)

Optimeringslära Kaj Holmberg

Föreläsning 5: Giriga algoritmer. Kruskals och Prims algoritmer

Kodning med distorsion

Datastrukturer och algoritmer. Innehåll. Trie. Informell specifikation. Organisation av Trie. Föreläsning 13 Trie och Sökträd.

International Olympiad in Informatics July 2011, Pattaya City, Thailand Tävlingsuppgifter Dag 2 Svenska 1.3. Papegojor

Turingmaskiner och oavgörbarhet. Turingmaskinen. Den maximalt förenklade modell för beräkning vi kommer använda är turingmaskinen.

Föreläsning 9: Turingmaskiner och oavgörbarhet. Turingmaskinen. Den maximalt förenklade modell för beräkning vi kommer använda är turingmaskinen.

Tildatenta Lösningsskiss

DIGITAL KOMMUNIKATION

Föreläsning 9 Datastrukturer (DAT037)

Kontinuitet och gränsvärden

Problem: BOW Bowling. Regler för Bowling. swedish. BOI 2015, dag 1. Tillgängligt minne: 256 MB

Trädstrukturer och grafer

Instruktioner - Datortentamen TDDD73 Funktionell och imperativ programmering i Python

Turingmaskinen - en abstrakt datormodell

Introduktion till algoritmer - Lektion 4 Matematikgymnasiet, Läsåret Lektion 4

Föreläsning 5: Giriga algoritmer. Kruskals och Prims algoritmer

Datastrukturer. föreläsning 10. Maps 1

Programkonstruktion och. Datastrukturer

Teoretisk del. Facit Tentamen TDDC (6)

TDDI16 Datastrukturer och algoritmer. Prioritetsköer, heapar, Union/Find

Dekomposition och dynamisk programmering

Föreläsning Datastrukturer (DAT036)

Upplägg. Binära träd. Träd. Binära träd. Binära träd. Antal löv på ett träd. Binära träd (9) Binära sökträd (10.1)

Prov i DAT 312: Algoritmer och datastrukturer för systemvetare

Träd Hierarkiska strukturer

Föreläsning Datastrukturer (DAT036)

Självbalanserande träd AVL-träd. Koffman & Wolfgang kapitel 9, avsnitt 1 2

13 Prioritetsköer, heapar

TDDC74 Programmering, abstraktion och modellering DUGGA 2

Tentamensskrivning i Diskret Matematik för CINTE och CMETE, SF1610, onsdagen den 20 augusti 2014, kl

Automatateori (2) Idag: Sammanhangsfria språk. Dessa kan uttryckas med Grammatik PDA

Transkript:

Datakompression fö 3 p.3 Datakompression fö 3 p.4 Optimala koder Övre gräns för optimala koder En prefixkod kallas optimal om det inte existerar någon annan kod (för samma alfabet och sannolikhetsfördelning) som har lägre kodordsmedellängd. Det existerar förstås flera koder som har samma kodordsmedellängd. Enklaste fallet är att bara byta 0:or mot 1:or. Även koder med olika uppsättning kodordslängder kan ha samma kodordsmedellängd. Givet att vi kodar en symbol i taget, så uppfyller en optimal kod l <H(Xj )+1 Låt l i = log p i = log p i + s i där 0 s i < 1 2 l i = = 2 log p i s i p i 2 s i p i = 1 Krafts olikhet är uppfylld, alltså existerar en trädkod med de givna kodordslängderna Datakompression fö 3 p.1 Övre gräns för optimala koder, forts. Gränser Datakompression fö 3 p.2 Vad har denna kod för kodordsmedellängd? L l = p i l i = = < p i ( log p i + s i ) p i log p i + p i log p i + p i s i p i = H(X j )+1 En optimal kod kan ju inte vara sämre än denna kod, då vore det ingen optimal kod. Alltså gäller även för en optimal kod att l <H(X j )+1. OBS: Om p i =2 k i, i för heltal k i, så kan vi konstruera en kod med l = H(Xj ). Vi har alltså visat att för en minnesfri källa där vi kodar en symbol i taget existerar det prefixkoder som uppfyller H(X j ) R = l <H(X j )+1 Resultatet kan enkelt generaliseras till källor med minne där vi kodar n symboler i taget. Vi får då H(X j X j+1...x j+n 1 ) l <H(X j X j+1...x j+n 1 )+1 R = l n 1 n H(X jx j+1...x j+n 1 ) R< 1 n H(X jx j+1...x j+n 1 )+ 1 n Genom att koda många symboler med varje kodord kan vi alltså komma godtyckligt nära entropigränsen, både då källan har minne och då den är minnesfri.

Datakompression fö 3 p.7 Datakompression fö 3 p.8 Krav på optimala koder Krav på optimala koder, forts. Antag att vi kodar en symbol från alfabetet A = {a 1,...,a L } med varje kodord, och att kodordslängderna är l 1,...,l L. Nödvändiga villkor för att koden ska vara optimal är 1. Om p(a i ) p(a j ) så måste l i l j. 2. De två minst sannolika symbolerna har kodord med samma längd. 3. I kodträdet för en optimal kod måste det gå ut två grenar från varje inre nod. 4. Antag att vi ändrar en inre nod i trädet till ett löv genom att slå ihop all löv som utgår ifrån det till en enda symbol i ett reducerat alfabet. Om originalträdet var optimalt för originalalfabetet så är det reducerade trädet optimalt för det reducerade alfabetet. 1. Om inte kunde vi bara byta kodord mellan de två symbolerna och få en kod med lägre kodordsmedellängd. 2. Antag att vi har en prefixkod där de två minst sannolika symbolerna har olika kodordslängd. Vi kan skapa en ny kod genom att ta bort de sista bitarna i det längre kodordet så att de två kodorden är lika långa. Den nya kodorden är fortfarande en prefixkod, eftersom det enligt 1 inte finns några kodord som är längre. Den nya koden har en lägre kodordsmedellängd, alltså är den ursprungliga koden inte optimal. 3. Antag att en prefixkod har en inre nod med bara en gren. Vi kan då ta bort den grenen och flytta upp delträdet därunder ett steg. Denna nya kod är fortfarande en prefixkod, och den har en lägre kodordsmedellängd. Alltså kan den ursprungliga koden inte vara optimal. 4. Om den reducerade koden inte var optimal skulle vi kunna konstruera en ny kod för det reducerade alfabetet och sen expandera den reducerade symbolen igen så att vi får en ny kod med lägre kodordsmedellängd än originalkoden. Huffmankodning Datakompression fö 3 p.5 Huffmankoder, forts. Datakompression fö 3 p.6 Enkel metod för att konstruera optimala trädkoder. Börja med enstaka symboler som löv. Slå i varje steg ihop de två minst sannolika noderna till en inre nod. Sannolikheten för den nya noden är summan av de två ursprungliga noderna. Om det finns fler noder med samma sannolikhet att välja mellan spelar det ingen roll vilka vi väljer. När vi konstruerat hela kodträdet, skapar vi kodorden genom att sätta 0 resp. 1 på de utgående grenarna i varje nod. Vilken gren som sätts till 0 resp. 1 spelar ingen roll. Antag att den mest sannolika symbolen för en minnesfri källa X k har sannolikheten p max. Man kan visa att kodordsmedellängden för en en huffmankod uppfyller l < { Jämför med vår tidigare övre gräns H(X k )+p max ; p max 0.5 H(X k )+p max +0.086 ; p max < 0.5 l <H(Xk )+1

Datakompression fö 3 p.11 Datakompression fö 3 p.12 Utvidgade huffmankoder Sidoinformation För små alfabet med skeva fördelningar, eller för källor med minne, kan en huffmankod vara ganska långt från entropigränsen. Detta kan ofta förbättras om man utvidgar källan, dvs man kodar fler symboler i taget med varje kodord. Den maximala redundansen (skillnanden mellan datatakten och entropin) minskar då som 1 n när vi kodar n symboler i taget. Notera att utvidgning inte garanterar att datatakten minskar, bara att den övre gränsen kommer närmare den undre gränsen. Normalt måste man skicka över huffmankodens utseende till mottagaren, vilket kommer att kräva extra data (sidoinformation). Vi har hittills antagit att vi kodar en så lång sekvens från källan att den extra kostnaden för huffmanträdet är försumbar. I praktiska tillämpningar är dock detta inte alltid fallet. Rättfram metod: För varje symbol i alfabetet skickas först kodordslängden och sedan själva kodordet. Med ett alfabet av storlek L och med maximal kodordslängd l max går det då åt L log l max + i l i extra bitar. Smartare metod: Ta bara fram kodordslängder l i med huffmanalgoritmen. Givet dessa längder konstrueras en trädkod. Avkodaren kan använda samma metod för att konstruera en trädkod, så vi behöver bara skicka över kodordslängden för varje symbol, vilket kräver L log l max extra bitar. Datakompression fö 3 p.9 Datakompression fö 3 p.10 När man konstruerar kodträd utgående från kodordslängder så måste man alltid tilldela kodorden i stigande längdordning. Typiskt så tilldelar man kodorden i lexikografisk ordning, så att det första kodordet består av bara nollor. Betrakta ett huffmanträd där kodorden tilldelats enligt denna princip. T.ex. om vi har fyra symboler och kodordslängderna 1, 2, 3 och 3 så blir kodorden 0, 10, 110, 111 vilket motsvarar trädet om vi låter 0-grenarna gå åt vänster och 1-grenarna åt höger. Om vi betecknar varje nod med vägen dit från roten 1 0 11 10 110 111 eller, om vi skriver de binära talen decimalt 1 0 3 2 6 7

Datakompression fö 3 p.15 Datakompression fö 3 p.16 Att gå ett steg till höger i trädet på samma nivå ger att värdet på noden ökar med ett. Att ta ett steg neråt längs 0-grenen dubblar värdet. En algoritm som delar ut kodord givet kodordslängder kan beskrivs så här: Fördela kodorden i stigande längdordning. Vi börjar med att ge det kortaste kodordet värdet 0. Vi lägger oss alltså längst till vänster på det djup i trädet som motsvarar kodordslängden. För varje nytt kodord tar vi ett steg till höger på samma nivå i trädet, dvs vi ökar värdet med 1. Om det nya kodordet har samma längd som det föregående så är kodordet det nya värdet. Om inte, så går vi neråt längs 0-grenen tills vi kommer till rätt djup. Varje steg neråt i trädet motsvaras av att vi multiplicerar värdet med 2. Repetera tills vi tagit hand om alla kodord. I pseudokod, givet sorterade kodordslängder length[ ] = {l 0 l 1 l 2... l L 1 } 1. i=0, c=0, ll=length[0] 2. code[i]=c 3. i=i+1, c=c+1 4. if i==l goto 8 5. if length[i]==ll goto 2 6. c=c*2, ll=ll+1 7. if length[i]==ll goto 2 else goto 6 8. done Kodordet för k är alltså code[k] skrivet som ett binärt tal med length[k] bitar. Observera att algoritmen utgår från sorterade längder, man måste också hålla reda på vilka symboler som kodorden motsvarar. Adaptiv huffmankodning Datakompression fö 3 p.13 Adaptiv huffmankodning, forts. Datakompression fö 3 p.14 Om vi vill koda en sekvens från en okänd källa med huffmankodning, måste vi känna till sannolikheterna för de olika symbolerna. Rättframmast är då att vi gör två pass över sekvensen. Först beräknar vi statistik på de olika symbolerna och sen använder vi de sannolikheterna för att koda källan. Istället skulle vi vilja göra allt i ett pass. Dessutom skulle vi vilja ha en metod som automatiskt anpassar sig om statistiken för källan ändrar sig under tiden. Enkel metod: 1. Börja med ett maximalt platt kodträd. 2. Koda N symboler från källan och beräkna samtidigt statistik, dvs räkna hur många gånger varje symbol uppträder. Bygg ett nytt huffmanträd med hjälp av de nya skattade sannolikheterna. 3. Repetera från 2. Ingen sidoinformation om trädets utseende måste skickas, eftersom avkodaren har tillgång till samma data som kodaren. Ju mindre N väljs, ju snabbare anpassar sig källan till ändrad statistik, å andra sidan måste vi konstruera om huffmanträdet mycket oftare vilket tar tid.

Adaptiv huffmankodning, forts Adaptiv huffmankodning, forts Smartare metod: Justera kodträdet efter varje kodad symbol. Vi behöver hålla reda på lite extra information i varje nod i trädet. Ett binärt träd med L löv har 2L 1 noder. Ge varje nod ett nummer mellan 1 och 2L 1. Varje nod har en vikt. För ett löv (yttre nod) är vikten antalet gånger den motsvarande symbolen har uppträtt (jfr. sannolikhet). För en inre nod är vikten summan av barnens vikter. Om nod j har vikten w j så ska det gälla att w 1 w 2... w 2L 1 Noder med nummer 2j 1 och 2j ska ha samma förälder och föräldern ska ha högre nummer än barnen. Träd med dessa egenskaper är huffmanträd. Börja med ett maximalt platt kodträd (motsvarande en fixlängdskod om L =2 k ). Vikten i varje löv sätts till 1, och vikten i varje inre nod sätts till summan av barnens vikter. Numrera noderna så att kraven uppfylls. För varje symbol som ska kodas: 1. Skicka kodordet motsvarande symbolen. 2. Gå till symbolens motsvarande nod. 3. Betrakta alla noder som har samma vikt som den nuvarande noden. Om den nuvarande noden inte är den nod med högst nummer byter vi plats på (dvs flyttar vikt, pekare till barnen och eventuell symbol) den nuvarande noden och den med högst nummer. 4. Öka den nuvarande nodens vikt med 1. 5. Om vi står i rotnoden är vi klara, annars går vi till nuvarande nodens förälder och repeterar från punkt 3. Adaptiv huffmankodning, forts Datakompression fö 3 p.17 Modifierad algoritm Datakompression fö 3 p.18 Eftersom uppdateringen av trädet sker efter att vi har kodat en symbol, kan vi på avkodarsidan göra samma uppdatering av trädet efter att vi avkodat en symbol. Ingen sidoinformation om trädet behöver skickas. En variant är att inte starta med ett fullt träd. Istället inför man en extra symbol (NYT, Not Yet Transmitted) och startar med ett träd som bara innehåller den symbolen, med vikt 0. När man kodar en symbol som ännu inte skickats kodas den med kodordet för NYT, följt av ett fixlängdskodord för den nya symbolen. Den gamla NYT-noden splittras därefter upp i två grenar, en för NYT-symbolen och en för den nya symbolen. NYT-noden behåller vikten 0, den nya symbolnoden får vikten 1. Om den nya symbolen är den sista ännu ej kodade symbolen ur alfabetet behöver vi inte splittra, utan ersätter bara NYT med den nya symbolen. Datakompression fö 3 p.19 1. Om symbolen inte kodats tidigare, skicka kodord för NYT följt av fixlängdskodord för den nya symbolen, annars skickas kodordet motsvarande symbolen. 2. Om vi kodade en NYT så splittras NYT-noden i två nya löv, en för NYT med vikt 0 och en för den nya symbolen med vikt 1. Nodnumren för de nya noderna ska vara de två största oanvända numren. Om det var den sista ännu ej kodade symbolen, så behöver vi inte splittra, utan ersätter bara NYT med den nya symbolen. 3. Gå till symbolens motsvarande nod (gamla NYT-noden om vi splittrade). 4. Betrakta alla noder som har samma vikt som den nuvarande noden, utom dess förälder. Om den nuvarande noden inte är den nod med högst nummer byter vi plats på (dvs flyttar vikt, pekare till barnen och eventuell symbol) den nuvarande noden och den med högst nummer. 5. Öka den nuvarande nodens vikt med 1. 6. Om vi står i rotnoden är vi klara, annars går vi till nuvarande nodens förälder och repeterar från punkt 4. Datakompression fö 3 p.20

Glömskefaktor Om man vill att kodningen ska bero mer av de senare symbolerna än av tidigare symboler kan man använda en glömskefaktor. När vikten i rotnoden är större än N delar man vikten i alla noder med K. Om man vill behålla vikterna som heltal får man dela vikten i alla löv med K (avrunda uppåt) och sen addera ihop vikterna från barnen till föräldrarna, hela vägen till rotnoden. Beroende på hur man väljer N och K så glömmer vi tidigare värden olika snabbt, d.v.s. vi får olika snabb adaptering till ändrad statistik. Datakompression fö 3 p.21