Beispiel #1
0
        /// <summary>
        /// 获取阶段性的平滑值。以当前键的前边界为起始,指定的数量数据拟合。是改进的阶段平滑窗口。
        /// </summary>
        /// <param name="key">键</param>
        /// <param name="order">拟合次数</param>
        /// <param name="fitDataCount">拟合窗口大小</param>
        /// <param name="marginCount">窗口边沿,不可大于窗口的一半,推荐1/4 窗口大小,最初的几个拟合采用原始的实时拟合算法,最大窗口为指定的边缘大小 </param>
        /// <param name="overlapCount">重合区域数量,默认和缓冲区(edge)相同</param>
        /// <param name="isOverlap">是否采用重合区域计算</param>
        /// <returns></returns>
        public RmsedNumeral GetSectedMovWindowPolyfitValue(int order, TKey key, int fitDataCount, int marginCount = -1, bool isOverlap = true, int overlapCount = -1)
        {
            if (fitDataCount < 4)
            {
                fitDataCount = 4;
            }

            if (marginCount >= fitDataCount / 2 || marginCount < 0)
            {
                marginCount = fitDataCount / 4;
            }

            if (overlapCount >= marginCount || overlapCount < 0)
            {
                overlapCount = marginCount / 2;
            }                                                                                       //默认

            double edgeSpan    = marginCount * Interval;
            double overlapSpan = overlapCount * Interval;

            double keyVal       = KeyToDouble(key);
            int    currentIndex = Geo.Utils.ListUtil.ClosestToIndexOf(this.OrderedKeys, key, KeyToDouble);

            //刚开始的实时常规算法
            //if (currentIndex < marginCount)
            //{
            //    return this.GetPolyFitValue(key, order, marginCount);
            //}

            var builder = PolyfitBuilders.GetOrCreate(order);

            if (!builder.IsFitted) //确保已经生成
            {
                builder = BuildPolyfitBuilder(order, currentIndex, fitDataCount, marginCount);
            }

            var pos = builder.GetPosition(keyVal, overlapSpan, edgeSpan);

            //如果在后面的缓冲区,且后续有足够的数据,则尝试拟合下一拟合区
            if (pos >= PositionOfMovingWindow.LatterOverlap)
            {
                var lastKeyVal = KeyToDouble(this.LastKey);
                if (builder.LastKey < lastKeyVal - edgeSpan || builder.LastKey != lastKeyVal)//新建下一段拟合器
                {
                    builder = BuildPolyfitBuilder(order, currentIndex, fitDataCount, marginCount);
                }
                else
                {
                    int oo = 0;//缓存已经用完
                }
            }

            var val = builder.GetPolyfitValue(keyVal, true, overlapSpan, edgeSpan);

            return(val);
        }
        /// <summary>
        /// 直接根据所指数据构建拟合器。由 PolyfitBuilders 统一管理。
        /// </summary>
        /// <param name="order"></param>
        /// <param name="startIndex"></param>
        /// <param name="endIndex"></param>
        /// <param name="isFromTheVeryFirstKey"></param>
        /// <returns></returns>
        public PolyfitBuilder BuildPolyfitBuilder(int order, int startIndex = 0, int endIndex = int.MaxValue, bool isFromTheVeryFirstKey = true)
        {
            if (endIndex > this.Count - 1 || endIndex < 1)
            {
                endIndex = this.Count - 1;
            }
            bool hasKeyToDouble = KeyToDouble != null;

            startIndex = Gdp.Utils.IntUtil.GetPositiveOrZero(startIndex);
            var keys = this.OrderedKeys;

            var builder = PolyfitBuilders.GetOrCreate(order);

            //检查是否已有,避免重复创建
            if ((hasKeyToDouble && builder.Currrent != null &&
                 builder.FirstKey == KeyToDouble(keys[startIndex]) &&
                 builder.LastKey == KeyToDouble(keys[endIndex]))
                )
            {
                int ii = 0;
            }
            else
            {
                if (startIndex == endIndex) //防止最后历元
                {
                    return(builder);
                }

                //重新生成,以当前Key为基准
                var dic = new Dictionary <double, double>();

                for (int i = startIndex; i <= endIndex; i++)
                {
                    var    item = keys[i];
                    double keyV = i;
                    if (hasKeyToDouble)
                    {
                        keyV = KeyToDouble(item);
                    }
                    dic.Add(keyV, this[item]);
                }

                builder.SetData(dic).SetIsFromTheVeryFirstKey(isFromTheVeryFirstKey);
                builder.Build();
            }

            if (builder.Currrent.StdDev > 10)
            {
                log.Warn("拟合 StdDev 大啊:" + builder.Currrent.StdDev + ", " + builder.Currrent.ToString());
            }

            return(builder);
        }