Beispiel #1
0
def BER(yi,yd,Ni,Nd,ibits,dbits):
    xi=np.zeros((yi.size,Ni))
    xd=np.zeros((yd.size,Nd))
    for i in range(0,yi.size):
        xi[i]=dec2bitarray(int(yi[i]),Ni)
    beri=np.sum(np.not_equal(xi.reshape((1,-1)),np.matrix(ibits).H.reshape((1,-1))))/xi.size 
    for i in range(0,yd.size):
        xd[i]=dec2bitarray(int(yd[i]),Nd)
    berd=np.sum(np.not_equal(xd.reshape((1,-1)),np.matrix(dbits).H.reshape((1,-1))))/xd.size 
    return beri, berd
Beispiel #2
0
def cyclic_code_genpoly(n, k):
    """
    Generate all possible generator polynomials for a (n, k)-cyclic code.

    Parameters
    ----------
    n : int
        Code blocklength of the cyclic code.

    k : int
        Information blocklength of the cyclic code.

    Returns
    -------
    poly_list : 1D ndarray of ints
        A list of generator polynomials (represented as integers) for the (n, k)-cyclic code.

    """

    if n % 2 == 0:
        raise ValueError("n cannot be an even number")

    for m in arange(1, 18):
        if (2**m - 1) % n == 0:
            break

    x_gf = GF(arange(1, 2**m), m)
    coset_fields = x_gf.cosets()

    coset_leaders = array([])
    minpol_degrees = array([])
    for field in coset_fields:
        coset_leaders = concatenate(
            (coset_leaders, array([field.elements[0]])))
        minpol_degrees = concatenate(
            (minpol_degrees, array([len(field.elements)])))

    y_gf = GF(coset_leaders, m)
    minpol_list = y_gf.minpolys()
    idx_list = arange(1, len(minpol_list))
    poly_list = array([])

    for i in range(1, 2**len(minpol_list)):
        i_array = dec2bitarray(i, len(minpol_list))
        subset_array = minpol_degrees[i_array == 1]
        if int(subset_array.sum()) == (n - k):
            poly_set = minpol_list[i_array == 1]
            gpoly = 1
            for poly in poly_set:
                gpoly_array = dec2bitarray(gpoly, 2**m)
                poly_array = dec2bitarray(poly, 2**m)
                gpoly = bitarray2dec(convolve(gpoly_array, poly_array) % 2)
            poly_list = concatenate((poly_list, array([gpoly])))

    return poly_list.astype(int)
Beispiel #3
0
def _backward_recursion(trellis, msg_length, noise_variance, sys_symbols,
                        non_sys_symbols, branch_probs, priors,
                        b_state_metrics):

    n = trellis.n
    number_states = trellis.number_states
    number_inputs = trellis.number_inputs

    codeword_array = empty(n, 'int')
    next_state_table = trellis.next_state_table
    output_table = trellis.output_table

    # Backward recursion
    for reverse_time_index in reversed(range(1, msg_length + 1)):

        for current_state in range(number_states):
            for current_input in range(number_inputs):
                next_state = next_state_table[current_state, current_input]
                code_symbol = output_table[current_state, current_input]
                codeword_array = dec2bitarray(code_symbol, n)
                parity_bit = codeword_array[1]
                msg_bit = codeword_array[0]
                rx_symbol_0 = sys_symbols[reverse_time_index - 1]
                rx_symbol_1 = non_sys_symbols[reverse_time_index - 1]
                branch_prob = _compute_branch_prob(msg_bit, parity_bit,
                                                   rx_symbol_0, rx_symbol_1,
                                                   noise_variance)
                branch_probs[current_input, current_state,
                             reverse_time_index - 1] = branch_prob
                b_state_metrics[current_state, reverse_time_index-1] += \
                        (b_state_metrics[next_state, reverse_time_index] * branch_prob *
                                priors[current_input, reverse_time_index-1])

        b_state_metrics[:,reverse_time_index-1] /= \
            b_state_metrics[:,reverse_time_index-1].sum()
Beispiel #4
0
def _backward_recursion(trellis, msg_length, noise_variance,
                        sys_symbols, non_sys_symbols, branch_probs,
                        priors, b_state_metrics):

    n = trellis.n
    number_states = trellis.number_states
    number_inputs = trellis.number_inputs

    codeword_array = empty(n, 'int')
    next_state_table = trellis.next_state_table
    output_table = trellis.output_table

    # Backward recursion
    for reverse_time_index in reversed(range(1, msg_length+1)):

        for current_state in range(number_states):
            for current_input in range(number_inputs):
                next_state = next_state_table[current_state, current_input]
                code_symbol = output_table[current_state, current_input]
                codeword_array = dec2bitarray(code_symbol, n)
                parity_bit = codeword_array[1]
                msg_bit = codeword_array[0]
                rx_symbol_0 = sys_symbols[reverse_time_index-1]
                rx_symbol_1 = non_sys_symbols[reverse_time_index-1]
                branch_prob = _compute_branch_prob(msg_bit, parity_bit,
                                                   rx_symbol_0, rx_symbol_1,
                                                   noise_variance)
                branch_probs[current_input, current_state, reverse_time_index-1] = branch_prob
                b_state_metrics[current_state, reverse_time_index-1] += \
                        (b_state_metrics[next_state, reverse_time_index] * branch_prob *
                                priors[current_input, reverse_time_index-1])

        b_state_metrics[:,reverse_time_index-1] /= \
            b_state_metrics[:,reverse_time_index-1].sum()
def BER(y, bits, N):
    x = np.zeros((y.size, N))
    for i in range(0, y.size):
        x[i] = dec2bitarray(int(y[i]), N)
    return np.sum(
        np.not_equal(x.reshape((1, x.size)),
                     np.matrix(bits).H.reshape((1, bits.size)))) / x.size
Beispiel #6
0
def get_const_symbols(mode='QAM', m=16):
    ''' Implement either QAM or PSK '''

    # m is given
    nbps = np.log2(m)

    # simplify constellations to 2^k alphabets
    if nbps.is_integer():
        nbps = nbps.astype(int)
    else:
        raise Exception('QAM: m must be a power of 2')

    # switch between modes
    if mode == 'QAM':

        blist = [util.dec2bitarray(x,nbps) for x in range(m)]
        bits = np.concatenate(blist)

        mod = comm.modulation.QAMModem(m)
        syms = mod.modulate(bits) / np.sqrt(10)
        return syms

    elif mode == 'PSK':

        thetas = [x/m * 2 * np.pi for x in range(m)]
        syms = np.exp(1j*np.asarray(thetas))
        return syms

    else:
        raise Exception('Invalid initialization!')
Beispiel #7
0
    def demodulate(self, input_symbols, demod_type, noise_var=0):
        """ Demodulate (map) a set of constellation symbols to corresponding bits.

        Supports hard-decision demodulation only.

        Parameters
        ----------
        input_symbols : 1D ndarray of complex floats
            Input symbols to be demodulated.

        demod_type : string
            'hard' for hard decision output (bits)
            'soft' for soft decision output (LLRs)

        noise_var : float
            AWGN variance. Needs to be specified only if demod_type is 'soft'

        Returns
        -------
        demod_bits : 1D ndarray of ints
            Corresponding demodulated bits.

        """
        if demod_type == 'hard':
            index_list = list(map(lambda i: argmin(abs(input_symbols[i] - self.constellation)), \
                                  range(0, len(input_symbols))))
            demod_bits = hstack(
                list(
                    map(lambda i: dec2bitarray(i, self.num_bits_symbol),
                        index_list)))
        elif demod_type == 'soft':
            demod_bits = zeros(len(input_symbols) * self.num_bits_symbol)
            for i in arange(len(input_symbols)):
                current_symbol = input_symbols[i]
                for bit_index in arange(self.num_bits_symbol):
                    llr_num = 0
                    llr_den = 0
                    for const_index in self.symbol_mapping:
                        if (const_index >> bit_index) & 1:
                            llr_num = llr_num + exp(
                                (-abs(current_symbol -
                                      self.constellation[const_index])**2) /
                                noise_var)
                        else:
                            llr_den = llr_den + exp(
                                (-abs(current_symbol -
                                      self.constellation[const_index])**2) /
                                noise_var)
                    demod_bits[i * self.num_bits_symbol +
                               self.num_bits_symbol - 1 - bit_index] = log(
                                   llr_num / llr_den)
        else:
            pass
            # throw an error

        return demod_bits
    def _test_qam_mapper_demapper(self, m):
        mapper = util.QamMapper(m)
        data_in = np.hstack(
            [dec2bitarray(n, int(np.sqrt(m))) for n in range(m)])
        qam_data = mapper.modulate(data_in)

        self.assertEqual(len(qam_data), (len(data_in) // np.log2(m)))
        self.assertTrue(len(set(qam_data)) == m)
        data_out = mapper.demodulate(qam_data)
        np.testing.assert_array_almost_equal(data_out, data_in)
Beispiel #9
0
def ts_i(L, Ni, index_SA):
    #    index=np.array([1,1,1,0,0,1,1,1])
    index = [index_SA]
    #    index=np.array([0,0,1,1,2,2,3,3])
    index = np.repeat(index, L // len(index))
    ibits = np.zeros((Ni, index.size))
    for i in range(0, index.size):
        ibits[:, i] = dec2bitarray(int(index[i]), Ni)
#    plt.figure()
#    plt.plot(index)
#    ibits=np.random.choice([0,1],L//k*Ni).reshape((Ni,-1)).repeat(k,1)

    return ibits
Beispiel #10
0
    def demodulate(self, input_symbols, demod_type, noise_var=0):
        """ Demodulate (map) a set of constellation symbols to corresponding bits.

        Parameters
        ----------
        input_symbols : 1D ndarray of complex floats
            Input symbols to be demodulated.

        demod_type : string
            'hard' for hard decision output (bits)
            'soft' for soft decision output (LLRs)

        noise_var : float
            AWGN variance. Needs to be specified only if demod_type is 'soft'

        Returns
        -------
        demod_bits : 1D ndarray of ints
            Corresponding demodulated bits.

        """
        if demod_type == 'hard':
            index_list = abs(input_symbols -
                             self._constellation[:, None]).argmin(0)
            demod_bits = dec2bitarray(index_list, self.num_bits_symbol)

        elif demod_type == 'soft':
            demod_bits = zeros(len(input_symbols) * self.num_bits_symbol)
            for i in arange(len(input_symbols)):
                current_symbol = input_symbols[i]
                for bit_index in arange(self.num_bits_symbol):
                    llr_num = 0
                    llr_den = 0
                    for const_index in self.symbol_mapping:
                        if (const_index >> bit_index) & 1:
                            llr_num = llr_num + exp(
                                (-abs(current_symbol -
                                      self._constellation[const_index])**2) /
                                noise_var)
                        else:
                            llr_den = llr_den + exp(
                                (-abs(current_symbol -
                                      self._constellation[const_index])**2) /
                                noise_var)
                    demod_bits[i * self.num_bits_symbol +
                               self.num_bits_symbol - 1 - bit_index] = log(
                                   llr_num / llr_den)
        else:
            raise ValueError('demod_type must be "hard" or "soft"')

        return demod_bits
Beispiel #11
0
def cyclic_code_genpoly(n, k):

    if n % 2 == 0:
        raise ValueError, "n cannot be an even number"

    for m in arange(1, 18):
        if (2**m - 1) % n == 0:
            break

    x_gf = GF(arange(1, 2**m), m)
    coset_fields = x_gf.cosets()

    coset_leaders = array([])
    minpol_degrees = array([])
    for field in coset_fields:
        coset_leaders = concatenate(
            (coset_leaders, array([field.elements[0]])))
        minpol_degrees = concatenate(
            (minpol_degrees, array([len(field.elements)])))

    y_gf = GF(coset_leaders, m)
    minpol_list = y_gf.minpolys()
    idx_list = arange(1, len(minpol_list))
    poly_list = array([])

    for i in xrange(1, 2**len(minpol_list)):
        i_array = dec2bitarray(i, len(minpol_list))
        subset_array = minpol_degrees[i_array == 1]
        if int(subset_array.sum()) == (n - k):
            poly_set = minpol_list[i_array == 1]
            gpoly = 1
            for poly in poly_set:
                gpoly_array = dec2bitarray(gpoly, 2**m)
                poly_array = dec2bitarray(poly, 2**m)
                gpoly = bitarray2dec(convolve(gpoly_array, poly_array) % 2)
            poly_list = concatenate((poly_list, array([gpoly])))

    return poly_list.astype(int)
Beispiel #12
0
def cyclic_code_genpoly(n, k):
    
    if n%2 == 0:
        raise ValueError, "n cannot be an even number"

    for m in arange(1, 18):
        if (2**m-1)%n == 0:
            break

    x_gf = GF(arange(1, 2**m), m)
    coset_fields = x_gf.cosets()
    
    coset_leaders = array([])
    minpol_degrees = array([])
    for field in coset_fields:
        coset_leaders = concatenate((coset_leaders, array([field.elements[0]])))
        minpol_degrees = concatenate((minpol_degrees, array([len(field.elements)])))
    
    y_gf = GF(coset_leaders, m)
    minpol_list = y_gf.minpolys()
    idx_list = arange(1, len(minpol_list))
    poly_list = array([])
    
    for i in xrange(1, 2**len(minpol_list)):
        i_array = dec2bitarray(i, len(minpol_list))
        subset_array = minpol_degrees[i_array == 1]
        if int(subset_array.sum()) == (n-k):
            poly_set = minpol_list[i_array == 1]
            gpoly = 1
            for poly in poly_set:
                gpoly_array = dec2bitarray(gpoly, 2**m)
                poly_array = dec2bitarray(poly, 2**m)
                gpoly = bitarray2dec(convolve(gpoly_array, poly_array) % 2)
            poly_list = concatenate((poly_list, array([gpoly])))

    return poly_list.astype(int)
Beispiel #13
0
def training_symbols(N, Nd, Ni):
    #Ni=2
    #Nd=2
    #N=16
    index = np.arange(0, 2**Ni)
    ibits = np.zeros([Ni, 2**Ni])
    for i in range(0, 2**Ni):
        ibits[:, i] = dec2bitarray(index[i], Ni)
    #!!!!auf ML_approx_unknown Zeile 93 anpassen!!
    ibits_ = ibits
    for j in range(1, N // (2**Ni)):
        ibits = np.concatenate((ibits_, ibits), 1)
        j = j + 1
    #ibits=np.transpose(ibits_).reshape([-1,1])
    dbits = np.random.choice([0, 1], N * Nd).reshape((Nd, -1))
    #dbits=np.random.choice([1],N*Nd).reshape((Nd,-1))
    return ibits, dbits
Beispiel #14
0
    def demodulate(self, input_symbols, demod_type, noise_var = 0):
        """ Demodulate (map) a set of constellation symbols to corresponding bits.

        Supports hard-decision demodulation only.

        Parameters
        ----------
        input_symbols : 1D ndarray of complex floats
            Input symbols to be demodulated.

        demod_type : string
            'hard' for hard decision output (bits)
            'soft' for soft decision output (LLRs)

        noise_var : float
            AWGN variance. Needs to be specified only if demod_type is 'soft'

        Returns
        -------
        demod_bits : 1D ndarray of ints
            Corresponding demodulated bits.

        """
        if demod_type == 'hard':
            index_list = map(lambda i: argmin(abs(input_symbols[i] - self.constellation)), \
                             range(0, len(input_symbols)))
            demod_bits = hstack(map(lambda i: dec2bitarray(i, self.num_bits_symbol),
                                index_list))
        elif demod_type == 'soft':
            demod_bits = zeros(len(input_symbols) * self.num_bits_symbol)
            for i in arange(len(input_symbols)):
                current_symbol = input_symbols[i]
                for bit_index in arange(self.num_bits_symbol):
                    llr_num = 0
                    llr_den = 0
                    for const_index in self.symbol_mapping:
                        if (const_index >> bit_index) & 1:
                            llr_num = llr_num + exp((-abs(current_symbol - self.constellation[const_index])**2)/noise_var)
                        else:
                            llr_den = llr_den + exp((-abs(current_symbol - self.constellation[const_index])**2)/noise_var)
                    demod_bits[i*self.num_bits_symbol + self.num_bits_symbol - 1 - bit_index] = log(llr_num/llr_den)
        else:
            pass
            # throw an error

        return demod_bits
Beispiel #15
0
    def demodulate(self, data):
        """ Demodulate (map) a set of constellation symbols to corresponding bits.

        Supports hard-decision demodulation only.

        Parameters
        ----------
        data : 1D ndarray of complex floats
            Input symbols to be demodulated.

        Returns
        -------
        demod_bits : 1D ndarray of ints
            Corresponding demodulated bits.

        """
        index_list = map(lambda i: np.argmin(abs(data[i] - self.constellation)), 
                             range(0, len(data)))
        demod_bits = np.hstack(list(map(lambda i: dec2bitarray(i, self.num_bits_symbol),
                                index_list)))
        return demod_bits
Beispiel #16
0
    def demodulate(self, input_symbols):
        """ Demodulate (map) a set of constellation symbols to corresponding bits.
        
        Supports hard-decision demodulation only.

        Parameters
        ----------
        input_symbols : 1D ndarray of complex floats
            Input symbols to be demodulated.

        Returns
        -------
        demod_bits : 1D ndarray of ints
            Corresponding demodulated bits.
            
        """
        num_bits_symbol = int(log2(self.m))
        index_list = map(lambda i: argmin(abs(input_symbols[i] - self.constellation)), \
                         xrange(0, len(input_symbols)))
        demod_bits = hstack(map(lambda i: dec2bitarray(i, num_bits_symbol), index_list))

        return demod_bits
Beispiel #17
0
def BER(y, bits, N):
    x = np.zeros((y.size, N))
    for i in range(0, y.size):
        x[i] = dec2bitarray(int(y[i]), N)
    return np.sum(
        np.not_equal(x.reshape((1, x.size)),
                     np.matrix(bits).H.reshape((1, bits.size)))) / x.size


#r_BB=r.channel(H,sender_.ibits,s_BB_off,SNR_noise_dB,SNR_RA_dB,filter_)
#
##r_BB=f.ML_FLL(r_BB,g)
#
#r_BBr_MF=r.Matched_Filter(r_BB.real,filter_.ir() ,filter_.n_up)
#r_BBi_MF=r.Matched_Filter(r_BB.imag,filter_.ir() ,filter_.n_up)
#r_=r_BBr_MF+1j*r_BBi_MF
#
##r_=s.channel(H,ibits,symbols,RA,SNR_noise_dB,SNR_RA_dB)
#
#yi,yd=r.detector(SNR_RA_dB,H,bpsk_map,r_)
#beri=r.BER(yi,sender_.ibits,Ni)
#berd=r.BER(yd,sender_.dbits,Nd)
#print(beri,berd)
##return beri,berd
Beispiel #18
0
def conv_encode(message_bits, trellis, code_type = 'default', puncture_matrix=None):
    """
    Encode bits using a convolutional code.

    Parameters
    ----------
    message_bits : 1D ndarray containing {0, 1}
        Stream of bits to be convolutionally encoded.

    generator_matrix : 2-D ndarray of ints
        Generator matrix G(D) of the convolutional code using which the input
        bits are to be encoded.

    M : 1D ndarray of ints
        Number of memory elements per input of the convolutional encoder.

    Returns
    -------
    coded_bits : 1D ndarray containing {0, 1}
        Encoded bit stream.
    """

    k = trellis.k
    n = trellis.n
    total_memory = trellis.total_memory
    rate = float(k)/n

    if puncture_matrix is None:
        puncture_matrix = np.ones((trellis.k, trellis.n))

    number_message_bits = np.size(message_bits)

    # Initialize an array to contain the message bits plus the truncation zeros
    if code_type == 'default':
        inbits = np.zeros(number_message_bits + total_memory + total_memory % k,
                      'int')
        number_inbits = number_message_bits + total_memory + total_memory % k

        # Pad the input bits with M zeros (L-th terminated truncation)
        inbits[0:number_message_bits] = message_bits
        number_outbits = int(number_inbits/rate)

    else:
        inbits = message_bits
        number_inbits = number_message_bits
        number_outbits = int((number_inbits + total_memory)/rate)

    outbits = np.zeros(number_outbits, 'int')
    p_outbits = np.zeros(int(number_outbits*
            puncture_matrix[0:].sum()/np.size(puncture_matrix, 1)), 'int')
    next_state_table = trellis.next_state_table
    output_table = trellis.output_table

    # Encoding process - Each iteration of the loop represents one clock cycle
    current_state = 0
    j = 0

    for i in range(int(number_inbits/k)): # Loop through all input bits
        current_input = bitarray2dec(inbits[i*k:(i+1)*k])
        current_output = output_table[current_state][current_input]
        outbits[j*n:(j+1)*n] = dec2bitarray(current_output, n)
        current_state = next_state_table[current_state][current_input]
        j += 1

    if code_type == 'rsc':

        term_bits = dec2bitarray(current_state, trellis.total_memory)
        term_bits = term_bits[::-1]
        for i in range(trellis.total_memory):
            current_input = bitarray2dec(term_bits[i*k:(i+1)*k])
            current_output = output_table[current_state][current_input]
            outbits[j*n:(j+1)*n] = dec2bitarray(current_output, n)
            current_state = next_state_table[current_state][current_input]
            j += 1

    j = 0
    for i in range(number_outbits):
        if puncture_matrix[0][i % np.size(puncture_matrix, 1)] == 1:
            p_outbits[j] = outbits[i]
            j = j + 1

    return p_outbits
Beispiel #19
0
import numpy as np
from random import randint
from commpy.modulation import QAMModem
from commpy.filters import rrcosfilter
from commpy.utilities import bitarray2dec, dec2bitarray

np.set_printoptions(threshold=np.nan)
N = 1024  # output size
M = 16
mod1 = QAMModem(M)  # QAM16
sB = dec2bitarray(randint(0, 2**(mod1.num_bits_symbol * N * M / 4)),
                  (mod1.num_bits_symbol * N * M / 4))  # Random bit stream
# print np.array2string(sB)
sQ = mod1.modulate(sB)  # Modulated baud points
print np.array2string(np.abs(sQ))
sPSF = rrcosfilter(N * 4, 0.2, 1, 4000)[1]
qW = np.convolve(sPSF, sQ)  # Waveform with PSF
#print np.array2string(qW)
Beispiel #20
0
    def __init__(self, memory, g_matrix, feedback = 0, code_type = 'default'):

        [self.k, self.n] = g_matrix.shape

        if code_type == 'rsc':
            for i in range(self.k):
                g_matrix[i][i] = feedback

        self.total_memory = memory.sum()
        self.number_states = pow(2, self.total_memory)
        self.number_inputs = pow(2, self.k)
        self.next_state_table = np.zeros([self.number_states,
                                          self.number_inputs], 'int')
        self.output_table = np.zeros([self.number_states,
                                      self.number_inputs], 'int')

        # Compute the entries in the next state table and the output table
        for current_state in range(self.number_states):

            for current_input in range(self.number_inputs):
                outbits = np.zeros(self.n, 'int')

                # Compute the values in the output_table
                for r in range(self.n):

                    output_generator_array = np.zeros(self.k, 'int')
                    shift_register = dec2bitarray(current_state,
                                                  self.total_memory)

                    for l in range(self.k):

                        # Convert the number representing a polynomial into a
                        # bit array
                        generator_array = dec2bitarray(g_matrix[l][r],
                                                       memory[l]+1)

                        # Loop over M delay elements of the shift register
                        # to compute their contribution to the r-th output
                        for i in range(memory[l]):
                            outbits[r] = (outbits[r] + \
                                (shift_register[i+l]*generator_array[i+1])) % 2

                        output_generator_array[l] = generator_array[0]
                        if l == 0:
                            feedback_array = (dec2bitarray(feedback, memory[l]) * shift_register[0:memory[l]]).sum()
                            shift_register[1:memory[l]] = \
                                    shift_register[0:memory[l]-1]
                            shift_register[0] = (dec2bitarray(current_input,
                                    self.k)[0] + feedback_array) % 2
                        else:
                            feedback_array = (dec2bitarray(feedback, memory[l]) *
                                    shift_register[l+memory[l-1]-1:l+memory[l-1]+memory[l]-1]).sum()
                            shift_register[l+memory[l-1]:l+memory[l-1]+memory[l]-1] = \
                                    shift_register[l+memory[l-1]-1:l+memory[l-1]+memory[l]-2]
                            shift_register[l+memory[l-1]-1] = \
                                    (dec2bitarray(current_input, self.k)[l] + feedback_array) % 2

                    # Compute the contribution of the current_input to output
                    outbits[r] = (outbits[r] + \
                        (np.sum(dec2bitarray(current_input, self.k) * \
                        output_generator_array + feedback_array) % 2)) % 2

                # Update the ouput_table using the computed output value
                self.output_table[current_state][current_input] = \
                    bitarray2dec(outbits)

                # Update the next_state_table using the new state of
                # the shift register
                self.next_state_table[current_state][current_input] = \
                    bitarray2dec(shift_register)
Beispiel #21
0
def conv_encode(message_bits, trellis, termination = 'term', puncture_matrix=None):
    """
    Encode bits using a convolutional code.
    Parameters
    ----------
    message_bits : 1D ndarray containing {0, 1}
        Stream of bits to be convolutionally encoded.
    trellis: pre-initialized Trellis structure.
    termination: {'cont', 'term'}, optional
        Create ('term') or not ('cont') termination bits.
    puncture_matrix: 2D ndarray containing {0, 1}, optional
        Matrix used for the puncturing algorithm
    Returns
    -------
    coded_bits : 1D ndarray containing {0, 1}
        Encoded bit stream.
    """

    k = trellis.k
    n = trellis.n
    total_memory = trellis.total_memory
    rate = float(k)/n
    
    code_type = trellis.code_type

    if puncture_matrix is None:
        puncture_matrix = np.ones((trellis.k, trellis.n))

    number_message_bits = np.size(message_bits)
    
    if termination == 'cont':
        inbits = message_bits
        number_inbits = number_message_bits
        number_outbits = int(number_inbits/rate)
    else:
        # Initialize an array to contain the message bits plus the truncation zeros
        if code_type == 'rsc':
            inbits = message_bits
            number_inbits = number_message_bits
            number_outbits = int((number_inbits + k * total_memory)/rate)
        else:
            number_inbits = number_message_bits + total_memory + total_memory % k
            inbits = np.zeros(number_inbits, 'int')
            # Pad the input bits with M zeros (L-th terminated truncation)
            inbits[0:number_message_bits] = message_bits
            number_outbits = int(number_inbits/rate)

    outbits = np.zeros(number_outbits, 'int')
    if puncture_matrix is not None:
        p_outbits = np.zeros(number_outbits, 'int')
    else:
        p_outbits = np.zeros(int(number_outbits*
            puncture_matrix[0:].sum()/np.size(puncture_matrix, 1)), 'int')
    next_state_table = trellis.next_state_table
    output_table = trellis.output_table

    # Encoding process - Each iteration of the loop represents one clock cycle
    current_state = 0
    j = 0

    for i in range(int(number_inbits/k)): # Loop through all input bits
        current_input = bitarray2dec(inbits[i*k:(i+1)*k])
        current_output = output_table[current_state][current_input]
        outbits[j*n:(j+1)*n] = dec2bitarray(current_output, n)
        current_state = next_state_table[current_state][current_input]
        j += 1

    if code_type == 'rsc' and termination == 'term':
        term_bits = dec2bitarray(current_state, trellis.total_memory)
        term_bits = term_bits[::-1]
        for i in range(trellis.total_memory):
            current_input = bitarray2dec(term_bits[i*k:(i+1)*k])
            current_output = output_table[current_state][current_input]
            outbits[j*n:(j+1)*n] = dec2bitarray(current_output, n)
            current_state = next_state_table[current_state][current_input]
            j += 1

    j = 0
    for i in range(number_outbits):
        if puncture_matrix[0][i % np.size(puncture_matrix, 1)] == 1:
            p_outbits[j] = outbits[i]
            j = j + 1

    return p_outbits
Beispiel #22
0
def _acs_traceback(r_codeword, trellis, decoding_type,
                   path_metrics, paths, decoded_symbols,
                   decoded_bits, tb_count, t, count,
                   tb_depth, current_number_states):

    k = trellis.k
    n = trellis.n
    number_states = trellis.number_states
    number_inputs = trellis.number_inputs

    branch_metric = 0.0

    next_state_table = trellis.next_state_table
    output_table = trellis.output_table
    pmetrics = np.empty(number_inputs)
    index_array = np.empty([number_states, 2], 'int')

    # Loop over all the current states (Time instant: t)
    for state_num in range(current_number_states):

        # Using the next state table find the previous states and inputs
        # leading into the current state (Trellis)
        number_found = _where_c(next_state_table, number_states, number_inputs, state_num, index_array)

        # Loop over all the previous states (Time instant: t-1)
        for i in range(number_found):

            previous_state = index_array[i, 0]
            previous_input = index_array[i, 1]

            # Using the output table, find the ideal codeword
            i_codeword = output_table[previous_state, previous_input]
            i_codeword_array = dec2bitarray(i_codeword, n)

            # Compute Branch Metrics
            if decoding_type == 'hard':
                branch_metric = hamming_dist(r_codeword.astype(int), i_codeword_array.astype(int))
            elif decoding_type == 'soft':
                neg_LL_0 = np.log(np.exp(r_codeword) + 1)  # negative log-likelihood to have received a 0
                neg_LL_1 = neg_LL_0 - r_codeword  # negative log-likelihood to have received a 1
                branch_metric = np.where(i_codeword_array, neg_LL_1, neg_LL_0).sum()
            elif decoding_type == 'unquantized':
                i_codeword_array = 2*i_codeword_array - 1
                branch_metric = euclid_dist(r_codeword, i_codeword_array)

            # ADD operation: Add the branch metric to the
            # accumulated path metric and store it in the temporary array
            pmetrics[i] = path_metrics[previous_state, 0] + branch_metric

        # COMPARE and SELECT operations
        # Compare and Select the minimum accumulated path metric
        path_metrics[state_num, 1] = pmetrics.min()

        # Store the previous state corresponding to the minimum
        # accumulated path metric
        min_idx = pmetrics.argmin()
        paths[state_num, tb_count] = index_array[min_idx, 0]

        # Store the previous input corresponding to the minimum
        # accumulated path metric
        decoded_symbols[state_num, tb_count] = index_array[min_idx, 1]

    if t >= tb_depth - 1:
        current_state = path_metrics[:,1].argmin()

        # Traceback Loop
        for j in reversed(range(1, tb_depth)):

            dec_symbol = decoded_symbols[current_state, j]
            previous_state = paths[current_state, j]
            decoded_bitarray = dec2bitarray(dec_symbol, k)
            decoded_bits[t - tb_depth + 1 + (j - 1) * k + count:t - tb_depth + 1 + j * k + count] = decoded_bitarray
            current_state = previous_state

        paths[:,0:tb_depth-1] = paths[:,1:]
        decoded_symbols[:,0:tb_depth-1] = decoded_symbols[:,1:]
Beispiel #23
0
import numpy as np
import commpy.channelcoding.convcode as cc
from commpy.utilities import dec2bitarray
import binascii

#***********************************************
#Conversion from text message into binary array#
#***********************************************
msg = 'Hello World'
#Ascci converted to hex and then to dec
for s in range(len(msg)):
    msg_dec = int(
        binascii.hexlify(msg[s].encode(encoding='UTF-8', errors='strict')), 16)
num = 8 * len(msg)
#Convert decimal numbers into array
gen = dec2bitarray(msg_dec, num)
#***********************************************
# DAC parameters configuration
#***********************************************
SPB = 10
#for d in range(len(gen)):
#	data = gen(d)*SPB
print(type(gen))
print(msg)
print(msg_dec)
print(num)
print(gen)
print(len(gen))
#print(data)

#++++++++++++++++++++++++++++++++++++++++++++++
Beispiel #24
0
    def __init__(self, memory, g_matrix, feedback = None, code_type = 'default'):

        [self.k, self.n] = g_matrix.shape
        self.code_type = code_type
        
        self.total_memory = memory.sum()
        self.number_states = pow(2, self.total_memory)
        self.number_inputs = pow(2, self.k)
        self.next_state_table = np.zeros([self.number_states,
                                          self.number_inputs], 'int')
        self.output_table = np.zeros([self.number_states,
                                      self.number_inputs], 'int')

        if isinstance(feedback, int):
            warn('Trellis  will only accept feedback as a matrix in the future. '
                 'Using the backwards compatibility version that may contain bugs for k > 1.', DeprecationWarning)

            if code_type == 'rsc':
                for i in range(self.k):
                    g_matrix[i][i] = feedback

            # Compute the entries in the next state table and the output table
            for current_state in range(self.number_states):

                for current_input in range(self.number_inputs):
                    outbits = np.zeros(self.n, 'int')

                    # Compute the values in the output_table
                    for r in range(self.n):

                        output_generator_array = np.zeros(self.k, 'int')
                        shift_register = dec2bitarray(current_state,
                                                      self.total_memory)

                        for l in range(self.k):

                            # Convert the number representing a polynomial into a
                            # bit array
                            generator_array = dec2bitarray(g_matrix[l][r],
                                                           memory[l] + 1)

                            # Loop over M delay elements of the shift register
                            # to compute their contribution to the r-th output
                            for i in range(memory[l]):
                                outbits[r] = (outbits[r] + \
                                              (shift_register[i + l] * generator_array[i + 1])) % 2

                            output_generator_array[l] = generator_array[0]
                            if l == 0:
                                feedback_array = (dec2bitarray(feedback, memory[l])[1:] * shift_register[0:memory[l]]).sum()
                                shift_register[1:memory[l]] = \
                                    shift_register[0:memory[l] - 1]
                                shift_register[0] = (dec2bitarray(current_input,
                                                                  self.k)[0] + feedback_array) % 2
                            else:
                                feedback_array = (dec2bitarray(feedback, memory[l]) *
                                                  shift_register[
                                                  l + memory[l - 1] - 1:l + memory[l - 1] + memory[l] - 1]).sum()
                                shift_register[l + memory[l - 1]:l + memory[l - 1] + memory[l] - 1] = \
                                    shift_register[l + memory[l - 1] - 1:l + memory[l - 1] + memory[l] - 2]
                                shift_register[l + memory[l - 1] - 1] = \
                                    (dec2bitarray(current_input, self.k)[l] + feedback_array) % 2

                        # Compute the contribution of the current_input to output
                        outbits[r] = (outbits[r] + \
                                      (np.sum(dec2bitarray(current_input, self.k) * \
                                              output_generator_array + feedback_array) % 2)) % 2

                    # Update the ouput_table using the computed output value
                    self.output_table[current_state][current_input] = \
                        bitarray2dec(outbits)

                    # Update the next_state_table using the new state of
                    # the shift register
                    self.next_state_table[current_state][current_input] = \
                        bitarray2dec(shift_register)

        else:
            if feedback is None:
                feedback = np.identity(self.k, int)

            # feedback_array[i] holds the i-th bit corresponding to each feedback polynomial.
            feedback_array = np.empty((self.total_memory + self.k, self.k, self.k), np.int8)
            for i in range(self.k):
                for j in range(self.k):
                    feedback_array[:, i, j] = dec2bitarray(feedback[i, j], self.total_memory + self.k)[::-1]

            # g_matrix_array[i] holds the i-th bit corresponding to each g_matrix polynomial.
            g_matrix_array = np.empty((self.total_memory + self.k, self.k, self.n), np.int8)
            for i in range(self.k):
                for j in range(self.n):
                    g_matrix_array[:, i, j] = dec2bitarray(g_matrix[i, j], self.total_memory + self.k)[::-1]

            # shift_regs holds on each column the state of a shift register.
            # The first row is the input of each shift reg.
            shift_regs = np.empty((self.total_memory + self.k, self.k), np.int8)

            # Compute the entries in the next state table and the output table
            for current_state in range(self.number_states):
                for current_input in range(self.number_inputs):
                    current_state_array = dec2bitarray(current_state, self.total_memory)

                    # Set the first row as the input.
                    shift_regs[0] = dec2bitarray(current_input, self.k)

                    # Set the other rows based on the current_state
                    idx = 0
                    for idx_mem, mem in enumerate(memory):
                        shift_regs[1:mem+1, idx_mem] = current_state_array[idx:idx + mem]
                        idx += mem

                    # Compute the output table
                    outputs_array = np.einsum('ik,ikl->l', shift_regs, g_matrix_array) % 2
                    self.output_table[current_state, current_input] = bitarray2dec(outputs_array)

                    # Update the first line based on the feedback polynomial
                    np.einsum('ik,ilk->l', shift_regs, feedback_array, out=shift_regs[0])
                    shift_regs %= 2

                    # Update current state array and compute next state table
                    idx = 0
                    for idx_mem, mem in enumerate(memory):
                        current_state_array[idx:idx + mem] = shift_regs[:mem, idx_mem]
                        idx += mem
                    self.next_state_table[current_state, current_input] = bitarray2dec(current_state_array)
Beispiel #25
0
def test_dec2bitarray():
    # Assert result
    assert_array_equal(dec2bitarray(17, 8), array((0, 0, 0, 1, 0, 0, 0, 1)))
    assert_array_equal(dec2bitarray((17, 12), 5), array((1, 0, 0, 0, 1, 0, 1, 1, 0, 0)))
Beispiel #26
0
def _acs_traceback(r_codeword, trellis, decoding_type, path_metrics, paths,
                   decoded_symbols, decoded_bits, tb_count, t, count, tb_depth,
                   current_number_states):

    k = trellis.k
    n = trellis.n
    number_states = trellis.number_states
    number_inputs = trellis.number_inputs

    branch_metric = 0.0

    next_state_table = trellis.next_state_table
    output_table = trellis.output_table
    pmetrics = np.empty(number_inputs)
    index_array = np.empty([number_states, 2], 'int')

    # Loop over all the current states (Time instant: t)
    for state_num in range(current_number_states):

        # Using the next state table find the previous states and inputs
        # leading into the current state (Trellis)
        number_found = _where_c(next_state_table, number_states, number_inputs,
                                state_num, index_array)

        # Loop over all the previous states (Time instant: t-1)
        for i in range(number_found):

            previous_state = index_array[i, 0]
            previous_input = index_array[i, 1]

            # Using the output table, find the ideal codeword
            i_codeword = output_table[previous_state, previous_input]
            i_codeword_array = dec2bitarray(i_codeword, n)

            # Compute Branch Metrics
            branch_metric = _compute_branch_metrics(decoding_type,
                                                    tuple(r_codeword),
                                                    tuple(i_codeword_array))

            # ADD operation: Add the branch metric to the
            # accumulated path metric and store it in the temporary array
            pmetrics[i] = path_metrics[previous_state, 0] + branch_metric

        # COMPARE and SELECT operations
        # Compare and Select the minimum accumulated path metric
        path_metrics[state_num, 1] = pmetrics.min()

        # Store the previous state corresponding to the minimum
        # accumulated path metric
        min_idx = pmetrics.argmin()
        paths[state_num, tb_count] = index_array[min_idx, 0]

        # Store the previous input corresponding to the minimum
        # accumulated path metric
        decoded_symbols[state_num, tb_count] = index_array[min_idx, 1]

    if t >= tb_depth - 1:
        current_state = path_metrics[:, 1].argmin()

        # Traceback Loop
        for j in reversed(range(1, tb_depth)):

            dec_symbol = decoded_symbols[current_state, j]
            previous_state = paths[current_state, j]
            decoded_bitarray = dec2bitarray(dec_symbol, k)
            decoded_bits[t - tb_depth + 1 + (j - 1) * k + count:t - tb_depth +
                         1 + j * k + count] = decoded_bitarray
            current_state = previous_state

        paths[:, 0:tb_depth - 1] = paths[:, 1:]
        decoded_symbols[:, 0:tb_depth - 1] = decoded_symbols[:, 1:]
Beispiel #27
0
def stack_soft_decoder(receive_code, metrics, trellis):
    # k = trellis.k
    n = trellis.n
    # number_states = trellis.number_states
    number_inputs = trellis.number_inputs
    next_state_table = trellis.next_state_table
    output_table = trellis.output_table
    path_metric = {}
    r_code = convert(receive_code)
    list_length = 128
    init_time = time.time()

    for i in range(10**8):
        # a long sequence to guarantee the iterations times of stack decoder
        # each receiving code to be decoded

        if i == 0:
            for j in range(number_inputs):
                p_metric = 0.0
                output = output_table[0][j]
                output_array = dec2bitarray(output, n)
                r_code_array = array(r_code[2 * i:(2 * i + 2)])
                p_metric += soft_metric(
                    metrics, output_array[0], r_code_array[0]) + soft_metric(
                        metrics, output_array[1], r_code_array[1])
                path_metric[str(j)] = p_metric
            path_metric = dict(
                sorted(path_metric.items(), key=operator.itemgetter(1)))
            # dictionary always go in the order from small to big

        elif i == 1:
            # get the path with best metric right now
            # current_best_path = dict(sorted(path_metric.items(),key = operator.itemgetter(1))[len(path_metric)-1])
            last_input = list(path_metric)[len(path_metric) - 1]
            # last_input = max(path_metric, key=lambda k: path_metric[k])
            current_state = next_state_table[0][int(last_input)]
            for j in range(number_inputs):
                p_metric = 0.0
                output = output_table[current_state][j]
                output_array = dec2bitarray(output, n)
                r_code_array = array(r_code[2 * i:(2 * i + 2)])
                p_metric += soft_metric(
                    metrics, output_array[0], r_code_array[0]) + soft_metric(
                        metrics, output_array[1], r_code_array[1])
                path_metric[str(last_input) +
                            str(j)] = path_metric[last_input] + p_metric

            path_metric.pop(str(last_input))
            path_metric = dict(
                sorted(path_metric.items(), key=operator.itemgetter(1)))
            # dictionary always go in the order as from small to big

        elif i >= 2:
            best_path_sofar = list(path_metric)[
                len(path_metric) - 1]  # ????it's an int other than string
            # best_path_sofar = max(path_metric, key=lambda k: path_metric[k])
            if len(best_path_sofar) >= 2:
                current_state = 0
                for m in best_path_sofar:
                    # current_state = int(str(best_path_sofar)[len(best_path_sofar) - 1] + str(best_path_sofar)
                    # [len(best_path_sofar) - 2])
                    current_state = next_state_table[current_state][int(m)]
            elif len(best_path_sofar) == 1:
                current_state = next_state_table[0][int(best_path_sofar)]
            else:
                current_state = 0
            for j in range(number_inputs):
                p_metric = 0.0
                output = output_table[current_state][j]
                output_array = dec2bitarray(output, n)
                r_code_array = array(
                    r_code[2 * len(best_path_sofar):(2 * len(best_path_sofar) +
                                                     2)])
                p_metric += soft_metric(
                    metrics, output_array[0], r_code_array[0]) + soft_metric(
                        metrics, output_array[1], r_code_array[1])
                path_metric[str(best_path_sofar) +
                            str(j)] = path_metric[best_path_sofar] + p_metric

            path_metric.pop(str(best_path_sofar))
            path_metric = dict(
                sorted(path_metric.items(), key=operator.itemgetter(1)))
            # dictionary always go in the order as from small to big
            if len(path_metric) > list_length:
                path_metric.pop(list(path_metric)[0])
            if len(list(path_metric)[len(path_metric) - 1]) >= math.ceil(
                    0.5 * len(r_code)):
                break
            if (time.time() - init_time) > 2:
                break

    decoded_bits = max(path_metric, key=lambda k: path_metric[k])
    decoded_code = [0] * len(decoded_bits)
    for k in range(len(decoded_bits)):
        decoded_code[k] = int(decoded_bits[k])

    return decoded_code
def stack_decoder(receive_code, metrics, trellis, initial_state, initial_metric, discarded_path='2'):
    k = trellis.k
    n = trellis.n
    number_states = trellis.number_states
    number_inputs = trellis.number_inputs
    next_state_table = trellis.next_state_table
    output_table = trellis.output_table
    r_code = convert(receive_code)
    final_state = 0
    path_metric = {discarded_path: -10**8}
    list_length = 128
    M = trellis.total_memory

    for i in range(10**6):  # a large number to guarantee the sufficient iterations times of stack decoder
        # each receiving code to be decoded
        if i == 0:
            for j in range(number_inputs):
                p_metric = 0.0
                output = output_table[initial_state][j]
                output_array = dec2bitarray(output, n)
                r_code_array = array(r_code[2 * i:(2 * i + 2)])
                p_metric += (soft_metric(metrics, output_array[0], r_code_array[0]) + soft_metric(metrics, output_array[1], r_code_array[1]))
                path_metric[str(j)] = p_metric + initial_metric
            path_metric = dict(sorted(path_metric.items(), key=operator.itemgetter(1)))
            # dictionary always go in the order as from small to big

        elif i == 1:
            # get the path with best metric right now
            # current_best_path = dict(sorted(path_metric.items(),key = operator.itemgetter(1))[len(path_metric)-1])
            # last_input = max(path_metric, key=lambda k: path_metric[k])
            last_input = list(path_metric)[len(path_metric) - 1]
            current_state = next_state_table[initial_state][int(last_input)]
            for j in range(number_inputs):
                p_metric = 0.0
                output = output_table[current_state][j]
                output_array = dec2bitarray(output, n)
                r_code_array = array(r_code[2 * i:(2 * i + 2)])
                p_metric += (soft_metric(metrics, output_array[0], r_code_array[0]) + soft_metric(metrics, output_array[1], r_code_array[1]))

                path_metric[str(last_input) + str(j)] = path_metric[last_input] + p_metric

            path_metric.pop(str(last_input))
            path_metric = dict(sorted(path_metric.items(), key=operator.itemgetter(1)))
            #  dictionary always go in the order as from small to big

        elif i >= 2:
            best_path_sofar = list(path_metric)[len(path_metric) - 1]  # ????? it's an int other than string
            if len(best_path_sofar) >= 2:
                current_state = initial_state
                for m in str(best_path_sofar):
                    # current_state = int(str(best_path_sofar)[len(best_path_sofar) - 1] + str(best_path_sofar)
                    # [len(best_path_sofar) - 2])
                    current_state = next_state_table[current_state][int(m)]
            elif len(best_path_sofar) == 1:
                current_state = next_state_table[initial_state][int(best_path_sofar)]
            else:
                current_state = initial_state
            for j in range(number_inputs):
                p_metric = 0.0
                output = output_table[current_state][j]
                output_array = dec2bitarray(output, n)
                r_code_array = array(r_code[2 * len(best_path_sofar):(2 * len(best_path_sofar) + 2)])
                p_metric += (soft_metric(metrics, output_array[0], r_code_array[0]) + soft_metric(metrics, output_array[1], r_code_array[1]))

                path_metric[str(best_path_sofar) + str(j)] = path_metric[best_path_sofar] + p_metric

            path_metric.pop(str(best_path_sofar))
            path_metric = dict(sorted(path_metric.items(), key=operator.itemgetter(1)))
            # dictionary always go in the order from small to big
            if len(path_metric) > list_length:
                path_metric.pop(list(path_metric)[0])
            if len(list(path_metric)[len(path_metric) - 1]) >= len(r_code)*0.5:
                break

    decoded_bits = list(path_metric)[len(path_metric) - 1]
    ini_state_bit = list(dec2bitarray(initial_state, 8)[::-1])
    final_metric = path_metric[decoded_bits]
    decoded_code = [0]*len(decoded_bits)
    for k in range(len(decoded_bits)):
        decoded_code[k] = int(decoded_bits[k])
    # decoded_code += ini_state_bit
    final_state = bitarray2dec(decoded_code[(int(len(r_code) * 0.5) - M):][::-1])

    return decoded_code, final_metric, final_state, decoded_bits
Beispiel #29
0
def polymultiply(x, y, m, prim_poly):
    x_array = dec2bitarray(x, m)
    y_array = dec2bitarray(y, m)
    prod = bitarray2dec(convolve(x_array, y_array) % 2)
    return polydivide(prod, prim_poly)
Beispiel #30
0
def polymultiply(x, y, m, prim_poly):
    x_array = dec2bitarray(x, m)
    y_array = dec2bitarray(y, m)
    prod = bitarray2dec(convolve(x_array, y_array) % 2)
    return polydivide(prod, prim_poly)
Beispiel #31
0
    def __init__(self, memory, g_matrix, feedback=0, code_type='default'):

        [self.k, self.n] = g_matrix.shape

        if code_type == 'rsc':
            for i in xrange(self.k):
                g_matrix[i][i] = feedback

        self.total_memory = memory.sum()
        self.number_states = pow(2, self.total_memory)
        self.number_inputs = pow(2, self.k)
        self.next_state_table = np.zeros(
            [self.number_states, self.number_inputs], 'int')
        self.output_table = np.zeros([self.number_states, self.number_inputs],
                                     'int')

        # Compute the entries in the next state table and the output table
        for current_state in xrange(self.number_states):

            for current_input in xrange(self.number_inputs):
                outbits = np.zeros(self.n, 'int')

                # Compute the values in the output_table
                for r in xrange(self.n):

                    output_generator_array = np.zeros(self.k, 'int')
                    shift_register = dec2bitarray(current_state,
                                                  self.total_memory)

                    for l in xrange(self.k):

                        # Convert the number representing a polynomial into a
                        # bit array
                        generator_array = dec2bitarray(g_matrix[l][r],
                                                       memory[l] + 1)

                        # Loop over M delay elements of the shift register
                        # to compute their contribution to the r-th output
                        for i in xrange(memory[l]):
                            outbits[r] = (outbits[r] + \
                                (shift_register[i+l]*generator_array[i+1])) % 2

                        output_generator_array[l] = generator_array[0]
                        if l == 0:
                            feedback_array = (
                                dec2bitarray(feedback, memory[l]) *
                                shift_register[0:memory[l]]).sum()
                            shift_register[1:memory[l]] = \
                                    shift_register[0:memory[l]-1]
                            shift_register[0] = (dec2bitarray(
                                current_input, self.k)[0] + feedback_array) % 2
                        else:
                            feedback_array = (
                                dec2bitarray(feedback, memory[l]) *
                                shift_register[l + memory[l - 1] - 1:l +
                                               memory[l - 1] + memory[l] -
                                               1]).sum()
                            shift_register[l+memory[l-1]:l+memory[l-1]+memory[l]-1] = \
                                    shift_register[l+memory[l-1]-1:l+memory[l-1]+memory[l]-2]
                            shift_register[l+memory[l-1]-1] = \
                                    (dec2bitarray(current_input, self.k)[l] + feedback_array) % 2

                    # Compute the contribution of the current_input to output
                    outbits[r] = (outbits[r] + \
                        (np.sum(dec2bitarray(current_input, self.k) * \
                        output_generator_array + feedback_array) % 2)) % 2

                # Update the ouput_table using the computed output value
                self.output_table[current_state][current_input] = \
                    bitarray2dec(outbits)

                # Update the next_state_table using the new state of
                # the shift register
                self.next_state_table[current_state][current_input] = \
                    bitarray2dec(shift_register)
Beispiel #32
0
def _acs_traceback(r_codeword, trellis, decoding_type,
                   path_metrics, paths, decoded_symbols,
                   decoded_bits, tb_count, t, count,
                   tb_depth, current_number_states):

    #cdef int state_num, i, j, number_previous_states, previous_state, \
    #        previous_input, i_codeword, number_found, min_idx, \
    #        current_state, dec_symbol

    k = trellis.k
    n = trellis.n
    number_states = trellis.number_states
    number_inputs = trellis.number_inputs

    branch_metric = 0.0

    next_state_table = trellis.next_state_table
    output_table = trellis.output_table
    pmetrics = np.empty(number_inputs)
    i_codeword_array = np.empty(n, 'int')
    index_array = np.empty([number_states, 2], 'int')
    decoded_bitarray = np.empty(k, 'int')

    # Loop over all the current states (Time instant: t)
    for state_num in range(current_number_states):

        # Using the next state table find the previous states and inputs
        # leading into the current state (Trellis)
        number_found = _where_c(next_state_table, number_states, number_inputs, state_num, index_array)

        # Loop over all the previous states (Time instant: t-1)
        for i in range(number_found):

            previous_state = index_array[i, 0]
            previous_input = index_array[i, 1]

            # Using the output table, find the ideal codeword
            i_codeword = output_table[previous_state, previous_input]
            #dec2bitarray_c(i_codeword, n, i_codeword_array)
            i_codeword_array = dec2bitarray(i_codeword, n)

            # Compute Branch Metrics
            if decoding_type == 'hard':
                #branch_metric = hamming_dist_c(r_codeword.astype(int), i_codeword_array.astype(int), n)
                branch_metric = hamming_dist(r_codeword.astype(int), i_codeword_array.astype(int))
            elif decoding_type == 'soft':
                pass
            elif decoding_type == 'unquantized':
                i_codeword_array = 2*i_codeword_array - 1
                branch_metric = euclid_dist(r_codeword, i_codeword_array)
            else:
                pass

            # ADD operation: Add the branch metric to the
            # accumulated path metric and store it in the temporary array
            pmetrics[i] = path_metrics[previous_state, 0] + branch_metric

        # COMPARE and SELECT operations
        # Compare and Select the minimum accumulated path metric
        path_metrics[state_num, 1] = pmetrics.min()

        # Store the previous state corresponding to the minimum
        # accumulated path metric
        min_idx = pmetrics.argmin()
        paths[state_num, tb_count] = index_array[min_idx, 0]

        # Store the previous input corresponding to the minimum
        # accumulated path metric
        decoded_symbols[state_num, tb_count] = index_array[min_idx, 1]

    if t >= tb_depth - 1:
        current_state = path_metrics[:,1].argmin()

        # Traceback Loop
        for j in reversed(range(1, tb_depth)):

            dec_symbol = decoded_symbols[current_state, j]
            previous_state = paths[current_state, j]
            decoded_bitarray = dec2bitarray(dec_symbol, k)
            decoded_bits[(t-tb_depth-1)+(j+1)*k+count:(t-tb_depth-1)+(j+2)*k+count] =  \
                    decoded_bitarray
            current_state = previous_state

        paths[:,0:tb_depth-1] = paths[:,1:]
        decoded_symbols[:,0:tb_depth-1] = decoded_symbols[:,1:]
Beispiel #33
0
def _acs_traceback(r_codeword, trellis, decoding_type, path_metrics, paths,
                   decoded_symbols, decoded_bits, tb_count, t, count, tb_depth,
                   current_number_states):

    #cdef int state_num, i, j, number_previous_states, previous_state, \
    #        previous_input, i_codeword, number_found, min_idx, \
    #        current_state, dec_symbol

    k = trellis.k
    n = trellis.n
    number_states = trellis.number_states
    number_inputs = trellis.number_inputs

    branch_metric = 0.0

    next_state_table = trellis.next_state_table
    output_table = trellis.output_table
    pmetrics = np.empty(number_inputs)
    i_codeword_array = np.empty(n, 'int')
    index_array = np.empty([number_states, 2], 'int')
    decoded_bitarray = np.empty(k, 'int')

    # Loop over all the current states (Time instant: t)
    for state_num in range(current_number_states):

        # Using the next state table find the previous states and inputs
        # leading into the current state (Trellis)
        number_found = _where_c(next_state_table, number_states, number_inputs,
                                state_num, index_array)

        # Loop over all the previous states (Time instant: t-1)
        for i in range(number_found):

            previous_state = index_array[i, 0]
            previous_input = index_array[i, 1]

            # Using the output table, find the ideal codeword
            i_codeword = output_table[previous_state, previous_input]
            #dec2bitarray_c(i_codeword, n, i_codeword_array)
            i_codeword_array = dec2bitarray(i_codeword, n)

            # Compute Branch Metrics
            if decoding_type == 'hard':
                #branch_metric = hamming_dist_c(r_codeword.astype(int), i_codeword_array.astype(int), n)
                branch_metric = hamming_dist(r_codeword.astype(int),
                                             i_codeword_array.astype(int))
            elif decoding_type == 'soft':
                pass
            elif decoding_type == 'unquantized':
                i_codeword_array = 2 * i_codeword_array - 1
                branch_metric = euclid_dist(r_codeword, i_codeword_array)
            else:
                pass

            # print("branch_metric: ")
            # print(branch_metric)
            # ADD operation: Add the branch metric to the
            # accumulated path metric and store it in the temporary array
            pmetrics[i] = path_metrics[previous_state, 0] + branch_metric

        # COMPARE and SELECT operations
        # Compare and Select the minimum accumulated path metric
        path_metrics[state_num, 1] = pmetrics.min()

        # Store the previous state corresponding to the minimum
        # accumulated path metric
        min_idx = pmetrics.argmin()
        paths[state_num, tb_count] = index_array[min_idx, 0]

        # Store the previous input corresponding to the minimum
        # accumulated path metric
        decoded_symbols[state_num, tb_count] = index_array[min_idx, 1]

    if t >= tb_depth - 1:
        current_state = path_metrics[:, 1].argmin()

        # Traceback Loop
        for j in reversed(range(1, tb_depth)):

            dec_symbol = decoded_symbols[current_state, j]
            previous_state = paths[current_state, j]
            decoded_bitarray = dec2bitarray(dec_symbol, k)
            decoded_bits[(t-tb_depth-1)+(j+1)*k+count:(t-tb_depth-1)+(j+2)*k+count] =  \
                    decoded_bitarray
            current_state = previous_state

        paths[:, 0:tb_depth - 1] = paths[:, 1:]
        decoded_symbols[:, 0:tb_depth - 1] = decoded_symbols[:, 1:]
Beispiel #34
0
def conv_encode(message_bits,
                trellis,
                code_type='default',
                puncture_matrix=None):
    """
    Encode bits using a convolutional code.

    Parameters
    ----------  
    message_bits : 1D ndarray containing {0, 1}
        Stream of bits to be convolutionally encoded.
    
    generator_matrix : 2-D ndarray of ints
        Generator matrix G(D) of the convolutional code using which the input 
        bits are to be encoded.
    
    M : 1D ndarray of ints 
        Number of memory elements per input of the convolutional encoder.

    Returns
    -------
    coded_bits : 1D ndarray containing {0, 1} 
        Encoded bit stream.
    """

    k = trellis.k
    n = trellis.n
    total_memory = trellis.total_memory
    rate = float(k) / n

    if puncture_matrix is None:
        puncture_matrix = np.ones((trellis.k, trellis.n))

    number_message_bits = np.size(message_bits)

    # Initialize an array to contain the message bits plus the truncation zeros
    if code_type == 'default':
        inbits = np.zeros(
            number_message_bits + total_memory + total_memory % k, 'int')
        number_inbits = number_message_bits + total_memory + total_memory % k

        # Pad the input bits with M zeros (L-th terminated truncation)
        inbits[0:number_message_bits] = message_bits
        number_outbits = int(number_inbits / rate)

    else:
        inbits = message_bits
        number_inbits = number_message_bits
        number_outbits = int((number_inbits + total_memory) / rate)

    outbits = np.zeros(number_outbits, 'int')
    p_outbits = np.zeros(
        number_outbits * puncture_matrix[0:].sum() /
        np.size(puncture_matrix, 1), 'int')
    next_state_table = trellis.next_state_table
    output_table = trellis.output_table

    # Encoding process - Each iteration of the loop represents one clock cycle
    current_state = 0
    j = 0

    for i in xrange(number_inbits / k):  # Loop through all input bits
        current_input = bitarray2dec(inbits[i * k:(i + 1) * k])
        current_output = output_table[current_state][current_input]
        outbits[j * n:(j + 1) * n] = dec2bitarray(current_output, n)
        current_state = next_state_table[current_state][current_input]
        j += 1

    if code_type == 'rsc':

        term_bits = dec2bitarray(current_state, trellis.total_memory)
        term_bits = term_bits[::-1]
        for i in xrange(trellis.total_memory):
            current_input = bitarray2dec(term_bits[i * k:(i + 1) * k])
            current_output = output_table[current_state][current_input]
            outbits[j * n:(j + 1) * n] = dec2bitarray(current_output, n)
            current_state = next_state_table[current_state][current_input]
            j += 1

    j = 0
    for i in xrange(number_outbits):
        if puncture_matrix[0][i % np.size(puncture_matrix, 1)] == 1:
            p_outbits[j] = outbits[i]
            j = j + 1

    return p_outbits
Beispiel #35
0
 def _identity_encode(self, data):
     return np.hstack([dec2bitarray(d, self.byte_width) for d in data])
Beispiel #36
-1
def cyclic_code_genpoly(n, k):
    """
    Generate all possible generator polynomials for a (n, k)-cyclic code.

    Parameters
    ----------
    n : int
        Code blocklength of the cyclic code.

    k : int
        Information blocklength of the cyclic code.

    Returns
    -------
    poly_list : 1D ndarray of ints
        A list of generator polynomials (represented as integers) for the (n, k)-cyclic code.

    """


    if n%2 == 0:
        raise ValueError("n cannot be an even number")

    for m in arange(1, 18):
        if (2**m-1)%n == 0:
            break

    x_gf = GF(arange(1, 2**m), m)
    coset_fields = x_gf.cosets()

    coset_leaders = array([])
    minpol_degrees = array([])
    for field in coset_fields:
        coset_leaders = concatenate((coset_leaders, array([field.elements[0]])))
        minpol_degrees = concatenate((minpol_degrees, array([len(field.elements)])))

    y_gf = GF(coset_leaders, m)
    minpol_list = y_gf.minpolys()
    idx_list = arange(1, len(minpol_list))
    poly_list = array([])

    for i in range(1, 2**len(minpol_list)):
        i_array = dec2bitarray(i, len(minpol_list))
        subset_array = minpol_degrees[i_array == 1]
        if int(subset_array.sum()) == (n-k):
            poly_set = minpol_list[i_array == 1]
            gpoly = 1
            for poly in poly_set:
                gpoly_array = dec2bitarray(gpoly, 2**m)
                poly_array = dec2bitarray(poly, 2**m)
                gpoly = bitarray2dec(convolve(gpoly_array, poly_array) % 2)
            poly_list = concatenate((poly_list, array([gpoly])))

    return poly_list.astype(int)