{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "Entropic Coding and Compression\n", "===============================\n", "\n", "*Important:* Please read the [installation page](http://gpeyre.github.io/numerical-tours/installation_python/) for details about how to install the toolboxes.\n", "$\\newcommand{\\dotp}[2]{\\langle #1, #2 \\rangle}$\n", "$\\newcommand{\\enscond}[2]{\\lbrace #1, #2 \\rbrace}$\n", "$\\newcommand{\\pd}[2]{ \\frac{ \\partial #1}{\\partial #2} }$\n", "$\\newcommand{\\umin}[1]{\\underset{#1}{\\min}\\;}$\n", "$\\newcommand{\\umax}[1]{\\underset{#1}{\\max}\\;}$\n", "$\\newcommand{\\umin}[1]{\\underset{#1}{\\min}\\;}$\n", "$\\newcommand{\\uargmin}[1]{\\underset{#1}{argmin}\\;}$\n", "$\\newcommand{\\norm}[1]{\\|#1\\|}$\n", "$\\newcommand{\\abs}[1]{\\left|#1\\right|}$\n", "$\\newcommand{\\choice}[1]{ \\left\\{ \\begin{array}{l} #1 \\end{array} \\right. }$\n", "$\\newcommand{\\pa}[1]{\\left(#1\\right)}$\n", "$\\newcommand{\\diag}[1]{{diag}\\left( #1 \\right)}$\n", "$\\newcommand{\\qandq}{\\quad\\text{and}\\quad}$\n", "$\\newcommand{\\qwhereq}{\\quad\\text{where}\\quad}$\n", "$\\newcommand{\\qifq}{ \\quad \\text{if} \\quad }$\n", "$\\newcommand{\\qarrq}{ \\quad \\Longrightarrow \\quad }$\n", "$\\newcommand{\\ZZ}{\\mathbb{Z}}$\n", "$\\newcommand{\\CC}{\\mathbb{C}}$\n", "$\\newcommand{\\RR}{\\mathbb{R}}$\n", "$\\newcommand{\\EE}{\\mathbb{E}}$\n", "$\\newcommand{\\Zz}{\\mathcal{Z}}$\n", "$\\newcommand{\\Ww}{\\mathcal{W}}$\n", "$\\newcommand{\\Vv}{\\mathcal{V}}$\n", "$\\newcommand{\\Nn}{\\mathcal{N}}$\n", "$\\newcommand{\\NN}{\\mathcal{N}}$\n", "$\\newcommand{\\Hh}{\\mathcal{H}}$\n", "$\\newcommand{\\Bb}{\\mathcal{B}}$\n", "$\\newcommand{\\Ee}{\\mathcal{E}}$\n", "$\\newcommand{\\Cc}{\\mathcal{C}}$\n", "$\\newcommand{\\Gg}{\\mathcal{G}}$\n", "$\\newcommand{\\Ss}{\\mathcal{S}}$\n", "$\\newcommand{\\Pp}{\\mathcal{P}}$\n", "$\\newcommand{\\Ff}{\\mathcal{F}}$\n", "$\\newcommand{\\Xx}{\\mathcal{X}}$\n", "$\\newcommand{\\Mm}{\\mathcal{M}}$\n", "$\\newcommand{\\Ii}{\\mathcal{I}}$\n", "$\\newcommand{\\Dd}{\\mathcal{D}}$\n", "$\\newcommand{\\Ll}{\\mathcal{L}}$\n", "$\\newcommand{\\Tt}{\\mathcal{T}}$\n", "$\\newcommand{\\si}{\\sigma}$\n", "$\\newcommand{\\al}{\\alpha}$\n", "$\\newcommand{\\la}{\\lambda}$\n", "$\\newcommand{\\ga}{\\gamma}$\n", "$\\newcommand{\\Ga}{\\Gamma}$\n", "$\\newcommand{\\La}{\\Lambda}$\n", "$\\newcommand{\\si}{\\sigma}$\n", "$\\newcommand{\\Si}{\\Sigma}$\n", "$\\newcommand{\\be}{\\beta}$\n", "$\\newcommand{\\de}{\\delta}$\n", "$\\newcommand{\\De}{\\Delta}$\n", "$\\newcommand{\\phi}{\\varphi}$\n", "$\\newcommand{\\th}{\\theta}$\n", "$\\newcommand{\\om}{\\omega}$\n", "$\\newcommand{\\Om}{\\Omega}$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This numerical tour studies source coding using entropic coders (Huffman and arithmetic)." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "using PyPlot\n", "using NtToolBox" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Source Coding and Entropy\n", "-------------------------\n", "Entropic coding converts a vector $x$ of integers into a binary stream\n", "$y$. Entropic coding exploits the\n", "redundancies in the statistical distribution of the entries of $x$ to\n", "reduce as much as possible the size of $y$. The lower bound for the\n", "number of bits $p$ of $y$ is the Shannon bound :\n", "\n", "$$p=-\\sum_ih(i)\\log_2(h(i))$$\n", "\n", "where $h(i)$ is the probability of apparition of symbol $i$ in $x$.\n", "\n", "Fist we generate a simple binary signal $x$ so that $0$ has a probability $p$\n", "to appear in $x$.\n", "\n", "Probability of 0." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": true }, "outputs": [], "source": [ "p = 0.1;" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Size.\n" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": true }, "outputs": [], "source": [ "n = 512;" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Signal, should be with token 1,2." ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": true }, "outputs": [], "source": [ "x = (rand(n) .> p) + 1;" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "One can check the probabilities by computing the empirical histogram." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Empirical p = 0.109375" ] } ], "source": [ "h = [sum(x .== 1); sum(x .== 2)]\n", "h = h/sum(h)\n", "\n", "print(\"Empirical p = $(h[1])\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can compute the entropy of the distribution represented as a vector $h$ of proability that should sum to 1.\n", "We take a max to avoid problems with null probabilties." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Entropy = 0.4980278865344765" ] } ], "source": [ "e = - sum(h.*log2([max(e,1e-20) for e in h]))\n", "print(\"Entropy = $e\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Huffman Coding\n", "--------------\n", "A Hufman code $C$ associates to each symbol $i$ in $\\{1,...,m\\}$ a binary code $C_i$\n", "whose length is as close as possible to the optimal bound\n", "$-\\log_2\\left(h(i)\\right)$, where $h(i)$ is the probability of apparition of the\n", "symbol $i$.\n", "\n", "We select a set of proabilities." ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": true }, "outputs": [], "source": [ "h = [.1, .15, .4, .15, .2];" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The tree $T$ contains the codes and is generated by an iterative algorithm.\n", "The initial \"tree\" is a collection of empty trees, pointing to the symbols numbers." ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": true }, "outputs": [], "source": [ "m = length(h)\n", "T=Array{Any,1}(zeros(m)); # create an empty tree" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We build iteratively the Huffman tree\n", "by grouping together the two erees that have the smallest probabilities.\n", "The merged tree has a probability which is the sum of the two selected\n", "probabilities.\n", "\n", "Initial probability." ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": true }, "outputs": [], "source": [ "#we use the symbols i = 0,1,2,3,4 (as strings) with the associated probabilities h(i)\n", "\n", "for i in 1:m\n", " T[i] = (h[i],string(i))\n", "end" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Iterative merging of the leading probabilities." ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": true, "scrolled": true }, "outputs": [], "source": [ "while length(T) > 1\n", "\n", " sort!(T) #sort according to the first values of the tuples (the probabilities)\n", " t = tuple(T[1:2]...)\n", " q = T[1][1] + T[2][1]\n", " T = [T[3:end]; [(q,t)]]\n", "end" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We trim the computed tree by removing the probabilities." ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": true }, "outputs": [], "source": [ "function trim(T)\n", " T0 = T[2]\n", " if typeof(T0) == String\n", " return T0\n", " else\n", " return (trim(T0[1]),trim(T0[2]))\n", " end\n", "end\n", "T = trim(T[1]);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We display the computed tree." ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "PyPlot.Figure(PyObject )" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plot_hufftree(T);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Once the tree $T$ is computed, one can compute the code $C_{i}$\n", "associated to each symbol $i$. This requires to perform a deep first\n", "search in the tree and stop at each node." ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": true }, "outputs": [], "source": [ "codes = Dict()\n", "\n", "function huffman_gencode(T,codes,c)\n", " if typeof(T) == String #test if T is a leaf\n", " codes[T] = c\n", " else\n", " huffman_gencode(T[1],codes, string(c, \"0\"))\n", " huffman_gencode(T[2],codes, string(c, \"1\"))\n", " end\n", "end\n", "\n", "huffman_gencode(T,codes,\"\") ;" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Display the code." ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Code of token 4: 110\n", "Code of token 1: 100\n", "Code of token 5: 111\n", "Code of token 2: 101\n", "Code of token 3: 0\n" ] } ], "source": [ "for e in keys(codes)\n", " println(string(\"Code of token \", e, \": \", codes[e]))\n", "end" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We draw a vector $x$ according to the distribution $h$.\n", "\n", "Size of the signal." ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": true }, "outputs": [], "source": [ "n = 1024;" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Randomization." ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "x = rand_discr(h, m=n);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "__Exercise 1__\n", "\n", "Implement the coding of the vector $x$ to obtain a binary vector $y$, which corresponds to replacing each sybmol $x(i)$ by the code $C_{x(i)}$." ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": true }, "outputs": [], "source": [ "include(\"NtSolutions/coding_2_entropic/exo1.jl\")" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": true }, "outputs": [], "source": [ "## Insert your code here." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Compare the length of the code with the entropy bound." ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Entropy bound = 2197.9538889431196\n", "Huffman code = 2212\n" ] } ], "source": [ "e = - sum(h.*log2([max(e,1e-20) for e in h]))\n", "println(\"Entropy bound = $(n*e)\")\n", "println(\"Huffman code = $(length(y))\") " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Decoding is more complicated, since it requires to iteratively parse the tree $T$." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Initial empty decoded stream." ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": true }, "outputs": [], "source": [ "x1 = [];" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Perform decoding." ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "collapsed": true }, "outputs": [], "source": [ "T0 = T\n", "for e in y\n", " if e == '0'\n", " T0 = T0[1]\n", " else\n", " T0 = T0[2]\n", " end\n", " if typeof(T0) == String\n", " append!(x1,T0)\n", " T0 = T\n", " end\n", "end\n", " " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We test if the decoding is correct." ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Error (should be zero) : 0.0" ] } ], "source": [ "err = norm(x-map(x->parse(Int, x), x1))\n", "print(\"Error (should be zero) : $err\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Huffman Block Coding\n", "--------------------\n", "A Huffman coder is inefficient because it can distribute only an integer\n", "number of bit per symbol. In particular, distribution where one of the\n", "symbol has a large probability are not well coded using a Huffman code.\n", "This can be aleviated by replacing the set of $m$ symbols by $m^q$\n", "symbols obtained by packing the symbols by blocks of $q$ (here we use $m=2$ for a binary alphabet). This breaks\n", "symbols with large probability into many symbols with smaller proablity,\n", "thus approaching the Shannon entropy bound.\n", "\n", "\n", "Generate a binary vector with a high probability of having 1, so that the\n", "Huffman code is not very efficient (far from Shanon bound).\n", "\n", "Proability of having 0." ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "collapsed": true }, "outputs": [], "source": [ "t = .12;" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Probability distriution." ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "collapsed": true }, "outputs": [], "source": [ "h = [t, 1-t];" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Generate signal." ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "collapsed": true }, "outputs": [], "source": [ "n = 4096*2\n", "x = (rand(n) .> t) + 1;" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For block of length $q=3$, create a new vector by coding each block\n", "with an integer in $\\{1,...,m^q=2^3\\}$. The new length of the vector is\n", "$n_1/q$ where $n_1=\\lceil n/q\\rceil q$.\n", "\n", "Block size." ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "collapsed": true }, "outputs": [], "source": [ "q = 3;" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Maximum token value." ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "collapsed": true }, "outputs": [], "source": [ "m = 2;" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "New size." ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "collapsed": true }, "outputs": [], "source": [ "n1 = Int(ceil(n/q)*q);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "New vector." ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "collapsed": true }, "outputs": [], "source": [ "x1 = zeros(n1)\n", "x1[1:length(x)] = x\n", "x1[length(x)+1:end] = 1\n", "x1 = x1 - 1\n", "x2 = []\n", "\n", "mult = [m^j for j in 0:q-1]\n", "for i in 1:q:n1-1\n", " append!(x2,sum(x1[i:i+q-1].*mult)+1)\n", "end" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "collapsed": true }, "outputs": [], "source": [ "H = h\n", "for i in 1:q-1\n", " Hold = H\n", " H = []\n", " for j in 1:length(h)\n", " append!(H,[e*h[j] for e in Hold])\n", " end\n", "end" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A simpler way to compute this block-histogram is to use the Kronecker product." ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "collapsed": true }, "outputs": [], "source": [ "H = h\n", "for i in 1:q-1\n", " H = kron(H, h)\n", "end" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "__Exercise 2__\n", "\n", "For various values of block size $k$, Perform the Huffman coding and compute the length of the code.\n", "Compare with the entropy lower bound." ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Entropy bound = 0.5293608652873644\n", "---\n", "Huffman(block size = 1) = 1.0\n", "Huffman(block size = 2) = 0.676025390625\n", "Huffman(block size = 3) = 0.5728759765625\n" ] }, { "data": { "image/png": "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", "text/plain": [ "PyPlot.Figure(PyObject )" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "Huffman(block size = 4) = 0.54638671875\n", "Huffman(block size = 5) = 0.5390625\n", "Huffman(block size = 6) = 0.5335693359375\n", "Huffman(block size = 7) = 0.5469970703125\n", "Huffman(block size = 8) = 0.5404052734375\n", "Huffman(block size = 9) = 0.5408935546875\n", "Huffman(block size = 10) = 0.5372314453125\n" ] } ], "source": [ "include(\"NtSolutions/coding_2_entropic/exo2.jl\");" ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "collapsed": true }, "outputs": [], "source": [ "## Insert your code here." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "" ] } ], "metadata": { "anaconda-cloud": {}, "kernelspec": { "display_name": "Julia 0.5.0", "language": "julia", "name": "julia-0.5" }, "language_info": { "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", "version": "0.5.0" } }, "nbformat": 4, "nbformat_minor": 1 }