diff options
author | Julian T <julian@jtle.dk> | 2021-03-11 13:18:35 +0100 |
---|---|---|
committer | Julian T <julian@jtle.dk> | 2021-03-11 13:18:35 +0100 |
commit | 1455ccc4eb1047aba2a50b8c2c3a5bd3887d0226 (patch) | |
tree | 6734cab7074f82f76919b7b03ead87e588b62e39 /sem6/com | |
parent | b7423cb043cfa4c9e88eeb345c3bb8dfd82aafc2 (diff) |
Do channel simulation assignment for Communications
Diffstat (limited to 'sem6/com')
-rw-r--r-- | sem6/com/m3/channel_test.py | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/sem6/com/m3/channel_test.py b/sem6/com/m3/channel_test.py new file mode 100644 index 0000000..c8f9e85 --- /dev/null +++ b/sem6/com/m3/channel_test.py @@ -0,0 +1,90 @@ +import numpy as np + +class MatrixEncoder: + def ident(dim, value=1): + return np.identity(dim) * value + +class Vector: + def __init__(self, arr): + self.arr = arr + self.len = len(arr) + + def add(self, other): + return self.__class__(self.arr + other.arr) + + def __str__(self): + return str(self.arr) + + def print(self, f="{}"): + print(f.format(self)) + return self + + def gaussian(size, mu, sigma): + return Vector(sigma * np.random.randn(size) + mu) + + +class BitVector(Vector): + def gen_uniform(size): + arr = np.random.randint(0, 2, size) + return BitVector(arr) + + def to_int(self): + reverse = np.flip(self.arr) + + res = 0 + for (i, b) in enumerate(reverse): + res += b * 2**i + return res + + def encode(self, matrix): + return SymbolVector(matrix[self.to_int()]) + + def from_int(index, size=None): + bits = [] + while index > 0: + remainder = index % 2 + index = index // 2 + bits.insert(0, remainder) + + # Padding if they want + if size is not None: + missing = max(0, size - len(bits)) + bits = [0] * missing + bits + + return BitVector(bits) + + def check_if_error(self, other): + return np.array_equal(self.arr, other.arr) + +class SymbolVector(Vector): + def with_noise(self, c): + noise = Vector.gaussian(self.len, 0, c) + return self.add(noise) + + def decide_and_decode(self, matrix): + dim = len(matrix) + # Collect all distances in vector + dists = np.arange(dim) + for (i, vec) in enumerate(matrix): + dists[i] = np.dot(self.arr, vec) + + # Find index with smallest + index = np.argmax(dists) + + # Convert integer back to bit vector + return BitVector.from_int(index, size=int(np.log2(dim))) + +encoder = MatrixEncoder.ident(4, np.sqrt(1)) + +faults = 0 +total = 10000 +for i in range(total): + original = BitVector.gen_uniform(2) + after = original.encode(encoder) \ + .with_noise(1) \ + .decide_and_decode(encoder) + if original.check_if_error(after): + faults += 1 + +print(f"Fault percentage {(faults / total) * 100}%") + |