Exemplo n.º 1
0
        private void CombineRanges(
            DvInt4 minRange1, DvInt4 maxRange1, DvInt4 minRange2, DvInt4 maxRange2,
            out DvInt4 newRangeMin, out DvInt4 newRangeMax)
        {
            Contracts.Assert(minRange2.RawValue >= 0 && maxRange2.RawValue >= 0);
            Contracts.Assert(minRange2.RawValue <= maxRange2.RawValue);
            Contracts.Assert(minRange1.RawValue >= 0 && maxRange1.RawValue >= 0);
            Contracts.Assert(minRange1.RawValue <= maxRange1.RawValue);
            Contracts.Assert(maxRange1.RawValue + 1 == minRange2.RawValue);

            newRangeMin = minRange1;
            newRangeMax = maxRange2;
        }
        private void GetCategoricalSlotRanges(int iinfo, ref VBuffer <DvInt4> dst)
        {
            Host.Assert(0 <= iinfo && iinfo < Infos.Length);

            var info = Infos[iinfo];

            Host.Assert(info.TypeSrc.ValueCount > 0);

            DvInt4[] ranges = new DvInt4[info.TypeSrc.ValueCount * 2];
            int      size   = info.TypeSrc.ItemType.KeyCount;

            ranges[0] = 0;
            ranges[1] = size - 1;
            for (int i = 2; i < ranges.Length; i += 2)
            {
                ranges[i]     = ranges[i - 1] + 1;
                ranges[i + 1] = ranges[i] + size - 1;
            }

            dst = new VBuffer <DvInt4>(ranges.Length, ranges);
        }
Exemplo n.º 3
0
 public void Conv(ref int?src, ref DvInt4 dst) => dst = src ?? DvInt4.NA;
Exemplo n.º 4
0
        private void GetCategoricalSlotRangesCore(int iinfo, int[] slotsMin, int[] slotsMax, int[] catRanges, ref VBuffer <DvInt4> dst)
        {
            Host.Assert(0 <= iinfo && iinfo < Infos.Length);
            Host.Assert(slotsMax != null && slotsMin != null);
            Host.Assert(slotsMax.Length == slotsMin.Length);

            Contracts.Assert(catRanges.Length > 0 && catRanges.Length % 2 == 0);

            var ranges = new int[catRanges.Length];

            catRanges.CopyTo(ranges, 0);
            int           rangesIndex            = 0;
            int           dropSlotsIndex         = 0;
            int           previousDropSlotsIndex = 0;
            int           droppedSlotsCount      = 0;
            bool          combine = false;
            DvInt4        min     = -1;
            DvInt4        max     = -1;
            List <DvInt4> newCategoricalSlotRanges = new List <DvInt4>();

            // Six possible ways a drop slot range interacts with categorical slots range.
            //
            //                    +--------------Drop-------------+
            //                    |                               |
            //
            //                +---Drop---+   +---Drop---+   +---Drop---+
            //  +---Drop---+  |          |   |          |   |          |  +---Drop---+
            //  |          |       |____________Range____________|        |          |
            //
            // The below code is better understood as a state machine.

            while (dropSlotsIndex < slotsMin.Length && rangesIndex < ranges.Length)
            {
                Contracts.Assert(rangesIndex % 2 == 0);
                Contracts.Assert(ranges[rangesIndex] <= ranges[rangesIndex + 1]);

                if (slotsMax[dropSlotsIndex] < ranges[rangesIndex])
                {
                    dropSlotsIndex++;
                }
                else if (slotsMin[dropSlotsIndex] > ranges[rangesIndex + 1])
                {
                    if (combine)
                    {
                        CombineRanges(min, max, ranges[rangesIndex] - droppedSlotsCount,
                                      ranges[rangesIndex + 1] - droppedSlotsCount, out min, out max);
                    }
                    else
                    {
                        Contracts.Assert(min.RawValue == -1 && max.RawValue == -1);
                        min = ranges[rangesIndex] - droppedSlotsCount;
                        max = ranges[rangesIndex + 1] - droppedSlotsCount;
                    }

                    newCategoricalSlotRanges.Add(min);
                    newCategoricalSlotRanges.Add(max);
                    min          = max = -1;
                    rangesIndex += 2;
                    combine      = false;
                }
                else if (slotsMin[dropSlotsIndex] <= ranges[rangesIndex] &&
                         slotsMax[dropSlotsIndex] >= ranges[rangesIndex + 1])
                {
                    rangesIndex += 2;
                    if (combine)
                    {
                        Contracts.Assert(min.RawValue >= 0 && min.RawValue <= max.RawValue);
                        newCategoricalSlotRanges.Add(min);
                        newCategoricalSlotRanges.Add(max);
                        min     = max = -1;
                        combine = false;
                    }

                    Contracts.Assert(min.RawValue == -1 && max.RawValue == -1);
                }
                else if (slotsMin[dropSlotsIndex] > ranges[rangesIndex] &&
                         slotsMax[dropSlotsIndex] < ranges[rangesIndex + 1])
                {
                    if (combine)
                    {
                        CombineRanges(min, max, ranges[rangesIndex] - droppedSlotsCount,
                                      slotsMin[dropSlotsIndex] - 1 - droppedSlotsCount, out min, out max);
                    }
                    else
                    {
                        Contracts.Assert(min.RawValue == -1 && max.RawValue == -1);

                        min     = ranges[rangesIndex] - droppedSlotsCount;
                        max     = slotsMin[dropSlotsIndex] - 1 - droppedSlotsCount;
                        combine = true;
                    }

                    ranges[rangesIndex] = slotsMax[dropSlotsIndex] + 1;
                    dropSlotsIndex++;
                }
                else if (slotsMax[dropSlotsIndex] < ranges[rangesIndex + 1])
                {
                    ranges[rangesIndex] = slotsMax[dropSlotsIndex] + 1;
                    dropSlotsIndex++;
                }
                else
                {
                    ranges[rangesIndex + 1] = slotsMin[dropSlotsIndex] - 1;
                }

                if (previousDropSlotsIndex < dropSlotsIndex)
                {
                    Contracts.Assert(dropSlotsIndex - previousDropSlotsIndex == 1);
                    droppedSlotsCount     += slotsMax[previousDropSlotsIndex] - slotsMin[previousDropSlotsIndex] + 1;
                    previousDropSlotsIndex = dropSlotsIndex;
                }
            }

            Contracts.Assert(rangesIndex % 2 == 0);

            if (combine)
            {
                Contracts.Assert(rangesIndex < ranges.Length - 1);
                CombineRanges(min, max, ranges[rangesIndex] - droppedSlotsCount,
                              ranges[rangesIndex + 1] - droppedSlotsCount, out min, out max);

                newCategoricalSlotRanges.Add(min);
                newCategoricalSlotRanges.Add(max);
                rangesIndex += 2;
                combine      = false;
                min          = max = -1;
            }

            Contracts.Assert(min.RawValue == -1 && max.RawValue == -1);

            for (int i = rangesIndex; i < ranges.Length; i++)
            {
                newCategoricalSlotRanges.Add(ranges[i] - droppedSlotsCount);
            }

            Contracts.Assert(newCategoricalSlotRanges.Count % 2 == 0);
            Contracts.Assert(newCategoricalSlotRanges.TrueForAll(x => x.RawValue >= 0));
            Contracts.Assert(0 <= droppedSlotsCount && droppedSlotsCount <= slotsMax[slotsMax.Length - 1] + 1);

            if (newCategoricalSlotRanges.Count > 0)
            {
                dst = new VBuffer <DvInt4>(newCategoricalSlotRanges.Count, newCategoricalSlotRanges.ToArray());
            }
        }