1# Author: Eric Larson
2# 2014
3
4import numpy as np
5cimport numpy as np
6cimport cython
7
8
9# Fast inner loop of max_len_seq.
10@cython.cdivision(True)  # faster modulo
11@cython.boundscheck(False)  # designed to stay within bounds
12@cython.wraparound(False)  # we don't use negative indexing
13def _max_len_seq_inner(Py_ssize_t[::1] taps,
14                       np.int8_t[::1] state,
15                       Py_ssize_t nbits, Py_ssize_t length,
16                       np.int8_t[::1] seq):
17    # Here we compute MLS using a shift register, indexed using a ring buffer
18    # technique (faster than using something like np.roll to shift)
19    cdef Py_ssize_t n_taps = taps.shape[0]
20    cdef Py_ssize_t idx = 0
21    cdef np.int8_t feedback
22    cdef Py_ssize_t i
23    for i in range(length):
24        feedback = state[idx]
25        seq[i] = feedback
26        for ti in range(n_taps):
27            feedback ^= state[(taps[ti] + idx) % nbits]
28        state[idx] = feedback
29        idx = (idx + 1) % nbits
30    # state must be rolled s.t. next run, when idx==0, it's in the right place
31    return np.roll(state, -idx, axis=0)
32