def Exercise4_2():
    print("Exercise4_2")
    '''
    Construct the Galois field GF(25) generated by p(X) = 1 + X2 + X5, showing a
    table with the polynomial and binary representations of its elements.
    '''
    p = np.array([1, 0, 1, 0, 0, 1])
    GF25 = GaloisField(p)
    GF25.printInfo()
def Exercise4_3():
    print("Exercise4_3")
    '''
    Determine the minimal polynomials of the elements of the Galois field GF(25)
    constructed in Problem 4.2.
    '''
    p = np.array([1, 0, 1, 0, 0, 1])
    GF25 = GaloisField(p)
    GF25.printMinimalPolynomials()
def exam2011problem4():
    p = np.array([1, 1, 0, 0, 1])
    GF16 = GaloisField(p)
    GF16.printInfo()
    t = 2
    bch = BCHCode(GF16, t, True)
    bch.printInfo()
    r = np.array([0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1])
    bch.S(r, True)

    equation = np.array([1, 1, 1])
    root1, root2 = GF16.roots(equation)
    j1 = GF16.elementToExp(GF16.elementFromExp(-GF16.elementToExp(root1)))
    j2 = GF16.elementToExp(GF16.elementFromExp(-GF16.elementToExp(root2)))
    print(j1, j2)

    c = bch.decode(r, True)
    print(GF16.polyToString(c))
def Exercise4_5():
    print("Exercise4_5")
    '''
    Determine the generator polynomial of a binary BCH code of code length n = 31
    able to correct error patterns of size t = 2 or less. Also, determine the value of
    k and the minimum Hamming distance of the code.
    '''
    # Since t = 2 we only need two minimal polynomials to construct the generator.
    p = np.array([1, 0, 1, 0, 0, 1])
    GF25 = GaloisField(p)

    bch = BCHCode(GF25, 2, True)
    bch.printInfo()
def Exercise4_6():
    print("Exercise4_6")
    '''
    A binary cyclic BCH code CBCH(n, k) has code length n = 15 and generator
    polynomial g(X) = (X + 1)(1 + X + X4)(1 + X + X2 + X3 + X4).
    (a) What is the minimum Hamming distance of the code?
    '''
    p = np.array([1, 1, 0, 0, 1])
    GF16 = GaloisField(p)
    #GF16.printMinimalPolynomials()

    roots = GF16.conjugateRootGroups()
    part1 = GF16.multPoly(GF16.minimalPolynomial(roots[1]),
                          GF16.minimalPolynomial(roots[2]))
    part2 = GF16.multPoly(part1, GF16.minimalPolynomial(roots[3]))
    print("Reduced generator polynomial: ", GF16.polyToString(part2))
    print()
    print(
        "DMin is the number of exponents in the generator polynomial which is: ",
        GF16.dminOfPoly(part2))
from BinarySymmetricChannel import BinarySymmetricChannel
from LinearBlockCode import LinearBlockCode
from CyclicCode import CyclicCode
from GaloisField import GaloisField
from BCHCode import BCHCode
import numpy as np
import CyclicCode as cc
import BCHCode as bch

if __name__ == '__main__':

    # Exercise 4.2 (precondition for 4.3)
    pX = np.array([1, 0, 1, 0, 0, 1])  # 1 + X^2 + X^5
    GF25 = GaloisField(pX)
    #GF25.printInfo()

    print("Exercise 4.3")
    print("------------")

    GF25.printMinimalPolynomials()

    print("Exercise 4.4")
    print("------------")

    print(GF25.roots(pX))
    t = 3
    C_BCH = BCHCode(GF25, t, True)

    print("Exercise 4.5")
    print("------------")
def Exercise4_4():
    print("Exercise4_4")
    '''
    Determine the generator polynomial of the binary BCH code CBCH(31, 16) able
    to correct error patterns of size t = 3 or less.
    '''
    p = np.array([1, 0, 1, 0, 0, 1])
    GF25 = GaloisField(p)
    GF25.printInfo()

    roots = GF25.conjugateRootGroups()
    print()
    print("(", GF25.polyToString(GF25.minimalPolynomial(roots[2])), ") * (",
          GF25.polyToString(GF25.minimalPolynomial(roots[3])), ") * (",
          GF25.polyToString(GF25.minimalPolynomial(roots[4])), ")")
    print()
    # The roots create Φ_1,Φ_3,Φ_51
    part1 = GF25.multPoly(GF25.minimalPolynomial(roots[2]),
                          GF25.minimalPolynomial(roots[3]))
    part2 = GF25.multPoly(part1, GF25.minimalPolynomial(roots[4]))
    print(GF25.polyToString(part2))
Beispiel #8
0
class Polynomial:
    GF = GaloisField()

    def __init__(self, init: list = None):
        if init is None:
            init = [0]

        self.polynomial = init

    def __len__(self):
        return len(self.polynomial)

    def append(self, object):
        self.polynomial.append(object)
        return self

    def __reversed__(self):
        self.polynomial.reverse()
        return self

    def __getitem__(self, key):
        """
        Override []
        :param key: index to get
        :return: item at position self.polynomial[key] or slice
        """
        if isinstance(key, slice):
            return Polynomial(self.polynomial[key.start:key.stop:key.step])

        return self.polynomial[key]

    def __setitem__(self, key, value):
        """
        Override x[key] = value
        :param key: index
        :param value: value to set
        :return: item at position self.polynomial = value
        """
        self.polynomial[key] = value
        return self

    def __add__(self, other):
        """
        Override + operator to perform polynomial addition
        """
        sum = [0] * max(len(self), len(other))

        sum[len(sum) - len(self):len(sum)] = copy.deepcopy(self.polynomial)

        for n in range(len(other)):
            sum[n + len(sum) - len(other)] ^= other[n]

        return Polynomial(sum)

    def __iadd__(self, other):
        """
        Override += operator for polynomial addition
        """
        self.polynomial = self.__add__(other).polynomial
        return self

    def pop(self, key=-1):
        """
        Remove the element at index
        :param key: the index of the element to remove
        :return: the element removed
        """
        item = self.polynomial.pop(key)
        return item

    def scale(self, x):
        """
        Multiply all the elements of the polynomial by a value x
        :param x: the scalar value
        :return: a new scaled Polynomial
        """

        new_polynomial = [self.GF.gfMul(self.polynomial[i], x) for i in range(len(self.polynomial))]
        return Polynomial(new_polynomial)

    def iscale(self, x):
        """
        Scale itself by a value x
        :param x: the scalar value
        :return: itself
        """
        self.polynomial = self.scale(x).polynomial
        return self

    def eval(self, x):
        """
        Evaluate self given x
        :param x: the value to evaluate for
        :return: the result of the evaluation
        """

        val = self.polynomial[0]
        for position in range(1, len(self.polynomial)):
            val = Polynomial.GF.gfMul(val, x) ^ self.polynomial[position]

        return val

    def __mul__(self, other):
        """
        Override * operator for polynomial multiplication
        """
        num = len(self) + len(other) - 1
        mul = [0] * num

        for posY in range(len(other)):
            for posX in range(len(self)):
                mul[posY + posX] ^= Polynomial.GF.gfMul(self[posX], other[posY])

        return Polynomial(mul)

    def __imul__(self, other):
        """
        Override *= for polynomial multiplication
        """
        self.polynomial = self.__mul__(other).polynomial
        return self

    def __truediv__(self, other):
        """
        Override / for polynomial division
        :return: the quotient, the remainder
        """
        num = copy.deepcopy(self)

        for posX in range(len(self) - len(other) - 1):
            for posY in range(1, len(other)):
                num[posX + posY] ^= Polynomial.GF.gfMul(other[posY], num[posX])

        div = -(len(other) - 1)
        return num[:div], num[div:]

    @staticmethod
    def generator(error_size):
        """
        Create the generator polynomial for a given error size
        :param error_size: the given error size
        :return: the generator polynomial for the specific Galois Field with a given error size
        """

        # Initialise the generator polynomial at 1
        polynomial_value = Polynomial([1])

        # Multiply "error_size" consecutive values in the GF
        for position in range(error_size):
            polynomial_value *= Polynomial([1, Polynomial.GF[position]])

        return polynomial_value

    @staticmethod
    def syndromePolynomial(block, error_size):
        """
        Create the syndrome polynomial
        :param block: the block for which we create the syndrome polynomial
        :param error_size: the number of parity symbols
        :return: the syndrome polynomial
        """
        block_polynomial = Polynomial(block)
        generator_polynomial = Polynomial([0] * error_size)

        for i in range(error_size):
            val = Polynomial.GF[i]
            generator_polynomial[i] = block_polynomial.eval(val)

        return generator_polynomial

    @staticmethod
    def errorLocatorPolynomial(error_positions):
        """
        Compute the error locator polynomial
        :param error_positions: the number of error symbols
        :return: the error locator polynomial
        """
        error_locator = Polynomial([1])

        for i in error_positions:
            error_locator *= (Polynomial([1]) + Polynomial([Polynomial.GF.gfPow(2, i), 0]))

        return error_locator

    @staticmethod
    def errorEvaluatorPolynomial(syndrome_polynomial, error_locator, error_size):
        """
        The error evaluator polynomial
        :param syndrome_polynomial: the syndrome polynomial
        :param error_locator: the error locator polynomial
        :param error_size: the number of parity symbols
        :return: the error evaluator polynomial
        """
        _, remainder = (syndrome_polynomial * error_locator) / Polynomial([1] + [0]*error_size)

        return remainder
Beispiel #9
0
import numpy as np
from BinarySymmetricChannel import BSC
from GaloisField import GaloisField
from GaloisField import GF2
from LinearBlockCode import LinearBlockCode
from CyclicCode import CyclicCode
from BCHCode import BCHCode
from numpy import poly1d

# print("CyclicCode")
# """
# A binary linear cyclic code Ccyc(n, k) has code length n = 7 and generator polynomial
# g(X) = 1 + X2 + X3 + X4.
#
# (a) Find the code rate, the generator and parity check matrices of the code in systematic form, and its Hamming distance.
# (b) If all the information symbols are ‘1’s, what is the corresponding code vector?
# (c) Find the syndrome corresponding to an error in the first information symbol, and show that the code is capable of correcting this error.
# """
# g = np.array([1, 0, 1, 1, 1])
# cc = CyclicCode(g, 7)
# cc.printInfo()

p = np.array([1, 0, 1, 0, 0, 1])
gf = GaloisField(p)
bch = BCHCode(gf, 2)
bch.printInfo()
bch.decode(np.poly([1, 1, 0, 1, 1, 1]))
Beispiel #10
0
class Polynomial:
    GF = GaloisField()

    def __init__(self, init: list = None):
        if init is None:
            init = [0]

        self.polynomial = init

    def __len__(self):
        return len(self.polynomial)

    def append(self, object):
        self.polynomial.append(object)
        return self

    def __reversed__(self):
        self.polynomial.reverse()
        return self

    def __getitem__(self, key):
        """
       重载 []
        :param key: index to get
        :return: item at position self.polynomial[key] or slice
        """
        if isinstance(key, slice):
            return Polynomial(self.polynomial[key.start:key.stop:key.step])

        return self.polynomial[key]

    def __setitem__(self, key, value):
        """
        重载x[key] = value
        :param key: index
        :param value: value to set
        :return: item at position self.polynomial = value
        """
        self.polynomial[key] = value
        return self

    def __add__(self, other):
        """
       重载+运算符来执行多项式加法
        """
        sum = [0] * max(len(self), len(other))

        sum[len(sum) - len(self):len(sum)] = copy.deepcopy(self.polynomial)

        for n in range(len(other)):
            sum[n + len(sum) - len(other)] ^= other[n]

        return Polynomial(sum)

    def __iadd__(self, other):
        """
        重载+=运算符来执行多项式加法
        """
        self.polynomial = self.__add__(other).polynomial
        return self

    def pop(self, key=-1):
        """
       删除索引处的元素
        :param key: 要删除的元素的索引
        :return: 删除的元素
        """
        item = self.polynomial.pop(key)
        return item

    def scale(self, x):
        """
       将多项式的所有元素乘以一个值x
        :param x: 标量值
        :return: a new scaled Polynomial
        """

        new_polynomial = [self.GF.gfMul(self.polynomial[i], x) for i in range(len(self.polynomial))]
        return Polynomial(new_polynomial)

    def iscale(self, x):
        """
       自身乘以一个值x
        :param x: 标量值
        :return: itself
        """
        self.polynomial = self.scale(x).polynomial
        return self

    def eval(self, x):
        """
        求自变量x的值
        :param x:要评估的值
        :return: 评估结果
        """

        val = self.polynomial[0]
        for position in range(1, len(self.polynomial)):
            val = Polynomial.GF.gfMul(val, x) ^ self.polynomial[position]

        return val

    def __mul__(self, other):
        """
        重载*运算符来执行多项式乘法
        """
        num = len(self) + len(other) - 1
        mul = [0] * num

        for posY in range(len(other)):
            for posX in range(len(self)):
                mul[posY + posX] ^= Polynomial.GF.gfMul(self[posX], other[posY])

        return Polynomial(mul)

    def __imul__(self, other):
        """
        重载*=运算符来执行多项式乘法
        """
        self.polynomial = self.__mul__(other).polynomial
        return self

    def __truediv__(self, other):
        """
       重载/运算符来执行多项式除法
        :return: the quotient, the remainder
        """
        num = copy.deepcopy(self)

        for posX in range(len(self) - len(other) - 1):
            for posY in range(1, len(other)):
                num[posX + posY] ^= Polynomial.GF.gfMul(other[posY], num[posX])

        div = -(len(other) - 1)
        return num[:div], num[div:]

    @staticmethod
    def generator(error_size):
        """
        为给定的错误大小创建生成器多项式
        :param error_size: 给定的错误大小
        :return: 给定误差大小的特定伽罗瓦域的生成多项式
        """

        # 初始化发生器多项式为1
        polynomial_value = Polynomial([1])

        # 在GF中相乘“error_size”的连续值
        for position in range(error_size):
            polynomial_value *= Polynomial([1, Polynomial.GF[position]])

        return polynomial_value

    @staticmethod
    def syndromePolynomial(block, error_size):
        """
        创建伴随多项式
        :param block: 我们用来创建伴随多项式的块
        :param error_size: 奇偶校验符号的数目
        :return: 综合症的多项式
        """
        block_polynomial = Polynomial(block)
        generator_polynomial = Polynomial([0] * error_size)

        for i in range(error_size):
            val = Polynomial.GF[i]
            generator_polynomial[i] = block_polynomial.eval(val)

        return generator_polynomial

    @staticmethod
    def errorLocatorPolynomial(error_positions):
        """
        计算错误定位多项式
        :param error_positions:错误符号的数目
        :return: 错误定位多项式
        """
        error_locator = Polynomial([1])

        for i in error_positions:
            error_locator *= (Polynomial([1]) + Polynomial([Polynomial.GF.gfPow(2, i), 0]))

        return error_locator

    @staticmethod
    def errorEvaluatorPolynomial(syndrome_polynomial, error_locator, error_size):
        """
        误差评估多项式
        :param syndrome_polynomial: 伴随多项式
        :param error_locator: the error locator polynomial
        :param error_size::错误定位多项式
        :return: 误差评估多项式
        """
        _, remainder = (syndrome_polynomial * error_locator) / Polynomial([1] + [0]*error_size)

        return remainder
from GaloisField import GF2
from LinearBlockCode import LinearBlockCode
from CyclicCode import CyclicCode
from BCHCode import BCHCode

print("Exercise 1")
"""
A binary linear cyclic code Ccyc(n, k) has code length n = 7 and generator polynomial 
g(X) = 1 + X2 + X3 + X4.

(a) Find the code rate, the generator and parity check matrices of the code in systematic form, and its Hamming distance.
(b) If all the information symbols are ‘1’s, what is the corresponding code vector?
(c) Find the syndrome corresponding to an error in the first information symbol, and show that the code is capable of correcting this error.
"""
p = np.array([1,0,1,0,0,1])
GF25 = GaloisField(p)
GF25.printInfo()

print("Exercise 2")
"""
A binary linear cyclic code Ccyc(n, k) has code length n = 7 and generator polynomial 
g(X) = 1 + X2 + X3 + X4.

(a) Find the code rate, the generator and parity check matrices of the code in systematic form, and its Hamming distance.
(b) If all the information symbols are ‘1’s, what is the corresponding code vector?
(c) Find the syndrome corresponding to an error in the first information symbol, and show that the code is capable of correcting this error.
"""
g = np.array([1,0,1,1,1])
cc = CyclicCode(g, 7)
cc.printInfo()
from GaloisField import GaloisField


print GaloisField.GaloisField(7,3)