forked from pmgbergen/porepy
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Generator for multinary numbers of given base and length.
Also unit tests.
- Loading branch information
Showing
2 changed files
with
92 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |