summaryrefslogtreecommitdiff
path: root/macros/arithenco.sci
diff options
context:
space:
mode:
Diffstat (limited to 'macros/arithenco.sci')
-rw-r--r--macros/arithenco.sci166
1 files changed, 166 insertions, 0 deletions
diff --git a/macros/arithenco.sci b/macros/arithenco.sci
new file mode 100644
index 0000000..a463afa
--- /dev/null
+++ b/macros/arithenco.sci
@@ -0,0 +1,166 @@
+function [code] = arithenco(seq, count)
+// This function encodes the given sequence using aritmetic coding
+
+// Calling sequence
+// 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