Skip to content

Commit

Permalink
Generator for multinary numbers of given base and length.
Browse files Browse the repository at this point in the history
Also unit tests.
  • Loading branch information
keileg committed Jan 9, 2017
1 parent 4dffb6a commit 905fb69
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 0 deletions.
46 changes: 46 additions & 0 deletions permutations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@

def multinary_permutations(base, length):
"""
Define a generator over all numbers of a certain length for a number system
with a specified base.
For details on the decomposition into an arbitrary base see
http://math.stackexchange.com/questions/111150/changing-a-number-between-arbitrary-bases
Note that the generator will loop over base**length combinations.
Examples:
Construct the numbers [00] to [11] in binary numbers
>>> multinary_permutations(2, 2)
[array([ 0., 0.]), array([ 1., 0.]), array([ 0., 1.]), array([ 1., 1.])]
Construct the numbers from 0 to 99 (permuted) in the decimal number
system.
>>> it = multinary_permutation(10, 2)
Parameters:
base (int): Base of the number system
length (int): Number of digits in the numbers
Yields:
array, size length: Array describing the next number combination.
"""

# There are in total base ** length numbers to be covered, these need to be
# rewritten into the base number system
for iter1 in range(base ** length):

# Array to store the multi-d index of the current index
bit_val = [0] * length
# Number to be decomposed
v = iter1

# Loop over all digits, find the expression of v in that system
for iter2 in range(length):
bit_val[iter2] = v % base
v = v // base
# Yield the next value
yield bit_val

46 changes: 46 additions & 0 deletions tests/test_permutations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import unittest
import numpy as np

from utils import permutations

class TestPermutations(unittest.TestCase):

def compare_lists(self, base, length, lst):
# Compare a pre-defined list with the result of multinary_permutations
# Define a generator, and check that all values produced are contained within lst
# Also count the number of iterations
iter_cnt = 0
for a in permutations.multinary_permutations(base, length):
found = False
for b in lst:
if np.array_equal(np.array(a), np.array(b)):
found = True
break
assert found
iter_cnt += 1
assert iter_cnt == len(lst)


def test_length_2(self):
# Explicitly construct a 2D array of all combination of base 3
base = 3
length = 2
lst = []
for i in range(base):
for j in range(base):
lst.append([i, j])
self.compare_lists(base, length, lst)

def test_base_4(self):
# Check with a manually constructed list of length 3
base = 4
length = 3
lst = []
for i in range(base):
for j in range(base):
for k in range(base):
lst.append([i, j, k])
self.compare_lists(base, length, lst)

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

0 comments on commit 905fb69

Please sign in to comment.