def testBadParameters(self): # Start with sane parameters. p = ScalarEncoderParameters() p.size = 10 p.activeBits = 2 p.minimum = 0 p.maximum = 1 ScalarEncoder(p) # Check a lot of bad parameters p.activeBits = 12 # Can not activate more bits than are in the SDR. with self.assertRaises(RuntimeError): ScalarEncoder(p) p.activeBits = 0 # not enough active bits with self.assertRaises(RuntimeError): ScalarEncoder(p) p.activeBits = 1 p.size = 0 # not enough bits with self.assertRaises(RuntimeError): ScalarEncoder(p) p.activeBits = 2 p.maximum = -1 # Maximum is less than the minimum with self.assertRaises(RuntimeError): ScalarEncoder(p) p.maximum = 1 p.size = 0 p.activeBits = 0 p.sparsity = .1 # Specify sparsity without output size with self.assertRaises(RuntimeError): ScalarEncoder(p) p.size = 10 p.activeBits = 2 p.sparsity = 0 p.sparsity = .2 # Sparsity & num activeBits specified with self.assertRaises(RuntimeError): ScalarEncoder(p) p.sparsity = 0 p.clipInput = True # Incompatible features... p.periodic = True with self.assertRaises(RuntimeError): ScalarEncoder(p) p.clipInput = False p.periodic = False p.radius = 1 # Size specified too many times with self.assertRaises(RuntimeError): ScalarEncoder(p) p.radius = 0 p.resolution = 1 # Size specified too many times with self.assertRaises(RuntimeError): ScalarEncoder(p) p.resolution = 0
def testStatistics(self): p = ScalarEncoderParameters() p.size = 100 p.activeBits = 10 p.minimum = 0 p.maximum = 20 p.clipInput = True enc = ScalarEncoder( p ) del p out = SDR( enc.parameters.size ) mtr = Metrics(out, 9999) # The activation frequency of bits near the endpoints of the range is a # little weird, because the bits at the very end are not used as often # as the ones in the middle of the range, unless clipInputs is enabled. # If clipInputs is enabled then the bits 1 radius from the end get used # twice as often as the should because they respond to inputs off # outside of the valid range as well as inputs inside of the range. for i in np.linspace( enc.parameters.minimum - enc.parameters.radius / 2, enc.parameters.maximum + enc.parameters.radius / 2, 100 + 10 ): enc.encode( i, out ) # print( i, out.sparse ) print(str(mtr)) assert( mtr.sparsity.min() > .95 * .10 ) assert( mtr.sparsity.max() < 1.05 * .10 ) assert( mtr.activationFrequency.min() > .50 * .10 ) assert( mtr.activationFrequency.max() < 1.75 * .10 ) assert( mtr.overlap.min() > .85 )
def testJSONSerialization(self): """ This test is to insure that Python can access the C++ serialization functions. Serialization is tested more completely in C++ unit tests. Just checking that Python can access it. """ p = ScalarEncoderParameters() p.size = 100 p.activeBits = 10 p.minimum = 0 p.maximum = 20 p.clipInput = True encoder1 = ScalarEncoder(p) filename = 'ScalarEncoder_testSerialization.json' encoder1.saveToFile(filename, "JSON") encoder2 = ScalarEncoder() encoder2.loadFromFile(filename, "JSON") value_to_encode = 69003 SDR_original = encoder1.encode(value_to_encode) SDR_loaded = encoder2.encode(value_to_encode) assert(SDR_original == SDR_loaded) os.remove(filename)
def testNaNs(self): p = ScalarEncoderParameters() p.size = 100 p.activeBits = 10 p.minimum = 0 p.maximum = 100 enc = ScalarEncoder(p) sdr = SDR( 100 ) enc.encode( float("nan"), sdr ) assert( sdr.getSum() == 0 )
def testEncode(self): p = ScalarEncoderParameters() p.size = 10 p.activeBits = 3 p.minimum = 0 p.maximum = 1 enc = ScalarEncoder(p) sdr = SDR( 10 ) enc.encode( 0, sdr ) assert( list(sdr.sparse) == [0, 1, 2] ) sdr2 = enc.encode( 1 ) assert( list(sdr2.sparse) == [7, 8, 9] )
def ScalarEncoderGenerator(mini, maxi, size, spars=-1): # if sparsity is not given, don't allow overlapping bits. if spars == -1: # unsure if correct diff = maxi - mini spars = 1 / (diff + 1) params = ScalarEncoderParameters() params.minimum = mini params.maximum = maxi params.size = size params.sparsity = spars encoder = ScalarEncoder(params) return encoder
def testConstructor(self): p = ScalarEncoderParameters() p.size = 1000 p.activeBits = 20 p.minimum = 0 p.maximum = 345 enc = ScalarEncoder( p ) assert( enc.dimensions == [1000] ) assert( enc.size == 1000 ) assert( not enc.parameters.clipInput ) assert( not enc.parameters.periodic ) assert( abs(enc.parameters.sparsity - 20./1000) < .01 ) assert( abs(enc.parameters.radius - 7) < 1 ) assert( abs(enc.parameters.resolution - .35) < .1 )
def testClipInput(self): p = ScalarEncoderParameters() p.size = 345 p.sparsity = .05 p.minimum = 0 p.maximum = 1 p.clipInput = 1 enc = ScalarEncoder(p) sdr1 = SDR( 345 ) sdr2 = SDR( 345 ) enc.encode( 0, sdr1 ) enc.encode( -1, sdr2 ) assert( sdr1 == sdr2 ) enc.encode( 1, sdr1 ) enc.encode( 10, sdr2 ) assert( sdr1 == sdr2 )
def testBadEncode(self): # Test bad SDR p = ScalarEncoderParameters() p.size = 10 p.activeBits = 2 p.minimum = 0 p.maximum = 1 enc = ScalarEncoder(p) good = SDR( 10 ) bad = SDR( 5 ) enc.encode( .25, good ) with self.assertRaises(RuntimeError): enc.encode( .25, bad ) # Test bad inputs, out of valid range & clipping disabled. with self.assertRaises(RuntimeError): enc.encode( -.0001, good ) with self.assertRaises(RuntimeError): enc.encode( 1.0001, good )
def testPickle(self): p = ScalarEncoderParameters() p.size = 100 p.activeBits = 10 p.minimum = 0 p.maximum = 20 p.clipInput = True enc = ScalarEncoder( p ) import pickle picklestr = pickle.dumps(enc) enc2 = pickle.loads(picklestr) #assert enc.parameters == enc2.parameters assert enc.size == enc2.size out = SDR( enc.parameters.size ) out2 = SDR( enc2.parameters.size ) enc.encode(10, out) enc2.encode(10, out2) assert out == out2
def testPeriodic(self): p = ScalarEncoderParameters() p.size = 100 p.activeBits = 10 p.minimum = 0 p.maximum = 20 p.periodic = True enc = ScalarEncoder( p ) out = SDR( enc.parameters.size ) mtr = Metrics(out, 9999) for i in range(201 * 10 + 1): x = (i % 201) / 10. enc.encode( x, out ) # print( x, out.sparse ) print(str(mtr)) assert( mtr.sparsity.min() > .95 * .10 ) assert( mtr.sparsity.max() < 1.05 * .10 ) assert( mtr.activationFrequency.min() > .9 * .10 ) assert( mtr.activationFrequency.max() < 1.1 * .10 ) assert( mtr.overlap.min() > .85 )