Exemple #1
0
def decode(block_length, bits):
    '''Create the codec instance and set parameters'''
    codec = turbo_codec()
    '''Prepare codec parameters'''
    gen_sequence = '11,13'
    gen = ivec(gen_sequence)
    constraint_length = 4

    codec.set_parameters(gen, gen, constraint_length, ivec())
    codec.set_interleaver(_interleaver_sequence(block_length))
    '''Encode with the given code rate and bitarray comprising uncoded bits'''
    '''Generate and return decoded bits'''
    decoded_bits = bvec()
    codec.decode(bits, decoded_bits, bvec())
    return decoded_bits
Exemple #2
0
def simluate_rayleigh_fading_channel(nrof_samples,
                                     avg_snr_dB,
                                     awgn_data,
                                     packet_sizes,
                                     norm_doppler=0.01,
                                     seed=9999,
                                     cqi_error_std=0.0):

    # Create a Rayleigh fading channel. The channel power is normalized to 1 by default
    channel = itpp.comm.TDL_Channel(itpp.vec('0.0'), itpp.ivec('0'))
    channel.set_norm_doppler(norm_doppler)

    channel_coeff_itpp = itpp.cmat()
    channel.generate(nrof_samples, channel_coeff_itpp)

    channel_coeff = np.array(channel_coeff_itpp.get_col(0))

    avg_snr = 10**(0.1 * avg_snr_dB)
    instantaneous_channel_snrs = (np.absolute(channel_coeff)**2) * avg_snr

    _, nrof_rates = awgn_data['snr_vs_per'].shape
    instantaneous_blers = []
    channel_quality_indices = []
    for i in range(nrof_samples):
        cqi_sinr_error = (itpp.random.randn() - 0.5) * cqi_error_std

        snr_dB = 10 * np.log10(instantaneous_channel_snrs[i])
        instantaneous_blers.append(determine_bler_at_sinr(snr_dB, awgn_data))
        channel_quality_indices.append(
            determine_cqi_from_sinr(snr_dB, packet_sizes, awgn_data,
                                    cqi_sinr_error))

    return (np.array(instantaneous_blers), np.array(channel_quality_indices))
Exemple #3
0
def deinterleave_and_channel_decode_symbols(symbols, interleaver_sequence):

    sequence_interleaver_d = itpp.comm.sequence_interleaver_double(
        symbols.length())
    sequence_interleaver_d.set_interleaver_sequence(interleaver_sequence)

    deinterleaved_symbols = sequence_interleaver_d.deinterleave(symbols,
                                                                keepzeroes=0)

    conv_code = itpp.comm.Convolutional_Code()

    generators = itpp.ivec(3)
    generators[0] = 91  # Octal 0133
    generators[1] = 101  # Octal 0145
    generators[2] = 125  # Octal 0175
    constraint_length = 7
    conv_code.set_generator_polynomials(generators, constraint_length)

    decoded_bits = conv_code.decode(deinterleaved_symbols)

    #     turbo_codec = itpp.comm.turbo_codec()
    #
    #     gen = itpp.ivec('11, 13')
    #     constraint_length = 4
    #
    #     turbo_codec.set_parameters(gen, gen, constraint_length, itpp.ivec())
    #     turbo_interleaver_sequence = generate_turbo_internal_interleaver_sequence(symbols.length())
    #     turbo_codec.set_interleaver(turbo_interleaver_sequence)
    #
    #     decoded_bits = itpp.bvec()
    #     turbo_codec.decode(symbols, decoded_bits, itpp.bvec())

    return decoded_bits
Exemple #4
0
def channel_encode_and_interleave_bits(bits):
    conv_code = itpp.comm.Convolutional_Code()

    generators = itpp.ivec(3)
    generators[0] = 91  # Octal 0133
    generators[1] = 101  # Octal 0145
    generators[2] = 125  # Octal 0175
    constraint_length = 7
    conv_code.set_generator_polynomials(generators, constraint_length)

    coded_bits = conv_code.encode(bits)

    #     turbo_codec = itpp.comm.turbo_codec()
    #
    #     gen = itpp.ivec('11, 13')
    #     constraint_length = 4
    #
    #     turbo_codec.set_parameters(gen, gen, constraint_length, itpp.ivec())
    #     turbo_interleaver_sequence = generate_turbo_internal_interleaver_sequence(bits.length())
    #     turbo_codec.set_interleaver(turbo_interleaver_sequence)
    #
    #     coded_bits = itpp.bvec()
    #     turbo_codec.encode(bits, coded_bits)

    sequence_interleaver_b = itpp.comm.sequence_interleaver_bin(
        coded_bits.length())
    sequence_interleaver_b.randomize_interleaver_sequence()

    interleaved_bits = sequence_interleaver_b.interleave(coded_bits)

    return (interleaved_bits,
            sequence_interleaver_b.get_interleaver_sequence())
def block_error_ratio_hamming_awgn(snr_db, block_size):

    mapping_k_m = {
        4: 3
    }  # Mapping from k (block size) to m. m = 3 implies (7,4) code
    m = mapping_k_m[block_size]
    '''Hamming encoder and decoder instance'''
    hamm = itpp.comm.hamming_code(m)
    n = pow(2, m) - 1  # channel use
    rate = float(block_size) / float(n)
    '''Generate random bits'''
    nrof_bits = 10000 * block_size
    source_bits = itpp.randb(nrof_bits)
    '''Encode the bits'''
    encoded_bits = hamm.encode(source_bits)
    '''Modulate the bits'''
    modulator_ = itpp.comm.modulator_2d()
    constellation = itpp.cvec('-1+0i, 1+0i')
    symbols = itpp.ivec('0, 1')
    modulator_.set(constellation, symbols)
    tx_signal = modulator_.modulate_bits(encoded_bits)
    '''Add the effect of channel to the signal'''
    noise_variance = 1.0 / (rate * pow(10, 0.1 * snr_db))
    noise = itpp.randn_c(tx_signal.length())
    noise *= itpp.math.sqrt(noise_variance)
    rx_signal = tx_signal + noise
    '''Demodulate the signal'''
    demodulated_bits = modulator_.demodulate_bits(rx_signal)
    '''Decode the received bits'''
    decoded_bits = hamm.decode(demodulated_bits)
    '''Calculate the block error ratio'''
    blerc = itpp.comm.BLERC(block_size)
    blerc.count(source_bits, decoded_bits)
    return blerc.get_errorrate()
Exemple #6
0
def _interleaver_sequence(block_size):

    K = block_size
    '''Get the index of parameters to be used from interleaver table
    '''
    index = 0
    if (40 <= K and K <= 512 and (K % 8 == 0)):
        index = (K - 40) / 8
    elif (528 <= K and K <= 1024 and (K % 16 == 0)):
        index = 60 + ((K - 528) / 16)
    elif (1056 <= K and K <= 2048 and (K % 32 == 0)):
        index = 92 + ((K - 1056) / 32)
    elif (2112 <= K and K <= 6144 and (K % 64 == 0)):
        index = 124 + ((K - 2112) / 64)
    else:
        error_str = 'Invalid interleaver size: ' + str(K)
        logging.error(error_str)
        #raise ValueError, error_str
    '''Get the parameters to generate the interleaver sequence
    '''
    f1 = _TURBO_INTERNAL_INTERLEAVER_TABLE.get(int(index), 1)
    f2 = _TURBO_INTERNAL_INTERLEAVER_TABLE.get(int(index), 2)
    '''Mapping from output index 'i' to input index 'PI_i'
    '''
    PI_mapping = lambda i: (f1 * i + f2 * i * i) % K
    PI = ivec(K)  # Placeholder for input indices
    for i in range(K):
        PI[i] = PI_mapping(i)

    return PI
def bit_error_ratio_hamming_awgn(snr_db):
    '''Hamming encoder and decoder instance'''
    k = 3 # (7,4) Hamming code
    hamm = itpp.comm.hamming_code(k)
    
    '''Generate random bits'''
    nrof_bits = k * 100000
    source_bits = itpp.random.randb(nrof_bits)
    
    '''Encode the bits'''
    encoded_bits = hamm.encode(source_bits)
    
    '''Modulate the bits'''
    modulator_ = itpp.comm.modulator_1d()
    constellation = itpp.vec('-1, 1')
    symbols = itpp.ivec('0, 1')
    modulator_.set(constellation, symbols)
    tx_signal = modulator_.modulate_bits(encoded_bits)
    
    '''Add the effect of channel to the signal'''
    noise_variance = 1.0 / (pow(10, 0.1 * snr_db))
    noise = itpp.random.randn(tx_signal.length())
    noise *= itpp.math.sqrt(noise_variance)
    rx_signal = tx_signal + noise
    
    '''Demodulate the signal'''
    demodulated_bits = modulator_.demodulate_bits(rx_signal)
    
    '''Decode the received bits'''
    decoded_bits = hamm.decode(demodulated_bits) 
    
    '''Calculate the bit error ratio'''
    return itpp.comm.BERC.count_errors(source_bits, decoded_bits, 0, 0, 0) / nrof_bits
Exemple #8
0
def generate_turbo_internal_interleaver_sequence(block_length):
    f1 = 3
    f2 = 10

    internal_interleaver_sequence = itpp.ivec(block_length)
    for i in range(block_length):
        internal_interleaver_sequence[i] = (f1 * i + f2 * i * i) % block_length

    return internal_interleaver_sequence
Exemple #9
0
def block_error_ratio_turbo_awgn(snr_db, interleaver_length):
    '''Create turbo_codec_instance'''
    codec = itpp.comm.turbo_codec()
    '''Set codec parameters'''
    gen = itpp.ivec(2)
    gen[0] = 11
    gen[1] = 13
    constraint_length = 4
    interleaver = itpp.ivec(
        '0, 19, 14, 33, 28, 47, 42, 13, 8, 27, 22, 41, 36, 7, 2, 21, 16, 35, 30, 1, 44, 15, 10, 29, 24, 43, 38, 9, 4, 23, 18, 37, 32, 3, 46, 17, 12, 31, 26, 45, 40, 11, 6, 25, 20, 39, 34, 5'
    )
    codec.set_parameters(gen, gen, constraint_length, itpp.ivec())
    codec.set_interleaver(interleaver)
    '''Generate random bits and encode them'''
    nrof_uncoded_bits = interleaver_length * 1000
    uncoded_bits = itpp.random.randb(nrof_uncoded_bits)
    encoded_bits = itpp.bvec()
    codec.encode(uncoded_bits, encoded_bits)
    '''Modulate bits using BPSK'''
    symbols = itpp.vec('1, -1')
    bits2symbol = itpp.ivec('0, 1')
    modulator_ = itpp.comm.modulator_1d(symbols, bits2symbol)
    tx_signal = modulator_.modulate_bits(encoded_bits)
    '''Add AWGN noise'''
    noise_variance = 1.0 / (pow(10, 0.1 * snr_db))
    noise = itpp.random.randn(tx_signal.length())
    noise *= itpp.math.sqrt(noise_variance)
    rx_signal = tx_signal + noise
    '''Demodulate received signal (soft bits, LOGMAP)'''
    soft_bits = itpp.vec()
    modulator_.demodulate_soft_bits(rx_signal, noise_variance, soft_bits,
                                    itpp.comm.Soft_Method.LOGMAP)
    '''Turbo decode the soft bits'''
    decoded_bits = itpp.bvec()
    codec.decode(soft_bits, decoded_bits, itpp.bvec())
    '''Count errors'''
    blerc = itpp.comm.BLERC(interleaver_length)
    blerc.count(decoded_bits, uncoded_bits)
    return blerc.get_errorrate()
Exemple #10
0
def block_error_ratio_uncoded_awgn(snr_db, block_size):
    '''Generate random bits'''
    nrof_bits = 3 * 10000 * block_size
    source_bits = itpp.random.randb(nrof_bits)
    '''Modulate the bits'''
    modulator_ = itpp.comm.modulator_1d()
    constellation = itpp.vec('-1, 1')
    symbols = itpp.ivec('0, 1')
    modulator_.set(constellation, symbols)
    tx_signal = modulator_.modulate_bits(source_bits)
    '''Add the effect of channel to the signal'''
    noise_variance = 1.0 / (pow(10, 0.1 * snr_db))
    noise = itpp.random.randn(tx_signal.length())
    noise *= itpp.math.sqrt(noise_variance)
    rx_signal = tx_signal + noise
    '''Demodulate the signal'''
    demodulated_bits = modulator_.demodulate_bits(rx_signal)
    '''Calculate the block error ratio'''
    blerc = itpp.comm.BLERC(block_size)
    blerc.count(source_bits, demodulated_bits)
    return blerc.get_errorrate()
def generateRaptorLDPC(numInfoBits, rate, outFilename):
    """
    Generates a left 4-degree regular, random right degree LDPC code with
    'numInfoBits' information bits.
    
    @param numInfoBits: the number of message bits the LDPC code will handle
    @param rate: the rate of the LDPC code
    @param outFilename: filename where the bits will be written
    """
    
    leftDegree = 4
    
    numVariables = int(numInfoBits / rate)
    print "numVariables:", numVariables
    
    dist = binom(numInfoBits, 1.0 * leftDegree / (numVariables - numInfoBits))
    maxRightDegree = int(dist.isf(1e-8))
    itRight = itpp.vec(maxRightDegree)
    for i in xrange(maxRightDegree):
        itRight[i] = dist.pmf(i+1)
    itRight[maxRightDegree-1] = itRight[maxRightDegree-1] + 1e-8

    itLeft = itpp.vec(leftDegree)
    for i in xrange(leftDegree-1):
        itLeft[i] = 0
    itLeft[leftDegree - 1] = 1.0
    print itLeft
    
    H = itpp.LDPC_Parity_Irregular()
    H.generate(numVariables, itLeft, itRight, "rand", itpp.ivec("150 8"))
    H.display_stats()
    print "got code with ", (H.get_nvar() - H.get_ncheck()), " nodes"
    
    
    G = itpp.LDPC_Generator_Systematic(H);
    C = itpp.LDPC_Code(H, G)
    C.save_code(outFilename);
def generateRaptorLDPC(numInfoBits, rate, outFilename):
    """
    Generates a left 4-degree regular, random right degree LDPC code with
    'numInfoBits' information bits.
    
    @param numInfoBits: the number of message bits the LDPC code will handle
    @param rate: the rate of the LDPC code
    @param outFilename: filename where the bits will be written
    """

    leftDegree = 4

    numVariables = int(numInfoBits / rate)
    print "numVariables:", numVariables

    dist = binom(numInfoBits, 1.0 * leftDegree / (numVariables - numInfoBits))
    maxRightDegree = int(dist.isf(1e-8))
    itRight = itpp.vec(maxRightDegree)
    for i in xrange(maxRightDegree):
        itRight[i] = dist.pmf(i + 1)
    itRight[maxRightDegree - 1] = itRight[maxRightDegree - 1] + 1e-8

    itLeft = itpp.vec(leftDegree)
    for i in xrange(leftDegree - 1):
        itLeft[i] = 0
    itLeft[leftDegree - 1] = 1.0
    print itLeft

    H = itpp.LDPC_Parity_Irregular()
    H.generate(numVariables, itLeft, itRight, "rand", itpp.ivec("150 8"))
    H.display_stats()
    print "got code with ", (H.get_nvar() - H.get_ncheck()), " nodes"

    G = itpp.LDPC_Generator_Systematic(H)
    C = itpp.LDPC_Code(H, G)
    C.save_code(outFilename)