diff --git a/src/nupic/algorithms/SpatialPooler.cpp b/src/nupic/algorithms/SpatialPooler.cpp index bd8b366173..3617aeb08e 100644 --- a/src/nupic/algorithms/SpatialPooler.cpp +++ b/src/nupic/algorithms/SpatialPooler.cpp @@ -186,7 +186,7 @@ UInt SpatialPooler::getPotentialRadius() const void SpatialPooler::setPotentialRadius(UInt potentialRadius) { - potentialRadius_ = potentialRadius; + potentialRadius_ = std::min(potentialRadius, numInputs_); //crop to numInputs (input size) } Real SpatialPooler::getPotentialPct() const @@ -196,6 +196,7 @@ Real SpatialPooler::getPotentialPct() const void SpatialPooler::setPotentialPct(Real potentialPct) { + NTA_ASSERT(potentialPct > 0 && potentialPct <= 1); //bounds check potentialPct_ = potentialPct; } @@ -219,7 +220,7 @@ void SpatialPooler::setNumActiveColumnsPerInhArea( { NTA_ASSERT(numActiveColumnsPerInhArea > 0); numActiveColumnsPerInhArea_ = numActiveColumnsPerInhArea; - localAreaDensity_ = 0; + localAreaDensity_ = -1; //disabling } Real SpatialPooler::getLocalAreaDensity() const @@ -231,7 +232,7 @@ void SpatialPooler::setLocalAreaDensity(Real localAreaDensity) { NTA_ASSERT(localAreaDensity > 0 && localAreaDensity <= 1); localAreaDensity_ = localAreaDensity; - numActiveColumnsPerInhArea_ = 0; + numActiveColumnsPerInhArea_ = 0; //disabling } UInt SpatialPooler::getStimulusThreshold() const diff --git a/src/test/unit/algorithms/SpatialPoolerTest.cpp b/src/test/unit/algorithms/SpatialPoolerTest.cpp index 88f3882a2e..17b2d3090f 100644 --- a/src/test/unit/algorithms/SpatialPoolerTest.cpp +++ b/src/test/unit/algorithms/SpatialPoolerTest.cpp @@ -2222,6 +2222,46 @@ namespace { EXPECT_EQ(0, countNonzero(activeColumns)); } + + TEST(SpatialPoolerTest, testDifferentConstructorVsSetterBehavior) + { + /** this test exposes wrong behavior, where SP created via constructor + behaves differently to a SP via setters (setXXX()), both with the same + params. + */ + SpatialPooler spConstruct{std::vector{10} /* input*/, std::vector{2048}/* SP output cols XXX sensitive*/, + /*pot radius*/ 20, //each col sees + /*pot pct*/ 0.5, //XXX sensitive + /*global inhibition*/ false, //XXX sensitive + /*Real localAreaDensity=*/0.02, //2% active cols + /*UInt numActiveColumnsPerInhArea=*/0, //mutex with above ^^ //XXX sensitive +}; + + SpatialPooler sp{std::vector{10} /* input*/, std::vector{2048}/* SP output cols */}; +sp.setPotentialRadius(20); +sp.setPotentialPct(0.5); +sp.setGlobalInhibition(false); +sp.setLocalAreaDensity(0.02); //2% active cols +//! sp.setNumActiveColumnsPerInhArea(0); //mutex with above ^^ + + // test 1: these two mutex settings had err compared to the API + // (localAreaDensity & numActiveColumnsPerInhArea) + sp.setNumActiveColumnsPerInhArea(5); + EXPECT_EQ(sp.getNumActiveColumnsPerInhArea(), 5); + EXPECT_FLOAT_EQ(sp.getLocalAreaDensity(), -1); //-1 means disabled + + sp.setLocalAreaDensity(0.02); + EXPECT_EQ(sp.getNumActiveColumnsPerInhArea(), 0); //0 means disabled + EXPECT_FLOAT_EQ(sp.getLocalAreaDensity(), 0.02); + + //test 2: compare potentialRadius + EXPECT_EQ(sp.getPotentialRadius(), spConstruct.getPotentialRadius()); + + // EXPECT_EQ(spConstruct, sp); //FIXME how compare 2 SP + check_spatial_eq(spConstruct, sp); +} + + TEST(SpatialPoolerTest, testSaveLoad) { const char* filename = "SpatialPoolerSerialization.tmp";