/// <summary>
        /// 新增加一个数据判断通过后才入库。
        /// 添加成功后返回true。
        /// </summary>
        /// <param name="key"></param>
        public virtual Boolean CheckAndAdd(double newVal, NumeralWindowData buffer)
        {
            if (ErrorJudge.IsFirst)
            {
                ErrorJudge.SetReferenceValue(newVal);
            }
            else
            {
                ErrorJudge.SetReferenceValue(this.CurrentValue);
            }

            if (ErrorJudge.IsOverLimit(newVal))//判断是否超限
            {
                var list = buffer.ToList();
                list.Insert(0, newVal);

                NumeralWindowData newBuffer = new NumeralWindowData(list);

                if (ErrorJudge.IsJumped(buffer)) //跳跃,则重新计算整数值,否则认为是粗差,直接忽略。
                {
                    CurrentAdjustment = null;    //重新计算滤波值,

                    Add(newVal);
                    return(true);
                }
                return(false);
            }
            else
            {
                Add(newVal);
                return(true);
            }
        }
Example #2
0
        /// <summary>
        /// 获取数窗口
        /// </summary>
        /// <param name="refKey"></param>
        /// <returns></returns>
        public NumeralWindowData <TKey> GetNumeralWindowData(TKey refKey)
        {
            foreach (var item in Cashes.Data)
            {
                if (item.Key.Contains(refKey))
                {
                    return(Cashes[item.Key]);
                }
            }

            //提取数据
            NumeralWindowData <TKey> window = new NumeralWindowData <TKey>(int.MaxValue);
            var seg = this.GetSegmentKeyValue(refKey);

            if (seg.Value == null)
            {
                return(null);
            }

            foreach (var item in seg.Value.Data)
            {
                window.Add(item.Key, item.Value);
            }

            //缓存
            Cashes[seg.Key] = window;


            return(window);
        }
Example #3
0
        /// <summary>
        /// 判断是否是跳变。通过后续缓存窗口数据判断。
        /// 请先调用 IsOverTolerance 确定超限后,再调用我。
        /// 这里假定粗差只出现少数几次或1次。
        /// </summary>
        /// <param name="buffer"></param>
        /// <returns></returns>
        public bool IsJumped(IEnumerable <double> buffer)
        {
            //算法:如果缓存中下面几个全超限,则认为不是粗差,是跳变。
            var nextFive = new NumeralWindowData(buffer);

            return(IsOverLimit(nextFive.AverageValue));
        }
Example #4
0
        public static NumeralWindowData operator +(NumeralWindowData data, double val)
        {
            NumeralWindowData result = new NumeralWindowData(data.Count);

            foreach (var item in data)
            {
                result.Add(item + val);
            }
            return(result);
        }
Example #5
0
        /// <summary>
        /// 获取差分指定次的数据窗口结果,后减前
        /// </summary>
        /// <returns></returns>
        public NumeralWindowData <TKey> GetDifferWindow(int differCount)
        {
            NumeralWindowData <TKey> result = this;

            for (int i = 0; i < differCount; i++)
            {
                result = result.GetDifferWindow();
            }
            return(result);
        }
Example #6
0
        public static NumeralWindowData <TKey> operator +(NumeralWindowData <TKey> data, double val)
        {
            NumeralWindowData <TKey> result = new NumeralWindowData <TKey>(data.Count);

            foreach (var item in data.Data)
            {
                result.Add(item.Key, item.Value + val);
            }
            return(result);
        }
Example #7
0
        /// <summary>
        /// 获取差分一次的数据窗口结果。
        /// </summary>
        /// <returns></returns>
        public NumeralWindowData GetDifferWindow()
        {
            double[] differs = new double[WindowSize - 1];
            for (int i = 0; i < WindowSize - 1; i++)
            {
                differs[i] = this[i + 1] - this[i];
            }
            NumeralWindowData differWindow = new NumeralWindowData(differs);

            return(differWindow);
        }
        /// <summary>
        /// 计算整数偏差。新偏差与原数据应该控制在 0.5 以内。
        /// </summary>
        /// <param name="buffer"></param>
        /// <returns></returns>
        public int CaculateIntBias(NumeralWindowData buffer)
        {
            var average    = buffer.AverageValue;
            var newIntBias = Geo.Utils.DoubleUtil.GetNearstIntBias(average, this.CurrentValue);

            if (IntBias != newIntBias)
            {
                OnIntBiasChanged(newIntBias);
            }
            return(newIntBias);
        }
Example #9
0
        /// <summary>
        /// 判断是否是跳变。通过后续缓存窗口数据判断。
        /// 请先调用 IsOverTolerance 确定超限后,再调用我。
        /// 这里假定粗差只出现少数几次或1次。
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="referValue"></param>
        /// <returns></returns>
        public bool IsJumped(IEnumerable <double> buffer, double referValue)
        {
            if (buffer == null)
            {
                return(false);
            }

            //算法:如果缓存中下面几个全超限,则认为不是粗差,是跳变。
            var nextFive = new NumeralWindowData(buffer);

            return(IsOverLimit(nextFive.AverageValue, referValue));
        }
Example #10
0
        /// <summary>
        /// 拟合后返回各项的拟合误差
        /// </summary>
        /// <param name="polyFitOrder"></param>
        /// <returns></returns>
        public NumeralWindowData <TKey> GetFitErrorWindow(int polyFitOrder)
        {
            NumeralWindowData <TKey> errors = new NumeralWindowData <TKey>(this.WindowSize)
            {
                KeyToDouble = KeyToDouble
            };
            var fitter = BuildPolyfitter(polyFitOrder);

            var firstKey = this.TheVeryFirstKey;

            foreach (var item in this.OrderedData)
            {
                var x     = KeyToDouble(item.Key) - KeyToDouble(firstKey);
                var error = item.Value - fitter.GetY(x);
                errors.Add(item.Key, error);
            }
            return(errors);
        }
Example #11
0
        /// <summary>
        /// 按键间隔分离小窗口。如果间之间的间距超过了指定宽度,则分离成两个或多个子窗口。
        /// </summary>
        /// <param name="funcKeyToDouble">将Key转换为数值</param>
        /// <param name="maxKeySpan"></param>
        /// <returns></returns>
        public List <NumeralWindowData <TKey> > Split(Func <TKey, double> funcKeyToDouble, double maxKeySpan)
        {
            var initSelects = new List <NumeralWindowData <TKey> >();
            var window      = new NumeralWindowData <TKey>(Int16.MaxValue);

            initSelects.Add(window);

            var lastKeyVal = Double.MinValue;

            foreach (var kv in this.Data)
            {
                var key   = kv.Key;
                var val   = kv.Value;
                var keVal = funcKeyToDouble(kv.Key);

                if (window.Count < 1)
                {
                    window.Add(kv.Key, kv.Value); lastKeyVal = keVal; continue;
                }

                var differ = Math.Abs(lastKeyVal - keVal);

                var isPassed = differ <= maxKeySpan;
                if (isPassed)
                {
                    window.Add(kv.Key, kv.Value);
                }
                else
                {
                    //update window size
                    window.WindowSize = window.Count;
                    //create new
                    window = new NumeralWindowData <TKey>(Int16.MaxValue);
                    initSelects.Add(window);
                }
                //update
                lastKeyVal = keVal;
            }
            window.WindowSize = window.Count;
            return(initSelects);
        }
Example #12
0
        /// <summary>
        /// 采用平均值方法,对值进行比较,如果超限则就地分解。
        /// </summary>
        /// <param name="errorTimes"></param>
        /// <returns></returns>
        public List <NumeralWindowData <TKey> > SplitByAverage(int errorTimes)
        {
            //1.初选,采用平均法,放大方差要求,将数据进行分段。
            //遍历,
            var initSelects = new List <NumeralWindowData <TKey> >();
            var window      = new NumeralWindowData <TKey>(Int16.MaxValue);

            initSelects.Add(window);

            foreach (var kv in this.Data)
            {
                var key = kv.Key;
                var val = kv.Value;

                if (window.Count < 1)
                {
                    window.Add(kv.Key, kv.Value); continue;
                }

                var ave    = window.Average;
                var differ = Math.Abs(ave.Value - kv.Value);
                var rms    = ave.Rms == 0 ? double.MaxValue : ave.Rms;

                var errorThreshold = errorTimes * rms;
                var isPassed       = differ <= errorThreshold;
                if (isPassed)
                {
                    window.Add(kv.Key, kv.Value);
                }
                else
                {
                    window.WindowSize = window.Count;
                    window            = new NumeralWindowData <TKey>(Int16.MaxValue);
                    initSelects.Add(window);
                }
            }
            window.WindowSize = window.Count;
            return(initSelects);
        }
Example #13
0
        /// <summary>
        /// 按照指定长度截断。最后如果太小,则直接追加到上一个。
        /// </summary>
        /// <param name="aboutSize">大致大小</param>
        /// <returns></returns>
        private List <NumeralWindowData <TKey> > Split(int aboutSize)
        {
            if (this.Count <= aboutSize)
            {
                return(new List <NumeralWindowData <TKey> >()
                {
                    this
                });
            }

            var initSelects = new List <NumeralWindowData <TKey> >();
            var window      = new NumeralWindowData <TKey>(aboutSize);

            foreach (var kv in this.Data)
            {
                if (window.IsFull)
                {
                    initSelects.Add(window);
                    window = new NumeralWindowData <TKey>(aboutSize);
                }

                window.Add(kv.Key, kv.Value);
            }

            //检查,最后如果太小,则直接追加到上一个。
            if (window.Count < aboutSize / 2)
            {
                var last = initSelects.Last();
                last.WindowSize += window.Count;
                last.Add(window.Data);
            }
            else
            {
                initSelects.Add(window);
            }

            return(initSelects);
        }
        /// <summary>
        /// 新增加一个数据判断通过后才入库。
        /// 添加成功后返回true。
        /// </summary>
        /// <param name="key"></param>
        public override Boolean CheckAndAdd(double newVal, NumeralWindowData buffer)
        {
            //这里同父类一样,采用原始数据判断,以减少计算量。
            if (ErrorJudge.IsFirst)   // 第一次取其小数
            {
                IntBias = CaculateIntBias(buffer.GetNeatlyWindowData());
                ErrorJudge.SetReferenceValue(newVal);
            }
            else
            {
                ErrorJudge.SetReferenceValue(this.IntFraction.Value);
            }

            var fraction = newVal - IntBias;

            if (ErrorJudge.IsOverLimit(newVal))//判断是否超限
            {
                var list = buffer.InsertAndReturnNew(0, newVal);

                if (ErrorJudge.IsJumped(list))//跳跃,则重新计算整数值,否则认为是粗差,直接忽略。
                {
                    var newBuffer2 = new NumeralWindowData(list);
                    var biasBuffer = newBuffer2.GetNeatlyWindowData();
                    IntBias = CaculateIntBias(biasBuffer);

                    fraction = newVal - IntBias;
                    Add(fraction);
                    return(true);
                }
                return(false);
            }
            else
            {
                Add(fraction);
                return(true);
            }
        }
Example #15
0
 /// <summary>
 /// 设置缓存。
 /// </summary>
 /// <param name="Buffers"></param>
 /// <returns></returns>
 public CyclicalNumerFilter SetBuffer(NumeralWindowData Buffers)
 {
     this.Buffers = Buffers;
     return(this);
 }