Skip to content

Commit bfd7a6a

Browse files
committed
Merge pull request #331 from cogmission/prep_v0.6.3
Prep v0.6.3
2 parents e7650e3 + 59d4264 commit bfd7a6a

6 files changed

Lines changed: 178 additions & 17 deletions

File tree

build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ apply plugin: 'eclipse'
44
apply plugin: 'signing'
55

66
group = 'org.numenta'
7-
version = '0.6.3-SNAPSHOT'
7+
version = '0.6.3'
88
archivesBaseName = 'htm.java'
99

1010
sourceCompatibility = 1.8
1111
targetCompatibility = 1.8
1212

1313
jar {
1414
manifest {
15-
attributes 'Implementation-Title': 'htm.java', 'Implementation-Version': '0.6.3-SNAPSHOT'
15+
attributes 'Implementation-Title': 'htm.java', 'Implementation-Version': '0.6.3'
1616
}
1717
}
1818

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
<groupId>org.numenta</groupId>
66
<artifactId>htm.java</artifactId>
7-
<version>0.6.3-SNAPSHOT</version>
7+
<version>0.6.3</version>
88
<name>htm.java</name>
99
<description>The Java version of Numenta's HTM technology</description>
1010

src/main/java/org/numenta/nupic/network/Layer.java

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -816,7 +816,11 @@ public void start() {
816816

817817
this.encoder = encoder == null ? sensor.getEncoder() : encoder;
818818

819-
completeDispatch((T)new int[] {});
819+
try {
820+
completeDispatch((T)new int[] {});
821+
}catch(Exception e) {
822+
notifyError(e);
823+
}
820824

821825
(LAYER_THREAD = new Thread("Sensor Layer [" + getName() + "] Thread") {
822826
public void run() {
@@ -832,9 +836,14 @@ public void run() {
832836
return false;
833837
}
834838

839+
if(Thread.currentThread().isInterrupted()) {
840+
notifyError(new RuntimeException("Unknown Exception while filtering input"));
841+
}
842+
835843
return true;
836844
}).forEach(intArray -> {
837845
((ManualInput)Layer.this.factory.inference).encoding(intArray);
846+
838847
Layer.this.compute((T)intArray);
839848

840849
// Notify all downstream observers that the stream is closed
@@ -1194,6 +1203,21 @@ void notifyComplete() {
11941203
publisher.onCompleted();
11951204
}
11961205

1206+
/**
1207+
* Called internally to propagate the specified {@link Exception}
1208+
* up the network hierarchy
1209+
* @param e the exception to notify users of
1210+
*/
1211+
void notifyError(Exception e) {
1212+
for(Observer<Inference> o : subscribers) {
1213+
o.onError(e);
1214+
}
1215+
for(Observer<Inference> o : observers) {
1216+
o.onError(e);
1217+
}
1218+
publisher.onError(e);
1219+
}
1220+
11971221
/**
11981222
* <p>
11991223
* Returns the content mask used to indicate what algorithm
@@ -1305,9 +1329,13 @@ private Map<Class<T>, Observable<ManualInput>> createDispatchMap() {
13051329
private Observable<ManualInput> mapEncoderBuckets(Observable<ManualInput> sequence) {
13061330
if(hasSensor()) {
13071331
if(getSensor().getMetaInfo().getFieldTypes().stream().anyMatch(
1308-
ft -> { return ft == FieldMetaType.SARR || ft == FieldMetaType.DARR; })) {
1332+
ft -> { return ft == FieldMetaType.SARR ||
1333+
ft == FieldMetaType.DARR ||
1334+
ft == FieldMetaType.COORD ||
1335+
ft == FieldMetaType.GEO; })) {
13091336
if(autoCreateClassifiers) {
1310-
throw new IllegalStateException("Cannot autoclassify with raw array input... Remove auto classify setting.");
1337+
throw new IllegalStateException("Cannot autoclassify with raw array input or " +
1338+
" Coordinate based encoders... Remove auto classify setting.");
13111339
}
13121340
return sequence;
13131341
}
@@ -1680,7 +1708,7 @@ public ManualInput call(String[] t1) {
16801708
sdr[i] = Integer.parseInt(t1[i]);
16811709
}
16821710

1683-
return inference.sdr(sdr).layerInput(sdr);
1711+
return inference.recordNum(getRecordNum()).sdr(sdr).layerInput(sdr);
16841712
}
16851713
});
16861714
}
@@ -1718,7 +1746,7 @@ public ManualInput call(Map t1) {
17181746

17191747
doEncoderBucketMapping(inference, t1);
17201748

1721-
return inference.layerInput(t1);
1749+
return inference.recordNum(getRecordNum()).layerInput(t1);
17221750
}
17231751
});
17241752
}
@@ -1740,7 +1768,7 @@ public Observable<ManualInput> call(Observable<int[]> t1) {
17401768
@Override
17411769
public ManualInput call(int[] t1) {
17421770
// Indicates a value that skips the encoding step
1743-
return inference.sdr(t1).layerInput(t1);
1771+
return inference.recordNum(getRecordNum()).sdr(t1).layerInput(t1);
17441772
}
17451773
});
17461774
}
@@ -1767,7 +1795,7 @@ public ManualInput call(ManualInput t1) {
17671795
swapped = true;
17681796
}
17691797
// Indicates a value that skips the encoding step
1770-
return inference.sdr(t1.getSDR()).recordNum(t1.getRecordNum()).layerInput(t1);
1798+
return inference.recordNum(getRecordNum()).sdr(t1.getSDR()).recordNum(t1.getRecordNum()).layerInput(t1);
17711799
}
17721800
});
17731801
}

src/test/java/org/numenta/nupic/network/LayerTest.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ public void testLayerWithObservableInput() {
401401
fail();
402402
}
403403
}
404-
404+
405405
@Test
406406
public void testLayerWithObservableInputIntegerArray() {
407407
Publisher manual = Publisher.builder()
@@ -784,15 +784,15 @@ public void testBasicSetup_TemporalMemory_MANUAL_MODE() {
784784
int[] expected1 = { 1, 5, 11, 12, 13 };
785785
int[] expected2 = { 2, 3, 11, 12, 13, 14 };
786786
int[] expected3 = { 2, 3, 8, 9, 12, 17, 18 };
787-
int[] expected4 = { 2, 3, 8, 12, 17, 18 };
788-
int[] expected5 = { 2, 7, 8, 9, 17, 18, 19 };
789-
int[] expected6 = { 1, 7, 8, 9, 17, 18 };
790-
int[] expected7 = { 1, 5, 7, 11, 12, 16 };
787+
int[] expected4 = { 2, 3, 7, 8, 9, 12, 17, 18, 19 };
788+
int[] expected5 = { 1, 2, 3, 7, 8, 9, 12, 17, 18, 19 };
789+
int[] expected6 = { 1, 5, 7, 8, 9, 11, 12, 16, 17, 18, 19 };
790+
int[] expected7 = { 1, 5, 7, 8, 9, 11, 12, 16, 17, 18 };
791791
final int[][] expecteds = { expected1, expected2, expected3, expected4, expected5, expected6, expected7 };
792792

793793
Layer<int[]> l = new Layer<>(p, null, null, new TemporalMemory(), null, null);
794794

795-
int timeUntilStable = 400;
795+
int timeUntilStable = 600;
796796

797797
l.subscribe(new Observer<Inference>() {
798798
int test = 0;
@@ -803,7 +803,8 @@ public void testBasicSetup_TemporalMemory_MANUAL_MODE() {
803803
@Override
804804
public void onNext(Inference output) {
805805
if(seq / 7 >= timeUntilStable) {
806-
//System.out.println("seq: " + (seq) + " --> " + (test) + " output = " + Arrays.toString(output.getSDR()));
806+
// System.out.println("seq: " + (seq) + " --> " + (test) + " output = " + Arrays.toString(output.getSDR()) +
807+
// "\t\t\t\t\t exp = " + Arrays.toString(expecteds[test]));
807808
assertTrue(Arrays.equals(expecteds[test], output.getSDR()));
808809
}
809810

src/test/java/org/numenta/nupic/network/NetworkTest.java

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@
4646
import org.numenta.nupic.datagen.ResourceLocator;
4747
import org.numenta.nupic.encoders.MultiEncoder;
4848
import org.numenta.nupic.network.sensor.FileSensor;
49+
import org.numenta.nupic.network.sensor.HTMSensor;
50+
import org.numenta.nupic.network.sensor.ObservableSensor;
51+
import org.numenta.nupic.network.sensor.Publisher;
4952
import org.numenta.nupic.network.sensor.Sensor;
5053
import org.numenta.nupic.network.sensor.SensorParams;
5154
import org.numenta.nupic.network.sensor.SensorParams.Keys;
@@ -636,4 +639,129 @@ public void testThreadedStartFlagging() {
636639
}
637640
}
638641

642+
double anomaly = 1;
643+
boolean completed = false;
644+
@Test
645+
public void testObservableWithCoordinateEncoder() {
646+
Publisher manual = Publisher.builder()
647+
.addHeader("timestamp,consumption,location")
648+
.addHeader("datetime,float,geo")
649+
.addHeader("T,,").build();
650+
651+
Sensor<ObservableSensor<String[]>> sensor = Sensor.create(
652+
ObservableSensor::create, SensorParams.create(Keys::obs, "", manual));
653+
654+
Parameters p = NetworkTestHarness.getParameters().copy();
655+
p = p.union(NetworkTestHarness.getGeospatialTestEncoderParams());
656+
p.setParameterByKey(KEY.RANDOM, new MersenneTwister(42));
657+
658+
HTMSensor<ObservableSensor<String[]>> htmSensor = (HTMSensor<ObservableSensor<String[]>>)sensor;
659+
660+
Network network = Network.create("test network", p)
661+
.add(Network.createRegion("r1")
662+
.add(Network.createLayer("1", p)
663+
.add(Anomaly.create())
664+
.add(new TemporalMemory())
665+
.add(new SpatialPooler())
666+
.add(htmSensor)));
667+
668+
network.start();
669+
670+
network.observe().subscribe(new Observer<Inference>() {
671+
@Override public void onCompleted() {
672+
assertEquals(0, anomaly, 0);
673+
completed = true;
674+
}
675+
@Override public void onError(Throwable e) { e.printStackTrace(); }
676+
@Override public void onNext(Inference output) {
677+
//System.out.println(output.getRecordNum() + ": input = " + Arrays.toString(output.getEncoding()));//output = " + Arrays.toString(output.getSDR()) + ", " + output.getAnomalyScore());
678+
if(output.getAnomalyScore() < anomaly) {
679+
anomaly = output.getAnomalyScore();
680+
System.out.println("anomaly = " + anomaly);
681+
}
682+
}
683+
});
684+
685+
int x = 0;
686+
for(int i = 0;i < 100;i++) {
687+
x = i % 10;
688+
manual.onNext("7/12/10 13:10,35.3,40.6457;-73.7" + x + "692;" + x); //5 = meters per second
689+
}
690+
691+
manual.onComplete();
692+
693+
Layer<?> l = network.lookup("r1").lookup("1");
694+
try {
695+
l.getLayerThread().join();
696+
}catch(Exception e) {
697+
e.printStackTrace();
698+
}
699+
700+
assertTrue(completed);
701+
702+
}
703+
704+
String errorMessage = null;
705+
@Test
706+
public void testObservableWithCoordinateEncoder_NEGATIVE() {
707+
Publisher manual = Publisher.builder()
708+
.addHeader("timestamp,consumption,location")
709+
.addHeader("datetime,float,geo")
710+
.addHeader("T,,").build();
711+
712+
Sensor<ObservableSensor<String[]>> sensor = Sensor.create(
713+
ObservableSensor::create, SensorParams.create(Keys::obs, "", manual));
714+
715+
Parameters p = NetworkTestHarness.getParameters().copy();
716+
p = p.union(NetworkTestHarness.getGeospatialTestEncoderParams());
717+
p.setParameterByKey(KEY.RANDOM, new MersenneTwister(42));
718+
719+
HTMSensor<ObservableSensor<String[]>> htmSensor = (HTMSensor<ObservableSensor<String[]>>)sensor;
720+
721+
Network network = Network.create("test network", p)
722+
.add(Network.createRegion("r1")
723+
.add(Network.createLayer("1", p)
724+
.alterParameter(KEY.AUTO_CLASSIFY, Boolean.TRUE)
725+
.add(Anomaly.create())
726+
.add(new TemporalMemory())
727+
.add(new SpatialPooler())
728+
.add(htmSensor)));
729+
730+
network.observe().subscribe(new Observer<Inference>() {
731+
@Override public void onCompleted() {
732+
//Should never happen here.
733+
assertEquals(0, anomaly, 0);
734+
completed = true;
735+
}
736+
@Override public void onError(Throwable e) {
737+
errorMessage = e.getMessage();
738+
network.halt();
739+
}
740+
@Override public void onNext(Inference output) {}
741+
});
742+
743+
network.start();
744+
745+
int x = 0;
746+
for(int i = 0;i < 100;i++) {
747+
x = i % 10;
748+
manual.onNext("7/12/10 13:10,35.3,40.6457;-73.7" + x + "692;" + x); //1st "x" is attempt to vary coords, 2nd "x" = meters per second
749+
}
750+
751+
manual.onComplete();
752+
753+
Layer<?> l = network.lookup("r1").lookup("1");
754+
try {
755+
l.getLayerThread().join();
756+
}catch(Exception e) {
757+
assertEquals(InterruptedException.class, e.getClass());
758+
}
759+
760+
// Assert onNext condition never gets set
761+
assertFalse(completed);
762+
assertEquals("Cannot autoclassify with raw array input or " +
763+
"Coordinate based encoders... Remove auto classify setting.", errorMessage);
764+
}
765+
766+
639767
}

vocabulary.dictionary

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,3 +201,7 @@ timeline
201201
keyframes
202202
popup
203203
affero
204+
deselected
205+
coords
206+
expecteds
207+
exp

0 commit comments

Comments
 (0)