void Cell::Retire() { // Release all Segments. Segment *segment; while ((segment = (Segment*)(Segments.RemoveFirst())) != NULL) { mem_manager.ReleaseObject(segment); } // Release all SegmentsUpdateInfo objects. SegmentUpdateInfo *segmentUpdateInfo; while ((segmentUpdateInfo = (SegmentUpdateInfo*)(_segmentUpdates.RemoveFirst())) != NULL) { mem_manager.ReleaseObject(segmentUpdateInfo); } }
void FastHashTable::Remove(int _key, void *_object) { int bucket_index = _key & KEY_MASK; FastHashTray *tray_to_remove; // Get pointer to first tray pointer for this bucket. FastHashTray **tray_ptr = &(buckets[bucket_index]); // Iterate through all trays in this bucket, up to the point where the given _object is found. while (((*tray_ptr) != NULL) && ((*tray_ptr)->key <= _key)) { if (((*tray_ptr)->key == _key) && ((*tray_ptr)->pointer == _object)) { // Record pointer to this tray to be removed. tray_to_remove = (*tray_ptr); // Set the pointer that points to the tray to remove, to point to the next tray instead. (*tray_ptr) = (*tray_ptr)->next; // Release the tray that's been removed. mem_manager.ReleaseObject(tray_to_remove); // Decrement the count count--; // The objecthas been removed; return. return; } // Advance to the next tray tray_ptr = &((*tray_ptr)->next); } }
void FastHashTable::Clear() { FastHashTray *cur_tray, *next_tray; // If the table is already empty, just return. if (count == 0) { return; } for (int i = 0; i < NUM_BUCKETS; i++) { // Release all trays in the current bucket cur_tray = buckets[i]; while (cur_tray != NULL) { next_tray = cur_tray->next; mem_manager.ReleaseObject(cur_tray); cur_tray = next_tray; } // Set the current bucket pointer to NULL buckets[i] = NULL; } // Reset the count count = 0; // Reset the iterator iterator_cur = NULL; iterator_bucket_index = NUM_BUCKETS; }
/// This function reinforces each segment in this Cell's SegmentUpdateInfo. /// /// Using the segmentUpdateInfo, the following changes are /// performed. If positiveReinforcement is true then synapses on the active /// list get their permanence counts incremented by permanenceInc. All other /// synapses get their permanence counts decremented by permanenceDec. If /// positiveReinforcement is false, then synapses on the active list get /// their permanence counts decremented by permanenceDec. After this step, /// any synapses in segmentUpdate that do yet exist get added with a permanence /// count of initialPerm. These new synapses are randomly chosen from the /// set of all cells that have learnState output = 1 at time step t. ///</remarks> void Cell::ApplySegmentUpdates(int _curTime, ApplyUpdateTrigger _trigger) { Segment *segment; SegmentUpdateInfo *segInfo; Synapse *syn; FastList modifiedSegments; FastListIter synapses_iter, seg_update_iter; bool apply_update; // Iterate through all segment updates, skipping those not to be applied now, and removing those that are applied. seg_update_iter.SetList(_segmentUpdates); for (segInfo = (SegmentUpdateInfo*)(seg_update_iter.Reset()); segInfo != NULL; segInfo = (SegmentUpdateInfo*)(seg_update_iter.Get())) { // Do not apply the current segment update if it was created at the current time step, and was created as a result of the cell being predictive. // If this is the case, then this segment update can only be evaluated at a later time step, and so should remain in the queue for now. apply_update = !((segInfo->GetCreationTimeStep() == _curTime) && (segInfo->GetUpdateType() == UPDATE_DUE_TO_PREDICTIVE)); // Do not apply the current segment update if its numPredictionSteps > 1, and if we are applying updates due to the cell still being predictive, // but with a greater numPredictionSteps. Unless the segment being updated predicted activation in 1 prediction step, it cannot be proven // incorrect, and so shouldn't be processed yet. This is because a "prediction step" can take more than one time step. if ((_trigger == AUT_LONGER_PREDICTION) && (segInfo->GetNumPredictionSteps() > 1)) { apply_update = false; } if (apply_update) { segment = segInfo->GetSegment(); if (segment != NULL) { if (_trigger == AUT_ACTIVE) { // The cell has become actve; positively reinforce the segment. segment->UpdatePermanences(segInfo->ActiveDistalSynapses); } else { // The cell has become inactive of is predictive but with a longer prediction. Negatively reinforce the segment. segment->DecreasePermanences(segInfo->ActiveDistalSynapses); } // Record that this segment has been modified, so it can later be checked for synapses that should be removed. if (modifiedSegments.IsInList(segment) == false) { modifiedSegments.InsertAtEnd(segment); } } // Add new synapses (and new segment if necessary) if (segInfo->GetAddNewSynapses() && (_trigger == AUT_ACTIVE)) { if (segment == NULL) { if (segInfo->CellsThatWillLearn.Count() > 0) //only add if learning cells available { segment = segInfo->CreateCellSegment(column->region->GetStepCounter()); } } else if (segInfo->CellsThatWillLearn.Count() > 0) { //add new synapses to existing segment segInfo->CreateSynapsesToLearningCells(&(column->region->DistalSynapseParams)); } } // Remove and release the current SegmentUpdateInfo. seg_update_iter.Remove(); mem_manager.ReleaseObject(segInfo); } else { // Leave the current segment upate in the queue, to be processed at a later time step. Advance to the next one. seg_update_iter.Advance(); } } // Only process modified segments if all segment updates have been processed, to avoid deleting segments or synapses that // are referred to by still-existing segment updates. if (_segmentUpdates.Count() == 0) { // All segment updates have been processed, so there are none left that may have references to this cell's // synapses or segments. Therefore we can iterate through all segments modified above, to prune unneeded synpses and segments. while (modifiedSegments.Count() > 0) { // Get pointer to the current modified segment, and remove it from the modifiedSegments list. segment = (Segment*)(modifiedSegments.GetFirst()); modifiedSegments.RemoveFirst(); // Remove from the current modified segment any synapses that have reached permanence of 0. synapses_iter.SetList(segment->Synapses); for (syn = (Synapse*)(synapses_iter.Reset()); syn != NULL;) { if (syn->GetPermanence() == 0.0f) { // Remove and release the current synapse, whose permanence has reached 0. synapses_iter.Remove(); mem_manager.ReleaseObject(syn); // Removing the synapse has advanced the iterator to the next synapse. Get a pointer to it. syn = (Synapse*)(synapses_iter.Get()); } else { // Advance to the next synapse. syn = (Synapse*)(synapses_iter.Advance()); } } // If this modified segment now has no synapses, remove the segment from this cell. if (segment->Synapses.Count() == 0) { Segments.Remove(segment, false); mem_manager.ReleaseObject(segment); } } } else { // Not all of the segment updates have been processed, so synapses and segments cannot be pruned. // (because they may be referred to by segment updates that still exist). So just clear the list of modified segments. modifiedSegments.Clear(); } }