Skip to content

Commit

Permalink
Added elias gamma and delta data compression codings (keon#564)
Browse files Browse the repository at this point in the history
* Added elias gamma and delta data compression algorithms

* Added more info about the codings.
  • Loading branch information
Nikolaos Karampinas authored and keon committed Oct 17, 2019
1 parent ebf96fa commit b6dbcfb
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ If you want to uninstall algorithms, it is as simple as:
- [compression](algorithms/compression)
- [huffman_coding](algorithms/compression/huffman_coding.py)
- [rle_compression](algorithms/compression/rle_compression.py)
- [elias](algorithms/compression/elias.py)
- [dfs](algorithms/dfs)
- [all_factors](algorithms/dfs/all_factors.py)
- [count_islands](algorithms/dfs/count_islands.py)
Expand Down
49 changes: 49 additions & 0 deletions algorithms/compression/elias.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
"""
Elias γ code or Elias gamma code is a universal code encoding positive integers.
It is used most commonly when coding integers whose upper-bound cannot be determined beforehand.
Elias δ code or Elias delta code is a universal code encoding the positive integers,
that includes Elias γ code when calculating.
Both were developed by Peter Elias.
"""
from math import log,ceil

log2 = lambda x: log(x,2)

# Calculates the binary number
def binary(x,l=1):
fmt = '{0:0%db}' % l
return fmt.format(x)

# Calculates the unary number
def unary(x):
return (x-1)*'1'+'0'

def elias_generic(lencoding, x):
"""
The compressed data is calculated in two parts.
The first part is the unary number of 1 + ⌊log2(x)⌋.
The second part is the binary number of x - 2^(⌊log2(x)⌋).
For the final result we add these two parts.
"""
if x == 0: return '0'

first_part = 1 + int(log2(x))

a = x - 2**(int(log2(x)))

k = int(log2(x))

return lencoding(first_part) + binary(a,k)

def elias_gamma(x):
"""
For the first part we put the unary number of x.
"""
return elias_generic(unary, x)

def elias_delta(x):
"""
For the first part we put the elias_g of the number.
"""
return elias_generic(elias_gamma,x)
20 changes: 20 additions & 0 deletions tests/test_compression.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from algorithms.compression.huffman_coding import HuffmanCoding
from algorithms.compression.rle_compression import (decode_rle, encode_rle)
from algorithms.compression.elias import (elias_gamma, elias_delta)

import unittest

Expand Down Expand Up @@ -44,6 +45,25 @@ def test_decode_rle(self):
self.assertEqual('WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW',
decode_rle('12W1B12W3B24W1B14W'))

class TestEliasCoding(unittest.TestCase):

def test_elias_gamma(self):
correct_result = ['0', '00', '100', '101', '11000', '11001', '11010', '11011', '1110000', '1110001', '1110010']

result = []
for i in range(11):
result.append(elias_gamma(i))

self.assertEqual(correct_result, result)

def test_elias_delta(self):
correct_result = ['0', '000', '1000', '1001', '10100', '10101', '10110', '10111', '11000000', '11000001', '11000010']

result = []
for i in range(11):
result.append(elias_delta(i))

self.assertEqual(correct_result, result)

if __name__ == "__main__":
unittest.main()

0 comments on commit b6dbcfb

Please sign in to comment.