Esempio n. 1
0
        /// <summary>
        /// Uses forecast equation for each historical year.
        /// </summary>
        /// <param name="year1"></param>
        /// <param name="year2"></param>
        /// <returns>a table comparing acutal to forecasted values</returns>
        public DataTable RunHistoricalForecasts(int year1, int year2, bool lookAhead, int forecastMonth, double[] estimationFactors, int forecastDay = 1)
        {
            DataTable tbl = new DataTable(Name);

            //Logger.EnableLogger();
            tbl.Columns.Add("Notes");
            tbl.Columns.Add("Year");
            tbl.Columns.Add("Actual Forecast Period Volume", typeof(double));
            tbl.Columns.Add("Forecasted Period Volume", typeof(double));
            tbl.Columns.Add("Difference", typeof(double));
            tbl.Columns.Add("Error", typeof(double));

            tbl.Columns.Add("Actual Residual Volume", typeof(double));
            tbl.Columns.Add("Forecasted Residual Volume", typeof(double));
            tbl.Columns.Add("Difference2", typeof(double));
            tbl.Columns.Add("Error2", typeof(double));

            // [JR] Hacks to write the inputs to the MLR process
            foreach (var item in this.YTerm.MonthNames)
            {
                tbl.Columns.Add("Y-Runoff-" + item.ToUpper(), typeof(double));
            }
            for (int i = 0; i < this.XTerms.Count(); i++)
            {
                var ithTerm  = this.XTerms[i];
                var termName = "X" + ithTerm.Number + "-" + ithTerm.ForecastTermType;
                foreach (var item in ithTerm.MonthNames)
                {
                    tbl.Columns.Add(termName + "-" + item.ToUpper(), typeof(double));
                }
            }

            for (int i = 1; i < estimationFactors.Length; i++)
            {
                tbl.Columns.Add("Forecast " + estimationFactors[i], typeof(double));
                //tbl.Columns.Add("Difference " + estimationFactors[i], typeof(double));
                //tbl.Columns.Add("Error " + estimationFactors[i], typeof(double));
            }

            HydrometData.SetupHydrometData(StartYear, EndYear, GetCbttPcodeList().ToArray(), DateTime.MaxValue, true, true); // date is ignored when reading all years

            string forecastPeriod = "";

            for (int year = year1; year <= year2; year++)
            {
                var row = tbl.NewRow();
                row["Year"] = year;
                Logger.WriteLine(year.ToString(), "ui");
                DateTime t = new DateTime(year, forecastMonth, forecastDay);
                try
                {
                    var fcResult = Evaluate(t, lookAhead, estimationFactors[0], false);
                    var actual   = YTerm.SeasonalRunoff(t);
                    row["Actual Forecast Period Volume"] = actual;
                    row["Forecasted Period Volume"]      = fcResult.Forecast;
                    var diff = fcResult.Forecast - actual; // convention of FORTRAN
                    row["Difference"] = diff;
                    row["Error"]      = (diff / actual) * 100.0;

                    var actualResid = actual - YTerm.RunoffToDate(t);
                    //var forecastResid = fcResult.GetForecastForSummary(lookAhead);
                    var forecastResid = fcResult.Forecast - YTerm.RunoffToDate(t);

                    row["Actual Residual Volume"]     = actualResid;
                    row["Forecasted Residual Volume"] = forecastResid;
                    row["Difference2"] = forecastResid - actualResid;
                    row["Error2"]      = (forecastResid - actualResid) / actualResid * 100.0;

                    for (int i = 1; i < estimationFactors.Length; i++)
                    {
                        var s = " " + estimationFactors[i];
                        fcResult = Evaluate(t, lookAhead, estimationFactors[i], false);
                        row["Forecasted Period Volume" + s] = fcResult.Forecast;
                        diff = actual - fcResult.Forecast; // convention of FORTRAN
                        //row["Difference"+s] = diff;
                        //row["Error"+s] = (diff / actual) * 100.0;
                    }

                    forecastPeriod = fcResult.ForecastPeriod;
                    // [JR] Hacks to write the inputs to the MLR process
                    #region
                    var sTEMP = this.YTerm.yData;
                    for (int ithMon = 0; ithMon < sTEMP.Count(); ithMon++)
                    {
                        row["Y-Runoff-" + sTEMP[ithMon].DateTime.ToString("MMM").ToUpper()] = sTEMP[ithMon].Value;
                    }
                    foreach (var term in this.XTerms)
                    {
                        if (term.xData.Count() > 0)
                        {
                            var termName = "X" + term.Number + "-" + term.ForecastTermType;
                            var sList    = term.xData;
                            var sSum     = new Reclamation.TimeSeries.Series();
                            for (int i = 0; i < sList.Count; i++)
                            {
                                foreach (var point in sList[i])
                                {
                                    if (i == 0)
                                    {
                                        sSum.Add(point.DateTime, 0.0);
                                    }
                                    sSum[point.DateTime] = new Reclamation.TimeSeries.Point(point.DateTime, sSum[point.DateTime].Value + point.Value);
                                }
                            }
                            foreach (var point in sSum)
                            {
                                try
                                {
                                    row[termName + "-" + point.DateTime.ToString("MMM").ToUpper()] = point.Value;
                                }
                                catch
                                {
                                }
                            }
                        }
                    }
                    #endregion
                }
                catch (Exception ex)
                {
                    row["Notes"] = ex.Message;
                    for (int i = 2; i < row.ItemArray.Count(); i++)
                    {
                        row[i] = Double.NaN;
                    }
                }
                tbl.Rows.Add(row);
            }

            // add some notes
            if (tbl.Rows.Count >= 5)
            {
                tbl.Rows[0]["Notes"] = this.Name;
                tbl.Rows[1]["Notes"] = "Current Forecast Month: " + forecastMonth;
                tbl.Rows[2]["Notes"] = "Current Forecast Day: " + forecastDay;
                tbl.Rows[3]["Notes"] = "Current Forecast Period: " + forecastPeriod;
                tbl.Rows[4]["Notes"] = "Full Forecast Period: " + this.YTerm.MonthNames[0].ToString().ToUpper() +
                                       "-" + this.YTerm.MonthNames[this.YTerm.MonthNames.Count() - 1].ToString().ToUpper();
            }

            var summaryRow = tbl.NewRow();

            summaryRow["Year"] = "Average";
            //summaryRow["Actual Forecast Period Volume"] = tbl.AsEnumerable().Average(x => x.Field<double>("Actual Forecast Period Volume"));
            //summaryRow["Forecasted Period Volume"] = tbl.AsEnumerable().Average(x => x.Field<double>("Forecasted Period Volume"));
            //summaryRow["Difference"] = tbl.AsEnumerable().Average(x => x.Field<double>("Difference"));
            //summaryRow["Error"] = tbl.AsEnumerable().Average(x => x.Field<double>("Error"));

            //summaryRow["Actual Residual Volume"] = tbl.AsEnumerable().Average(x => x.Field<double>("Actual Residual Volume"));
            //summaryRow["Forecasted Residual Volume"] = tbl.AsEnumerable().Average(x => x.Field<double>("Forecasted Residual Volume"));
            //summaryRow["Difference2"] = tbl.AsEnumerable().Average(x => x.Field<double>("Difference2"));
            //summaryRow["Error2"] = tbl.AsEnumerable().Average(x => x.Field<double>("Error2"));

            for (int i = 2; i < tbl.Columns.Count; i++)
            {
                var colName = tbl.Columns[i].ColumnName;
                try
                {
                    var colAvg = tbl.AsEnumerable().Select(x => x.Field <double>(colName)).Where(s => s.ToString() != Double.NaN.ToString()).Average();
                    summaryRow[colName] = colAvg;
                }
                catch
                {
                }
            }

            // Get percent of average for MLR inputs
            for (int i = 10; i < tbl.Columns.Count; i++)
            {
                var colName = tbl.Columns[i].ColumnName;
                try
                {
                    DataColumn ithColumn = tbl.Columns[colName];
                    foreach (DataRow row in tbl.Rows)
                    {
                        double oldVal = row.Field <double>(ithColumn);
                        row.SetField(ithColumn, oldVal / Convert.ToDouble(summaryRow[colName].ToString()));
                    }
                }
                catch
                {
                }
            }

            tbl.Rows.Add(summaryRow);

            return(tbl);
        }
Esempio n. 2
0
        public ForecastResult Evaluate(DateTime t, bool lookAhead, double estimationScaleFactor, bool setupCache = true)
        {
            Logger.WriteLine("Evaluate( " + this.Name + ")");
            var rval = new ForecastResult();

            rval.Equation         = this;
            rval.EstimationFactor = estimationScaleFactor;
            string msg = t.ToShortDateString() + " Forecast " + this.Name + "    " + DateTime.Now.ToShortDateString();

            rval.Details.Add(msg);
            Logger.WriteLine(msg);

            if (setupCache)
            {
                HydrometData.SetupHydrometData(StartYear, EndYear, GetCbttPcodeList().ToArray(), t, true, false);
            }

            rval.Forecast = 0.0;
            //var total = 0;
            int i = 0;

            for (i = 0; i < this.XTerms.Count; i++)
            {
                var X = XTerms[i];
                Logger.WriteLine("Evaluating X" + X.Number);
                var d = X.Evaluate(t, lookAhead, estimationScaleFactor);
                rval.Forecast += d * this.coefficients[X.Number - 1];// apply coeficients...
                rval.Details.AddRange(X.Details());
                rval.Details.Add("X" + X.Number + " = " + d.ToString("F2"));
                rval.Details.Add("");
                Logger.WriteLine("X" + X.Number + "= " + rval.Forecast);
            }

            rval.Details.Add("");

            rval.Forecast += coefficients[coefficients.Length - 1];// k term
            //  Y = C
            string s = "Coefficients: ";

            for (i = 0; i < coefficients.Length; i++)
            {
                s += " " + coefficients[i].ToString("F4");
            }
            rval.Details.Add(s);



            //var runoff = YTerm.Evaluate(t, lookAhead,estimationScaleFactor);
            var runoffToDate   = YTerm.RunoffToDate(t);
            var seasonalRunoff = YTerm.SeasonalRunoff(t);

            rval.Details.AddRange(YTerm.Details());
            var dr = YTerm.MonthNames;

            rval.Details.Add("");
            rval.ForecastPeriod = (t.ToString("MMM") + "-" + dr[dr.Count - 1]).ToUpper();
            rval.AverageRunoff  = Lookup30YearAverageRunoff(t);

            string fullPeriod = (dr[0] + "-" + dr[dr.Count - 1]).ToUpper();

            rval.Details.Add(fullPeriod + "  = " + rval.Forecast.ToString("F2"));


            if (lookAhead)
            {
                // actual runoff
                rval.Details.Add("++ using look ahead for future data");
                rval.Details.Add(dr[0] + "  - " + dr[dr.Count - 1] + " runoff : " + seasonalRunoff.ToString("F1"));
            }
            else
            {
                rval.Details.Add("Runoff to Date : " + runoffToDate.ToString("F1"));
                // forecast forward
                var fc = rval.Forecast - runoffToDate;
                rval.ResidualForecast = fc;
                rval.Details.Add("Date - " + dr[dr.Count - 1] + " forecast : " + fc.ToString("F1"));
            }



            rval.Details.Add("average " + rval.ForecastPeriod + " runoff  = " + rval.AverageRunoff.ToString("F2"));


            return(rval);
        }
Esempio n. 3
0
        /// <summary>
        /// Uses forecast equation for each historical year.
        /// </summary>
        /// <param name="year1"></param>
        /// <param name="year2"></param>
        /// <returns>a table comparing acutal to forecasted values</returns>
        public DataTable RunHistoricalForecasts(int year1, int year2, bool lookAhead, int forecastMonth, double[] estimationFactors, int forecastDay = 1)
        {
            DataTable tbl = new DataTable(Name);

            //Logger.EnableLogger();
            tbl.Columns.Add("Notes");
            tbl.Columns.Add("Year");
            tbl.Columns.Add("Actual Forecast Period Volume", typeof(double));
            tbl.Columns.Add("Forecasted Period Volume", typeof(double));
            tbl.Columns.Add("Difference", typeof(double));
            tbl.Columns.Add("Error", typeof(double));


            tbl.Columns.Add("Actual Residual Volume", typeof(double));
            tbl.Columns.Add("Forecasted Residual Volume", typeof(double));
            tbl.Columns.Add("Difference2", typeof(double));
            tbl.Columns.Add("Error2", typeof(double));


            for (int i = 1; i < estimationFactors.Length; i++)
            {
                tbl.Columns.Add("Forecast " + estimationFactors[i], typeof(double));
                //tbl.Columns.Add("Difference " + estimationFactors[i], typeof(double));
                //tbl.Columns.Add("Error " + estimationFactors[i], typeof(double));
            }

            HydrometData.SetupHydrometData(StartYear, EndYear, GetCbttPcodeList().ToArray(), DateTime.MaxValue, true, true); // date is ignored when reading all years

            for (int year = year1; year <= year2; year++)
            {
                var row = tbl.NewRow();
                row["Year"] = year;
                Logger.WriteLine(year.ToString(), "ui");
                DateTime t = new DateTime(year, forecastMonth, forecastDay);
                try
                {
                    var fcResult = Evaluate(t, lookAhead, estimationFactors[0], false);
                    var actual   = YTerm.SeasonalRunoff(t);
                    row["Actual Forecast Period Volume"] = actual;
                    row["Forecasted Period Volume"]      = fcResult.Forecast;
                    var diff = fcResult.Forecast - actual;   // convention of FORTRAN
                    row["Difference"] = diff;
                    row["Error"]      = (diff / actual) * 100.0;

                    var actualResid   = actual - YTerm.RunoffToDate(t);
                    var forecastResid = fcResult.GetForecastForSummary(lookAhead);

                    row["Actual Residual Volume"]     = actualResid;
                    row["Forecasted Residual Volume"] = forecastResid;
                    row["Difference2"] = forecastResid - actualResid;
                    row["Error2"]      = (forecastResid - actualResid) / actualResid * 100.0;

                    for (int i = 1; i < estimationFactors.Length; i++)
                    {
                        var s = " " + estimationFactors[i];
                        fcResult = Evaluate(t, lookAhead, estimationFactors[i], false);
                        row["Forecasted Period Volume" + s] = fcResult.Forecast;
                        diff = actual - fcResult.Forecast; // convention of FORTRAN
                        //row["Difference"+s] = diff;
                        //row["Error"+s] = (diff / actual) * 100.0;
                    }
                }
                catch (Exception ex)
                {
                    row["Notes"] = ex.Message;
                }


                tbl.Rows.Add(row);
            }

            // add some notes
            if (tbl.Rows.Count >= 3)
            {
                tbl.Rows[0]["Notes"] = this.Name;
                tbl.Rows[1]["Notes"] = "forecast Month " + forecastMonth;
                tbl.Rows[2]["Notes"] = "forecast Day " + forecastDay;
            }

            var summaryRow = tbl.NewRow();

            summaryRow["Year"] = "Average";
            summaryRow["Actual Forecast Period Volume"] = tbl.AsEnumerable().Average(x => x.Field <double>("Actual Forecast Period Volume"));
            summaryRow["Forecasted Period Volume"]      = tbl.AsEnumerable().Average(x => x.Field <double>("Forecasted Period Volume"));
            summaryRow["Difference"] = tbl.AsEnumerable().Average(x => x.Field <double>("Difference"));
            summaryRow["Error"]      = tbl.AsEnumerable().Average(x => x.Field <double>("Error"));


            summaryRow["Actual Residual Volume"]     = tbl.AsEnumerable().Average(x => x.Field <double>("Actual Residual Volume"));
            summaryRow["Forecasted Residual Volume"] = tbl.AsEnumerable().Average(x => x.Field <double>("Forecasted Residual Volume"));
            summaryRow["Difference2"] = tbl.AsEnumerable().Average(x => x.Field <double>("Difference2"));
            summaryRow["Error2"]      = tbl.AsEnumerable().Average(x => x.Field <double>("Error2"));


            tbl.Rows.Add(summaryRow);

            return(tbl);
        }