public static IEnumerable <TKey> GetKeyRangeBetween <TKey, TValue>(this SortedList <TKey, TValue> sortedList, TKey low, TKey high)
    {
        int lowIndex = sortedList.BinarySearch(low);

        if (lowIndex < 0)
        {
            // list doesn't contain the key, find nearest behind
            // If not found, BinarySearch returns the complement of the index
            lowIndex = ~lowIndex;
        }
        int highIndex = sortedList.BinarySearch(high);

        if (highIndex < 0)
        {
            // list doesn't contain the key, find nearest before
            // If not found, BinarySearch returns the complement of the index
            highIndex = ~highIndex - 1;
        }
        var keys = sortedList.Keys;

        for (int i = lowIndex; i < highIndex; i++)
        {
            yield return(keys[i]);
        }
    }
示例#2
0
        /// <summary>
        /// Binary searches one of the control point lists to find the active control point at <paramref name="time"/>.
        /// </summary>
        /// <param name="list">The list to search.</param>
        /// <param name="time">The time to find the control point at.</param>
        /// <param name="prePoint">The control point to use when <paramref name="time"/> is before any control points. If null, a new control point will be constructed.</param>
        /// <returns>The active control point at <paramref name="time"/>.</returns>
        private T binarySearch <T>(SortedList <T> list, double time, T prePoint = null)
            where T : ControlPoint, new()
        {
            if (list.Count == 0)
            {
                return(new T());
            }

            if (time < list[0].Time)
            {
                return(prePoint ?? new T());
            }

            int index = list.BinarySearch(new T {
                Time = time
            });

            // Check if we've found an exact match (t == time)
            if (index >= 0)
            {
                return(list[index]);
            }

            index = ~index;

            // BinarySearch will return the index of the first element _greater_ than the search
            // This is the inactive point - the active point is the one before it (index - 1)
            return(list[index - 1]);
        }
示例#3
0
        /// <summary>
        /// Retrieves the value of the series at a specified point in time. See Remarks for
        /// info on interpolation modes.
        /// </summary>
        /// <remarks>
        /// <para>
        /// When the specified key does not exist in the data set, <see cref="Get"/> will
        /// interpolate or extrapolate as necessary. This can be prevented by using interpolation
        /// mode "None", in which case an exception will be thrown instead.
        /// </para>
        /// <para>
        /// If extrapolation is required, this method will always extrapolate to the nearest
        /// available value. For example, the series "5, 8, 12" would be extrapolated as "5, 5, 5, 8, 12, 12, 12".
        /// </para>
        /// </remarks>
        /// <param name="time"></param>
        /// <param name="interpolation"></param>
        public decimal Get(DateTime time, GncInterpolation interpolation)
        {
            if (time.Kind != DateTimeKind.Utc)
            {
                throw new RTException("DateTime passed to GncTimeSeries.Get must be a UTC time.");
            }

            if (_data.Count == 0)
            {
                throw new InvalidOperationException("Cannot Get a value from an empty GncTimeSeries.");
            }

            if (interpolation == GncInterpolation.None)
            {
                return(_data[time]);           // Throws if not found, as desired for this interpolation type
            }
            int index1, index2;

            _data.BinarySearch(time, out index1, out index2);

            if (index1 == index2)
            {
                return(_data.Values[index1]);  // Found the key we're looking for
            }
            if (index1 == int.MinValue)
            {
                return(_data.Values[index2]);  // Must extrapolate to the left
            }
            if (index2 == int.MaxValue)
            {
                return(_data.Values[index1]);  // Must extrapolate to the right
            }
            if (interpolation == GncInterpolation.NearestBefore)
            {
                return(_data.Values[index1]);
            }
            else if (interpolation == GncInterpolation.NearestAfter)
            {
                return(_data.Values[index2]);
            }
            else if (interpolation == GncInterpolation.Nearest)
            {
                var spanL = time - _data.Keys[index1];
                var spanR = _data.Keys[index2] - time;
                return((spanL <= spanR) ? _data.Values[index1] : _data.Values[index2]);
            }
            else if (interpolation == GncInterpolation.Linear)
            {
                decimal spanL = (decimal)(time - _data.Keys[index1]).Ticks;
                decimal spanR = (decimal)(_data.Keys[index2] - time).Ticks;
                decimal valL  = _data.Values[index1];
                decimal valR  = _data.Values[index2];
                return(valL + (valR - valL) * spanL / (spanL + spanR));
            }

            throw new NotImplementedException(); // if new interpolation modes are added
        }
示例#4
0
        public void TestBinarySearch()
        {
            Assert.Throws <ArgumentNullException>(() => { int i1, i2; CollectionExtensions.BinarySearch <string, string>(null, null, out i1, out i2); });
            Assert.Throws <ArgumentNullException>(() => { int i1, i2; CollectionExtensions.BinarySearch <string, string>(new SortedList <string, string>(), null, out i1, out i2); });
            Assert.Throws <ArgumentNullException>(() => { int i1, i2; CollectionExtensions.BinarySearch <string, string>(null, "", out i1, out i2); });
            Assert.DoesNotThrow(() => { int i1, i2; CollectionExtensions.BinarySearch <string, string>(new SortedList <string, string>(), "", out i1, out i2); });

            SortedList <int, string> list = new SortedList <int, string>();

            Action <int, int, int> assert = (int key, int index1, int index2) =>
            {
                int i1, i2;
                list.BinarySearch(key, out i1, out i2);
                Assert.AreEqual(index1, i1);
                Assert.AreEqual(index2, i2);
            };

            assert(5, int.MinValue, int.MaxValue);

            list.Add(5, "five"); // 5
            assert(4, int.MinValue, 0);
            assert(5, 0, 0);
            assert(6, 0, int.MaxValue);

            list.Add(6, "six"); // 5, 6
            assert(4, int.MinValue, 0);
            assert(5, 0, 0);
            assert(6, 1, 1);
            assert(7, 1, int.MaxValue);

            list.Add(3, "three"); // 3, 5, 6
            assert(2, int.MinValue, 0);
            assert(3, 0, 0);
            assert(4, 0, 1);
            assert(5, 1, 1);
            assert(6, 2, 2);
            assert(7, 2, int.MaxValue);

            list.Add(15, "fifteen"); // 3, 5, 6, 15
            assert(2, int.MinValue, 0);
            assert(3, 0, 0);
            assert(4, 0, 1);
            assert(5, 1, 1);
            assert(6, 2, 2);
            assert(7, 2, 3);
            assert(11, 2, 3);
            assert(14, 2, 3);
            assert(15, 3, 3);
            assert(16, 3, int.MaxValue);

            assert(-999999999, int.MinValue, 0);
            assert(999999999, 3, int.MaxValue);
        }
示例#5
0
    public static IEnumerable <KeyValuePair <TKey, TValue> > GetElementsGreaterThanOrEqual <TKey, TValue>(this SortedList <TKey, TValue> instance, TKey target) where TKey : IComparable <TKey>
    {
        int index = instance.BinarySearch(target);

        if (index < 0)
        {
            index = ~index;
        }
        for (int i = index; i < instance.Count; i++)
        {
            yield return(new KeyValuePair <TKey, TValue>(instance.Keys[i], instance.Values[i]));
        }
    }
示例#6
0
        /// <summary>
        ///     Built-in binary search.
        ///     Time complexity: O(n log n).
        ///     Space complexity: O(n).
        /// </summary>
        public override void AddNum(int num)
        {
            var index = SortedList.BinarySearch(num);

            if (index < 0)
            {
                SortedList.Insert(~index, num);
            }
            else
            {
                SortedList.Insert(index, num);
            }
        }
示例#7
0
        /// <summary>
        /// Generates a <see cref="MultiplierControlPoint"/> with the default timing change/difficulty change from the beatmap at a time.
        /// </summary>
        /// <param name="time">The time to create the control point at.</param>
        /// <returns>The default <see cref="MultiplierControlPoint"/> at <paramref name="time"/>.</returns>
        public MultiplierControlPoint CreateControlPointAt(double time)
        {
            if (DefaultControlPoints.Count == 0)
            {
                return(new MultiplierControlPoint(time));
            }

            int index = DefaultControlPoints.BinarySearch(new MultiplierControlPoint(time));

            if (index < 0)
            {
                return(new MultiplierControlPoint(time));
            }

            return(new MultiplierControlPoint(time, DefaultControlPoints[index]));
        }
示例#8
0
        /// <summary>
        /// Finds the <see cref="MultiplierControlPoint"/> which affects the speed of hitobjects at a specific time.
        /// </summary>
        /// <param name="time">The time which the <see cref="MultiplierControlPoint"/> should affect.</param>
        /// <returns>The <see cref="MultiplierControlPoint"/>.</returns>
        private MultiplierControlPoint controlPointAt(double time)
        {
            if (controlPoints.Count == 0)
            {
                return(new MultiplierControlPoint(double.NegativeInfinity));
            }

            if (time < controlPoints[0].StartTime)
            {
                return(controlPoints[0]);
            }

            searchPoint.StartTime = time;
            int index = controlPoints.BinarySearch(searchPoint);

            if (index < 0)
            {
                index = ~index - 1;
            }

            return(controlPoints[index]);
        }
示例#9
0
文件: Loadings.cs 项目: quanted/hms
        public double ReturnTSLoad(DateTime TimeIndex)
        {
            if (!ITSI_Translated)
            {
                Translate_ITimeSeriesInput();
            }

            double   RetLoad;
            DateTime TIHolder;

            {
                RetLoad = 0;
                bool foundopt = false;
                if ((list != null) && (list.Count != 0))
                {
                    if (lastindexread > -1)
                    {
                        if (list.Keys[lastindexread] == TimeIndex)
                        {
                            RetLoad = list.Values[lastindexread]; foundopt = true;
                        }
                        else if (lastindexread < list.Count - 2)
                        {
                            if (list.Keys[lastindexread + 1] == TimeIndex)
                            {
                                RetLoad = list.Values[lastindexread + 1]; foundopt = true; lastindexread = lastindexread + 1;
                            }
                        }
                    }
                    if (!foundopt)
                    {
                        TIHolder = TimeIndex;
                        if (!Hourly)
                        {
                            TIHolder = TimeIndex.Date;
                        }

                        int indx = list.BinarySearch(TIHolder);
                        if (indx >= 0)
                        {
                            RetLoad = list.Values[indx]; lastindexread = indx;
                        }
                        else
                        {
                            //                       This procedure calculates the time-series loading for a given timeindex.
                            //                         If there is only one time-series loading point present, that is essentially
                            //                         the same thing as a constant load, no further data are available.
                            //
                            //                         If there is more than one point, then the procedure linearly interpolates
                            //                         the correct loading for the time index.A year cycle is also assumed for
                            //                         loading.If the timeindex is between two points, a straight linear interpolation
                            //                         is done.If the timeindex is not between two points,
                            //                         it is moved forward or backward by 1 year increments to try
                            //                         and get it between two points.  If necessary another "dummy" loading is added
                            //                         after the timeindex to make interpolation possible. (if jumping does not
                            //                         place the point within two points}

                            if (list.Count == 0)
                            {
                                RetLoad = 0;
                            }
                            else
                            {
                                //   Four Cases,  (1) TimeIndex before all loading dates,
                                //  (2) TimeIndex after all loading dates,
                                //  (3) TimeIndex in the middle of 2 loading dates
                                //  (4) TimeIndex = Loading Date.}

                                if (indx == ~list.Count) // {case 2}
                                {
                                    do                   //  Move TimeIndex back to create case 1,3, or 4
                                    {
                                        TIHolder = TIHolder.AddYears(-1);
                                        indx     = list.BinarySearch(TIHolder);
                                    }while (indx == ~list.Count);
                                }

                                //     Try to Translate Case 1 into Case 3 or 4 by Moving TimeIndex up.
                                //     May jump all loadings and create case 2}

                                if (indx == -1)
                                {
                                    do                                     // Move TimeIndex forward to create case 2,3, or 4}
                                    {
                                        TIHolder = TIHolder.AddYears(1);
                                        indx     = list.BinarySearch(TIHolder);
                                    }while (indx == -1);
                                }

                                if (indx == ~list.Count)  // Jumped to Case 2, Need to Add "New" Load at end for interpolation
                                {
                                    do
                                    {
                                        list.Add(list.Keys[0].AddYears(1), list.Values[0]);
                                        indx = list.BinarySearch(TIHolder);
                                    }while (indx == ~list.Count);
                                }

                                if (indx >= 0)
                                {
                                    RetLoad = list.Values[indx]; lastindexread = indx;
                                }
                                else
                                {
                                    indx = ~indx;
                                    //   Case 3, Linear Interpolation between TLoad[i - 1] (x1, y1), and TLoad[i] (x2, y2)
                                    double   y1, y2;
                                    DateTime x1, x2;
                                    y1 = list.Values[indx - 1]; x1 = list.Keys[indx - 1];
                                    y2 = list.Values[indx]; x2 = list.Keys[indx];
                                    double m = (y2 - y1) / (x2 - x1).TotalDays;
                                    RetLoad = m * (TIHolder - x1).TotalDays + y1;
                                }
                            }
                        }
                    }
                }
            }
            return(RetLoad);
        }
        public void TestBinarySearch()
        {
            Assert.Throws<ArgumentNullException>(() => { int i1, i2; CollectionExtensions.BinarySearch<string, string>(null, null, out i1, out i2); });
            Assert.Throws<ArgumentNullException>(() => { int i1, i2; CollectionExtensions.BinarySearch<string, string>(new SortedList<string, string>(), null, out i1, out i2); });
            Assert.Throws<ArgumentNullException>(() => { int i1, i2; CollectionExtensions.BinarySearch<string, string>(null, "", out i1, out i2); });
            Assert.DoesNotThrow(() => { int i1, i2; CollectionExtensions.BinarySearch<string, string>(new SortedList<string, string>(), "", out i1, out i2); });

            SortedList<int, string> list = new SortedList<int, string>();

            Action<int, int, int> assert = (int key, int index1, int index2) =>
            {
                int i1, i2;
                list.BinarySearch(key, out i1, out i2);
                Assert.AreEqual(index1, i1);
                Assert.AreEqual(index2, i2);
            };

            assert(5, int.MinValue, int.MaxValue);

            list.Add(5, "five"); // 5
            assert(4, int.MinValue, 0);
            assert(5, 0, 0);
            assert(6, 0, int.MaxValue);

            list.Add(6, "six"); // 5, 6
            assert(4, int.MinValue, 0);
            assert(5, 0, 0);
            assert(6, 1, 1);
            assert(7, 1, int.MaxValue);

            list.Add(3, "three"); // 3, 5, 6
            assert(2, int.MinValue, 0);
            assert(3, 0, 0);
            assert(4, 0, 1);
            assert(5, 1, 1);
            assert(6, 2, 2);
            assert(7, 2, int.MaxValue);

            list.Add(15, "fifteen"); // 3, 5, 6, 15
            assert(2, int.MinValue, 0);
            assert(3, 0, 0);
            assert(4, 0, 1);
            assert(5, 1, 1);
            assert(6, 2, 2);
            assert(7, 2, 3);
            assert(11, 2, 3);
            assert(14, 2, 3);
            assert(15, 3, 3);
            assert(16, 3, int.MaxValue);

            assert(-999999999, int.MinValue, 0);
            assert(999999999, 3, int.MaxValue);
        }
示例#11
0
 /// <summary>Determines whether an <seealso cref="GuidelineEditorPresetEvent"/> is contained in the track.</summary>
 /// <param name="e">The <seealso cref="GuidelineEditorPresetEvent"/> to check whether it is contained in the track.</param>
 public bool Contains(GuidelineEditorPresetEvent e) => events.BinarySearch(e) > -1;
示例#12
0
 /// <summary>Returns the index of the specified <seealso cref="TimingPoint"/> in the list.</summary>
 /// <param name="timingPoint">The <seealso cref="TimingPoint"/> whose index in the list to get.</param>
 public int IndexOf(TimingPoint timingPoint) => timingPoints.BinarySearch(timingPoint);