WienerKolmogorovEstimator implements IComponentsEstimator { @Override public DefaultSeriesDecomposition decompose(SeatsModel model, UcarimaModel ucm, InformationSet info, SeatsContext context) { DefaultSeriesDecomposition decomposition = new DefaultSeriesDecomposition( DecompositionMode.Additive); BurmanEstimatesC burman = new BurmanEstimatesC(); UcarimaModel ucmc = ucm.clone(); ucmc.compact(2, 2); TsData s = model.getSeries(); int nf = nf(s.getFrequency()); TsDomain fdomain = new TsDomain(s.getEnd(), nf); burman.setForecastsCount(nf); if (model.isMeanCorrection()) { burman.setUcarimaModelWithMean(ucmc); } else { burman.setUcarimaModel(ucmc); } burman.setData(s); burman.setSer(model.getSer()); int ncmps = ucmc.getComponentsCount(); TsData[] cmps = new TsData[ncmps]; TsData[] fcmps = new TsData[ncmps]; TsData[] ecmps = new TsData[ncmps]; TsData[] efcmps = new TsData[ncmps]; for (int i = 0; i < ncmps; ++i) { if (i == 0 || !ucmc.getComponent(i).isNull()) { double[] tmp = burman.estimates(i, true); cmps[i] = new TsData(s.getStart(), tmp, false); ecmps[i] = new TsData(s.getStart(), burman.stdevEstimates(i), false); tmp = burman.forecasts(i, true); if (tmp != null) { fcmps[i] = new TsData(s.getEnd(), tmp, false); } tmp = burman.stdevForecasts(i, true); if (tmp != null) { efcmps[i] = new TsData(s.getEnd(), tmp, false); } } } TsData fs = new TsData(s.getEnd(), burman.getSeriesForecasts(), false); TsData efs = null, efsa = null; for (int i = 0; i < efcmps.length; ++i) { if (efcmps[i] != null) { TsData var = efcmps[i].times(efcmps[i]); efs = TsData.add(efs, var); if (i != 1) { efsa = TsData.add(efsa, var); } } } decomposition.add(s, ComponentType.Series); decomposition.add(fs.fittoDomain(fdomain), ComponentType.Series, ComponentInformation.Forecast); if (efs != null) { decomposition.add(efs.fittoDomain(fdomain).sqrt(), ComponentType.Series, ComponentInformation.StdevForecast); } if (cmps[0] != null) { decomposition.add(cmps[0], ComponentType.Trend); } if (cmps[1] != null) { decomposition.add(cmps[1], ComponentType.Seasonal); } if (fcmps[0] != null) { decomposition.add(fcmps[0].fittoDomain(fdomain), ComponentType.Trend, ComponentInformation.Forecast); } if (fcmps[1] != null) { decomposition.add(fcmps[1].fittoDomain(fdomain), ComponentType.Seasonal, ComponentInformation.Forecast); } decomposition.add(TsData.subtract(fs, fcmps[1]), ComponentType.SeasonallyAdjusted, ComponentInformation.Forecast); if (ecmps[0] != null) { decomposition.add(ecmps[0], ComponentType.Trend, ComponentInformation.Stdev); } if (efcmps[0] != null) { decomposition.add(efcmps[0], ComponentType.Trend, ComponentInformation.StdevForecast); } decomposition.add(TsData.subtract(s, cmps[1]), ComponentType.SeasonallyAdjusted); if (ecmps[1] != null) { decomposition.add(ecmps[1], ComponentType.Seasonal, ComponentInformation.Stdev); decomposition.add(ecmps[1], ComponentType.SeasonallyAdjusted, ComponentInformation.Stdev); decomposition.add(efsa.sqrt(), ComponentType.SeasonallyAdjusted, ComponentInformation.StdevForecast); } if (efcmps[1] != null) { decomposition.add(efcmps[1], ComponentType.Seasonal, ComponentInformation.StdevForecast); } decomposition.add(cmps[2], ComponentType.Irregular); if (fcmps[2] != null) { decomposition.add(fcmps[2], ComponentType.Irregular, ComponentInformation.Forecast); } if (ecmps[2] != null) { decomposition.add(ecmps[2], ComponentType.Irregular, ComponentInformation.Stdev); } if (efcmps[2] != null) { decomposition.add(efcmps[2], ComponentType.Irregular, ComponentInformation.StdevForecast); } return decomposition; } WienerKolmogorovEstimator(int npred); @Override DefaultSeriesDecomposition decompose(SeatsModel model, UcarimaModel ucm,
            InformationSet info, SeatsContext context);  }
@Test public void testAirline() { DefaultModelDecomposer decomposer = new DefaultModelDecomposer(false); DescriptiveStatistics tstats = new DescriptiveStatistics(Data.X); double range = tstats.getMax() - tstats.getMin(); for (int i = 1; i <= 19; i+=2) { for (int j = 1; j <= 19; j+=2) { SarimaModel arima = new SarimaModelBuilder().createAirlineModel(12, i * .1 - 1, j * .1 - 1); SeatsModel seats = new SeatsModel(Data.X, arima, false); UcarimaModel ucm = decomposer.decompose(seats, null, null); if (ucm != null) { WienerKolmogorovEstimator wk = new WienerKolmogorovEstimator(-1); DefaultSeriesDecomposition sa1 = wk.decompose(seats, ucm, null, null); KalmanEstimator kl = new KalmanEstimator(-1); DefaultSeriesDecomposition sa2 = kl.decompose(seats, ucm, null, null); TsData t1 = sa1.getSeries(ComponentType.Trend, ComponentInformation.Value); TsData t2 = sa2.getSeries(ComponentType.Trend, ComponentInformation.Value); double d = t1.distance(t2) / range; assertTrue(d < EPS); t1 = sa1.getSeries(ComponentType.Seasonal, ComponentInformation.Value); t2 = sa2.getSeries(ComponentType.Seasonal, ComponentInformation.Value); d = t1.distance(t2) / range; assertTrue(d < EPS); seats.setMeanCorrection(true); sa1 = wk.decompose(seats, ucm, null, null); sa2 = kl.decompose(seats, ucm, null, null); t1 = sa1.getSeries(ComponentType.Trend, ComponentInformation.Value); t2 = sa2.getSeries(ComponentType.Trend, ComponentInformation.Value); d = t1.distance(t2) / range; assertTrue(d < EPS); t1 = sa1.getSeries(ComponentType.Seasonal, ComponentInformation.Value); t2 = sa2.getSeries(ComponentType.Seasonal, ComponentInformation.Value); d = t1.distance(t2) / range; assertTrue(d < EPS); } } } }