Beispiel #1
0
func (sp *SpatialPooler) getNeighborsND(columnIndex int, dimensions []int, radius int, wrapAround bool) []int {
	if len(dimensions) < 1 {
		panic("Dimensions empty")
	}

	bounds := append(dimensions[1:], 1)
	bounds = utils.RevCumProdInt(bounds)

	columnCoords := make([]int, len(bounds))
	for j := 0; j < len(bounds); j++ {
		columnCoords[j] = utils.Mod(columnIndex/bounds[j], dimensions[j])
	}

	rangeND := make([][]int, len(dimensions))
	for i := 0; i < len(dimensions); i++ {
		if wrapAround {
			cRange := make([]int, (radius*2)+1)
			for j := 0; j < (2*radius)+1; j++ {
				cRange[j] = utils.Mod((columnCoords[i]-radius)+j, dimensions[i])
			}
			rangeND[i] = cRange
		} else {
			var cRange []int
			for j := 0; j < (radius*2)+1; j++ {
				temp := columnCoords[i] - radius + j
				if temp >= 0 && temp < dimensions[i] {
					cRange = append(cRange, temp)
				}
			}
			rangeND[i] = cRange
		}
	}

	cp := utils.CartProductInt(rangeND)
	var neighbors []int
	for i := 0; i < len(cp); i++ {
		val := utils.DotInt(bounds, cp[i])
		if val != columnIndex && !utils.ContainsInt(val, neighbors) {
			neighbors = append(neighbors, val)
		}
	}

	return neighbors
}
Beispiel #2
0
func TestGetNeighborsND(t *testing.T) {
	sp := SpatialPooler{}

	dimensions := []int{5, 7, 2}
	var layout [5][7][2]int

	counter := 0
	for i := range layout {
		for j := range layout[i] {
			for k := range layout[i][j] {
				layout[i][j][k] = counter
				counter++
			}
		}
	}

	radius := 1
	x := 1
	y := 3
	z := 2

	columnIndex := layout[z][y][x]

	neighbors := sp.getNeighborsND(columnIndex, dimensions, radius, true)

	var expected []int

	for i := radius * -1; i <= radius; i++ {
		for j := radius * -1; j <= radius; j++ {
			for k := radius * -1; k <= radius; k++ {
				zprime := (z + i) % dimensions[0]
				yprime := (y + j) % dimensions[1]
				xprime := (x + k) % dimensions[2]
				if layout[zprime][yprime][xprime] != columnIndex && !utils.ContainsInt(layout[zprime][yprime][xprime], expected) {
					expected = append(expected, layout[zprime][yprime][xprime])
				}

			}
		}
	}

	assert.Equal(t, expected, neighbors)

	dimensions = []int{5, 7, 9}
	var layoutb [5][7][9]int
	counter = 0
	for i := range layoutb {
		for j := range layoutb[i] {
			for k := range layoutb[i][j] {
				layoutb[i][j][k] = counter
				counter++
			}
		}
	}

	radius = 3
	x = 0
	y = 0
	z = 3
	columnIndex = layoutb[z][y][x]
	neighbors = sp.getNeighborsND(columnIndex, dimensions, radius, true)
	expected = []int{}
	for i := radius * -1; i <= radius; i++ {
		for j := radius * -1; j <= radius; j++ {
			for k := radius * -1; k <= radius; k++ {
				zprime := utils.Mod((z + i), (dimensions[0]))
				yprime := utils.Mod((y + j), (dimensions[1]))
				xprime := utils.Mod((x + k), (dimensions[2]))

				if layoutb[zprime][yprime][xprime] != columnIndex && !utils.ContainsInt(layoutb[zprime][yprime][xprime], expected) {
					expected = append(expected, layoutb[zprime][yprime][xprime])
				}

			}
		}
	}

	assert.Equal(t, expected, neighbors)

	dimensions = []int{5, 10, 7, 6}
	var layoutc [5][10][7][6]int
	counter = 0
	for i := range layoutc {
		for j := range layoutc[i] {
			for k := range layoutc[i][j] {
				for m := range layoutc[i][j][k] {
					layoutc[i][j][k][m] = counter
					counter++
				}
			}
		}
	}

	radius = 4
	w := 2
	x = 5
	y = 6
	z = 2
	columnIndex = layoutc[z][y][x][w]
	neighbors = sp.getNeighborsND(columnIndex, dimensions, radius, true)
	expected = []int{}
	for i := radius * -1; i <= radius; i++ {
		for j := radius * -1; j <= radius; j++ {
			for k := radius * -1; k <= radius; k++ {
				for m := radius * -1; m <= radius; m++ {
					zprime := utils.Mod((z + i), (dimensions[0]))
					yprime := utils.Mod((y + j), (dimensions[1]))
					xprime := utils.Mod((x + k), (dimensions[2]))
					wprime := utils.Mod((w + m), (dimensions[3]))

					if layoutc[zprime][yprime][xprime][wprime] != columnIndex && !utils.ContainsInt(layoutc[zprime][yprime][xprime][wprime], expected) {
						expected = append(expected, layoutc[zprime][yprime][xprime][wprime])
					}

				}

			}
		}
	}

	assert.Equal(t, expected, neighbors)

	layoutd := []bool{false, false, true, false, true, false, false, false}
	columnIndex = 3
	dimensions = []int{8}
	radius = 1
	mask := sp.getNeighborsND(columnIndex, dimensions, radius, true)
	t.Log("mask", mask)

	for idx, val := range layoutd {
		if utils.ContainsInt(idx, mask) {
			assert.Equal(t, true, val)
		} else {
			assert.Equal(t, false, val)
		}
	}

	layoute := []bool{false, true, true, false, true, true, false, false}
	columnIndex = 3
	dimensions = []int{8}
	radius = 2

	mask = sp.getNeighborsND(columnIndex, dimensions, radius, true)
	t.Log("mask", mask)

	for idx, val := range layoute {
		if utils.ContainsInt(idx, mask) {
			assert.Equal(t, true, val)
		} else {
			assert.Equal(t, false, val)
		}
	}

	// Wrap around
	layoutf := []bool{false, true, true, false, false, false, true, true}
	columnIndex = 0
	dimensions = []int{8}
	radius = 2

	mask = sp.getNeighborsND(columnIndex, dimensions, radius, true)
	t.Log("mask", mask)

	for idx, val := range layoutf {
		if utils.ContainsInt(idx, mask) {
			assert.Equal(t, true, val)
		} else {
			assert.Equal(t, false, val)
		}
	}

	//Radius too big
	layoutg := []bool{true, true, true, true, true, true, false, true}
	columnIndex = 6
	dimensions = []int{8}
	radius = 20

	mask = sp.getNeighborsND(columnIndex, dimensions, radius, true)
	t.Log("mask", mask)

	for idx, val := range layoutg {
		if utils.ContainsInt(idx, mask) {
			assert.Equal(t, true, val)
		} else {
			assert.Equal(t, false, val)
		}
	}

	//These are all the same tests from 2D
	ints := [][]int{{0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0},
		{0, 1, 1, 1, 0},
		{0, 1, 0, 1, 0},
		{0, 1, 1, 1, 0},
		{0, 0, 0, 0, 0}}

	layouth := NewDenseBinaryMatrixFromInts(ints)
	t.Log(layouth.ToString())

	columnIndex = 3*5 + 2
	dimensions = []int{6, 5}
	radius = 1

	mask = sp.getNeighborsND(columnIndex, dimensions, radius, true)
	t.Log("mask", mask)
	t.Log("1d", layouth.Flatten())
	for idx, val := range layouth.Flatten() {
		if utils.ContainsInt(idx, mask) {
			assert.Equal(t, true, val)
		} else {
			assert.Equal(t, false, val)
		}
	}

	ints = [][]int{{0, 0, 0, 0, 0},
		{1, 1, 1, 1, 1},
		{1, 1, 1, 1, 1},
		{1, 1, 0, 1, 1},
		{1, 1, 1, 1, 1},
		{1, 1, 1, 1, 1}}

	layoutj := NewDenseBinaryMatrixFromInts(ints)
	t.Log(layouth.ToString())

	columnIndex = 3*5 + 2
	radius = 2

	mask = sp.getNeighborsND(columnIndex, dimensions, radius, true)
	t.Log("mask", mask)
	t.Log("1d", layouth.Flatten())
	for idx, val := range layoutj.Flatten() {
		if utils.ContainsInt(idx, mask) {
			assert.Equal(t, true, val)
		} else {
			assert.Equal(t, false, val)
		}
	}

	//Radius too big
	ints = [][]int{{1, 1, 1, 1, 1},
		{1, 1, 1, 1, 1},
		{1, 1, 1, 1, 1},
		{1, 1, 0, 1, 1},
		{1, 1, 1, 1, 1},
		{1, 1, 1, 1, 1}}

	layoutk := NewDenseBinaryMatrixFromInts(ints)
	t.Log(layouth.ToString())

	columnIndex = 3*5 + 2
	radius = 7

	mask = sp.getNeighborsND(columnIndex, dimensions, radius, true)
	t.Log("mask", mask)
	t.Log("1d", layoutk.Flatten())
	for idx, val := range layoutk.Flatten() {
		if utils.ContainsInt(idx, mask) {
			assert.Equal(t, true, val)
		} else {
			assert.Equal(t, false, val)
		}
	}

	//Wrap-around
	ints = [][]int{{1, 0, 0, 1, 1},
		{0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0},
		{1, 0, 0, 1, 1},
		{1, 0, 0, 1, 0}}

	layoutl := NewDenseBinaryMatrixFromInts(ints)
	t.Log(layoutl.ToString())

	columnIndex = 29
	radius = 1

	mask = sp.getNeighborsND(columnIndex, dimensions, radius, true)
	t.Log("mask", mask)
	t.Log("1d", layoutl.Flatten())
	for idx, val := range layoutl.Flatten() {
		if utils.ContainsInt(idx, mask) {
			assert.Equal(t, true, val)
		} else {
			assert.Equal(t, false, val)
		}
	}

	//No wrap around
	columnIndex = 8
	radius = 2
	dimensions = []int{10}
	neighbors = sp.getNeighborsND(columnIndex, dimensions, radius, false)
	expected = []int{6, 7, 9}
	assert.Equal(t, expected, neighbors)

}