public void CanLearnAndInfer1OnRecognizedSubInputs_5By4Layer0_5Coverage()
        {
            uint maxoutputsize = 5;
            var coverage = 0.5;
            var clone = false;
            uint layerheight = 5;
            uint layerwidth = 4;
            int inputtolayerratio = 2;

            var layer = new Spatial2DLayer(SpatialLayerType.Gaussian, layerheight, layerwidth, coverage, clone, maxoutputsize);
            var input1 = new SparseMatrix((int)layerheight * inputtolayerratio, (int)layerwidth * inputtolayerratio, 1.0);
            var input2 = 2 * input1;

            //
            layer.Learn(input1);
            layer.Learn(input2);

            var infer2 = layer.Infer(input2);
            var infer1 = layer.Infer(input1);
            var input3 = (SparseMatrix)new SparseMatrix((int)layerwidth * inputtolayerratio, (int)layerwidth * inputtolayerratio, 1.0)
                .Stack(new SparseMatrix((int)(layerheight - layerwidth) * inputtolayerratio, (int)layerwidth * inputtolayerratio, 3.0));
            var infer3 = layer.Infer(input3);

            //
            foreach (var infer in new SparseMatrix[] { infer1, infer2, infer3 })
            {
                for (int row = 0; row < layerheight; row++)
                {
                    for (int col = 0; col < layerwidth * layer.MaxNodeOutputSize; col += layer.MaxNodeOutputSize)
                    {
                        var subInput = infer.SubMatrix(row, 1, col, layer.MaxNodeOutputSize);
                        if (infer.Equals(infer3) && row >= layerheight - 2 && row < layerheight)
                            for (int i = 0; i < subInput.ColumnCount; i++)
                                Assert.IsTrue(subInput[0, i] < 0.1);
                        else
                            Assert.IsTrue(subInput[0, 0] == 1.0 || subInput[0, 1] == 1.0);
                    }
                }
            }
        }
        public void SpatialLayer2DGaussianCanLearnAndInferFromBitmapPicture2DSensor()
        {
            var sensor = new BitmapPicture2DSensor(presentationsPerInput: 1, pathSpeed: 2, useRandomOrigin: false);
            sensor.SetTrainingFolder(TrainingSetPath);

            var layer = new Spatial2DLayer(SpatialLayerType.Gaussian, 16, 16, 0.1, true);

            foreach (var input in sensor.GetTrainingInputs(true))
            {
                foreach (var iteration in input)
                {
                    layer.Learn(iteration);
                }
            }

            Assert.IsTrue(((SpatialNode2DGaussian)layer.ClonedNode).CoincidencesFrequencies.Keys.Count > 0);
        }
        public void SeesCorrectSubmatrixWhenTrainingWith0_5Coverage()
        {
            var inputsize = 10;
            var size = (uint)inputsize / 2;
            var coverage = 0.5;
            var layer = new Spatial2DLayer(SpatialLayerType.Gaussian, size, size, coverage, true, 1000);

            var list = from i in Enumerable.Range(0, inputsize)
                       select (double)i;

            var matrix = new SparseMatrix(inputsize, inputsize);
            for (int i = 0; i < matrix.RowCount; ++i)
            {
                matrix.SetRow(i, list.ToArray());
            }

            // for each node in the 2D layer
            for (int nodeRow = 0; nodeRow < layer.Height; nodeRow++)
            {
                for (int nodeCol = 0; nodeCol < layer.Width; nodeCol++)
                {
                    // Act
                    var subMatrix = layer.GetSubMatrixForNodeAt(nodeRow, nodeCol, matrix);

                    // check if its 2D input is ok
                    var width = inputsize / size + coverage * (inputsize - inputsize / size);
                    var delta = (inputsize - width) / (size - 1);

                    for (int i = 0; i < (int)width; i++)
                    {
                        for (int j = 0; j < (int)width; j++)
                        {

                            Assert.AreEqual(nodeCol * delta + j, subMatrix[i, j]);
                        }
                    }
                }
            }
        }
        public void SeesCorrectSubmatrixWhenCloneTrainingWith0Coverage()
        {
            var inputsize = 10;
            var size = (uint)inputsize / 2;
            var coverage = 0.0;
            var layer = new Spatial2DLayer(SpatialLayerType.Gaussian, size, size, coverage, true, 1000);

            var list = from i in Enumerable.Range(0, inputsize)
                       select (double)i;

            var matrix = new SparseMatrix(inputsize, inputsize);
            for (int i = 0; i < matrix.RowCount; ++i)
            {
                matrix.SetRow(i, list.ToArray());
            }

            // Act
            var subMatrix = layer.GetSubMatrixForNodeAt(layer.ClonedNodeRow, layer.ClonedNodeCol, matrix);

            //
            var width = inputsize / size + coverage * (inputsize - inputsize / size);
            var delta = (inputsize - width) / (size - 1);

            var centerRow = layer.Height / 2;
            var centerCol = layer.Width / 2;

            for (int i = 0; i < (int)width; i++)
            {
                for (int j = 0; j < (int)width; j++)
                {
                    Assert.AreEqual(centerCol * delta + j, subMatrix[i, j]);
                }
            }
        }
        public void ErrorWhenLearningAfterLayerIsTrained()
        {
            var layer = new Spatial2DLayer(SpatialLayerType.Gaussian, 1, 1, 0.0, true, 1000);

            layer.Learn(new SparseMatrix(5));
            layer.Infer(new SparseMatrix(5));
            try
            {
                layer.Learn(new SparseMatrix(5));
                Assert.Inconclusive("Should have fired an exception");
            }
            catch (Exception e)
            {

                Debug.WriteLine(e.Message);
                Assert.IsInstanceOfType(e, typeof(HtmRuleException));
            }
        }
        public void CanLearnNewInputs_5By4Layer0Coverage()
        {
            uint maxoutputsize = 5;
            var coverage = 0.0;
            var clone = false;
            uint height = 5;
            uint width = 4;

            var layer = new Spatial2DLayer(SpatialLayerType.Gaussian, height, width, coverage, clone, maxoutputsize);
            var input1 = (SparseMatrix) SparseMatrix.Identity(8).Stack(new SparseMatrix(2, 8));
            var input2 = 2*input1;

            //
            layer.Learn(input1);
            layer.Learn(input2);

            //
            for (int i = 0; i < height; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    var node = (SpatialNode2DGaussian)layer.NodeArray[i, j];
                    foreach (var coinc in node.CoincidencesFrequencies)
                        Assert.AreEqual(1, coinc.Value);
                }
            }
        }