<EOL>self.segmentUpdates = {}<EOL>self.resetStats()<EOL>self._prevInfPatterns = []<EOL>self._prevLrnPatterns = []<EOL>stateShape = (self.numberOfCols, self.cellsPerColumn)<EOL>self.lrnActiveState = {}<EOL>self.lrnActiveState["<STR_LIT:t>"] = numpy.zeros(stateShape, dtype="<STR_LIT>")<EOL>self.lrnActiveState["<STR_LIT>"] = numpy.zeros(stateShape, dtype="<STR_LIT>")<EOL>self.lrnPredictedState = {}<EOL>self.lrnPredictedState["<STR_LIT:t>"] = numpy.zeros(stateShape, dtype="<STR_LIT>")<EOL>self.lrnPredictedState["<STR_LIT>"] = numpy.zeros(stateShape, dtype="<STR_LIT>")<EOL>self.infActiveState = {}<EOL>self.infActiveState["<STR_LIT:t>"] = numpy.zeros(stateShape, dtype="<STR_LIT>")<EOL>self.infActiveState["<STR_LIT>"] = numpy.zeros(stateShape, dtype="<STR_LIT>")<EOL>self.infActiveState["<STR_LIT>"] = numpy.zeros(stateShape, dtype="<STR_LIT>")<EOL>self.infActiveState["<STR_LIT>"] = numpy.zeros(stateShape, dtype="<STR_LIT>")<EOL>self.infPredictedState = {}<EOL>self.infPredictedState["<STR_LIT:t>"] = numpy.zeros(stateShape, dtype="<STR_LIT>")<EOL>self.infPredictedState["<STR_LIT>"] = numpy.zeros(stateShape, dtype="<STR_LIT>")<EOL>self.infPredictedState["<STR_LIT>"] = numpy.zeros(stateShape, dtype="<STR_LIT>")<EOL>self.infPredictedState["<STR_LIT>"] = numpy.zeros(stateShape, dtype="<STR_LIT>")<EOL>self.cellConfidence = {}<EOL>self.cellConfidence["<STR_LIT:t>"] = numpy.zeros(stateShape, dtype="<STR_LIT>")<EOL>self.cellConfidence["<STR_LIT>"] = numpy.zeros(stateShape, dtype="<STR_LIT>")<EOL>self.cellConfidence["<STR_LIT>"] = numpy.zeros(stateShape, dtype="<STR_LIT>")<EOL>self.colConfidence = {}<EOL>self.colConfidence["<STR_LIT:t>"] = numpy.zeros(self.numberOfCols, dtype="<STR_LIT>")<EOL>self.colConfidence["<STR_LIT>"] = numpy.zeros(self.numberOfCols, dtype="<STR_LIT>")<EOL>self.colConfidence["<STR_LIT>"] = numpy.zeros(self.numberOfCols,<EOL>dtype="<STR_LIT>")<EOL>


state = self.__dict__.copy()<EOL>for ephemeralMemberName in self._getEphemeralMembers():<EOL><INDENT>state.pop(ephemeralMemberName, None)<EOL><DEDENT>state['<STR_LIT>'] = self._getRandomState()<EOL>state['<STR_LIT:version>'] = TM_VERSION<EOL>return state<EOL>

@internal
        Return serializable state.  This function will return a version of the
        __dict__ with all "ephemeral" members stripped out.  "Ephemeral" members
        are defined as those that do not need to be (nor should be) stored
        in any kind of persistent file (e.g., NuPIC network XML file.)


self._setRandomState(state['<STR_LIT>'])<EOL>del state['<STR_LIT>']<EOL>version = state.pop('<STR_LIT:version>')<EOL>assert version == TM_VERSION<EOL>self.__dict__.update(state)<EOL>

@internal
        Set the state of ourself from a serialized state.


proto.version = TM_VERSION<EOL>self._random.write(proto.random)<EOL>proto.numberOfCols = self.numberOfCols<EOL>proto.cellsPerColumn = self.cellsPerColumn<EOL>proto.initialPerm = float(self.initialPerm)<EOL>proto.connectedPerm = float(self.connectedPerm)<EOL>proto.minThreshold = self.minThreshold<EOL>proto.newSynapseCount = self.newSynapseCount<EOL>proto.permanenceInc = float(self.permanenceInc)<EOL>proto.permanenceDec = float(self.permanenceDec)<EOL>proto.permanenceMax = float(self.permanenceMax)<EOL>proto.globalDecay = float(self.globalDecay)<EOL>proto.activationThreshold = self.activationThreshold<EOL>proto.doPooling = self.doPooling<EOL>proto.segUpdateValidDuration = self.segUpdateValidDuration<EOL>proto.burnIn = self.burnIn<EOL>proto.collectStats = self.collectStats<EOL>proto.verbosity = self.verbosity<EOL>proto.pamLength = self.pamLength<EOL>proto.maxAge = self.maxAge<EOL>proto.maxInfBacktrack = self.maxInfBacktrack<EOL>proto.maxLrnBacktrack = self.maxLrnBacktrack<EOL>proto.maxSeqLength = self.maxSeqLength<EOL>proto.maxSegmentsPerCell = self.maxSegmentsPerCell<EOL>proto.maxSynapsesPerSegment = self.maxSynapsesPerSegment<EOL>proto.outputType = self.outputType<EOL>proto.activeColumns = self.activeColumns<EOL>cellListProto = proto.init("<STR_LIT>", len(self.cells))<EOL>for i, columnSegments in enumerate(self.cells):<EOL><INDENT>columnSegmentsProto = cellListProto.init(i, len(columnSegments))<EOL>for j, cellSegments in enumerate(columnSegments):<EOL><INDENT>cellSegmentsProto = columnSegmentsProto.init(j, len(cellSegments))<EOL>for k, segment in enumerate(cellSegments):<EOL><INDENT>segment.write(cellSegmentsProto[k])<EOL><DEDENT><DEDENT><DEDENT>proto.lrnIterationIdx = self.lrnIterationIdx<EOL>proto.iterationIdx = self.iterationIdx<EOL>proto.segID = self.segID<EOL>if self.currentOutput is None:<EOL><INDENT>proto.currentOutput.none = None<EOL><DEDENT>else:<EOL><INDENT>proto.currentOutput.list = self.currentOutput.tolist()<EOL><DEDENT>proto.pamCounter = self.pamCounter<EOL>proto.collectSequenceStats = self.collectSequenceStats<EOL>proto.resetCalled = self.resetCalled<EOL>proto.avgInputDensity = self.avgInputDensity or -<NUM_LIT:1.0><EOL>proto.learnedSeqLength = self.learnedSeqLength<EOL>proto.avgLearnedSeqLength = self.avgLearnedSeqLength<EOL>proto.prevLrnPatterns = self._prevLrnPatterns<EOL>proto.prevInfPatterns = self._prevInfPatterns<EOL>segmentUpdatesListProto = proto.init("<STR_LIT>",<EOL>len(self.segmentUpdates))<EOL>for i, (key, updates) in enumerate(self.segmentUpdates.items()):<EOL><INDENT>cellSegmentUpdatesProto = segmentUpdatesListProto[i]<EOL>cellSegmentUpdatesProto.columnIdx = key[<NUM_LIT:0>]<EOL>cellSegmentUpdatesProto.cellIdx = key[<NUM_LIT:1>]<EOL>segmentUpdatesProto = cellSegmentUpdatesProto.init("<STR_LIT>",<EOL>len(updates))<EOL>for j, (lrnIterationIdx, segmentUpdate) in enumerate(updates):<EOL><INDENT>segmentUpdateWrapperProto = segmentUpdatesProto[j]<EOL>segmentUpdateWrapperProto.lrnIterationIdx = lrnIterationIdx<EOL>segmentUpdate.write(segmentUpdateWrapperProto.segmentUpdate)<EOL><DEDENT><DEDENT>proto.cellConfidenceT = self.cellConfidence["<STR_LIT:t>"].tolist()<EOL>proto.cellConfidenceT1 = self.cellConfidence["<STR_LIT>"].tolist()<EOL>proto.cellConfidenceCandidate = self.cellConfidence["<STR_LIT>"].tolist()<EOL>proto.colConfidenceT = self.colConfidence["<STR_LIT:t>"].tolist()<EOL>proto.colConfidenceT1 = self.colConfidence["<STR_LIT>"].tolist()<EOL>proto.colConfidenceCandidate = self.colConfidence["<STR_LIT>"].tolist()<EOL>proto.lrnActiveStateT = self.lrnActiveState["<STR_LIT:t>"].tolist()<EOL>proto.lrnActiveStateT1 = self.lrnActiveState["<STR_LIT>"].tolist()<EOL>proto.infActiveStateT = self.infActiveState["<STR_LIT:t>"].tolist()<EOL>proto.infActiveStateT1 = self.infActiveState["<STR_LIT>"].tolist()<EOL>proto.infActiveStateBackup = self.infActiveState["<STR_LIT>"].tolist()<EOL>proto.infActiveStateCandidate = self.infActiveState["<STR_LIT>"].tolist()<EOL>proto.lrnPredictedStateT = self.lrnPredictedState["<STR_LIT:t>"].tolist()<EOL>proto.lrnPredictedStateT1 = self.lrnPredictedState["<STR_LIT>"].tolist()<EOL>proto.infPredictedStateT = self.infPredictedState["<STR_LIT:t>"].tolist()<EOL>proto.infPredictedStateT1 = self.infPredictedState["<STR_LIT>"].tolist()<EOL>proto.infPredictedStateBackup = self.infPredictedState["<STR_LIT>"].tolist()<EOL>proto.infPredictedStateCandidate = self.infPredictedState["<STR_LIT>"].tolist()<EOL>proto.consolePrinterVerbosity = self.consolePrinterVerbosity<EOL>

Populate serialization proto instance.

        :param proto: (BacktrackingTMProto) the proto instance to populate


assert proto.version == TM_VERSION<EOL>obj = object.__new__(cls)<EOL>obj._random = Random()<EOL>obj._random.read(proto.random)<EOL>obj.numberOfCols = int(proto.numberOfCols)<EOL>obj.cellsPerColumn = int(proto.cellsPerColumn)<EOL>obj._numberOfCells = obj.numberOfCols * obj.cellsPerColumn<EOL>obj.initialPerm = numpy.float32(proto.initialPerm)<EOL>obj.connectedPerm = numpy.float32(proto.connectedPerm)<EOL>obj.minThreshold = int(proto.minThreshold)<EOL>obj.newSynapseCount = int(proto.newSynapseCount)<EOL>obj.permanenceInc = numpy.float32(proto.permanenceInc)<EOL>obj.permanenceDec = numpy.float32(proto.permanenceDec)<EOL>obj.permanenceMax = numpy.float32(proto.permanenceMax)<EOL>obj.globalDecay = numpy.float32(proto.globalDecay)<EOL>obj.activationThreshold = int(proto.activationThreshold)<EOL>obj.doPooling = proto.doPooling<EOL>obj.segUpdateValidDuration = int(proto.segUpdateValidDuration)<EOL>obj.burnIn = int(proto.burnIn)<EOL>obj.collectStats = proto.collectStats<EOL>obj.verbosity = int(proto.verbosity)<EOL>obj.pamLength = int(proto.pamLength)<EOL>obj.maxAge = int(proto.maxAge)<EOL>obj.maxInfBacktrack = int(proto.maxInfBacktrack)<EOL>obj.maxLrnBacktrack = int(proto.maxLrnBacktrack)<EOL>obj.maxSeqLength = int(proto.maxSeqLength)<EOL>obj.maxSegmentsPerCell = proto.maxSegmentsPerCell<EOL>obj.maxSynapsesPerSegment = proto.maxSynapsesPerSegment<EOL>obj.outputType = proto.outputType<EOL>obj.activeColumns = [int(col) for col in proto.activeColumns]<EOL>obj.cells = [[] for _ in range(len(proto.cells))]<EOL>for columnSegments, columnSegmentsProto in zip(obj.cells, proto.cells):<EOL><INDENT>columnSegments.extend([[] for _ in range(len(columnSegmentsProto))])<EOL>for cellSegments, cellSegmentsProto in zip(columnSegments,<EOL>columnSegmentsProto):<EOL><INDENT>for segmentProto in cellSegmentsProto:<EOL><INDENT>segment = Segment.read(segmentProto, obj)<EOL>cellSegments.append(segment)<EOL><DEDENT><DEDENT><DEDENT>obj.lrnIterationIdx = int(proto.lrnIterationIdx)<EOL>obj.iterationIdx = int(proto.iterationIdx)<EOL>obj.segID = int(proto.segID)<EOL>obj.pamCounter = int(proto.pamCounter)<EOL>obj.collectSequenceStats = proto.collectSequenceStats<EOL>obj.resetCalled = proto.resetCalled<EOL>avgInputDensity = proto.avgInputDensity<EOL>if avgInputDensity < <NUM_LIT:0.0>:<EOL><INDENT>obj.avgInputDensity = None<EOL><DEDENT>else:<EOL><INDENT>obj.avgInputDensity = avgInputDensity<EOL><DEDENT>obj.learnedSeqLength = int(proto.learnedSeqLength)<EOL>obj.avgLearnedSeqLength = proto.avgLearnedSeqLength<EOL>obj._initEphemerals()<EOL>if proto.currentOutput.which() == "<STR_LIT:none>":<EOL><INDENT>obj.currentOutput = None<EOL><DEDENT>else:<EOL><INDENT>obj.currentOutput = numpy.array(proto.currentOutput.list,<EOL>dtype='<STR_LIT>')<EOL><DEDENT>for pattern in proto.prevLrnPatterns:<EOL><INDENT>obj.prevLrnPatterns.append([v for v in pattern])<EOL><DEDENT>for pattern in proto.prevInfPatterns:<EOL><INDENT>obj.prevInfPatterns.append([v for v in pattern])<EOL><DEDENT>for cellWrapperProto in proto.segmentUpdates:<EOL><INDENT>key = (cellWrapperProto.columnIdx, cellWrapperProto.cellIdx)<EOL>value = []<EOL>for updateWrapperProto in cellWrapperProto.segmentUpdates:<EOL><INDENT>segmentUpdate = SegmentUpdate.read(updateWrapperProto.segmentUpdate, obj)<EOL>value.append((int(updateWrapperProto.lrnIterationIdx), segmentUpdate))<EOL><DEDENT>obj.segmentUpdates[key] = value<EOL><DEDENT>numpy.copyto(obj.cellConfidence["<STR_LIT:t>"], proto.cellConfidenceT)<EOL>numpy.copyto(obj.cellConfidence["<STR_LIT>"], proto.cellConfidenceT1)<EOL>numpy.copyto(obj.cellConfidence["<STR_LIT>"],<EOL>proto.cellConfidenceCandidate)<EOL>numpy.copyto(obj.colConfidence["<STR_LIT:t>"], proto.colConfidenceT)<EOL>numpy.copyto(obj.colConfidence["<STR_LIT>"], proto.colConfidenceT1)<EOL>numpy.copyto(obj.colConfidence["<STR_LIT>"], proto.colConfidenceCandidate)<EOL>numpy.copyto(obj.lrnActiveState["<STR_LIT:t>"], proto.lrnActiveStateT)<EOL>numpy.copyto(obj.lrnActiveState["<STR_LIT>"], proto.lrnActiveStateT1)<EOL>numpy.copyto(obj.infActiveState["<STR_LIT:t>"], proto.infActiveStateT)<EOL>numpy.copyto(obj.infActiveState["<STR_LIT>"], proto.infActiveStateT1)<EOL>numpy.copyto(obj.infActiveState["<STR_LIT>"], proto.infActiveStateBackup)<EOL>numpy.copyto(obj.infActiveState["<STR_LIT>"],<EOL>proto.infActiveStateCandidate)<EOL>numpy.copyto(obj.lrnPredictedState["<STR_LIT:t>"], proto.lrnPredictedStateT)<EOL>numpy.copyto(obj.lrnPredictedState["<STR_LIT>"], proto.lrnPredictedStateT1)<EOL>numpy.copyto(obj.infPredictedState["<STR_LIT:t>"], proto.infPredictedStateT)<EOL>numpy.copyto(obj.infPredictedState["<STR_LIT>"], proto.infPredictedStateT1)<EOL>numpy.copyto(obj.infPredictedState["<STR_LIT>"],<EOL>proto.infPredictedStateBackup)<EOL>numpy.copyto(obj.infPredictedState["<STR_LIT>"],<EOL>proto.infPredictedStateCandidate)<EOL>obj.consolePrinterVerbosity = int(proto.consolePrinterVerbosity)<EOL>return obj<EOL>

Deserialize from proto instance.

        :param proto: (BacktrackingTMProto) the proto instance to read from


try:<EOL><INDENT>return super(BacktrackingTM, self).__getattr__(name)<EOL><DEDENT>except AttributeError:<EOL><INDENT>raise AttributeError("<STR_LIT>" % name)<EOL><DEDENT>

@internal
        Patch __getattr__ so that we can catch the first access to 'cells' and load.

        This function is only called when we try to access an attribute that doesn't
        exist.  We purposely make sure that "self.cells" doesn't exist after
        unpickling so that we'll hit this, then we can load it on the first access.

        If this is called at any other time, it will raise an AttributeError.
        That's because:
        - If 'name' is "cells", after the first call, self._realCells won't exist
          so we'll get an implicit AttributeError.
        - If 'name' isn't "cells", I'd expect our super wouldn't have __getattr__,
          so we'll raise our own Attribute error.  If the super did get __getattr__,
          we'll just return what it gives us.


pass<EOL>


return pickle.dumps(self._random)<EOL>

@internal
        Return the random number state.

        This is used during unit testing to generate repeatable results.


self._random = pickle.loads(state)<EOL>

@internal Set the random number state.

        This is used during unit testing to generate repeatable results.


if self.verbosity >= <NUM_LIT:3>:<EOL><INDENT>print("<STR_LIT>")<EOL><DEDENT>self.lrnActiveState['<STR_LIT>'].fill(<NUM_LIT:0>)<EOL>self.lrnActiveState['<STR_LIT:t>'].fill(<NUM_LIT:0>)<EOL>self.lrnPredictedState['<STR_LIT>'].fill(<NUM_LIT:0>)<EOL>self.lrnPredictedState['<STR_LIT:t>'].fill(<NUM_LIT:0>)<EOL>self.infActiveState['<STR_LIT>'].fill(<NUM_LIT:0>)<EOL>self.infActiveState['<STR_LIT:t>'].fill(<NUM_LIT:0>)<EOL>self.infPredictedState['<STR_LIT>'].fill(<NUM_LIT:0>)<EOL>self.infPredictedState['<STR_LIT:t>'].fill(<NUM_LIT:0>)<EOL>self.cellConfidence['<STR_LIT>'].fill(<NUM_LIT:0>)<EOL>self.cellConfidence['<STR_LIT:t>'].fill(<NUM_LIT:0>)<EOL>self.segmentUpdates = {}<EOL>self._internalStats['<STR_LIT>'] = <NUM_LIT:0><EOL>self._internalStats['<STR_LIT>'] = <NUM_LIT:0><EOL>self._internalStats['<STR_LIT>']   = <NUM_LIT:0><EOL>self._internalStats['<STR_LIT>'] = <NUM_LIT:0><EOL>self._internalStats['<STR_LIT>'] = <NUM_LIT:0><EOL>self._internalStats['<STR_LIT>'] = <NUM_LIT:0><EOL>self._internalStats['<STR_LIT>'] = <NUM_LIT:0><EOL>self._internalStats['<STR_LIT>'] = None<EOL>if self.collectSequenceStats:<EOL><INDENT>if self._internalStats['<STR_LIT>'].sum() > <NUM_LIT:0>:<EOL><INDENT>sig = self._internalStats['<STR_LIT>'].copy()<EOL>sig.reshape(self.numberOfCols * self.cellsPerColumn)<EOL>self._internalStats['<STR_LIT>'] = sig<EOL><DEDENT>self._internalStats['<STR_LIT>'].fill(<NUM_LIT:0>)<EOL><DEDENT>self.resetCalled = True<EOL>self._prevInfPatterns = []<EOL>self._prevLrnPatterns = []<EOL>

Reset the state of all cells.

This is normally used between sequences while training. All internal states
are reset to 0.


self._stats = dict()<EOL>self._internalStats = dict()<EOL>self._internalStats['<STR_LIT>'] = <NUM_LIT:0><EOL>self._internalStats['<STR_LIT>'] = <NUM_LIT:0><EOL>self._internalStats['<STR_LIT>']      = <NUM_LIT:0><EOL>self._internalStats['<STR_LIT>']     = <NUM_LIT:0><EOL>self._internalStats['<STR_LIT>']   = <NUM_LIT:0><EOL>self._internalStats['<STR_LIT>']   = <NUM_LIT:0><EOL>self._internalStats['<STR_LIT>'] = <NUM_LIT:0><EOL>self._internalStats['<STR_LIT>']   = <NUM_LIT:0><EOL>self._internalStats['<STR_LIT>'] = <NUM_LIT:0><EOL>self._internalStats['<STR_LIT>'] = <NUM_LIT:0><EOL>self._internalStats['<STR_LIT>'] = <NUM_LIT:0><EOL>self._internalStats['<STR_LIT>'] = <NUM_LIT:0><EOL>self._internalStats['<STR_LIT>'] = <NUM_LIT:0><EOL>self._internalStats['<STR_LIT>'] = <NUM_LIT:0><EOL>self._internalStats['<STR_LIT>'] = <NUM_LIT:0><EOL>self._internalStats['<STR_LIT>'] = None<EOL>if self.collectSequenceStats:<EOL><INDENT>self._internalStats['<STR_LIT>'] = (<EOL>numpy.zeros((self.numberOfCols, self.cellsPerColumn),<EOL>dtype="<STR_LIT>"))<EOL><DEDENT>

Reset the learning and inference stats. This will usually be called by
user code at the start of each inference run (for a particular data set).


if not self.collectStats:<EOL><INDENT>return None<EOL><DEDENT>self._stats['<STR_LIT>'] = self._internalStats['<STR_LIT>']<EOL>self._stats['<STR_LIT>'] = self._internalStats['<STR_LIT>']<EOL>self._stats['<STR_LIT>'] = self._internalStats['<STR_LIT>']<EOL>self._stats['<STR_LIT>'] = self._internalStats['<STR_LIT>']<EOL>self._stats['<STR_LIT>'] = self._internalStats['<STR_LIT>']<EOL>nPredictions = max(<NUM_LIT:1>, self._stats['<STR_LIT>'])<EOL>self._stats['<STR_LIT>'] = (<EOL>self._internalStats['<STR_LIT>'])<EOL>self._stats['<STR_LIT>'] = (<EOL>self._internalStats['<STR_LIT>'] / nPredictions)<EOL>self._stats['<STR_LIT>'] = (<EOL>self._internalStats['<STR_LIT>'])<EOL>self._stats['<STR_LIT>'] = (<EOL>self._internalStats['<STR_LIT>'] / nPredictions)<EOL>self._stats['<STR_LIT>'] = (<EOL>self._internalStats['<STR_LIT>'])<EOL>self._stats['<STR_LIT>'] = (<EOL>self._internalStats['<STR_LIT>'] / nPredictions)<EOL>self._stats['<STR_LIT>'] = (self._internalStats['<STR_LIT>'] /<EOL>nPredictions)<EOL>self._stats['<STR_LIT>'] = (self._internalStats['<STR_LIT>'] /<EOL>nPredictions)<EOL>self._stats['<STR_LIT>'] = (<EOL>self._internalStats['<STR_LIT>'])<EOL>return self._stats<EOL>

Return the current learning and inference stats. This returns a dict
containing all the learning and inference stats we have collected since the
last :meth:`resetStats` call. If :class:`BacktrackingTM` ``collectStats``
parameter is False, then None is returned.

:returns: (dict) The following keys are returned in the dict when
    ``collectStats`` is True:

      - ``nPredictions``: the number of predictions. This is the total
            number of inferences excluding burn-in and the last inference.
      - ``curPredictionScore``: the score for predicting the current input
            (predicted during the previous inference)
      - ``curMissing``: the number of bits in the current input that were
            not predicted to be on.
      - ``curExtra``: the number of bits in the predicted output that are
            not in the next input
      - ``predictionScoreTotal``: the sum of every prediction score to date
      - ``predictionScoreAvg``: ``predictionScoreTotal / nPredictions``
      - ``pctMissingTotal``: the total number of bits that were missed over
            all predictions
      - ``pctMissingAvg``: ``pctMissingTotal / nPredictions``
      - ``prevSequenceSignature``: signature for the sequence immediately
            preceding the last reset. 'None' if ``collectSequenceStats`` is
            False.


def _updateStatsInferEnd(self, stats, bottomUpNZ, predictedState,<EOL>colConfidence):

<EOL>if not self.collectStats:<EOL><INDENT>return<EOL><DEDENT>stats['<STR_LIT>'] += <NUM_LIT:1><EOL>(numExtra2, numMissing2, confidences2) = self._checkPrediction(<EOL>patternNZs=[bottomUpNZ], output=predictedState,<EOL>colConfidence=colConfidence)<EOL>predictionScore, positivePredictionScore, negativePredictionScore = (<EOL>confidences2[<NUM_LIT:0>])<EOL>stats['<STR_LIT>'] = float(predictionScore)<EOL>stats['<STR_LIT>'] = <NUM_LIT:1.0> - float(positivePredictionScore)<EOL>stats['<STR_LIT>'] = float(negativePredictionScore)<EOL>stats['<STR_LIT>'] = numMissing2<EOL>stats['<STR_LIT>'] = numExtra2<EOL>if stats['<STR_LIT>'] <= self.burnIn:<EOL><INDENT>return<EOL><DEDENT>stats['<STR_LIT>'] += <NUM_LIT:1><EOL>numExpected = max(<NUM_LIT:1.0>, float(len(bottomUpNZ)))<EOL>stats['<STR_LIT>'] += numMissing2<EOL>stats['<STR_LIT>'] += numExtra2<EOL>stats['<STR_LIT>'] += <NUM_LIT> * numExtra2 / numExpected<EOL>stats['<STR_LIT>'] += <NUM_LIT> * numMissing2 / numExpected<EOL>stats['<STR_LIT>'] += float(predictionScore)<EOL>stats['<STR_LIT>'] += <NUM_LIT:1.0> - float(positivePredictionScore)<EOL>stats['<STR_LIT>'] += float(negativePredictionScore)<EOL>if self.collectSequenceStats:<EOL><INDENT>cc = self.cellConfidence['<STR_LIT>'] * self.infActiveState['<STR_LIT:t>']<EOL>sconf = cc.sum(axis=<NUM_LIT:1>)<EOL>for c in range(self.numberOfCols):<EOL><INDENT>if sconf[c] > <NUM_LIT:0>:<EOL><INDENT>cc[c, :] /= sconf[c]<EOL><DEDENT><DEDENT>self._internalStats['<STR_LIT>'] += cc<EOL><DEDENT>

Called at the end of learning and inference, this routine will update
a number of stats in our _internalStats dictionary, including our computed
prediction score.

:param stats            internal stats dictionary
:param bottomUpNZ       list of the active bottom-up inputs
:param predictedState   The columns we predicted on the last time step (should
                        match the current bottomUpNZ in the best case)
:param colConfidence    Column confidences we determined on the last time step


def formatRow(var, i):<EOL><INDENT>s = '<STR_LIT>'<EOL>for c in range(self.numberOfCols):<EOL><INDENT>if c > <NUM_LIT:0> and c % <NUM_LIT:10> == <NUM_LIT:0>:<EOL><INDENT>s += '<STR_LIT:U+0020>'<EOL><DEDENT>s += str(var[c, i])<EOL><DEDENT>s += '<STR_LIT:U+0020>'<EOL>return s<EOL><DEDENT>for i in range(self.cellsPerColumn):<EOL><INDENT>print(formatRow(aState, i))<EOL><DEDENT>

Print an integer array that is the same shape as activeState.

:param aState: TODO: document


def printConfidence(self, aState, maxCols = <NUM_LIT:20>):

def formatFPRow(var, i):<EOL><INDENT>s = '<STR_LIT>'<EOL>for c in range(min(maxCols, self.numberOfCols)):<EOL><INDENT>if c > <NUM_LIT:0> and c % <NUM_LIT:10> == <NUM_LIT:0>:<EOL><INDENT>s += '<STR_LIT:U+0020>'<EOL><DEDENT>s += '<STR_LIT>' % var[c, i]<EOL><DEDENT>s += '<STR_LIT:U+0020>'<EOL>return s<EOL><DEDENT>for i in range(self.cellsPerColumn):<EOL><INDENT>print(formatFPRow(aState, i))<EOL><DEDENT>

Print a floating point array that is the same shape as activeState.

:param aState: TODO: document
:param maxCols: TODO: document


def printColConfidence(self, aState, maxCols = <NUM_LIT:20>):

def formatFPRow(var):<EOL><INDENT>s = '<STR_LIT>'<EOL>for c in range(min(maxCols, self.numberOfCols)):<EOL><INDENT>if c > <NUM_LIT:0> and c % <NUM_LIT:10> == <NUM_LIT:0>:<EOL><INDENT>s += '<STR_LIT:U+0020>'<EOL><DEDENT>s += '<STR_LIT>' % var[c]<EOL><DEDENT>s += '<STR_LIT:U+0020>'<EOL>return s<EOL><DEDENT>print(formatFPRow(aState))<EOL>

Print up to maxCols number from a flat floating point array.

:param aState: TODO: document
:param maxCols: TODO: document


def printStates(self, printPrevious = True, printLearnState = True):

def formatRow(var, i):<EOL><INDENT>s = '<STR_LIT>'<EOL>for c in range(self.numberOfCols):<EOL><INDENT>if c > <NUM_LIT:0> and c % <NUM_LIT:10> == <NUM_LIT:0>:<EOL><INDENT>s += '<STR_LIT:U+0020>'<EOL><DEDENT>s += str(var[c, i])<EOL><DEDENT>s += '<STR_LIT:U+0020>'<EOL>return s<EOL><DEDENT>print("<STR_LIT>")<EOL>for i in range(self.cellsPerColumn):<EOL><INDENT>if printPrevious:<EOL><INDENT>print(formatRow(self.infActiveState['<STR_LIT>'], i), end='<STR_LIT:U+0020>')<EOL><DEDENT>print(formatRow(self.infActiveState['<STR_LIT:t>'], i))<EOL><DEDENT>print("<STR_LIT>")<EOL>for i in range(self.cellsPerColumn):<EOL><INDENT>if printPrevious:<EOL><INDENT>print(formatRow(self.infPredictedState['<STR_LIT>'], i), end='<STR_LIT:U+0020>')<EOL><DEDENT>print(formatRow(self.infPredictedState['<STR_LIT:t>'], i))<EOL><DEDENT>if printLearnState:<EOL><INDENT>print("<STR_LIT>")<EOL>for i in range(self.cellsPerColumn):<EOL><INDENT>if printPrevious:<EOL><INDENT>print(formatRow(self.lrnActiveState['<STR_LIT>'], i), end='<STR_LIT:U+0020>')<EOL><DEDENT>print(formatRow(self.lrnActiveState['<STR_LIT:t>'], i))<EOL><DEDENT>print("<STR_LIT>")<EOL>for i in range(self.cellsPerColumn):<EOL><INDENT>if printPrevious:<EOL><INDENT>print(formatRow(self.lrnPredictedState['<STR_LIT>'], i), end='<STR_LIT:U+0020>')<EOL><DEDENT>print(formatRow(self.lrnPredictedState['<STR_LIT:t>'], i))<EOL><DEDENT><DEDENT>

TODO: document

:param printPrevious:
:param printLearnState:
:return:


print("<STR_LIT>")<EOL>for i in range(self.cellsPerColumn):<EOL><INDENT>for c in range(self.numberOfCols):<EOL><INDENT>print(int(y[c, i]), end='<STR_LIT:U+0020>')<EOL><DEDENT>print()<EOL><DEDENT>


print("<STR_LIT>")<EOL>for c in range(self.numberOfCols):<EOL><INDENT>print(int(x[c]), end='<STR_LIT:U+0020>')<EOL><DEDENT>print()<EOL>


print("<STR_LIT>", self.numberOfCols)<EOL>print("<STR_LIT>", self.cellsPerColumn)<EOL>print("<STR_LIT>", self.minThreshold)<EOL>print("<STR_LIT>", self.newSynapseCount)<EOL>print("<STR_LIT>", self.activationThreshold)<EOL>print()<EOL>print("<STR_LIT>", self.initialPerm)<EOL>print("<STR_LIT>", self.connectedPerm)<EOL>print("<STR_LIT>", self.permanenceInc)<EOL>print("<STR_LIT>", self.permanenceDec)<EOL>print("<STR_LIT>", self.permanenceMax)<EOL>print("<STR_LIT>", self.globalDecay)<EOL>print()<EOL>print("<STR_LIT>", self.doPooling)<EOL>print("<STR_LIT>", self.segUpdateValidDuration)<EOL>print("<STR_LIT>", self.pamLength)<EOL>

Print the parameter settings for the TM.


def printActiveIndices(self, state, andValues=False):

if len(state.shape) == <NUM_LIT:2>:<EOL><INDENT>(cols, cellIdxs) = state.nonzero()<EOL><DEDENT>else:<EOL><INDENT>cols = state.nonzero()[<NUM_LIT:0>]<EOL>cellIdxs = numpy.zeros(len(cols))<EOL><DEDENT>if len(cols) == <NUM_LIT:0>:<EOL><INDENT>print("<STR_LIT>")<EOL>return<EOL><DEDENT>prevCol = -<NUM_LIT:1><EOL>for (col, cellIdx) in zip(cols, cellIdxs):<EOL><INDENT>if col != prevCol:<EOL><INDENT>if prevCol != -<NUM_LIT:1>:<EOL><INDENT>print("<STR_LIT>", end='<STR_LIT:U+0020>')<EOL><DEDENT>print("<STR_LIT>" % (col), end='<STR_LIT:U+0020>')<EOL>prevCol = col<EOL><DEDENT>if andValues:<EOL><INDENT>if len(state.shape) == <NUM_LIT:2>:<EOL><INDENT>value = state[col, cellIdx]<EOL><DEDENT>else:<EOL><INDENT>value = state[col]<EOL><DEDENT>print("<STR_LIT>" % (cellIdx, value), end='<STR_LIT:U+0020>')<EOL><DEDENT>else:<EOL><INDENT>print("<STR_LIT>" % (cellIdx), end='<STR_LIT:U+0020>')<EOL><DEDENT><DEDENT>print("<STR_LIT:]>")<EOL>

Print the list of ``[column, cellIdx]`` indices for each of the active cells
in state.

:param state: TODO: document
:param andValues: TODO: document


def printComputeEnd(self, output, learn=False):

if self.verbosity >= <NUM_LIT:3>:<EOL><INDENT>print("<STR_LIT>")<EOL>print("<STR_LIT>", learn)<EOL>print("<STR_LIT>" % (<EOL>self.infActiveState['<STR_LIT:t>'].min(axis=<NUM_LIT:1>).sum()), end='<STR_LIT:U+0020>')<EOL>print("<STR_LIT>" % (<EOL>self._internalStats['<STR_LIT>']), end='<STR_LIT:U+0020>')<EOL>print("<STR_LIT>" % (<EOL>self._internalStats['<STR_LIT>']), end='<STR_LIT:U+0020>')<EOL>print("<STR_LIT>" % (<EOL><NUM_LIT:1> - self._internalStats['<STR_LIT>']))<EOL>print("<STR_LIT>", self.getNumSegments(), end='<STR_LIT:U+0020>')<EOL>print("<STR_LIT>", self.avgLearnedSeqLength)<EOL>print("<STR_LIT>" % (<EOL>self.infActiveState['<STR_LIT:t>'].sum()))<EOL>self.printActiveIndices(self.infActiveState['<STR_LIT:t>'])<EOL>if self.verbosity >= <NUM_LIT:6>:<EOL><INDENT>self.printState(self.infActiveState['<STR_LIT:t>'])<EOL><DEDENT>print("<STR_LIT>" % (<EOL>self.infPredictedState['<STR_LIT:t>'].sum()))<EOL>self.printActiveIndices(self.infPredictedState['<STR_LIT:t>'])<EOL>if self.verbosity >= <NUM_LIT:6>:<EOL><INDENT>self.printState(self.infPredictedState['<STR_LIT:t>'])<EOL><DEDENT>print("<STR_LIT>" % (<EOL>self.lrnActiveState['<STR_LIT:t>'].sum()))<EOL>self.printActiveIndices(self.lrnActiveState['<STR_LIT:t>'])<EOL>if self.verbosity >= <NUM_LIT:6>:<EOL><INDENT>self.printState(self.lrnActiveState['<STR_LIT:t>'])<EOL><DEDENT>print("<STR_LIT>" % (<EOL>self.lrnPredictedState['<STR_LIT:t>'].sum()))<EOL>self.printActiveIndices(self.lrnPredictedState['<STR_LIT:t>'])<EOL>if self.verbosity >= <NUM_LIT:6>:<EOL><INDENT>self.printState(self.lrnPredictedState['<STR_LIT:t>'])<EOL><DEDENT>print("<STR_LIT>")<EOL>self.printActiveIndices(self.cellConfidence['<STR_LIT:t>'], andValues=True)<EOL>if self.verbosity >= <NUM_LIT:6>:<EOL><INDENT>self.printConfidence(self.cellConfidence['<STR_LIT:t>'])<EOL><DEDENT>print("<STR_LIT>")<EOL>self.printActiveIndices(self.colConfidence['<STR_LIT:t>'], andValues=True)<EOL>print("<STR_LIT>")<EOL>cc = self.cellConfidence['<STR_LIT>'] * self.infActiveState['<STR_LIT:t>']<EOL>self.printActiveIndices(cc, andValues=True)<EOL>if self.verbosity == <NUM_LIT:4>:<EOL><INDENT>print("<STR_LIT>")<EOL>self.printCells(predictedOnly=True)<EOL><DEDENT>elif self.verbosity >= <NUM_LIT:5>:<EOL><INDENT>print("<STR_LIT>")<EOL>self.printCells(predictedOnly=False)<EOL><DEDENT>print()<EOL><DEDENT>elif self.verbosity >= <NUM_LIT:1>:<EOL><INDENT>print("<STR_LIT>", learn)<EOL>print("<STR_LIT>" % len(output.nonzero()[<NUM_LIT:0>]), end='<STR_LIT:U+0020>')<EOL>self.printActiveIndices(output.reshape(self.numberOfCols,<EOL>self.cellsPerColumn))<EOL><DEDENT>

Called at the end of inference to print out various diagnostic
information based on the current verbosity level.

:param output: TODO: document
:param learn: TODO: document


print("<STR_LIT>", len(self.segmentUpdates))<EOL>for key, updateList in self.segmentUpdates.items():<EOL><INDENT>c, i = key[<NUM_LIT:0>], key[<NUM_LIT:1>]<EOL>print(c, i, updateList)<EOL><DEDENT>


def printCell(self, c, i, onlyActiveSegments=False):

if len(self.cells[c][i]) > <NUM_LIT:0>:<EOL><INDENT>print("<STR_LIT>", c, "<STR_LIT>", i, "<STR_LIT::>", end='<STR_LIT:U+0020>')<EOL>print(len(self.cells[c][i]), "<STR_LIT>")<EOL>for j, s in enumerate(self.cells[c][i]):<EOL><INDENT>isActive = self._isSegmentActive(s, self.infActiveState['<STR_LIT:t>'])<EOL>if not onlyActiveSegments or isActive:<EOL><INDENT>isActiveStr = "<STR_LIT:*>" if isActive else "<STR_LIT:U+0020>"<EOL>print("<STR_LIT>" % (isActiveStr, j), end='<STR_LIT:U+0020>')<EOL>s.debugPrint()<EOL><DEDENT><DEDENT><DEDENT>

TODO: document

:param c:
:param i:
:param onlyActiveSegments:
:return:


if predictedOnly:<EOL><INDENT>print("<STR_LIT>")<EOL><DEDENT>else:<EOL><INDENT>print("<STR_LIT>")<EOL><DEDENT>print("<STR_LIT>", self.activationThreshold, end='<STR_LIT:U+0020>')<EOL>print("<STR_LIT>", self.minThreshold, end='<STR_LIT:U+0020>')<EOL>print("<STR_LIT>", self.connectedPerm)<EOL>for c in range(self.numberOfCols):<EOL><INDENT>for i in range(self.cellsPerColumn):<EOL><INDENT>if not predictedOnly or self.infPredictedState['<STR_LIT:t>'][c, i]:<EOL><INDENT>self.printCell(c, i, predictedOnly)<EOL><DEDENT><DEDENT><DEDENT>

TODO: document

:param predictedOnly:
:return:


return len(self.cells[c][i])<EOL>

:param c: (int) column index
:param i: (int) cell index within column
:returns: (int) the total number of synapses in cell (c, i)


nSyns = self.getSegmentInfo()[<NUM_LIT:1>]<EOL>return nSyns<EOL>

:returns: (int) the total number of synapses


return float(self.getNumSynapses()) / max(<NUM_LIT:1>, self.getNumSegments())<EOL>

:returns: (int) the average number of synapses per segment


nSegs = self.getSegmentInfo()[<NUM_LIT:0>]<EOL>return nSegs<EOL>

:returns: (int) the total number of segments


return self.numberOfCols * self.cellsPerColumn<EOL>

:returns: (int) the total number of cells


def getSegmentOnCell(self, c, i, segIdx):

seg = self.cells[c][i][segIdx]<EOL>retlist = [[seg.segID, seg.isSequenceSeg, seg.positiveActivations,<EOL>seg.totalActivations, seg.lastActiveIteration,<EOL>seg._lastPosDutyCycle, seg._lastPosDutyCycleIteration]]<EOL>retlist += seg.syns<EOL>return retlist<EOL>

:param c: (int) column index
:param i: (int) cell index in column
:param segIdx: (int) segment index to match

:returns: (list) representing the the segment on cell (c, i) with index
    ``segIdx``.
    ::

      [  [segmentID, sequenceSegmentFlag, positiveActivations,
          totalActivations, lastActiveIteration,
          lastPosDutyCycle, lastPosDutyCycleIteration],
         [col1, idx1, perm1],
         [col2, idx2, perm2], ...
      ]


def _addToSegmentUpdates(self, c, i, segUpdate):

<EOL>if segUpdate is None or len(segUpdate.activeSynapses) == <NUM_LIT:0>:<EOL><INDENT>return<EOL><DEDENT>key = (c, i) <EOL>if key in self.segmentUpdates:<EOL><INDENT>self.segmentUpdates[key] += [(self.lrnIterationIdx, segUpdate)]<EOL><DEDENT>else:<EOL><INDENT>self.segmentUpdates[key] = [(self.lrnIterationIdx, segUpdate)]<EOL><DEDENT>

Store a dated potential segment update. The "date" (iteration index) is used
later to determine whether the update is too old and should be forgotten.
This is controlled by parameter ``segUpdateValidDuration``.

:param c: TODO: document
:param i: TODO: document
:param segUpdate: TODO: document


<EOL>(creationDate, segUpdate) = updateInfo<EOL>key = (segUpdate.columnIdx, segUpdate.cellIdx)<EOL>self.segmentUpdates[key].remove(updateInfo)<EOL>

Remove a segment update (called when seg update expires or is processed)

:param updateInfo: (tuple) (creationDate, SegmentUpdate)


<EOL>if self.outputType == '<STR_LIT>':<EOL><INDENT>mostActiveCellPerCol = self.cellConfidence['<STR_LIT:t>'].argmax(axis=<NUM_LIT:1>)<EOL>self.currentOutput = numpy.zeros(self.infActiveState['<STR_LIT:t>'].shape,<EOL>dtype='<STR_LIT>')<EOL>numCols = self.currentOutput.shape[<NUM_LIT:0>]<EOL>self.currentOutput[(range(numCols), mostActiveCellPerCol)] = <NUM_LIT:1><EOL>activeCols = self.infActiveState['<STR_LIT:t>'].max(axis=<NUM_LIT:1>)<EOL>inactiveCols = numpy.where(activeCols==<NUM_LIT:0>)[<NUM_LIT:0>]<EOL>self.currentOutput[inactiveCols, :] = <NUM_LIT:0><EOL><DEDENT>elif self.outputType == '<STR_LIT>':<EOL><INDENT>self.currentOutput = self.infActiveState['<STR_LIT:t>']<EOL><DEDENT>elif self.outputType == '<STR_LIT>':<EOL><INDENT>self.currentOutput = numpy.logical_or(self.infPredictedState['<STR_LIT:t>'],<EOL>self.infActiveState['<STR_LIT:t>'])<EOL><DEDENT>else:<EOL><INDENT>raise RuntimeError("<STR_LIT>")<EOL><DEDENT>return self.currentOutput.reshape(-<NUM_LIT:1>).astype('<STR_LIT>')<EOL>

Computes output for both learning and inference. In both cases, the
output is the boolean OR of ``activeState`` and ``predictedState`` at ``t``.
Stores ``currentOutput`` for ``checkPrediction``.

:returns: TODO: document


<EOL>return self.infActiveState['<STR_LIT:t>'].reshape(-<NUM_LIT:1>).astype('<STR_LIT>')<EOL>

Return the current active state. This is called by the node to
obtain the sequence output of the TM.

:returns: TODO: document


return self.infPredictedState['<STR_LIT:t>']<EOL>

:returns: numpy array of predicted cells, representing the current predicted
  state. ``predictedCells[c][i]`` represents the state of the i'th cell in
  the c'th column.


<EOL>pristineTPDynamicState = self._getTPDynamicState()<EOL>assert (nSteps><NUM_LIT:0>)<EOL>multiStepColumnPredictions = numpy.zeros((nSteps, self.numberOfCols),<EOL>dtype="<STR_LIT>")<EOL>step = <NUM_LIT:0><EOL>while True:<EOL><INDENT>multiStepColumnPredictions[step, :] = self.topDownCompute()<EOL>if step == nSteps-<NUM_LIT:1>:<EOL><INDENT>break<EOL><DEDENT>step += <NUM_LIT:1><EOL>self.infActiveState['<STR_LIT>'][:, :] = self.infActiveState['<STR_LIT:t>'][:, :]<EOL>self.infPredictedState['<STR_LIT>'][:, :] = self.infPredictedState['<STR_LIT:t>'][:, :]<EOL>self.cellConfidence['<STR_LIT>'][:, :] = self.cellConfidence['<STR_LIT:t>'][:, :]<EOL>self.infActiveState['<STR_LIT:t>'][:, :] = self.infPredictedState['<STR_LIT>'][:, :]<EOL>self.infPredictedState['<STR_LIT:t>'].fill(<NUM_LIT:0>)<EOL>self.cellConfidence['<STR_LIT:t>'].fill(<NUM_LIT:0.0>)<EOL>self._inferPhase2()<EOL><DEDENT>self._setTPDynamicState(pristineTPDynamicState)<EOL>return multiStepColumnPredictions<EOL>

This function gives the future predictions for <nSteps> timesteps starting
from the current TM state. The TM is returned to its original state at the
end before returning.

1. We save the TM state.
2. Loop for nSteps

   a. Turn-on with lateral support from the current active cells
   b. Set the predicted cells as the next step's active cells. This step
      in learn and infer methods use input here to correct the predictions.
      We don't use any input here.

3. Revert back the TM state to the time before prediction

:param nSteps: (int) The number of future time steps to be predicted
:returns: all the future predictions - a numpy array of type "float32" and
      shape (nSteps, numberOfCols). The ith row gives the tm prediction for
      each column at a future timestep (t+i+1).


return ["<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>]<EOL>

Any newly added dynamic states in the TM should be added to this list.

Parameters:
--------------------------------------------
retval:       The list of names of TM dynamic state variables.


tpDynamicState = dict()<EOL>for variableName in self._getTPDynamicStateVariableNames():<EOL><INDENT>tpDynamicState[variableName] = copy.deepcopy(self.__dict__[variableName])<EOL><DEDENT>return tpDynamicState<EOL>

Parameters:
--------------------------------------------
retval:       A dict with all the dynamic state variable names as keys and
              their values at this instant as values.


for variableName in self._getTPDynamicStateVariableNames():<EOL><INDENT>self.__dict__[variableName] = tpDynamicState.pop(variableName)<EOL><DEDENT>

Set all the dynamic state variables from the <tpDynamicState> dict.

<tpDynamicState> dict has all the dynamic state variable names as keys and
their values at this instant as values.

We set the dynamic state variables in the tm object with these items.


if self.lrnIterationIdx < <NUM_LIT:100>:<EOL><INDENT>alpha = <NUM_LIT:0.5><EOL><DEDENT>else:<EOL><INDENT>alpha = <NUM_LIT:0.1><EOL><DEDENT>self.avgLearnedSeqLength = ((<NUM_LIT:1.0> - alpha) * self.avgLearnedSeqLength +<EOL>(alpha * prevSeqLength))<EOL>

Update our moving average of learned sequence length.


return self.avgLearnedSeqLength<EOL>

:returns: Moving average of learned sequence length


<EOL>numPrevPatterns = len(self._prevInfPatterns)<EOL>if numPrevPatterns <= <NUM_LIT:0>:<EOL><INDENT>return<EOL><DEDENT>currentTimeStepsOffset = numPrevPatterns - <NUM_LIT:1><EOL>self.infActiveState['<STR_LIT>'][:, :] = self.infActiveState['<STR_LIT:t>'][:, :]<EOL>self.infPredictedState['<STR_LIT>'][:, :] = self.infPredictedState['<STR_LIT>'][:, :]<EOL>badPatterns = []<EOL>inSequence = False<EOL>candConfidence = None<EOL>candStartOffset = None<EOL>for startOffset in range(<NUM_LIT:0>, numPrevPatterns):<EOL><INDENT>if startOffset == currentTimeStepsOffset and candConfidence is not None:<EOL><INDENT>break<EOL><DEDENT>if self.verbosity >= <NUM_LIT:3>:<EOL><INDENT>print((<EOL>"<STR_LIT>" % (<EOL>numPrevPatterns - <NUM_LIT:1> - startOffset),<EOL>self._prevInfPatterns[startOffset]))<EOL><DEDENT>inSequence = False<EOL>for offset in range(startOffset, numPrevPatterns):<EOL><INDENT>if offset == currentTimeStepsOffset:<EOL><INDENT>totalConfidence = self.colConfidence['<STR_LIT:t>'][activeColumns].sum()<EOL><DEDENT>self.infPredictedState['<STR_LIT>'][:, :] = self.infPredictedState['<STR_LIT:t>'][:, :]<EOL>inSequence = self._inferPhase1(self._prevInfPatterns[offset],<EOL>useStartCells = (offset == startOffset))<EOL>if not inSequence:<EOL><INDENT>break<EOL><DEDENT>if self.verbosity >= <NUM_LIT:3>:<EOL><INDENT>print(("<STR_LIT>",<EOL>self._prevInfPatterns[offset]))<EOL><DEDENT>inSequence = self._inferPhase2()<EOL>if not inSequence:<EOL><INDENT>break<EOL><DEDENT><DEDENT>if not inSequence:<EOL><INDENT>badPatterns.append(startOffset)<EOL>continue<EOL><DEDENT>candConfidence = totalConfidence<EOL>candStartOffset = startOffset<EOL>if self.verbosity >= <NUM_LIT:3> and startOffset != currentTimeStepsOffset:<EOL><INDENT>print(("<STR_LIT>"<EOL>"<STR_LIT>" % (numPrevPatterns - <NUM_LIT:1> - startOffset),<EOL>totalConfidence))<EOL><DEDENT>if candStartOffset == currentTimeStepsOffset:  <EOL><INDENT>break<EOL><DEDENT>self.infActiveState['<STR_LIT>'][:, :] = self.infActiveState['<STR_LIT:t>'][:, :]<EOL>self.infPredictedState['<STR_LIT>'][:, :] = (<EOL>self.infPredictedState['<STR_LIT:t>'][:, :])<EOL>self.cellConfidence['<STR_LIT>'][:, :] = self.cellConfidence['<STR_LIT:t>'][:, :]<EOL>self.colConfidence['<STR_LIT>'][:] = self.colConfidence['<STR_LIT:t>'][:]<EOL>break<EOL><DEDENT>if candStartOffset is None:<EOL><INDENT>if self.verbosity >= <NUM_LIT:3>:<EOL><INDENT>print("<STR_LIT>")<EOL><DEDENT>self.infActiveState['<STR_LIT:t>'][:, :] = self.infActiveState['<STR_LIT>'][:, :]<EOL>self._inferPhase2()<EOL><DEDENT>else:<EOL><INDENT>if self.verbosity >= <NUM_LIT:3>:<EOL><INDENT>print(("<STR_LIT>"<EOL>"<STR_LIT>" % (numPrevPatterns - <NUM_LIT:1> - candStartOffset),<EOL>self._prevInfPatterns[candStartOffset]))<EOL><DEDENT>if candStartOffset != currentTimeStepsOffset:<EOL><INDENT>self.infActiveState['<STR_LIT:t>'][:, :] = self.infActiveState['<STR_LIT>'][:, :]<EOL>self.infPredictedState['<STR_LIT:t>'][:, :] = (<EOL>self.infPredictedState['<STR_LIT>'][:, :])<EOL>self.cellConfidence['<STR_LIT:t>'][:, :] = self.cellConfidence['<STR_LIT>'][:, :]<EOL>self.colConfidence['<STR_LIT:t>'][:] = self.colConfidence['<STR_LIT>'][:]<EOL><DEDENT><DEDENT>for i in range(numPrevPatterns):<EOL><INDENT>if (i in badPatterns or<EOL>(candStartOffset is not None and i <= candStartOffset)):<EOL><INDENT>if self.verbosity >= <NUM_LIT:3>:<EOL><INDENT>print(("<STR_LIT>",<EOL>self._prevInfPatterns[<NUM_LIT:0>]))<EOL><DEDENT>self._prevInfPatterns.pop(<NUM_LIT:0>)<EOL><DEDENT>else:<EOL><INDENT>break<EOL><DEDENT><DEDENT>self.infPredictedState['<STR_LIT>'][:, :] = self.infPredictedState['<STR_LIT>'][:, :]<EOL>

This "backtracks" our inference state, trying to see if we can lock onto
the current set of inputs by assuming the sequence started up to N steps
ago on start cells.

This will adjust @ref infActiveState['t'] if it does manage to lock on to a
sequence that started earlier. It will also compute infPredictedState['t']
based on the possibly updated @ref infActiveState['t'], so there is no need to
call inferPhase2() after calling inferBacktrack().

This looks at:
    - ``infActiveState['t']``

This updates/modifies:
    - ``infActiveState['t']``
    - ``infPredictedState['t']``
    - ``colConfidence['t']``
    - ``cellConfidence['t']``

How it works:

This method gets called from :meth:`updateInferenceState` when we detect
either of the following two conditions:

#. The current bottom-up input had too many un-expected columns
#. We fail to generate a sufficient number of predicted columns for the
   next time step.

Either of these two conditions indicate that we have fallen out of a
learned sequence.

Rather than simply "giving up" and bursting on the unexpected input
columns, a better approach is to see if perhaps we are in a sequence that
started a few steps ago. The real world analogy is that you are driving
along and suddenly hit a dead-end, you will typically go back a few turns
ago and pick up again from a familiar intersection.

This back-tracking goes hand in hand with our learning methodology, which
always tries to learn again from start cells after it loses context. This
results in a network that has learned multiple, overlapping paths through
the input data, each starting at different points. The lower the global
decay and the more repeatability in the data, the longer each of these
paths will end up being.

The goal of this function is to find out which starting point in the past
leads to the current input with the most context as possible. This gives us
the best chance of predicting accurately going forward. Consider the
following example, where you have learned the following sub-sequences which
have the given frequencies:

::

              ? - Q - C - D - E      10X      seq 0
              ? - B - C - D - F      1X       seq 1
              ? - B - C - H - I      2X       seq 2
              ? - B - C - D - F      3X       seq 3
      ? - Z - A - B - C - D - J      2X       seq 4
      ? - Z - A - B - C - H - I      1X       seq 5
      ? - Y - A - B - C - D - F      3X       seq 6

    ----------------------------------------
  W - X - Z - A - B - C - D          <= input history
                          ^
                          current time step

Suppose, in the current time step, the input pattern is D and you have not
predicted D, so you need to backtrack. Suppose we can backtrack up to 6
steps in the past, which path should we choose? From the table above, we can
see that the correct answer is to assume we are in seq 4. How do we
implement the backtrack to give us this right answer? The current
implementation takes the following approach:

#. Start from the farthest point in the past.
#. For each starting point S, calculate the confidence of the current
   input, conf(startingPoint=S), assuming we followed that sequence.
   Note that we must have learned at least one sequence that starts at
   point S.
#. If conf(startingPoint=S) is significantly different from
   conf(startingPoint=S-1), then choose S-1 as the starting point.

The assumption here is that starting point S-1 is the starting point of
a learned sub-sequence that includes the current input in it's path and
that started the longest ago. It thus has the most context and will be
the best predictor going forward.

From the statistics in the above table, we can compute what the confidences
will be for each possible starting point:

::

  startingPoint           confidence of D
  -----------------------------------------
  B (t-2)               4/6  = 0.667   (seq 1,3)/(seq 1,2,3)
  Z (t-4)               2/3  = 0.667   (seq 4)/(seq 4,5)

First of all, we do not compute any confidences at starting points t-1, t-3,
t-5, t-6 because there are no learned sequences that start at those points.

Notice here that Z is the starting point of the longest sub-sequence leading
up to the current input. Event though starting at t-2 and starting at t-4
give the same confidence value, we choose the sequence starting at t-4
because it gives the most context, and it mirrors the way that learning
extends sequences.

:param activeColumns: (list) of active column indices


def _inferPhase1(self, activeColumns, useStartCells):

<EOL>self.infActiveState['<STR_LIT:t>'].fill(<NUM_LIT:0>)<EOL>numPredictedColumns = <NUM_LIT:0><EOL>if useStartCells:<EOL><INDENT>for c in activeColumns:<EOL><INDENT>self.infActiveState['<STR_LIT:t>'][c, <NUM_LIT:0>] = <NUM_LIT:1><EOL><DEDENT><DEDENT>else:<EOL><INDENT>for c in activeColumns:<EOL><INDENT>predictingCells = numpy.where(self.infPredictedState['<STR_LIT>'][c] == <NUM_LIT:1>)[<NUM_LIT:0>]<EOL>numPredictingCells = len(predictingCells)<EOL>if numPredictingCells > <NUM_LIT:0>:<EOL><INDENT>self.infActiveState['<STR_LIT:t>'][c, predictingCells] = <NUM_LIT:1><EOL>numPredictedColumns += <NUM_LIT:1><EOL><DEDENT>else:<EOL><INDENT>self.infActiveState['<STR_LIT:t>'][c, :] = <NUM_LIT:1> <EOL><DEDENT><DEDENT><DEDENT>if useStartCells or numPredictedColumns >= <NUM_LIT> * len(activeColumns):<EOL><INDENT>return True<EOL><DEDENT>else:<EOL><INDENT>return False<EOL><DEDENT>

Update the inference active state from the last set of predictions
and the current bottom-up.

This looks at:
    - ``infPredictedState['t-1']``
This modifies:
    - ``infActiveState['t']``

:param activeColumns: (list) active bottom-ups
:param useStartCells: (bool) If true, ignore previous predictions and simply
       turn on the start cells in the active columns
:returns: (bool) True if the current input was sufficiently predicted, OR if
       we started over on startCells. False indicates that the current input
       was NOT predicted, and we are now bursting on most columns.


<EOL>self.infPredictedState['<STR_LIT:t>'].fill(<NUM_LIT:0>)<EOL>self.cellConfidence['<STR_LIT:t>'].fill(<NUM_LIT:0>)<EOL>self.colConfidence['<STR_LIT:t>'].fill(<NUM_LIT:0>)<EOL>for c in range(self.numberOfCols):<EOL><INDENT>for i in range(self.cellsPerColumn):<EOL><INDENT>for s in self.cells[c][i]:<EOL><INDENT>numActiveSyns = self._getSegmentActivityLevel(<EOL>s, self.infActiveState['<STR_LIT:t>'], connectedSynapsesOnly=False)<EOL>if numActiveSyns < self.activationThreshold:<EOL><INDENT>continue<EOL><DEDENT>if self.verbosity >= <NUM_LIT:6>:<EOL><INDENT>print("<STR_LIT>" % (c, i), end='<STR_LIT:U+0020>')<EOL>s.debugPrint()<EOL><DEDENT>dc = s.dutyCycle()<EOL>self.cellConfidence['<STR_LIT:t>'][c, i] += dc<EOL>self.colConfidence['<STR_LIT:t>'][c] += dc<EOL>if self._isSegmentActive(s, self.infActiveState['<STR_LIT:t>']):<EOL><INDENT>self.infPredictedState['<STR_LIT:t>'][c, i] = <NUM_LIT:1><EOL><DEDENT><DEDENT><DEDENT><DEDENT>sumConfidences = self.colConfidence['<STR_LIT:t>'].sum()<EOL>if sumConfidences > <NUM_LIT:0>:<EOL><INDENT>self.colConfidence['<STR_LIT:t>'] /= sumConfidences<EOL>self.cellConfidence['<STR_LIT:t>'] /= sumConfidences<EOL><DEDENT>numPredictedCols = self.infPredictedState['<STR_LIT:t>'].max(axis=<NUM_LIT:1>).sum()<EOL>if numPredictedCols >= <NUM_LIT:0.5> * self.avgInputDensity:<EOL><INDENT>return True<EOL><DEDENT>else:<EOL><INDENT>return False<EOL><DEDENT>

Phase 2 for the inference state. The computes the predicted state, then
checks to insure that the predicted state is not over-saturated, i.e.
look too close like a burst. This indicates that there were so many
separate paths learned from the current input columns to the predicted
input columns that bursting on the current input columns is most likely
generated mix and match errors on cells in the predicted columns. If
we detect this situation, we instead turn on only the start cells in the
current active columns and re-generate the predicted state from those.

This looks at:
    - `` infActiveState['t']``

This modifies:
    - `` infPredictedState['t']``
    - `` colConfidence['t']``
    - `` cellConfidence['t']``

:returns: (bool) True if we have a decent guess as to the next input.
          Returning False from here indicates to the caller that we have
          reached the end of a learned sequence.


<EOL>self.infActiveState['<STR_LIT>'][:, :] = self.infActiveState['<STR_LIT:t>'][:, :]<EOL>self.infPredictedState['<STR_LIT>'][:, :] = self.infPredictedState['<STR_LIT:t>'][:, :]<EOL>self.cellConfidence['<STR_LIT>'][:, :] = self.cellConfidence['<STR_LIT:t>'][:, :]<EOL>self.colConfidence['<STR_LIT>'][:] = self.colConfidence['<STR_LIT:t>'][:]<EOL>if self.maxInfBacktrack > <NUM_LIT:0>:<EOL><INDENT>if len(self._prevInfPatterns) > self.maxInfBacktrack:<EOL><INDENT>self._prevInfPatterns.pop(<NUM_LIT:0>)<EOL><DEDENT>self._prevInfPatterns.append(activeColumns)<EOL><DEDENT>inSequence = self._inferPhase1(activeColumns, self.resetCalled)<EOL>if not inSequence:<EOL><INDENT>if self.verbosity >= <NUM_LIT:3>:<EOL><INDENT>print ("<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT>self._inferBacktrack(activeColumns)<EOL>return<EOL><DEDENT>inSequence = self._inferPhase2()<EOL>if not inSequence:<EOL><INDENT>if self.verbosity >= <NUM_LIT:3>:<EOL><INDENT>print ("<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT>self._inferBacktrack(activeColumns)<EOL><DEDENT>

Update the inference state. Called from :meth:`compute` on every iteration.

:param activeColumns: (list) active column indices.


def _learnBacktrackFrom(self, startOffset, readOnly=True):

<EOL>numPrevPatterns = len(self._prevLrnPatterns)<EOL>currentTimeStepsOffset = numPrevPatterns - <NUM_LIT:1><EOL>if not readOnly:<EOL><INDENT>self.segmentUpdates = {}<EOL><DEDENT>if self.verbosity >= <NUM_LIT:3>:<EOL><INDENT>if readOnly:<EOL><INDENT>print((<EOL>"<STR_LIT>" % (<EOL>numPrevPatterns - <NUM_LIT:1> - startOffset),<EOL>self._prevLrnPatterns[startOffset]))<EOL><DEDENT>else:<EOL><INDENT>print((<EOL>"<STR_LIT>" % (<EOL>numPrevPatterns - <NUM_LIT:1> - startOffset),<EOL>self._prevLrnPatterns[startOffset]))<EOL><DEDENT><DEDENT>inSequence = True<EOL>for offset in range(startOffset, numPrevPatterns):<EOL><INDENT>self.lrnPredictedState['<STR_LIT>'][:, :] = self.lrnPredictedState['<STR_LIT:t>'][:, :]<EOL>self.lrnActiveState['<STR_LIT>'][:, :] = self.lrnActiveState['<STR_LIT:t>'][:, :]<EOL>inputColumns = self._prevLrnPatterns[offset]<EOL>if not readOnly:<EOL><INDENT>self._processSegmentUpdates(inputColumns)<EOL><DEDENT>if offset == startOffset:<EOL><INDENT>self.lrnActiveState['<STR_LIT:t>'].fill(<NUM_LIT:0>)<EOL>for c in inputColumns:<EOL><INDENT>self.lrnActiveState['<STR_LIT:t>'][c, <NUM_LIT:0>] = <NUM_LIT:1><EOL><DEDENT>inSequence = True<EOL><DEDENT>else:<EOL><INDENT>inSequence = self._learnPhase1(inputColumns, readOnly=readOnly)<EOL><DEDENT>if not inSequence or offset == currentTimeStepsOffset:<EOL><INDENT>break<EOL><DEDENT>if self.verbosity >= <NUM_LIT:3>:<EOL><INDENT>print("<STR_LIT>", inputColumns)<EOL><DEDENT>self._learnPhase2(readOnly=readOnly)<EOL><DEDENT>return inSequence<EOL>

A utility method called from learnBacktrack. This will backtrack
starting from the given startOffset in our prevLrnPatterns queue.

It returns True if the backtrack was successful and we managed to get
predictions all the way up to the current time step.

If readOnly, then no segments are updated or modified, otherwise, all
segment updates that belong to the given path are applied.

This updates/modifies:

    - lrnActiveState['t']

This trashes:

    - lrnPredictedState['t']
    - lrnPredictedState['t-1']
    - lrnActiveState['t-1']

:param startOffset: Start offset within the prevLrnPatterns input history
:param readOnly:
:return: True if we managed to lock on to a sequence that started
                   earlier.
                   If False, we lost predictions somewhere along the way
                   leading up to the current time.


<EOL>numPrevPatterns = len(self._prevLrnPatterns) - <NUM_LIT:1><EOL>if numPrevPatterns <= <NUM_LIT:0>:<EOL><INDENT>if self.verbosity >= <NUM_LIT:3>:<EOL><INDENT>print("<STR_LIT>")<EOL><DEDENT>return False<EOL><DEDENT>badPatterns = []<EOL>inSequence = False<EOL>for startOffset in range(<NUM_LIT:0>, numPrevPatterns):<EOL><INDENT>inSequence = self._learnBacktrackFrom(startOffset, readOnly=True)<EOL>if inSequence:<EOL><INDENT>break<EOL><DEDENT>badPatterns.append(startOffset)<EOL><DEDENT>if not inSequence:<EOL><INDENT>if self.verbosity >= <NUM_LIT:3>:<EOL><INDENT>print ("<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT>self._prevLrnPatterns = []<EOL>return False<EOL><DEDENT>if self.verbosity >= <NUM_LIT:3>:<EOL><INDENT>print(("<STR_LIT>"<EOL>"<STR_LIT>" % (numPrevPatterns - startOffset),<EOL>self._prevLrnPatterns[startOffset]))<EOL><DEDENT>self._learnBacktrackFrom(startOffset, readOnly=False)<EOL>for i in range(numPrevPatterns):<EOL><INDENT>if i in badPatterns or i <= startOffset:<EOL><INDENT>if self.verbosity >= <NUM_LIT:3>:<EOL><INDENT>print(("<STR_LIT>",<EOL>self._prevLrnPatterns[<NUM_LIT:0>]))<EOL><DEDENT>self._prevLrnPatterns.pop(<NUM_LIT:0>)<EOL><DEDENT>else:<EOL><INDENT>break<EOL><DEDENT><DEDENT>return numPrevPatterns - startOffset<EOL>

This "backtracks" our learning state, trying to see if we can lock onto
the current set of inputs by assuming the sequence started up to N steps
ago on start cells.

This will adjust @ref lrnActiveState['t'] if it does manage to lock on to a
sequence that started earlier.

:returns:          >0 if we managed to lock on to a sequence that started
                  earlier. The value returned is how many steps in the
                  past we locked on.
                  If 0 is returned, the caller needs to change active
                  state to start on start cells.

How it works:
-------------------------------------------------------------------
This method gets called from updateLearningState when we detect either of
the following two conditions:

#. Our PAM counter (@ref pamCounter) expired
#. We reached the max allowed learned sequence length

Either of these two conditions indicate that we want to start over on start
cells.

Rather than start over on start cells on the current input, we can
accelerate learning by backtracking a few steps ago and seeing if perhaps
a sequence we already at least partially know already started.

This updates/modifies:
    - @ref lrnActiveState['t']

This trashes:
    - @ref lrnActiveState['t-1']
    - @ref lrnPredictedState['t']
    - @ref lrnPredictedState['t-1']


def _learnPhase1(self, activeColumns, readOnly=False):

<EOL>self.lrnActiveState['<STR_LIT:t>'].fill(<NUM_LIT:0>)<EOL>numUnpredictedColumns = <NUM_LIT:0><EOL>for c in activeColumns:<EOL><INDENT>predictingCells = numpy.where(self.lrnPredictedState['<STR_LIT>'][c] == <NUM_LIT:1>)[<NUM_LIT:0>]<EOL>numPredictedCells = len(predictingCells)<EOL>assert numPredictedCells <= <NUM_LIT:1><EOL>if numPredictedCells == <NUM_LIT:1>:<EOL><INDENT>i = predictingCells[<NUM_LIT:0>]<EOL>self.lrnActiveState['<STR_LIT:t>'][c, i] = <NUM_LIT:1><EOL>continue<EOL><DEDENT>numUnpredictedColumns += <NUM_LIT:1><EOL>if readOnly:<EOL><INDENT>continue<EOL><DEDENT>i, s, numActive = self._getBestMatchingCell(<EOL>c, self.lrnActiveState['<STR_LIT>'], self.minThreshold)<EOL>if s is not None and s.isSequenceSegment():<EOL><INDENT>if self.verbosity >= <NUM_LIT:4>:<EOL><INDENT>print("<STR_LIT>", c)<EOL><DEDENT>self.lrnActiveState['<STR_LIT:t>'][c, i] = <NUM_LIT:1><EOL>segUpdate = self._getSegmentActiveSynapses(<EOL>c, i, s, self.lrnActiveState['<STR_LIT>'], newSynapses = True)<EOL>s.totalActivations += <NUM_LIT:1><EOL>trimSegment = self._adaptSegment(segUpdate)<EOL>if trimSegment:<EOL><INDENT>self._trimSegmentsInCell(c, i, [s], minPermanence = <NUM_LIT>,<EOL>minNumSyns = <NUM_LIT:0>)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>i = self._getCellForNewSegment(c)<EOL>if (self.verbosity >= <NUM_LIT:4>):<EOL><INDENT>print("<STR_LIT>", c, end='<STR_LIT:U+0020>')<EOL>print("<STR_LIT>", i)<EOL><DEDENT>self.lrnActiveState['<STR_LIT:t>'][c, i] = <NUM_LIT:1><EOL>segUpdate = self._getSegmentActiveSynapses(<EOL>c, i, None, self.lrnActiveState['<STR_LIT>'], newSynapses=True)<EOL>segUpdate.sequenceSegment = True <EOL>self._adaptSegment(segUpdate)  <EOL><DEDENT><DEDENT>numBottomUpColumns = len(activeColumns)<EOL>if numUnpredictedColumns < numBottomUpColumns / <NUM_LIT:2>:<EOL><INDENT>return True   <EOL><DEDENT>else:<EOL><INDENT>return False<EOL><DEDENT>

Compute the learning active state given the predicted state and
the bottom-up input.

:param activeColumns list of active bottom-ups
:param readOnly      True if being called from backtracking logic.
                     This tells us not to increment any segment
                     duty cycles or queue up any updates.
:returns: True if the current input was sufficiently predicted, OR
         if we started over on startCells. False indicates that the current
         input was NOT predicted, well enough to consider it as "inSequence"

This looks at:
    - @ref lrnActiveState['t-1']
    - @ref lrnPredictedState['t-1']

This modifies:
    - @ref lrnActiveState['t']
    - @ref lrnActiveState['t-1']


<EOL>self.lrnPredictedState['<STR_LIT:t>'].fill(<NUM_LIT:0>)<EOL>for c in range(self.numberOfCols):<EOL><INDENT>i, s, numActive = self._getBestMatchingCell(<EOL>c, self.lrnActiveState['<STR_LIT:t>'], minThreshold = self.activationThreshold)<EOL>if i is None:<EOL><INDENT>continue<EOL><DEDENT>self.lrnPredictedState['<STR_LIT:t>'][c, i] = <NUM_LIT:1><EOL>if readOnly:<EOL><INDENT>continue<EOL><DEDENT>segUpdate = self._getSegmentActiveSynapses(<EOL>c, i, s, activeState=self.lrnActiveState['<STR_LIT:t>'],<EOL>newSynapses=(numActive < self.newSynapseCount))<EOL>s.totalActivations += <NUM_LIT:1>    <EOL>self._addToSegmentUpdates(c, i, segUpdate)<EOL>if self.doPooling:<EOL><INDENT>predSegment = self._getBestMatchingSegment(c, i,<EOL>self.lrnActiveState['<STR_LIT>'])<EOL>segUpdate = self._getSegmentActiveSynapses(c, i, predSegment,<EOL>self.lrnActiveState['<STR_LIT>'], newSynapses=True)<EOL>self._addToSegmentUpdates(c, i, segUpdate)<EOL><DEDENT><DEDENT>

Compute the predicted segments given the current set of active cells.

:param readOnly       True if being called from backtracking logic.
                      This tells us not to increment any segment
                      duty cycles or queue up any updates.

This computes the lrnPredictedState['t'] and queues up any segments that
became active (and the list of active synapses for each segment) into
the segmentUpdates queue

This looks at:
    - @ref lrnActiveState['t']

This modifies:
    - @ref lrnPredictedState['t']
    - @ref segmentUpdates


<EOL>self.lrnPredictedState['<STR_LIT>'][:, :] = self.lrnPredictedState['<STR_LIT:t>'][:, :]<EOL>self.lrnActiveState['<STR_LIT>'][:, :] = self.lrnActiveState['<STR_LIT:t>'][:, :]<EOL>if self.maxLrnBacktrack > <NUM_LIT:0>:<EOL><INDENT>if len(self._prevLrnPatterns) > self.maxLrnBacktrack:<EOL><INDENT>self._prevLrnPatterns.pop(<NUM_LIT:0>)<EOL><DEDENT>self._prevLrnPatterns.append(activeColumns)<EOL>if self.verbosity >= <NUM_LIT:4>:<EOL><INDENT>print("<STR_LIT>")<EOL>print(self._prevLrnPatterns)<EOL><DEDENT><DEDENT>self._processSegmentUpdates(activeColumns)<EOL>if self.pamCounter > <NUM_LIT:0>:<EOL><INDENT>self.pamCounter -= <NUM_LIT:1><EOL><DEDENT>self.learnedSeqLength += <NUM_LIT:1><EOL>if not self.resetCalled:<EOL><INDENT>inSequence = self._learnPhase1(activeColumns)<EOL>if inSequence:<EOL><INDENT>self.pamCounter = self.pamLength<EOL><DEDENT><DEDENT>if self.verbosity >= <NUM_LIT:3>:<EOL><INDENT>print("<STR_LIT>", self.pamCounter, "<STR_LIT>",self.learnedSeqLength)<EOL><DEDENT>if (self.resetCalled or self.pamCounter == <NUM_LIT:0> or<EOL>(self.maxSeqLength != <NUM_LIT:0> and<EOL>self.learnedSeqLength >= self.maxSeqLength)):<EOL><INDENT>if  self.verbosity >= <NUM_LIT:3>:<EOL><INDENT>if self.resetCalled:<EOL><INDENT>print("<STR_LIT>", activeColumns, "<STR_LIT>")<EOL><DEDENT>elif self.pamCounter == <NUM_LIT:0>:<EOL><INDENT>print("<STR_LIT>", activeColumns, "<STR_LIT>")<EOL><DEDENT>else:<EOL><INDENT>print("<STR_LIT>", activeColumns, "<STR_LIT>")<EOL><DEDENT><DEDENT>if self.pamCounter == <NUM_LIT:0>:<EOL><INDENT>seqLength = self.learnedSeqLength - self.pamLength<EOL><DEDENT>else:<EOL><INDENT>seqLength = self.learnedSeqLength<EOL><DEDENT>if  self.verbosity >= <NUM_LIT:3>:<EOL><INDENT>print("<STR_LIT>", seqLength)<EOL><DEDENT>self._updateAvgLearnedSeqLength(seqLength)<EOL>backSteps = <NUM_LIT:0><EOL>if not self.resetCalled:<EOL><INDENT>backSteps = self._learnBacktrack()<EOL><DEDENT>if self.resetCalled or backSteps is None or backSteps == <NUM_LIT:0>:<EOL><INDENT>backSteps = <NUM_LIT:0><EOL>self.lrnActiveState['<STR_LIT:t>'].fill(<NUM_LIT:0>)<EOL>for c in activeColumns:<EOL><INDENT>self.lrnActiveState['<STR_LIT:t>'][c, <NUM_LIT:0>] = <NUM_LIT:1><EOL><DEDENT>self._prevLrnPatterns = []<EOL><DEDENT>self.pamCounter =  self.pamLength<EOL>self.learnedSeqLength = backSteps<EOL>self.segmentUpdates = {}<EOL><DEDENT>self._learnPhase2()<EOL>

Update the learning state. Called from compute() on every iteration
:param activeColumns List of active column indices


def compute(self, bottomUpInput, enableLearn, enableInference=None):

<EOL>if enableInference is None:<EOL><INDENT>if enableLearn:<EOL><INDENT>enableInference = False<EOL><DEDENT>else:<EOL><INDENT>enableInference = True<EOL><DEDENT><DEDENT>assert (enableLearn or enableInference)<EOL>activeColumns = bottomUpInput.nonzero()[<NUM_LIT:0>]<EOL>if enableLearn:<EOL><INDENT>self.lrnIterationIdx += <NUM_LIT:1><EOL><DEDENT>self.iterationIdx +=  <NUM_LIT:1><EOL>if self.verbosity >= <NUM_LIT:3>:<EOL><INDENT>print("<STR_LIT>" % (self.iterationIdx))<EOL>print("<STR_LIT>", activeColumns)<EOL><DEDENT>if enableLearn:<EOL><INDENT>if self.lrnIterationIdx in Segment.dutyCycleTiers:<EOL><INDENT>for c, i in itertools.product(range(self.numberOfCols),<EOL>range(self.cellsPerColumn)):<EOL><INDENT>for segment in self.cells[c][i]:<EOL><INDENT>segment.dutyCycle()<EOL><DEDENT><DEDENT><DEDENT><DEDENT>if self.avgInputDensity is None:<EOL><INDENT>self.avgInputDensity = len(activeColumns)<EOL><DEDENT>else:<EOL><INDENT>self.avgInputDensity = (<NUM_LIT> * self.avgInputDensity +<EOL><NUM_LIT> * len(activeColumns))<EOL><DEDENT>if enableInference:<EOL><INDENT>self._updateInferenceState(activeColumns)<EOL><DEDENT>if enableLearn:<EOL><INDENT>self._updateLearningState(activeColumns)<EOL>if self.globalDecay > <NUM_LIT:0.0> and ((self.lrnIterationIdx % self.maxAge) == <NUM_LIT:0>):<EOL><INDENT>for c, i in itertools.product(range(self.numberOfCols),<EOL>range(self.cellsPerColumn)):<EOL><INDENT>segsToDel = [] <EOL>for segment in self.cells[c][i]:<EOL><INDENT>age = self.lrnIterationIdx - segment.lastActiveIteration<EOL>if age <= self.maxAge:<EOL><INDENT>continue<EOL><DEDENT>synsToDel = [] <EOL>for synapse in segment.syns:<EOL><INDENT>synapse[<NUM_LIT:2>] = synapse[<NUM_LIT:2>] - self.globalDecay <EOL>if synapse[<NUM_LIT:2>] <= <NUM_LIT:0>:<EOL><INDENT>synsToDel.append(synapse) <EOL><DEDENT><DEDENT>if len(synsToDel) == segment.getNumSynapses():<EOL><INDENT>segsToDel.append(segment) <EOL><DEDENT>elif len(synsToDel) > <NUM_LIT:0>:<EOL><INDENT>for syn in synsToDel: <EOL><INDENT>segment.syns.remove(syn)<EOL><DEDENT><DEDENT><DEDENT>for seg in segsToDel: <EOL><INDENT>self._cleanUpdatesList(c, i, seg)<EOL>self.cells[c][i].remove(seg)<EOL><DEDENT><DEDENT><DEDENT><DEDENT>if self.collectStats:<EOL><INDENT>if enableInference:<EOL><INDENT>predictedState = self.infPredictedState['<STR_LIT>']<EOL><DEDENT>else:<EOL><INDENT>predictedState = self.lrnPredictedState['<STR_LIT>']<EOL><DEDENT>self._updateStatsInferEnd(self._internalStats,<EOL>activeColumns,<EOL>predictedState,<EOL>self.colConfidence['<STR_LIT>'])<EOL><DEDENT>output = self._computeOutput()<EOL>self.printComputeEnd(output, learn=enableLearn)<EOL>self.resetCalled = False<EOL>return output<EOL>

Handle one compute, possibly learning.

.. note::  It is an error to have both ``enableLearn`` and
           ``enableInference`` set to False

.. note:: By default, we don't compute the inference output when learning
          because it slows things down, but you can override this by passing
          in True for ``enableInference``.

:param bottomUpInput: The bottom-up input as numpy list, typically from a
       spatial pooler.
:param enableLearn: (bool) If true, perform learning
:param enableInference: (bool) If None, default behavior is to disable the
       inference output when ``enableLearn`` is on. If true, compute the
       inference output. If false, do not compute the inference output.

:returns: TODO: document


return self.compute(bottomUpInput, enableLearn=False)<EOL>

TODO: document

:param bottomUpInput:
:return:


def learn(self, bottomUpInput, enableInference=None):

return self.compute(bottomUpInput, enableLearn=True,<EOL>enableInference=enableInference)<EOL>

TODO: document

:param bottomUpInput:
:param enableInference:
:return:


return self.colConfidence['<STR_LIT:t>']<EOL>

Returns the stored cell confidences from the last compute.

:returns: Column confidence scores


<EOL>return self._columnConfidences()<EOL>

For now, we will assume there is no one above us and that bottomUpOut is
simply the output that corresponds to our currently stored column
confidences.

:returns: the same thing as :meth:`columnConfidences`


def _trimSegmentsInCell(self, colIdx, cellIdx, segList, minPermanence,<EOL>minNumSyns):

<EOL>if minPermanence is None:<EOL><INDENT>minPermanence = self.connectedPerm<EOL><DEDENT>if minNumSyns is None:<EOL><INDENT>minNumSyns = self.activationThreshold<EOL><DEDENT>nSegsRemoved, nSynsRemoved = <NUM_LIT:0>, <NUM_LIT:0><EOL>segsToDel = [] <EOL>for segment in segList:<EOL><INDENT>synsToDel = [syn for syn in segment.syns if syn[<NUM_LIT:2>] < minPermanence]<EOL>if len(synsToDel) == len(segment.syns):<EOL><INDENT>segsToDel.append(segment) <EOL><DEDENT>else:<EOL><INDENT>if len(synsToDel) > <NUM_LIT:0>:<EOL><INDENT>for syn in synsToDel: <EOL><INDENT>segment.syns.remove(syn)<EOL>nSynsRemoved += <NUM_LIT:1><EOL><DEDENT><DEDENT>if len(segment.syns) < minNumSyns:<EOL><INDENT>segsToDel.append(segment)<EOL><DEDENT><DEDENT><DEDENT>nSegsRemoved += len(segsToDel)<EOL>for seg in segsToDel: <EOL><INDENT>self._cleanUpdatesList(colIdx, cellIdx, seg)<EOL>self.cells[colIdx][cellIdx].remove(seg)<EOL>nSynsRemoved += len(seg.syns)<EOL><DEDENT>return nSegsRemoved, nSynsRemoved<EOL>

This method goes through a list of segments for a given cell and
deletes all synapses whose permanence is less than minPermanence and deletes
any segments that have less than minNumSyns synapses remaining.

:param colIdx        Column index
:param cellIdx       Cell index within the column
:param segList       List of segment references
:param minPermanence Any syn whose permamence is 0 or < minPermanence will
                     be deleted.
:param minNumSyns    Any segment with less than minNumSyns synapses remaining
                     in it will be deleted.

:returns: tuple (numSegsRemoved, numSynsRemoved)


def trimSegments(self, minPermanence=None, minNumSyns=None):

<EOL>if minPermanence is None:<EOL><INDENT>minPermanence = self.connectedPerm<EOL><DEDENT>if minNumSyns is None:<EOL><INDENT>minNumSyns = self.activationThreshold<EOL><DEDENT>totalSegsRemoved, totalSynsRemoved = <NUM_LIT:0>, <NUM_LIT:0><EOL>for c, i in itertools.product(range(self.numberOfCols),<EOL>range(self.cellsPerColumn)):<EOL><INDENT>(segsRemoved, synsRemoved) = self._trimSegmentsInCell(<EOL>colIdx=c, cellIdx=i, segList=self.cells[c][i],<EOL>minPermanence=minPermanence, minNumSyns=minNumSyns)<EOL>totalSegsRemoved += segsRemoved<EOL>totalSynsRemoved += synsRemoved<EOL><DEDENT>if self.verbosity >= <NUM_LIT:5>:<EOL><INDENT>print("<STR_LIT>")<EOL>self.printCells(predictedOnly=False)<EOL><DEDENT>return totalSegsRemoved, totalSynsRemoved<EOL>

This method deletes all synapses whose permanence is less than
minPermanence and deletes any segments that have less than
minNumSyns synapses remaining.

:param minPermanence: (float) Any syn whose permanence is 0 or <
       ``minPermanence``  will be deleted. If None is passed in, then
       ``self.connectedPerm`` is used.
:param minNumSyns: (int) Any segment with less than ``minNumSyns`` synapses
       remaining in it will be deleted. If None is passed in, then
       ``self.activationThreshold`` is used.
:returns: (tuple) ``numSegsRemoved``, ``numSynsRemoved``


def _cleanUpdatesList(self, col, cellIdx, seg):

<EOL>for key, updateList in self.segmentUpdates.items():<EOL><INDENT>c, i = key[<NUM_LIT:0>], key[<NUM_LIT:1>]<EOL>if c == col and i == cellIdx:<EOL><INDENT>for update in updateList:<EOL><INDENT>if update[<NUM_LIT:1>].segment == seg:<EOL><INDENT>self._removeSegmentUpdate(update)<EOL><DEDENT><DEDENT><DEDENT><DEDENT>

Removes any update that would be for the given col, cellIdx, segIdx.

NOTE: logically, we need to do this when we delete segments, so that if
an update refers to a segment that was just deleted, we also remove
that update from the update list. However, I haven't seen it trigger
in any of the unit tests yet, so it might mean that it's not needed
and that situation doesn't occur, by construction.


<EOL>self.trimSegments(minPermanence=<NUM_LIT>)<EOL>for c, i in itertools.product(range(self.numberOfCols),<EOL>range(self.cellsPerColumn)):<EOL><INDENT>for segment in self.cells[c][i]:<EOL><INDENT>segment.dutyCycle()<EOL><DEDENT><DEDENT>if self.cellsPerColumn > <NUM_LIT:1>:<EOL><INDENT>for c in range(self.numberOfCols):<EOL><INDENT>assert self.getNumSegmentsInCell(c, <NUM_LIT:0>) == <NUM_LIT:0><EOL><DEDENT><DEDENT>

Called when learning has been completed. This method just calls
:meth:`trimSegments` and then clears out caches.


def _checkPrediction(self, patternNZs, output=None, colConfidence=None,<EOL>details=False):

<EOL>numPatterns = len(patternNZs)<EOL>orAll = set()<EOL>orAll = orAll.union(*patternNZs)<EOL>if output is None:<EOL><INDENT>assert self.currentOutput is not None<EOL>output = self.currentOutput<EOL><DEDENT>output = set(output.sum(axis=<NUM_LIT:1>).nonzero()[<NUM_LIT:0>])<EOL>totalExtras = len(output.difference(orAll))<EOL>totalMissing = len(orAll.difference(output))<EOL>if colConfidence is None:<EOL><INDENT>colConfidence = self.colConfidence['<STR_LIT:t>']<EOL><DEDENT>confidences = []<EOL>for i in range(numPatterns):<EOL><INDENT>positivePredictionSum = colConfidence[patternNZs[i]].sum()<EOL>positiveColumnCount   = len(patternNZs[i])<EOL>totalPredictionSum    = colConfidence.sum()<EOL>totalColumnCount      = len(colConfidence)<EOL>negativePredictionSum = totalPredictionSum - positivePredictionSum<EOL>negativeColumnCount   = totalColumnCount   - positiveColumnCount<EOL>if positiveColumnCount != <NUM_LIT:0>:<EOL><INDENT>positivePredictionScore = positivePredictionSum<EOL><DEDENT>else:<EOL><INDENT>positivePredictionScore = <NUM_LIT:0.0><EOL><DEDENT>if negativeColumnCount != <NUM_LIT:0>:<EOL><INDENT>negativePredictionScore = negativePredictionSum<EOL><DEDENT>else:<EOL><INDENT>negativePredictionScore = <NUM_LIT:0.0><EOL><DEDENT>currentSum = negativePredictionScore + positivePredictionScore<EOL>if currentSum > <NUM_LIT:0>:<EOL><INDENT>positivePredictionScore *= <NUM_LIT:1.0>/currentSum<EOL>negativePredictionScore *= <NUM_LIT:1.0>/currentSum<EOL><DEDENT>predictionScore = positivePredictionScore - negativePredictionScore<EOL>confidences.append((predictionScore,<EOL>positivePredictionScore,<EOL>negativePredictionScore))<EOL><DEDENT>if details:<EOL><INDENT>missingPatternBits = [set(pattern).difference(output)<EOL>for pattern in patternNZs]<EOL>return (totalExtras, totalMissing, confidences, missingPatternBits)<EOL><DEDENT>else:<EOL><INDENT>return (totalExtras, totalMissing, confidences)<EOL><DEDENT>

This function produces goodness-of-match scores for a set of input patterns,
by checking for their presence in the current and predicted output of the
TM. Returns a global count of the number of extra and missing bits, the
confidence scores for each input pattern, and (if requested) the
bits in each input pattern that were not present in the TM's prediction.

:param patternNZs a list of input patterns that we want to check for. Each
                  element is a list of the non-zeros in that pattern.
:param output     The output of the TM. If not specified, then use the
                  TM's current output. This can be specified if you are
                  trying to check the prediction metric for an output from
                  the past.
:param colConfidence The column confidences. If not specified, then use the
                     TM's current self.colConfidence. This can be specified if you
                     are trying to check the prediction metrics for an output
                     from the past.
:param details    if True, also include details of missing bits per pattern.

:returns:  list containing:

          [
            totalExtras,
            totalMissing,
            [conf_1, conf_2, ...],
            [missing1, missing2, ...]
          ]

@retval totalExtras a global count of the number of 'extras', i.e. bits that
                    are on in the current output but not in the or of all the
                    passed in patterns
@retval totalMissing a global count of all the missing bits, i.e. the bits
                     that are on in the or of the patterns, but not in the
                     current output
@retval conf_i the confidence score for the i'th pattern inpatternsToCheck
               This consists of 3 items as a tuple:
               (predictionScore, posPredictionScore, negPredictionScore)
@retval missing_i the bits in the i'th pattern that were missing
                  in the output. This list is only returned if details is
                  True.


def _isSegmentActive(self, seg, activeState):

<EOL>return isSegmentActive(seg.syns, activeState,<EOL>self.connectedPerm, self.activationThreshold)<EOL>

A segment is active if it has >= activationThreshold connected
synapses that are active due to activeState.

Notes: studied various cutoffs, none of which seem to be worthwhile
       list comprehension didn't help either

:param seg TODO: document
:param activeState TODO: document


def _getSegmentActivityLevel(self, seg, activeState,<EOL>connectedSynapsesOnly=False):

<EOL>return getSegmentActivityLevel(seg.syns, activeState, connectedSynapsesOnly,<EOL>self.connectedPerm)<EOL>

This routine computes the activity level of a segment given activeState.
It can tally up only connected synapses (permanence >= connectedPerm), or
all the synapses of the segment, at either t or t-1.

:param seg TODO: document
:param activeState TODO: document
:param connectedSynapsesOnly TODO: document


def _getBestMatchingCell(self, c, activeState, minThreshold):

<EOL>bestActivityInCol = minThreshold<EOL>bestSegIdxInCol = -<NUM_LIT:1><EOL>bestCellInCol = -<NUM_LIT:1><EOL>for i in range(self.cellsPerColumn):<EOL><INDENT>maxSegActivity = <NUM_LIT:0><EOL>maxSegIdx = <NUM_LIT:0><EOL>for j, s in enumerate(self.cells[c][i]):<EOL><INDENT>activity = self._getSegmentActivityLevel(s, activeState)<EOL>if activity > maxSegActivity:<EOL><INDENT>maxSegActivity = activity<EOL>maxSegIdx = j<EOL><DEDENT><DEDENT>if maxSegActivity >= bestActivityInCol:<EOL><INDENT>bestActivityInCol = maxSegActivity<EOL>bestSegIdxInCol = maxSegIdx<EOL>bestCellInCol = i<EOL><DEDENT><DEDENT>if bestCellInCol == -<NUM_LIT:1>:<EOL><INDENT>return (None, None, None)<EOL><DEDENT>else:<EOL><INDENT>return (bestCellInCol, self.cells[c][bestCellInCol][bestSegIdxInCol],<EOL>bestActivityInCol)<EOL><DEDENT>

Find weakly activated cell in column with at least minThreshold active
synapses.

:param c            which column to look at
:param activeState  the active cells
:param minThreshold minimum number of synapses required

:returns: tuple (cellIdx, segment, numActiveSynapses)


def _getBestMatchingSegment(self, c, i, activeState):

maxActivity, which = self.minThreshold, -<NUM_LIT:1><EOL>for j, s in enumerate(self.cells[c][i]):<EOL><INDENT>activity = self._getSegmentActivityLevel(s, activeState,<EOL>connectedSynapsesOnly=False)<EOL>if activity >= maxActivity:<EOL><INDENT>maxActivity, which = activity, j<EOL><DEDENT><DEDENT>if which == -<NUM_LIT:1>:<EOL><INDENT>return None<EOL><DEDENT>else:<EOL><INDENT>return self.cells[c][i][which]<EOL><DEDENT>

For the given cell, find the segment with the largest number of active
synapses. This routine is aggressive in finding the best match. The
permanence value of synapses is allowed to be below connectedPerm. The number
of active synapses is allowed to be below activationThreshold, but must be
above minThreshold. The routine returns the segment index. If no segments are
found, then an index of -1 is returned.

:param c TODO: document
:param i TODO: document
:param activeState TODO: document


<EOL>if self.maxSegmentsPerCell < <NUM_LIT:0>:<EOL><INDENT>if self.cellsPerColumn > <NUM_LIT:1>:<EOL><INDENT>i = self._random.getUInt32(self.cellsPerColumn-<NUM_LIT:1>) + <NUM_LIT:1><EOL><DEDENT>else:<EOL><INDENT>i = <NUM_LIT:0><EOL><DEDENT>return i<EOL><DEDENT>candidateCellIdxs = []<EOL>if self.cellsPerColumn == <NUM_LIT:1>:<EOL><INDENT>minIdx = <NUM_LIT:0><EOL>maxIdx = <NUM_LIT:0><EOL><DEDENT>else:<EOL><INDENT>minIdx = <NUM_LIT:1>                      <EOL>maxIdx = self.cellsPerColumn-<NUM_LIT:1><EOL><DEDENT>for i in range(minIdx, maxIdx+<NUM_LIT:1>):<EOL><INDENT>numSegs = len(self.cells[colIdx][i])<EOL>if numSegs < self.maxSegmentsPerCell:<EOL><INDENT>candidateCellIdxs.append(i)<EOL><DEDENT><DEDENT>if len(candidateCellIdxs) > <NUM_LIT:0>:<EOL><INDENT>candidateCellIdx = (<EOL>candidateCellIdxs[self._random.getUInt32(len(candidateCellIdxs))])<EOL>if self.verbosity >= <NUM_LIT:5>:<EOL><INDENT>print("<STR_LIT>" % (<EOL>colIdx, candidateCellIdx, len(self.cells[colIdx][candidateCellIdx])))<EOL><DEDENT>return candidateCellIdx<EOL><DEDENT>candidateSegment = None<EOL>candidateSegmentDC = <NUM_LIT:1.0><EOL>for i in range(minIdx, maxIdx+<NUM_LIT:1>):<EOL><INDENT>for s in self.cells[colIdx][i]:<EOL><INDENT>dc = s.dutyCycle()<EOL>if dc < candidateSegmentDC:<EOL><INDENT>candidateCellIdx = i<EOL>candidateSegmentDC = dc<EOL>candidateSegment = s<EOL><DEDENT><DEDENT><DEDENT>if self.verbosity >= <NUM_LIT:5>:<EOL><INDENT>print(("<STR_LIT>"<EOL>"<STR_LIT>" % (candidateSegment.segID, colIdx, candidateCellIdx)))<EOL>candidateSegment.debugPrint()<EOL><DEDENT>self._cleanUpdatesList(colIdx, candidateCellIdx, candidateSegment)<EOL>self.cells[colIdx][candidateCellIdx].remove(candidateSegment)<EOL>return candidateCellIdx<EOL>

Return the index of a cell in this column which is a good candidate
for adding a new segment.

When we have fixed size resources in effect, we insure that we pick a
cell which does not already have the max number of allowed segments. If
none exists, we choose the least used segment in the column to re-allocate.

:param colIdx which column to look at
:returns: cell index


def _getSegmentActiveSynapses(self, c, i, s, activeState, newSynapses=False):

activeSynapses = []<EOL>if s is not None: <EOL><INDENT>activeSynapses = [idx for idx, syn in enumerate(s.syns)if activeState[syn[<NUM_LIT:0>], syn[<NUM_LIT:1>]]]<EOL><DEDENT>if newSynapses: <EOL><INDENT>nSynapsesToAdd = self.newSynapseCount - len(activeSynapses)<EOL>activeSynapses += self._chooseCellsToLearnFrom(c, i, s, nSynapsesToAdd,<EOL>activeState)<EOL><DEDENT>update = BacktrackingTM._SegmentUpdate(c, i, s, activeSynapses)<EOL>return update<EOL>

Return a segmentUpdate data structure containing a list of proposed
changes to segment s. Let activeSynapses be the list of active synapses
where the originating cells have their activeState output = 1 at time step
t. (This list is empty if s is None since the segment doesn't exist.)
newSynapses is an optional argument that defaults to false. If newSynapses
is true, then newSynapseCount - len(activeSynapses) synapses are added to
activeSynapses. These synapses are randomly chosen from the set of cells
that have learnState = 1 at timeStep.

:param c TODO: document
:param i TODO: document
:param s TODO: document
:param activeState TODO: document
:param newSynapses TODO: document


def _chooseCellsToLearnFrom(self, c, i, s, n, activeState):

if n <= <NUM_LIT:0>:<EOL><INDENT>return []<EOL><DEDENT>tmpCandidates = numpy.where(activeState == <NUM_LIT:1>)<EOL>if len(tmpCandidates[<NUM_LIT:0>]) == <NUM_LIT:0>:<EOL><INDENT>return []<EOL><DEDENT>if s is None: <EOL><INDENT>cands = [syn for syn in zip(tmpCandidates[<NUM_LIT:0>], tmpCandidates[<NUM_LIT:1>])]<EOL><DEDENT>else:<EOL><INDENT>synapsesAlreadyInSegment = set((syn[<NUM_LIT:0>], syn[<NUM_LIT:1>]) for syn in s.syns)<EOL>cands = [syn for syn in zip(tmpCandidates[<NUM_LIT:0>], tmpCandidates[<NUM_LIT:1>])<EOL>if (syn[<NUM_LIT:0>], syn[<NUM_LIT:1>]) not in synapsesAlreadyInSegment]<EOL><DEDENT>if len(cands) <= n:<EOL><INDENT>return cands<EOL><DEDENT>if n == <NUM_LIT:1>: <EOL><INDENT>idx = self._random.getUInt32(len(cands))<EOL>return [cands[idx]]  <EOL><DEDENT>indices = numpy.array([j for j in range(len(cands))], dtype='<STR_LIT>')<EOL>tmp = numpy.zeros(min(n, len(indices)), dtype='<STR_LIT>')<EOL>self._random.sample(indices, tmp)<EOL>return sorted([cands[j] for j in tmp])<EOL>

Choose n random cells to learn from.

This function is called several times while learning with timeStep = t-1, so
we cache the set of candidates for that case. It's also called once with
timeStep = t, and we cache that set of candidates.

:returns: tuple (column index, cell index).


<EOL>removeKeys = []<EOL>trimSegments = []<EOL>for key, updateList in self.segmentUpdates.items():<EOL><INDENT>c, i = key[<NUM_LIT:0>], key[<NUM_LIT:1>]<EOL>if c in activeColumns:<EOL><INDENT>action = '<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>if self.doPooling and self.lrnPredictedState['<STR_LIT:t>'][c, i] == <NUM_LIT:1>:<EOL><INDENT>action = '<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>action = '<STR_LIT>'<EOL><DEDENT><DEDENT>updateListKeep = []<EOL>if action != '<STR_LIT>':<EOL><INDENT>for (createDate, segUpdate) in updateList:<EOL><INDENT>if self.verbosity >= <NUM_LIT:4>:<EOL><INDENT>print("<STR_LIT>", self.lrnIterationIdx, end='<STR_LIT:U+0020>')<EOL>print(segUpdate)<EOL><DEDENT>if self.lrnIterationIdx - createDate > self.segUpdateValidDuration:<EOL><INDENT>continue<EOL><DEDENT>if action == '<STR_LIT>':<EOL><INDENT>trimSegment = self._adaptSegment(segUpdate)<EOL>if trimSegment:<EOL><INDENT>trimSegments.append((segUpdate.columnIdx, segUpdate.cellIdx,<EOL>segUpdate.segment))<EOL><DEDENT><DEDENT>else:<EOL><INDENT>updateListKeep.append((createDate, segUpdate))<EOL><DEDENT><DEDENT><DEDENT>self.segmentUpdates[key] = updateListKeep<EOL>if len(updateListKeep) == <NUM_LIT:0>:<EOL><INDENT>removeKeys.append(key)<EOL><DEDENT><DEDENT>for key in removeKeys:<EOL><INDENT>self.segmentUpdates.pop(key)<EOL><DEDENT>for (c, i, segment) in trimSegments:<EOL><INDENT>self._trimSegmentsInCell(c, i, [segment], minPermanence = <NUM_LIT>,<EOL>minNumSyns = <NUM_LIT:0>)<EOL><DEDENT>

Go through the list of accumulated segment updates and process them
as follows:

if the segment update is too old, remove the update
else if the cell received bottom-up, update its permanences
else if it's still being predicted, leave it in the queue
else remove it.

:param activeColumns TODO: document


<EOL>trimSegment = False<EOL>c, i, segment = segUpdate.columnIdx, segUpdate.cellIdx, segUpdate.segment<EOL>activeSynapses = segUpdate.activeSynapses<EOL>synToUpdate = set([syn for syn in activeSynapses if type(syn) == int])<EOL>if segment is not None:<EOL><INDENT>if self.verbosity >= <NUM_LIT:4>:<EOL><INDENT>print("<STR_LIT>" % (segment.segID, c, i))<EOL>print("<STR_LIT>", end='<STR_LIT:U+0020>')<EOL>segment.debugPrint()<EOL><DEDENT>segment.lastActiveIteration = self.lrnIterationIdx<EOL>segment.positiveActivations += <NUM_LIT:1>       <EOL>segment.dutyCycle(active=True)<EOL>lastSynIndex = len(segment.syns) - <NUM_LIT:1><EOL>inactiveSynIndices = [s for s in range(<NUM_LIT:0>, lastSynIndex+<NUM_LIT:1>)if s not in synToUpdate]<EOL>trimSegment = segment.updateSynapses(inactiveSynIndices,<EOL>-self.permanenceDec)<EOL>activeSynIndices = [syn for syn in synToUpdate if syn <= lastSynIndex]<EOL>segment.updateSynapses(activeSynIndices, self.permanenceInc)<EOL>synsToAdd = [syn for syn in activeSynapses if type(syn) != int]<EOL>if self.maxSynapsesPerSegment > <NUM_LIT:0>and len(synsToAdd) + len(segment.syns) > self.maxSynapsesPerSegment:<EOL><INDENT>numToFree = (len(segment.syns) + len(synsToAdd) -<EOL>self.maxSynapsesPerSegment)<EOL>segment.freeNSynapses(numToFree, inactiveSynIndices, self.verbosity)<EOL><DEDENT>for newSyn in synsToAdd:<EOL><INDENT>segment.addSynapse(newSyn[<NUM_LIT:0>], newSyn[<NUM_LIT:1>], self.initialPerm)<EOL><DEDENT>if self.verbosity >= <NUM_LIT:4>:<EOL><INDENT>print("<STR_LIT>", end='<STR_LIT:U+0020>')<EOL>segment.debugPrint()<EOL><DEDENT><DEDENT>else:<EOL><INDENT>newSegment = Segment(tm=self, isSequenceSeg=segUpdate.sequenceSegment)<EOL>for synapse in activeSynapses:<EOL><INDENT>newSegment.addSynapse(synapse[<NUM_LIT:0>], synapse[<NUM_LIT:1>], self.initialPerm)<EOL><DEDENT>if self.verbosity >= <NUM_LIT:3>:<EOL><INDENT>print("<STR_LIT>" % (self.segID-<NUM_LIT:1>, c, i), end='<STR_LIT:U+0020>')<EOL>newSegment.debugPrint()<EOL><DEDENT>self.cells[c][i].append(newSegment)<EOL><DEDENT>return trimSegment<EOL>

This function applies segment update information to a segment in a
cell.

Synapses on the active list get their permanence counts incremented by
permanenceInc. All other synapses get their permanence counts decremented
by permanenceDec.

We also increment the positiveActivations count of the segment.

:param segUpdate SegmentUpdate instance
:returns: True if some synapses were decremented to 0 and the segment is a
         candidate for trimming


def getSegmentInfo(self, collectActiveData = False):

nSegments, nSynapses = <NUM_LIT:0>, <NUM_LIT:0><EOL>nActiveSegs, nActiveSynapses = <NUM_LIT:0>, <NUM_LIT:0><EOL>distSegSizes, distNSegsPerCell = {}, {}<EOL>distPermValues = {}   <EOL>numAgeBuckets = <NUM_LIT:20><EOL>distAges = []<EOL>ageBucketSize = int((self.lrnIterationIdx+<NUM_LIT:20>) / <NUM_LIT:20>)<EOL>for i in range(numAgeBuckets):<EOL><INDENT>distAges.append(['<STR_LIT>' % (i*ageBucketSize, (i+<NUM_LIT:1>)*ageBucketSize-<NUM_LIT:1>), <NUM_LIT:0>])<EOL><DEDENT>for c in range(self.numberOfCols):<EOL><INDENT>for i in range(self.cellsPerColumn):<EOL><INDENT>if len(self.cells[c][i]) > <NUM_LIT:0>:<EOL><INDENT>nSegmentsThisCell = len(self.cells[c][i])<EOL>nSegments += nSegmentsThisCell<EOL>if nSegmentsThisCell in distNSegsPerCell:<EOL><INDENT>distNSegsPerCell[nSegmentsThisCell] += <NUM_LIT:1><EOL><DEDENT>else:<EOL><INDENT>distNSegsPerCell[nSegmentsThisCell] = <NUM_LIT:1><EOL><DEDENT>for seg in self.cells[c][i]:<EOL><INDENT>nSynapsesThisSeg = seg.getNumSynapses()<EOL>nSynapses += nSynapsesThisSeg<EOL>if nSynapsesThisSeg in distSegSizes:<EOL><INDENT>distSegSizes[nSynapsesThisSeg] += <NUM_LIT:1><EOL><DEDENT>else:<EOL><INDENT>distSegSizes[nSynapsesThisSeg] = <NUM_LIT:1><EOL><DEDENT>for syn in seg.syns:<EOL><INDENT>p = int(syn[<NUM_LIT:2>]*<NUM_LIT:10>)<EOL>if p in distPermValues:<EOL><INDENT>distPermValues[p] += <NUM_LIT:1><EOL><DEDENT>else:<EOL><INDENT>distPermValues[p] = <NUM_LIT:1><EOL><DEDENT><DEDENT>age = self.lrnIterationIdx - seg.lastActiveIteration<EOL>ageBucket = int(age/ageBucketSize)<EOL>distAges[ageBucket][<NUM_LIT:1>] += <NUM_LIT:1><EOL>if collectActiveData:<EOL><INDENT>if self._isSegmentActive(seg, self.infActiveState['<STR_LIT:t>']):<EOL><INDENT>nActiveSegs += <NUM_LIT:1><EOL><DEDENT>for syn in seg.syns:<EOL><INDENT>if self.activeState['<STR_LIT:t>'][syn[<NUM_LIT:0>]][syn[<NUM_LIT:1>]] == <NUM_LIT:1>:<EOL><INDENT>nActiveSynapses += <NUM_LIT:1><EOL><DEDENT><DEDENT><DEDENT><DEDENT><DEDENT><DEDENT><DEDENT>return (nSegments, nSynapses, nActiveSegs, nActiveSynapses,<EOL>distSegSizes, distNSegsPerCell, distPermValues, distAges)<EOL>

Returns information about the distribution of segments, synapses and
        permanence values in the current TM. If requested, also returns information
        regarding the number of currently active segments and synapses.

        :returns: tuple described below:

          ::

            (
              nSegments,
              nSynapses,
              nActiveSegs,
              nActiveSynapses,
              distSegSizes,
              distNSegsPerCell,
              distPermValues,
              distAges
            )

        - ``nSegments``: (int) total number of segments
        - ``nSynapses``: (int) total number of synapses
        - ``nActiveSegs``: (int) total number of active segments (0 if
              ``collectActiveData`` is False)
        - ``nActiveSynapses``: (int) total number of active synapses 0 if
              ``collectActiveData`` is False
        - ``distSegSizes``: (dict) where d[n] = number of segments with n synapses
        - ``distNSegsPerCell``: (dict) where d[n] = number of cells with n segments
        - ``distPermValues``: (dict) where d[p] = number of synapses with perm = p/10
        - ``distAges``: (list) of tuples (``ageRange``, ``numSegments``)


def dutyCycle(self, active=False, readOnly=False):

<EOL>if self.tm.lrnIterationIdx <= self.dutyCycleTiers[<NUM_LIT:1>]:<EOL><INDENT>dutyCycle = float(self.positiveActivations)/ self.tm.lrnIterationIdx<EOL>if not readOnly:<EOL><INDENT>self._lastPosDutyCycleIteration = self.tm.lrnIterationIdx<EOL>self._lastPosDutyCycle = dutyCycle<EOL><DEDENT>return dutyCycle<EOL><DEDENT>age = self.tm.lrnIterationIdx - self._lastPosDutyCycleIteration<EOL>if age == <NUM_LIT:0> and not active:<EOL><INDENT>return self._lastPosDutyCycle<EOL><DEDENT>for tierIdx in range(len(self.dutyCycleTiers)-<NUM_LIT:1>, <NUM_LIT:0>, -<NUM_LIT:1>):<EOL><INDENT>if self.tm.lrnIterationIdx > self.dutyCycleTiers[tierIdx]:<EOL><INDENT>alpha = self.dutyCycleAlphas[tierIdx]<EOL>break<EOL><DEDENT><DEDENT>dutyCycle = pow(<NUM_LIT:1.0>-alpha, age) * self._lastPosDutyCycle<EOL>if active:<EOL><INDENT>dutyCycle += alpha<EOL><DEDENT>if not readOnly:<EOL><INDENT>self._lastPosDutyCycleIteration = self.tm.lrnIterationIdx<EOL>self._lastPosDutyCycle = dutyCycle<EOL><DEDENT>return dutyCycle<EOL>

Compute/update and return the positive activations duty cycle of
        this segment. This is a measure of how often this segment is
        providing good predictions.

        :param active   True if segment just provided a good prediction

        :param readOnly If True, compute the updated duty cycle, but don't change
                   the cached value. This is used by debugging print statements.

        :returns: The duty cycle, a measure of how often this segment is
        providing good predictions.

        **NOTE:** This method relies on different schemes to compute the duty cycle
        based on how much history we have. In order to support this tiered
        approach **IT MUST BE CALLED ON EVERY SEGMENT AT EACH DUTY CYCLE TIER**
        (@ref dutyCycleTiers).

        When we don't have a lot of history yet (first tier), we simply return
        number of positive activations / total number of iterations

        After a certain number of iterations have accumulated, it converts into
        a moving average calculation, which is updated only when requested
        since it can be a bit expensive to compute on every iteration (it uses
        the pow() function).

        The duty cycle is computed as follows:

            dc[t] = (1-alpha) * dc[t-1] + alpha * value[t]

        If the value[t] has been 0 for a number of steps in a row, you can apply
        all of the updates at once using:

            dc[t] = (1-alpha)^(t-lastT) * dc[lastT]

        We use the alphas and tiers as defined in @ref dutyCycleAlphas and
        @ref dutyCycleTiers.


<EOL>print("<STR_LIT>" % (self.segID), end='<STR_LIT:U+0020>')<EOL>if self.isSequenceSeg:<EOL><INDENT>print("<STR_LIT:True>", end='<STR_LIT:U+0020>')<EOL><DEDENT>else:<EOL><INDENT>print("<STR_LIT:False>", end='<STR_LIT:U+0020>')<EOL><DEDENT>print("<STR_LIT>" % (self.dutyCycle(readOnly=True)), end='<STR_LIT:U+0020>')<EOL>print("<STR_LIT>" % (self.positiveActivations,<EOL>self.totalActivations), end='<STR_LIT:U+0020>')<EOL>print("<STR_LIT>" % (self.tm.lrnIterationIdx - self.lastActiveIteration), end='<STR_LIT:U+0020>')<EOL>sortedSyns = sorted(self.syns)<EOL>for _, synapse in enumerate(sortedSyns):<EOL><INDENT>print("<STR_LIT>" % (synapse[<NUM_LIT:0>], synapse[<NUM_LIT:1>], synapse[<NUM_LIT:2>]), end='<STR_LIT:U+0020>')<EOL><DEDENT>print()<EOL>

Print segment information for verbose messaging and debugging.
        This uses the following format:

         ID:54413 True 0.64801 (24/36) 101 [9,1]0.75 [10,1]0.75 [11,1]0.75

        where:
          54413 - is the unique segment id
          True - is sequence segment
          0.64801 - moving average duty cycle
          (24/36) - (numPositiveActivations / numTotalActivations)
          101 - age, number of iterations since last activated
          [9,1]0.75 - synapse from column 9, cell #1, strength 0.75
          [10,1]0.75 - synapse from column 10, cell #1, strength 0.75
          [11,1]0.75 - synapse from column 11, cell #1, strength 0.75


def freeNSynapses(self, numToFree, inactiveSynapseIndices, verbosity= <NUM_LIT:0>):

<EOL>assert (numToFree <= len(self.syns))<EOL>if (verbosity >= <NUM_LIT:4>):<EOL><INDENT>print("<STR_LIT>", numToFree, end='<STR_LIT:U+0020>')<EOL>print("<STR_LIT>", end='<STR_LIT:U+0020>')<EOL>for i in inactiveSynapseIndices:<EOL><INDENT>print(self.syns[i][<NUM_LIT:0>:<NUM_LIT:2>], end='<STR_LIT:U+0020>')<EOL><DEDENT>print()<EOL><DEDENT>if len(inactiveSynapseIndices) > <NUM_LIT:0>:<EOL><INDENT>perms = numpy.array([self.syns[i][<NUM_LIT:2>] for i in inactiveSynapseIndices])<EOL>candidates = numpy.array(inactiveSynapseIndices)[<EOL>perms.argsort()[<NUM_LIT:0>:numToFree]]<EOL>candidates = list(candidates)<EOL><DEDENT>else:<EOL><INDENT>candidates = []<EOL><DEDENT>if len(candidates) < numToFree:<EOL><INDENT>activeSynIndices = [i for i in range(len(self.syns))<EOL>if i not in inactiveSynapseIndices]<EOL>perms = numpy.array([self.syns[i][<NUM_LIT:2>] for i in activeSynIndices])<EOL>moreToFree = numToFree - len(candidates)<EOL>moreCandidates = numpy.array(activeSynIndices)[<EOL>perms.argsort()[<NUM_LIT:0>:moreToFree]]<EOL>candidates += list(moreCandidates)<EOL><DEDENT>if verbosity >= <NUM_LIT:4>:<EOL><INDENT>print("<STR_LIT>" % (<EOL>len(candidates)), candidates)<EOL>print("<STR_LIT>", end='<STR_LIT:U+0020>')<EOL>self.debugPrint()<EOL><DEDENT>synsToDelete = [self.syns[i] for i in candidates]<EOL>for syn in synsToDelete:<EOL><INDENT>self.syns.remove(syn)<EOL><DEDENT>if verbosity >= <NUM_LIT:4>:<EOL><INDENT>print("<STR_LIT>", end='<STR_LIT:U+0020>')<EOL>self.debugPrint()<EOL><DEDENT>

Free up some synapses in this segment. We always free up inactive
        synapses (lowest permanence freed up first) before we start to free up
        active ones.

        :param numToFree              number of synapses to free up
        :param inactiveSynapseIndices list of the inactive synapse indices.


def addSynapse(self, srcCellCol, srcCellIdx, perm):

self.syns.append([int(srcCellCol), int(srcCellIdx), numpy.float32(perm)])<EOL>

Add a new synapse

        :param srcCellCol source cell column
        :param srcCellIdx source cell index within the column
        :param perm       initial permanence


def updateSynapses(self, synapses, delta):

reached0 = False<EOL>if delta > <NUM_LIT:0>:<EOL><INDENT>for synapse in synapses:<EOL><INDENT>self.syns[synapse][<NUM_LIT:2>] = newValue = self.syns[synapse][<NUM_LIT:2>] + delta<EOL>if newValue > self.tm.permanenceMax:<EOL><INDENT>self.syns[synapse][<NUM_LIT:2>] = self.tm.permanenceMax<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>for synapse in synapses:<EOL><INDENT>self.syns[synapse][<NUM_LIT:2>] = newValue = self.syns[synapse][<NUM_LIT:2>] + delta<EOL>if newValue <= <NUM_LIT:0>:<EOL><INDENT>self.syns[synapse][<NUM_LIT:2>] = <NUM_LIT:0><EOL>reached0 = True<EOL><DEDENT><DEDENT><DEDENT>return reached0<EOL>

Update a set of synapses in the segment.

        :param tm       The owner TM
        :param synapses List of synapse indices to update
        :param delta    How much to add to each permanence

        :returns:   True if synapse reached 0


i = bisect_left(arr, val)<EOL>if i != len(arr) and arr[i] == val:<EOL><INDENT>return i<EOL><DEDENT>return -<NUM_LIT:1><EOL>

Function for running binary search on a sorted list.

:param arr: (list) a sorted list of integers to search
:param val: (int)  a integer to search for in the sorted array
:returns: (int) the index of the element if it is found and -1 otherwise.


return (self.cell == other.cell and<EOL>(sorted(self._synapses, key=lambda x: x._ordinal) ==<EOL>sorted(other._synapses, key=lambda x: x._ordinal)))<EOL>

Explicitly implement this for unit testing. The flatIdx is not designed
        to be consistent after serialize / deserialize, and the synapses might not
        enumerate in the same order.


return (self.segment.cell == other.segment.cell and<EOL>self.presynapticCell == other.presynapticCell and<EOL>abs(self.permanence - other.permanence) < EPSILON)<EOL>

Explicitly implement this for unit testing. Allow floating point
        differences for synapse permanence.


return self._cells[cell]._segments<EOL>

Returns the segments that belong to a cell.

:param cell: (int) Cell index
:returns: (list) Segment objects representing segments on the given cell.


return segment._synapses<EOL>

Returns the synapses on a segment.

:param segment: (int) Segment index
:returns: (set) Synapse objects representing synapses on the given segment.


return synapse<EOL>

Returns the data for a synapse.

.. note:: This method exists to match the interface of the C++ Connections.
   This allows tests and tools to inspect the connections using a common
   interface.

:param synapse: (:class:`Synapse`)
:returns: Synapse data


return segment<EOL>

Returns the data for a segment.

.. note:: This method exists to match the interface of the C++ Connections.
   This allows tests and tools to inspect the connections using a common
   interface.

:param segment (:class:`Segment`)
:returns: segment data