def testCompute(self): """ Check that there are no errors in call to compute. """ inputs = SDR(100).randomize(.05) active = SDR(100) sp = SP(inputs.dimensions, active.dimensions, stimulusThreshold=1) sp.compute(inputs, True, active) assert (active.getSum() > 0)
def testConstructorErrors(self): def _assertAnyException(func): try: func() except RuntimeError: return except TypeError: return else: self.fail() A = SDR(100) B = SDR((100, 2)) C = SDR([3, 3]) D = SDR([3, 4]) # Test bad argument dimensions _assertAnyException(lambda: Concatenation(A)) # Not enough inputs! _assertAnyException(lambda: Concatenation(A, B)) _assertAnyException( lambda: Concatenation(B, C)) # All dims except axis must match! _assertAnyException( lambda: Concatenation(C, D)) # All dims except axis must match! Concatenation(C, D, 1) # This should work _assertAnyException( lambda: Concatenation(inputs=(C, D), axis=2)) # invalid axis _assertAnyException( lambda: Concatenation(inputs=(C, D), axis=-1)) # invalid axis
def testPickle(self): for sparsity in (0, .3, 1): A = SDR((103, )) A.randomize(sparsity) P = pickle.dumps(A) B = pickle.loads(P) assert (A == B)
def testExampleUsage(self): assert (issubclass(Reshape, SDR)) # Convert SDR dimensions from (4 x 4) to (8 x 2) A = SDR([4, 4]) B = Reshape(A, [8, 2]) A.coordinates = ([1, 1, 2], [0, 1, 2]) assert ((np.array(B.coordinates) == ([2, 2, 5], [0, 1, 0])).all())
def encode(self, location, grid_cells=None): location = list(location) assert (len(location) == 2) if grid_cells is None: grid_cells = SDR((self.size, )) if any(math.isnan(x) for x in location): grid_cells.zero() return grid_cells # Find the distance from the location to each grid cells nearest # receptive field center. # Convert the units of location to hex grid with angle 0, scale 1, offset 0. displacement = location - self.offsets_ radius = np.empty(self.size) for mod_idx in range(len(self.partitions_)): start, stop = self.partitions_[mod_idx] R = self.rot_mats_[mod_idx] displacement[start:stop] = R.dot(displacement[start:stop].T).T radius[start:stop] = self.periods[mod_idx] / 2 # Convert into and out of hexagonal coordinates, which rounds to the # nearest hexagons center. nearest = hexy.cube_to_pixel(hexy.pixel_to_cube(displacement, radius), radius) # Find the distance between the location and the RF center. distances = np.hypot(*(nearest - displacement).T) # Activate the closest grid cells in each module. index = [] for start, stop in self.partitions_: z = int(round(self.sparsity * (stop - start))) index.extend(np.argpartition(distances[start:stop], z)[:z] + start) grid_cells.sparse = index return grid_cells
def testExampleUsage(self): A = SDR(10) B = SDR(10) X = SDR(A.dimensions) A.sparse = [0, 1, 2, 3] B.sparse = [2, 3, 4, 5] X.intersection(A, B) assert (set(X.sparse) == set([2, 3]))
def testExampleUsage(self): A = SDR(10) B = SDR(10) C = SDR(20) A.sparse = [0, 1, 2] B.sparse = [0, 1, 2] C.concatenate(A, B) assert (set(C.sparse) == set([0, 1, 2, 10, 11, 12]))
def testNan(self): gc = GridCellEncoder(size=200, sparsity=.25, periods=[6, 8.5, 12, 17, 24], seed=42) zero = SDR(gc.dimensions) zero.randomize(.25) gc.encode([3, float('nan')], zero) assert (zero.getSum() == 0)
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 testExampleUsage(self): # Make an SDR with 9 values, arranged in a (3 x 3) grid. X = SDR(dimensions=(3, 3)) # These three statements are equivalent. X.dense = [[0, 1, 0], [0, 1, 0], [0, 0, 1]] assert (X.dense.tolist() == [[0, 1, 0], [0, 1, 0], [0, 0, 1]]) assert ([list(v) for v in X.coordinates] == [[0, 1, 2], [1, 1, 2]]) assert (list(X.sparse) == [1, 4, 8]) X.coordinates = [[0, 1, 2], [1, 1, 2]] assert (X.dense.tolist() == [[0, 1, 0], [0, 1, 0], [0, 0, 1]]) assert ([list(v) for v in X.coordinates] == [[0, 1, 2], [1, 1, 2]]) assert (list(X.sparse) == [1, 4, 8]) X.sparse = [1, 4, 8] # Access data in any format, SDR will automatically convert data formats, # even if it was not the format used by the most recent assignment to the # SDR. assert (X.dense.tolist() == [[0, 1, 0], [0, 1, 0], [0, 0, 1]]) assert ([list(v) for v in X.coordinates] == [[0, 1, 2], [1, 1, 2]]) assert (list(X.sparse) == [1, 4, 8]) # Data format conversions are cached, and when an SDR value changes the # cache is cleared. X.sparse = [1, 2, 3] # Assign new data to the SDR, clearing the cache. X.dense # This line will convert formats. X.dense # This line will resuse the result of the previous line X = SDR((1000, 1000)) data = X.dense data[0, 4] = 1 data[444, 444] = 1 X.dense = data assert (list(X.sparse) == [4, 444444])
def testErrorChecks(self): params1 = RDSE_Parameters() params1.size = 100 params1.sparsity = .10 params1.radius = 10 R1 = RDSE(params1) A = SDR([10, 10]) R1.encode(33, A) # Test wrong input dimensions B = SDR(1) with self.assertRaises(RuntimeError): R1.encode(3, B) # Test invalid parameters, size == 0 params1.size = 0 with self.assertRaises(RuntimeError): RDSE(params1) params1.size = 100 # Test invalid parameters, activeBits == 0 params1.activeBits = 0 params1.sparsity = 0.00001 # Rounds to zero! with self.assertRaises(RuntimeError): RDSE(params1) # Test missing activeBits params2 = RDSE_Parameters() params2.size = 100 params2.radius = 10 with self.assertRaises(RuntimeError): RDSE(params2) # Test missing resolution/radius params3 = RDSE_Parameters() params3.size = 100 params3.activeBits = 10 with self.assertRaises(RuntimeError): RDSE(params3) # Test too many parameters: activeBits & sparsity params4 = RDSE_Parameters() params4.size = 100 params4.sparsity = .6 params4.activeBits = 10 params4.radius = 4 with self.assertRaises(RuntimeError): RDSE(params4) # Test too many parameters: resolution & radius params5 = RDSE_Parameters() params5.size = 100 params5.activeBits = 10 params5.radius = 4 params5.resolution = 4 with self.assertRaises(RuntimeError): RDSE(params5)
def testSparsity(self): test_cases = [ (0.5, 0.5), (0.1, 0.9), (0.25, 0.3), (0.5, 0.5, 0.5), (0.95, 0.95, 0.95), (0.10, 0.10, 0.60), (0.0, 1.0, 1.0), (0.5, 0.5, 0.5, 0.5), (0.11, 0.25, 0.33, 0.5, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98), ] size = 10000 seed = 99 X = SDR(size) for sparsities in test_cases: sdrs = [] for S in sparsities: inp = SDR(size) inp.randomize(S, seed) seed += 1 sdrs.append(inp) X.intersection(sdrs) mean_sparsity = np.product(sparsities) assert (X.getSparsity() >= (2. / 3.) * mean_sparsity) assert (X.getSparsity() <= (4. / 3.) * mean_sparsity)
def testChaining(self): A = SDR([10, 10]) B = Reshape(A, [100]) C = Reshape(B, [4, 25]) D = Reshape(B, [1, 100]) A.dense.fill(1) A.dense = A.dense assert (len(C.sparse) == A.size) assert (len(D.sparse) == A.size) del B
def testExampleUsage(self): assert (issubclass(Intersection, SDR)) A = SDR(100) B = SDR(100) C = Concatenation(A, B) assert (C.dimensions == [200]) D = SDR((640, 480, 3)) E = SDR((640, 480, 7)) F = Concatenation(D, E, 2) assert (F.dimensions == [640, 480, 10])
def testChaining(self): A = SDR([10, 10]) B = Reshape(A, [100]) C = Reshape(B, [4, 25]) D = B.reshape([1, 100]) # Test convenience method. A.dense.fill(1) A.dense = A.dense assert (len(C.sparse) == A.size) assert (len(D.sparse) == A.size) del B
def testDelete(self): # Make & Delete it a few times to make sure that doesn't crash. A = SDR(100) B = SDR(100) C = SDR(100) X = Concatenation(A, B, C) Concatenation(A, B, C) Y = Concatenation(A, C) Concatenation(B, C) del B del A del Y del C del X
def testConstructor(self): # Test all of the constructor overloads A = SDR((100, 2)) B = SDR((100, 2)) C = SDR((100, 2)) D = SDR((100, 2)) Concatenation(A, B) Concatenation(A, B, 1) Concatenation(A, B, C) Concatenation(A, B, C, 1) Concatenation(A, B, C, D) Concatenation(A, B, C, D, 1) Concatenation([A, B, C, D]) Concatenation([A, B, C, D], 1) Concatenation(inputs=[A, B, C, D], axis=1)
def testAverageOverlap(self): """ Verify that nearby values have the correct amount of semantic similarity. Also measure sparsity & activation frequency. """ P = RDSE_Parameters() P.size = 2000 P.sparsity = .08 P.radius = 12 P.seed = 42 R = RDSE(P) A = SDR(R.parameters.size) num_samples = 10000 M = Metrics(A, num_samples + 1) for i in range(num_samples): R.encode(i, A) print(M) assert (M.overlap.min() > (1 - 1. / R.parameters.radius) - .04) assert (M.overlap.max() < (1 - 1. / R.parameters.radius) + .04) assert (M.overlap.mean() > (1 - 1. / R.parameters.radius) - .001) assert (M.overlap.mean() < (1 - 1. / R.parameters.radius) + .001) assert (M.sparsity.min() > R.parameters.sparsity - .01) assert (M.sparsity.max() < R.parameters.sparsity + .01) assert (M.sparsity.mean() > R.parameters.sparsity - .005) assert (M.sparsity.mean() < R.parameters.sparsity + .005) assert (M.activationFrequency.min() > R.parameters.sparsity - .05) assert (M.activationFrequency.max() < R.parameters.sparsity + .05) assert (M.activationFrequency.mean() > R.parameters.sparsity - .005) assert (M.activationFrequency.mean() < R.parameters.sparsity + .005) assert (M.activationFrequency.entropy() > .99)
def testRandomOverlap(self): """ Verify that distant values have little to no semantic similarity. Also measure sparsity & activation frequency. """ P = RDSE_Parameters() P.size = 2000 P.sparsity = .08 P.radius = 12 P.seed = 42 R = RDSE(P) num_samples = 1000 A = SDR(R.parameters.size) M = Metrics(A, num_samples + 1) for i in range(num_samples): X = i * R.parameters.radius R.encode(X, A) print(M) assert (M.overlap.max() < .15) assert (M.overlap.mean() < .10) assert (M.sparsity.min() > R.parameters.sparsity - .01) assert (M.sparsity.max() < R.parameters.sparsity + .01) assert (M.sparsity.mean() > R.parameters.sparsity - .005) assert (M.sparsity.mean() < R.parameters.sparsity + .005) assert (M.activationFrequency.min() > R.parameters.sparsity - .05) assert (M.activationFrequency.max() < R.parameters.sparsity + .05) assert (M.activationFrequency.mean() > R.parameters.sparsity - .005) assert (M.activationFrequency.mean() < R.parameters.sparsity + .005) assert (M.activationFrequency.entropy() > .99)
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 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 testExampleUsage(self): A = SDR(10) B = SDR(10) A.sparse = [2, 3, 4, 5] B.sparse = [0, 1, 2, 3] X = Intersection(A, B) assert ((X.sparse == [2, 3]).all()) B.zero() assert (X.getSparsity() == 0)
def testDeterminism(self): GOLD = SDR(200) GOLD.sparse = [ 8, 11, 13, 15, 16, 18, 29, 32, 37, 39, 41, 42, 45, 47, 57, 59, 69, 71, 72, 75, 80, 84, 88, 94, 95, 96, 99, 101, 106, 116, 121, 126, 128, 135, 139, 143, 149, 150, 158, 159, 160, 171, 176, 178, 182, 184, 188, 194, 197, 198 ] gc = GridCellEncoder(size=GOLD.size, sparsity=.25, periods=[6, 8.5, 12, 17, 24], seed=42) actual = gc.encode([77, 88]) print(actual) assert (actual == GOLD)
def testRadius(self): p = ScalarEncoderParameters() p.activeBits = 10 p.minimum = 0 p.maximum = 100 p.radius = 10 enc = ScalarEncoder(p) sdr1 = SDR(enc.parameters.size) sdr2 = SDR(enc.parameters.size) enc.encode(77, sdr1) enc.encode(77, sdr2) assert (sdr1.getOverlap(sdr2) == 10) enc.encode(0, sdr1) enc.encode(1, sdr2) assert (sdr1.getOverlap(sdr2) == 9) enc.encode(60, sdr1) enc.encode(69, sdr2) assert (sdr1.getOverlap(sdr2) == 1) enc.encode(45, sdr1) enc.encode(55, sdr2) assert (sdr1.getOverlap(sdr2) == 0)
def testResolution(self): p = ScalarEncoderParameters() p.activeBits = 10 p.minimum = 0 p.maximum = 100 p.resolution = .5 enc = ScalarEncoder(p) sdr1 = SDR(enc.parameters.size) sdr2 = SDR(enc.parameters.size) enc.encode(.0, sdr1) enc.encode(.1, sdr2) assert (sdr1 == sdr2) enc.encode(.0, sdr1) enc.encode(.6, sdr2) assert (sdr1.getOverlap(sdr2) == 9) enc.encode(70, sdr1) enc.encode(72.5, sdr2) assert (sdr1.getOverlap(sdr2) == 5) enc.encode(70, sdr1) enc.encode(75, sdr2) assert (sdr1.getOverlap(sdr2) == 0) enc.encode(60, sdr1) enc.encode(80, sdr2) assert (sdr1.getOverlap(sdr2) == 0)
def encode(self, location, grid_cells=None): """ Transform a 2-D coordinate into an SDR. Argument location: pair of coordinates, such as "[X, Y]" Argument grid_cells: Optional, the SDR object to store the results in. Its dimensions must be "[GridCellEncoder.size]" Returns grid_cells, an SDR object. This will be created if not given. """ location = list(location) assert(len(location) == 2) if grid_cells is None: grid_cells = SDR((self.size,)) else: assert(isinstance(grid_cells, SDR)) assert(grid_cells.dimensions == [self.size]) if any(math.isnan(x) for x in location): grid_cells.zero() return grid_cells # Find the distance from the location to each grid cells nearest # receptive field center. # Convert the units of location to hex grid with angle 0, scale 1, offset 0. displacement = location - self.offsets_ radius = np.empty(self.size) for mod_idx in range(len(self.partitions_)): start, stop = self.partitions_[mod_idx] R = self.rot_mats_[mod_idx] displacement[start:stop] = R.dot(displacement[start:stop].T).T radius[start:stop] = self.periods[mod_idx] / 2 # Convert into and out of hexagonal coordinates, which rounds to the # nearest hexagons center. nearest = hexy.cube_to_pixel(hexy.pixel_to_cube(displacement, radius), radius) # Find the distance between the location and the RF center. distances = np.hypot(*(nearest - displacement).T) # Activate the closest grid cells in each module. index = [] for start, stop in self.partitions_: z = int(round(self.sparsity * (stop - start))) index.extend( np.argpartition(distances[start : stop], z)[:z] + start ) grid_cells.sparse = index return grid_cells
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 testDenseInplace(self): # Check that assigning dense data to itself (ie: sdr.dense = sdr.dense) # is significantly faster than copying the data on assignment. # Also, it should not be *too* much faster because this test-case is # tuned to very fast in both situations. A = SDR(100 * 1000) B = np.copy(A.dense) copy_time = time.clock() for i in range(100): A.dense = B copy_time = time.clock() - copy_time inplace_time = time.clock() for i in range(100): A.dense = A.dense inplace_time = time.clock() - inplace_time assert (inplace_time < copy_time / 3)
def testVersusNumpy(self): # Each testcase is a pair of lists of SDR dimensions and axis # dimensions. test_cases = [ ([(9, 30, 40), (2, 30, 40)], 0), ([(2, 30, 40), (2, 99, 40)], 1), ([(2, 30, 40), (2, 30, 99)], 2), ([(100, ), (10), (30)], 0), ([(100, 2), (10, 2), (30, 2)], 0), ([(1, 77), (1, 99), (1, 88)], 1), ([(1, 77, 2), (1, 99, 2), (1, 88, 2)], 1), ] for sdr_dims, axis in test_cases: sdrs = [SDR(dims) for dims in sdr_dims] [sdr.randomize(.50) for sdr in sdrs] cat_dims = sdrs[0].dimensions cat_dims[axis] = sum(sdr.dimensions[axis] for sdr in sdrs) cat = SDR(cat_dims) cat.concatenate(sdrs, axis) np_cat = np.concatenate([sdr.dense for sdr in sdrs], axis=axis) assert ((cat.dense == np_cat).all())
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])