More on LFSR

Switching polynomial

Changing feedback polynomial in between

After generating some bits from an LFSR, a feedback polynomial can be changed keeping the current state as intial state and generate the new sequece.

import numpy as np
from pylfsr import LFSR

L = LFSR(fpoly=[23,18],initstate ='ones')
seq0 = L.runKCycle(10)

# Change after 10 clocks
#L.changeFpoly(newfpoly =[23,14],reset=False)
L.set_fpoly(fpoly =[23,14],reset=False)
seq1 = L.runKCycle(20)

# Change after 20 clocks
L.set_fpoly(fpoly=[23,9],reset=False)
seq2 = L.runKCycle(20)

Switching Configuration

Changing configuration in between

import numpy as np
from pylfsr import LFSR

L = LFSR(fpoly=[23,18],initstate ='ones',conf='fibonacci')
seq0 = L.runKCycle(10)

# Change after 10 clocks
L.set_conf(conf='galois',reset=False)
seq1 = L.runKCycle(20)

Output from different register

To select output sequence from 3 register from last, `seq_bit_index=-3` is used

import numpy as np
from pylfsr import LFSR

L = LFSR(fpoly=[6, 5, 2, 1],initstate ='ones',conf='galois', seq_bit_index=-3)
L.Viz()
L.runFullPeriod()
seq = L.arr2str(L.seq)
seq
https://github.com/Nikeshbajaj/Linear_Feedback_Shift_Register/blob/master/images/L_p6521_galois_ob3_1.png?raw=true
'110101111110110100010000101100101010010011110000011011100110001'

To select output sequence from 1st register, `seq_bit_index=0`

import numpy as np
from pylfsr import LFSR

L = LFSR(fpoly=[6, 5, 2, 1],initstate ='ones',conf='galois', seq_bit_index=0)
L.Viz()
L.runFullPeriod()
seq = L.arr2str(L.seq)
seq
https://github.com/Nikeshbajaj/Linear_Feedback_Shift_Register/blob/master/images/L_p6521_galois_ob0_1.png?raw=true
'100101010010011110000011011100110001110101111110110100010000101'

Feedback (Primitive) Polynomials:

A primitive polynomial is is irreducible, and not trivial to derive. A list of primitive polynomials upto 32 degree can be found at Ref, which is not an exhaustive list. Since for each primitive polynomial, an image replica (which is also primitive) can be computed easily list include half of polynomials for each degree and other half can be compputed by get_Ifpoly() method, see example 7.2

Ref : http://www.partow.net/programming/polynomials/index.html

Get a list of feedback polynomials for a m-bit LFSR

import numpy as np
from pylfsr import LFSR
import pylfsr as PYL



PYL.get_fpolyList(m=5)
[[5, 2], [5, 4, 2, 1], [5, 4, 3, 2]]

# list of all feedback polynomials as a dictionary
fpolyDict = PYL.get_fpolyList()

Or optional way, if LFSR object is already in place

from pylfsr import LFSR

L = LFSR()
# list of 5-bit feedback polynomials
fpolys = L.get_fpolyList(m=5)
[[5, 2], [5, 4, 2, 1], [5, 4, 3, 2]]

# list of all feedback polynomials as a dictionary
fpolyDict = L.get_fpolyList()

Image/Replica of feedback polynomial

Get a image replica of a feedback polynomial

Image replica of a primitive polynomial is a primitive polynomial, hence a valid feedback polynomial for LFSR For m-bit primitive polynomial p(x) = x^m + x^k + .. + 1, a image replica is ip(x) = x^(-m)p(x) where 0 < k < m

import numpy as np
from pylfsr import LFSR
import pylfsr as PYL

L = LFSR()
L.get_Ifpoly([5,3])
[5, 2]
L.get_Ifpoly([5,4,3,2])
[5, 3, 2, 1]

Or

import pylfsr as PYL

PYL.get_Ifpoly([5,4,3,2])
[5, 3, 2, 1]

Plotting LFSR

To plot any LFSR `dispLFSR` can be used

import pylfsr as PYL

PYL.dispLFSR(state=[1,1,1,1,0], fpoly=[5,3], conf='fibonacci', seq='111', title='R1')
https://github.com/Nikeshbajaj/Linear_Feedback_Shift_Register/blob/master/images/L_p61_1.png?raw=true

Lempel-ziv Complexity

Lempel-ziv Complexity of a given binary (or non-binary) sequencey can be computed using `lempel_ziv_complexity`

import numpy as np
from pylfsr import LFSR
import pylfsr as PYL

L = LFSR(fpoly=[6, 1],initstate ='ones')
#L.Viz()
seq = L.runFullPeriod()

PLY.lempel_ziv_complexity(seq)
21

Lempel-ziv Dictionary

To get dictionary of all the patterns in given sequence, `lempel_ziv_patterns` can be used, which is exactly the one used to compute the Lempel-ziv Complexity. Lempel-ziv Complexity is the length of dictionary.

import numpy as np
from pylfsr import LFSR
import pylfsr as PYL

L = LFSR(fpoly=[6, 1],initstate ='ones')
#L.Viz()
seq = L.runFullPeriod()

PLY.lempel_ziv_patterns(seq)
{'0',
'00',
'000',
'001',
'01',
'010',
'0100',
'011',
'1',
'10',
'100',
'1000',
'1001',
'101',
'11',
'110',
'1100',
'11001',
'1101',
'111',
'1110'}