In [1]:
import numpy as np
In [2]:
# probability of symbols
p = np.array( [ .25, .2, .2, .15, .07, .05, .025, .025, .02, .01] )
# get codeword lengths by rounding towards 0 and mapping to int
# (type conversion being necessary to use cw_lengths as indices)
cw_lengths = np.ceil( - np.log2( p ) )
cw_lengths = cw_lengths.astype( int )
# show probabilities and codewords lengths
print( 'Probabilities:' )
print( 'p = {}\n'.format( p ) )
print( 'Codeword lengths:' )
print( 'L(x_n) = {}'.format( cw_lengths ) )
In [3]:
# function for determining the binary representation of a float
# using predefined number of fractional bits
def get_bin ( q, L):
'''
Multiplying by 2^L, rounding and transforming to bits
'''
q_up = int( q * 2**L )
q_bin = np.binary_repr( q_up, width = L )
return q_bin[ : L ]
In [4]:
# get cdf
# NOTE: 0 is pre-pended in order to realize Q_n = \sum_i=1^n-1 P(x_i)
F = np.cumsum( np.append( 0, p ) )
codewords = [ get_bin( F[ i ] , cw_lengths[ i ] ) for i in range( len( p ) ) ]
# printing
print('Codewords are:\n{}'.format( codewords ) )
In [5]:
# Printing various information
print('Max. Entropie: \t\t\tH0 = {:2.3f}'.format( np.log2(len(p))) )
print('Entropy: \t\t\tH(X) = {:2.3f}'.format( -np.sum( p * np.log2( p ) ) ) )
# get and print average codeword length
L = np.sum( [ len( codewords[i] ) * p[i] for i in range(len(p)) ] )
print('Average codeword length: \tL = {:2.3f}'.format( L ) )
In [6]:
###
# you may, for example, optimize the generated code by eliminating
# unnecessary bits
###
# your code ###
In [ ]: