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 }
func (sp *SpatialPooler) avgConnectedSpanForColumnND(index int) float64 { dimensions := sp.InputDimensions bounds := append(dimensions[1:], 1) bounds = utils.RevCumProdInt(bounds) connected := sp.connectedSynapses.GetRowIndices(index) if len(connected) == 0 { return 0 } maxCoord := make([]int, len(dimensions)) minCoord := make([]int, len(dimensions)) inputMax := 0 for i := 0; i < len(dimensions); i++ { if dimensions[i] > inputMax { inputMax = dimensions[i] } } for i := 0; i < len(maxCoord); i++ { maxCoord[i] = -1.0 minCoord[i] = inputMax } //calc min/max of (i/bounds) % dimensions for _, val := range connected { for j := 0; j < len(dimensions); j++ { coord := (val / bounds[j]) % dimensions[j] if coord > maxCoord[j] { maxCoord[j] = coord } if coord < minCoord[j] { minCoord[j] = coord } } } sum := 0 for i := 0; i < len(dimensions); i++ { sum += maxCoord[i] - minCoord[i] + 1 } return float64(sum) / float64(len(dimensions)) }