예제 #1
0
        /// <summary>
        /// Uniform Column Mapping <br></br>
        /// Maps a column to its respective input index, keeping to the topology of the region. It takes the index of the column as an argument and determines
        /// what is the index of the flattened input vector that is to be the center of the column's potential pool. It distributes the columns over the inputs
        /// uniformly. The return value is an integer representing the index of the input bit. Examples of the expected output of this method:
        /// <list type="bullet">
        ///     <item>
        ///     If the topology is one dimensional, and the column index is 0, this method will return the input index 0. If the column index is 1, and there are
        ///     3 columns over 7 inputs, this method will return the input index 3.
        ///     </item>
        ///     <item>If the topology is two dimensional, with column dimensions [3, 5] and input dimensions [7, 11], and the column index is 3, the method returns
        ///     input index 8.
        ///     </item>
        /// </list>
        /// </summary>
        /// <param name="columnIndex">The index identifying a column in the permanence, potential and connectivity matrices.</param>
        /// <param name="colTop"></param>
        /// <param name="inpTop"></param>
        /// <returns>Flat index of mapped column.</returns>
        public static int MapColumn(int columnIndex, HtmModuleTopology colTop, HtmModuleTopology inpTop)
        {
            int[] columnCoords = AbstractFlatMatrix.ComputeCoordinates(colTop.NumDimensions,
                                                                       colTop.DimensionMultiplies, colTop.IsMajorOrdering, columnIndex);

            double[] colCoords = ArrayUtils.ToDoubleArray(columnCoords);

            double[] columnRatios = ArrayUtils.Divide(
                colCoords, ArrayUtils.ToDoubleArray(colTop.Dimensions), 0, 0);

            double[] inputCoords = ArrayUtils.Multiply(
                ArrayUtils.ToDoubleArray(inpTop.Dimensions), columnRatios, 0, 0);

            var colSpanOverInputs = ArrayUtils.Divide(
                ArrayUtils.ToDoubleArray(inpTop.Dimensions),
                ArrayUtils.ToDoubleArray(colTop.Dimensions), 0, 0);

            inputCoords = ArrayUtils.AddOffset(inputCoords, ArrayUtils.Multiply(colSpanOverInputs, 0.5));

            // Makes sure that inputCoords are in range [0, inpDims]
            int[] inputCoordInts = ArrayUtils.Clip(ArrayUtils.ToIntArray(inputCoords), inpTop.Dimensions, -1);

            return(AbstractFlatMatrix.ComputeIndex(inputCoordInts, inpTop.Dimensions, inpTop.NumDimensions,
                                                   inpTop.DimensionMultiplies, inpTop.IsMajorOrdering, true));
        }
예제 #2
0
        /// <summary>
        /// Returns a flat index computed from the specified coordinates.
        /// </summary>
        /// <param name="coordinates">  The index of the point</param>
        /// <param name="topology"></param>
        /// <returns>using the dimensions as a mixed radix definition.For example, in dimensions
        /// 42x10, the point [1, 4] is index 1*420 + 4*10 = 460.</returns>
        public static int GetFlatIndexFromCoordinates(int[] coordinates, HtmModuleTopology topology)
        {
            int[] localMults = topology.IsMajorOrdering ? HtmCompute.Reverse(topology.DimensionMultiplies) : topology.DimensionMultiplies;
            int   baseNum    = 0;

            for (int i = 0; i < coordinates.Length; i++)
            {
                baseNum += (localMults[i] * coordinates[i]);
            }
            return(baseNum);
        }
예제 #3
0
        /// <summary>
        /// Calculates multidimensional coordinates from flat array index.
        /// </summary>
        /// <param name="index">Flat index.</param>
        /// <returns>Coordinates in multidimensional space.</returns>
        public static int[] GetCoordinatesFromIndex(int index, HtmModuleTopology topology)
        {
            int[] returnVal = new int[topology.NumDimensions];
            int   baseNum   = index;

            for (int i = 0; i < topology.DimensionMultiplies.Length; i++)
            {
                int quotient = baseNum / topology.DimensionMultiplies[i];
                baseNum     %= topology.DimensionMultiplies[i];
                returnVal[i] = quotient;
            }
            return(topology.IsMajorOrdering ? Reverse(returnVal) : returnVal);
        }
예제 #4
0
        public void SerializeHtmModuleTopologyTest(int[] dimensions, bool isMajorOrdering)
        {
            HtmModuleTopology htm = new HtmModuleTopology(dimensions, isMajorOrdering);

            using (StreamWriter sw = new StreamWriter($"ser_{nameof(SerializeHtmModuleTopologyTest)}.txt"))
            {
                htm.Serialize(sw);
            }
            using (StreamReader sr = new StreamReader($"ser_{nameof(SerializeHtmModuleTopologyTest)}.txt"))
            {
                HtmModuleTopology htm1 = HtmModuleTopology.Deserialize(sr);

                Assert.IsTrue(htm1.Equals(htm));
            }
        }
예제 #5
0
        /// <summary>
        /// Gets indexes of neighborhood cells within centered radius
        /// </summary>
        /// <param name="centerIndex">The index of the point. The coordinates are expressed as a single index by
        /// using the dimensions as a mixed radix definition. For example, in dimensions 42x10, the point [1, 4] is index 1*420 + 4*10 = 460.
        /// </param>
        /// <param name="radius"></param>
        /// <param name="topology"></param>
        /// <returns>The points in the neighborhood, including centerIndex.</returns>
        public static int[] GetWrappingNeighborhood(int centerIndex, int radius, HtmModuleTopology topology)
        {
            int[] cp = HtmCompute.GetCoordinatesFromIndex(centerIndex, topology);

            // Dims of columns
            IntGenerator[] intGens = new IntGenerator[topology.Dimensions.Length];
            for (int i = 0; i < topology.Dimensions.Length; i++)
            {
                intGens[i] = new IntGenerator(cp[i] - radius, Math.Min((cp[i] - radius) + topology.Dimensions[i] - 1, cp[i] + radius) + 1);
            }

            List <List <int> > result = new List <List <int> >();

            result.Add(new List <int>());

            List <List <int> > interim = new List <List <int> >();

            int k = 0;

            foreach (IntGenerator gen in intGens)
            {
                interim.Clear();
                interim.AddRange(result);
                result.Clear();

                foreach (var lx in interim)
                {
                    gen.Reset();

                    for (int y = 0; y < gen.Size(); y++)
                    {
                        int py = ArrayUtils.Modulo(gen.Next(), topology.Dimensions[k]);
                        //int py = gen.next() % dimensions[k];

                        List <int> tl = new List <int>();
                        tl.AddRange(lx);
                        tl.Add(py);
                        result.Add(tl);
                    }
                }

                k++;
            }

            return(result.Select((tl) => GetFlatIndexFromCoordinates(tl.ToArray(), topology)).ToArray());
        }
예제 #6
0
        /// <summary>
        /// Gets the list of neighborhood columns around the centar with the given radius in the specified topology.
        /// </summary>
        /// <param name="centerIndex"></param>
        /// <param name="radius"></param>
        /// <param name="topology"></param>
        /// <returns></returns>
        public static int[] GetNeighborhood(int centerIndex, int radius, HtmModuleTopology topology)
        {
            var centerPosition = HtmCompute.GetCoordinatesFromIndex(centerIndex, topology);

            IntGenerator[] intGens = new IntGenerator[topology.Dimensions.Length];
            for (int i = 0; i < topology.Dimensions.Length; i++)
            {
                intGens[i] = new IntGenerator(Math.Max(0, centerPosition[i] - radius),
                                              Math.Min(topology.Dimensions[i] - 1, centerPosition[i] + radius) + 1);
            }

            List <List <int> > result = new List <List <int> >();

            result.Add(new List <int>());

            List <List <int> > interim = new List <List <int> >();

            foreach (IntGenerator gen in intGens)
            {
                interim.Clear();
                interim.AddRange(result);
                result.Clear();

                foreach (var lx in interim)
                {
                    gen.Reset();

                    for (int y = 0; y < gen.Size(); y++)
                    {
                        int        py = gen.Next();
                        List <int> tl = new List <int>();
                        tl.AddRange(lx);
                        tl.Add(py);
                        result.Add(tl);
                    }
                }
            }

            return(result.Select((tl) => GetFlatIndexFromCoordinates(tl.ToArray(), topology)).ToArray());
        }
예제 #7
0
 /// <summary>
 /// Gets a neighborhood of inputs. Simply calls topology.wrappingNeighborhood or topology.neighborhood. A subclass can insert different topology behavior by overriding this method.
 /// </summary>
 /// <param name="isWrapAround"></param>
 /// <param name="inputTopology"></param>
 /// <param name="centerInput">The center of the neighborhood.</param>
 /// <param name="potentialRadius">Span of the input field included in each neighborhood</param>
 /// <returns>The input's in the neighborhood. (1D)</returns>
 public static int[] GetInputNeighborhood(bool isWrapAround, HtmModuleTopology inputTopology, int centerInput, int potentialRadius)
 {
     return(isWrapAround ?
            GetWrappingNeighborhood(centerInput, potentialRadius, inputTopology) :
            GetNeighborhood(centerInput, potentialRadius, inputTopology));
 }