Codage entropique à longueur variable

Transcription

Codage entropique à longueur variable
Codage entropique à longueur variable
Olivier RIOUL
ENST/COMELEC
[email protected]
1
Description d’un système de codage à longueur variable
On se donne une source discrète (données, fichier, . . . ) dont chaque symbole x prend une parmi M valeurs possibles {x1 , x2 , . . . , xM }. On appelle cela
une source M -aire X.
Une distribution de probabilité p(x) caractérise les statistiques de cette
source, on la suppose connue (ou estimée) sous la forme {p1 , p2 , . . . , pM }, où
pi est la probabilité d’occurrence du symbole xi .
Le schéma de codage est illustré par la figure suivante :
Code
Source X
- C
- Codeur
- Décodeur
- X
Le codeur code chaque symbole de source xi par un mot de code ci .
Le code est, par définition, l’ensemble des mots de codes C = {c1 , . . . , cM }.
Un code à longueur variable (VLC : Variable-Length Code) est tel
que les différents mots de code n’ont pas nécessairement la même longueur,
en bits. On note li la longueur en bits du mot de code ci . La distribution
des longueurs du code est donc {l1 , l2 , . . . , lM }.
Voici un exemple de code VLC pour M = 4 :
xi
0
1
2
3
pi li
1/2 1
1/4 2
1/8 3
1/8 3
1
ci
0
10
110
111
Le décodeur reconstruit les symboles de source à partir de la séquence
binaire des mots de codes. Le taux de codage (coding rate) R est le
nombre moyen de bits codés par symbole de source, c’est à dire
R=
M
X
pi li .
i=1
On peut interpréter, si on veut, R comme une moyenne de la longueur L
d’un mot de code (selon la loi de probabilité de X) :
R = E (L).
Pour l’exemple ci-dessus, on a
R=
1 2 3 3
+ + + = 1.75 bits/symbole.
2 4 8 8
Quoi qu’il en soit, un code est donc d’autant plus efficace en compression
que R est petit. Trouver le « meilleur » code, « optimiser » le système, c’est
donc déterminer le (ou les) code(s) qui rendent R minimal pour une source
donnée, et donc pour une distribution de probabilité {p1 , p2 , . . . , pM } fixée.
Noter que les performances des codes ne dépendent que des distributions de
longueurs.
2
Codes uniquement décodables
Le but du codage de source sans pertes est de comprimer les données
de telle façon que l’on puisse reconstruire parfaitement (sans pertes, sans
erreur) la source au destinaaire.
Pour cela, il faut que le décodage ait lieu sans ambiguïté, c’est à dire
qu’une séquence codée donnée doit être interprétable de façon unique comme
une succession (concaténation) de mots de codes déterminés. Un code permettant un tel décodage (sans ambiguïté) est qualifié d’uniquement décodable (u.d.).
Formellement, cela signifie que si on a deux séquences de mots de code
concaténés identiques :
c1 c2 · · · ck = c01 c02 · · · c0l
où les ci et c0j appartiennent au code C, alors les mots de code sont un à un
identiques :
k = l et ci = c0i , i = 1, . . . , k.
Voici quatre exemples de codes : lesquels sont u.d. ?
2
xi
0
1
2
3
code 1 code 2 code 3 code 4
0
0
10
0
0
10
00
10
1
100
11
110
1
101
110
111
Le premier code est très performant (R = 1 !) mais évidemment inutilisable, car ambigu : pour être u.d., le code doit être « inversible », c’est à dire
que les mots de code doivent être distincts. Ceci montre qu’il y a forcément
une limite inférieure sur le taux R : dans cet exemple, la valeur R = 1 n’est
pas atteignable.
Le deuxième code est bien « inversible » mais pas u.d. : par exemple, la
séquence codée C = 101010 . . . peut se décoder X = 130 . . . ou X = 301 . . ..
Un tel code est donc également inutilisable.
Le troisième code est plus intéressant : malgré les apparences, il est u.d. !
En effet, on peut imaginer un décodeur qui examine la parité du nombre
de zéros qui suit la première séquence « 11 » ; ce n’est qu’après avoir re-lu
un « 1 » qu’il peut correctement découper la séquence codée et fournir les
symboles de source. Cet exemple montre que certains codes u.d. peuvent
nécessiter une implantation complexe du décodeur, qui doit lire la séquence
codée binaire suffisamment loin à l’avance pour décoder un symbole de source.
3
Codes instantanés et condition du préfixe
Le quatrième code donné ci-dessus est, par contre, très simple à décoder ;
De tels codes sont appelés codes instantanés, car le décodeur n’a besoin de
lire que les li premiers bits d’une séquence codée pour pouvoir l’interpréter
« instantanément » et de manière unique comme étant le mot de code ci ,
représentant le symbole xi .
Un code instantané est caractérisé par la condition du préfixe : Aucun mot de code n’est le préfixe d’un autre mot de code
(c’est à dire aucun ci ne débute un cj , j 6= i).
Preuve: Il est facile de démontrer que la condition du préfixe caractérise bien
un code instantané : cette condition est d’abord clairement suffisante, sinon
un ci débuterait un autre cj et il y aurait ambiguïté lorsque le décodeur lit
ci , de sorte qu’il ne pourrait pas conclure instantanément. Réciproquement,
avec la condition du préfixe le décodage est clairement instantané, car dès
qu’un mot de code ci est lu, il peut être décodé sans ambiguïté.
Un code instantané est aussi appelé code à préfixe (prefix code) dans
la littérature. Pour résumer le vocabulaire vu jusqu’ici on a les ensembles
3
emboîtés suivants :
{codes VLC} ⊃ {codes inversibles} ⊃ {codes u.d.} ⊃ {codes instantanés}.
4
Inégalité de Kraft-McMillan
Pour trouver le meilleur code pour une source donnée, il faut minimiser le
taux R sous la contrainte que le code soit u.d. Afin de réaliser cette optimisation, on caractérise d’abord le fait qu’un code soit u.d. sur la distribution
des longueurs :
[McMillan, 1956] Tout code u.d. vérifie l’inégalité :
M
X
2−li 6 1
i=1
appelée inégalité de Kraft-McMillan.
Preuve: Pour un code u.d., toute séquence de l bits peut se décomposer
d’au plus une façon comme concaténation de mots de codes ci1 ci2 · · · cik où
li1 + li2 + · · · + lik = l. Cela vient directement de la définition d’un code u.d.
Le nombre total Nl (k) de concaténations possibles de k mots de codes
donnant une séquence codée de longueur totale l bits ne peut donc pas dépasser le nombre total de séquences de l bits, qui est 2l . (Sinon, il y aurait
forcément ambiguïté.) On a donc l’inégalité : Nl (k) 6 2l .
Mais par ailleurs, si on développe la puissance kième (produit de k facteurs identiques)
M
X
X
xli1 +li2 +···+lik
(
xli )k =
i=1
i1 ,i2 ,...,ik
et si on regroupe les termes de même puissance l = li1 + li2 + · · · + lik on
trouve précisément Nl (k) puissances xl pour chaque l. Ainsi :
M
X
X
(
xli )k =
Nl (k)xl
i=1
l
La somme au second membre va de l = klmin à l = klmax où lmin et lmax
désignent les longueurs minimale et maximale d’un mot de code.
On conclut facilement en faisant x = 1/2 et k → ∞ : on voit par exemple
que
M
X
p
2−li 6 k k(lmax − lmin ) + 1 → 1
i=1
quand k → ∞.
4
5
Algorithme de Kraft
Pour l’instant l’inégalité de Kraft-McMillan n’est qu’une condition nécessaire pour qu’un code soit u.d. Mais il y a une réciproque :
[Kraft, 1949] Si l’inégalité de Kraft-McMillan est vérifiée,
alors il existe un code u.d., et même instantané, qui admette
{l1 , l2 , . . . , lM } comme distribution de longueurs.
Voici une preuve dont l’intérêt est de fournir un algorithme simple qui
donne un code instantané {c1 , . . . , cM } à partir d’une distribution de longueurs {l1 , l2 , . . . , lM } vérifiant l’inégalité de Kraft-McMillan. (Il y a d’autres
preuves classiques, qu’on trouve dans la littérature, qui utilisent la notion
d’arbre binaire.)
Preuve: On se donne une distribution de longueurs l1 6 l2 6 . . . 6 lM
vérifiant l’inégalité de Kraft-McMillan1 . A chaque mot de code ci (à trouver)
on associe le nombre c̄i = 0, ci ∈ [0, 1[ dont les décimales de l’écriture en base
2 est formée des bits de ci . On note Ii l’intervalle Ii = [c̄i ; c¯i + 2−li [.
Par exemple, ci = 010 donne c̄i = 0, 010 = 14 . et Ii = [0, 010; 0, 011[= [ 41 ; 38 [
est l’ensemble des nombres de [0; 1[ dont les décimales en base 2 commencent
par ci .
Clairement, ci détermine l’intervalle Ii , et réciproquement : il suffit de
tronquer le développement binaire de la limite gauche de l’intervalle (de longueur Li ) à log2 L1i bits pour retrouver ci .
On peut alors traduire le fait qu’un code soit instantané sur les intervalles :
Aucun ci ne débute un cj si et seulement si c̄j 6∈ Ii . Autrement dit le code
est instantané si et seulement si les Ii sont des intervalles disjoints.
L’inégalité de Kraft-McMillan revient précisément à dire que la somme
des longueurs des Ii est 6 1. S’ils sont disjoints, on peut donc les mettre
bout-à-bout en restant dans le segment [0, 1[.
On en déduit facilement un algorithme de construction du code
instantané : On met bout-à-bout les intervalles Ii , classés par longueurs
décroissantes (li croissantes) dans le segment [0, 1[ en partant de la gauche :
I1
I2
I3
···
-
0.0
0.10
1
0.110
0.111
On peut toujours se ramener à un tel ordre croissant, quitte à permuter les symboles
dans l’alphabet de la source.
5
On commence donc par c̄1 = 0.0 . . . 0, et on pose c̄i+1 = extrémité droite
de Ii à chaque étape. Cela revient, pour chaque étape, à calculer ci + 1
(addition binaire) puis à compléter avec des zéros si nécessaire pour obtenir
ci+1 de longueur li+1 > li . Comme les intervalles sont disjoints, le code est
bien instantané.
Un exemple vaut mieux qu’un grand discours :
li
1
2
3
5
5
5
6
6
code
0
10
110
11100
11101
11110
111110
111111
Noter qu’avec cet algorithme on détecte automatiquement si si les li ne
vérifient pas l’inégalité de Kraft-McMillan : on « dépasse » alors l’extrémité
droite du segment [0, 1[, et on ne peut plus continuer. Par exemple :
li
1
2
3
4
5
5
6
code
0
10
110
1110
11110
11111
Erreur
1 1 1
1
1
1
1
+ + +
+
+
+
>1
2 4 8 16 32 32 64
Une conséquence importante de la caractérisation par l’inégalité de KraftMcMillan est que tout code u.d. peut être remplacé par un code instantané
de même distribution de longueurs et donc de même taux. On peut donc
limiter la recherche du meilleur code à l’ensemble des codes instantanés. C’est un soulagement : du coup, on pourra toujours choisir un code
optimal pour lequel le décodage est instantané, donc très simple à implanter.
6
6
Recherche du code Optimal
D’après ce qui précède, pour trouver le meilleur code pour une source
donnée, il suffit de minimiser le taux R sur la distribution de longueurs
uniquement, avec la contrainte donnée par l’inégalité de Kraft-McMillan :
X
X
min{R =
pi li |
2−li 6 1}
i
i
On reconnait un problème classique qui se résout par la méthode des multiplicateurs de Lagrange.
Appliquons (brutalement) la méthode du Lagrangien ; celui-ci s’écrit
X
X
L=
pi li − λ
2−li
i
i
où λ est le multiplicateur de Lagrange. On doit annuler les dérivées
∂L
= pi − λ0 2−li = 0
∂li
où λ0 est toujours constant (indépendant de i). Ainsi l’optimum est atteint
les pi et 2−li sont proportionnels, pour une contrainte saturée
P −llorsque
i
= 1. La constante de proportionnalité vaut forcément λ0 = 1 ; on
i2
trouve donc que R est minimisé lorsque
li = log2
1
,
pi
auquel cas on découvre avec stupéfaction que le taux minimal est l’entropie
de la source :
M
X
1
H=
pi log2
pi
i=1
Seulement voilà, c’était trop beau : ce qu’on vient de faire est faux,
puisque ce résultat ne donne pas, en général, des longueurs li entières ! Il
fallait tenir compte de cette contrainte supplémentaire, et la méthode du
Lagrangien était donc inadaptée.
7
Codes de Fano-Shannon
On peut quand même exploiter ce qu’on vient de faire ; d’abord, l’entropie
est atteinte dans le cas exceptionnel où les pi sont des puissances négatives
de 2 (car alors li = log2 p1i est bien entier). Par exemple, le code
7
pi li
1/2 1
1/4 2
1/8 3
1/8 3
ci
0
10
110
111
est « optimalement optimal », puisqu’ici R = H. En général, un code, même
optimal, n’atteint pas l’entropie à cause de la contrainte supplémentaire des
longueurs entières ; son taux est forcément plus grand. Cela montre que le
taux d’un code u.d. est toujours limité inférieurement par l’entropie :
R>H .
On comprend maintenant pourquoi la technique du codage sans pertes est
aussi appelée codage entropique : on cherche à s’approcher l’entropie qui
représente une borne inférieure sur le taux.
Sans chercher à optimiser rigoureusement, peut-on trouver des codes dont
les taux ne soient pas trop éloignés de l’entropie ? Il faut pour cela obtenir
les longueurs entières ; une façon de faire est de prendre2
li = dlog2
1
e
pi
On vérifie immédiatement qu’avec ce choix, l’inégalité de Kraft-McMillan
est vérifiée (puisque qu’on a pris soin d’arrondir vers le haut, de sorte que
2−li 6 pi ).
On obtient la famille des codes de Fano-Shannon (1948) (qui vérifient
bien l’inégalité de Kraft-McMillan) et pour lesquels on trouve
H 6 R 6 H + 1.
Preuve: Il suffit de prouver la deuxième inégalité :
X
X
X
1
1
R=
pi dlog2 e 6
pi log2
+1 =H +
pi = H + 1.
p
p
i
i
i
i
i
d’où l’encadrement annoncé.
On est donc au pire à un bit près de l’entropie. On verra ci-dessous qu’on
ne peut pas améliorer cette distance à l’entropie pour des codes « scalaires ».
En fait, on a présenté ici ces codes de Fano-Shannon que par souci pédagogique ; leur intérêt est surtout historique, depuis que Huffman a proposé
un algorithme pour trouver les codes VLC optimaux, qui fait l’objet de la
section suivante.
2
dxe désigne le plus petit entier > x. On a x 6 dxe 6 x + 1.
8
8
Codes de Huffman
Comme on s’en doute par leur définition, on constate en pratique que les
codes de Fano-Shannon sont rarement optimaux. Pour trouver les meilleurs
codes il faut se résoudre à résoudre (sic) complètement le problème de la
minimisation de R, en tenant compte du fait que les longueurs li doivent être
entières.
Une résolution complète du problème de recherche du meilleur code est
donnée par algorithme itératif sur M appelé algorithme de Huffman
(1952). On obtient alors un code de Huffman dont le taux R est minimal
pour une source donnée (par les pi ).
Comprendre cet algorithme demande un peu de travail. D’abord quelques
préliminaires.
8.1
Préliminaires
Considérons un code VLC optimal pour une source de distribution de
probabilité3 p1 > p2 > · · · > pM . Que peut-on en dire a priori sur ce code ?
D’abord, on aura nécessairement un ordre croissant de longueurs :
l1 6 l2 6 · · · 6 lM
Preuve: En effet, si ce n’est pas le cas, disons pi > pj et li > lj , on a
pi li + pj lj > pi lj + pj li et on trouverait un meilleur code en échangeant ci et
cj .
Ainsi les symboles de source les plus probables doivent être codés par
les mots de code les plus courts ; c’est intuitivement évident, ce principe est
connu depuis Morse4 .
Autre chose intuitivement évidente (déjà utilisée ci-dessus) :
L’inégalité de Kraft McMillan est nécessairement une égalité
pour un code optimal.
Preuve: Sinon, on aurait
X
2−li < 1.
i
Mais cette somme est un multiple entier de 2−lM car lM est la plus grande
longueur. On a donc K2−lM < 1, K < 2lM , donc K 6 2lM − 1 puisque K est
3
On peut toujours se ramener à un tel ordre décroissant, quitte à permuter les symboles
dans l’alphabet de la source.
4
Le code Morse, vous connaissez ? : · − − − · · − − · · · la lettre la plus courante (le « e »)
est codée par le mot le plus court (« · »)).
9
entier. Autrement dit
X
2−li 6 1 − 2−lM .
i
En conséquence, si on remplace lM par lM − 1, l’inégalité de Kraft-McMillan
reste satisfaite. Ainsi on trouverait de cette façon un code u.d. meilleur. On déduit du raisonnement de la question précédente qu’à l’optimum,
K est un entier pair, donc
lM −1 = lM .
Avec l’algorithme de Kraft ci-dessus, on s’aperçoit donc qu’on peut toujours
se ramener au cas où les deux mots de codes cM −1 et cM ne diffèrent que par
le dernier bit.
8.2
Réduction de Huffman
Le principe de cette « réduction » est le suivant : On considère une source
M -aire de distribution de probabilité (par ordre décroissant)
p1 > p2 > · · · > pM .
La réduction de Huffman consiste à considérer la source (M − 1)-aire,
dite « réduite », de distribution de probabilité
p1 , p2 , · · · , pM −2 , p0M −1 = pM −1 + pM .
Autrement dit, on « combine » les deux symboles les moins probables. Noter
qu’après cette opération, la dernière probabilité p0M −1 n’est plus forcément à
sa place dans l’ordre décroissant.
Notons CM = {c1 , . . . , cM −1 , cM } le code optimal cherché (« à l’ordre
M »). D’après ci-dessus, on peut supposer que cM −1 et cM ne diffèrent que
par le dernier bit ; écrivons donc cM −1 = [c0M −1 0] et cM = [c0M −1 1]. En termes
0
de longueurs cela donne lM = lM −1 = lM
−1 + 1.
En comparant les taux de codage de la source initiale et de la source
réduite après réduction de Huffman, on peut montrer que :
Le code CM −1 = {c1 , . . . , cM −2 , c0M −1 } est optimal pour la
source réduite.
10
Preuve: En effet, son taux est
RM −1 =
=
M
−2
X
i=1
M
−2
X
0
pi li + p0M −1 lM
−1
pi li + (pM −1 + pM )(l{M −1 ou M } − 1)
i=1
= RM − (pM −1 + pM )
où RM est le taux du code optimal CM . Le terme pM −1 + pM est constant
(on optimise pour une source donnée !), donc RM −1 est bien minimal puisque
RM l’est.
La réduction de Huffman permet donc de réduire le problème de la recherche du code optimal à l’ordre M à celui à l’ordre M − 1. En continuant
ainsi, par réductions de Huffman successives, on arrive à M = 2 ; mais pour
M = 2, le code {0,1} est (trivialement) optimal (pour toute source binaire).
Attention tout de même : pour appliquer les réductions de Huffman successives, il faut prendre soin de réordonner à chaque étape les probabilités après chaque réduction de Huffman, car chaque réduction nécessite de
connaitre les deux symboles les moins probables.
8.3
Remonter le tout
Il reste à remonter l’itération pour construire de proche en proche des
codes optimaux de plus en plus grands. Il suffit, à chaque étape, de construire
le code optimal {c1 , . . . , cM −1 , cM } à partir de {c1 , . . . , cM −2 , c0M −1 }. C’est
facile, car d’après ci-dessus, on doit simplement poser :
cM −1 = [c0M −1 0] et cM = [c0M −1 1].
Bien entendu, à chaque étape, il faut prendre en compte les réarrangements
des probabilités qui ont été faits lors de la descente par réductions successives.
8.4
Exemple
Descente. La colonne de gauche donne la distribution de probabilité
initiale (M = 8). Chaque réduction crée une nouvelle colonne à droite (après
réarrangement par ordre décroissant) :
11
0.25
0.25
0.2
0.14
0.1
0.04
0.01
0.01
0.25
0.25
0.2
0.14
0.1
0.04
0.02
0.25
0.25
0.2
0.14
0.1
0.06
0.25
0.25
0.2
0.16
0.14
0.3 0.45 0.55
0.25 0.3 0.45
0.25 0.25
0.2
Remontée. De la droite vers la gauche, on construit de proche en proche
le code optimal en tenant compte des permutations faites (on peut utiliser le
même tableau si on le fait à la main) :
01
10
11
001
0000
00010
000110
000111
01
10
11
001
0000
00010
00011
01
10
11
001
0000
0001
01
10
11
000
001
00 1 0
01 00 1
10 01
11
Le taux de codage obtenu est R = 2, 54 à comparer avec l’entropie H =
2.51231997733309 . . .. On est à près d’1% de l’entropie, ce qui arrive souvent
lorsque la source n’est pas trop dissymétrique.
Noter qu’on pourrait tout aussi bien travailler sur les longueurs des mots
de code plutot que sur ces mots de code eux-mêmes, et terminer par l’algorithme de Kraft qui donne le code :
00
01
10
110
1110
11110
111110
111111
2
2
2
3
4
5
6
6
2
2
2
3
4
5
5
2
2
2
3
4
4
2
2
2
3
3
2 1 1
2 2 1
2 2
2
Bien sûr on obtient un autre code, et pourrait d’ailleurs trouver d’autres
variantes (par exemple en échangeant cM −1 et cM à certaines étapes (ou à
toutes), en échangeant 0 et 1 sur une ou plusieurs colonne(s) de la liste des
12
mots de code obtenus. . . , ou encore en permutant des mots de code de même
longueur).
Par contre, dans cet exemple, la distribution de longueurs optimale est
unique. Ce n’est pas toujours le cas, d’ailleurs ; dès qu’il y a deux ex-aequo
dans une étape de ré-arrangement des probabilités, il vient un certain arbitraire dans l’ordre des probabilités dans la phase descendante, qui peut
conduire a plusieurs possibilités pour la distribution de longueurs optimale
obtenue à la fin. Exercice : le vérifier sur des exemples. . .
9
Nécessité d’un codage vectoriel
On a vu que le taux de codage d’un code de Fano-Shannon, et donc a
fortiori du meilleur code (de Huffman) vérifie l’inégalité H 6 R 6 H + 1.
Mais peut-on améliorer cet encadrement ? Autrement dit, peut-on trouver
une famille de codes pour lesquels, quelque soit la distribution de probabilité
de la source, le taux ne s’éloigne pas de l’entropie plus qu’une quantité < 1 ?
La réponse est non, comme le montre l’exemple suivant d’un source binaire
(M = 2) :
xi
1
0
pi
ε
1−ε
li
1
1
ci
1
0
Ce code (qui consiste à ne pas coder du tout) est optimal : on ne peut
évidemment pas faire mieux (pas de longueur nulle pour une code u.d. !) :
R = 1. Mais l’entropie vaut5
H = H2 (ε) = ε log2
1
1
+ (1 − ε) log2
→0
ε
1−ε
quand ε → 0.
Ainsi il y a des sources pour lesquelles le taux optimal R approche H + 1
d’aussi près qu’on veut.
Cet exemple d’une source binaire d’entropie faible est caractéristique : on
ne peut pas en général « bien coder » (en fait on ne peut pas comprimer du
tout) ce type de source à cause de la limitation imposée dès le départ dans
notre présentation des codes VLC : à savoir qu’on code la source symbole
par symbole (c’est du codage « scalaire »).
Il est donc nécessaire, dans de pareils cas, de passer en codage vectoriel,
c’est à dire de prendre en compte, lors du codage, plusieurs symboles successifs en meme temps. En tout état de cause, une telle approche prend en
5
Quand ε est très petit (devant 1), on dit que la source X est dissymétrique. H2 (ε)
est la fonction d’entropie binaire, faible pour une source dissymétrique.
13
compte les corrélations éventuelles des symboles de source là où le codage
scalaire est impuissant à le faire ; le codage vectoriel doit donc conduire à
une performance améliorée.
Pour prendre en compte plusieurs symboles successifs en même temps,
on peut tout simplement coder la source par blocs de n symboles. C’est du
codage vectoriel (en dimension n). Cela revient à remplacer la source initiale
par une « super-source » dont les symboles sont des vecteurs de n symboles
successifs de la source initiale. Cette « super-source » s’appelle « extension
d’ordre n » de la source initiale6 .
10
Théorème de Shannon
Examinons de plus près l’intérêt de coder vectoriellement (disons en dimension n) une source X donnée. Appliquons donc un code VLC optimal
(de Huffman) à l’extension d’ordre n de la source. En fait, un code de FanoShannon fait l’affaire pour ce qui nous occupe ici. D’après ci-dessus, on a
l’encadrement :
Hn 6 Rn 6 Hn + 1
où Rn et Hn sont respectivement le taux de codage et l’entropie de la source
étendue à l’ordre n. Ces deux quantités s’expriment en bits codés par symbole
de source ; or un symbole de source est ici un « super-symbole », c’est à dire
un vecteur de n symboles de source initiale X.
Par conséquent, on revient aux mêmes unités (bits codés par symbole de
source X) en divisant par n ; le taux de codage, exprimé en bits par symbole
de source X, vaut
Rn
R=
n
alors que l’entropie
H=
Hn
n
représente l’entropie d’ordre n de la source (en bits par symbole de
source X).
L’encadrement ci-dessus devient :
H6R6H+
6
1
.
n
Le cas scalaire est naturellement un cas particulier du cas vectoriel : il suffit de poser
n = 1.
14
On voit bien que la situation du cas scalaire (n = 1) s’est améliorée, à cause
de la présence du n1 : plus on monte en dimension, plus on s’approche
de l’entropie.
On s’approche plus de l’entropie, mais de quelle entropie ? Pour le savoir,
évaluons H dans le cas simple d’une source « sans mémoire », c’est à
dire une source X dont les symboles sont indépendants dans le temps (et
identiquement distribués : suite « i.i.d. »).
L’entropie d’une source sans mémoire à l’ordre n est indépendante de n, et vaut
H=H =
M
X
i=1
pi log2
1
.
pi
Preuve: Soit X = (X1 , X2 , . . . , Xn ) un vecteur de source, et p(x1 , . . . , xn ) la
probabilité asoociée. Alors par définition
H=
1 X
1
p(x1 , . . . , xn ) log2
n x ,...,x
p(x1 , . . . , xn )
1
n
Par commodité on peut introduire une espérance :
H=
1
1
E log2
n
p(X1 , . . . , Xn )
Or la source est sans mémoire : ses symboles sont indépendants, ce qui s’écrit :
p(x1 , . . . , xn ) = p(x1 ) · · · p(xn )
de sorte que
n
Y
1
1
H = E log2
n
p(Xk )
k=1
n
1X
1
=
E log2
n k=1
p(Xk )
n
=
1X
H
n k=1
nH
n
= H.
=
D’où le résultat.
15
Ainsi, pour une source sans mémoire, en prenant une dimension n assez
grande, l’encadrement H 6 R 6 H + n1 montre qu’on s’approche aussi près
de l’entropie que l’on veut.
La situation est encore meilleure dans le cas d’un source avec mémoire ;
En effet dans le cas général on montre que :
Pour une source quelconque, l’entropie H d’ordre n vérifie l’inégalité :
H6H
Preuve: Considérons la différence H − H, interprétée comme la différence
de l’entropie avec et sans mémoire. Avec les mêmes notations que ci-dessous,
H−H =
=
n
Y
1
1
1
1
E log2
− E log2
n
p(X1 , . . . , Xn ) n
p(Xk )
k=1
p(X1 ) · · · p(Xn )
1
E log2
n
p(X1 , . . . , Xn )
Or une inégalité de concavité bien connue7 affirme que la moyenne de logarithmes est 6 au logarithme de la moyenne :
H−H 6
p(X1 ) · · · p(Xn )
1
log2 E
n
p(X1 , . . . , Xn )
En explicitant l’espérance au second membre, il vient
E
X
p(X1 ) · · · p(Xn )
p(x1 ) · · · p(xn )
=
p(x1 , . . . , xn )
p(X1 , . . . , Xn )
p(x1 , . . . , xn )
x1 ,...,xn
X
=
p(x1 ) · · · p(xn )
=
=
x1 ,...,xn
n X
Y
p(xk )
k=1 xk
n
Y
1
k=1
= 1,
d’où le résultat :
H−H 6
1
log2 1 = 0.
n
7
Mais on peut ne pas la connaître : utiliser alors à la place l’inégalité log(x) 6 x − 1
qui donne le même résultat.
16
En fait, sous des hypothèses assez faibles (stationnarité de la source) on
montre que l’entropie d’ordre n décroît, lorsque n → ∞, vers une valeur
limite appelée « entropie » (d’ordre ∞) de la source.
Ainsi, en présence de « mémoire », en particulier lorsque les symboles de
X sont corrélés en temps, l’entropie de source décroit lorsque n augmente.
A la limite, l’encadrement sur le taux montre qu’on s’approche d’aussi près
qu’on veut de l’entropie (d’ordre infini) : il suffit de coder en très grande
dimension.
On vient de démontrer le
Théorème de Shannon (1948).8 Par codage vectoriel en
dimension sufisemment élevée, le taux de codage peut être rendu
aussi proche de l’entropie de la source que l’on veut.
L’entropie apparait donc non seulement comme une « limite » inférieure sur
le taux de codage mais aussi comme une limite « théoriquement atteignable ».
Lorsque la source est « avec mémoire » on a H < H ; on en conclut que le
codage vectoriel permet de réduire le taux en prenant en compte
les corrélations des symboles de source.
Ceci dit, l’intérêt du codage vectoriel ne se limite pas à la prise en compte
des corrélations des symboles de source, puisqu’on a vu que même pour une
source sans mémoire, au augmente les performances (en s’approchant de H)
lorsque n croît (grâce au terme n1 ). Ainsi le codage vectoriel permet de
réduire le taux même pour une source sans mémoire.
Le théorème de Shannon semble (à première vue) clore définitivement la
question du codage sans pertes en proposant de réaliser un codage vectoriel
en grande dimension pour toute source. Du point de vue des performances,
c’est optimal : on s’approche d’aussi près qu’on veut de l’entropie, et de tout
façon on ne peut pas decendre en dessous.
Cependant il y a un hic : Pour coder une source M -aire en dimension n,
il faut appliquer un code VLC à la source étendue pour laquelle on a M n
symboles possibles. Le code doit donc être de taille M n , qui augmente exponentiellement avec n. Par exemple, si on veut garantir un taux s’approchant
de l’entropie à moins d’un centième de bit pour une source binaire, il faut un
code de taille
2100 = 1267650600228229401496703205376
8
C’est le « premier » théorème de Shannon pour le codage de source sans pertes ; il
existe d’autres théorèmes de Shannon pour le codage de source avec pertes, le codage de
canal, et le codage de source et de canal combinés.
17
Inutile de dire que c’est prohibitif : il faudrait stocker la table du code au
codeur et au décodeur, ou transmettre cette table du codeur au décodeur, ce
qui nécessite un « overhead » (données annexes) qui prend une part non
négligeable du débit global.
En résumé, le codage vectoriel en grande dimension est d’un grand intérêt. . . théorique. Mais en pratique, pour des questions de complexité et
de mémoire, on est amené à imaginer d’autres solutions pour prendre en
compte des symboles de source successifs. Une de ces solutions est le codage
par plages, objet de la section qui suit.
11
Codage par plages d’une source binaire
Revenons, pour fixer les idées, à la source binaire dissymétrique (d’entropie faible, ε petit) :
xi
1
0
pi
ε
1−ε
Un codage vectoriel d’une telle source est possible, mais peut conduire,
comme on l’a vu, à une taille de code trop grande. En pratique, on peut
utiliser alors des techniques de codage par plage (RLC : Run-Length
Coding) pour améliorer les performances sans trop monter en complexité.
Nous allons tenter de comprendre l’idée sur la source binaire dissymétrique
donnée en exemple.
11.1
Source équivalente des plages
Tout d’abord, la source X est transformée en une autre source L dont
les symboles sont des entiers l > 0 représentant les longueurs des plages
successives de zéros (entre deux occurences de « 1 ») de la source initiale X.
Par exemple, la réalisation d’une séquence de symboles x de la source X :
0001010000000110000010001 . . .
est représentée par la séquence les longueurs l :
3, 1, 7, 0, 5, 3, . . . .
Ainsi une plage de longueur l correspond à la séquence binaire de source
X = 00 · · · 01 de (l + 1) bits. La distribution de probabilité p(l) de L est donc
18
donnée par9
p(l) = (1 − ε)l ε.
En les mettant bout à bout ces séquences de (l + 1) bits, on peut clairement
reconstruire la séquence des symboles de source initiale x0 , x1 , . . . à partir de
la représentation en longueurs de plages : l1 , l2 , . . .. Ainsi la source est plages
est « équivalente » à la source binaire initiale.
L’entropie de L vaut :
H(L) =
H2 (ε)
ε
Preuve: On peut le vérifier péniblement par le calcul en développant H(L) =
P
1
l>0 p(l) log2 p(l) (Exercice : le faire !). On peut aussi procéder comme suit :
Puisqu’équivalentes, les deux sources X et L ont même entropie, à condition bien sûr que ces entropies soient exprimées dans la même unité, par
exemple en bits par bit de source X L’entropie de X vaut H2 (ε). Or le
nombre moyen de bits de source par plage est10
E (L + 1) =
X
(l + 1)(1 − ε)l ε =
l>0
1
ε
On en déduit immédiatement, sans calcul, la formule donnant l’entropie de
L, en bits par plage.
11.2
Le codage des plages
Le principe du codage par plages est évidemment de coder la source équivalente des plages de façon à tenir compte des séquences de zéros consécutifs.
Mais comme le nombre des valeurs possibles des longueurs L = l est infini,
on ne peut pas appliquer directement un codage VLC (par exemple par l’algorithme de Huffman) sur la source L.
Pour résoudre ce problème, on procèdera ici en découpant en tranches
les valeurs des longueurs de plage, et on codera chaque tranche à l’aide d’un
code de Huffman de taille N . C’est compliqué à décrire en détail, mais le
principe est simple. Voici le détail :
9
On suppose ici que lesP
bits de source X sont indépendants (« source sans mémoire »).
+∞
On vérifiera qu’on a bien l=0 p(l) = 1.
10
Rappelons la formule
X
x
lxl =
.
(1 − x)2
l>0
19
On code tout d’abord les N − 1 premières valeurs des longueurs de plage :
l = 0, 1, . . . , N − 2
ainsi que l’événement L > N − 1, à l’aide de l’algorithme de Huffman.
Le code de Huffman obtenu est noté H1 ; il possède donc N mots de code.
Le mot de code associé à l’événement L > N − 1 est noté Pf 1 et servira de
préfixe au codage des longueurs > N − 1.
On code également la deuxième tranche, constituée des N − 1 valeurs suivantes des longueurs de plage :
l = N − 1, N, . . . , 2N − 3
ainsi que l’événement L > 2N − 2, en mettant en oeuvre l’algorithme de
Huffman11 . Le code de Huffman obtenu est noté H2 , il est aussi de taille N .
Le mot de code associé à l’événement L > 2N − 2 est noté Pf 2 et servira de
préfixe au codage des longueurs > 2N − 2.
On procède de même pour toutes les tranches suivantes. On obtient donc
une suite de codes de Huffman de taille N : H1 , H2 , H3 , . . ., et une suite de
préfixes Pf 1 , Pf 2 , Pf 3 , . . . correspondants.
Finalement la source L est codée comme suit : Si L = l appartient à la
kième tranche, il est codé par
c̄l = Pf 1 Pf 2 . . . Pf k−1 cl
où cl est le mot de code du code Hk correspondant à L = l.
Par exemple, si N = 4, L = 6, Pf 1 = Pf 2 = 10,
H3 = {0, 10, 110, 111}
où le mot de code correspondant à L = 6 est c6 = 110, alors L = 6 sera codé
par
c̄6 = 1010110.
Tout a été fait pour permettre de réaliser un algorithme naturel de décodage instantané pour retrouver la source L à partir de sa représentation
codée : le décodeur recherche d’abord les préfixes éventuels Pf 1 Pf 2 . . . Pf k−1
au début de la séquence à décoder, ce qui lui permet de repérer la tranche
k ; puis il décode un mot de code du code de Huffman Hk .
En fait on a la simplification suivante :
11
A partir de laP
deuxième tranche, l’algorithme de Huffman est mis en oeuvre bien que
la normalisation
i pi = 1 des probabilités n’est pas satisfaite, ce qui ne pose aucun
problème (l’algorithme n’utilise pas cette normalisation de toute façon).
20
Les codes de Huffman H1 , H2 , . . . sont toujours identiques,
et par conséquent les préfixes Pf 1 = Pf 2 = Pf 3 = . . . sont également identiques.
Preuve: Les probabilités en entrée de l’algorithme de Huffman qui fournit
Hk sont, au facteur multiplicatif (1 − ε)(N −1)(k−1) près, les mêmes que pour
le code H1 ; et ce facteur n’affecte pas le résultat de l’algorithme.
11.3
Performances et exemples
Grâce à la simplication ci-dessus on peut déterminer une formule simple
pour le taux de codage :
Le taux de codage global du système complet (en bits codés par
bit de source) vaut
R=
εRH
1 − (1 − ε)N −1
où RH est le taux de codage de chacun des codes de Huffman
H1 , H2 , H3 , . . ..
Preuve: Le taux de codage global du système complet est le nombre moyen
de bits codés par bit de source, c’est à dire :
R=
+∞
X
p(l)|c̄l |
l=0
où |c̄l | désigne la longueur (en bits) du mot de code c̄l (représentation codée
de la longueur L = l).
Pour calculer R, il faut tenir compte des longueurs des préfixes éventuels.
Exprimons d’abord R en bits par plage ; on a, en découpant en tranches (avec
des codes de Huffman et des préfixes identiques pour chaque tranche) :
R = p(0)|c0 | + · · · + p(N − 2)|cN −2 | + Prob{L > N − 1}|Pf 1 |
+ p(N − 1)|c0 | + · · · + p(2N − 3)|cN −2 | + Prob{L > 2N − 2}|Pf 1 |
+ ···
= RH + (1 − ε)N −1 RH + (1 − ε)2(N −1) RH + · · ·
Ici on a tenu compte du facteur mulitplicatif (1 − ε)N −1 pour les probabilités
d’une tranche à la suivante. On a donc
RH
R=
bits/plage
1 − (1 − ε)N −1
εRH
=
bits/bit
1 − (1 − ε)N −1
21
d’où la formule.
Evidemment ce résultat dépend du choix de la longueur N des tranches.
On peut d’ailleurs vérifier le résultat dans le cas extrême où N → ∞ ; le
code de Huffman donne alors un taux s’approchant de l’entropie d’après le
théorème de Shannon (appliqué à la source équivalente des longueurs) :
RH → H(L) =
H2 (ε)
ε
Puisque (1 − ε)N −1 → 0, on aboutit à
R → H2 (ε) = H
La limite est l’entropie de la source X, et donc la méthode de codage par
plages exposée ici est asymptotiquement optimale.
En pratique on détermine la longueur N des tranches par un compromis
entre taille du code de Huffman (elle ne doit pas être trop grande) et valeur
du taux R donnée par l’expression ci-dessus. Donnons un exemple précis pour
ε = 0.1 et N = 4. On applique l’algorithme de Huffman pour déterminer le
taux RH :
(1 − ε)3 = 0.729 0.729 0.729
1 1 1
ε = 0.1
0.171 0.271
2 2 1
longueurs :
ε(1 − ε) = 0.09 0.1
3 2
ε(1 − ε)2 = 0.081
3
d’où RH = 1.442 et R = 0.5321 . . . bits/bit obtenu par codage de Huffman
des plages.
On peut comparer ce résultat à un codage vectoriel en dimension n = 2
(pour une même taille de code de Huffman) :
(1 − ε)2 = 0.81 0.81 0.81
1 1 1
ε(1 − ε) = 0.09 0.1 0.19
2 2 1
longueurs :
ε(1 − ε) = 0.09 0.09
3 2
2
ε = 0.01
3
ce qui donne R = 1.29
= 0.645 bits/bit. Pour une même complexité, le codage
2
par plages se révèle meilleur que le codage vectoriel. Ce serait encore plus
flagrant pour de plus grandes valeurs de N (Exercice : le faire !).
22
12
Codage arithmétique
D’autres systèmes de codage de source sans pertes ont été proposés pour
prendre en compte les dépendances temporelles (d’un symbole à l’autre) de
la source (avec mémoire). Ces sytèmes de codage permettent de coder une
source quelconque sans connaitre a priori ses statistiques (c’est ce qu’on appelle du codage « universel »), mais sont plus complexes à mettre en
oeuvre. Les plus connus sont les systèmes de codage de Lempel-Ziv (1976)
et de codage arithmétique (1982).
Dans cette section, on va présenter les idées principales du codage arithmétique, qui est une des techniques de compression sans pertes les plus récentes, et probablement la plus importante dans les applications et les normes
actuelles.
Le codage arithmétique est une extension itérative d’une technique de codage connue depuis les années 50, appelée codage d’Elias (ou de ShannonFano-Elias). Cette dernière technique a été simplement introduite comme
moyen de construction d’un code VLC « scalaire », où on code chaque symbole de source l’un après l’autre. Décrivons d’abord le codage d’Elias :
12.1
Codes d’Elias
La distribution de probabilité des symboles de source vérifie la relation :
M
X
pi = 1.
i=1
On peut donc construire une partition (un « découpage ») du segment [0, 1[
(de longueur 1) en intervalles contigus12 I1 , . . . , IM , où chaque Ii est de longueur pi . Dans la suite, chaque point du segment [0, 1[ est un nombre qui
sera représenté par son développement binaire (en base 2), par exemple :
0.110100100 . . ..
I1
I2
I3
I4
···
IM
-
0
1
12
On choisira ces intervalles semi-ouverts (fermé à gauche, ouvert à droite) ; ainsi la
définition précise est :
i−1
i
X
X
Ii =
pi ;
pi .
j=1
23
j=1
L’idée est de coder un symbole de source xi par un point quelconque du
segment de l’intervalle correspondant Ii :
c̄i ∈ Ii .
On utilise ici la même notation que lors de la description de l’algorithme
de Kraft ci-dessus : le mot de code ci correspondant au symbole xi sera
tel que c̄i = 0, ci ∈ [0, 1[ : les décimales de l’écriture en base 2 de c̄i est
formée des bits de ci . Noter que même en supposant c̄i déterminé dans Ii ,
il reste une indétermination sur ci : ses premiers bits sont déterminés par
le développement de c̄i en base deux, mais sa longueur li , c’est à dire le
nombre de bits de précision (après la virgule) qu’on choisit pour le nombre
c̄i , reste à choisir.
Afin de pouvoir décoder, il est nécessaire que la précision sur c̄i soit
suffisamment grande pour caractériser dans quel intervalle Ii il se
trouve. Or, si c̄i est connu avec une précision de li bits, il peut prendre
n’importe quelle valeur dans l’intervalle
[c̄i ; c¯i + 2−li [
puisque cet intervalle est l’ensemble des nombres dont les li premières décimales en base 2 coincident avec ci . Il est donc nécessaire de choisir la précision
li de sorte que
[c̄i ; c¯i + 2−li [⊂ Ii .
Ainsi on pourra toujours déterminer un nombre c̄i ∈ Ii convenable, pourvu
que Ii contienne un intervalle du type [n2−li , (n + 1)2−li [, où n est entier
(auquel cas n = ci en base 2). Il est facile de voir que ce sera toujours
possible si
2 · 2−li 6 l(Ii ) = pi .
On ne peut pas, en général, choisir un li plus petit car Ii pourrait être alors
« à cheval » sur deux intervalles consécutifs du type [(n − 1)2−li , n2−li [ et
[n2−li , (n + 1)2−li [ :
MAUVAIS
(n−1)2−li
n2−li
(n+1)2−li
Ii
-
(n−1)2−li
n2−li
(n+1)2−li
BON
24
On pourra donc prendre pour li le plus petit entier vérifiant l’inégalité
ci-dessus, c’est à dire13 :
1
li = dlog2 e + 1
pi
Remarquons que, d’après l’analyse faite ci-dessus pour l’algorithme de Kraft,
on obtient un code instantané, car les intervalles [c̄i ; c¯i + 2−li [ sont tous
disjoints. De plus, par un calcul analogue au cas des codes de Fano-Shannon
traité ci-dessus, on en déduit l’encadrement sur le taux de codage :
H 6 R 6 H + 2.
Cet encadrement est moins bon que celui obtenu pour les codes de FanoShannon, ce qui explique pourquoi le codage d’Elias est rapidement tombé
dans l’oubli ; il n’a été ré-exhumé qu’à la lumière de la technique itérative du
codage arithmétique, qu’on va maintenant décire.
12.2
Itérations du codage arithmétique
L’idée du codage arithmétique est d’itérer la procédure d’Elias au fur et
à mesure du temps, afin coder plusieurs symboles de source successifs. On
prendra ainsi en compte les corrélations éventuelles des symboles de la source
(avec mémoire).
Commencons par le codage de deux symboles consécutifs14 (x1 , x2 ). La
distribution de probabilité conjointe de ce vecteur s’écrit :
p(x1 , x2 ) = p(x1 )p(x2 |x1 )
où p(x2 |x1 ) est la probabilité conditionnelle de x2 sachant x1 .
On commence par appliquer la procédure d’Elias pour le symbole x1 ;
on obtient une représentation codée dans un intervalle I1 de longueur p(x1 ).
Pour tenir compte de x2 , on considère non pas les probabilités p(x2 ), mais
les probabilités conditionnelles p(x2 |x1 ) qui vérifient la relation :
X
p(x2 |x1 ) = 1.
x2
On recommence alors la procédure d’Elias, non plus sur le segment [0, 1[,
mais sur l’intervalle I1 qu’on re-partitionne en intervalles I2 plus
fins, de longueurs proportionnelles aux p(x2 |x1 ) :
13
dxe désigne le plus petit entier > x.
A partir de maintenant les indices désignent le temps : x1 , x2 , . . . sont les symboles
de source observés aux instants t = 1, 2, . . ..
14
25
···
I1
-
0
PP
PP
!
!!
!
!
!!
!!
!!
1
PP
PP
P
···
I2
PP
P
P
P
-
Puisque l(I1 ) = p(x1 ), ces nouveaux intervalles I2 sont en fait de longueur
l(I2 ) = p(x1 )p(x2 |x1 ) = p(x1 , x2 ).
Arrivé jusque là, rien n’empêche de continuer et de coder le symbole
suivant x3 , en re-découpant l’intervalle I2 en sous-intervalles I3 de longueurs
proportionnelles à p(x3 |x1 , x2 ). Ces intervalles seront en fait de longueur
p(x1 , x2 )p(x3 |x1 , x2 ) = p(x1 , x2 , x3 )
et ainsi de suite. Après n itérations de l’algorithme d’Elias on obtient un
intervalle de longueur
p(x1 , x2 , . . . , xn ) = p(x1 )p(x2 |x1 )p(x3 |x1 , x2 ) · · · p(xn |x1 , . . . , xn−1 )
qui prend bien en compte la dépendance temporelle des symboles de source.
12.3
Points techniques et performances
Le résultat du codage est donc formée des décimales du nombre c̄ ∈ In ,
avec une précision suffisante pour qu’il appartienne à un intervalle In unique.
Ainsi, en théorie, il suffit de disposer d’une implantation d’une arithmétique
à précision infinie (ou suffisamment grande). Ceci explique le terme « codage
arithmétique ».
Le décodage procède dans le même sens que le codage : on regarde
d’abord dans quel intervalle I1 se trouve c̄, on en déduit x1 , puis on regarde
à l’intérieur de I1 dans quel intervalle I2 se trouve c̄, on en déduit x2 , et ainsi
de suite. On décode ainsi « au fil de l’eau » x1 , x2 , . . ..
En pratique, il est hors de question de demander une implantation d’une
artihmétique à précision infinie. C’est la raison pour laquelle il est nécessaire
de procéder à des « remises à l’échelle » subtiles chaque fois que la précisionmachine va être atteinte, de façon à éviter les problèmes d’underflow. Ces
remises à l’échelle sont re-parcourues lors du décodage. Je passe ici sous
silence les nombreux détails d’implantation qui sont très techniques.
26
Il est facile d’évaluer les performances de ce codage : Le mot de code
d’Elias au bout de n étapes aura une longueur (longueur de précision de c̄) :
l = dlog2
1
e+1
p(x1 , x2 , . . . , xn )
et le taux de codage Rn , en bits par vecteur (x1 , . . . , xn ), vérifie donc l’encadrement :
Hn 6 Rn 6 Hn + 2,
d’où, en se ramenant à des bits par symbole de source :
H6R6H+
2
n
où H est l’entropie d’ordre n de la source. On retrouve une situation déjà
rencontrée lors de l’analyse du codage vectoriel en dimension n, qui fournit le théorème de Shannon : le taux de codage s’approche d’aussi près
qu’on veut de l’entropie. Le codage arithmétique est donc optimal dans le
cas général des sources avec mémoire.
12.4
Adaptativité et universalité
L’intérêt du codage artihmétique n’est pas tant de fournir un algorithme
de codage optimal mais il permet surtout un codage adaptatif : plutôt
que de supposer connu une fois pour toutes la distribution de probabilité
conjointe de la source p(x1 , . . . , xn ) (par modélisation et/ou estimation sur
toute la source), il est possible d’estimer au fur et à mesure les probabilités
conditionnelles
p(xn |x1 , . . . , xn−1 )
dont on a besoin pour l’étape n. Ceci permet une plus grande flexibilité pour
coder n’importe quel type de source, en s’adaptant à des variations éventuelles de statistiques. Bien entendu, cette estimation est d’abord grossière ;
elle s’affine au fur et à mesure du codage des données x1 , x2 , . . ..
On peut même aller plus loin : plutôt que de transmettre en données annexes (overhead) ces estimations de probabilité du codeur au décodeur (qui
en a également besoin), on peut envisager de répeter au décodage (indépendamment du codeur) l’estimation voulue sur les données au fur et à
mesure de leur décodage. On obtient alors un algorithme de décodage
universel qui est capable de coder (et de décoder sans information supplémentaire) tout type de source sans connaissance a priori de ses statistiques.
27
Références
[1] Robert Mc Eliece, The Theory of Information and Coding, Addison Wesley, 1977.
[2] Thomas Cover, Joy Thomas, Elements of Information Theory, J. Wiley
& sons, 1991.
[3] Allan Gersho, Robert Gray, Vector Quantization and Signal Compression,
Kluwer Academic, 1992.
[4] Nicolas Moreau, Techniques de Compression des Signaux, Masson CNETENST, 1994.
28