Esempio n. 1
0
        public SeasonalTrendLoess buildSmoother(double[] data)
        {
            this.sanityCheck(data);

            if (this.fPeriodic)
            {
                this.fSeasonalWidth  = (100 * data.Length);
                this.fSeasonalDegree = 0;
            }
            else if (this.fSeasonalDegree == 0)
            {
                this.fSeasonalDegree = 1;
            }

            var seasonalSettings = buildSettings(this.fSeasonalWidth, this.fSeasonalDegree, this.fSeasonalJump);

            if (this.fFlatTrend)
            {
                this.fTrendWidth  = 100 * this.fPeriodLength * data.Length;
                this.fTrendDegree = 0;
            }
            else if (this.fLinearTrend)
            {
                this.fTrendWidth  = 100 * this.fPeriodLength * data.Length;
                this.fTrendDegree = 1;
            }
            else if (this.fTrendDegree == 0)
            {
                this.fTrendDegree = 1;
            }

            if ((this.fTrendWidth == 0))
            {
                this.fTrendWidth = SeasonalTrendLoessBuilder.calcDefaultTrendWidth(this.fPeriodLength, this.fSeasonalWidth);
            }

            LoessSettings trendSettings = this.buildSettings(this.fTrendWidth, this.fTrendDegree, this.fTrendJump);

            if ((this.fLowpassWidth == 0))
            {
                this.fLowpassWidth = this.fPeriodLength;
            }

            LoessSettings lowpassSettings = this.buildSettings(this.fLowpassWidth, this.fLowpassDegree, this.fLowpassJump);

            var stl = new SeasonalTrendLoess(data, this.fPeriodLength, this.fInnerIterations, this.fRobustIterations,
                                             seasonalSettings, trendSettings, lowpassSettings);

            return(stl);
        }
Esempio n. 2
0
        /// <summary>
        /// Perform STL time series decomposition
        /// </summary>
        /// <param name="values"></param>
        /// <param name="sWindow"></param>
        /// <param name="sDegree"></param>
        /// <param name="tWindow"></param>
        /// <param name="tDegree"></param>
        /// <param name="lWindow"></param>
        /// <param name="lDegree"></param>
        /// <param name="sJump"></param>
        /// <param name="tJump"></param>
        /// <param name="lJump"></param>
        /// <param name="isRobust"></param>
        /// <param name="inner"></param>
        /// <param name="outer"></param>
        /// <returns>Tuple of the three components</returns>
        public static (double[] Trend, double[] Seasonal, double[] Residual) Fit(double[] values,
                                                                                 int sWindow, int sDegree = 0, int tWindow = 0, int tDegree = 1, int lWindow = 0, int lDegree = 0,
                                                                                 int sJump = 0, int tJump = 0, int lJump = 0, bool isRobust = false, int inner = 0, int outer = 0)
        {
            var builder = new SeasonalTrendLoessBuilder();

            builder.PeriodLength = sWindow;    // Data has a period of 12
            builder.Periodic     = sWindow > 0;
            //  setSeasonalWidth(12).   // Monthly data smoothed over 35 years
            builder.Robust = isRobust;         // Not expecting outliers, so no robustness iterations


            var smoother = builder.buildSmoother(values);

            var stl = smoother.decompose();

            return(stl.Trend, stl.Seasonal, stl.Residual);
        }
Esempio n. 3
0
        public static Decomposition performRobustPeriodicDecomposition(double[] data, int periodicity)
        {
            //  The LOESS interpolator with degree 0 and a very long window (arbitrarily chosen to be 100 times the length of
            //  the array) will interpolate all points as the average value of the series. This particular setting is used
            //  for smoothing the seasonal sub-cycles, so the end result is that the seasonal component of the decomposition
            //  is exactly periodic.
            //  This fit is for diagnostic purposes, so we just do a single inner and outer iteration.
            var stlBuilder = new SeasonalTrendLoessBuilder();

            stlBuilder.PeriodLength     = periodicity;
            stlBuilder.SeasonalWidth    = 100 * data.Length;
            stlBuilder.SeasonalDegree   = 0;
            stlBuilder.InnerIterations  = 1;
            stlBuilder.RobustIterations = 1;
            var stl = stlBuilder.buildSmoother(data);

            return(stl.decompose());
        }