Professional Documents
Culture Documents
2 Huffman Codes
Suppose one wants to design a memoryless prefix code for compressing a data vector x over a k-ary alphabet
A. Let F = (F1 , F2 , . . . , Fk ) denote the vector in which Fi is the number of times that the i-th most frequent
symbol in A appears in x. Suppose we were to encode x using a memoryless prefix code for which the
underlying Kraft vector is L = (L1 , L2 , . . . , Lk ). Then the length of the encoder output bitstring B(x) is
F • L = F1 L1 + F2 L2 + . . . + Fk Lk
The best prefix code would be one for which B(x is minimized. To design such a code, one finds a Kraft
vector L for which L • F is minimized. Exhaustive search is not a very good way to find such a Kraft vector
for large k. (For example, for k = 11, you’d have to search through 89 possibilities for L.) The Huffman
algorithm gives us an efficient way to find an optimal L for F , that is, a Kraft vector for which the dot
product L • F is minimized. (The example below shows that there can be more than one optimal L for a
given F .) A code designed using an optimal L for F shall be called a Huffman code.
EXAMPLE. We consider the data vector x = (a, a, a, a, b, b, c, c, d, e) over the alphabet A = {a, b, c, d, e}.
The vector of frequencies F for x is F = (4, 2, 2, 1, 1). There are three possible Kraft vectors that can be
used to define a memoryless prefix code for x, namely,
L = (1, 2, 3, 4, 4)
L = (1, 3, 3, 3, 3)
L = (2, 2, 2, 3, 3)
The reader can check that each of these three choices gives the dot product L • F = 22. These Kraft vectors
give rise to three distinct memoryless prefix codes for x, each of which yields an encoder output codeword
length of B(x) = 22 codebits. Since this is the smallest possible length for B(x), each of these three codes
is a Huffman code for x.
M ♦N = (M1 + N1 , M2 + 1, M3 + 1, . . . , Mr + 1, N2 + 1, N3 + 1, . . . , Ns + 1)
For example, (3, 1, 2, 2)♦(5, 1, 2, 3, 4, 4) = (8, 2, 3, 3, 2, 3, 4, 5, 5).
Suppose one has a list of vectors with integer components
U 1, U 2, . . . , U j (1)
where j ≥ 2. We perform what we call a pruning operation on the list (1) to obtain a list of vectors
V 1 , V 2 , . . . , V j−1 (2)
First, choose any two vectors U i1 , U i2 (i1 6= i2 ) from list (1) such that these two vectors have the smallest
initial components among all the initial components of vectors in list (1). Form the vector U = U i1 ♦[Ui2 .
Then, strike out U i1 , U i2 from the list (1), and append the new vector U to the end of the list. The resulting
list is the list (2). For example, if list (1) is the list
to obtain a list of j − 1 integer vectors U 1 , V 2 , .
1
codeword assignments
1 1
2 01
3 000
0 001
(Notice that we have assigned the shortest codeword to the most frequent symbol in x and the longest
codeword to the least frequent symbol; if we do not do this, the codeword B(x) assigned to x below becomes
longer.) Replacing each sample in x with its assigned codeword, we get the sequence of codewords
000, 000, 01, 1, 000, 01, 01, 1, 01, 01, 1, 001, 1, 1, 1, 001 (1)
Concatenating these together, we see that the encoder output B(x) in response to the encoder input x is:
B(x) = (0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1)
The fact that S is a prefix set allows the decoder to obtain the decomposition (1) from B(x), whence the
decoding of B(x) into x can be completed using the above table.
(To see this, first argue that if {w1 , w2 , wk−1 , w̃k } fails to be a prefix set, then the prefix set {w1 , w2 , . . . , wk }
is of Type I.) These facts motivate one to define the following two operations on prefix sets:
• A Type I operation on a prefix set S generates a new prefix set in which a longest or second longest
bitstring w in S is replaced by the two bitstrings w0 and w1.
• A Type II operation on a prefix set S generates a new prefix set in which a longest or second longest
bitstring w in S is replaced by either the bitstring w0 or the bitstring w1.
Thus, if S1 is a Type I prefix set, there exists a simpler prefix set S2 such that S1 is obtained from S2 via a
Type I operation; if S1 is a Type II prefix set, there exists a prefix set S2 such that S1 is obtained from S2
via a Type II operation.
EXAMPLE. The prefix set S1 = {0, 11, 101} is of Type II. It can be reduced to the prefix set S2 =
{0, 10, 11}. S1 is obtained from S2 via a Type II operation (replacing 10 with 101). The prefix set S1 =
{0, 10, 110, 111} is of Type I. It can be reduced to the prefix set S2 = {0, 10, 11}. S1 is obtained from S2 via
a Type I operation (replacing 11 with 110 and 111).
If S and S 0 are prefix sets, let us write S → S 0 to denote that S 0 is obtained from S via either a Type I
or Type II operation. Then, in view of the preceding, the following must be true:
• If S is a nontrivial prefix set, then there must exist prefix sets S1 , S2 , . . . , Sj such that S1 is trivial and
S1 → S2 → S3 → . . . → Sj = S
2
EXAMPLE. Let S be the prefix set
S5 = {0, 1}
Notice that S5 is trivial and S5 → S4 → S3 → S2 → S1 → S.
v(S) = (L1 , L2 , . . . , Lk )
where Li is the length of wi . Let us call a vector (L1 , L2 , . . . , Lk ) having nondecreasing positive integer
components a Kraft vector if the inequality
(In other words, the lengths of the bitstrings in a prefix set satisfy Kraft’s inequality.) Here is how you can
see that this statement is true. First, it is true for the trivial prefix sets. Secondly, suppose the statement
holds for a prefix set S, and that v(S) = (L1 , L2 , . . . , Lk ). If you perform a Type I or Type II operation on
S to get the prefix set S 0 , then in forming v(S 0 ) you replace some component Li of v(S) with Li + 1 (Type
II operation), or else you replace Li with two components Li + 1, Li + 1 (Type I operation). Since
3
• An improper Kraft vector is a Kraft vector (L1 , L2 , . . . , Lk ) in which
2Lk −Lk−1 I = J
where I is an integer and J is an odd integer. Since the left side of the preceding equation must be odd,
we must have 2Lk = 2Lk−1 , rather than 2Lk > 2Lk−1 . The second statement above follows from the first
statement. To see that the third statement is true, observe that if (2) holds, then
EXAMPLE. (1, 2, 4, 4, 4, 5) is an improper Kraft vector. So, (1, 2, 4, 4, 4, 4) is a Kraft vector. Since
it’s improper, (1, 2, 3, 4, 4, 4) is also a Kraft vector. (2, 2, 2, 2) is a proper Kraft vector. Consequently, so is
(1, 2, 2), and then so is (1, 1).
From the preceding example, it can be seen that any proper Kraft vector eventually reduces to the vector
(1, 1) through a chain of proper Kraft vectors. Also, any improper Kraft vector reduces to either the vector
(1) or the vector (1, 1) through a chain of Kraft vectors.
Let v be a fixed Kraft vector. Combining this section with the previous one, we obtain a method for
constructing a prefix set S for which v(S) = v: Starting with v, do a chain of reductions until you obtain (1)
or (1, 1). Then, starting with the prefix set {0} or {0, 1}, you can go back up the chain doing appropriate
Type I or Type II operations until you wind up with the desired prefix set S.
EXAMPLE. Let’s construct a prefix set S for which v(S) = (1, 2, 4, 4, 4, 5). Doing a chain of reductions,
we get the Kraft vectors
(1,2,4,4,4,5,6,6) (proper)
(1,2,4,4,4,5,5) (proper)
(1,2,4,4,4,4) (proper)
(1,2,3,4,4) (proper)
(1,2,3,3) (proper)
(1,2,2) (proper)
(1,1)
4
Start with the prefix set S0 = {0, 1} and go back up the chain. To get each Kraft vector back up the chain,
we have to do an appropriate Type I operation to the prefix set from the preceding set:
S0 → S1 = {0, 10, 11} and v(S1 ) = (1, 2, 2)
S1 → S2 = {0, 10, 110, 111} and v(S2 ) = (1, 2, 3, 3)
S2 → S3 = {0, 10, 110, 1110, 1111} and v(S3 ) = (1, 2, 3, 4, 4)
S3 → S4 = {0, 10, 1100, 1101, 1110, 1111} and v(S4 ) = (1, 2, 4, 4, 4, 4)
S4 → S5 = {0, 10, 1100, 1101, 1110, 11110, 11111} and v(S5 ) = (1, 2, 4, 4, 4, 5, 5)
S5 → S6 = {0, 10, 1100, 1101, 1110, 11110, 111110, 111111} and v(S6 ) = (1, 2, 4, 4, 4, 5, 6, 6)
All k-ary compact codes arise as the result of the above expansion operations performed on (k − 1)-ary
compact codes. Let us obtain the 5-ary compact codes this way:
5
There are thus three 5-ary compact codes, the (1, 2, 3, 4, 4), (1, 3, 3, 3, 3), and (2, 2, 2, 3, 3) codes.
Let us now classify the 6-ary compact codes. First, we generate them from the 5-ary codes:
For large k, it has been determined that there are about (1.7941472)k compact codes.
• concat
• prefix encode
• compactcodeP
• compactcodeI
The function concat is a utility (a function used to build other functions), the function prefix encode is
an encoding function, and the functions compactcodeP and compactcodeI are code design functions.
6
2.5.1 concat
The m-file concat.m is given below:
The function “concat” created by this m-file operates as follows. Let I be the vector of indices of two or
more bitstrings. Then y = concat(I) is the bitstring obtained by concatenating together from left to right
the bitstrings whose indices are in I. For example, the vector of indices of the bitstrings 1, 01, 000, 001 is [2,
4, 7, 8]. Executing the MATLAB line
y = concat([2 4 7 8]);
you will see the bitstring 1010000001 displayed on the screen. (This is the bitstring obtained by concate-
nating together the bitstrings 1, 01, 000, 001.) The vector [1,0,1,0,0,0,0,0,1] will also be stored in
MATLAB memory.
7
end
n=length(x);
for i3=1:n;
q(i3)=z(x(i3)+1);
end
y=concat(q);
The MATLAB function “prefix encode” created by this m-file accomplishes memoryless prefix encoding.
Let x denote the data vector to be encoded, and we suppose that the alphabet of this data vector is the set
{0, 1, . . . , k − 1} for some positive integer k. Let W denote the vector of indices of the prefix set of bitstrings
{w1 , w2 , . . . , wk } for the memoryless prefix code that is to be employed. Executing the MATLAB line
y=prefix_encode(W,x);
creates the encoder output bitstring y in MATLAB memory and this bitstring is also printed out on the
screen. For example, let x = [3, 3, 2, 1, 3, 2, 2, 1, 2, 2, 1, 0, 1, 1, 1, 0] be the data vector, and let the prefix set
for the code be {1, 01, 000, 001}. Converting this set to integer form, we get W = [2, 4, 7, 8]. Typing in the
MATLAB command “prefix encode(W,x);”, you will see the sequence
0000000110000101101011001111001
printed out on the screen. This is the encoder output.
2.5.3 compactcodeP
This is the m-file “compactcodeP.m”:
8
t=find(u<u(i+1));
j=length(t);
u=[u(1:j-1) u(j)+1 u(j)+1 u(j+1:i+1)];
v=[v(1:j-1) 2*v(j)+1 2*v(j)+2 v(j+1:i+1)];
end
end
y=v;
print_bitstrings(y);
We describe what the MATLAB function “compactcodeP” does. Let L be a proper Kraft vector (L1 , L2 , . . . , Lk ).
Executing the MATLAB command compactcodeP(L) prints out on the screen a prefix set {w1 , w2 , . . . , wk }
of a compact code whose Kraft vector equals L. For example, executing the line
compactcodeP([1 2 3 4 4]);
results in the appearance on the screen of the following prefix set for a (1, 2, 3, 4, 4) compact code:
0
10
110
1110
1111
2.5.4 compactcodeI
The following is the m-file “compactcodeI.m”:
9
We describe what the MATLAB function “compactcodeI” does. Let L be an improper Kraft vector
(L1 , L2 , . . . , Lk ). Executing the MATLAB command compactcodeI(L) prints out on the screen a prefix
set {w1 , w2 , . . . , wk } of a compact code whose kraft vector (L01 , L02 , . . . , L0k ) satisfies L0i ≤ Li for each i. For
example, executing the line
compactcodeI([2 3 3 3 4 5 5]);
you will see the following prefix set appear on the screen:
00
010
011
100
101
110
111
The Kraft vector for this prefix set is the proper Kraft vector [2, 3, 3, 3, 3, 3, 3], each of whose components is
less than or equal to the corresponding component of the improper Kraft vector [2, 3, 3, 3, 4, 5, 5]. The above
prefix set therefore yields a (2, 3, 3, 3, 3, 3, 3) compact code.
10