home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-07-17 | 47.9 KB | 1,504 lines |
- Newsgroups: comp.sources.misc
- From: Radford Neal <radford@ai.toronto.edu>
- Subject: v20i096: low-perc - Low-precision arithmetic coding routines, Part01/01
- Message-ID: <1991Jul16.012844.21809@sparky.IMD.Sterling.COM>
- X-Md4-Signature: dfa067089e1e1408ffb0cff849157f04
- Date: Tue, 16 Jul 1991 01:28:44 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: Radford Neal <radford@ai.toronto.edu>
- Posting-number: Volume 20, Issue 96
- Archive-name: low-perc/part01
-
- The following is a README file for the 'shar' archive that follows.
-
- The code is also available by anonymous ftp from fsa.cpsc.ucalgary.ca,
- in directory pub/arithmetic.coding/low.precision.version. Any updates
- will be placed there.
-
-
- LOW-PRECISION ARITHMETIC CODING IMPLEMENTATION
-
- Radford M. Neal, July 1991
-
-
- This directory contains C source for an implementation of arithmetic
- coding using low-precision division. This division can be performed
- using shift/add operations, with potential savings in time on any
- machine without parallel multiply/divide hardware.
-
- The implementation is based on that in the paper of Witten, Neal, and
- Cleary published in the June 1987 Communications of the ACM. Anyone
- wishing to understand this program is urged to first read that paper.
- Differences in this version are as follows:
-
- 1) The arithmetic coding operations have been fiddled so that
- the division involved can be done to very low precision.
- There is a tradeoff between precision and compression performance,
- but nearly optimal results are obtained with a precision of
- six bits, and precisions of as low as three, bits give reasonable
- results. A precision of at least two bits is required for
- correct operation.
-
- 2) In order for (1) to be possible, the model is now required
- to produce "partially normalized" frequencies, in which the
- total for all symbols is always more than half the maximum
- allowed total. This is not onerous, at least for the models
- used here.
-
- 3) The model must also now arrainge for the most probable symbol
- to have index 1. This was always the case, but previously
- this was solely a matter of time efficiency. Now, failure
- to do this would impact compression efficiency, though not
- correct operation.
-
- 4) The precision to which symbol frequencies may be held is much
- higher in this implementation - 27 bits with the default
- parameter settings. The CACM implementation was restricted
- to 14 bit frequencies. This is of significance in applications
- where the number of symbols is large, such as with word-based
- models.
-
- 5) Encode/decode procedures specialized for use with a two-symbol
- alphabet have been added. These are demonstrated by a simple
- adaptive image compression program.
-
- 6) Various minor modifications and structural changes to the
- program have been made.
-
- Two versions of the coding procedures are provided - one using C
- multiply and divide operators, the other using shifts and adds. These
- versions, and the resulting encode/decode programs, are distinguished
- by the suffixes "_mul" and "_sft". Which version is fastest will
- depend on the particular machine and compiler used. All encode/decode
- programs simply read from standard input and write to standard output.
-
- The file 'tstpic' contains a test picture for the image
- encoding/decoding programs. The format of such pictures may be
- discerned by examination of this example, and of the program code.
-
- A program for calculating a bound on maximum expected redundancy
- resulting from low-precision division is included. Typical redundancy
- is much less than this bound.
-
- For the multiply/divide version, the requirement that the model
- produce partially normalized frequencies is not really necessary.
-
- The program is intended for demonstation purposes. It is not optimized
- for time efficiency, and provides little in the way of error checking.
-
- This code is public domain, and may be used by anyone for any purpose.
- I do, however, expect that distributions utilizing this code will
- include an acknowledgement of its source. The program is provided
- without any warranty as to correct operation. To the best of my
- knowledge, the techniques used are free of any patent complications,
- but no guarantees are offered in this respect either.
-
- Address comments to:
-
- Radford Neal
- Dept. of Computer Science
- University of Toronto
- 10 King's College Road
- Toronto, Ontario, CANADA
- M5S 1A4
-
- e-mail: radford@ai.toronto.edu
-
-
- ---- cut here and feed to sh ----
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of shell archive."
- # Contents: Makefile bit_io.c code.h code_mul.c code_sft.c decode.c
- # decpic.c encode.c encpic.c model.c model.h redundancy.c tstpic
- # Wrapped by ian@cpsc.ucalgary.ca on Mon Jul 8 14:09:11 1991
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Makefile'\"
- else
- echo shar: Extracting \"'Makefile'\" \(1205 characters\)
- sed "s/^X//" >'Makefile' <<'END_OF_FILE'
- XCFLAGS = -O
- X
- Xall: encode_mul decode_mul encode_sft decode_sft \
- X encpic_mul decpic_mul encpic_sft decpic_sft
- X
- X
- Xencode_mul: encode.o model.o bit_io.o code_mul.o
- X cc -O encode.o model.o bit_io.o code_mul.o -o encode_mul
- X
- Xdecode_mul: decode.o model.o bit_io.o code_mul.o
- X cc -O decode.o model.o bit_io.o code_mul.o -o decode_mul
- X
- Xencode_sft: encode.o model.o bit_io.o code_sft.o
- X cc -O encode.o model.o bit_io.o code_sft.o -o encode_sft
- X
- Xdecode_sft: decode.o model.o bit_io.o code_sft.o
- X cc -O decode.o model.o bit_io.o code_sft.o -o decode_sft
- X
- X
- Xencpic_mul: encpic.o bit_io.o code_mul.o
- X cc -O encpic.o bit_io.o code_mul.o -o encpic_mul
- X
- Xdecpic_mul: decpic.o bit_io.o code_mul.o
- X cc -O decpic.o bit_io.o code_mul.o -o decpic_mul
- X
- Xencpic_sft: encpic.o bit_io.o code_sft.o
- X cc -O encpic.o bit_io.o code_sft.o -o encpic_sft
- X
- Xdecpic_sft: decpic.o bit_io.o code_sft.o
- X cc -O decpic.o bit_io.o code_sft.o -o decpic_sft
- X
- X
- Xencode.o: encode.c model.h code.h
- Xdecode.o: decode.c model.h code.h
- Xmodel.o: model.c model.h code.h
- X
- Xencpic.o: encpic.c model.h code.h
- Xdecpic.o: decpic.c model.h code.h
- X
- Xcode_mul.o: code_mul.c code.h
- Xcode_sft.o: code_sft.c code.h
- Xbit_io.o: bit_io.c code.h
- END_OF_FILE
- if test 1205 -ne `wc -c <'Makefile'`; then
- echo shar: \"'Makefile'\" unpacked with wrong size!
- fi
- # end of 'Makefile'
- fi
- if test -f 'bit_io.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'bit_io.c'\"
- else
- echo shar: Extracting \"'bit_io.c'\" \(1690 characters\)
- sed "s/^X//" >'bit_io.c' <<'END_OF_FILE'
- X/* BIT_IO.C - BIT INPUT/OUTPUT ROUTINES. */
- X
- X#include <stdio.h>
- X
- X#include "code.h"
- X
- X
- X/* THE BIT BUFFER. */
- X
- Xstatic int buffer; /* Bits waiting to be input */
- Xstatic int bits_to_go; /* Number of bits still in buffer */
- X
- Xstatic int garbage; /* Number of garbage bytes after EOF */
- X
- X
- X/* INITIALIZE FOR BIT OUTPUT. */
- X
- Xstart_outputing_bits()
- X{
- X buffer = 0; /* Buffer is empty to start */
- X bits_to_go = 8; /* with. */
- X}
- X
- X
- X/* INITIALIZE FOR BIT INPUT. */
- X
- Xstart_inputing_bits()
- X{
- X bits_to_go = 0; /* Buffer starts out with */
- X garbage = 0; /* no bits in it. */
- X}
- X
- X
- X/* OUTPUT A BIT. */
- X
- Xoutput_bit(bit)
- X int bit;
- X{
- X if (bits_to_go==0) { /* Output buffer if it is */
- X putc(buffer,stdout); /* full. */
- X bits_to_go = 8;
- X }
- X
- X buffer >>= 1; /* Put bit in top of buffer.*/
- X if (bit) buffer |= 0x80;
- X bits_to_go -= 1;
- X}
- X
- X
- X/* INPUT A BIT. */
- X
- Xint input_bit()
- X{
- X int t;
- X
- X if (bits_to_go==0) { /* Read next byte if no */
- X buffer = getc(stdin); /* bits left in the buffer. */
- X bits_to_go = 8;
- X if (buffer==EOF) { /* Return anything after */
- X if (garbage*8>=Code_bits) { /* end-of-file, but not too */
- X fprintf(stderr,"Bad input file (2)\n"); /* much of anything.*/
- X exit(1);
- X }
- X garbage += 1;
- X }
- X }
- X
- X t = buffer&1; /* Return the next bit from */
- X buffer >>= 1; /* the bottom of the byte. */
- X bits_to_go -= 1;
- X return t;
- X}
- X
- X
- X/* FLUSH OUT THE LAST BITS. */
- X
- Xdone_outputing_bits()
- X{
- X putc(buffer>>bits_to_go,stdout);
- X}
- END_OF_FILE
- if test 1690 -ne `wc -c <'bit_io.c'`; then
- echo shar: \"'bit_io.c'\" unpacked with wrong size!
- fi
- # end of 'bit_io.c'
- fi
- if test -f 'code.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'code.h'\"
- else
- echo shar: Extracting \"'code.h'\" \(1328 characters\)
- sed "s/^X//" >'code.h' <<'END_OF_FILE'
- X/* CODE.H - DECLARATIONS USED FOR ARITHMETIC ENCODING AND DECODING */
- X
- X
- X/* PRECISION OF CODING VALUES. Coding values are fixed-point binary
- X fractions in the range [0,1), represented as integers scaled by
- X 2^Code_bits. */
- X
- X#define Code_bits 32 /* Number of bits for code values */
- X#define Code_quarter (1<<(Code_bits-2)) /* Quarter point for code values */
- X#define Code_half (1<<(Code_bits-1)) /* Halfway point for code values */
- X
- Xtypedef unsigned code_value; /* Data type holding code values */
- X
- X
- X/* PRECISION OF SYMBOL PROBABILITIES. Symbol probabilities must be partially
- X normalized, so that the total for all symbols is in the range (1/2,1].
- X These probabilities are represented as integers scaled by 2^Freq_bits. */
- X
- X#define Freq_bits 27 /* Number of bits for frequencies */
- X#define Freq_half (1<<(Freq_bits-1)) /* Halfway point for frequencies */
- X#define Freq_full (1<<Freq_bits) /* Largest frequency value */
- X
- Xtypedef unsigned freq_value; /* Data type holding frequencies */
- X
- X
- X/* PRECISION OF DIVISION. Division of a code value by a frequency value
- X gives a result of precision (Code_bits-Freq_bits), which must be at
- X least two for correct operation (larger differences give smaller code
- X size). */
- X
- Xtypedef unsigned div_value; /* Data type for result of division */
- END_OF_FILE
- if test 1328 -ne `wc -c <'code.h'`; then
- echo shar: \"'code.h'\" unpacked with wrong size!
- fi
- # end of 'code.h'
- fi
- if test -f 'code_mul.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'code_mul.c'\"
- else
- echo shar: Extracting \"'code_mul.c'\" \(7887 characters\)
- sed "s/^X//" >'code_mul.c' <<'END_OF_FILE'
- X/* CODE_MUL.C - ARITHMETIC ENCODING/DECODING, USING MULTIPLY/DIVIDE. */
- X
- X#include <stdio.h>
- X
- X#include "code.h"
- X
- X
- X/* CURRENT STATE OF THE ENCODING/DECODING. */
- X
- Xstatic code_value low; /* Start of current coding region, in [0,1) */
- X
- Xstatic code_value range; /* Size of region, normally kept in the */
- X /* interval [1/4,1/2] */
- X
- Xstatic code_value value; /* Currently-seen code value, in [0,1) */
- X
- Xstatic int bits_to_follow; /* Number of opposite bits to output after */
- X /* the next bit */
- X
- Xstatic div_value F; /* Common factor used, in interval [1/4,1) */
- X
- Xstatic code_value split_region();
- X
- X
- X/* OUTPUT BIT PLUS FOLLOWING OPPOSITE BITS. */
- X
- X#define bit_plus_follow(bit) \
- Xdo { \
- X output_bit(bit); /* Output the bit. */\
- X while (bits_to_follow>0) { /* Output bits_to_follow */\
- X output_bit(!(bit)); /* opposite bits. Set */\
- X bits_to_follow -= 1; /* bits_to_follow to zero. */\
- X } \
- X} while (0) \
- X
- X
- X/* START ENCODING A STREAM OF SYMBOLS. */
- X
- Xstart_encoding()
- X{
- X low = Code_half; /* Use half the code region */
- X range = Code_half; /* (wastes first bit as 1). */
- X bits_to_follow = 0; /* No opposite bits follow. */
- X}
- X
- X
- X/* START DECODING A STREAM OF SYMBOLS. */
- X
- Xstart_decoding()
- X{
- X int i;
- X
- X value = input_bit(); /* Check that first bit */
- X if (value!=1) { /* is a 1. */
- X fprintf(stderr,"Bad input file (1)\n");
- X exit(1);
- X }
- X
- X for (i = 1; i<Code_bits; i++) { /* Fill the code value with */
- X value += value; /* input bits. */
- X value += input_bit();
- X }
- X
- X low = Code_half; /* Use half the code region */
- X range = Code_half; /* (first bit must be 1). */
- X}
- X
- X
- X/* ENCODE A SYMBOL. */
- X
- Xencode_symbol(symbol,cum_freq)
- X int symbol; /* Symbol to encode */
- X freq_value cum_freq[]; /* Cumulative symbol frequencies */
- X{
- X narrow_region(cum_freq,symbol,0); /* Narrow coding region. */
- X push_out_bits(); /* Output determined bits. */
- X}
- X
- X
- X/* ENCODE A BIT. */
- X
- Xencode_bit(bit,freq0,freq1)
- X int bit; /* Bit to encode (0 or 1) */
- X freq_value freq0; /* Frequency for 0 bit */
- X freq_value freq1; /* Frequency for 1 bit */
- X{
- X code_value split;
- X
- X if (freq1>freq0) { /* Encode bit when most */
- X split = split_region(freq0,freq1); /* probable symbol is a 1. */
- X if (bit) { low += split; range -= split; }
- X else { range = split; }
- X }
- X
- X else { /* Encode bit when most */
- X split = split_region(freq1,freq0); /* probable symbol is a 0. */
- X if (bit) { range = split; }
- X else { low += split; range -= split; }
- X }
- X
- X push_out_bits(); /* Output determined bits. */
- X}
- X
- X
- X/* DECODE THE NEXT SYMBOL. */
- X
- Xint decode_symbol(cum_freq)
- X freq_value cum_freq[]; /* Cumulative symbol frequencies */
- X{
- X int symbol; /* Symbol decoded */
- X
- X symbol = find_symbol(cum_freq); /* Find decoded symbol. */
- X narrow_region(cum_freq,symbol,1); /* Narrow coding region. */
- X discard_bits(); /* Discard output bits. */
- X
- X return symbol;
- X}
- X
- X
- X/* DECODE A BIT. */
- X
- Xint decode_bit(freq0,freq1)
- X freq_value freq0; /* Frequency for 0 bit */
- X freq_value freq1; /* Frequency for 1 bit */
- X{
- X code_value split;
- X int bit;
- X
- X if (freq1>freq0) { /* Decode bit when most */
- X split = split_region(freq0,freq1); /* probable symbol is a 1. */
- X bit = value-low >= split;
- X if (bit) { low += split; range -= split; }
- X else { range = split; }
- X }
- X
- X else { /* Decode bit when most */
- X split = split_region(freq1,freq0); /* probable symbol is a 0. */
- X bit = value-low < split;
- X if (bit) { range = split; }
- X else { low += split; range -= split; }
- X }
- X
- X discard_bits(); /* Discard output bits. */
- X
- X return bit;
- X}
- X
- X
- X/* DETERMINE DECODED SYMBOL FROM INPUT VALUE. */
- X
- Xstatic int find_symbol(cum_freq)
- X freq_value cum_freq[]; /* Cumulative symbol frequencies */
- X{
- X freq_value cum; /* Cumulative frequency calculated */
- X int symbol; /* Symbol decoded */
- X
- X F = range / cum_freq[0]; /* Compute common factor. */
- X
- X cum = (value-low) / F; /* Compute target cum freq. */
- X for (symbol = 1; cum_freq[symbol]>cum; symbol++) ; /* Then find symbol. */
- X
- X return symbol;
- X}
- X
- X
- X/* NARROW CODING REGION TO THAT ALLOTTED TO SYMBOL. */
- X
- Xstatic narrow_region(cum_freq,symbol,have_F)
- X freq_value cum_freq[]; /* Cumulative symbol frequencies */
- X int symbol; /* Symbol decoded */
- X int have_F; /* Is F already computed? */
- X{
- X code_value T; /* Temporary value */
- X
- X if (!have_F) F = range / cum_freq[0]; /* Compute common factor. */
- X
- X if (symbol==1) { /* Narrow range for symbol */
- X T = F * cum_freq[symbol]; /* at the top. */
- X low += T;
- X range -= T;
- X }
- X
- X else { /* Narrow range for symbol */
- X T = F * cum_freq[symbol]; /* not at the top. */
- X low += T;
- X range = F * cum_freq[symbol-1] - T;
- X }
- X}
- X
- X
- X/* FIND BINARY SPLIT FOR CODING REGION. */
- X
- Xstatic code_value split_region(freq_b,freq_t)
- X freq_value freq_b; /* Frequency for symbol in bottom half */
- X freq_value freq_t; /* Frequency for symbol in top half */
- X{
- X return freq_b * (range / (freq_b+freq_t));
- X}
- X
- X
- X/* OUTPUT BITS THAT ARE NOW DETERMINED. */
- X
- Xstatic push_out_bits()
- X{
- X while (range<=Code_quarter) {
- X
- X if (low>=Code_half) { /* Output 1 if in top half.*/
- X bit_plus_follow(1);
- X low -= Code_half; /* Subtract offset to top. */
- X }
- X
- X else if (low+range<=Code_half) { /* Output 0 in bottom half. */
- X bit_plus_follow(0);
- X }
- X
- X else { /* Output an opposite bit */
- X bits_to_follow += 1; /* later if in middle half. */
- X low -= Code_quarter; /* Subtract offset to middle*/
- X }
- X
- X low += low; /* Scale up code region. */
- X range += range;
- X }
- X}
- X
- X
- X/* DISCARD BITS THE ENCODER WOULD HAVE OUTPUT. */
- X
- Xstatic discard_bits()
- X{
- X while (range<=Code_quarter) {
- X
- X if (low>=Code_half) { /* Expand top half. */
- X low -= Code_half; /* Subtract offset to top. */
- X value -= Code_half;
- X }
- X
- X else if (low+range<=Code_half) { /* Expand bottom half. */
- X /* nothing */
- X }
- X
- X else { /* Expand middle half. */
- X low -= Code_quarter; /* Subtract offset to middle*/
- X value -= Code_quarter;
- X }
- X
- X low += low; /* Scale up code region. */
- X range += range;
- X
- X value += value; /* Move in next input bit. */
- X value += input_bit();
- X }
- X}
- X
- X
- X/* FINISH ENCODING THE STREAM. */
- X
- Xdone_encoding()
- X{
- X for (;;) {
- X
- X if (low+(range>>1)>=Code_half) { /* Output a 1 if mostly in */
- X bit_plus_follow(1); /* top half. */
- X range = low+range-Code_half;
- X low = low<Code_half ? 0 : low-Code_half;
- X }
- X
- X else { /* Output a 0 if mostly in */
- X bit_plus_follow(0); /* bottom half. */
- X if (low+range>Code_half) {
- X range = Code_half-low;
- X }
- X }
- X
- X if (range==Code_half) break; /* Quit when coding region */
- X /* becomes entire interval. */
- X low += low;
- X range += range; /* Scale up code region. */
- X }
- X}
- END_OF_FILE
- if test 7887 -ne `wc -c <'code_mul.c'`; then
- echo shar: \"'code_mul.c'\" unpacked with wrong size!
- fi
- # end of 'code_mul.c'
- fi
- if test -f 'code_sft.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'code_sft.c'\"
- else
- echo shar: Extracting \"'code_sft.c'\" \(11930 characters\)
- sed "s/^X//" >'code_sft.c' <<'END_OF_FILE'
- X/* CODE_SFT.C - ARITHMETIC ENCODING/DECODING, USING SHIFT/ADD. */
- X
- X#include <stdio.h>
- X
- X#include "code.h"
- X
- X
- X/* CURRENT STATE OF THE ENCODING/DECODING. */
- X
- Xstatic code_value low; /* Start of current coding region, in [0,1) */
- X
- Xstatic code_value range; /* Size of region, normally kept in the */
- X /* interval [1/4,1/2] */
- X
- Xstatic code_value value; /* Currently-seen code value, in [0,1) */
- X
- Xstatic int bits_to_follow; /* Number of opposite bits to output after */
- X /* the next bit */
- X
- Xstatic code_value split_region();
- X
- X
- X/* OUTPUT BIT PLUS FOLLOWING OPPOSITE BITS. */
- X
- X#define bit_plus_follow(bit) \
- Xdo { \
- X output_bit(bit); /* Output the bit. */\
- X while (bits_to_follow>0) { /* Output bits_to_follow */\
- X output_bit(!(bit)); /* opposite bits. Set */\
- X bits_to_follow -= 1; /* bits_to_follow to zero. */\
- X } \
- X} while (0) \
- X
- X
- X/* START ENCODING A STREAM OF SYMBOLS. */
- X
- Xstart_encoding()
- X{
- X low = Code_half; /* Use half the code region */
- X range = Code_half; /* (wastes first bit as 1). */
- X bits_to_follow = 0; /* No opposite bits follow. */
- X}
- X
- X
- X/* START DECODING A STREAM OF SYMBOLS. */
- X
- Xstart_decoding()
- X{
- X int i;
- X
- X value = input_bit(); /* Check that first bit */
- X if (value!=1) { /* is a 1. */
- X fprintf(stderr,"Bad input file (1)\n");
- X exit(1);
- X }
- X
- X for (i = 1; i<Code_bits; i++) { /* Fill the code value with */
- X value += value; /* input bits. */
- X value += input_bit();
- X }
- X
- X low = Code_half; /* Use half the code region */
- X range = Code_half; /* (first bit must be 1). */
- X}
- X
- X
- X/* ENCODE A SYMBOL. */
- X
- Xencode_symbol(symbol,cum_freq)
- X int symbol; /* Symbol to encode */
- X freq_value cum_freq[]; /* Cumulative symbol frequencies */
- X{
- X narrow_region(cum_freq,symbol); /* Narrow coding region. */
- X push_out_bits(); /* Output determined bits. */
- X}
- X
- X
- X/* ENCODE A BIT. */
- X
- Xencode_bit(bit,freq0,freq1)
- X int bit; /* Bit to encode (0 or 1) */
- X freq_value freq0; /* Frequency for 0 bit */
- X freq_value freq1; /* Frequency for 1 bit */
- X{
- X code_value split;
- X
- X if (freq1>freq0) { /* Encode bit when most */
- X split = split_region(freq0,freq1); /* probable symbol is a 1. */
- X if (bit) { low += split; range -= split; }
- X else { range = split; }
- X }
- X
- X else { /* Encode bit when most */
- X split = split_region(freq1,freq0); /* probable symbol is a 0. */
- X if (bit) { range = split; }
- X else { low += split; range -= split; }
- X }
- X
- X push_out_bits(); /* Output determined bits. */
- X}
- X
- X
- X/* DECODE THE NEXT SYMBOL. */
- X
- Xint decode_symbol(cum_freq)
- X freq_value cum_freq[]; /* Cumulative symbol frequencies */
- X{
- X int symbol; /* Symbol decoded */
- X
- X symbol = find_symbol(cum_freq); /* Find decoded symbol. */
- X narrow_region(cum_freq,symbol); /* Narrow coding region. */
- X discard_bits(); /* Discard output bits. */
- X
- X return symbol;
- X}
- X
- X
- X/* DECODE A BIT. */
- X
- Xint decode_bit(freq0,freq1)
- X freq_value freq0; /* Frequency for 0 bit */
- X freq_value freq1; /* Frequency for 1 bit */
- X{
- X code_value split;
- X int bit;
- X
- X if (freq1>freq0) { /* Decode bit when most */
- X split = split_region(freq0,freq1); /* probable symbol is a 1. */
- X bit = value-low >= split;
- X if (bit) { low += split; range -= split; }
- X else { range = split; }
- X }
- X
- X else { /* Decode bit when most */
- X split = split_region(freq1,freq0); /* probable symbol is a 0. */
- X bit = value-low < split;
- X if (bit) { range = split; }
- X else { low += split; range -= split; }
- X }
- X
- X discard_bits(); /* Discard output bits. */
- X
- X return bit;
- X}
- X
- X
- X/* DETERMINE DECODED SYMBOL FROM INPUT VALUE. */
- X
- Xstatic int find_symbol(cum_freq)
- X freq_value cum_freq[]; /* Cumulative symbol frequencies */
- X{
- X int symbol; /* Symbol decoded */
- X freq_value M, P, Q, B; /* Temporary values */
- X div_value F, G;
- X code_value A;
- X
- X A = range; /* Compute the value of */
- X M = cum_freq[0] << (Code_bits-Freq_bits-1); /* F = range/cum_freq[0]. */
- X F = 0;
- X
- X if (A>=M) { A -= M; F += 1; }
- X# if Code_bits-Freq_bits>2
- X A <<= 1; F <<= 1;
- X if (A>=M) { A -= M; F += 1; }
- X# endif
- X# if Code_bits-Freq_bits>3
- X A <<= 1; F <<= 1;
- X if (A>=M) { A -= M; F += 1; }
- X# endif
- X# if Code_bits-Freq_bits>4
- X A <<= 1; F <<= 1;
- X if (A>=M) { A -= M; F += 1; }
- X# endif
- X# if Code_bits-Freq_bits>5
- X A <<= 1; F <<= 1;
- X if (A>=M) { A -= M; F += 1; }
- X# endif
- X# if Code_bits-Freq_bits>6
- X for (i = Code_bits-Freq_bits-6; i>0; i--) {
- X A <<= 1; F <<= 1;
- X if (A>=M) { A -= M; F += 1; }
- X }
- X# endif
- X A <<= 1; F <<= 1;
- X if (A>=M) { F += 1; }
- X
- X A = value - low; /* Find the symbol that */
- X B = Freq_half; /* fits the input. To do */
- X G = F << (Freq_bits-1); /* so compute (value-low)/F */
- X P = 0; /* to as many bits as is */
- X Q = cum_freq[0]; /* necessary. */
- X symbol = 1;
- X
- X while (cum_freq[symbol]>P) {
- X if (A>=G) {
- X A -= G;
- X P = P+B;
- X }
- X else {
- X Q = P+B;
- X while (cum_freq[symbol]>=Q) symbol += 1;
- X }
- X B >>= 1; G >>= 1;
- X }
- X
- X return symbol;
- X}
- X
- X
- X/* NARROW CODING REGION TO THAT ALLOTTED TO SYMBOL. */
- X
- Xstatic narrow_region(cum_freq,symbol)
- X freq_value cum_freq[]; /* Cumulative symbol frequencies */
- X int symbol; /* Symbol decoded */
- X{
- X code_value A, Ta, Tb; /* Temporary values */
- X freq_value M, Ba, Bb;
- X int i;
- X
- X A = range;
- X M = cum_freq[0] << (Code_bits-Freq_bits-1);
- X
- X if (symbol==1) { /* Narrow range for symbol */
- X /* at the top. */
- X Ba = cum_freq[symbol];
- X Ta = 0; /* Compute the value of */
- X /* Ta = cum_freq[symbol] */
- X if (A>=M) { A -= M; Ta += Ba; } /* * (range/cum_freq[0])*/
- X# if Code_bits-Freq_bits>2
- X A <<= 1; Ta <<= 1;
- X if (A>=M) { A -= M; Ta += Ba; }
- X# endif
- X# if Code_bits-Freq_bits>3
- X A <<= 1; Ta <<= 1;
- X if (A>=M) { A -= M; Ta += Ba; }
- X# endif
- X# if Code_bits-Freq_bits>4
- X A <<= 1; Ta <<= 1;
- X if (A>=M) { A -= M; Ta += Ba; }
- X# endif
- X# if Code_bits-Freq_bits>5
- X A <<= 1; Ta <<= 1;
- X if (A>=M) { A -= M; Ta += Ba; }
- X# endif
- X# if Code_bits-Freq_bits>6
- X for (i = Code_bits-Freq_bits-6; i>0; i--) {
- X A <<= 1; Ta <<= 1;
- X if (A>=M) { A -= M; Ta += Ba; }
- X }
- X# endif
- X A <<= 1; Ta <<= 1;
- X if (A>=M) { Ta += Ba; }
- X
- X low += Ta;
- X range -= Ta;
- X }
- X
- X else { /* Narrow range for symbol */
- X /* not at the top. */
- X Ba = cum_freq[symbol];
- X Bb = cum_freq[symbol-1]; /* Compute the value of */
- X Ta = Tb = 0; /* Ta = cum_freq[symbol] */
- X /* * (range/cum_freq[0])*/
- X if (A>=M) { A -= M; Ta += Ba; Tb += Bb; }/*and of */
- X# if Code_bits-Freq_bits>2 /* Tb = cum_freq[symbol-1]*/
- X A <<= 1; Ta <<= 1; Tb <<= 1; /* * (range/cum_freq[0] */
- X if (A>=M) { A -= M; Ta += Ba; Tb += Bb; }
- X# endif
- X# if Code_bits-Freq_bits>3
- X A <<= 1; Ta <<= 1; Tb <<= 1;
- X if (A>=M) { A -= M; Ta += Ba; Tb += Bb; }
- X# endif
- X# if Code_bits-Freq_bits>4
- X A <<= 1; Ta <<= 1; Tb <<= 1;
- X if (A>=M) { A -= M; Ta += Ba; Tb += Bb; }
- X# endif
- X# if Code_bits-Freq_bits>5
- X A <<= 1; Ta <<= 1; Tb <<= 1;
- X if (A>=M) { A -= M; Ta += Ba; Tb += Bb; }
- X# endif
- X# if Code_bits-Freq_bits>6
- X for (i = Code_bits-Freq_bits-6; i>0; i--) {
- X A <<= 1; Ta <<= 1; Tb <<= 1;
- X if (A>=M) { A -= M; Ta += Ba; Tb += Bb; }
- X }
- X# endif
- X A <<= 1; Ta <<= 1; Tb <<= 1;
- X if (A>=M) { Ta += Ba; Tb += Bb; }
- X
- X low += Ta;
- X range = Tb - Ta;
- X }
- X}
- X
- X
- X/* FIND BINARY SPLIT FOR CODING REGION. */
- X
- Xstatic code_value split_region(freq_b,freq_t)
- X freq_value freq_b; /* Frequency for symbol in bottom half */
- X freq_value freq_t; /* Frequency for symbol in top half */
- X{
- X code_value A, T; /* Temporary values */
- X freq_value M, B;
- X int i;
- X
- X A = range;
- X M = (freq_b+freq_t) << (Code_bits-Freq_bits-1);
- X B = freq_b;
- X T = 0; /* Compute the value of */
- X /* T = freq_b * (range */
- X if (A>=M) { A -= M; T += B; } /* / (freq_b+freq_t)) */
- X# if Code_bits-Freq_bits>2
- X A <<= 1; T <<= 1;
- X if (A>=M) { A -= M; T += B; }
- X# endif
- X# if Code_bits-Freq_bits>3
- X A <<= 1; T <<= 1;
- X if (A>=M) { A -= M; T += B; }
- X# endif
- X# if Code_bits-Freq_bits>4
- X A <<= 1; T <<= 1;
- X if (A>=M) { A -= M; T += B; }
- X# endif
- X# if Code_bits-Freq_bits>5
- X A <<= 1; T <<= 1;
- X if (A>=M) { A -= M; T += B; }
- X# endif
- X# if Code_bits-Freq_bits>6
- X for (i = Code_bits-Freq_bits-6; i>0; i--) {
- X A <<= 1; T <<= 1;
- X if (A>=M) { A -= M; T += B; }
- X }
- X# endif
- X A <<= 1; T <<= 1;
- X if (A>=M) { T += B; }
- X
- X return T;
- X}
- X
- X
- X/* OUTPUT BITS THAT ARE NOW DETERMINED. */
- X
- Xstatic push_out_bits()
- X{
- X while (range<=Code_quarter) {
- X
- X if (low>=Code_half) { /* Output 1 if in top half.*/
- X bit_plus_follow(1);
- X low -= Code_half; /* Subtract offset to top. */
- X }
- X
- X else if (low+range<=Code_half) { /* Output 0 in bottom half. */
- X bit_plus_follow(0);
- X }
- X
- X else { /* Output an opposite bit */
- X bits_to_follow += 1; /* later if in middle half. */
- X low -= Code_quarter; /* Subtract offset to middle*/
- X }
- X
- X low += low; /* Scale up code region. */
- X range += range;
- X }
- X}
- X
- X
- X/* DISCARD BITS THE ENCODER WOULD HAVE OUTPUT. */
- X
- Xstatic discard_bits()
- X{
- X while (range<=Code_quarter) {
- X
- X if (low>=Code_half) { /* Expand top half. */
- X low -= Code_half; /* Subtract offset to top. */
- X value -= Code_half;
- X }
- X
- X else if (low+range<=Code_half) { /* Expand bottom half. */
- X /* nothing */
- X }
- X
- X else { /* Expand middle half. */
- X low -= Code_quarter; /* Subtract offset to middle*/
- X value -= Code_quarter;
- X }
- X
- X low += low; /* Scale up code region. */
- X range += range;
- X
- X value += value; /* Move in next input bit. */
- X value += input_bit();
- X }
- X}
- X
- X
- X/* FINISH ENCODING THE STREAM. */
- X
- Xdone_encoding()
- X{
- X for (;;) {
- X
- X if (low+(range>>1)>=Code_half) { /* Output a 1 if mostly in */
- X bit_plus_follow(1); /* top half. */
- X range = low+range-Code_half;
- X low = low<Code_half ? 0 : low-Code_half;
- X }
- X
- X else { /* Output a 0 if mostly in */
- X bit_plus_follow(0); /* bottom half. */
- X if (low+range>Code_half) {
- X range = Code_half-low;
- X }
- X }
- X
- X if (range==Code_half) break; /* Quit when coding region */
- X /* becomes entire interval. */
- X low += low;
- X range += range; /* Scale up code region. */
- X }
- X}
- END_OF_FILE
- if test 11930 -ne `wc -c <'code_sft.c'`; then
- echo shar: \"'code_sft.c'\" unpacked with wrong size!
- fi
- # end of 'code_sft.c'
- fi
- if test -f 'decode.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'decode.c'\"
- else
- echo shar: Extracting \"'decode.c'\" \(751 characters\)
- sed "s/^X//" >'decode.c' <<'END_OF_FILE'
- X/* DECODE.C - MAIN PROGRAM FOR DECODING. */
- X
- X#include <stdio.h>
- X
- X#include "code.h"
- X#include "model.h"
- X
- Xmain()
- X{
- X int symbol; /* Character to decoded as a symbol index */
- X int ch; /* Character to decoded as a character code */
- X
- X start_model(); /* Set up other modules. */
- X start_inputing_bits();
- X start_decoding();
- X
- X for (;;) { /* Loop through characters. */
- X
- X symbol = decode_symbol(cum_freq); /* Decode next symbol. */
- X if (symbol==EOF_symbol) break; /* Exit loop if EOF symbol. */
- X ch = index_to_char[symbol]; /* Translate to a character.*/
- X putc(ch,stdout); /* Write that character. */
- X update_model(symbol); /* Update the model. */
- X }
- X
- X exit(0);
- X}
- END_OF_FILE
- if test 751 -ne `wc -c <'decode.c'`; then
- echo shar: \"'decode.c'\" unpacked with wrong size!
- fi
- # end of 'decode.c'
- fi
- if test -f 'decpic.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'decpic.c'\"
- else
- echo shar: Extracting \"'decpic.c'\" \(1783 characters\)
- sed "s/^X//" >'decpic.c' <<'END_OF_FILE'
- X/* DECPIC.C - MAIN PROGRAM FOR DECODING PICTURES. */
- X
- X#include <stdio.h>
- X
- X#include "code.h"
- X
- X#define Height 40 /* Height of images */
- X#define Width 40 /* Width of images */
- X
- Xstatic int image[Height][Width]; /* The image to be encoded */
- X
- Xstatic int freq0[2][2]; /* Frequencies of '0' in contexts */
- Xstatic int freq1[2][2]; /* Frequencies of '1' in contexts */
- X
- Xstatic int inc[2][2]; /* Current increment */
- X
- Xmain()
- X{
- X int i, j, a, l;
- X
- X start_inputing_bits();
- X start_decoding();
- X
- X /* Initialize model. */
- X
- X for (a = 0; a<2; a++) {
- X for (l = 0; l<2; l++) {
- X inc[a][l] = Freq_half;
- X freq0[a][l] = inc[a][l]; /* Set frequencies of 0's */
- X freq1[a][l] = inc[a][l]; /* and 1's to be equal. */
- X }
- X }
- X
- X /* Decode and write image. */
- X
- X for (i = 0; i<Height; i++) {
- X for (j = 0; j<Width; j++) {
- X a = i==0 ? 0 : image[i-1][j]; /* Find current context. */
- X l = j==0 ? 0 : image[i][j-1];
- X image[i][j] = /* Decode pixel. */
- X decode_bit(freq0[a][l],freq1[a][l]);
- X printf("%c%c",image[i][j] ? '#' : '.',
- X j==Width-1 ? '\n' : ' ');
- X if (image[i][j]) { /* Update frequencies for */
- X freq1[a][l] += inc[a][l]; /* this context. */
- X }
- X else {
- X freq0[a][l] += inc[a][l];
- X }
- X if (freq0[a][l]+freq1[a][l]>Freq_full) {
- X freq0[a][l] = (freq0[a][l]+1) >> 1;
- X freq1[a][l] = (freq1[a][l]+1) >> 1;
- X if (inc[a][l]>1) inc[a][l] >>= 1;
- X }
- X }
- X }
- X
- X exit(0);
- X}
- END_OF_FILE
- if test 1783 -ne `wc -c <'decpic.c'`; then
- echo shar: \"'decpic.c'\" unpacked with wrong size!
- fi
- # end of 'decpic.c'
- fi
- if test -f 'encode.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'encode.c'\"
- else
- echo shar: Extracting \"'encode.c'\" \(899 characters\)
- sed "s/^X//" >'encode.c' <<'END_OF_FILE'
- X/* ENCODE.C - MAIN PROGRAM FOR ENCODING. */
- X
- X#include <stdio.h>
- X
- X#include "code.h"
- X#include "model.h"
- X
- Xmain()
- X{
- X int ch; /* Character to encode as a character code */
- X int symbol; /* Character to encode as a symbol index */
- X
- X start_model(); /* Set up other modules. */
- X start_outputing_bits();
- X start_encoding();
- X
- X for (;;) { /* Loop through characters. */
- X
- X ch = getc(stdin); /* Read the next character. */
- X if (ch==EOF) break; /* Exit loop on end-of-file.*/
- X symbol = char_to_index[ch]; /* Translate to an index. */
- X encode_symbol(symbol,cum_freq); /* Encode that symbol. */
- X update_model(symbol); /* Update the model. */
- X }
- X
- X encode_symbol(EOF_symbol,cum_freq); /* Encode the EOF symbol. */
- X
- X done_encoding(); /* Send the last few bits. */
- X done_outputing_bits();
- X
- X exit(0);
- X}
- END_OF_FILE
- if test 899 -ne `wc -c <'encode.c'`; then
- echo shar: \"'encode.c'\" unpacked with wrong size!
- fi
- # end of 'encode.c'
- fi
- if test -f 'encpic.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'encpic.c'\"
- else
- echo shar: Extracting \"'encpic.c'\" \(2283 characters\)
- sed "s/^X//" >'encpic.c' <<'END_OF_FILE'
- X/* ENCPIC.C - MAIN PROGRAM FOR ENCODING PICTURES. */
- X
- X#include <stdio.h>
- X
- X#include "code.h"
- X
- X#define Height 40 /* Height of images */
- X#define Width 40 /* Width of images */
- X
- Xstatic int image[Height][Width]; /* The image to be encoded */
- X
- Xstatic int freq0[2][2]; /* Frequencies of '0' in contexts */
- Xstatic int freq1[2][2]; /* Frequencies of '1' in contexts */
- X
- Xstatic int inc[2][2]; /* Current increment */
- X
- Xmain()
- X{
- X int i, j, a, l, ch;
- X
- X start_outputing_bits();
- X start_encoding();
- X
- X /* Read image. */
- X
- X for (i = 0; i<Height; i++) {
- X for (j = 0; j<Width; j++) {
- X do {
- X ch = getc(stdin); /* Read the next character, */
- X } while (ch=='\n' || ch==' '); /* ignoring whitespace. */
- X if (ch!='.' && ch!='#') { /* Check for bad character. */
- X fprintf(stderr,"Bad image file\n");
- X exit(-1);
- X }
- X image[i][j] = ch=='#'; /* Convert char to pixel. */
- X }
- X }
- X
- X /* Initialize model. */
- X
- X for (a = 0; a<2; a++) {
- X for (l = 0; l<2; l++) {
- X inc[a][l] = Freq_half;
- X freq0[a][l] = inc[a][l]; /* Set frequencies of 0's */
- X freq1[a][l] = inc[a][l]; /* and 1's to be equal. */
- X }
- X }
- X
- X /* Encode image. */
- X
- X for (i = 0; i<Height; i++) {
- X for (j = 0; j<Width; j++) {
- X a = i==0 ? 0 : image[i-1][j]; /* Find current context. */
- X l = j==0 ? 0 : image[i][j-1];
- X encode_bit(image[i][j], /* Encode pixel. */
- X freq0[a][l],freq1[a][l]);
- X if (image[i][j]) { /* Update frequencies for */
- X freq1[a][l] += inc[a][l]; /* this context. */
- X }
- X else {
- X freq0[a][l] += inc[a][l];
- X }
- X if (freq0[a][l]+freq1[a][l]>Freq_full) {
- X freq0[a][l] = (freq0[a][l]+1) >> 1;
- X freq1[a][l] = (freq1[a][l]+1) >> 1;
- X if (inc[a][l]>1) inc[a][l] >>= 1;
- X }
- X }
- X }
- X
- X done_encoding(); /* Send the last few bits. */
- X done_outputing_bits();
- X
- X exit(0);
- X}
- END_OF_FILE
- if test 2283 -ne `wc -c <'encpic.c'`; then
- echo shar: \"'encpic.c'\" unpacked with wrong size!
- fi
- # end of 'encpic.c'
- fi
- if test -f 'model.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'model.c'\"
- else
- echo shar: Extracting \"'model.c'\" \(2318 characters\)
- sed "s/^X//" >'model.c' <<'END_OF_FILE'
- X/* MODEL.C - THE ADAPTIVE SOURCE MODEL */
- X
- X#include <stdio.h>
- X
- X#include "code.h"
- X#include "model.h"
- X
- Xstatic freq_value freq[No_of_symbols+1]; /* Symbol frequencies */
- Xstatic freq_value inc; /* Value to increment frequencies by */
- X
- X
- X/* INITIALIZE THE MODEL. */
- X
- Xstart_model()
- X{
- X int i;
- X
- X for (i = 0; i<No_of_chars; i++) { /* Set up tables that */
- X char_to_index[i] = i+1; /* translate between symbol */
- X index_to_char[i+1] = i; /* indexes and characters. */
- X }
- X
- X inc = 1;
- X while (inc*No_of_symbols<=Freq_half) { /* Find increment that puts */
- X inc *= 2; /* total in required range. */
- X }
- X
- X cum_freq[No_of_symbols] = 0; /* Set up initial frequency */
- X for (i = No_of_symbols; i>0; i--) { /* counts to be equal for */
- X freq[i] = inc; /* all symbols. */
- X cum_freq[i-1] = cum_freq[i] + freq[i];
- X }
- X
- X freq[0] = 0; /* Freq[0] must not be the */
- X /* same as freq[1]. */
- X}
- X
- X
- X/* UPDATE THE MODEL TO ACCOUNT FOR A NEW SYMBOL. */
- X
- Xupdate_model(symbol)
- X int symbol; /* Index of new symbol */
- X{
- X int ch_i, ch_symbol; /* Temporaries for exchanging symbols */
- X int i;
- X
- X for (i = symbol; freq[i]==freq[i-1]; i--) ; /* Find symbol's new index. */
- X
- X if (i<symbol) {
- X ch_i = index_to_char[i]; /* Update the translation */
- X ch_symbol = index_to_char[symbol]; /* tables if the symbol has */
- X index_to_char[i] = ch_symbol; /* moved. */
- X index_to_char[symbol] = ch_i;
- X char_to_index[ch_i] = symbol;
- X char_to_index[ch_symbol] = i;
- X }
- X
- X freq[i] += inc; /* Increment the frequency */
- X while (i>0) { /* count for the symbol and */
- X i -= 1; /* update the cumulative */
- X cum_freq[i] += inc; /* frequencies. */
- X }
- X
- X if (cum_freq[0]>Freq_full) { /* See if frequency counts */
- X cum_freq[No_of_symbols] = 0; /* are past their maximum. */
- X for (i = No_of_symbols; i>=0; i--) { /* If so, halve all counts */
- X freq[i] = (freq[i]+1) >> 1; /* (keeping them non-zero). */
- X cum_freq[i-1] = cum_freq[i] + freq[i];
- X }
- X if (inc>1) inc >>= 1; /* Halve increment if can. */
- X }
- X}
- END_OF_FILE
- if test 2318 -ne `wc -c <'model.c'`; then
- echo shar: \"'model.c'\" unpacked with wrong size!
- fi
- # end of 'model.c'
- fi
- if test -f 'model.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'model.h'\"
- else
- echo shar: Extracting \"'model.h'\" \(848 characters\)
- sed "s/^X//" >'model.h' <<'END_OF_FILE'
- X/* MODEL.H - INTERFACE TO THE MODEL. */
- X
- X
- X/* THE SET OF SYMBOLS THAT MAY BE ENCODED. Symbols are indexed by integers
- X from 1 to No_of_symbols. */
- X
- X#define No_of_chars 256 /* Number of character symbols */
- X#define EOF_symbol (No_of_chars+1) /* Index of EOF symbol */
- X
- X#define No_of_symbols (No_of_chars+1) /* Total number of symbols */
- X
- X
- X/* TRANSLATION TABLES BETWEEN CHARACTERS AND SYMBOL INDEXES. */
- X
- Xint char_to_index[No_of_chars]; /* To index from character */
- Xunsigned char index_to_char[No_of_symbols+1]; /* To character from index */
- X
- X
- X/* CUMULATIVE FREQUENCY TABLE. Cumulative frequencies are stored as
- X partially normalized counts. The normalization factor is cum_freq[0],
- X which must lie in the range (1/2,1]. */
- X
- Xfreq_value cum_freq[No_of_symbols+1]; /* Cumulative symbol frequencies */
- END_OF_FILE
- if test 848 -ne `wc -c <'model.h'`; then
- echo shar: \"'model.h'\" unpacked with wrong size!
- fi
- # end of 'model.h'
- fi
- if test -f 'redundancy.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'redundancy.c'\"
- else
- echo shar: Extracting \"'redundancy.c'\" \(1597 characters\)
- sed "s/^X//" >'redundancy.c' <<'END_OF_FILE'
- X/* REDUNDANCY.C - PROGRAM TO CALCULATE MAXIMUM CODING INEFFICIENCY. */
- X
- X#include <stdio.h>
- X#include <math.h>
- X
- X
- X/* This program calculates a bound on the expected number of extra bits
- X produced as a result of doing arithmetic coding using divides of a given
- X precision, expressed as a percentage of the optimal coding size. The
- X expectation is calculated on the assumption that the model's symbol
- X probabilities are correct.
- X
- X The bound assumes that the coding range and total frequencies are such
- X as to cause maximum truncation in the division, with the minimum true
- X quotient. The bound varies as a function of the probability, p, of
- X the most probable symbol. All but at most one of the remaining symbols
- X are assumed to have probabilities equal to p (this gives minimum optimal
- X coding size, and hence maximum relative inefficiency). */
- X
- Xmain()
- X{
- X double p;
- X
- X printf(
- X "\nPrecision: 2 3 4 5 6 7 8 9\n\n");
- X
- X for (p = 0.001; p<0.0095; p+=0.001) do_p(p);
- X for (p = 0.010; p<0.9905; p+=0.010) do_p(p);
- X for (p = 0.991; p<0.9995; p+=0.001) do_p(p);
- X
- X exit(0);
- X}
- X
- Xdo_p(p)
- X double p;
- X{
- X int precision, n;
- X double e, opt, excess;
- X
- X printf(" p=%5.3f ",p);
- X for (precision = 2; precision<10; precision++) {
- X e = pow(2.0,-(double)precision)/(0.25+pow(2.0,-(double)precision));
- X n = (int)(1/p);
- X opt = - n*p*log(p);
- X if (n*p!=1) opt -= (1-n*p)*log(1-n*p);
- X excess = - (1-p)*log(1-e) - p*log(1-e+e/p);
- X printf(" %5.2f",100*excess/opt);
- X }
- X printf("\n");
- X}
- END_OF_FILE
- if test 1597 -ne `wc -c <'redundancy.c'`; then
- echo shar: \"'redundancy.c'\" unpacked with wrong size!
- fi
- # end of 'redundancy.c'
- fi
- if test -f 'tstpic' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'tstpic'\"
- else
- echo shar: Extracting \"'tstpic'\" \(3200 characters\)
- sed "s/^X//" >'tstpic' <<'END_OF_FILE'
- X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
- X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
- X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
- X. . . # # . . . . . . . . . . . . . . . . . . . . . . # . . . . . . . . . . . .
- X. . . # # . . . . . . . . . . . . . . . . . . . # . # . . . . . . . . . . . . .
- X. . . # # . . . . . . . . . . . . . . . . . # # # # . . . . . . . . . . . . . .
- X. . . . . . . . . . # # . . . . . . . . . . . . . # . . . . . . . . . . . . . .
- X. . . . . . . . # # # # # . . . . . . . . . . . . . . . . . . . . . . . . . . .
- X. . . . . . . . . . # . # . . . . . . . . . . . . . . . . . . . . . . . . . . .
- X. . . . . . . . . . . # . . . . . . . . . . . . . . . . . . . . . . . . . . . .
- X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
- X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
- X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
- X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
- X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
- X# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
- X. . . . . . . . . . . . # # # # . . . . . . . . . . . . . . . . . . . . . . . .
- X. . . . . . . . . . . . . . # . . . . . . . . . . . . . . . . . . . . . . . . .
- X. . . . . . . . . . . . . . . . . . . . . . . . . . . . # # . . . . . . . . . .
- X. . . . . . . . . . . . . . . . . . . . . . . . . . # # # # # # # . . . . . . .
- X. . . . . . . . . . . . . . . . . . . . . . . . . # # # # # # # # . . . . . . .
- X. . . . . . . . . . . . . . . . . . . . . . . . . . # # # # . # # . . . . . . .
- X. . . . . . . . . . . . . . . . . . . . . . . . . . # # # # # # # . . . . . . .
- X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . # # # . . . . . . . .
- X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
- X. . . . . . . . . # # . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
- X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
- X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
- X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
- X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
- X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
- X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
- X. . . . . . . . . . . . . . . . . . . . . . . . . . . . # . . . . . . . . . . .
- X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
- X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . #
- X. . . . . # # # . # # # # . . . . . . . . . . . . . . . . . . . . . . . . . # #
- X. . . . . . . . # . . . . # # . . . . . . . . . . . . . . . . . . . . . . . . #
- X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # #
- X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # # #
- X. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # # #
- END_OF_FILE
- if test 3200 -ne `wc -c <'tstpic'`; then
- echo shar: \"'tstpic'\" unpacked with wrong size!
- fi
- # end of 'tstpic'
- fi
- echo shar: End of shell archive.
- exit 0
-
- exit 0 # Just in case...
- --
- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM
- Sterling Software, IMD UUCP: uunet!sparky!kent
- Phone: (402) 291-8300 FAX: (402) 291-4362
- Please send comp.sources.misc-related mail to kent@uunet.uu.net.
-