Minimalist RDSE encoder to ensure understanding. A little help with the "random" part please?

So I’m trying to build a pretty bare minimum implementation of the RDSE to play with. This is how I learn best. I’ve been working from the videos and papers online to get the encoding of a single value into a bitarray. That part works great, code below:

class Encoding_Layer():

	def __init__(self, min_val, max_val, buckets, active_bits):
		self.min_val = min_val
		self.max_val = max_val
		self.buckets = buckets
		self.active_bits = active_bits
		self.total_bits = buckets + active_bits - 1
		self.range = max_val - min_val
		self.bitarray = bitarray(self.total_bits)

	def encode_value(self, value):
		self.bitarray.setall(False)
		i = math.floor(self.buckets * (value - self.min_val) / self.range)
		count = 0
		for x in range(self.active_bits):
			self.bitarray[i + count] = True
			count += 1

Now I’ve got my output as a nice pretty bitarray, but I’m having trouble understanding how to implement the hash function to map the indices of the array to a new output array. Hoping someone can help me understand how this one is supposed to work. If you can provide a (simple) Python example that would
work with my current code, that would be extremely helpful.

2 Likes

Just to update this in case anyone is interested in following along, I’ve completed my implementation of the RDSE in python. I was able to dig into the literature a bit more and found that the HTM.core version seems to just be picking a value at random, and then checking for a few rules to make sure that value would work, then adding it to the list. I decided that was unnecessary for my purposes, and decided to just go with a random.shuffle with a static seed. This should work for testing and learning, since the error rate is practically negligible. My code for the class is below. It’s not pretty, but it helped me to understand the process much better.

class Encoding_Layer():

	def __init__(self, min_val, max_val, buckets, active_bits):
		self.min_val = min_val
		self.max_val = max_val
		self.buckets = buckets
		self.active_bits = active_bits
		self.total_bits = buckets + active_bits - 1
		self.range = max_val - min_val
		self.bitarray = bitarray(self.total_bits)


	def encode_value(self, value): 
		self.bitarray.setall(False) #set the bitarray to false, otherwise it initializes with some random value I haven't figured out
		self.i = math.floor(self.buckets * (value - self.min_val) / self.range) #function to get bucket i
		indexmap = list(range(len(self.bitarray))) 
		random.seed(4)
		random.shuffle(indexmap) #indexmap creates a new list of indices of bits, then shuffles it around at random to create an index map to randomize the distribution
		for x in range(encoder.active_bits):
			self.bitarray[indexmap[encoder.i + x]] = True #iterate through the # of active bits to turn on each one via the index map created above

I finished working through the spatial pooler as well, but I think my code has some issues somewhere. Unfortunately, it’s too complex to attempt to debug from just the console, so I’m trying to learn tkinter to make a UI that will show me what is happening during each step. I might make another post once I finish that.

2 Likes