Skip to content

Commit e73b54b

Browse files
committed
TM: activateDendrites now uses SDR
removes old alternative with vectors
1 parent 7d172b1 commit e73b54b

File tree

3 files changed

+25
-49
lines changed

3 files changed

+25
-49
lines changed

src/nupic/algorithms/TemporalMemory.cpp

Lines changed: 12 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,7 @@ void TemporalMemory::activateCells(const SDR &activeColumns, const bool learn) {
522522
segmentsValid_ = false;
523523
}
524524

525+
525526
void TemporalMemory::activateDendrites(const bool learn,
526527
const SDR &extraActive,
527528
const SDR &extraWinners)
@@ -536,48 +537,24 @@ void TemporalMemory::activateDendrites(const bool learn,
536537
both.intersection(extraActive, extraWinners);
537538
NTA_ASSERT(both == extraWinners) << "ExtraWinners must be a subset of ExtraActive";
538539
#endif
539-
activateDendrites( learn, extraActive.getSparse(),
540-
extraWinners.getSparse());
541540
}
542541
else
543542
{
544543
NTA_CHECK( extraActive.getSum() == 0u && extraWinners.getSum() == 0u )
545544
<< "External predictive inputs must be declared to TM constructor!";
546-
activateDendrites(learn);
547545
}
548-
}
549546

550-
void TemporalMemory::activateDendrites(const bool learn,
551-
const vector<UInt> &extraActive,
552-
const vector<UInt> &extraWinners)
553-
{
547+
554548
if( segmentsValid_ )
555549
return;
556550

557-
// Handle external predictive inputs. extraActive & extraWinners default
558-
// values are `vector({ SENTINEL })`
559-
const auto SENTINEL = std::numeric_limits<UInt>::max();
560-
if( extra_ )
561-
{
562-
NTA_CHECK( extraActive.size() != 1 || extraActive[0] != SENTINEL )
563-
<< "TM.ActivateDendrites() missing argument extraActive!";
564-
NTA_CHECK( extraWinners.size() != 1 || extraWinners[0] != SENTINEL )
565-
<< "TM.ActivateDendrites() missing argument extraWinners!";
566-
567-
for(const auto &active : extraActive) {
551+
for(const auto &active : extraActive.getSparse()) {
568552
NTA_ASSERT( active < extra_ );
569553
activeCells_.push_back( static_cast<CellIdx>(active + numberOfCells()) );
570-
}
571-
for(const auto &winner : extraWinners) {
554+
}
555+
for(const auto &winner : extraWinners.getSparse()) {
572556
NTA_ASSERT( winner < extra_ );
573557
winnerCells_.push_back( static_cast<CellIdx>(winner + numberOfCells()) );
574-
}
575-
}
576-
else {
577-
NTA_CHECK( extraActive.size() == 1 && extraActive[0] == SENTINEL )
578-
<< "External predictive inputs must be declared to TM constructor!";
579-
NTA_CHECK( extraWinners.size() == 1 && extraWinners[0] == SENTINEL )
580-
<< "External predictive inputs must be declared to TM constructor!";
581558
}
582559

583560
const size_t length = connections.segmentFlatListLength();
@@ -590,16 +567,13 @@ void TemporalMemory::activateDendrites(const bool learn,
590567

591568
// Active segments, connected synapses.
592569
activeSegments_.clear();
593-
for (Segment segment = 0;
594-
segment < numActiveConnectedSynapsesForSegment_.size(); segment++) {
595-
if (numActiveConnectedSynapsesForSegment_[segment] >=
596-
activationThreshold_) {
570+
for (Segment segment = 0; segment < numActiveConnectedSynapsesForSegment_.size(); segment++) {
571+
if (numActiveConnectedSynapsesForSegment_[segment] >= activationThreshold_) {
597572
activeSegments_.push_back(segment);
598573
}
599574
}
600-
std::sort(
601-
activeSegments_.begin(), activeSegments_.end(),
602-
[&](Segment a, Segment b) { return connections.compareSegments(a, b); });
575+
const auto compareSegments = [&](const Segment a, const Segment b) { return connections.compareSegments(a, b); };
576+
std::sort( activeSegments_.begin(), activeSegments_.end(), compareSegments);
603577
// Update segment bookkeeping.
604578
if (learn) {
605579
for (const auto &segment : activeSegments_) {
@@ -610,19 +584,17 @@ void TemporalMemory::activateDendrites(const bool learn,
610584

611585
// Matching segments, potential synapses.
612586
matchingSegments_.clear();
613-
for (Segment segment = 0;
614-
segment < numActivePotentialSynapsesForSegment_.size(); segment++) {
587+
for (Segment segment = 0; segment < numActivePotentialSynapsesForSegment_.size(); segment++) {
615588
if (numActivePotentialSynapsesForSegment_[segment] >= minThreshold_) {
616589
matchingSegments_.push_back(segment);
617590
}
618591
}
619-
std::sort(
620-
matchingSegments_.begin(), matchingSegments_.end(),
621-
[&](Segment a, Segment b) { return connections.compareSegments(a, b); });
592+
std::sort( matchingSegments_.begin(), matchingSegments_.end(), compareSegments);
622593

623594
segmentsValid_ = true;
624595
}
625596

597+
626598
void TemporalMemory::compute(const SDR &activeColumns,
627599
const bool learn,
628600
const SDR &extraActive,

src/nupic/algorithms/TemporalMemory.hpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -215,26 +215,28 @@ using namespace nupic::algorithms::connections;
215215
* used during segment cleanup.
216216
*
217217
* @param extraActive
218-
* (optional) Vector of active external predictive inputs. External inputs must be cell
218+
* (optional) SDR of active external predictive inputs. External inputs must be cell
219219
* indexes in the range [0, extra).
220220
*
221221
* @param extraWinners
222-
* (optional) Vector of winning external predictive inputs. When learning, only these
222+
* (optional) SDR of winning external predictive inputs. When learning, only these
223223
* inputs are considered active.
224224
* ExtraWinners must be a subset of extraActive.
225225
* External inputs must be cell indices in the range [0, extra).
226226
*
227227
* See TM::compute() for details of the parameters.
228228
*
229229
*/
230-
void activateDendrites(const bool learn = true,
231-
const vector<UInt> &extraActive = {std::numeric_limits<UInt>::max()},
232-
const vector<UInt> &extraWinners = {std::numeric_limits<UInt>::max()});
233-
234-
void activateDendrites(const bool learn, //TODO provide convenience overload activateDendrites(bool), and remove the vector version
230+
void activateDendrites(const bool learn,
235231
const sdr::SDR &extraActive,
236232
const sdr::SDR &extraWinners);
237233

234+
inline void activateDendrites(const bool learn = true) {
235+
const sdr::SDR extraActive(std::vector<UInt>{ extra });
236+
const sdr::SDR extraWinners(std::vector<UInt>{extra });
237+
activateDendrites(learn, extraActive, extraWinners);
238+
}
239+
238240
/**
239241
* Perform one time step of the Temporal Memory algorithm.
240242
*

src/test/unit/algorithms/TemporalMemoryTest.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1665,9 +1665,11 @@ TEST(TemporalMemoryTest, testExtraActive) {
16651665
// Test the test: Verify that when the external inputs are missing this test
16661666
// fails.
16671667
tm.reset();
1668+
extraActive.zero(); //zero out the external inputs
1669+
extraWinners.zero();
16681670
for(const auto &x : pattern) {
16691671
// Predict whats going to happen.
1670-
tm.activateDendrites(true, vector<UInt>({}), vector<UInt>({}));
1672+
tm.activateDendrites(true, extraActive, extraWinners);
16711673
auto predictedCells = tm.getPredictiveCells();
16721674
ASSERT_TRUE( predictedCells.getSum() == 0 ); // No predictions, numActive < threshold
16731675
// Calculate TM output
@@ -1692,7 +1694,7 @@ TEST(TemporalMemoryTest, testEquals) {
16921694

16931695
TEST(TemporalMemoryTest, testIncorrectDefaultConstructor) {
16941696
TemporalMemory tmFail; //default empty constructor is only used for deserialization
1695-
SDR data1({tmFail.getColumnDimensions()});
1697+
SDR data1({0});
16961698
EXPECT_ANY_THROW(tmFail.compute(data1, true));
16971699

16981700
TemporalMemory tmOk({32} /*column dims must always be specified*/);

0 commit comments

Comments
 (0)