[python] QR code application of Reed-solomon codes (4)

 4. Division

        For polynomials, the efficient algorithm of synthetic division is mainly used. Before talking about synthetic division, review the long division:

例:f(x) = x3 - x2 - x - 1

Expand f(x) to Taylor's expression based on offset a : c 0  + c 1 (xa) + c 2 (xa) 2  + c 3 (xa) 3

Suppose the offset value a=2

Expansion of f(x)  above = 1 + 7(x-2) + 5(x-2) 2  + (xa) 3

i.e. c 0 = 1, c 1  = 7, c 2  = 5, c 3  = 1

We can calculate c 0,  c 1,  c 2,  c 3 separately by long division


        

Get the remainder 1 , which is c 0and repeat the calculation twice (x2 + x + 1) / (x-2)  =  (x + 3) … 7, (x + 3) / (x-2) =  1 … 5

All coefficients c 0 to c 3 are all counted up

The same result can also be obtained by synthetic division, but the calculation method is much simpler than the above

Still taking the above f(x) as an example, obtain c 0,  c 1,  c 2,  c 3 by comprehensive division

The first step is to extract the coefficients of  x 3 , -x 2 , -x, -1 , multiply -a  of xa by -1 and put it on the far right 

The calculation steps are as follows:

  1. The first number in row 1 remains unchanged and moves down to row 2
  2. Add the 1st number in the 2nd row 1 * 2  and the 2nd number in the 1st row to get the 2nd number in the 2nd row ,
  3. Add the 2nd number  1 * 2 in the 2nd row and the 3rd number in the 1st row to get the 3rd number in the 2nd row ,
  4. Add the 3rd number in the 2nd row  1 * 2 and the 4th number in the 1st row to get the 4th number in the 2nd row

The last number in the second row is the remainder, and the remainder is not calculated as a parameter. The above are the steps of a comprehensive division, and the number in the third row is obtained by the second comprehensive division.

The following code is an extended implementation of the algorithm for the GF(2^p) polynomial:

def gf_poly_div(dividend, divisor):
    '''Applies to fast polynomial division in GF(2^p) field.'''
   
    msg_out = list(dividend) # Copy the dividend (suffix ecc bytes at the end, padded with 0)
    #normalizer = divisor[0] # precomputing for performance
    for i in range(0, len(dividend) - (len(divisor)-1)):
        #msg_out[i] /= normalizer
        coef = msg_out[i]
        if coef != 0: # Avoid log(0) undefined errors.
            for j in range(1, len(divisor)): # Since the first position of the polynomial is 1, (1^1==0) it can be skipped
                if divisor[j] != 0: # log(0) is undefined
                    msg_out[i + j] ^= gf_mul(divisor[j], coef) # Equivalent to mathematical expression: msg_out[i + j] += -divisor[j] * coef , but XOR operation is efficient

    # msg_out contains the quotient and remainder, the highest power of the remainder ( == length-1) is the same as the divisor, and the breakpoint is calculated below.
    separator = -(len(divisor)-1)
    return msg_out[:separator], msg_out[separator:] # Return quotient, remainder

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325616186&siteId=291194637