Esempio n. 1
0
/*
 Maps a column to its input bits. This method encapsultes the topology of
the region. It takes the index of the column as an argument and determines
what are the indices of the input vector that are located within the
column's potential pool. The return value is a list containing the indices
of the input bits. The current implementation of the base class only
supports a 1 dimensional topology of columsn with a 1 dimensional topology
of inputs. To extend this class to support 2-D topology you will need to
override this method. Examples of the expected output of this method:
* If the potentialRadius is greater than or equal to the entire input
space, (global visibility), then this method returns an array filled with
all the indices
* If the topology is one dimensional, and the potentialRadius is 5, this
method will return an array containing 5 consecutive values centered on
the index of the column (wrapping around if necessary).
* If the topology is two dimensional (not implemented), and the
potentialRadius is 5, the method should return an array containing 25
'1's, where the exact indices are to be determined by the mapping from
1-D index to 2-D position.

Parameters:
----------------------------
index: The index identifying a column in the permanence, potential
and connectivity matrices.
wrapAround: A boolean value indicating that boundaries should be
region boundaries ignored.
*/
func (sp *SpatialPooler) mapPotential(index int, wrapAround bool) []bool {
	// Distribute column over inputs uniformly
	ratio := float64(index) / float64(mathutil.Max((sp.numColumns-1), 1))
	index = int(float64(sp.numInputs-1) * ratio)

	var indices []int
	indLen := 2*sp.PotentialRadius + 1

	for i := 0; i < indLen; i++ {
		temp := (i + index - sp.PotentialRadius)
		if wrapAround {
			temp = temp % sp.numInputs
			if temp < 0 {
				temp = sp.numInputs + temp
			}
		} else {
			if !(temp >= 0 && temp < sp.numInputs) {
				continue
			}
		}
		//no dupes
		if !utils.ContainsInt(temp, indices) {
			indices = append(indices, temp)
		}
	}

	// Select a subset of the receptive field to serve as the
	// the potential pool

	//shuffle indices
	for i := range indices {
		j := rand.Intn(i + 1)
		indices[i], indices[j] = indices[j], indices[i]
	}

	sampleLen := int(utils.RoundPrec(float64(len(indices))*sp.PotentialPct, 0))
	sample := indices[:sampleLen]
	//project indices onto input mask
	mask := make([]bool, sp.numInputs)
	for i, _ := range mask {
		mask[i] = utils.ContainsInt(i, sample)
	}

	return mask
}
Esempio n. 2
0
/*
 Update the inhibition radius. The inhibition radius is a meausre of the
square (or hypersquare) of columns that each a column is "conencted to"
on average. Since columns are are not connected to each other directly, we
determine this quantity by first figuring out how many *inputs* a column is
connected to, and then multiplying it by the total number of columns that
exist for each input. For multiple dimension the aforementioned
calculations are averaged over all dimensions of inputs and columns. This
value is meaningless if global inhibition is enabled.
*/
func (sp *SpatialPooler) updateInhibitionRadius(avgConnectedSpanForColumnND avgConnectedSpanForColumnNDFunc,
	avgColumnsPerInput avgColumnsPerInputFunc) {

	if sp.GlobalInhibition {
		cmax := utils.MaxSliceInt(sp.ColumnDimensions)
		sp.inhibitionRadius = cmax
		return
	}

	avgConnectedSpan := 0.0
	for i := 0; i < sp.numColumns; i++ {
		avgConnectedSpan += avgConnectedSpanForColumnND(i)
	}
	avgConnectedSpan = avgConnectedSpan / float64(sp.numColumns)

	columnsPerInput := avgColumnsPerInput()
	diameter := avgConnectedSpan * columnsPerInput
	radius := (diameter - 1) / 2.0
	radius = math.Max(1.0, radius)

	sp.inhibitionRadius = int(utils.RoundPrec(radius, 0))
}
Esempio n. 3
0
func AlmostEqualFloat(a, b float64) bool {
	ar := utils.RoundPrec(a, 2)
	br := utils.RoundPrec(b, 2)
	return ar == br
}