diff --git a/b_asic/utils.py b/b_asic/utils.py index baa3b29afded1d29eb60271cf80815722d7b4892..19cf56422c359b682174f7a5660a5cf4a3eb8f0a 100644 --- a/b_asic/utils.py +++ b/b_asic/utils.py @@ -1,4 +1,4 @@ -"""B-ASIC Utils.""" +"""B-ASIC Utilities.""" from typing import List, Sequence @@ -9,17 +9,22 @@ def interleave(*args) -> List[Num]: """ Interleave a number of arrays. - For the input ``interleave([1, 2], [3, 4])``, return ``[1, 3, 2, 4]``. - Parameters ---------- *args : a number of arrays Arrays to interleave. Must be of the same length. - Returns - ------- - - + Examples + -------- + >>> from b_asic.utils import interleave + ... + ... a = [1, 2] + ... b = [3, 4] + ... interleave(a, b) + [1, 3, 2, 4] + >>> c = [-1, 0] + ... interleave(a, b, c) + [1, 3, -1, 2, 4, 0] """ return [val for tup in zip(*args) for val in tup] @@ -39,9 +44,77 @@ def downsample(a: Sequence[Num], factor: int, phase: int = 0) -> List[Num]: phase : int, default: 0 The phase of the downsampling. - Returns - ------- + Examples + -------- + >>> from b_asic.utils import downsample + ... + ... a = list(range(6)) + ... downsample(a, 3) + [0, 3] + >>> downsample(a, 3, 1) + [1, 4] + """ + return a[phase::factor] +def upsample(a: Sequence[Num], factor: int, phase: int = 0) -> List[Num]: """ - return a[phase::factor] + Upsample a sequence with an integer factor. + + Insert *factor* - 1 zeros between every value, starting with *phase* zeros. + + Parameters + ---------- + a : array + The array to upsample. + factor : int + The factor to upsample with. + phase : int, default: 0 + The phase of the upsampling. + + Examples + -------- + >>> from b_asic.utils import upsample + ... + ... a = list(range(1, 4)) + ... upsample(a, 3) + [1, 0, 0, 2, 0, 0, 3, 0, 0] + >>> upsample(a, 3, 1) + [0, 1, 0, 0, 2, 0, 0, 3, 0] + """ + length = len(a) + zeros = [0] * length + args = [] + for _ in range(phase): + args.append(zeros) + args.append(a) + for _ in range(factor - phase - 1): + args.append(zeros) + return interleave(*args) + + +def decompose(a: Sequence[Num], factor: int) -> List[List[Num]]: + """ + Polyphase decompose signal *a* into *factor* parts. + + Return *factor* lists, each with every *factor* value. + + Parameters + ---------- + a : array + The array to polyphase decompose. + factor : int + The number of polyphase components with. + + Examples + -------- + >>> from b_asic.utils import decompose + ... + ... a = list(range(6)) + ... decompose(a, 2) + [[0, 2, 4], [1, 3, 5]] + >>> decompose(a, 3) + [[0, 3], [1, 4], [2, 5]] + + """ + return [downsample(a, factor, phase) for phase in range(factor)] diff --git a/test/test_utils.py b/test/test_utils.py index b67446a98fc1364ddeb4affcd156d9fb2773af83..823f01924894884f152b90805b1a2184a70ec6be 100644 --- a/test/test_utils.py +++ b/test/test_utils.py @@ -2,7 +2,7 @@ B-ASIC test suite for the utils module. """ -from b_asic.utils import downsample, interleave +from b_asic.utils import decompose, downsample, interleave, upsample def test_interleave(): @@ -20,3 +20,18 @@ def test_downsample(): assert downsample(a, 6, 3) == [3, 9] assert downsample(a, 4) == [0, 4, 8] assert downsample(a, 3, 1) == [1, 4, 7, 10] + + +def test_upsample(): + a = list(range(3)) + assert upsample(a, 2) == [0, 0, 1, 0, 2, 0] + assert upsample(a, 2, 1) == [0, 0, 0, 1, 0, 2] + a = list(range(1, 4)) + assert upsample(a, 3) == [1, 0, 0, 2, 0, 0, 3, 0, 0] + assert upsample(a, 3, 1) == [0, 1, 0, 0, 2, 0, 0, 3, 0] + + +def test_decompose(): + a = list(range(6)) + assert decompose(a, 2) == [[0, 2, 4], [1, 3, 5]] + assert decompose(a, 3) == [[0, 3], [1, 4], [2, 5]]