/* Updates the minimum duty cycles. The minimum duty cycles are determined locally. Each column's minimum duty cycles are set to be a percent of the maximum duty cycles in the column's neighborhood. Unlike updateMinDutyCyclesGlobal, here the values can be quite different for different columns. */ func (sp *SpatialPooler) updateMinDutyCyclesLocal(getNeighborsND getNeighborsNDFunc) { for i := 0; i < sp.numColumns; i++ { maskNeighbors := getNeighborsND(i, sp.ColumnDimensions, sp.inhibitionRadius, false) maskNeighbors = append(maskNeighbors, i) maxOverlap := utils.MaxSliceFloat64(utils.SubsetSliceFloat64(sp.overlapDutyCycles, maskNeighbors)) sp.minOverlapDutyCycles[i] = maxOverlap * sp.MinPctOverlapDutyCycles maxActive := utils.MaxSliceFloat64(utils.SubsetSliceFloat64(sp.activeDutyCycles, maskNeighbors)) sp.minActiveDutyCycles[i] = maxActive * sp.MinPctActiveDutyCycles } }
func (sp *SpatialPooler) inhibitColumnsLocal(overlaps []float64, density float64) []int { var activeColumns []int addToWinners := utils.MaxSliceFloat64(overlaps) / 1000.0 for i := 0; i < sp.numColumns; i++ { mask := sp.getNeighborsND(i, sp.ColumnDimensions, sp.inhibitionRadius, false) ovSlice := make([]float64, len(mask)) for idx, val := range mask { ovSlice[idx] = overlaps[val] } numActive := int(0.5 + density*float64(len(mask)+1)) numBigger := 0 for _, ov := range ovSlice { if ov > overlaps[i] { numBigger++ } } if numBigger < numActive { activeColumns = append(activeColumns, i) overlaps[i] += addToWinners } } return activeColumns }
/* Updates the minimum duty cycles in a global fashion. Sets the minimum duty cycles for the overlap and activation of all columns to be a percent of the maximum in the region, specified by minPctOverlapDutyCycle and minPctActiveDutyCycle respectively. Functionaly it is equivalent to updateMinDutyCyclesLocal, but this function exploits the globalilty of the compuation to perform it in a straightforward, and more efficient manner. */ func (sp *SpatialPooler) updateMinDutyCyclesGlobal() { minOverlap := sp.MinPctOverlapDutyCycles * utils.MaxSliceFloat64(sp.overlapDutyCycles) utils.FillSliceFloat64(sp.minOverlapDutyCycles, minOverlap) minActive := sp.MinPctActiveDutyCycles * utils.MaxSliceFloat64(sp.activeDutyCycles) utils.FillSliceFloat64(sp.minActiveDutyCycles, minActive) }