def test_001_interleaving_works(self):
        NUM_TESTED_SYMBOLS = 2000
        
        # randomize message
        msg = numpy.random.bytes(40) + chr(numpy.random.randint(0,1<<4))
        # randomize interleaving seqeuence
        interleaving = [random.randrange(648) for i in xrange(NUM_TESTED_SYMBOLS)] + [647]

        # Encode the message using a reference encoder
        refEnc = ldpc.MatrixLDPCEncoder(ldpc.getWifiLDPC648(1,2), 1)
        refSeq = rf.vectorus()
        refEnc.setPacket(msg)
        refEnc.encode(648, refSeq)
        
        # Encode the message using an InterleavedEncoder
        innerEnc = ldpc.MatrixLDPCEncoder(ldpc.getWifiLDPC648(1,2), 1)
        interleavingVec = rf.vectorus(interleaving)
        enc = rf.codes.InterleavedEncoder(innerEnc, interleavingVec)
        enc.setPacket(msg)
        out = []
        tmpOut = rf.vectorus()
        numRemaining = NUM_TESTED_SYMBOLS
        while(numRemaining > 0):
            print "remaining", numRemaining
            numNew = random.randrange(1, min(10, numRemaining)+1)
            enc.encode(numNew, tmpOut)
            out.extend(list(tmpOut))
            numRemaining -= numNew
            
        # compare actual sequence to anticipated sequence
        for i in xrange(NUM_TESTED_SYMBOLS):
            self.assertEqual(out[i], refSeq[interleaving[i]], 
                             "output sequence doesn't match computed output at index %d" % i)
    def test_003_Decoder(self):
        PACKET_LENGTH_BITS = 96 * 3
        NUM_PASSES = 5
        NUM_LAST_CODE_STEP_SYMBOLS = 2
        BEAM_WIDTH = 16

        codeParams = reference.CodeParams(salsaNumRounds=12,
                                          hashWordSize=64,
                                          numBitsPerCodingStep=3,
                                          symbolSizeBits=10,
                                          transmittedPointPrecisionBits=16,
                                          lookaheadDepth=0)

        # get packet
        packet = numpy.random.bytes(PACKET_LENGTH_BITS / 8)

        assert (PACKET_LENGTH_BITS % codeParams.numBitsPerCodingStep == 0)

        # decide on symbol schedule
        numCodingSteps = PACKET_LENGTH_BITS / codeParams.numBitsPerCodingStep
        cppSpineValueIndices = wireless.vectorus()
        for codeStep in xrange(numCodingSteps - 1):
            for i in xrange(NUM_PASSES):
                cppSpineValueIndices.push_back(codeStep)
        # For last code step
        for i in xrange(NUM_PASSES * NUM_LAST_CODE_STEP_SYMBOLS):
            cppSpineValueIndices.push_back(numCodingSteps - 1)

        # Create C++ encoder and mapper
        cppEncoder = spinal.CodeFactory(
                codeParams.numBitsPerCodingStep,
                numCodingSteps,
                codeParams.symbolSizeBits) \
            .salsa().encoder()
        cppMapper = wireless.LinearMapper(
            codeParams.symbolSizeBits,
            codeParams.transmittedPointPrecisionBits)
        cppEncoderSymbols = wireless.vectorus()
        cppMapperSymbols = wireless.vectori()

        # Encode with C++ encoder
        cppEncoder.setPacket(packet)
        cppEncoder.encode(cppSpineValueIndices, cppEncoderSymbols)
        cppMapper.process(cppEncoderSymbols, cppMapperSymbols)

        # Decode with C++ decoder
        cppDecoder = spinal.CodeFactory(
                codeParams.numBitsPerCodingStep,
                numCodingSteps,
                codeParams.symbolSizeBits) \
            .salsa() \
            .linear(codeParams.transmittedPointPrecisionBits) \
            .beamDecoder(BEAM_WIDTH,
                         NUM_PASSES,
                         NUM_PASSES * NUM_LAST_CODE_STEP_SYMBOLS)
        cppDecoder.add(cppSpineValueIndices, cppMapperSymbols)
        decodedPacket = cppDecoder.decode()

        self.assertEquals(decodedPacket.packet, packet)
    def test_002_Encoder(self):
        PACKET_LENGTH_BITS = 192
        NUM_PASSES = 5
        NUM_LAST_CODE_STEP_SYMBOLS = 2
        
        codeParams = reference.CodeParams(salsaNumRounds = 12,
                                         hashWordSize = 64,
                                         numBitsPerCodingStep = 4,
                                         symbolSizeBits = 16,
                                         transmittedPointPrecisionBits = 16,
                                         lookaheadDepth = 0)
        
        # get packet
        packet = numpy.random.bytes(PACKET_LENGTH_BITS / 8)
        
        assert(PACKET_LENGTH_BITS % codeParams.numBitsPerCodingStep == 0)
        
        # decide on symbol schedule
        numCodingSteps = PACKET_LENGTH_BITS / codeParams.numBitsPerCodingStep
        numSymbolsForCodingStep = numpy.ones([numCodingSteps], dtype=numpy.uint32)
        numSymbolsForCodingStep *= NUM_PASSES
        numSymbolsForCodingStep[-1] *= NUM_LAST_CODE_STEP_SYMBOLS
        
        # Create C++ encoder
        cppEncoder = spinal.CodeFactory(
                codeParams.numBitsPerCodingStep,
                numCodingSteps,
                codeParams.symbolSizeBits) \
            .salsa().encoder()
        cppSymbols = wireless.vectorus()
        
        # Convert symbol schedule to spine value indices array
        cppSpineValueIndices = wireless.vectorus()
        for codeStep in xrange(numCodingSteps):
            for i in xrange(numSymbolsForCodingStep[codeStep]):
                cppSpineValueIndices.push_back(codeStep)
            
        # Encode with c++ encoder
        cppEncoder.setPacket(packet)
        cppEncoder.encode(cppSpineValueIndices,
                          cppSymbols)
        
        # Encode with python encoder
        pyEncoder = reference.Encoder(codeParams)
        pySymbols = pyEncoder.encode(packet, numSymbolsForCodingStep)

        # Check the two encoders produced the same symbols
        self.assertTrue(pySymbols == list(cppSymbols))
    def test_002_Encoder(self):
        PACKET_LENGTH_BITS = 192
        NUM_PASSES = 5
        NUM_LAST_CODE_STEP_SYMBOLS = 2

        codeParams = reference.CodeParams(salsaNumRounds=12,
                                          hashWordSize=64,
                                          numBitsPerCodingStep=4,
                                          symbolSizeBits=16,
                                          transmittedPointPrecisionBits=16,
                                          lookaheadDepth=0)

        # get packet
        packet = numpy.random.bytes(PACKET_LENGTH_BITS / 8)

        assert (PACKET_LENGTH_BITS % codeParams.numBitsPerCodingStep == 0)

        # decide on symbol schedule
        numCodingSteps = PACKET_LENGTH_BITS / codeParams.numBitsPerCodingStep
        numSymbolsForCodingStep = numpy.ones([numCodingSteps],
                                             dtype=numpy.uint32)
        numSymbolsForCodingStep *= NUM_PASSES
        numSymbolsForCodingStep[-1] *= NUM_LAST_CODE_STEP_SYMBOLS

        # Create C++ encoder
        cppEncoder = spinal.CodeFactory(
                codeParams.numBitsPerCodingStep,
                numCodingSteps,
                codeParams.symbolSizeBits) \
            .salsa().encoder()
        cppSymbols = wireless.vectorus()

        # Convert symbol schedule to spine value indices array
        cppSpineValueIndices = wireless.vectorus()
        for codeStep in xrange(numCodingSteps):
            for i in xrange(numSymbolsForCodingStep[codeStep]):
                cppSpineValueIndices.push_back(codeStep)

        # Encode with c++ encoder
        cppEncoder.setPacket(packet)
        cppEncoder.encode(cppSpineValueIndices, cppSymbols)

        # Encode with python encoder
        pyEncoder = reference.Encoder(codeParams)
        pySymbols = pyEncoder.encode(packet, numSymbolsForCodingStep)

        # Check the two encoders produced the same symbols
        self.assertTrue(pySymbols == list(cppSymbols))
Exemple #5
0
 def _get_puncturing(punctureSpec, numStreams, forEncoder):
     # Choose puncturing
     import wireless
     if punctureSpec['type'] == '8-way-v2':
         puncturing = wireless.codes.StridedPuncturingSchedule(
                                 numStreams,
                                 punctureSpec['numLastCodeStep'])
     elif punctureSpec['type'] == 'static':
         puncturing = wireless.codes.StaticPuncturingSchedule()
         schedule = wireless.vectorus(punctureSpec['schedule'])
         puncturing.set(schedule)
     else:
         raise RuntimeError, 'unknown puncturing type %s' % punctureSpec['type'] 
 
     
     # Choose the repetition ratio for the puncturing
     if punctureSpec.has_key('encoderToSymbolRate'):
         encoderRate, symbolRate = punctureSpec['encoderToSymbolRate']
         if forEncoder:
             repeatRatio = encoderRate
         else:
             repeatRatio = symbolRate
     else:
         repeatRatio = 1
 
     # Wrap the puncturing schedule with repetition, if neccessary
     if repeatRatio != 1:
         return wireless.codes.RepeatingPuncturingSchedule(puncturing, 
                                                   repeatRatio)
     else:
         return puncturing
    def test_004_one_iteration_result_check(self):
        P = 0.94
        code = rf.codes.ldpc.getWifiLDPC648(1,2)
        encoder = rf.codes.ldpc.MatrixLDPCEncoder(code, 1)

        encodedBits = rf.vectorus()
        packet = '2659df41ec49b827bd494aaed625201cabfb2a75d5fc7d5f2c03c242794cb108271d54881bcf20ca09'.decode('hex')
        expected_packet = {1:'2659df41ec09ba273f4d5baed621201cabbb2a75d5fcfd5f2c03c242796cb108271d54a81bcf30ca09'.decode('hex'),
                           2:'2659df41ec49b827bf4d4aeed621201cabfb2a75d5fc7d5f2c03c242794cb108271d54881bcf30ca09'.decode('hex'),
                           3:'2659df41ec49b827bd494aaed625201cabfb2a75d5fc7d5f2c03c242794cb108271d54881bcf30ca09'.decode('hex'),
                           4:'2659df41ec49b827bd494aaed625201cabfb2a75d5fc7d5f2c03c242794cb108271d54881bcf20ca09'.decode('hex')}
        encoder.setPacket(packet)
        encoder.encode(648,encodedBits)
        
        symVector = rf.vector_symbol()
        noisyVector = rf.vector_symbol()
        for b in list(encodedBits): symVector.push_back(b)
        noisifier = rf.channels.BscChannel(1 - P)
        noisifier.seed(numpy.array([134123], dtype=numpy.uint32))
        noisyBits = noisifier.process(symVector, noisyVector)
        
        # convert encodedBits into LLR values.
        logLLR = math.log(P/(1.0-P))
        encodedLLRs = rf.vectorf()
        for i in xrange(648):
            encodedLLRs.push_back(2.0 * logLLR * noisyVector[i] - logLLR)
        
        for num_iters in sorted(expected_packet.keys()):
            decoder = rf.codes.ldpc.MatrixLDPCDecoder(code, num_iters)
            decoder.add(encodedLLRs)
            
            res = decoder.decode()
            #print res.packet[:41].encode('hex')
            self.assertEquals(res.packet, expected_packet[num_iters])
    def test_003_decode_with_AWGN_noise_over_BPSK(self):
        SNR_dB = 0
        code = rf.codes.ldpc.getWifiLDPC648(1,2)
        encoder = rf.codes.ldpc.MatrixLDPCEncoder(code, 1)

        encodedBits = rf.vectorus()
        packet = numpy.random.bytes(((648/2)+7)/8)
        encoder.setPacket(packet)
        encoder.encode(648,encodedBits)
        
        # Convert into symbols with 20 bit precision
        symbols = rf.vector_symbol()
        mapper = rf.mappers.LinearMapper(1,20)
        mapper.process(encodedBits, symbols)

        # Apply AWGN noise
        noisySymbols = rf.vector_symbol()
        n0 = mapper.getAveragePower() / math.pow(10.0, SNR_dB/10.0)
        noisifier = rf.channels.SymbolAwgnChannel(n0)
        noisifier.seed(numpy.array([numpy.random.randint(0,1<<31)], dtype=numpy.uint32))
        noisifier.process(symbols,noisySymbols)
        
        # Soft-demap
        demapper = rf.demappers.GrayDemapper(rf.mappers.GrayMapper(1, 20), 1)
        receivedLLRs = rf.vectorf()
        demapper.process(noisySymbols, n0, receivedLLRs)
        
        # Decode
        decoder = rf.codes.ldpc.MatrixLDPCDecoder(code, 10)
        decoder.add(receivedLLRs)
        
        res = decoder.decode()
        
        self.assertEquals(res.packet[:40], packet[:40])
        self.assertEquals(ord(res.packet[40]) & 0x0F, ord(packet[40]) & 0x0F)
Exemple #8
0
 def _get_puncturing(punctureSpec, numStreams, forEncoder):
     # Choose puncturing
     import wireless
     if punctureSpec['type'] == '8-way-v2':
         puncturing = wireless.codes.StridedPuncturingSchedule(
                                 numStreams,
                                 punctureSpec['numLastCodeStep'])
     elif punctureSpec['type'] == 'static':
         puncturing = wireless.codes.StaticPuncturingSchedule()
         schedule = wireless.vectorus(punctureSpec['schedule'])
         puncturing.set(schedule)
     else:
         raise RuntimeError, 'unknown puncturing type %s' % punctureSpec['type'] 
 
     
     # Choose the repetition ratio for the puncturing
     if punctureSpec.has_key('encoderToSymbolRate'):
         encoderRate, symbolRate = punctureSpec['encoderToSymbolRate']
         if forEncoder:
             repeatRatio = encoderRate
         else:
             repeatRatio = symbolRate
     else:
         repeatRatio = 1
 
     # Wrap the puncturing schedule with repetition, if neccessary
     if repeatRatio != 1:
         return wireless.codes.RepeatingPuncturingSchedule(puncturing, 
                                                   repeatRatio)
     else:
         return puncturing
    def test_002_decode_with_BSC_noise(self):
        P = 0.96
        NUM_EXPERIMENTS = 20
        code = rf.codes.ldpc.getWifiLDPC648(1,2)
        encoder = rf.codes.ldpc.MatrixLDPCEncoder(code, 1)

        for experimentInd in xrange(NUM_EXPERIMENTS):
            encodedBits = rf.vectorus()
            packet = numpy.random.bytes(((648/2)+7)/8)
            encoder.setPacket(packet)
            encoder.encode(648,encodedBits)
            
            symVector = rf.vector_symbol()
            noisyVector = rf.vector_symbol()
            for b in list(encodedBits): symVector.push_back(b)
            noisifier = rf.channels.BscChannel(1 - P)
            noisifier.seed(numpy.array([numpy.random.randint(0,1<<31)], dtype=numpy.uint32))
            noisyBits = noisifier.process(symVector, noisyVector)
            
            # convert encodedBits into LLR values.
            logLLR = math.log(P/(1.0-P))
            encodedLLRs = rf.vectorf()
            for i in xrange(648):
                encodedLLRs.push_back(2.0 * logLLR * noisyVector[i] - logLLR)
            
            decoder = rf.codes.ldpc.MatrixLDPCDecoder(code, 50)
            decoder.add(encodedLLRs)
            
            res = decoder.decode()
            
            self.assertEquals(res.packet[:40], packet[:40])
            self.assertEquals(ord(res.packet[40]) & 0x0F, ord(packet[40]) & 0x0F)
Exemple #10
0
    def test_001_interleaving_works(self):
        NUM_TESTED_SYMBOLS = 2000

        # randomize message
        msg = numpy.random.bytes(40) + chr(numpy.random.randint(0, 1 << 4))
        # randomize interleaving seqeuence
        interleaving = [
            random.randrange(648) for i in xrange(NUM_TESTED_SYMBOLS)
        ] + [647]

        # Encode the message using a reference encoder
        refEnc = ldpc.MatrixLDPCEncoder(ldpc.getWifiLDPC648(1, 2), 1)
        refSeq = rf.vectorus()
        refEnc.setPacket(msg)
        refEnc.encode(648, refSeq)

        # Encode the message using an InterleavedEncoder
        innerEnc = ldpc.MatrixLDPCEncoder(ldpc.getWifiLDPC648(1, 2), 1)
        interleavingVec = rf.vectorus(interleaving)
        enc = rf.codes.InterleavedEncoder(innerEnc, interleavingVec)
        enc.setPacket(msg)
        out = []
        tmpOut = rf.vectorus()
        numRemaining = NUM_TESTED_SYMBOLS
        while (numRemaining > 0):
            print "remaining", numRemaining
            numNew = random.randrange(1, min(10, numRemaining) + 1)
            enc.encode(numNew, tmpOut)
            out.extend(list(tmpOut))
            numRemaining -= numNew

        # compare actual sequence to anticipated sequence
        for i in xrange(NUM_TESTED_SYMBOLS):
            self.assertEqual(
                out[i], refSeq[interleaving[i]],
                "output sequence doesn't match computed output at index %d" %
                i)
    def test_001_no_repetitions(self):

        NUM_TESTED_LOCATIONS = 500

        for modulus in xrange(1, 30):
            for numLastValueSymbols in [1, 2, 7]:
                punc = spinal.StridedPuncturingSchedule(
                    modulus, numLastValueSymbols)
                numSymbolsFullPass = modulus - 1 + numLastValueSymbols
                spineIndices = wireless.vectorus()
                proto = spinal.StridedProtocol(1, modulus,
                                               NUM_TESTED_LOCATIONS,
                                               numLastValueSymbols, 1)

                lastNumSymbols = 0

                nextNumSymbols = proto.numSymbolsNextDecode(0)
                while (nextNumSymbols != 0):
                    # How many symbols were added?
                    numAddedSymbols = nextNumSymbols - lastNumSymbols
                    self.assertNotEqual(numAddedSymbols, 0,
                                        "Protocol did not advance!")
                    if nextNumSymbols != NUM_TESTED_LOCATIONS:
                        self.assertGreaterEqual(
                            numAddedSymbols, numSymbolsFullPass / 8,
                            "Expected the number of symbols between decodes to fit the puncturing"
                        )
                        self.assertLessEqual(
                            numAddedSymbols, (numSymbolsFullPass + 7) / 8,
                            "Expected the number of symbols between decodes to fit the puncturing"
                        )

                    # Get the spine indices from the puncturing schedule
                    punc.batchNext(numAddedSymbols, spineIndices)

                    # Make sure that the sequence in spineIndices is strictly
                    # increasing
                    for i in xrange(spineIndices.size() - 1):
                        self.assertGreaterEqual(
                            spineIndices[i + 1], spineIndices[i],
                            "Expected the spine location between decodes to be a non-decreasing sequence, but location %d violates this"
                            % (lastNumSymbols + i))

                    # Advance to next protocol demand
                    proto.setResult(0, nextNumSymbols, False)
                    lastNumSymbols = nextNumSymbols
                    nextNumSymbols = proto.numSymbolsNextDecode(0)
Exemple #12
0
    def test_004_one_iteration_result_check(self):
        P = 0.94
        code = rf.codes.ldpc.getWifiLDPC648(1, 2)
        encoder = rf.codes.ldpc.MatrixLDPCEncoder(code, 1)

        encodedBits = rf.vectorus()
        packet = '2659df41ec49b827bd494aaed625201cabfb2a75d5fc7d5f2c03c242794cb108271d54881bcf20ca09'.decode(
            'hex')
        expected_packet = {
            1:
            '2659df41ec09ba273f4d5baed621201cabbb2a75d5fcfd5f2c03c242796cb108271d54a81bcf30ca09'
            .decode('hex'),
            2:
            '2659df41ec49b827bf4d4aeed621201cabfb2a75d5fc7d5f2c03c242794cb108271d54881bcf30ca09'
            .decode('hex'),
            3:
            '2659df41ec49b827bd494aaed625201cabfb2a75d5fc7d5f2c03c242794cb108271d54881bcf30ca09'
            .decode('hex'),
            4:
            '2659df41ec49b827bd494aaed625201cabfb2a75d5fc7d5f2c03c242794cb108271d54881bcf20ca09'
            .decode('hex')
        }
        encoder.setPacket(packet)
        encoder.encode(648, encodedBits)

        symVector = rf.vector_symbol()
        noisyVector = rf.vector_symbol()
        for b in list(encodedBits):
            symVector.push_back(b)
        noisifier = rf.channels.BscChannel(1 - P)
        noisifier.seed(numpy.array([134123], dtype=numpy.uint32))
        noisyBits = noisifier.process(symVector, noisyVector)

        # convert encodedBits into LLR values.
        logLLR = math.log(P / (1.0 - P))
        encodedLLRs = rf.vectorf()
        for i in xrange(648):
            encodedLLRs.push_back(2.0 * logLLR * noisyVector[i] - logLLR)

        for num_iters in sorted(expected_packet.keys()):
            decoder = rf.codes.ldpc.MatrixLDPCDecoder(code, num_iters)
            decoder.add(encodedLLRs)

            res = decoder.decode()
            #print res.packet[:41].encode('hex')
            self.assertEquals(res.packet, expected_packet[num_iters])
 def test_001_no_repetitions(self):
     
     NUM_TESTED_LOCATIONS = 500
     
     for modulus in xrange(1,30):
         for numLastValueSymbols in [1,2,7]:
             punc = spinal.StridedPuncturingSchedule(modulus,numLastValueSymbols)
             numSymbolsFullPass = modulus - 1 + numLastValueSymbols
             spineIndices = wireless.vectorus()
             proto = spinal.StridedProtocol(1,
                                            modulus,
                                            NUM_TESTED_LOCATIONS,
                                            numLastValueSymbols,
                                            1)
             
             lastNumSymbols = 0
             
             nextNumSymbols = proto.numSymbolsNextDecode(0)
             while(nextNumSymbols != 0):
                 # How many symbols were added?
                 numAddedSymbols = nextNumSymbols - lastNumSymbols
                 self.assertNotEqual(numAddedSymbols, 0, "Protocol did not advance!")
                 if nextNumSymbols != NUM_TESTED_LOCATIONS:
                     self.assertGreaterEqual(numAddedSymbols, 
                                             numSymbolsFullPass / 8, 
                                             "Expected the number of symbols between decodes to fit the puncturing")
                     self.assertLessEqual(numAddedSymbols, 
                                          (numSymbolsFullPass + 7) / 8, 
                                          "Expected the number of symbols between decodes to fit the puncturing")
                 
                 # Get the spine indices from the puncturing schedule
                 punc.batchNext(numAddedSymbols, spineIndices)
                 
                 # Make sure that the sequence in spineIndices is strictly 
                 # increasing
                 for i in xrange(spineIndices.size() - 1):
                     self.assertGreaterEqual(spineIndices[i+1], spineIndices[i],
                                             "Expected the spine location between decodes to be a non-decreasing sequence, but location %d violates this" % (lastNumSymbols + i))
                 
                 # Advance to next protocol demand
                 proto.setResult(0, nextNumSymbols, False)
                 lastNumSymbols = nextNumSymbols
                 nextNumSymbols = proto.numSymbolsNextDecode(0)
Exemple #14
0
    def test_001_decode_without_noise(self):
        code = rf.codes.ldpc.getWifiLDPC648(1, 2)
        encoder = rf.codes.ldpc.MatrixLDPCEncoder(code, 1)

        encodedBits = rf.vectorus()
        packet = numpy.random.bytes(((648 / 2) + 7) / 8)
        encoder.setPacket(packet)
        encoder.encode(648, encodedBits)

        # convert encodedBits into LLR values.
        encodedLLRs = rf.vectorf()
        for i in xrange(648):
            encodedLLRs.push_back(8.0 * encodedBits[i] - 4.0)

        decoder = rf.codes.ldpc.MatrixLDPCDecoder(code, 5)
        decoder.add(encodedLLRs)

        res = decoder.decode()

        self.assertEquals(res.packet[:40], packet[:40])
        self.assertEquals(ord(res.packet[40]) & 0x0F, ord(packet[40]) & 0x0F)
    def test_001_decode_without_noise(self):
        code = rf.codes.ldpc.getWifiLDPC648(1,2)
        encoder = rf.codes.ldpc.MatrixLDPCEncoder(code, 1)

        encodedBits = rf.vectorus()
        packet = numpy.random.bytes(((648/2)+7)/8)
        encoder.setPacket(packet)
        encoder.encode(648,encodedBits)
        
        # convert encodedBits into LLR values.
        encodedLLRs = rf.vectorf()
        for i in xrange(648):
            encodedLLRs.push_back(8.0* encodedBits[i] - 4.0)

        decoder = rf.codes.ldpc.MatrixLDPCDecoder(code, 5)
        decoder.add(encodedLLRs)
        
        res = decoder.decode()
        
        self.assertEquals(res.packet[:40], packet[:40])
        self.assertEquals(ord(res.packet[40]) & 0x0F, ord(packet[40]) & 0x0F)
Exemple #16
0
    def test_001_repetitions_are_correct(self):
        """
        Make sure that the stream positions output by the repetition puncturing
        schedule are indeed repetitions of the original puncturing schedule.
        """
        NUM_CODE_STEPS = 20
        TESTED_POSITIONS = 100
        NUM_REPETITION_SET = [1, 2, 3, 6]

        for numRepetitions in NUM_REPETITION_SET:
            for numLastStepSymbolsPerPass in xrange(1, 4):
                punc = spinal.StridedPuncturingSchedule(
                    NUM_CODE_STEPS, numLastStepSymbolsPerPass)
                punc2 = spinal.StridedPuncturingSchedule(
                    NUM_CODE_STEPS, numLastStepSymbolsPerPass)
                repeatedPunc = spinal.RepeatingPuncturingSchedule(
                    punc2, numRepetitions)

                indices = wireless.vectorus()

                # Run twice, once without resetting and another time after
                # resetting the puncturing schedules
                for resetIter in xrange(2):
                    punc.batchNext(TESTED_POSITIONS, indices)
                    unrepeated = list(indices)

                    repeatedPunc.batchNext(TESTED_POSITIONS * numRepetitions,
                                           indices)
                    repeated = list(indices)

                    for i in range(len(repeated)):
                        self.assertEqual(
                            repeated[i], unrepeated[i / numRepetitions],
                            "location %d in repeated schedule should match location %d in original schedule"
                            % (i, i / numRepetitions))

                    # We reset to check that the repeating puncturing schedule
                    # works well after a reset
                    punc.reset()
                    repeatedPunc.reset()
 def test_001_test_vectors_encode(self):
     # input and output bits were prepared using CML, using Cdma2000 scenario
     #    number 5.
     messageStr = file('turbo-message-1530.dat').read()
     codewordStr = file('turbo-interleaved-1530.dat').read()
     
     # get encoder
     enc = rf.codes.strider.StriderTurboCode.createEncoder(1530)
     enc.setPacket(messageStr)
     
     # encode
     encoderOutput = rf.vectorus()
     enc.encode(7668, encoderOutput)
     
     # compare number of bits
     self.assertEqual(7668, encoderOutput.size(), "encoder didn't produce the expected number of bits")
     
     # compare to test vector
     for i in xrange(encoderOutput.size()):
         self.assertEqual((ord(codewordStr[i / 8]) >> (i % 8)) & 0x1, 
                          encoderOutput[i], 
                          'output differs on bit %d' % i)
Exemple #18
0
    def test_001_test_vectors_encode(self):
        # input and output bits were prepared using CML, using Cdma2000 scenario
        #    number 5.
        messageStr = file('turbo-message-1530.dat').read()
        codewordStr = file('turbo-interleaved-1530.dat').read()

        # get encoder
        enc = rf.codes.strider.StriderTurboCode.createEncoder(1530)
        enc.setPacket(messageStr)

        # encode
        encoderOutput = rf.vectorus()
        enc.encode(7668, encoderOutput)

        # compare number of bits
        self.assertEqual(7668, encoderOutput.size(),
                         "encoder didn't produce the expected number of bits")

        # compare to test vector
        for i in xrange(encoderOutput.size()):
            self.assertEqual((ord(codewordStr[i / 8]) >> (i % 8)) & 0x1,
                             encoderOutput[i], 'output differs on bit %d' % i)
Exemple #19
0
    def test_002_decode_with_BSC_noise(self):
        P = 0.96
        NUM_EXPERIMENTS = 20
        code = rf.codes.ldpc.getWifiLDPC648(1, 2)
        encoder = rf.codes.ldpc.MatrixLDPCEncoder(code, 1)

        for experimentInd in xrange(NUM_EXPERIMENTS):
            encodedBits = rf.vectorus()
            packet = numpy.random.bytes(((648 / 2) + 7) / 8)
            encoder.setPacket(packet)
            encoder.encode(648, encodedBits)

            symVector = rf.vector_symbol()
            noisyVector = rf.vector_symbol()
            for b in list(encodedBits):
                symVector.push_back(b)
            noisifier = rf.channels.BscChannel(1 - P)
            noisifier.seed(
                numpy.array([numpy.random.randint(0, 1 << 31)],
                            dtype=numpy.uint32))
            noisyBits = noisifier.process(symVector, noisyVector)

            # convert encodedBits into LLR values.
            logLLR = math.log(P / (1.0 - P))
            encodedLLRs = rf.vectorf()
            for i in xrange(648):
                encodedLLRs.push_back(2.0 * logLLR * noisyVector[i] - logLLR)

            decoder = rf.codes.ldpc.MatrixLDPCDecoder(code, 50)
            decoder.add(encodedLLRs)

            res = decoder.decode()

            self.assertEquals(res.packet[:40], packet[:40])
            self.assertEquals(
                ord(res.packet[40]) & 0x0F,
                ord(packet[40]) & 0x0F)
 def test_001_repetitions_are_correct(self):
     """
     Make sure that the stream positions output by the repetition puncturing
     schedule are indeed repetitions of the original puncturing schedule.
     """
     NUM_CODE_STEPS = 20
     TESTED_POSITIONS = 100
     NUM_REPETITION_SET = [1,2,3,6]
     
     for numRepetitions in NUM_REPETITION_SET:
         for numLastStepSymbolsPerPass in xrange(1,4):
             punc = spinal.StridedPuncturingSchedule(NUM_CODE_STEPS, 
                                                     numLastStepSymbolsPerPass)
             punc2 = spinal.StridedPuncturingSchedule(NUM_CODE_STEPS, 
                                                     numLastStepSymbolsPerPass)
             repeatedPunc = spinal.RepeatingPuncturingSchedule(punc2,
                                                               numRepetitions)
             
             indices = wireless.vectorus()
             
             # Run twice, once without resetting and another time after
             # resetting the puncturing schedules
             for resetIter in xrange(2):
                 punc.batchNext(TESTED_POSITIONS, indices)
                 unrepeated = list(indices)
      
                 repeatedPunc.batchNext(TESTED_POSITIONS * numRepetitions, indices)
                 repeated = list(indices)
                 
                 for i in range(len(repeated)):
                     self.assertEqual(repeated[i], unrepeated[i/numRepetitions], 
                                      "location %d in repeated schedule should match location %d in original schedule" %(i, i/numRepetitions))
                 
                 # We reset to check that the repeating puncturing schedule
                 # works well after a reset
                 punc.reset()
                 repeatedPunc.reset()
Exemple #21
0
    def test_003_decode_with_AWGN_noise_over_BPSK(self):
        SNR_dB = 0
        code = rf.codes.ldpc.getWifiLDPC648(1, 2)
        encoder = rf.codes.ldpc.MatrixLDPCEncoder(code, 1)

        encodedBits = rf.vectorus()
        packet = numpy.random.bytes(((648 / 2) + 7) / 8)
        encoder.setPacket(packet)
        encoder.encode(648, encodedBits)

        # Convert into symbols with 20 bit precision
        symbols = rf.vector_symbol()
        mapper = rf.mappers.LinearMapper(1, 20)
        mapper.process(encodedBits, symbols)

        # Apply AWGN noise
        noisySymbols = rf.vector_symbol()
        n0 = mapper.getAveragePower() / math.pow(10.0, SNR_dB / 10.0)
        noisifier = rf.channels.SymbolAwgnChannel(n0)
        noisifier.seed(
            numpy.array([numpy.random.randint(0, 1 << 31)],
                        dtype=numpy.uint32))
        noisifier.process(symbols, noisySymbols)

        # Soft-demap
        demapper = rf.demappers.GrayDemapper(rf.mappers.GrayMapper(1, 20), 1)
        receivedLLRs = rf.vectorf()
        demapper.process(noisySymbols, n0, receivedLLRs)

        # Decode
        decoder = rf.codes.ldpc.MatrixLDPCDecoder(code, 10)
        decoder.add(receivedLLRs)

        res = decoder.decode()

        self.assertEquals(res.packet[:40], packet[:40])
        self.assertEquals(ord(res.packet[40]) & 0x0F, ord(packet[40]) & 0x0F)
    def test_003_Decoder(self):
        PACKET_LENGTH_BITS = 96*3
        NUM_PASSES = 5
        NUM_LAST_CODE_STEP_SYMBOLS = 2
        BEAM_WIDTH = 16

        codeParams = reference.CodeParams(salsaNumRounds = 12,
                                         hashWordSize = 64,
                                         numBitsPerCodingStep = 3,
                                         symbolSizeBits = 10,
                                         transmittedPointPrecisionBits = 16,
                                         lookaheadDepth = 0)
        
        # get packet
        packet = numpy.random.bytes(PACKET_LENGTH_BITS / 8)
        
        assert(PACKET_LENGTH_BITS % codeParams.numBitsPerCodingStep == 0)
        
        # decide on symbol schedule
        numCodingSteps = PACKET_LENGTH_BITS / codeParams.numBitsPerCodingStep
        cppSpineValueIndices = wireless.vectorus()
        for codeStep in xrange(numCodingSteps - 1):
            for i in xrange(NUM_PASSES):
                cppSpineValueIndices.push_back(codeStep)
        # For last code step
        for i in xrange(NUM_PASSES * NUM_LAST_CODE_STEP_SYMBOLS):
            cppSpineValueIndices.push_back(numCodingSteps - 1)
        
        
        # Create C++ encoder and mapper
        cppEncoder = spinal.CodeFactory(
                codeParams.numBitsPerCodingStep,
                numCodingSteps,
                codeParams.symbolSizeBits) \
            .salsa().encoder()
        cppMapper = wireless.LinearMapper(codeParams.symbolSizeBits,
                                           codeParams.transmittedPointPrecisionBits)
        cppEncoderSymbols = wireless.vectorus()
        cppMapperSymbols = wireless.vectori()
        
        # Encode with C++ encoder
        cppEncoder.setPacket(packet)
        cppEncoder.encode(cppSpineValueIndices,
                          cppEncoderSymbols)
        cppMapper.process(cppEncoderSymbols, cppMapperSymbols)
        
        # Decode with C++ decoder
        cppDecoder = spinal.CodeFactory(
                codeParams.numBitsPerCodingStep,
                numCodingSteps,
                codeParams.symbolSizeBits) \
            .salsa() \
            .linear(codeParams.transmittedPointPrecisionBits) \
            .beamDecoder(BEAM_WIDTH,
                         NUM_PASSES,
                         NUM_PASSES * NUM_LAST_CODE_STEP_SYMBOLS)
        cppDecoder.add(cppSpineValueIndices,
                       cppMapperSymbols)
        decodedPacket = cppDecoder.decode()
        
        self.assertEquals(decodedPacket.packet, packet)
Exemple #23
0
    def test_001_Punctured_Encoder(self):
        PACKET_LENGTH_BITS = 192
        NUM_PASSES = 5
        NUM_LAST_CODE_STEP_SYMBOLS = 2
        
        codeParams = spinal.reference.CodeParams(salsaNumRounds = 12,
                                         hashWordSize = 64,
                                         numBitsPerCodingStep = 4,
                                         symbolSizeBits = 10,
                                         transmittedPointPrecisionBits = 10,
                                         lookaheadDepth = 0)
        
        # get packet
        packet = numpy.random.bytes(PACKET_LENGTH_BITS / 8)
        
        assert(PACKET_LENGTH_BITS % codeParams.numBitsPerCodingStep == 0)
        
        numCodingSteps = PACKET_LENGTH_BITS / codeParams.numBitsPerCodingStep
        totalNumSymbols = (numCodingSteps - 1 + NUM_LAST_CODE_STEP_SYMBOLS) * NUM_PASSES
     
        # decide on symbol schedule
        cppSpineValueIndices = wireless.vectorus()
        for codeStep in xrange(numCodingSteps - 1):
            for i in xrange(NUM_PASSES):
                cppSpineValueIndices.push_back(codeStep)
        # For last code step
        for i in xrange(NUM_PASSES * NUM_LAST_CODE_STEP_SYMBOLS):
            cppSpineValueIndices.push_back(numCodingSteps - 1)

        
        # Make c++ encoder without puncturing
        cppEncoder = spinal.CodeFactory(
                codeParams.numBitsPerCodingStep,
                numCodingSteps,
                codeParams.symbolSizeBits) \
            .salsa().encoder()
        unpuncturedSymbols = wireless.vectorus()

        
        # Encode unpunctured with C++ encoder
        cppEncoder.setPacket(packet)
        cppEncoder.encode(cppSpineValueIndices,
                          unpuncturedSymbols)
        
        # Make puncturing schedule
        punc = spinal.StridedPuncturingSchedule(numCodingSteps,
                                                NUM_LAST_CODE_STEP_SYMBOLS)
        
        # Make encoder with puncturing
        puncturedEncoder = spinal.PuncturedEncoder(cppEncoder,
                                                   punc)
        
        # Encode with puncturing
        puncturedSymbols = wireless.vectorus()
        puncturedEncoder.setPacket(packet)
        puncturedEncoder.encode(totalNumSymbols, puncturedSymbols)
        
        # Make a dictionary from spine value to all locations that are produced
        # from that spine value
        d = {}
        punc.reset()
        for i in xrange(totalNumSymbols):
            d.setdefault(punc.next(), []).append(i)
        
        # Check the two encoders produced the same symbols (taking into account
        #    the puncturing schedule)
        for codeStep in xrange(numCodingSteps - 1):
            for i in xrange(NUM_PASSES):
                self.assertEqual(unpuncturedSymbols[codeStep * NUM_PASSES + i], 
                                 puncturedSymbols[ d[codeStep][i] ],
                                 "location %d should contain the %dth sample from spine value %d, but does not match" \
                                    % (d[codeStep][i], i, codeStep))
        # last codestep
        codeStep = (numCodingSteps - 1)
        for i in xrange(NUM_PASSES * NUM_LAST_CODE_STEP_SYMBOLS):
            self.assertEqual(unpuncturedSymbols[codeStep * NUM_PASSES + i], 
                             puncturedSymbols[ d[codeStep][i] ],
                             "location %d should contain the %dth sample from spine value %d, but does not match" \
                                % (d[codeStep][i], i, codeStep))