Example #1
0
    def __init__(self, k, map_func, message):
        """
        Constructor
        @param k the number of bits in each block fed into the hash function
        @param map_func a function that maps a 16-bit pseudo-random number
             into a constellation point
        @param message a string with the message to be transmitted
        """
        self.k = k

        self.map_func = map_func
        
        # divide the mesage into blocks of k bits
        self.message_blocks = self._divide_message_into_blocks(message, self.k)
        
        # calculate the spine
        self.spine = []
        spine_value = 0
        for block in self.message_blocks:
            # Calculate the next spine value
            spine_value = hash_func(spine_value, block)
            
            # Add the new value to the spine
            self.spine.append(spine_value)
        
        # Make RNGs for each spine value
        self.rngs = [RNG(spine_value) for spine_value in self.spine]
Example #2
0
    def __init__(self, k, map_func, message):
        """
        Constructor
        @param k the number of bits in each block fed into the hash function
        @param map_func a function that maps a 16-bit pseudo-random number
             into a constellation point
        @param message a string with the message to be transmitted
        """
        self.k = k

        self.map_func = map_func
        
        # divide the mesage into blocks of k bits
        self.message_blocks = self._divide_message_into_blocks(message, self.k)
        
        # calculate the spine
        self.spine = []
        spine_value = 0
        for block in self.message_blocks:
            # Calculate the next spine value
            spine_value = hash_func(spine_value, block)
            
            # Add the new value to the spine
            self.spine.append(spine_value)
        
        # Make RNGs for each spine value
        self.rngs = [RNG(spine_value) for spine_value in self.spine]
Example #3
0
 def expand_wavefront_fading_P(self ,wavefront):
     """
     Given the wavefront of the current spine location, and symbols produced
     from the next spine location, advance the wavefront to contain spine 
     values from the next spine location.
     """
     #pdb.set_trace();
     k = self.k
     cL = len(channel)
     new_wavefront = []
     passNum = self.passNum
     delay = self.delay
     # For each node in the current wavefront
     symbols, channel, PQ,head = self.para
     path_metric, spine_value, path, channelCache_P, channelCache_Q  = wavefront
     fading = []        #pdb.set_trace();
     # For each possible message block (2^k options)
     for edge in xrange( 1 << k ):
         # Calculate the new spine value
         if PQ == 0 :
             new_channelCache = channelCache_P[:]
         else: 
             new_channelCache = channelCache_Q[:]
         # Get an RNG for the new spine value
         new_spine_value = hash_func(spine_value, edge)
         self.rng = RNG(new_spine_value)
         
         # Go over all received symbols, and compute the edge metric
         edge_metric = 0
         for d in xrange(delay):
             node_symbolTemp = self.map_func(self.rng.next())
             new_channelCache[-delay+d] = node_symbolTemp;
         acc = 0
         for received_symbol in symbols:
             acc += 1
             node_symbol = 0
             if acc <= len(symbols)-delay:
                 node_symbolTemp = self.map_func(self.rng.next())
                 new_channelCache.append(node_symbolTemp)
                 new_channelCache = new_channelCache[1:]
             else:
                     #print new_channelCache_temp
                 new_channelCache.append(0)
                 new_channelCache = new_channelCache[1:]
             #print 'node' ,new_channelCache
             for tt in xrange(cL):
                 node_symbol += new_channelCache[-tt-1]*channel[tt]
             #print 'with fading',node_symbol
             distance = received_symbol - node_symbol
             edge_metric += distance * distance
         # The new path metric is the sum of all edges from the root
         #print 'metric', edge_metric
         new_path_metric = path_metric + edge_metric
         # Add new node to wavefront
         if PQ == 0 :
             new_wavefront = (new_path_metric, new_spine_value, path + [edge], new_channelCache,channelCache_Q)
         else :
             new_wavefront = (new_path_metric, new_spine_value, path + [edge], channelCache_P, new_channelCache)
         return new_wavefront
Example #4
0
 def _produce_more_values(self):
     '''
     helper function, produces the next values to be output from the RNG, and
         adds them to self.next_values. This function should only be called 
         from within the RNG class
     '''
     from Hash import hash_func
     
     # Hash the seed with the current index
     hash_output = hash_func(self.seed, self.i)
     
     # Get two 16-bit words from the state
     self.next_values = self.next_values + [(hash_output >> 16) & 0xFFFF, hash_output & 0xFFFF]
     
     # increment current index
     self.i = (self.i + 3243335647) & ((1 << 32) - 1)
Example #5
0
    def _expand_wavefront(self, symbols):
        """
        Given the wavefront of the current spine location, and symbols produced
        from the next spine location, advance the wavefront to contain spine 
        values from the next spine location.
        """
        # pdb.set_trace();
        k = self.k

        new_wavefront = []
        # For each node in the current wavefront
        for (path_metric, symbolsSqu, spine_value, path, waste, waste1) in self.wavefront:
            # For each possible message block (2^k options)
            for edge in xrange(1 << k):
                # Calculate the new spine value
                new_spine_value = hash_func(spine_value, edge)

                # Get an RNG for the new spine value
                rng = RNG(new_spine_value)

                # Go over all received symbols, and compute the edge metric
                edge_metric = 0
                for received_symbol in symbols:
                    # What the transmitter would have produced if it had this
                    # spine value
                    node_symbol = self.map_func(rng.next())

                    # Add the distance squared to the edge metric
                    distance = received_symbol - node_symbol
                    edge_metric += distance * distance

                # The new path metric is the sum of all edges from the root
                new_path_metric = path_metric + edge_metric

                # Add new node to wavefront
                new_wavefront.append(
                    (new_path_metric, new_spine_value, path + [edge], [0]))

        # Update the wavefront to the newly computed wavefront
        self.wavefront = new_wavefront
Example #6
0
    def _expand_wavefront(self, symbols):
        """
        Given the wavefront of the current spine location, and symbols produced
        from the next spine location, advance the wavefront to contain spine 
        values from the next spine location.
        """

        k = self.k

        new_wavefront = []
        # For each node in the current wavefront
        for (path_metric, spine_value, path) in self.wavefront:
            # For each possible message block (2^k options)
            for edge in xrange(1 << k):
                # Calculate the new spine value
                new_spine_value = hash_func(spine_value, edge)

                # Get an RNG for the new spine value
                rng = RNG(new_spine_value)

                # Go over all received symbols, and compute the edge metric
                edge_metric = 0
                for received_symbol in symbols:
                    # What the transmitter would have produced if it had this spine value
                    node_symbol = self.map_func(rng.next())

                    # Add the distance squared to the edge metric
                    distance = received_symbol - node_symbol
                    edge_metric += distance * distance

                # The new path metric is the sum of all edges from the root
                new_path_metric = path_metric + edge_metric

                # Add new node to wavefront
                new_wavefront.append(
                    (new_path_metric, new_spine_value, path + [edge]))

        # Update the wavefront to the newly computed wavefront
        self.wavefront = new_wavefront
Example #7
0
    def _expand_wavefront_fading(self, symbols, mu):
        """
        Given the wavefront of the current spine location, and symbols produced
        from the next spine location, advance the wavefront to contain spine 
        values from the next spine location.
        """
        k = self.k
        cL = len(self.channel)
        new_wavefront = []
        passNum = self.passNum
        delay = self.delay
        # For each node in the current wavefront
        if len(symbols):
            self.receviedSymbols= self.receviedSymbols+ symbols
            symbolsSqu = self.receviedSymbols[:]
        else:
            symbolsSqu = []
        for (path_metric, waste, spine_value, path, channelCache, waste1) in self.wavefront:

            # pdb.set_trace();
            # For each possible message block (2^k options)
            for edge in xrange(1 << k):
                # Calculate the new spine value
                new_channelCache = channelCache[:]
                channel = self.channel[:]
                # Get an RNG for the new spine value
                new_spine_value = hash_func(spine_value, edge)
                self.rng = RNG(new_spine_value)

                # Go over all received symbols, and compute the edge metric
                edge_metric = 0
                node_symbolTemp = 0 + 0j
                if len(symbols) != 0:
                    L = min(delay, len(symbols))
                    for d in xrange(L):
                        node_symbolTemp = self.map_func(self.rng.next())
                        new_channelCache[-delay + d] = node_symbolTemp
                    acc = 0
                    for received_symbol in symbols:
                        acc += 1
                        node_symbol = 0
                        if acc <= len(symbols) - delay:
                            node_symbolTemp = self.map_func(self.rng.next())
                            new_channelCache.append(node_symbolTemp)
                        else:
                            new_channelCache.append(0)
                        # print 'node' ,new_channelCache
                        for tt in xrange(cL):
                            if channel[tt] != 0:
                                node_symbol += new_channelCache[-tt -
                                                                1] * channel[tt]
                        # print 'with fading',node_symbol
                        # pdb.set_trace()
                        distance = received_symbol - node_symbol
                        # if self.adaptable and acc <= len(symbols) - delay:
                        if self.adaptable:
                            for j in xrange(len(channel)):
                                channel[j] = channel[j] + (mu * np.conjugate(new_channelCache[-j - 1]) * distance)
                        # print channel
                        edge_metric += abs(distance)**2
                        # pdb.set_trace()
                # The new path metric is the sum of all edges from the root
                new_path_metric = path_metric + edge_metric
                # print 'metric', new_path_metric
                # Add new node to wavefront
                new_wavefront.append(
                    (new_path_metric, waste, new_spine_value, path + [edge], new_channelCache, channel))

        # Update the wavefront to the newly computed wavefront
        self.wavefront = new_wavefront
        path_metric, waste, spine_value, path, channelCache, nextChannel = min(self.wavefront)
        self.channel = nextChannel