Example #1
0
        private void ActivateCellsInColumn(Connections conn, bool learn, Pair <Column, List <List <object> > > tuple, ComputeCycle cycle, ConcurrentDictionary <int, ComputeCycle> cycles, ISet <Cell> prevActiveCells, ISet <Cell> prevWinnerCells, double permanenceIncrement, double permanenceDecrement)
        {
            ColumnData activeColumnData = new ColumnData();

            activeColumnData.Set(tuple);

            if (activeColumnData.IsExistAnyActiveCol(cIndexofACTIVE_COLUMNS))
            {
                // If there are some active segments on the column already...
                if (activeColumnData.ActiveSegments != null && activeColumnData.ActiveSegments.Count > 0)
                {
                    //Debug.Write("A");

                    List <Cell> cellsOwnersOfActSegs = ActivatePredictedColumn(conn, activeColumnData.ActiveSegments,
                                                                               activeColumnData.MatchingSegments, prevActiveCells, prevWinnerCells,
                                                                               permanenceIncrement, permanenceDecrement, learn, cycle.ActiveSynapses);

                    ComputeCycle colCycle = new ComputeCycle();
                    cycles[tuple.Key.Index] = colCycle;

                    foreach (var item in cellsOwnersOfActSegs)
                    {
                        colCycle.ActiveCells.Add(item);
                        colCycle.WinnerCells.Add(item);
                    }
                }
                else
                {
                    Debug.Write("M");

                    //
                    // If no active segments are detected (start of learning) then all cells are activated
                    // and a random single cell is chosen as a winner.
                    BurstingResult burstingResult = BurstColumn(conn, activeColumnData.Column(), activeColumnData.MatchingSegments,
                                                                prevActiveCells, prevWinnerCells, permanenceIncrement, permanenceDecrement, conn.HtmConfig.Random,
                                                                learn);


                    ComputeCycle colCycle = new ComputeCycle();
                    cycles[tuple.Key.Index] = colCycle;

                    //
                    // Here we activate all cells by putting them to list of active cells.
                    foreach (var item in burstingResult.Cells)
                    {
                        colCycle.ActiveCells.Add(item);
                    }

                    colCycle.WinnerCells.Add((Cell)burstingResult.BestCell);
                }
            }
            else
            {
                if (learn)
                {
                    PunishPredictedColumn(conn, activeColumnData.ActiveSegments, activeColumnData.MatchingSegments,
                                          prevActiveCells, prevWinnerCells, conn.HtmConfig.PredictedSegmentDecrement);
                }
            }
        }
Example #2
0
        public void testPredictedActiveCellsAreAlwaysWinners()
        {
            TemporalMemory tm = new TemporalMemory();
            Connections    cn = new Connections();
            Parameters     p  = GetDefaultParameters();

            p.Apply(cn);
            TemporalMemory.Init(cn);

            int[]       previousActiveColumns = { 0 };
            int[]       activeColumns         = { 1 };
            Cell[]      previousActiveCells   = { cn.GetCell(0), cn.GetCell(1), cn.GetCell(2), cn.GetCell(3) };
            List <Cell> expectedWinnerCells   = new List <Cell>(cn.GetCellSet(new int[] { 4, 6 }));

            DistalDendrite activeSegment1 = cn.CreateSegment(expectedWinnerCells[0]);

            cn.CreateSynapse(activeSegment1, previousActiveCells[0], 0.5);
            cn.CreateSynapse(activeSegment1, previousActiveCells[1], 0.5);
            cn.CreateSynapse(activeSegment1, previousActiveCells[2], 0.5);

            DistalDendrite activeSegment2 = cn.CreateSegment(expectedWinnerCells[1]);

            cn.CreateSynapse(activeSegment2, previousActiveCells[0], 0.5);
            cn.CreateSynapse(activeSegment2, previousActiveCells[1], 0.5);
            cn.CreateSynapse(activeSegment2, previousActiveCells[2], 0.5);

            ComputeCycle cc = tm.Compute(cn, previousActiveColumns, false); // learn=false

            cc = tm.Compute(cn, activeColumns, false);                      // learn=false

            Assert.IsTrue(cc.winnerCells.SetEquals(new HashSet <Cell>(expectedWinnerCells)));
        }
Example #3
0
        public void testZeroActiveColumns()
        {
            TemporalMemory tm = new TemporalMemory();
            Connections    cn = new Connections();
            Parameters     p  = GetDefaultParameters();

            p.Apply(cn);
            TemporalMemory.Init(cn);

            int[] previousActiveColumns = { 0 };
            Cell  cell4 = cn.GetCell(4);

            DistalDendrite activeSegment = cn.CreateSegment(cell4);

            cn.CreateSynapse(activeSegment, cn.GetCell(0), 0.5);
            cn.CreateSynapse(activeSegment, cn.GetCell(1), 0.5);
            cn.CreateSynapse(activeSegment, cn.GetCell(2), 0.5);
            cn.CreateSynapse(activeSegment, cn.GetCell(3), 0.5);

            ComputeCycle cc = tm.Compute(cn, previousActiveColumns, true);

            Assert.IsFalse(cc.ActiveCells().Count == 0);
            Assert.IsFalse(cc.WinnerCells().Count == 0);
            Assert.IsFalse(cc.PredictiveCells().Count == 0);

            int[]        zeroColumns = new int[0];
            ComputeCycle cc2         = tm.Compute(cn, zeroColumns, true);

            Assert.IsTrue(cc2.ActiveCells().Count == 0);
            Assert.IsTrue(cc2.WinnerCells().Count == 0);
            Assert.IsTrue(cc2.PredictiveCells().Count == 0);
        }
Example #4
0
        public void TestActivateCorrectlyPredictiveCells()
        {
            TemporalMemory tm = new TemporalMemory();
            Connections    cn = new Connections();
            Parameters     p  = GetDefaultParameters();

            p.Apply(cn);
            TemporalMemory.Init(cn);

            int[]          previousActiveColumns = { 0 };
            int[]          activeColumns         = { 1 };
            Cell           cell4 = cn.GetCell(4);
            HashSet <Cell> expectedActiveCells = new HashSet <Cell> {
                cell4
            };                                                               //Stream.of(cell4).collect(Collectors.toSet());

            DistalDendrite activeSegment = cn.CreateSegment(cell4);

            cn.CreateSynapse(activeSegment, cn.GetCell(0), 0.5);
            cn.CreateSynapse(activeSegment, cn.GetCell(1), 0.5);
            cn.CreateSynapse(activeSegment, cn.GetCell(2), 0.5);
            cn.CreateSynapse(activeSegment, cn.GetCell(3), 0.5);

            ComputeCycle cc = tm.Compute(cn, previousActiveColumns, true);

            Assert.IsTrue(cc.PredictiveCells().SetEquals(expectedActiveCells));
            ComputeCycle cc2 = tm.Compute(cn, activeColumns, true);

            Assert.IsTrue(cc2.ActiveCells().SetEquals(expectedActiveCells));
        }
Example #5
0
        public void TestTemporalMemoryExplicit()
        {
            int[]   input1 = new int[] { 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0 };
            int[]   input2 = new int[] { 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0 };
            int[]   input3 = new int[] { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
            int[]   input4 = new int[] { 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0 };
            int[]   input5 = new int[] { 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0 };
            int[]   input6 = new int[] { 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1 };
            int[]   input7 = new int[] { 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0 };
            int[][] inputs = { input1, input2, input3, input4, input5, input6, input7 };

            Parameters  p   = GetParameters();
            Connections con = new Connections();

            p.Apply(con);
            TemporalMemory tm = new TemporalMemory();

            TemporalMemory.Init(con);

            ComputeCycle cc = null;

            for (int x = 0; x < 602; x++)
            {
                foreach (int[] i in inputs)
                {
                    cc = tm.Compute(con, ArrayUtils.Where(i, ArrayUtils.WHERE_1), true);
                }
            }

            TEST_AGGREGATION[TM_EXPL] = SDR.AsCellIndices(cc.activeCells);
        }
Example #6
0
        /// <summary>
        /// <inheritdoc/>
        /// </summary>
        /// <param name="conn"></param>
        /// <param name="activeColumnIndices"></param>
        /// <param name="learn"></param>
        /// <returns></returns>
        protected override ComputeCycle ActivateCells(Connections conn, int[] activeColumnIndices, bool learn)
        {
            ComputeCycle cycle = new ComputeCycle
            {
                ActivColumnIndicies = activeColumnIndices
            };

            ConcurrentDictionary <int, ComputeCycle> cycles = new ConcurrentDictionary <int, ComputeCycle>();

            ISet <Cell> prevActiveCells = conn.ActiveCells;
            ISet <Cell> prevWinnerCells = conn.WinnerCells;

            // The list of active columns.
            List <Column> activeColumns = new List <Column>();

            foreach (var indx in activeColumnIndices.OrderBy(i => i))
            {
                activeColumns.Add(conn.GetColumn(indx));
            }

            Func <Object, Column> segToCol = (segment) =>
            {
                var colIndx   = ((DistalDendrite)segment).ParentCell.ParentColumnIndex;
                var parentCol = this.connections.HtmConfig.Memory.GetColumn(colIndx);
                return(parentCol);
            };

            Func <object, Column> times1Fnc = x => (Column)x;

            var list = new Pair <List <object>, Func <object, Column> > [3];

            list[0] = new Pair <List <object>, Func <object, Column> >(Array.ConvertAll(activeColumns.ToArray(), item => (object)item).ToList(), times1Fnc);
            list[1] = new Pair <List <object>, Func <object, Column> >(Array.ConvertAll(conn.ActiveSegments.ToArray(), item => (object)item).ToList(), segToCol);
            list[2] = new Pair <List <object>, Func <object, Column> >(Array.ConvertAll(conn.MatchingSegments.ToArray(), item => (object)item).ToList(), segToCol);

            GroupBy2 <Column> grouper = GroupBy2 <Column> .Of(list);

            double permanenceIncrement = conn.HtmConfig.PermanenceIncrement;
            double permanenceDecrement = conn.HtmConfig.PermanenceDecrement;

            ParallelOptions opts = new ParallelOptions
            {
                MaxDegreeOfParallelism = Environment.ProcessorCount
            };

            //
            // Grouping by columns, which have active and matching segments.
            Parallel.ForEach(grouper, opts, (tuple) =>
            {
                ActivateCellsInColumn(conn, learn, tuple, cycle, cycles, prevActiveCells, prevWinnerCells, permanenceIncrement, permanenceDecrement);
            });

            foreach (var colCycle in cycles.Values)
            {
                cycle.ActiveCells.AddRange(colCycle.ActiveCells);
                cycle.WinnerCells.AddRange(colCycle.WinnerCells);
            }

            return(cycle);
        }
        public virtual ComputeCycle Compute(Connections cnx, int[] activeColumns, string sequenceLabel, bool learn)
        {
            // Append last cycle's predictiveCells to *predicTEDCells* trace
            ((IndicesTrace)getTraceMap().Get("predictedCells")).items.Add(
                new HashSet <int>(Connections.AsCellIndexes(cnx.GetPredictiveCells())));

            ComputeCycle cycle = getMonitor().Compute(cnx, activeColumns, learn);

            // Append this cycle's predictiveCells to *predicTIVECells* trace
            ((IndicesTrace)getTraceMap().Get("predictiveCells")).items.Add(
                new HashSet <int>(Connections.AsCellIndexes(cnx.GetPredictiveCells())));

            ((IndicesTrace)getTraceMap().Get("activeCells")).items.Add(
                new HashSet <int>(Connections.AsCellIndexes(cnx.GetActiveCells())));
            ((IndicesTrace)getTraceMap().Get("activeColumns")).items.Add(new HashSet <int>(activeColumns));
            //Arrays.stream(activeColumns).boxed().collect(Collectors.toCollection(HashSet::new)));
            ((CountsTrace)getTraceMap().Get("numSegments")).items.Add(cnx.GetNumSegments());
            ((CountsTrace)getTraceMap().Get("numSynapses")).items.Add((int)(cnx.GetNumSynapses() ^ (cnx.GetNumSynapses() >> 32)));
            ((StringsTrace)getTraceMap().Get("sequenceLabels")).items.Add(sequenceLabel);
            ((BoolsTrace)getTraceMap().Get("resets")).items.Add(resetActive());

            setResetActive(false);

            setTransitionTracesStale(true);

            return(cycle);
        }
Example #8
0
        /**
         * Calculate the active cells, using the current active columns and dendrite
         * segments. Grow and reinforce synapses.
         *
         * <pre>
         * Pseudocode:
         *   for each column
         *     if column is active and has active distal dendrite segments
         *       call activatePredictedColumn
         *     if column is active and doesn't have active distal dendrite segments
         *       call burstColumn
         *     if column is inactive and has matching distal dendrite segments
         *       call punishPredictedColumn
         *
         * </pre>
         *
         * @param conn
         * @param activeColumnIndices
         * @param learn
         */
        public void ActivateCells(Connections conn, ComputeCycle cycle, int[] activeColumnIndices, bool learn)
        {
            ColumnData columnData = new ColumnData();

            HashSet <Cell> prevActiveCells = conn.GetActiveCells();
            HashSet <Cell> prevWinnerCells = conn.GetWinnerCells();

            List <Column> activeColumns = activeColumnIndices
                                          .OrderBy(i => i)
                                          .Select(i => conn.GetColumn(i))
                                          .ToList();

            Func <Column, Column>         identity = c => c;
            Func <DistalDendrite, Column> segToCol = segment => segment.GetParentCell().GetColumn();

            //@SuppressWarnings({ "rawtypes" })
            GroupBy2 <Column> grouper = GroupBy2 <Column> .Of(
                new Tuple <List <object>, Func <object, Column> >(activeColumns.Cast <object>().ToList(), x => identity((Column)x)),
                new Tuple <List <object>, Func <object, Column> >(new List <DistalDendrite>(conn.GetActiveSegments()).Cast <object>().ToList(), x => segToCol((DistalDendrite)x)),
                new Tuple <List <object>, Func <object, Column> >(new List <DistalDendrite>(conn.GetMatchingSegments()).Cast <object>().ToList(), x => segToCol((DistalDendrite)x)));

            double permanenceIncrement = conn.GetPermanenceIncrement();
            double permanenceDecrement = conn.GetPermanenceDecrement();

            foreach (Tuple t in grouper)
            {
                columnData = columnData.Set(t);

                if (columnData.IsNotNone(ACTIVE_COLUMNS))
                {
                    if (columnData.ActiveSegments().Any())
                    {
                        List <Cell> cellsToAdd = ActivatePredictedColumn(conn, columnData.ActiveSegments(),
                                                                         columnData.MatchingSegments(), prevActiveCells, prevWinnerCells,
                                                                         permanenceIncrement, permanenceDecrement, learn);

                        cycle.ActiveCells().UnionWith(cellsToAdd);
                        cycle.WinnerCells().UnionWith(cellsToAdd);
                    }
                    else
                    {
                        Tuple cellsXwinnerCell = BurstColumn(conn, columnData.Column(), columnData.MatchingSegments(),
                                                             prevActiveCells, prevWinnerCells, permanenceIncrement, permanenceDecrement, conn.GetRandom(),
                                                             learn);

                        cycle.ActiveCells().UnionWith((IEnumerable <Cell>)cellsXwinnerCell.Get(0));
                        cycle.WinnerCells().Add((Cell)cellsXwinnerCell.Get(1));
                    }
                }
                else
                {
                    if (learn)
                    {
                        PunishPredictedColumn(conn, columnData.ActiveSegments(), columnData.MatchingSegments(),
                                              prevActiveCells, prevWinnerCells, conn.GetPredictedSegmentDecrement());
                    }
                }
            }
        }
Example #9
0
        /////////////////////////// CORE FUNCTIONS /////////////////////////////

        /**
         * Feeds input record through TM, performing inferencing and learning
         *
         * @param connections       the connection memory
         * @param activeColumns     direct proximal dendrite input
         * @param learn             learning mode flag
         * @return                  {@link ComputeCycle} container for one cycle of inference values.
         */
        public ComputeCycle Compute(Connections connections, int[] activeColumns, bool learn)
        {
            ComputeCycle cycle = new ComputeCycle();

            ActivateCells(connections, cycle, activeColumns, learn);
            ActivateDendrites(connections, cycle, learn);

            return(cycle);
        }
        public void TestRecycleWeakestSynapseToMakeRoomForNewSynapse()
        {
            throw new AssertInconclusiveException("Not fixed.");

            TemporalMemory tm = new TemporalMemory();
            Connections    cn = new Connections();
            Parameters     p  = getDefaultParameters(null, KEY.CELLS_PER_COLUMN, 30);

            p.Set(KEY.COLUMN_DIMENSIONS, new int[] { 100 });
            //p.Set(KEY.COLUMN_DIMENSIONS, new int[] { 5 });
            p = getDefaultParameters(p, KEY.MIN_THRESHOLD, 1);
            p = getDefaultParameters(p, KEY.PERMANENCE_INCREMENT, 0.02);
            p = getDefaultParameters(p, KEY.PERMANENCE_DECREMENT, 0.02);
            p.Set(KEY.MAX_SYNAPSES_PER_SEGMENT, 3);
            p.apply(cn);
            tm.Init(cn);

            Assert.AreEqual(3, cn.HtmConfig.MaxSynapsesPerSegment);

            int[]        prevActiveColumns = { 0, 1, 2 };
            IList <Cell> prevWinnerCells   = cn.GetCellSet(new int[] { 0, 1, 2 });

            int[] activeColumns = { 4 };

            DistalDendrite matchingSegment = cn.CreateDistalSegment(cn.GetCell(4));

            cn.CreateSynapse(matchingSegment, cn.GetCell(81), 0.6);
            // Weakest Synapse
            cn.CreateSynapse(matchingSegment, cn.GetCell(0), 0.11);

            ComputeCycle cc = tm.Compute(prevActiveColumns, true) as ComputeCycle;

            Assert.IsTrue(prevWinnerCells.SequenceEqual(cc.WinnerCells));
            tm.Compute(activeColumns, true);

            //DD List<Synapse> synapses = cn.GetSynapses(matchingSegment);
            List <Synapse> synapses = matchingSegment.Synapses;

            Assert.AreEqual(3, synapses.Count);
            //Set<Cell> presynapticCells = synapses.stream().map(s->s.getPresynapticCell()).collect(Collectors.toSet());
            List <Cell> presynapticCells = new List <Cell>();

            //DD foreach (var syn in cn.GetSynapses(matchingSegment))
            foreach (var syn in matchingSegment.Synapses)
            {
                presynapticCells.Add(syn.GetPresynapticCell());
            }

            Assert.IsFalse(presynapticCells.Count(c => c.Index == 0) > 0);

            //Assert.IsFalse(presynapticCells.stream().mapToInt(cell->cell.getIndex()).anyMatch(i->i == 0));
        }
Example #11
0
        public void TestBurstUnpredictedColumns()
        {
            TemporalMemory tm = new TemporalMemory();
            Connections    cn = new Connections();
            Parameters     p  = getDefaultParameters();

            p.apply(cn);
            tm.init(cn);

            int[]       activeColumns = { 0 };
            ISet <Cell> burstingCells = cn.getCellSet(new int[] { 0, 1, 2, 3 });

            ComputeCycle cc = tm.Compute(activeColumns, true) as ComputeCycle;

            Assert.IsTrue(cc.ActiveCells.SequenceEqual(burstingCells));
        }
Example #12
0
        public void testBurstUnpredictedColumns()
        {
            TemporalMemory tm = new TemporalMemory();
            Connections    cn = new Connections();
            Parameters     p  = GetDefaultParameters();

            p.Apply(cn);
            TemporalMemory.Init(cn);

            int[]          activeColumns = { 0 };
            HashSet <Cell> burstingCells = cn.GetCellSet(new int[] { 0, 1, 2, 3 });

            ComputeCycle cc = tm.Compute(cn, activeColumns, true);

            Assert.IsTrue(cc.ActiveCells().SetEquals(burstingCells));
        }
        public void TestBurstUnpredictedColumns1()
        {
            HtmConfig   htmConfig = GetDefaultTMParameters();
            Connections cn        = new Connections(htmConfig);

            TemporalMemory tm = new TemporalMemory();

            tm.Init(cn);

            int[]        activeColumns = { 0 };
            IList <Cell> burstingCells = cn.GetCellSet(new int[] { 0, 1, 2, 3 });

            ComputeCycle cc = tm.Compute(activeColumns, true) as ComputeCycle;

            Assert.IsTrue(cc.ActiveCells.SequenceEqual(burstingCells));
        }
Example #14
0
        public void TestTemporalMemoryThroughLayer()
        {
            Parameters p = GetParameters();

            int[]   input1 = new int[] { 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0 };
            int[]   input2 = new int[] { 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0 };
            int[]   input3 = new int[] { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
            int[]   input4 = new int[] { 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0 };
            int[]   input5 = new int[] { 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0 };
            int[]   input6 = new int[] { 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1 };
            int[]   input7 = new int[] { 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0 };
            int[][] inputs = { input1, input2, input3, input4, input5, input6, input7 };

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

            int timeUntilStable = 600;

            l.Subscribe(Observer.Create <IInference>(
                            output => { }, Console.WriteLine, () => { }
                            ));
            //    @Override public void onCompleted() { }
            //    @Override public void onError(Throwable e) { e.printStackTrace(); }
            //    @Override public void onNext(Inference output) { }
            //});

            // Now push some warm up data through so that "onNext" is called above
            for (int j = 0; j < timeUntilStable; j++)
            {
                for (int i = 0; i < inputs.Length; i++)
                {
                    l.Compute(inputs[i]);
                }
            }

            for (int j = 0; j < 2; j++)
            {
                for (int i = 0; i < inputs.Length; i++)
                {
                    l.Compute(inputs[i]);
                }
            }

            ComputeCycle cc = l.GetInference().GetComputeCycle();

            TEST_AGGREGATION[TM_LYR] = SDR.AsCellIndices(cc.activeCells);
        }
        public void TestActiveSegmentGrowSynapsesAccordingToPotentialOverlap()
        {
            TemporalMemory tm = new TemporalMemory();
            Connections    cn = new Connections();
            Parameters     p  = getDefaultParameters(null, KEY.CELLS_PER_COLUMN, 1);

            p = getDefaultParameters(p, KEY.MIN_THRESHOLD, 1);
            p = getDefaultParameters(p, KEY.ACTIVATION_THRESHOLD, 2);
            p = getDefaultParameters(p, KEY.MAX_NEW_SYNAPSE_COUNT, 4);
            p.apply(cn);
            tm.Init(cn);

            // Use 1 cell per column so that we have easy control over the winner cells.
            int[]       previousActiveColumns = { 0, 1, 2, 3, 4 };
            List <Cell> prevWinnerCells       = new List <Cell>(new Cell[] { cn.GetCell(0), cn.GetCell(1), cn.GetCell(2), cn.GetCell(3), cn.GetCell(4) });

            int[] activeColumns = { 5 };

            DistalDendrite activeSegment = cn.CreateDistalSegment(cn.GetCell(5));

            cn.CreateSynapse(activeSegment, cn.GetCell(0), 0.5);
            cn.CreateSynapse(activeSegment, cn.GetCell(1), 0.5);
            cn.CreateSynapse(activeSegment, cn.GetCell(2), 0.2);

            ComputeCycle cc = tm.Compute(previousActiveColumns, true) as ComputeCycle;

            Assert.IsTrue(prevWinnerCells.SequenceEqual(cc.WinnerCells));
            cc = tm.Compute(activeColumns, true) as ComputeCycle;

            List <Cell> presynapticCells = new List <Cell>();

            foreach (var syn in activeSegment.GetAllSynapses(cn))
            {
                presynapticCells.Add(syn.getPresynapticCell());
            }

            //= cn.getSynapses(activeSegment).stream()
            //.map(s->s.getPresynapticCell())
            //.collect(Collectors.toSet());

            Assert.IsTrue(
                presynapticCells.Count == 4 && (
                    (presynapticCells.Contains(cn.GetCell(0)) && presynapticCells.Contains(cn.GetCell(1)) && presynapticCells.Contains(cn.GetCell(2)) && presynapticCells.Contains(cn.GetCell(3))) ||
                    (presynapticCells.Contains(cn.GetCell(0)) && presynapticCells.Contains(cn.GetCell(1)) && presynapticCells.Contains(cn.GetCell(2)) && presynapticCells.Contains(cn.GetCell(4)))));
        }
Example #16
0
        public void testActiveSegmentGrowSynapsesAccordingToPotentialOverlap()
        {
            TemporalMemory tm = new TemporalMemory();
            Connections    cn = new Connections();
            Parameters     p  = GetDefaultParameters(null, Parameters.KEY.CELLS_PER_COLUMN, 1);

            p = GetDefaultParameters(p, Parameters.KEY.MIN_THRESHOLD, 1);
            p = GetDefaultParameters(p, Parameters.KEY.ACTIVATION_THRESHOLD, 2);
            p = GetDefaultParameters(p, Parameters.KEY.MAX_NEW_SYNAPSE_COUNT, 4);
            p.Apply(cn);
            TemporalMemory.Init(cn);

            // Use 1 cell per column so that we have easy control over the winner cells.
            int[]          previousActiveColumns = { 0, 1, 2, 3, 4 };
            HashSet <Cell> prevWinnerCells       = new HashSet <Cell>(Arrays.AsList(0, 1, 2, 3, 4)
                                                                      .Select(i => cn.GetCell(i))
                                                                      .ToList());

            int[] activeColumns = { 5 };

            DistalDendrite activeSegment = cn.CreateSegment(cn.GetCell(5));

            cn.CreateSynapse(activeSegment, cn.GetCell(0), 0.5);
            cn.CreateSynapse(activeSegment, cn.GetCell(1), 0.5);
            cn.CreateSynapse(activeSegment, cn.GetCell(2), 0.2);

            ComputeCycle cc = tm.Compute(cn, previousActiveColumns, true);

            Assert.IsTrue(prevWinnerCells.SetEquals(cc.WinnerCells()));
            cc = tm.Compute(cn, activeColumns, true);

            HashSet <Cell> presynapticCells = new HashSet <Cell>(cn.GetSynapses(activeSegment)
                                                                 .Select(s => s.GetPresynapticCell())
                                                                 .ToList());

            Assert.IsTrue(
                presynapticCells.Count == 4 && (
                    !presynapticCells.Except(new List <Cell> {
                cn.GetCell(0), cn.GetCell(1), cn.GetCell(2), cn.GetCell(3)
            }).Any() ||
                    !presynapticCells.Except(new List <Cell> {
                cn.GetCell(0), cn.GetCell(1), cn.GetCell(2), cn.GetCell(4)
            }).Any()));
        }
        public void TestNewSegmentAddSynapsesToAllWinnerCells()
        {
            TemporalMemory tm = new TemporalMemory();
            Connections    cn = new Connections();
            Parameters     p  = getDefaultParameters(null, KEY.MAX_NEW_SYNAPSE_COUNT, 4);

            p.apply(cn);
            tm.Init(cn);

            int[] previousActiveColumns = { 0, 1, 2 };
            int[] activeColumns         = { 4 };

            ComputeCycle cc = tm.Compute(previousActiveColumns, true) as ComputeCycle;
            List <Cell>  prevWinnerCells = new List <Cell>(cc.WinnerCells);

            Assert.AreEqual(3, prevWinnerCells.Count);

            cc = tm.Compute(activeColumns, true) as ComputeCycle;

            List <Cell> winnerCells = new List <Cell>(cc.WinnerCells);

            Assert.AreEqual(1, winnerCells.Count);

            //DD
            //List<DistalDendrite> segments = winnerCells[0].GetSegments(cn);
            List <DistalDendrite> segments = winnerCells[0].DistalDendrites;

            //List<DistalDendrite> segments = winnerCells[0].Segments;
            Assert.AreEqual(1, segments.Count);
            //List<Synapse> synapses = segments[0].GetAllSynapses(cn);
            List <Synapse> synapses = segments[0].Synapses;

            List <Cell> presynapticCells = new List <Cell>();

            foreach (Synapse synapse in synapses)
            {
                Assert.AreEqual(0.21, synapse.Permanence, 0.01);
                presynapticCells.Add(synapse.GetPresynapticCell());
            }

            presynapticCells.Sort();

            Assert.IsTrue(prevWinnerCells.SequenceEqual(presynapticCells));
        }
Example #18
0
        public void testNoChangeToMatchingSegmentsInPredictedActiveColumn()
        {
            TemporalMemory tm = new TemporalMemory();
            Connections    cn = new Connections();
            Parameters     p  = GetDefaultParameters();

            p.Apply(cn);
            TemporalMemory.Init(cn);

            int[]          previousActiveColumns = { 0 };
            int[]          activeColumns         = { 1 };
            Cell[]         previousActiveCells   = { cn.GetCell(0), cn.GetCell(1), cn.GetCell(2), cn.GetCell(3) };
            Cell           expectedActiveCell    = cn.GetCell(4);
            HashSet <Cell> expectedActiveCells   = new HashSet <Cell> {
                expectedActiveCell
            };                                                                             // Stream.of(expectedActiveCell).collect(Collectors.toCollection(HashSet < Cell >::new));
            Cell otherBurstingCell = cn.GetCell(5);

            DistalDendrite activeSegment = cn.CreateSegment(expectedActiveCell);

            cn.CreateSynapse(activeSegment, previousActiveCells[0], 0.5);
            cn.CreateSynapse(activeSegment, previousActiveCells[1], 0.5);
            cn.CreateSynapse(activeSegment, previousActiveCells[2], 0.5);
            cn.CreateSynapse(activeSegment, previousActiveCells[3], 0.5);

            DistalDendrite matchingSegmentOnSameCell = cn.CreateSegment(expectedActiveCell);
            Synapse        s1 = cn.CreateSynapse(matchingSegmentOnSameCell, previousActiveCells[0], 0.3);
            Synapse        s2 = cn.CreateSynapse(matchingSegmentOnSameCell, previousActiveCells[1], 0.3);

            DistalDendrite matchingSegmentOnOtherCell = cn.CreateSegment(otherBurstingCell);
            Synapse        s3 = cn.CreateSynapse(matchingSegmentOnOtherCell, previousActiveCells[0], 0.3);
            Synapse        s4 = cn.CreateSynapse(matchingSegmentOnOtherCell, previousActiveCells[1], 0.3);

            ComputeCycle cc = tm.Compute(cn, previousActiveColumns, true);

            Assert.IsTrue(cc.PredictiveCells().SetEquals(expectedActiveCells));
            tm.Compute(cn, activeColumns, true);

            Assert.AreEqual(0.3, s1.GetPermanence(), 0.01);
            Assert.AreEqual(0.3, s2.GetPermanence(), 0.01);
            Assert.AreEqual(0.3, s3.GetPermanence(), 0.01);
            Assert.AreEqual(0.3, s4.GetPermanence(), 0.01);
        }
        public void TestMatchingSegmentAddSynapsesToAllWinnerCells()
        {
            TemporalMemory tm = new TemporalMemory();
            Connections    cn = new Connections();
            Parameters     p  = getDefaultParameters(null, KEY.CELLS_PER_COLUMN, 1);

            p = getDefaultParameters(p, KEY.MIN_THRESHOLD, 1);
            p.apply(cn);
            tm.Init(cn);

            int[]        previousActiveColumns = { 0, 1 };
            IList <Cell> prevWinnerCells       = cn.GetCellSet(new int[] { 0, 1 });

            int[] activeColumns = { 4 };

            DistalDendrite matchingSegment = cn.CreateDistalSegment(cn.GetCell(4));

            cn.CreateSynapse(matchingSegment, cn.GetCell(0), 0.5);

            ComputeCycle cc = tm.Compute(previousActiveColumns, true) as ComputeCycle;

            Assert.IsTrue(cc.WinnerCells.SequenceEqual(prevWinnerCells));

            cc = tm.Compute(activeColumns, true) as ComputeCycle;

            //DD List<Synapse> synapses = cn.GetSynapses(matchingSegment);
            List <Synapse> synapses = matchingSegment.Synapses;

            Assert.AreEqual(2, synapses.Count);

            synapses.Sort();

            foreach (Synapse synapse in synapses)
            {
                if (synapse.GetPresynapticCell().Index == 0)
                {
                    continue;
                }

                Assert.AreEqual(0.21, synapse.Permanence, 0.01);
                Assert.AreEqual(1, synapse.GetPresynapticCell().Index);
            }
        }
Example #20
0
        public void testMatchingSegmentAddSynapsesToSubsetOfWinnerCells()
        {
            TemporalMemory tm = new TemporalMemory();
            Connections    cn = new Connections();
            Parameters     p  = GetDefaultParameters(null, Parameters.KEY.CELLS_PER_COLUMN, 1);

            p = GetDefaultParameters(p, Parameters.KEY.MIN_THRESHOLD, 1);
            p.Apply(cn);
            TemporalMemory.Init(cn);

            int[]          previousActiveColumns = { 0, 1, 2, 3 };
            HashSet <Cell> prevWinnerCells       = cn.GetCellSet(new int[] { 0, 1, 2, 3 });

            int[] activeColumns = { 4 };

            DistalDendrite matchingSegment = cn.CreateSegment(cn.GetCell(4));

            cn.CreateSynapse(matchingSegment, cn.GetCell(0), 0.5);

            ComputeCycle cc = tm.Compute(cn, previousActiveColumns, true);

            Assert.IsTrue(cc.WinnerCells().SetEquals(prevWinnerCells));
            cc = tm.Compute(cn, activeColumns, true);

            List <Synapse> synapses = cn.GetSynapses(matchingSegment);

            Assert.AreEqual(3, synapses.Count);

            synapses.Sort();
            foreach (Synapse synapse in synapses)
            {
                if (synapse.GetPresynapticCell().GetIndex() == 0)
                {
                    continue;
                }

                Assert.AreEqual(0.21, synapse.GetPermanence(), 0.01);
                Assert.IsTrue(synapse.GetPresynapticCell().GetIndex() == 1 ||
                              synapse.GetPresynapticCell().GetIndex() == 2 ||
                              synapse.GetPresynapticCell().GetIndex() == 3);
            }
        }
        public void TestNoChangeToMatchingSegmentsInPredictedActiveColumn()
        {
            TemporalMemory tm = new TemporalMemory();
            Connections    cn = new Connections();
            Parameters     p  = getDefaultParameters();

            p.apply(cn);
            tm.Init(cn);

            int[]       previousActiveColumns = { 0 };
            int[]       activeColumns         = { 1 };
            Cell[]      previousActiveCells   = { cn.GetCell(0), cn.GetCell(1), cn.GetCell(2), cn.GetCell(3) };
            Cell        expectedActiveCell    = cn.GetCell(4);
            List <Cell> expectedActiveCells   = new List <Cell>(new Cell[] { expectedActiveCell });
            Cell        otherBurstingCell     = cn.GetCell(5);

            DistalDendrite activeSegment = cn.CreateDistalSegment(expectedActiveCell);

            cn.CreateSynapse(activeSegment, previousActiveCells[0], 0.5);
            cn.CreateSynapse(activeSegment, previousActiveCells[1], 0.5);
            cn.CreateSynapse(activeSegment, previousActiveCells[2], 0.5);
            cn.CreateSynapse(activeSegment, previousActiveCells[3], 0.5);

            DistalDendrite matchingSegmentOnSameCell = cn.CreateDistalSegment(expectedActiveCell);
            Synapse        s1 = cn.CreateSynapse(matchingSegmentOnSameCell, previousActiveCells[0], 0.3);
            Synapse        s2 = cn.CreateSynapse(matchingSegmentOnSameCell, previousActiveCells[1], 0.3);

            DistalDendrite matchingSegmentOnOtherCell = cn.CreateDistalSegment(otherBurstingCell);
            Synapse        s3 = cn.CreateSynapse(matchingSegmentOnOtherCell, previousActiveCells[0], 0.3);
            Synapse        s4 = cn.CreateSynapse(matchingSegmentOnOtherCell, previousActiveCells[1], 0.3);

            ComputeCycle cc = tm.Compute(previousActiveColumns, true) as ComputeCycle;

            Assert.IsTrue(cc.PredictiveCells.SequenceEqual(expectedActiveCells));
            tm.Compute(activeColumns, true);

            Assert.AreEqual(0.3, s1.Permanence, 0.01);
            Assert.AreEqual(0.3, s2.Permanence, 0.01);
            Assert.AreEqual(0.3, s3.Permanence, 0.01);
            Assert.AreEqual(0.3, s4.Permanence, 0.01);
        }
        public void SerializationDeSerializationBasicTest()
        {
            TemporalMemory tm = new TemporalMemory();
            Connections    cn = new Connections();
            Parameters     p  = getDefaultParameters();

            p.apply(cn);
            tm.init(cn);

            int[] previousActiveColumns = { 0 };
            int[] activeColumns         = { 1 };


            Cell cell4 = cn.getCell(4);


            ISet <Cell> expectedActiveCells = new HashSet <Cell>(new Cell[] { cell4 });


            DistalDendrite activeSegment = cn.CreateDistalSegment(cell4);


            cn.createSynapse(activeSegment, cn.getCell(0), 0.5);
            cn.createSynapse(activeSegment, cn.getCell(1), 0.5);
            cn.createSynapse(activeSegment, cn.getCell(2), 0.5);
            cn.createSynapse(activeSegment, cn.getCell(3), 0.5);


            ComputeCycle cc = tm.Compute(previousActiveColumns, true) as ComputeCycle;

            Assert.IsTrue(cc.predictiveCells.SequenceEqual(expectedActiveCells));

            tm.Serializer("tmSerializeNew.json");
            var tm1 = TemporalMemory.Deserializer("tmSerializeNew.json");


            ComputeCycle cc2 = tm1.Compute(activeColumns, true) as ComputeCycle;

            Assert.IsTrue(cc2.ActiveCells.SequenceEqual(expectedActiveCells));
        }
Example #23
0
        public void testRecycleWeakestSynapseToMakeRoomForNewSynapse()
        {
            TemporalMemory tm = new TemporalMemory();
            Connections    cn = new Connections();
            Parameters     p  = GetDefaultParameters(null, Parameters.KEY.CELLS_PER_COLUMN, 1);

            p.SetParameterByKey(Parameters.KEY.COLUMN_DIMENSIONS, new int[] { 100 });
            p = GetDefaultParameters(p, Parameters.KEY.MIN_THRESHOLD, 1);
            p = GetDefaultParameters(p, Parameters.KEY.PERMANENCE_INCREMENT, 0.02);
            p = GetDefaultParameters(p, Parameters.KEY.PERMANENCE_DECREMENT, 0.02);
            p.SetParameterByKey(Parameters.KEY.MAX_SYNAPSES_PER_SEGMENT, 3);
            p.Apply(cn);
            TemporalMemory.Init(cn);

            Assert.AreEqual(3, cn.GetMaxSynapsesPerSegment());

            int[]          prevActiveColumns = { 0, 1, 2 };
            HashSet <Cell> prevWinnerCells   = cn.GetCellSet(new int[] { 0, 1, 2 });

            int[] activeColumns = { 4 };

            DistalDendrite matchingSegment = cn.CreateSegment(cn.GetCell(4));

            cn.CreateSynapse(matchingSegment, cn.GetCell(81), 0.6);
            // Weakest Synapse
            cn.CreateSynapse(matchingSegment, cn.GetCell(0), 0.11);

            ComputeCycle cc = tm.Compute(cn, prevActiveColumns, true);

            Assert.IsTrue(prevWinnerCells.SetEquals(cc.winnerCells));
            tm.Compute(cn, activeColumns, true);

            List <Synapse> synapses = cn.GetSynapses(matchingSegment);

            Assert.AreEqual(3, synapses.Count);
            HashSet <Cell> presynapticCells = new HashSet <Cell>(synapses.Select(s => s.GetPresynapticCell()));

            Assert.IsFalse(presynapticCells.Select(cell => cell.GetIndex()).Any(i => i == 0));
        }
Example #24
0
        public void testNewSegmentAddSynapsesToSubsetOfWinnerCells()
        {
            TemporalMemory tm = new TemporalMemory();
            Connections    cn = new Connections();
            Parameters     p  = getDefaultParameters(null, KEY.MAX_NEW_SYNAPSE_COUNT, 2);

            p.apply(cn);
            tm.init(cn);

            int[] previousActiveColumns = { 0, 1, 2 };
            int[] activeColumns         = { 4 };

            ComputeCycle cc = tm.Compute(previousActiveColumns, true) as ComputeCycle;

            ISet <Cell> prevWinnerCells = cc.WinnerCells;

            Assert.AreEqual(3, prevWinnerCells.Count);

            cc = tm.Compute(activeColumns, true) as ComputeCycle;

            List <Cell> winnerCells = new List <Cell>(cc.WinnerCells);

            Assert.AreEqual(1, winnerCells.Count);

            List <DistalDendrite> segments = winnerCells[0].getSegments(cn);

            //List<DistalDendrite> segments = winnerCells[0].Segments;
            Assert.AreEqual(1, segments.Count);

            List <Synapse> synapses = cn.getSynapses(segments[0]);

            Assert.AreEqual(2, synapses.Count);

            foreach (Synapse synapse in synapses)
            {
                Assert.AreEqual(0.21, synapse.getPermanence(), 0.01);
                Assert.IsTrue(prevWinnerCells.Contains(synapse.getPresynapticCell()));
            }
        }
Example #25
0
        /**
         * Calculate dendrite segment activity, using the current active cells.
         *
         * <pre>
         * Pseudocode:
         *   for each distal dendrite segment with activity >= activationThreshold
         *     mark the segment as active
         *   for each distal dendrite segment with unconnected activity >= minThreshold
         *     mark the segment as matching
         * </pre>
         *
         * @param conn     the Connectivity
         * @param cycle    Stores current compute cycle results
         * @param learn    If true, segment activations will be recorded. This information is used
         *                 during segment cleanup.
         */
        public void ActivateDendrites(Connections conn, ComputeCycle cycle, bool learn)
        {
            Connections.Activity activity = conn.ComputeActivity(cycle.activeCells, conn.GetConnectedPermanence());

            List <DistalDendrite> activeSegments = ArrayUtils.Range(0, activity.numActiveConnected.Length)
                                                   .Where(i => activity.numActiveConnected[i] >= conn.GetActivationThreshold())
                                                   .Select(i => conn.GetSegmentForFlatIdx(i))
                                                   .ToList();

            List <DistalDendrite> matchingSegments = ArrayUtils.Range(0, activity.numActiveConnected.Length)
                                                     .Where(i => activity.numActivePotential[i] >= conn.GetMinThreshold())
                                                     .Select(i => conn.GetSegmentForFlatIdx(i))
                                                     .ToList();

            activeSegments.Sort(conn.segmentPositionSortKey);
            matchingSegments.Sort(conn.segmentPositionSortKey);

            //Collections.sort(activeSegments, conn.segmentPositionSortKey);
            //Collections.sort(matchingSegments, conn.segmentPositionSortKey);

            cycle.activeSegments   = activeSegments;
            cycle.matchingSegments = matchingSegments;

            conn.lastActivity = activity;
            conn.SetActiveCells(new HashSet <Cell>(cycle.activeCells));
            conn.SetWinnerCells(new HashSet <Cell>(cycle.winnerCells));
            conn.SetActiveSegments(activeSegments);
            conn.setMatchingSegments(matchingSegments);
            // Forces generation of the predictive cells from the above active segments
            conn.ClearPredictiveCells();
            conn.GetPredictiveCells();

            if (learn)
            {
                activeSegments.ForEach(s => conn.RecordSegmentActivity(s));
                conn.StartNewIteration();
            }
        }
        public void SerializationDeSerializationTest()
        {
            TemporalMemory tm1 = new TemporalMemory();
            Connections    cn1 = new Connections();
            Parameters     p1  = getDefaultParameters();

            p1.apply(cn1);
            tm1.init(cn1);
            int[] previousActiveColumns = { 0 };
            int[] activeColumns         = { 1 };

            Cell           cell4 = cn1.getCell(4);
            ISet <Cell>    expectedActiveCells = new HashSet <Cell>(new Cell[] { cell4 });
            DistalDendrite activeSegment       = cn1.CreateDistalSegment(cell4);

            cn1.createSynapse(activeSegment, cn1.getCell(0), 0.5);
            cn1.createSynapse(activeSegment, cn1.getCell(1), 0.5);
            cn1.createSynapse(activeSegment, cn1.getCell(2), 0.5);
            cn1.createSynapse(activeSegment, cn1.getCell(3), 0.5);
            ComputeCycle cc1 = new ComputeCycle();

            for (int i = 0; i < 5; i++)
            {
                cc1 = tm1.Compute(previousActiveColumns, true);
            }
            Assert.IsTrue(cc1.predictiveCells.SequenceEqual(expectedActiveCells));

            tm1.Serializer("tmTTrainSerialized.json");
            string       ser1 = File.ReadAllText("tmTTrainSerialized.json");
            var          tm2  = TemporalMemory.Deserializer("tmTTrainSerialized.json");
            ComputeCycle cc2  = new ComputeCycle();


            cc2 = tm2.Compute(activeColumns, true);

            Assert.IsTrue(cc2.ActiveCells.SequenceEqual(expectedActiveCells));
        }
        public void TestActivateCorrectlyPredictiveCells(int tmImplementation)
        {
            TemporalMemory tm = tmImplementation == 0 ? new TemporalMemory() : new TemporalMemoryMT();
            Connections    cn = new Connections();
            Parameters     p  = getDefaultParameters();

            p.apply(cn);
            tm.Init(cn);

            int[] previousActiveColumns = { 0 };
            int[] activeColumns         = { 1 };

            // Cell4 belongs to column with index 1.
            Cell cell4 = cn.GetCell(4);

            // ISet<Cell> expectedActiveCells = Stream.of(cell4).collect(Collectors.toSet());
            ISet <Cell> expectedActiveCells = new HashSet <Cell>(new Cell[] { cell4 });

            // We add distal dentrite at column1.cell4
            DistalDendrite activeSegment = cn.CreateDistalSegment(cell4);

            //
            // We add here synapses between column0.cells[0-3] and segment.
            cn.CreateSynapse(activeSegment, cn.GetCell(0), 0.5);
            cn.CreateSynapse(activeSegment, cn.GetCell(1), 0.5);
            cn.CreateSynapse(activeSegment, cn.GetCell(2), 0.5);
            cn.CreateSynapse(activeSegment, cn.GetCell(3), 0.5);

            ComputeCycle cc = tm.Compute(previousActiveColumns, true) as ComputeCycle;

            Assert.IsTrue(cc.PredictiveCells.SequenceEqual(expectedActiveCells));

            ComputeCycle cc2 = tm.Compute(activeColumns, true) as ComputeCycle;

            Assert.IsTrue(cc2.ActiveCells.SequenceEqual(expectedActiveCells));
        }
Example #28
0
        public void testAddSegmentToCellWithFewestSegments()
        {
            bool grewOnCell1 = false;
            bool grewOnCell2 = false;

            for (int seed = 0; seed < 100; seed++)
            {
                TemporalMemory tm = new TemporalMemory();
                Connections    cn = new Connections();
                Parameters     p  = GetDefaultParameters(null, Parameters.KEY.MAX_NEW_SYNAPSE_COUNT, 4);
                p = GetDefaultParameters(p, Parameters.KEY.PREDICTED_SEGMENT_DECREMENT, 0.02);
                p = GetDefaultParameters(p, Parameters.KEY.SEED, seed);
                p.SetParameterByKey(Parameters.KEY.RANDOM, new XorshiftRandom(seed));
                p.Apply(cn);
                TemporalMemory.Init(cn);

                int[]          prevActiveColumns = { 1, 2, 3, 4 };
                Cell[]         prevActiveCells   = { cn.GetCell(4), cn.GetCell(5), cn.GetCell(6), cn.GetCell(7) };
                int[]          activeColumns     = { 0 };
                Cell[]         nonMatchingCells  = { cn.GetCell(0), cn.GetCell(3) };
                HashSet <Cell> activeCells       = cn.GetCellSet(new int[] { 0, 1, 2, 3 });

                DistalDendrite segment1 = cn.CreateSegment(nonMatchingCells[0]);
                cn.CreateSynapse(segment1, prevActiveCells[0], 0.5);
                DistalDendrite segment2 = cn.CreateSegment(nonMatchingCells[1]);
                cn.CreateSynapse(segment2, prevActiveCells[1], 0.5);

                tm.Compute(cn, prevActiveColumns, true);
                ComputeCycle cc = tm.Compute(cn, activeColumns, true);

                Assert.IsTrue(cc.ActiveCells().SetEquals(activeCells));

                Assert.AreEqual(3, cn.GetNumSegments());
                Assert.AreEqual(1, cn.GetNumSegments(cn.GetCell(0)));
                Assert.AreEqual(1, cn.GetNumSegments(cn.GetCell(3)));
                Assert.AreEqual(1, cn.GetNumSynapses(segment1));
                Assert.AreEqual(1, cn.GetNumSynapses(segment2));

                List <DistalDendrite> segments = new List <DistalDendrite>(cn.GetSegments(cn.GetCell(1)));
                if (segments.Count == 0)
                {
                    List <DistalDendrite> segments2 = cn.GetSegments(cn.GetCell(2));
                    Assert.IsFalse(segments2.Count == 0);
                    grewOnCell2 = true;
                    segments.AddRange(segments2);
                }
                else
                {
                    grewOnCell1 = true;
                }

                Assert.AreEqual(1, segments.Count);
                List <Synapse> synapses = segments[0].GetAllSynapses(cn);
                Assert.AreEqual(4, synapses.Count);

                HashSet <Column> columnCheckList = cn.GetColumnSet(prevActiveColumns);

                foreach (Synapse synapse in synapses)
                {
                    Assert.AreEqual(0.2, synapse.GetPermanence(), 0.01);

                    Column column = synapse.GetPresynapticCell().GetColumn();
                    Assert.IsTrue(columnCheckList.Contains(column));
                    columnCheckList.Remove(column);
                }

                Assert.AreEqual(0, columnCheckList.Count);
            }

            Assert.IsTrue(grewOnCell1);
            Assert.IsTrue(grewOnCell2);
        }
        public void TestAddSegmentToCellWithFewestSegments()
        {
            bool grewOnCell1 = false;
            bool grewOnCell2 = false;

            for (int seed = 0; seed < 100; seed++)
            {
                TemporalMemory tm = new TemporalMemory();
                Connections    cn = new Connections();
                Parameters     p  = getDefaultParameters(null, KEY.MAX_NEW_SYNAPSE_COUNT, 4);
                p = getDefaultParameters(p, KEY.PREDICTED_SEGMENT_DECREMENT, 0.02);
                p = getDefaultParameters(p, KEY.SEED, seed);
                p.apply(cn);
                tm.Init(cn);

                int[]        prevActiveColumns = { 1, 2, 3, 4 };
                Cell[]       prevActiveCells   = { cn.GetCell(4), cn.GetCell(5), cn.GetCell(6), cn.GetCell(7) };
                int[]        activeColumns     = { 0 };
                Cell[]       nonMatchingCells  = { cn.GetCell(0), cn.GetCell(3) };
                IList <Cell> activeCells       = cn.GetCellSet(new int[] { 0, 1, 2, 3 });

                DistalDendrite segment1 = cn.CreateDistalSegment(nonMatchingCells[0]);
                cn.CreateSynapse(segment1, prevActiveCells[0], 0.5);
                DistalDendrite segment2 = cn.CreateDistalSegment(nonMatchingCells[1]);
                cn.CreateSynapse(segment2, prevActiveCells[1], 0.5);

                tm.Compute(prevActiveColumns, true);
                ComputeCycle cc = tm.Compute(activeColumns, true) as ComputeCycle;

                Assert.IsTrue(cc.ActiveCells.SequenceEqual(activeCells));

                Assert.AreEqual(3, cn.NumSegments());
                Assert.AreEqual(1, cn.NumSegments(cn.GetCell(0)));
                Assert.AreEqual(1, cn.NumSegments(cn.GetCell(3)));
                Assert.AreEqual(1, segment1.Synapses.Count);
                Assert.AreEqual(1, segment2.Synapses.Count);

                //DD
                //List<DistalDendrite> segments = new List<DistalDendrite>(cn.GetSegments(cn.GetCell(1)));
                List <DistalDendrite> segments = new List <DistalDendrite>(cn.GetCell(1).DistalDendrites);
                if (segments.Count == 0)
                {
                    //DD
                    //List<DistalDendrite> segments2 = cn.GetSegments(cn.GetCell(2));
                    List <DistalDendrite> segments2 = cn.GetCell(2).DistalDendrites;
                    Assert.IsFalse(segments2.Count == 0);
                    grewOnCell2 = true;
                    segments.AddRange(segments2);
                }
                else
                {
                    grewOnCell1 = true;
                }

                Assert.AreEqual(1, segments.Count);
                List <Synapse> synapses = segments[0].Synapses;
                Assert.AreEqual(4, synapses.Count);

                ISet <Column> columnCheckList = cn.GetColumnSet(prevActiveColumns);

                foreach (Synapse synapse in synapses)
                {
                    Assert.AreEqual(0.2, synapse.Permanence, 0.01);

                    var    parentColIndx = synapse.GetPresynapticCell().ParentColumnIndex;
                    Column column        = cn.HtmConfig.Memory.GetColumn(parentColIndx);
                    Assert.IsTrue(columnCheckList.Contains(column));
                    columnCheckList.Remove(column);
                }

                Assert.AreEqual(0, columnCheckList.Count);
            }

            Assert.IsTrue(grewOnCell1);
            Assert.IsTrue(grewOnCell2);
        }
        private void RunExperiment(int inputBits, HtmConfig cfgL4, EncoderBase encoder, List <double> inputValues, HtmConfig cfgL2)
        {
            Stopwatch swL2 = new Stopwatch();

            int  maxMatchCnt = 0;
            bool learn       = true;
            bool isSP4Stable = false;
            bool isSP2STable = false;

            Connections memL4 = new Connections(cfgL4);
            Connections memL2 = new Connections(cfgL2);

            int numInputs = inputValues.Distinct <double>().ToList().Count;
            HtmClassifier <string, ComputeCycle> cls = new HtmClassifier <string, ComputeCycle>();

            layerL4 = new CortexLayer <object, object>("L4");
            layerL2 = new CortexLayer <object, object>("L2");
            //tm4 = new TemporalMemoryMT();
            //tm2 = new TemporalMemoryMT();
            tm4 = new TemporalMemory();
            tm2 = new TemporalMemory();

            //
            // HPC for Layer 4 SP
            HomeostaticPlasticityController hpa_sp_L4 = new HomeostaticPlasticityController(memL4, numInputs * 50, (isStable, numPatterns, actColAvg, seenInputs) =>
            {
                if (isStable)
                {
                    Debug.WriteLine($"SP L4 STABLE: Patterns: {numPatterns}, Inputs: {seenInputs}, iteration: {seenInputs / numPatterns}");
                }
                else
                {
                    Debug.WriteLine($"SP L4 INSTABLE: Patterns: {numPatterns}, Inputs: {seenInputs}, iteration: {seenInputs / numPatterns}");
                }
                learn = isSP4Stable = isStable;
                cls.ClearState();
            }, numOfCyclesToWaitOnChange: 50);


            //
            // HPC for Layer 2 SP
            HomeostaticPlasticityController hpa_sp_L2 = new HomeostaticPlasticityController(memL2, numInputs * 50, (isStable, numPatterns, actColAvg, seenInputs) =>
            {
                if (isStable)
                {
                    Debug.WriteLine($"SP L2 STABLE: Patterns: {numPatterns}, Inputs: {seenInputs}, iteration: {seenInputs / numPatterns}");
                }
                else
                {
                    Debug.WriteLine($"SP L2 INSTABLE: Patterns: {numPatterns}, Inputs: {seenInputs}, iteration: {seenInputs / numPatterns}");
                }

                learn = isSP2STable = isStable;
                cls.ClearState();
            }, numOfCyclesToWaitOnChange: 50);

            SpatialPooler sp4 = new SpatialPooler(hpa_sp_L4);

            SpatialPooler sp2 = new SpatialPooler(hpa_sp_L2);

            sp4.Init(memL4);
            sp2.Init(memL2);

            // memL2.TraceInputPotential();

            tm4.Init(memL4);
            tm2.Init(memL2);

            layerL4.HtmModules.Add("encoder", encoder);
            layerL4.HtmModules.Add("sp", sp4);
            layerL4.HtmModules.Add("tm", tm4);

            layerL2.HtmModules.Add("sp", sp2);
            layerL2.HtmModules.Add("tm", tm2);

            int[] inpCellsL4ToL2 = new int[cfgL4.CellsPerColumn * cfgL4.NumColumns];

            double[]      inputs             = inputValues.ToArray();
            int[]         prevActiveCols     = new int[0];
            int           cycle              = 0;
            int           matches            = 0;
            string        lastPredictedValue = "0";
            int           maxCycles          = 3500;
            int           maxPrevInputs      = inputValues.Count - 1;
            List <string> previousInputs     = new List <string>();


            //
            // Training SP at Layer 4 to get stable. New-born stage.
            //
            using (StreamWriter swL4Sdrs = new StreamWriter($"L4-SDRs-in_{cfgL2.NumInputs}-col_{cfgL2.NumColumns}-r_{cfgL2.PotentialRadius}.txt"))
            {
                using (StreamWriter sw = new StreamWriter($"in_{cfgL2.NumInputs}-col_{cfgL2.NumColumns}-r_{cfgL2.PotentialRadius}.txt"))
                {
                    for (int i = 0; i < maxCycles; i++)
                    {
                        matches = 0;
                        cycle   = i;
                        Debug.WriteLine($"-------------- Newborn Cycle {cycle} at L4 SP region  ---------------");

                        foreach (double input in inputs)
                        {
                            Debug.WriteLine($" INPUT: '{input}'\t Cycle:{cycle}");
                            Debug.Write("L4: ");
                            object lyrOut           = layerL4.Compute(input, learn);
                            int[]  activeColumns    = layerL4.GetResult("sp") as int[];
                            int[]  cellSdrL4Indexes = memL4.ActiveCells.Select(c => c.Index).ToArray();
                            Debug.WriteLine($"L4out Active Coloumn for input: {input}: {Helpers.StringifyVector(activeColumns)}");
                            Debug.WriteLine($"L4out SDR for input: {input}: {Helpers.StringifyVector(cellSdrL4Indexes)}");


                            if (isSP4Stable)
                            {
                                /// <summary>
                                /// Checking Layer4 SP is giving similar or different
                                /// Active Cell Sdr Indexes After it reaches to stable state.
                                /// This portion is actuallly to hold all acive cell sdr
                                /// indexes after Layer 4 SP reaches at stable state via HPC.
                                ///
                                /// But why we have done this?
                                ///
                                /// Actually, In Necortex api we have obeserved during severel
                                /// experiments that whenvever Layer4 SP reaches to STABLE sate
                                /// it doesnt give us smilar pattern of Active Cell SDR Indexes
                                /// for each particular input data.
                                ///
                                /// Instead active cell sdr patern of L4 varried  though it has reached
                                /// to stable sate!
                                ///
                                /// So we want to obeserve whether Layer 4 SP is giving similar active cell sdr indexes
                                /// or different acrive cell sdr indexes after it reaches to stable state.
                                ///
                                /// If we receive similar acrive cell sdr indexes from Layer 4 sp after it reaches
                                /// to stable state then do train Layer 2 sp by as usual process in NeocortexApi by
                                /// calling Layer4.Compute().
                                ///
                                /// But if we receive different active cell sdr indexes then we will train Layer 2 sp
                                /// from L4_ActiveCell_sdr_log so that during training
                                /// Layer 2 SP gets similar stable active cell sdr indexes of layer4
                                /// from that dictionary. As a result, L2 SP will get similar sequence
                                /// of active cell sdr indexes during SP Tarining and reach to STABLE state
                                /// </summary>

                                Array.Sort(cellSdrL4Indexes);
                                if (!L4_ActiveCell_sdr_log.ContainsKey(input))
                                {
                                    L4_ActiveCell_sdr_log.Add(input, cellSdrL4Indexes);
                                }
                                else
                                {
                                    if (L4_ActiveCell_sdr_log[input].SequenceEqual(cellSdrL4Indexes))
                                    {
                                        Debug.WriteLine($"Layer4.Compute() is giving similar cell sdr indexes for input : {input} after reaching to stable state");
                                        isSimilar_L4_active_cell_sdr = true;
                                    }
                                    else
                                    {
                                        isSimilar_L4_active_cell_sdr = false;
                                        Debug.WriteLine($"Layer4.Compute() is giving different cell sdr indexes for input : {input} after reaching to stable state");
                                        Debug.WriteLine($"Sdr Mismatch with L4_ActiveCell_sdr_log after reaching to stable state");
                                        Debug.WriteLine($" L4_ActiveCell_sdr_log output for input {input}: { Helpers.StringifyVector(L4_ActiveCell_sdr_log[input])}");
                                        Debug.WriteLine($"L4 out sdr input:{input} {Helpers.StringifyVector(cellSdrL4Indexes)}");
                                        //Debug.WriteLine($"L4 out ac input: {input}: {Helpers.StringifyVector(activeColumns)}");
                                    }
                                }


                                if (!isSimilar_L4_active_cell_sdr)
                                {
                                    cellSdrL4Indexes = L4_ActiveCell_sdr_log[input];
                                }


                                //
                                // Training SP at Layer 2 to get stable. New-born stage.
                                //

                                // Write SDR as output of L4 and input of L2
                                // swL4Sdrs.WriteLine($"{input} - {Helpers.StringifyVector(cellSdrL4Indexes)}");
                                // Set the output active cell array

                                InitArray(inpCellsL4ToL2, 0);
                                ArrayUtils.SetIndexesTo(inpCellsL4ToL2, cellSdrL4Indexes, 1);
                                Debug.WriteLine($"L4 cell sdr to L2 SP Train for Input {input}: ");
                                layerL2.Compute(inpCellsL4ToL2, true);
                                int[]  overlaps    = ArrayUtils.IndexWhere(memL2.Overlaps, o => o > 0);
                                string strOverlaps = Helpers.StringifyVector(overlaps);
                                Debug.WriteLine($"Potential columns: {overlaps.Length}, overlaps: {strOverlaps}");
                            }
                        }


                        if (isSP4Stable && isSP2STable)
                        {
                            break;
                        }
                    }
                }
            }


            //
            // SP+TM at L2
            for (int i = 0; i < maxCycles; i++)
            {
                matches = 0;

                cycle = i;

                Debug.WriteLine($"-------------- L2 TM Train region Cycle {cycle} ---------------");

                foreach (double input in inputs)
                {
                    Debug.WriteLine($"-------------- {input} ---------------");

                    // Reset tha array

                    //var cellSdrL4Indexes = L4_ActiveCell_sdr_log[input];
                    object layerL4Out = layerL4.Compute(input, learn);
                    previousInputs.Add(input.ToString());

                    if (previousInputs.Count > (maxPrevInputs + 1))
                    {
                        previousInputs.RemoveAt(0);
                    }
                    if (previousInputs.Count < maxPrevInputs)
                    {
                        continue;
                    }

                    key = GetKey(previousInputs, input);

                    List <Cell> actCells;
                    InitArray(inpCellsL4ToL2, 0);
                    int[] cellSdrL4Indexes;

                    if (!isSimilar_L4_active_cell_sdr)
                    {
                        cellSdrL4Indexes = L4_ActiveCell_sdr_log[input];
                    }
                    else
                    {
                        cellSdrL4Indexes = memL4.ActiveCells.Select(c => c.Index).ToArray();
                    }


                    // Set the output active cell array
                    ArrayUtils.SetIndexesTo(inpCellsL4ToL2, cellSdrL4Indexes, 1);

                    ComputeCycle layerL2Out = layerL2.Compute(inpCellsL4ToL2, true) as ComputeCycle;


                    if (layerL2Out.ActiveCells.Count == layerL2Out.WinnerCells.Count)
                    {
                        actCells = layerL2Out.ActiveCells;
                    }
                    else
                    {
                        actCells = layerL2Out.WinnerCells;
                    }

                    /// <summary>
                    /// HTM Classifier has added for Layer 2
                    /// </summary>

                    cls.Learn(key, actCells.ToArray());

                    if (key == lastPredictedValue)
                    {
                        matches++;
                        Debug.WriteLine($"Match. Actual  Sequence: {key} - Last Predicted Sequence: {lastPredictedValue}");
                    }
                    else
                    {
                        Debug.WriteLine($"Missmatch! Actual Sequence: {key} - Last Predicted Sequence: {lastPredictedValue}");
                    }


                    /// <summary>
                    /// Classifier is taking Predictive Cells from Layer 2
                    /// </summary>

                    if (layerL2Out.PredictiveCells.Count > 0)
                    {
                        string predictedInputValue = cls.GetPredictedInputValue(layerL2Out.PredictiveCells.ToArray());

                        Debug.WriteLine($"Current Input: {input} \t| New Predicted Input Sequence: {predictedInputValue}");

                        lastPredictedValue = predictedInputValue;
                    }
                    else
                    {
                        Debug.WriteLine($"NO CELLS PREDICTED for next cycle.");
                        lastPredictedValue = String.Empty;
                    }
                }

                double accuracy = (double)matches / (double)inputs.Length * 100.0;

                Debug.WriteLine($"Cycle: {cycle}\tMatches={matches} of {inputs.Length}\t {accuracy}%");

                if (accuracy >= 100.0)
                {
                    maxMatchCnt++;
                    Debug.WriteLine($"100% accuracy reched {maxMatchCnt} times.");
                    //
                    // Experiment is completed if we are 20 cycles long at the 100% accuracy.
                    if (maxMatchCnt >= 20)
                    {
                        Debug.WriteLine($"Exit experiment in the stable state after 20 repeats with 100% of accuracy.");
                        learn = false;
                        break;
                    }
                }
                else if (maxMatchCnt > 0)
                {
                    Debug.WriteLine($"At 100% accuracy after {maxMatchCnt} repeats we get a drop of accuracy with {accuracy}. This indicates instable state. Learning will be continued.");
                }
            }
        }