1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
|
function [code] = arithenco(seq, count)
// This function encodes the given sequence using aritmetic coding
// Syntax
// CODE = ARITHENCO(SEQ, COUNT)
// Description
// CODE = ARITHENCO(SEQ, COUNT) encodes the given sequence (SEQ) using arithmetic coding.
// COUNT is vector whihc gives information about the source statistics (i.e. frequency of each symbol in the source alphabet)
// CODE is the binary arithmetic code
// Source Alphabet is assumed to be {1,2,....N} where N is a positive integer
// Therefore, sequence should be finite and positive
// Length of the COUNT should match the length of the source alphabet
// Examples
// counts = [40 1 9];
// len = 4;
// seq = [1 3 2 1]
// code = arithenco(seq,counts);
// disp(code)
// Bibliography
// Sayood, K., Introduction to Data Compression, Morgan Kaufmann, 2000, Chapter 4, Section 4.4.3.
// See also
// arithdeco
// Authors
// Pola Lakshmi Priyanka, IIT Bombay//
//*************************************************************************************************************************************//
//Input argument check
[outa,inpa]=argn(0);
if(~inpa==2)
error("comm:arithenco:Wrong number of Input Arguments");
end
[row_seq,col_seq]=size(seq);
[row_sta,col_sta]=size(count);
// Check to make sure that sequence is 1D
if(~(row_seq==1|col_seq==1))
error("comm:arithenco: Invalid dimensions: Input Sequence should be 1D ");
end
// Check for source statistics matrix
if(~(row_sta==1|col_sta==1))
error("comm:arithenco: Invalid dimensions: Argument 2 should be 1D ");
end
if(~isreal(seq) | or(seq<0) )
error("comm:arithenco: Input sequence should be finite positive integer");
end
if(~isreal(count) | or(count<0) )
error("comm:arithenco: Source statistics should be finite positive integer");
end
//Check if number of elements in source alphabet is equal to dimensions of source statistics matrix
if max(seq) > length(count)
error("comm:arithenco:Source alphabet size does not match with source statistics size");
end
//Check the incoming orientation and adjust if necessary
if (row_seq > 1),
seq = seq.';
end
if (row_sta > 1),
count = count.';
end
[row_s,col_s]=size(seq);
[row_c,col_c]=size(count);
//Calculate the cumulative count
cum_count=[0,cumsum(count)];
scale3=0;
total_count=cum_count(length(cum_count));
//Initialization
m=ceil(log2(total_count)) + 2;
low=zeros(1,m);
up=ones(1,m);
dec_low=0;
dec_up=2^m-1;
code_len = length(seq) * ( ceil(log2(length(count))) + 2 ) + m;
code = zeros(1, code_len);
code_index = 1;
// For each bit in the seq
for k=1:length(seq)
symbol = seq(k);
// Compute the lower and upper bounds
dec_low_new = dec_low + floor( (dec_up-dec_low+1)*cum_count(symbol+1-1)/total_count );
dec_up = dec_low + floor( (dec_up-dec_low+1)*cum_count(symbol+1)/total_count )-1;
dec_low = dec_low_new;
for i=1:m
low(i)=strtod(part(dec2bin(dec_low,m),i))
end
for i=1:m
up(i)=strtod(part(dec2bin(dec_up,m),i))
end
//Loop while E1, E2 or E3 condition
while(isequal(low(1),up(1))) | (isequal(low(2),1) & isequal(up(2),0))
// Check for E1 or E2 condition
if isequal(low(1),up(1)) then //E1 or E2 holds
// Transmit MSB
b=low(1);
code(code_index) = b;
code_index = code_index + 1;
//Left shift
low=[low(2:m) 0];
up=[up(2:m) 1];
while (scale3>0)
code(code_index) = bitxor(b,1);
code_index = code_index + 1;
scale3 = scale3-1;
end
end
if (isequal(low(2),1) & isequal(up(2),0)) then //for E3
//left shift
low=[low(2:m),0];
up=[up(2:m),1];
//disp(up,low,"up,low");
low(1)=bitxor(low(1),1);
up(1)=bitxor(up(1),1);
scale3=scale3+1;
end
end
dec_low=0;dec_up=0;
for i=1:length(low)
dec_low=dec_low+low(i)*2^(length(low)-i);
dec_up=dec_up+up(i)*2^(length(up)-i);
end
end
if scale3==0 then
code(code_index:code_index + m - 1) = low;
code_index = code_index + m;
end
if ~scale3==0 then
b=low(1);
code(code_index)=b;
code_index = code_index + 1;
while (scale3>0)
code(code_index) = bitxor(b,1);
code_index = code_index + 1;
scale3 = scale3-1;
end
code(code_index:code_index+m-2) = low(2:m);
code_index = code_index + m - 1;
end
code = code(1:code_index-1);
endfunction
|