示例#1
0
        /**
         * {@inheritDoc}
         */
        public override Tuple Decode(int[] encoded, string parentFieldName)
        {
            // Get the scalar values from the underlying scalar encoder
            DecodeResult decodeResult = (DecodeResult)_encoder.Decode(encoded, parentFieldName);

            Map <string, RangeList> fields = decodeResult.GetFields();

            if (fields.Keys.Count == 0)
            {
                return(decodeResult);
            }

            // Convert each range into normal space
            RangeList inRanges  = fields.Values.ToArray()[0];
            RangeList outRanges = new RangeList(new List <MinMax>(), "");

            foreach (MinMax minMax in inRanges.GetRanges())
            {
                MinMax scaledMinMax = new MinMax(Math.Pow(10, minMax.Min()),
                                                 Math.Pow(10, minMax.Max()));
                outRanges.Add(scaledMinMax);
            }

            // Generate a text description of the ranges
            string desc      = "";
            int    numRanges = outRanges.Count;

            for (int i = 0; i < numRanges; i++)
            {
                MinMax minMax = outRanges.GetRange(i);
                if (minMax.Min() != minMax.Max())
                {
                    desc += string.Format("{0:#.00}-{1:#.00}", minMax.Min(), minMax.Max());
                }
                else
                {
                    desc += string.Format("{0:#.00}", minMax.Min());
                }
                if (i < numRanges - 1)
                {
                    desc += ", ";
                }
            }
            outRanges.SetDescription(desc);

            string fieldName;

            if (!parentFieldName.Equals(""))
            {
                fieldName = string.Format("{0}.{1}", parentFieldName, GetName());
            }
            else
            {
                fieldName = GetName();
            }

            Map <string, RangeList> outFields = new Map <string, RangeList>();

            outFields.Add(fieldName, outRanges);

            List <string> fieldNames = new List <string>();

            fieldNames.Add(fieldName);

            return(new DecodeResult(outFields, fieldNames));
        }
示例#2
0
        /**
         * Returns a {@link DecodeResult} which is a tuple of range names
         * and lists of {@link RangeLists} in the first entry, and a list
         * of descriptions for each range in the second entry.
         *
         * @param encoded			the encoded bit vector
         * @param parentFieldName	the field the vector corresponds with
         * @return
         */
        public override Tuple Decode(int[] encoded, string parentFieldName) // returns DecodeResult
        {
            // For now, we simply assume any top-down output greater than 0
            // is ON. Eventually, we will probably want to incorporate the strength
            // of each top-down output.
            if (encoded == null || encoded.Length < 1)
            {
                return(null);
            }
            int[] tmpOutput = Arrays.CopyOf(encoded, encoded.Length);

            // ------------------------------------------------------------------------
            // First, assume the input pool is not sampled 100%, and fill in the
            //  "holes" in the encoded representation (which are likely to be present
            //  if this is a coincidence that was learned by the SP).

            // Search for portions of the output that have "holes"
            int maxZerosInARow = GetHalfWidth();

            for (int wi = 0; wi < maxZerosInARow; wi++)
            {
                int[] searchStr = new int[wi + 3];
                Arrays.Fill(searchStr, 1);
                ArrayUtils.SetRangeTo(searchStr, 1, -1, 0);
                int subLen = searchStr.Length;

                // Does this search string appear in the output?
                if (IsPeriodic())
                {
                    for (int j = 0; j < GetN(); j++)
                    {
                        int[] outputIndices = ArrayUtils.Range(j, j + subLen);
                        outputIndices = ArrayUtils.Modulo(outputIndices, GetN());
                        if (Arrays.AreEqual(searchStr, ArrayUtils.Sub(tmpOutput, outputIndices)))
                        {
                            ArrayUtils.SetIndexesTo(tmpOutput, outputIndices, 1);
                        }
                    }
                }
                else
                {
                    for (int j = 0; j < GetN() - subLen + 1; j++)
                    {
                        if (Arrays.AreEqual(searchStr, ArrayUtils.Sub(tmpOutput, ArrayUtils.Range(j, j + subLen))))
                        {
                            ArrayUtils.SetRangeTo(tmpOutput, j, j + subLen, 1);
                        }
                    }
                }
            }

            LOGGER.Debug("raw output:" + Arrays.ToString(
                             ArrayUtils.Sub(encoded, ArrayUtils.Range(0, GetN()))));
            LOGGER.Debug("filtered output:" + Arrays.ToString(tmpOutput));

            // ------------------------------------------------------------------------
            // Find each run of 1's.
            //int[] nz = tmpOutput.Where(n => n > 0).ToArray();
            int[] nz = ArrayUtils.Where(tmpOutput, x => x > 0);

            //        int[] nz = ArrayUtils.Where(tmpOutput, new Condition.Adapter<Integer>() {
            //        @Override

            //        public boolean eval(int n)
            //    {
            //        return n > 0;
            //    }
            //});
            List <Tuple> runs = new List <Tuple>(); //will be tuples of (startIdx, runLength)

            Array.Sort(nz);
            int[] run = new int[] { nz[0], 1 };
            int   i   = 1;

            while (i < nz.Length)
            {
                if (nz[i] == run[0] + run[1])
                {
                    run[1] += 1;
                }
                else
                {
                    runs.Add(new Tuple(run[0], run[1]));
                    run = new int[] { nz[i], 1 };
                }
                i += 1;
            }
            runs.Add(new Tuple(run[0], run[1]));

            // If we have a periodic encoder, merge the first and last run if they
            // both go all the way to the edges
            if (IsPeriodic() && runs.Count > 1)
            {
                int l = runs.Count - 1;
                if (((int)runs[0].Get(0)) == 0 && ((int)runs[l].Get(0)) + ((int)runs[l].Get(1)) == GetN())
                {
                    runs[l] = new Tuple((int)runs[l].Get(0), ((int)runs[l].Get(1)) + ((int)runs[0].Get(1)));
                    runs    = runs.SubList(1, runs.Count);
                }
            }

            // ------------------------------------------------------------------------
            // Now, for each group of 1's, determine the "left" and "right" edges, where
            // the "left" edge is inset by halfwidth and the "right" edge is inset by
            // halfwidth.
            // For a group of width w or less, the "left" and "right" edge are both at
            // the center position of the group.
            int           left   = 0;
            int           right  = 0;
            List <MinMax> ranges = new List <MinMax>();

            foreach (Tuple tupleRun in runs)
            {
                int start  = (int)tupleRun.Get(0);
                int runLen = (int)tupleRun.Get(1);
                if (runLen <= GetW())
                {
                    left = right = start + runLen / 2;
                }
                else
                {
                    left  = start + GetHalfWidth();
                    right = start + runLen - 1 - GetHalfWidth();
                }

                double inMin, inMax;
                // Convert to input space.
                if (!IsPeriodic())
                {
                    inMin = (left - GetPadding()) * GetResolution() + GetMinVal();
                    inMax = (right - GetPadding()) * GetResolution() + GetMinVal();
                }
                else
                {
                    inMin = (left - GetPadding()) * GetRange() / GetNInternal() + GetMinVal();
                    inMax = (right - GetPadding()) * GetRange() / GetNInternal() + GetMinVal();
                }
                // Handle wrap-around if periodic
                if (IsPeriodic())
                {
                    if (inMin >= GetMaxVal())
                    {
                        inMin -= GetRange();
                        inMax -= GetRange();
                    }
                }

                // Clip low end
                if (inMin < GetMinVal())
                {
                    inMin = GetMinVal();
                }
                if (inMax < GetMinVal())
                {
                    inMax = GetMinVal();
                }

                // If we have a periodic encoder, and the max is past the edge, break into
                //  2 separate ranges
                if (IsPeriodic() && inMax >= GetMaxVal())
                {
                    ranges.Add(new MinMax(inMin, GetMaxVal()));
                    ranges.Add(new MinMax(GetMinVal(), inMax - GetRange()));
                }
                else
                {
                    if (inMax > GetMaxVal())
                    {
                        inMax = GetMaxVal();
                    }
                    if (inMin > GetMaxVal())
                    {
                        inMin = GetMaxVal();
                    }
                    ranges.Add(new MinMax(inMin, inMax));
                }
            }

            string desc = GenerateRangeDescription(ranges);
            string fieldName;

            // Return result
            if (parentFieldName != null && !string.IsNullOrWhiteSpace(parentFieldName))
            {
                fieldName = string.Format("%s.%s", parentFieldName, GetName());
            }
            else
            {
                fieldName = GetName();
            }

            RangeList inner = new RangeList(ranges, desc);
            Map <string, RangeList> fieldsDict = new Map <string, RangeList>();

            fieldsDict.Add(fieldName, inner);

            return(new DecodeResult(fieldsDict, new List <string> {
                fieldName
            }));
        }