Exemple #1
0
/*
	Encodes input to specified slice. Slice should be valid length
*/
func (se *ScalerEncoder) EncodeToSlice(input float64, learn bool, output []bool) {

	// Get the bucket index to use
	bucketIdx := se.getFirstOnBit(input)

	//if len(bucketIdx) {
	//This shouldn't get hit
	//	panic("Missing input value")
	//TODO output[0:self.n] = 0 TODO: should all 1s, or random SDR be returned instead?
	//} else {
	// The bucket index is the index of the first bit to set in the output
	output = output[:se.N]

	minbin := bucketIdx
	maxbin := minbin + 2*se.halfWidth

	if se.Periodic {

		// Handle the edges by computing wrap-around
		if maxbin >= se.N {
			bottombins := maxbin - se.N + 1
			utils.FillSliceRangeBool(output, true, 0, bottombins)
			maxbin = se.N - 1
		}
		if minbin < 0 {
			topbins := -minbin
			utils.FillSliceRangeBool(output, true, se.N-topbins, (se.N - (se.N - topbins)))
			minbin = 0
		}

	}

	if minbin < 0 {
		panic("invalid minbin")
	}
	if maxbin >= se.N {
		panic("invalid maxbin")
	}

	// set the output (except for periodic wraparound)
	utils.FillSliceRangeBool(output, true, minbin, (maxbin+1)-minbin)

	if se.Verbosity >= 2 {
		fmt.Println("input:", input)
		fmt.Printf("half width:%v \n", se.Width)
		fmt.Printf("range: %v - %v \n", se.MinVal, se.MaxVal)
		fmt.Printf("n: %v width: %v resolution: %v \n", se.N, se.Width, se.Resolution)
		fmt.Printf("radius: %v periodic: %v \n", se.Radius, se.Periodic)
		fmt.Printf("output: %v \n", output)
	}

	//}

}
func BoostTest(t *testing.T) {
	bt := boostTest{}
	spParams := NewSpParams()
	spParams.InputDimensions = []int{90}
	spParams.ColumnDimensions = []int{600}
	spParams.PotentialRadius = 90
	spParams.PotentialPct = 0.9
	spParams.GlobalInhibition = true
	spParams.NumActiveColumnsPerInhArea = 60
	spParams.MinPctActiveDutyCycle = 0.1
	spParams.SynPermActiveInc = 0
	spParams.SynPermInactiveDec = 0
	spParams.DutyCyclePeriod = 10
	bt.sp = NewSpatialPooler(spParams)

	// Create a set of input vectors, x
	// B,C,D don't overlap at all with other patterns
	bt.x = make([][]bool, 5)
	for i := range bt.x {
		bt.x[i] = make([]bool, bt.sp.numInputs)
	}

	utils.FillSliceRangeBool(bt.x[0], true, 0, 20)
	utils.FillSliceRangeBool(bt.x[1], true, 10, 30)
	utils.FillSliceRangeBool(bt.x[2], true, 30, 50)
	utils.FillSliceRangeBool(bt.x[3], true, 50, 70)
	utils.FillSliceRangeBool(bt.x[4], true, 70, 90)
	// For each column, this will contain the last iteration number where that
	// column was a winner
	bt.winningIteration = make([]int, bt.sp.numColumns)

	// For each input vector i, lastSDR[i] contains the most recent SDR output
	// by the SP.
	bt.lastSDR = make([][]bool, 5)

	phase1(t, &bt)
	phase2(t, &bt)
	phase3(t, &bt)
	phase4(t, &bt)
}
Exemple #3
0
/*
	Decode an encoded sequence. Returns range of values
*/
func (se *ScalerEncoder) Decode(encoded []bool) []utils.TupleFloat {

	if !utils.AnyTrue(encoded) {
		return []utils.TupleFloat{}
	}

	tmpOutput := encoded[:se.N]

	// First, assume the input pool is not sampled 100%, and fill in the
	// "holes" in the encoded representation (which are likely to be present
	// if this is a coincidence that was learned by the SP).

	// Search for portions of the output that have "holes"
	maxZerosInARow := se.halfWidth

	for i := 0; i < maxZerosInARow; i++ {
		searchSeq := make([]bool, i+3)
		subLen := len(searchSeq)
		searchSeq[0] = true
		searchSeq[subLen-1] = true

		if se.Periodic {
			for j := 0; j < se.N; j++ {
				outputIndices := make([]int, subLen)

				for idx, _ := range outputIndices {
					outputIndices[idx] = (j + idx) % se.N
				}

				if utils.BoolEq(searchSeq, utils.SubsetSliceBool(tmpOutput, outputIndices)) {
					utils.SetIdxBool(tmpOutput, outputIndices, true)
				}
			}

		} else {

			for j := 0; j < se.N-subLen+1; j++ {
				if utils.BoolEq(searchSeq, tmpOutput[j:j+subLen]) {
					utils.FillSliceRangeBool(tmpOutput, true, j, subLen)
				}
			}

		}

	}

	if se.Verbosity >= 2 {
		fmt.Println("raw output:", utils.Bool2Int(encoded[:se.N]))
		fmt.Println("filtered output:", utils.Bool2Int(tmpOutput))
	}

	// ------------------------------------------------------------------------
	// Find each run of 1's in sequence

	nz := utils.OnIndices(tmpOutput)
	//key = start index, value = run length
	runs := make([]utils.TupleInt, 0, len(nz))

	runStart := -1
	runLen := 0

	for idx, val := range tmpOutput {
		if val {
			//increment or new idx
			if runStart == -1 {
				runStart = idx
				runLen = 0
			}
			runLen++
		} else {
			if runStart != -1 {
				runs = append(runs, utils.TupleInt{runStart, runLen})
				runStart = -1
			}

		}
	}

	if runStart != -1 {
		runs = append(runs, utils.TupleInt{runStart, runLen})
		runStart = -1
	}

	// If we have a periodic encoder, merge the first and last run if they
	// both go all the way to the edges
	if se.Periodic && len(runs) > 1 {
		if runs[0].A == 0 && runs[len(runs)-1].A+runs[len(runs)-1].B == se.N {
			runs[len(runs)-1].B += runs[0].B
			runs = runs[1:]
		}
	}

	// ------------------------------------------------------------------------
	// Now, for each group of 1's, determine the "left" and "right" edges, where
	// the "left" edge is inset by halfwidth and the "right" edge is inset by
	// halfwidth.
	// For a group of width w or less, the "left" and "right" edge are both at
	// the center position of the group.

	ranges := make([]utils.TupleFloat, 0, len(runs)+2)

	for _, val := range runs {
		var left, right int
		start := val.A
		length := val.B

		if length <= se.Width {
			right = start + length/2
			left = right
		} else {
			left = start + se.halfWidth
			right = start + length - 1 - se.halfWidth
		}

		var inMin, inMax float64

		// Convert to input space.
		if !se.Periodic {
			inMin = float64(left-se.padding)*se.Resolution + se.MinVal
			inMax = float64(right-se.padding)*se.Resolution + se.MinVal
		} else {
			inMin = float64(left-se.padding)*se.Range/float64(se.nInternal) + se.MinVal
			inMax = float64(right-se.padding)*se.Range/float64(se.nInternal) + se.MinVal
		}

		// Handle wrap-around if periodic
		if se.Periodic {
			if inMin >= se.MaxVal {
				inMin -= se.Range
				inMax -= se.Range
			}
		}

		// Clip low end
		if inMin < se.MinVal {
			inMin = se.MinVal
		}
		if inMax < se.MinVal {
			inMax = se.MinVal
		}

		// If we have a periodic encoder, and the max is past the edge, break into
		// 2 separate ranges

		if se.Periodic && inMax >= se.MaxVal {
			ranges = append(ranges, utils.TupleFloat{inMin, se.MaxVal})
			ranges = append(ranges, utils.TupleFloat{se.MinVal, inMax - se.Range})
		} else {
			//clip high end
			if inMax > se.MaxVal {
				inMax = se.MaxVal
			}
			if inMin > se.MaxVal {
				inMin = se.MaxVal
			}
			ranges = append(ranges, utils.TupleFloat{inMin, inMax})
		}
	}

	//desc := se.generateRangeDescription(ranges)

	return ranges
}