; Copyright (c) 1995, Research Systems, Inc. All rights reserved. ; Unauthorized reproduction prohibited. ;+ ; NAME: Forecast ; ; PURPOSE: This example demonstrates the fundamental principles of statistical ; time-series analysis. ; ; MAJOR TOPICS: Statistics and Widgets. ; ; CALLING SEQUENCE: Forecast ; ; PROCEDURE: Forecast computes future values of a time-series using an ; autoregressive forecasting model. The accuracy of the model and ; the number of forecasts are adjustable through slider widgets. ; ; MAJOR FUNCTIONS and PROCEDURES: ; A_CORRELATE: Sample autocorrelation function. ; PLOT: X-Y plotting. ; PLOTS: Line and symbol plotting. ; SPLINE: Spline interpolation. ; TS_FCAST: Autoregressive time-series forecasting. ; ; COMMON BLOCKS and STRUCTURES: ; Attributes: This common block contains the attributes of the time- ; series data; maximum value, number of elements, etc. ; Parameters: This common block contains the parameters that are used ; to initialize and update the state of the widget hierarchy. ; SeriesData: This common block contains the time-series and forecast ; data. ; ; RESTRICTIONS: Platform specific information... ; ; REFERENCE: The Analysis of Time Series, An Introduction (Fourth Edition) ; Chapman and Hall ; ISBN 0-412-31820-2 ; ; MODIFICATION HISTORY: Written by: GGS, RSI, January 1995 ;- PRO AutoCorr ; This call-back function computes the sample autocorrelation function ; and the 95% confidence interval of cYdata. The results are plotted in ; the draw window, cPwindow2. ; Define the time-series and forecasting data COMMON block. COMMON SeriesData, cXdata, cYdata, cFuture ; Define the data attributes COMMON block. COMMON Attributes, cNy, cXmax, cYmax, cYmin ; Define the parameters COMMON block. COMMON Parameters, cOrder, cNfcast, cFcastmax, cInfotext, $ cPwindow1, cPwindow2 ; Set the active plot window to cPwindow2. WSET, cPwindow2 ; Compute the sample autocorrelation function of cYdata for the time ;indexes, [0, 1, 2, ... , cNy-2]. autocorrY = A_CORRELATE(cYdata, INDGEN(cNy-1)) ; Compute the 95% confidence interval for cYdata. conf = 1.96 / SQRT(cNy) ; Establish the plotting coordinate system. PLOT, autocorrY, YRANGE=[-1, 1], YSTYLE=2, YMINOR=1, YTICKLEN=-0.008, $ LINESTYLE=0, COLOR=0, BACKGROUND=200, $ TITLE="Time-Series Sample Autocorrelation", /NODATA ; Overplot the sample autocorrelation function of cYdata. OPLOT, autocorrY, COLOR=86 ; Plot the upper confidence interval limit line. PLOTS, 0, conf, COLOR=0 PLOTS, cXmax, conf, COLOR=0, LINESTYLE=5, /CONTINUE ; Plot the lower confidence interval limit line. PLOTS, 0, -conf, COLOR=0 PLOTS, cXmax, -conf, COLOR=0, LINESTYLE=5, /CONTINUE END pro AutoFcast ; This call-back function computes the autoregressive forecasting model ; of the time-series data, cYdata. The time-series data and forecasts ; are plotted in the draw window, cPwindow1. ; Reference the time-series and forecasting data COMMON block. COMMON SeriesData ; Reference the data attributes COMMON block. COMMON Attributes ; Reference the parameters COMMON block. COMMON Parameters ; Compute (cNfcast) forecasts using a model of order (cOrder). cFuture = TS_FCAST(cYdata, cOrder, cNfcast) ; Set the active plot window to cPwindow2. WSET, cPwindow1 ; Establish the plotting coordinate system. PLOT, cXdata, cYdata, XRANGE=[0, cXmax+cFcastmax], XSTYLE=2, $ YRANGE=[cYmin-1, cYmax+1], YSTYLE=2, $ YMINOR=1, YTICKLEN=-0.008, LINESTYLE=0, $ CHARSIZE=1.3, COLOR=0, BACKGROUND=200, /NODATA ; Overplot the time-series data with a "diamond" symbol. OPLOT, cXdata, cYdata, PSYM=4, SYMSIZE=2, COLOR=86 ; Overplot the forecast data with a "triangle" symbol. OPLOT, [cXmax+indgen(cNfcast)+1], cFuture, PSYM=5, SYMSIZE=1.5, COLOR=156 ; Compute a smooth spline fit to the time-series and forecast data by ; increasing the number of points by a factor of fac. fac = 10 xint = FINDGEN(fac*MAX(cXdata+cNfcast)+1) / fac yint = SPLINE(FINDGEN(cNy+cNfcast), [cYdata,cFuture], xint, 0.1) ; Overplot the time-series and forecast data with the spline fit. OPLOT, xint, yint, LINESTYLE=0, COLOR=0 ; Create a symbol legend using the NORMAL coordinate system. ; Plot a "diamond" symbol. PLOTS, 0.25, 0.07, PSYM = 4, SYMSIZE = 2, COLOR = 86, /NORMAL ; Plot the corresponding label. XYOUTS, 0.27, 0.06, "Time-Series Data", COLOR = 0, /NORMAL ;Plot a "triangle" symbol. PLOTS, 0.65, 0.075, PSYM = 5, SYMSIZE = 1.5, COLOR = 156, /NORMAL ; Plot the corresponding label XYOUTS, 0.67, 0.06, "Autoregressive Forecasts", COLOR = 0, /NORMAL END PRO Hardcopy, event ; This call-back function creates a Postscript file of the time-series ; data and forecasts. ; Reference the time-series and forecasting data COMMON block. COMMON SeriesData ; Reference the data attributes COMMON block. COMMON Attributes ; Reference the parameters COMMON block. COMMON Parameters ; Determine the current device setting. devSetting = !D.NAME ; Let the user specify the filename and path. psfile = PICKFILE(FILE="Forecast.ps", GROUP=event.top, /WRITE) ; If a file name is selected then proceed with PS output. IF psfile NE "" THEN BEGIN ; Ensure that the selected file may be opened. OPENW, unit, psfile, /GET_LUN, ERROR=FileError ; A zero error status indicates a valid file. ; Notify the user if an error occurs. IF FileError NE 0 THEN BEGIN errorMessage = WIDGET_MESSAGE([!err_string, $ ' Cannot open the file ' + psfile]) ;CLOSE, unit RETURN ENDIF ELSE $ CLOSE, unit ; Set the active device to Postscript. SET_PLOT, "PS" ; Define the characteristics of the Postscript file. DEVICE, FILENAME=psfile, XSIZE=10.5, YSIZE=3.5, XOFFSET=1.5, $ YOFFSET=10.8, BITS_PER_PIXEL=8, /INCHES, /LANDSCAPE ; Establish the plotting coordinate system. PLOT, cXdata, cYdata, XRANGE=[0, cXmax+cFcastmax], XSTYLE=2, $ YRANGE=[cYmin-1, cYmax+1], YSTYLE=2, $ YMINOR=1, YTICKLEN=-0.008, LINESTYLE=0, $ CHARSIZE=0.8, /NODATA ; Overplot the time-series data with a "diamond" symbol. OPLOT, cXdata, cYdata, PSYM=4 ; Overplot the forecast data with a "triangle" symbol. OPLOT, [cXmax+INDGEN(cNfcast)+1], cFuture, PSYM=5 ; Compute a smooth spline fit to the time-series and forecast data by ; increasing the number of points by a factor of fac. fac = 10 xint = FINDGEN(fac * MAX(cXdata+cNfcast)+1) / fac yint = SPLINE(FINDGEN(cNy+cNfcast), [cYdata,cFuture], xint, 0.1) ; Overplot the time-series and forecast data with the spline fit. OPLOT, xint, yint, LINESTYLE=0 ; Create a symbol legend using the NORMAL coordinate system. ; Plot a "diamond" symbol. PLOTS, 0.25, 0.05, PSYM=4, /NORMAL ; Plot the corresponding label. XYOUTS, 0.27, 0.04, "Time-Series Data", SIZE=0.8, /NORMAL ;Plot a "triangle" symbol. PLOTS, 0.65, 0.055, PSYM=5, /NORMAL ; Plot the corresponding label XYOUTS, 0.67, 0.04, "Autoregressive Forecasts", SIZE=0.8, /NORMAL ; Close the Postscript device. DEVICE, /CLOSE ; Restore the original device setting. SET_PLOT, devSetting ENDIF ELSE RETURN END PRO Info ; This call-back function defines an informational string that is ; displayed when the "Info" button is pressed. ; Reference the parameters COMMON block. COMMON Parameters ; Define the informational string. cInfotext = $ [" This example illustrates the fundamental principles of time-series "+$ "forecasting by allowing the user to generate data and change the "+ $ "forecasting parameters.", "", $ " A time-series is a sequential collection of data observations indexed "+ $ "over time. Modelling a time-series as a combination of past values "+ $ "and residual white noise allows the extrapolation of data for future "+ $ "values of time. This process is known as FORECASTING and uses an "+ $ "AUTOREGRESSIVE FORECASTING MODEL of ORDER P, where P represents "+ $ "the number of past time-series values used to compute the forecast. "+ $ "In general, the accuracy of the forecast improves as the value of P "+ $ "increases. The order of the AUTOREGRESSIVE FORECASTING MODEL and "+ $ "the number of forecasts are adjusted using the sliders in the "+ $ "Forecasting Parameters box.", "", $ " The SAMPLE AUTOCORRELATION function is a commonly used tool to "+ $ "determine the accuracy of a forecasting model. The autocorrelation "+ $ "of a time-series measures the dependence between observations as "+ $ "a function of their time difference or LAG. An N-element time-series "+ $ "with approximately 95% of its values in the interval, ", $ " [-1.96/sqrt(N), 1.96/sqrt(N)],", $ "is said to be STATIONARY and is the prerequisite to an accurate "+ $ "forecast. This interval is displayed with dashed lines on the plot "+ $ "of the SAMPLE AUTOCORRELATION.", "", $ " Button Descriptions:", "", $ " Info: Displays this help file.", $ " Postscript: Creates Postscript file of time-series and "+ $ "forecast plot.", $ " Random Time-Series: Generates a new pseudo-random time-series.", $ " Exit Forecasting: Quits Forecasting Example.", "", $ " See the MATHEMATICS section of the on-line help for more information."] END PRO TSdata, RANDOM = random ; This call-back function defines either a pseudo-random or static ; time-series. ; Reference the time-series and forecasting data COMMON block. COMMON SeriesData ; Reference the data attributes COMMON block. COMMON Attributes ; Reference the parameters COMMON block. COMMON Parameters ; Create a pseudo-random time-series. IF KEYWORD_SET(random) NE 0 THEN $ cYdata = SMOOTH(RANDOMN(seed, 41) * RANDOMU(seed, 41) * 50, 5) $ ELSE $ ; Uniformly sampled time-series data. cYdata = [66.85, 67.08, 70.79, 69.90, 66.76, 67.43, 65.92, 66.31, $ 67.12, 67.18, 65.05, 66.40, 65.54, 66.08, 65.39, 66.51, $ 67.25, 69.12, 68.45, 68.57, 69.57, 67.05, 67.41, 65.81, $ 67.70, 67.92, 69.67, 68.20, 67.72, 67.56, 65.30, 65.46, $ 63.41, 64.98, 66.03, 66.80, 66.79, 65.96, 67.47, 69.02, $ 69.88] cNy = N_ELEMENTS(cYdata) ;Number of time-series points. cXdata = LINDGEN(cNy) ;Indexed time intervals, [0, 1, 2, ... , Cny-1]. cXmax = MAX(cXdata) ;Maximum x value. cYmax = MAX(cYdata) ;Maximum y value. cYmin = MIN(cYdata) ;Minimum y value. cFcastmax = cNy - 1 ;Maximum number of forecasts. END pro ForecastEventHdlr, event ; This procedure is the event handler. ; Reference the parameters COMMON block. COMMON Parameters ; Determine the event. WIDGET_CONTROL, event.id, GET_UVALUE=eventval ; Take the following action based on the corresponding event. CASE eventval OF "GenerateTS": BEGIN ; Activate the HOURGLASS cursor to indicate ; a computationally intensive event. WIDGET_CONTROL, event.id, /HOURGLASS ; Generate a pseudo-random time-series. TSdata, /random ; Compute the autoregressive forecasting model. AutoFcast ; Compute the sample autocorrelation function. AutoCorr END "HARDCopy": BEGIN WIDGET_CONTROL, event.id ; Create a Postscript file. Hardcopy, event END "INFO": BEGIN WIDGET_CONTROL, event.id ; Display informational text. ShowInfo, GROUP=event.top, HEIGHT=35, WIDTH=80, $ INFOTEXT=cInfotext, $ TITLE="Time-Series Forecasting Info" END ; Destroy widget hierarchy. "QUIT": WIDGET_CONTROL, event.top, /DESTROY "SETOrder": BEGIN ; Determine the order of the forecasting model. WIDGET_CONTROL, event.id, GET_VALUE=cOrder ; Compute the forecast using a model of order (cOrder). AutoFcast END "SETNumber": BEGIN ; Determine the number of the forecasts. WIDGET_CONTROL, event.id, GET_VALUE=cNfcast ; Compute (cNfcast) forecasts. AutoFcast END ENDCASE END PRO CleanUpForecast, wForecastWindow ; Get the color table saved in the window's user value WIDGET_CONTROL, wForecastWindow, GET_UVALUE=previousState ; Restore the previous color table. TVLCT, previousState.colorTable ; Restore the previous plot font. !P.FONT = previousState.plotFont END pro Forecast, GROUP = group ; This is the main procedure. Common block data is initialized and ; the widget hierarchy is realized. ; Reference the time-series and forecasting data COMMON block. COMMON SeriesData ; Reference the data attributes COMMON block. COMMON Attributes ; Reference the parameters COMMON block. COMMON Parameters ; Get the current color vectors to restore when this application is exited. TVLCT, savedR, savedG, savedB, /GET ; Build color table from color vectors colorTable = [[savedR],[savedG],[savedB]] ; Save the current plot font in order to restore it when ; the spiro application is exited plotFont = !P.FONT ; Save items to be restored on exit in a structure previousState = {colorTable:colorTable, plotFont:plotFont} ; Call the TSdata procedure to initialize common block data. TSdata ; Call the Info procedure to initialize informational string. Info ; Define the initial forecasting model order parameter. cOrder = 25 ; Define the initial number of forecasts. cNfcast = 40 ; Load a predefined color tabel. LOADCT, 12, /SILENT ; Use harware-drawn font. !P.FONT=0 ; Determine hardware display size. DEVICE, GET_SCREEN_SIZE = cScrnsz ; Define a main widget base. wTop = WIDGET_BASE(TITLE="Time-Series Forecasting Tool", /COLUMN, UVALUE=previousState) ; Define a draw widget with a horizontal dimension that is 80% of the ; horizontal hardware display size and a vertical dimension that is 30% ; of the horizontal hardware display size. wDraw1 = WIDGET_DRAW(wTop, XSIZE=0.8*cScrnsz(0), YSIZE=0.3*cScrnsz(0), $ RETAIN=2) ; Define a sub-base with row format belonging to wTop. wRbase = WIDGET_BASE(wTop, /ROW) ; Define a sub-base with column format belonging to wRbase. wCbase1 = WIDGET_BASE(wRbase, /COLUMN, /FRAME) ; Define a sub-base with column format belonging to wRbase. wCbase2 = WIDGET_BASE(wRbase, /COLUMN, /FRAME) ; Define a sub-base with column format belonging to wRbase. wCbase3 = WIDGET_BASE(wRbase, /COLUMN, /FRAME) ; Define a draw widget with a horizontal dimension that is 40% of the ; horizontal hardware display size and a vertical dimension that is 20% ; of the horizontal hardware display size. wDraw2 = WIDGET_DRAW(wCbase3, XSIZE=0.4*cScrnsz(0), YSIZE=0.2*cScrnsz(0), $ RETAIN=2) ; Define two label widgets belonging to wCbase1. wLabel1 = WIDGET_LABEL(wCbase1, VALUE = " Forecasting Parameters ", /FRAME) wLabel2 = WIDGET_LABEL(wCbase1, VALUE = " ") ; Define a slider widget to adjust the order of the forecasting model. wSlider1 = WIDGET_SLIDER(wCbase1, MIN=2, MAX=cFcastmax, VALUE=cOrder, $ UVALUE="SETOrder", XSIZE=0.2*cScrnsz(0), $ TITLE="Order of the Model") ; Define a slider widget to adjust the number of forecasts. wSlider2 = WIDGET_SLIDER(wCbase1, MIN=1, MAX=cFcastmax, VALUE=cNfcast, $ UVALUE="SETNumber", XSIZE=0.2*cScrnsz(0), $ TITLE="Number of Forecasts") ; Define a button widget to display informational text. wButton1 = WIDGET_BUTTON(wCbase2, VALUE=" Info...", UVALUE="INFO") ; Define a button widget to create a Postscript file. wButton3 = WIDGET_BUTTON(wCbase2, VALUE=" Postscript... ", UVALUE="HARDCopy") ; Define a button widget to generate a pseudo-random time-series. wButton4 = WIDGET_BUTTON(wCbase2, VALUE=" Random Time-Series ", $ UVALUE="GenerateTS") ; Define a button widget to quit the application. wButton5 = WIDGET_BUTTON(wCbase2, VALUE=" Exit Forecasting ", UVALUE="QUIT") ; Realize the widget hierarchy. WIDGET_CONTROL, wTop, /REALIZE ; Setup the device to use the pointer cursors DEVICE, /CURSOR_ORIGINAL ; Determine the window value of plot window, wDraw1. WIDGET_CONTROL, wDraw1, GET_VALUE=cPwindow1 ; Determine the window value of plot window, wDraw2. WIDGET_CONTROL, wDraw2, GET_VALUE=cPwindow2 ; Set the active plot window to cPwindow2. WSET, cPwindow2 ; Compute the initial forecast. AutoFcast ; Compute the initial sample autocorrelation. AutoCorr ; Register with the BIG GUY, XMANAGER! XMANAGER, "Forecast", wTop, GROUP_LEADER=group, EVENT_HANDLER = "ForecastEventHdlr", $ CLEANUP="CleanUpForecast" END