Changeset 8468


Ignore:
Timestamp:
08/10/12 15:58:36 (9 years ago)
Author:
mkommend
Message:

#1081: Adapated calculation of results for horizons larger than 1.

Location:
branches/HeuristicLab.TimeSeries
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/TimeSeries/AutoregressiveModeling.cs

    r8430 r8468  
    8383
    8484    internal ITimeSeriesPrognosisSolution CreateAutoRegressiveSolution(ITimeSeriesPrognosisProblemData problemData, int timeOffset, out double rmsError, out double cvRmsError) {
    85       Dataset dataset = problemData.Dataset;
    8685      string targetVariable = problemData.TargetVariable;
    8786
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/TimeSeriesPrognosisSolutionView.cs

    r8010 r8468  
    4040      base.OnContentChanged();
    4141      if (Content != null) {
    42         horizonTextBox.Text = Content.Horizon.ToString();
     42        //horizonTextBox.Text = Content.Horizon.ToString();
    4343      }
    4444    }
     
    7070      int val;
    7171      int.TryParse(horizonTextBox.Text, out val);
    72       Content.Horizon = val;
     72      //Content.Horizon = val;
    7373    }
    7474  }
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolutionBase.cs

    r8458 r8468  
    2929  [StorableClass]
    3030  public abstract class RegressionSolutionBase : DataAnalysisSolution, IRegressionSolution {
    31     private const string TrainingMeanSquaredErrorResultName = "Mean squared error (training)";
    32     private const string TestMeanSquaredErrorResultName = "Mean squared error (test)";
    33     private const string TrainingMeanAbsoluteErrorResultName = "Mean absolute error (training)";
    34     private const string TestMeanAbsoluteErrorResultName = "Mean absolute error (test)";
    35     private const string TrainingSquaredCorrelationResultName = "Pearson's R² (training)";
    36     private const string TestSquaredCorrelationResultName = "Pearson's R² (test)";
    37     private const string TrainingRelativeErrorResultName = "Average relative error (training)";
    38     private const string TestRelativeErrorResultName = "Average relative error (test)";
    39     private const string TrainingNormalizedMeanSquaredErrorResultName = "Normalized mean squared error (training)";
    40     private const string TestNormalizedMeanSquaredErrorResultName = "Normalized mean squared error (test)";
    41     private const string TrainingMeanErrorResultName = "Mean error (training)";
    42     private const string TestMeanErrorResultName = "Mean error (test)";
     31    protected const string TrainingMeanSquaredErrorResultName = "Mean squared error (training)";
     32    protected const string TestMeanSquaredErrorResultName = "Mean squared error (test)";
     33    protected const string TrainingMeanAbsoluteErrorResultName = "Mean absolute error (training)";
     34    protected const string TestMeanAbsoluteErrorResultName = "Mean absolute error (test)";
     35    protected const string TrainingSquaredCorrelationResultName = "Pearson's R² (training)";
     36    protected const string TestSquaredCorrelationResultName = "Pearson's R² (test)";
     37    protected const string TrainingRelativeErrorResultName = "Average relative error (training)";
     38    protected const string TestRelativeErrorResultName = "Average relative error (test)";
     39    protected const string TrainingNormalizedMeanSquaredErrorResultName = "Normalized mean squared error (training)";
     40    protected const string TestNormalizedMeanSquaredErrorResultName = "Normalized mean squared error (test)";
     41    protected const string TrainingMeanErrorResultName = "Mean error (training)";
     42    protected const string TestMeanErrorResultName = "Mean error (test)";
     43
     44    protected const string TrainingMeanSquaredErrorResultDescription = "Mean of squared errors of the model on the training partition";
     45    protected const string TestMeanSquaredErrorResultDescription = "Mean of squared errors of the model on the test partition";
     46    protected const string TrainingMeanAbsoluteErrorResultDescription = "Mean of absolute errors of the model on the training partition";
     47    protected const string TestMeanAbsoluteErrorResultDescription = "Mean of absolute errors of the model on the test partition";
     48    protected const string TrainingSquaredCorrelationResultDescription = "Squared Pearson's correlation coefficient of the model output and the actual values on the training partition";
     49    protected const string TestSquaredCorrelationResultDescription = "Squared Pearson's correlation coefficient of the model output and the actual values on the test partition";
     50    protected const string TrainingRelativeErrorResultDescription = "Average of the relative errors of the model output and the actual values on the training partition";
     51    protected const string TestRelativeErrorResultDescription = "Average of the relative errors of the model output and the actual values on the test partition";
     52    protected const string TrainingNormalizedMeanSquaredErrorResultDescription = "Normalized mean of squared errors of the model on the training partition";
     53    protected const string TestNormalizedMeanSquaredErrorResultDescription = "Normalized mean of squared errors of the model on the test partition";
     54    protected const string TrainingMeanErrorResultDescription = "Mean of errors of the model on the training partition";
     55    protected const string TestMeanErrorResultDescription = "Mean of errors of the model on the test partition";
    4356
    4457    public new IRegressionModel Model {
     
    115128    protected RegressionSolutionBase(IRegressionModel model, IRegressionProblemData problemData)
    116129      : base(model, problemData) {
    117       Add(new Result(TrainingMeanSquaredErrorResultName, "Mean of squared errors of the model on the training partition", new DoubleValue()));
    118       Add(new Result(TestMeanSquaredErrorResultName, "Mean of squared errors of the model on the test partition", new DoubleValue()));
    119       Add(new Result(TrainingMeanAbsoluteErrorResultName, "Mean of absolute errors of the model on the training partition", new DoubleValue()));
    120       Add(new Result(TestMeanAbsoluteErrorResultName, "Mean of absolute errors of the model on the test partition", new DoubleValue()));
    121       Add(new Result(TrainingSquaredCorrelationResultName, "Squared Pearson's correlation coefficient of the model output and the actual values on the training partition", new DoubleValue()));
    122       Add(new Result(TestSquaredCorrelationResultName, "Squared Pearson's correlation coefficient of the model output and the actual values on the test partition", new DoubleValue()));
    123       Add(new Result(TrainingRelativeErrorResultName, "Average of the relative errors of the model output and the actual values on the training partition", new PercentValue()));
    124       Add(new Result(TestRelativeErrorResultName, "Average of the relative errors of the model output and the actual values on the test partition", new PercentValue()));
    125       Add(new Result(TrainingNormalizedMeanSquaredErrorResultName, "Normalized mean of squared errors of the model on the training partition", new DoubleValue()));
    126       Add(new Result(TestNormalizedMeanSquaredErrorResultName, "Normalized mean of squared errors of the model on the test partition", new DoubleValue()));
    127       Add(new Result(TrainingMeanErrorResultName, "Mean of errors of the model on the training partition", new DoubleValue()));
    128       Add(new Result(TestMeanErrorResultName, "Mean of errors of the model on the test partition", new DoubleValue()));
     130      Add(new Result(TrainingMeanSquaredErrorResultName, TrainingMeanSquaredErrorResultDescription, new DoubleValue()));
     131      Add(new Result(TestMeanSquaredErrorResultName, TestMeanSquaredErrorResultDescription, new DoubleValue()));
     132      Add(new Result(TrainingMeanAbsoluteErrorResultName, TrainingMeanAbsoluteErrorResultDescription, new DoubleValue()));
     133      Add(new Result(TestMeanAbsoluteErrorResultName, TestMeanAbsoluteErrorResultDescription, new DoubleValue()));
     134      Add(new Result(TrainingSquaredCorrelationResultName, TrainingSquaredCorrelationResultDescription, new DoubleValue()));
     135      Add(new Result(TestSquaredCorrelationResultName, TestSquaredCorrelationResultDescription, new DoubleValue()));
     136      Add(new Result(TrainingRelativeErrorResultName, TrainingRelativeErrorResultDescription, new PercentValue()));
     137      Add(new Result(TestRelativeErrorResultName, TestRelativeErrorResultDescription, new PercentValue()));
     138      Add(new Result(TrainingNormalizedMeanSquaredErrorResultName, TrainingNormalizedMeanSquaredErrorResultDescription, new DoubleValue()));
     139      Add(new Result(TestNormalizedMeanSquaredErrorResultName, TestNormalizedMeanSquaredErrorResultDescription, new DoubleValue()));
     140      Add(new Result(TrainingMeanErrorResultName, TrainingMeanErrorResultDescription, new DoubleValue()));
     141      Add(new Result(TestMeanErrorResultName, TestMeanErrorResultDescription, new DoubleValue()));
    129142    }
    130143
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/Models/TimeSeriesPrognosisAutoRegressiveModel.cs

    r8458 r8468  
    2222using System;
    2323using System.Collections.Generic;
    24 using System.Linq;
    2524using HeuristicLab.Common;
    2625using HeuristicLab.Core;
     
    3736    [Storable]
    3837    public string TargetVariable { get; private set; }
    39     [Storable]
    40     public int TimeOffset { get; private set; }
     38
     39    public int TimeOffset { get { return Phi.Length; } }
    4140
    4241    [StorableConstructor]
     
    4746      this.Constant = original.Constant;
    4847      this.TargetVariable = original.TargetVariable;
    49       this.TimeOffset = original.TimeOffset;
    5048    }
    5149    public override IDeepCloneable Clone(Cloner cloner) {
    5250      return new TimeSeriesPrognosisAutoRegressiveModel(this, cloner);
    5351    }
    54     public TimeSeriesPrognosisAutoRegressiveModel(double alpha, double beta, string targetVariable)
     52    public TimeSeriesPrognosisAutoRegressiveModel(string targetVariable, double[] phi, double constant)
    5553      : base() {
    56       //Alpha = alpha;
    57       //Beta = beta;
     54      Phi = (double[])phi.Clone();
     55      Constant = constant;
    5856      TargetVariable = targetVariable;
    59       TimeOffset = 1;
    6057    }
    6158
     
    6360      var rowsEnumerator = rows.GetEnumerator();
    6461      var horizonsEnumerator = horizons.GetEnumerator();
    65       var targetVariables = dataset.GetReadOnlyDoubleValues(TargetVariable);
     62      var targetValues = dataset.GetReadOnlyDoubleValues(TargetVariable);
    6663      // produce a n-step forecast for all rows
    6764      while (rowsEnumerator.MoveNext() & horizonsEnumerator.MoveNext()) {
     
    6966        int horizon = horizonsEnumerator.Current;
    7067        double[] prognosis = new double[horizon];
    71         for (int i = 0; i < horizon; i++)
    72           prognosis[i] = targetVariables[row - TimeOffset];
     68
     69        for (int h = 0; h < horizon; h++) {
     70          double estimatedValue = 0.0;
     71          for (int i = 1; i < TimeOffset; i++) {
     72            int offset = h - i;
     73            if (offset >= 0) estimatedValue += prognosis[offset] * Phi[i - 1];
     74            else estimatedValue += targetValues[row + offset] * Phi[i - 1];
     75
     76          }
     77          estimatedValue += Constant;
     78          prognosis[h] = estimatedValue;
     79        }
     80
    7381        yield return prognosis;
    7482      }
     
    7987
    8088    public IEnumerable<double> GetEstimatedValues(Dataset dataset, IEnumerable<int> rows) {
    81       return GetPrognosedValues(dataset, rows, rows.Select(r => 1)).SelectMany(e => e);
     89      var targetVariables = dataset.GetReadOnlyDoubleValues(TargetVariable);
     90      foreach (int row in rows) {
     91        double estimatedValue = 0.0;
     92        for (int i = 1; i <= TimeOffset; i++) {
     93          estimatedValue += targetVariables[row - i] * Phi[i - 1];
     94        }
     95        estimatedValue += Constant;
     96        yield return estimatedValue;
     97      }
    8298    }
    8399
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/Models/TimeSeriesPrognosisMovingAverageModel.cs

    r8458 r8468  
    8282      return GetPrognosedValues(dataset, rows, rows.Select(r => 1)).SelectMany(e => e);
    8383    }
     84    public IEnumerable<double> GetEstimatedValues(Dataset dataset, IEnumerable<int> rows, int x) {
     85      var targetValues = dataset.GetReadOnlyDoubleValues(TargetVariable).ToList();
     86      foreach (int row in rows) {
     87        yield return targetValues.GetRange(row - WindowSize, WindowSize).Average();
     88      }
     89    }
     90
    8491
    8592    public ITimeSeriesPrognosisSolution CreateTimeSeriesPrognosisSolution(ITimeSeriesPrognosisProblemData problemData) {
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionBase.cs

    r8458 r8468  
    3131  [StorableClass]
    3232  public abstract class TimeSeriesPrognosisSolutionBase : RegressionSolutionBase, ITimeSeriesPrognosisSolution {
    33     private const string TrainingDirectionalSymmetryResultName = "Average directional symmetry (training)";
    34     private const string TestDirectionalSymmetryResultName = "Average directional symmetry (test)";
    35     private const string TrainingWeightedDirectionalSymmetryResultName = "Average weighted directional symmetry (training)";
    36     private const string TestWeightedDirectionalSymmetryResultName = "Average weighted directional symmetry (test)";
    37     private const string TrainingTheilsUStatisticLastResultName = "Average Theil's U (last) (training)";
    38     private const string TestTheilsUStatisticLastResultName = "Average Theil's U (last) (test)";
    39     private const string TrainingTheilsUStatisticMeanResultName = "Average Theil's U (mean) (training)";
    40     private const string TestTheilsUStatisticMeanResultName = "Average Theil's U (mean) (test)";
    41     private const string TrainingTheilsUStatisticMaResultName = "Average Theil's U (moving average) (training)";
    42     private const string TestTheilsUStatisticMaResultName = "Average Theil's U (moving average) (test)";
     33    #region result names
     34    protected const string TrainingDirectionalSymmetryResultName = "Average directional symmetry (training)";
     35    protected const string TestDirectionalSymmetryResultName = "Average directional symmetry (test)";
     36    protected const string TrainingWeightedDirectionalSymmetryResultName = "Average weighted directional symmetry (training)";
     37    protected const string TestWeightedDirectionalSymmetryResultName = "Average weighted directional symmetry (test)";
     38    protected const string TrainingTheilsUStatisticAR1ResultName = "Theil's U2 (AR1) (training)";
     39    protected const string TestTheilsUStatisticLastResultName = "Theil's U2 (AR1) (test)";
     40    protected const string TrainingTheilsUStatisticMeanResultName = "Theil's U2 (mean) (training)";
     41    protected const string TestTheilsUStatisticMeanResultName = "Theil's U2 (mean) (test)";
     42    protected const string TrainingTheilsUStatisticMovingAverageResultName = "Theil's U2 (moving average) (training)";
     43    protected const string TestTheilsUStatisticMovingAverageResultName = "Theil's U2 (moving average) (test)";
     44
     45    protected const string PrognosisTrainingMeanSquaredErrorResultName = "Prognosis " + TrainingMeanSquaredErrorResultName;
     46    protected const string PrognosisTestMeanSquaredErrorResultName = "Prognosis " + TestMeanSquaredErrorResultName;
     47    protected const string PrognosisTrainingMeanAbsoluteErrorResultName = "Prognosis " + TrainingMeanAbsoluteErrorResultName;
     48    protected const string PrognosisTestMeanAbsoluteErrorResultName = "Prognosis " + TestMeanAbsoluteErrorResultName;
     49    protected const string PrognosisTrainingSquaredCorrelationResultName = "Prognosis " + TrainingSquaredCorrelationResultName;
     50    protected const string PrognosisTestSquaredCorrelationResultName = "Prognosis " + TestSquaredCorrelationResultName;
     51    protected const string PrognosisTrainingRelativeErrorResultName = "Prognosis " + TrainingRelativeErrorResultName;
     52    protected const string PrognosisTestRelativeErrorResultName = "Prognosis " + TestRelativeErrorResultName;
     53    protected const string PrognosisTrainingNormalizedMeanSquaredErrorResultName = "Prognosis " + TrainingNormalizedMeanSquaredErrorResultName;
     54    protected const string PrognosisTestNormalizedMeanSquaredErrorResultName = "Prognosis " + TestNormalizedMeanSquaredErrorResultName;
     55    protected const string PrognosisTrainingMeanErrorResultName = "Prognosis " + TrainingMeanErrorResultName;
     56    protected const string PrognosisTestMeanErrorResultName = "Prognosis " + TestMeanErrorResultName;
     57
     58    protected const string PrognosisTrainingDirectionalSymmetryResultName = "Prognosis " + TrainingDirectionalSymmetryResultName;
     59    protected const string PrognosisTestDirectionalSymmetryResultName = "Prognosis " + TestDirectionalSymmetryResultName;
     60    protected const string PrognosisTrainingWeightedDirectionalSymmetryResultName = "Prognosis " + TrainingWeightedDirectionalSymmetryResultName;
     61    protected const string PrognosisTestWeightedDirectionalSymmetryResultName = "Prognosis " + TestWeightedDirectionalSymmetryResultName;
     62    protected const string PrognosisTrainingTheilsUStatisticAR1ResultName = "Prognosis " + TrainingTheilsUStatisticAR1ResultName;
     63    protected const string PrognosisTestTheilsUStatisticAR1ResultName = "Prognosis " + TestTheilsUStatisticLastResultName;
     64    protected const string PrognosisTrainingTheilsUStatisticMeanResultName = "Prognosis " + TrainingTheilsUStatisticMeanResultName;
     65    protected const string PrognosisTestTheilsUStatisticMeanResultName = "Prognosis " + TestTheilsUStatisticMeanResultName;
     66    protected const string PrognosisTrainingTheilsUStatisticMovingAverageResultName = "Prognosis " + TrainingTheilsUStatisticMovingAverageResultName;
     67    protected const string PrognosisTestTheilsUStatisticMovingAverageResultName = "Prognosis " + TestTheilsUStatisticMovingAverageResultName;
     68    #endregion
     69
     70    #region result descriptions
     71    protected const string TrainingDirectionalSymmetryResultDescription = "The average directional symmetry of the forecasts of the model on the training partition";
     72    protected const string TestDirectionalSymmetryResultDescription = "The average directional symmetry of the forecasts of the model on the test partition";
     73    protected const string TrainingWeightedDirectionalSymmetryResultDescription = "The average weighted directional symmetry of the forecasts of the model on the training partition";
     74    protected const string TestWeightedDirectionalSymmetryResultDescription = "The average weighted directional symmetry of the forecasts of the model on the test partition";
     75    protected const string TrainingTheilsUStatisticAR1ResultDescription = "The Theil's U statistic (reference: AR1 model) of the forecasts of the model on the training partition";
     76    protected const string TestTheilsUStatisticAR1ResultDescription = "The Theil's U statistic (reference: AR1 model) of the forecasts of the model on the test partition";
     77    protected const string TrainingTheilsUStatisticMeanResultDescription = "The Theil's U statistic (reference: mean model) of the forecasts of the model on the training partition";
     78    protected const string TestTheilsUStatisticMeanResultDescription = "The Theil's U statistic (reference: mean value) of the forecasts of the model on the test partition";
     79    protected const string TrainingTheilsUStatisticMovingAverageResultDescription = "The Theil's U statistic (reference: moving average model) of the forecasts of the model on the training partition";
     80    protected const string TestTheilsUStatisticMovingAverageResultDescription = "The Theil's U statistic (reference: moving average model) of the forecasts of the model on the test partition";
     81
     82    protected const string PrognosisTrainingMeanSquaredErrorResultDescription = TrainingMeanSquaredErrorResultDescription;
     83    protected const string PrognosisTestMeanSquaredErrorResultDescription = TestMeanSquaredErrorResultDescription;
     84    protected const string PrognosisTrainingMeanAbsoluteErrorResultDescription = TrainingMeanAbsoluteErrorResultDescription;
     85    protected const string PrognosisTestMeanAbsoluteErrorResultDescription = TestMeanAbsoluteErrorResultDescription;
     86    protected const string PrognosisTrainingSquaredCorrelationResultDescription = TrainingSquaredCorrelationResultDescription;
     87    protected const string PrognosisTestSquaredCorrelationResultDescription = TestSquaredCorrelationResultDescription;
     88    protected const string PrognosisTrainingRelativeErrorResultDescription = TrainingRelativeErrorResultDescription;
     89    protected const string PrognosisTestRelativeErrorResultDescription = TestRelativeErrorResultDescription;
     90    protected const string PrognosisTrainingNormalizedMeanSquaredErrorResultDescription = TrainingNormalizedMeanSquaredErrorResultDescription;
     91    protected const string PrognosisTestNormalizedMeanSquaredErrorResultDescription = TestNormalizedMeanSquaredErrorResultDescription;
     92    protected const string PrognosisTrainingMeanErrorResultDescription = TrainingMeanErrorResultDescription;
     93    protected const string PrognosisTestMeanErrorResultDescription = TestMeanErrorResultDescription;
     94
     95    protected const string PrognosisTrainingDirectionalSymmetryResultDescription = TrainingDirectionalSymmetryResultDescription;
     96    protected const string PrognosisTestDirectionalSymmetryResultDescription = TestDirectionalSymmetryResultDescription;
     97    protected const string PrognosisTrainingWeightedDirectionalSymmetryResultDescription = TrainingWeightedDirectionalSymmetryResultDescription;
     98    protected const string PrognosisTestWeightedDirectionalSymmetryResultDescription = TestWeightedDirectionalSymmetryResultDescription;
     99    protected const string PrognosisTrainingTheilsUStatisticAR1ResultDescription = TrainingTheilsUStatisticAR1ResultDescription;
     100    protected const string PrognosisTestTheilsUStatisticAR1ResultDescription = TestTheilsUStatisticAR1ResultDescription;
     101    protected const string PrognosisTrainingTheilsUStatisticMeanResultDescription = TrainingTheilsUStatisticMeanResultDescription;
     102    protected const string PrognosisTestTheilsUStatisticMeanResultDescription = TestTheilsUStatisticMeanResultDescription;
     103    protected const string PrognosisTrainingTheilsUStatisticMovingAverageResultDescription = TrainingTheilsUStatisticMovingAverageResultDescription;
     104    protected const string PrognosisTestTheilsUStatisticMovingAverageResultDescription = TestTheilsUStatisticMovingAverageResultDescription;
     105    #endregion
    43106
    44107    public new ITimeSeriesPrognosisModel Model {
     
    50113      get { return (ITimeSeriesPrognosisProblemData)base.ProblemData; }
    51114      set { base.ProblemData = value; }
    52     }
    53 
    54     [Storable]
    55     private int horizon;
    56     public int Horizon {
    57       get { return horizon; }
    58       set {
    59         if (horizon != value) {
    60           horizon = value;
    61           RecalculateResults();
    62         }
    63       }
    64115    }
    65116
     
    83134      private set { ((DoubleValue)this[TestWeightedDirectionalSymmetryResultName].Value).Value = value; }
    84135    }
    85     public double TrainingTheilsUStatisticLast {
    86       get { return ((DoubleValue)this[TrainingTheilsUStatisticLastResultName].Value).Value; }
    87       private set { ((DoubleValue)this[TrainingTheilsUStatisticLastResultName].Value).Value = value; }
    88     }
    89     public double TestTheilsUStatisticLast {
     136    public double TrainingTheilsUStatisticAR1 {
     137      get { return ((DoubleValue)this[TrainingTheilsUStatisticAR1ResultName].Value).Value; }
     138      private set { ((DoubleValue)this[TrainingTheilsUStatisticAR1ResultName].Value).Value = value; }
     139    }
     140    public double TestTheilsUStatisticAR1 {
    90141      get { return ((DoubleValue)this[TestTheilsUStatisticLastResultName].Value).Value; }
    91142      private set { ((DoubleValue)this[TestTheilsUStatisticLastResultName].Value).Value = value; }
     
    100151    }
    101152    public double TrainingTheilsUStatisticMovingAverage {
    102       get { return ((DoubleValue)this[TrainingTheilsUStatisticMaResultName].Value).Value; }
    103       private set { ((DoubleValue)this[TrainingTheilsUStatisticMaResultName].Value).Value = value; }
     153      get { return ((DoubleValue)this[TrainingTheilsUStatisticMovingAverageResultName].Value).Value; }
     154      private set { ((DoubleValue)this[TrainingTheilsUStatisticMovingAverageResultName].Value).Value = value; }
    104155    }
    105156    public double TestTheilsUStatisticMovingAverage {
    106       get { return ((DoubleValue)this[TestTheilsUStatisticMaResultName].Value).Value; }
    107       private set { ((DoubleValue)this[TestTheilsUStatisticMaResultName].Value).Value = value; }
     157      get { return ((DoubleValue)this[TestTheilsUStatisticMovingAverageResultName].Value).Value; }
     158      private set { ((DoubleValue)this[TestTheilsUStatisticMovingAverageResultName].Value).Value = value; }
     159    }
     160
     161    //prognosis results for different horizons
     162    public double PrognosisTrainingMeanSquaredError {
     163      get {
     164        if (!ContainsKey(PrognosisTrainingMeanSquaredErrorResultName)) return double.NaN;
     165        return ((DoubleValue)this[PrognosisTrainingMeanSquaredErrorResultName].Value).Value;
     166      }
     167      private set {
     168        if (!ContainsKey(PrognosisTrainingMeanSquaredErrorResultName)) Add(new Result(PrognosisTrainingMeanSquaredErrorResultName, PrognosisTrainingMeanSquaredErrorResultDescription, new DoubleValue()));
     169        ((DoubleValue)this[PrognosisTrainingMeanSquaredErrorResultName].Value).Value = value;
     170      }
     171    }
     172
     173    public double PrognosisTestMeanSquaredError {
     174      get {
     175        if (!ContainsKey(PrognosisTestMeanSquaredErrorResultName)) return double.NaN;
     176        return ((DoubleValue)this[PrognosisTestMeanSquaredErrorResultName].Value).Value;
     177      }
     178      private set {
     179        if (!ContainsKey(PrognosisTestMeanSquaredErrorResultName)) Add(new Result(PrognosisTestMeanSquaredErrorResultName, PrognosisTestMeanSquaredErrorResultDescription, new DoubleValue()));
     180        ((DoubleValue)this[PrognosisTestMeanSquaredErrorResultName].Value).Value = value;
     181      }
     182    }
     183
     184    public double PrognosisTrainingMeanAbsoluteError {
     185      get {
     186        if (!ContainsKey(PrognosisTrainingMeanAbsoluteErrorResultName)) return double.NaN;
     187        return ((DoubleValue)this[PrognosisTrainingMeanAbsoluteErrorResultName].Value).Value;
     188      }
     189      private set {
     190        if (!ContainsKey(PrognosisTrainingMeanAbsoluteErrorResultName)) Add(new Result(PrognosisTrainingMeanAbsoluteErrorResultName, PrognosisTrainingMeanAbsoluteErrorResultDescription, new DoubleValue()));
     191        ((DoubleValue)this[PrognosisTrainingMeanAbsoluteErrorResultName].Value).Value = value;
     192      }
     193    }
     194
     195    public double PrognosisTestMeanAbsoluteError {
     196      get {
     197        if (!ContainsKey(PrognosisTestMeanAbsoluteErrorResultName)) return double.NaN;
     198        return ((DoubleValue)this[PrognosisTestMeanAbsoluteErrorResultName].Value).Value;
     199      }
     200      private set {
     201        if (!ContainsKey(PrognosisTestMeanAbsoluteErrorResultName)) Add(new Result(PrognosisTestMeanAbsoluteErrorResultName, PrognosisTestMeanAbsoluteErrorResultDescription, new DoubleValue()));
     202        ((DoubleValue)this[PrognosisTestMeanAbsoluteErrorResultName].Value).Value = value;
     203      }
     204    }
     205
     206    public double PrognosisTrainingRSquared {
     207      get {
     208        if (!ContainsKey(PrognosisTrainingSquaredCorrelationResultName)) return double.NaN;
     209        return ((DoubleValue)this[PrognosisTrainingSquaredCorrelationResultName].Value).Value;
     210      }
     211      private set {
     212        if (!ContainsKey(PrognosisTrainingSquaredCorrelationResultName)) Add(new Result(PrognosisTrainingSquaredCorrelationResultName, PrognosisTrainingSquaredCorrelationResultDescription, new DoubleValue()));
     213        ((DoubleValue)this[PrognosisTrainingSquaredCorrelationResultName].Value).Value = value;
     214      }
     215    }
     216
     217    public double PrognosisTestRSquared {
     218      get {
     219        if (!ContainsKey(PrognosisTestSquaredCorrelationResultName)) return double.NaN;
     220        return ((DoubleValue)this[PrognosisTestSquaredCorrelationResultName].Value).Value;
     221      }
     222      private set {
     223        if (!ContainsKey(PrognosisTestSquaredCorrelationResultName)) Add(new Result(PrognosisTestSquaredCorrelationResultName, PrognosisTestSquaredCorrelationResultDescription, new DoubleValue()));
     224        ((DoubleValue)this[PrognosisTestSquaredCorrelationResultName].Value).Value = value;
     225      }
     226    }
     227
     228    public double PrognosisTrainingRelativeError {
     229      get {
     230        if (!ContainsKey(PrognosisTrainingRelativeErrorResultName)) return double.NaN;
     231        return ((DoubleValue)this[PrognosisTrainingRelativeErrorResultName].Value).Value;
     232      }
     233      private set {
     234        if (!ContainsKey(PrognosisTrainingRelativeErrorResultName)) Add(new Result(PrognosisTrainingRelativeErrorResultName, PrognosisTrainingRelativeErrorResultDescription, new DoubleValue()));
     235        ((DoubleValue)this[PrognosisTrainingRelativeErrorResultName].Value).Value = value;
     236      }
     237    }
     238
     239    public double PrognosisTestRelativeError {
     240      get {
     241        if (!ContainsKey(PrognosisTestRelativeErrorResultName)) return double.NaN;
     242        return ((DoubleValue)this[PrognosisTestRelativeErrorResultName].Value).Value;
     243      }
     244      private set {
     245        if (!ContainsKey(PrognosisTestRelativeErrorResultName)) Add(new Result(PrognosisTestRelativeErrorResultName, PrognosisTestRelativeErrorResultDescription, new DoubleValue()));
     246        ((DoubleValue)this[PrognosisTestRelativeErrorResultName].Value).Value = value;
     247      }
     248    }
     249
     250    public double PrognosisTrainingNormalizedMeanSquaredError {
     251      get {
     252        if (!ContainsKey(PrognosisTrainingNormalizedMeanSquaredErrorResultName)) return double.NaN;
     253        return ((DoubleValue)this[PrognosisTrainingNormalizedMeanSquaredErrorResultName].Value).Value;
     254      }
     255      private set {
     256        if (!ContainsKey(PrognosisTrainingNormalizedMeanSquaredErrorResultName)) Add(new Result(PrognosisTrainingNormalizedMeanSquaredErrorResultName, PrognosisTrainingNormalizedMeanSquaredErrorResultDescription, new DoubleValue()));
     257        ((DoubleValue)this[PrognosisTrainingNormalizedMeanSquaredErrorResultName].Value).Value = value;
     258      }
     259    }
     260
     261    public double PrognosisTestNormalizedMeanSquaredError {
     262      get {
     263        if (!ContainsKey(PrognosisTestNormalizedMeanSquaredErrorResultName)) return double.NaN;
     264        return ((DoubleValue)this[PrognosisTestNormalizedMeanSquaredErrorResultName].Value).Value;
     265      }
     266      private set {
     267        if (!ContainsKey(PrognosisTestNormalizedMeanSquaredErrorResultName)) Add(new Result(PrognosisTestNormalizedMeanSquaredErrorResultName, PrognosisTestNormalizedMeanSquaredErrorResultDescription, new DoubleValue()));
     268        ((DoubleValue)this[PrognosisTestNormalizedMeanSquaredErrorResultName].Value).Value = value;
     269      }
     270    }
     271
     272    public double PrognosisTrainingMeanError {
     273      get {
     274        if (!ContainsKey(PrognosisTrainingMeanErrorResultName)) return double.NaN;
     275        return ((DoubleValue)this[PrognosisTrainingMeanErrorResultName].Value).Value;
     276      }
     277      private set {
     278        if (!ContainsKey(PrognosisTrainingMeanErrorResultName)) Add(new Result(PrognosisTrainingMeanErrorResultName, PrognosisTrainingMeanErrorResultDescription, new DoubleValue()));
     279        ((DoubleValue)this[PrognosisTrainingMeanErrorResultName].Value).Value = value;
     280      }
     281    }
     282
     283    public double PrognosisTestMeanError {
     284      get {
     285        if (!ContainsKey(PrognosisTestMeanErrorResultName)) return double.NaN;
     286        return ((DoubleValue)this[PrognosisTestMeanErrorResultName].Value).Value;
     287      }
     288      private set {
     289        if (!ContainsKey(PrognosisTestMeanErrorResultName)) Add(new Result(PrognosisTestMeanErrorResultName, PrognosisTestMeanErrorResultDescription, new DoubleValue()));
     290        ((DoubleValue)this[PrognosisTestMeanErrorResultName].Value).Value = value;
     291      }
     292    }
     293
     294
     295    public double PrognosisTrainingDirectionalSymmetry {
     296      get {
     297        if (!ContainsKey(PrognosisTrainingDirectionalSymmetryResultName)) return double.NaN;
     298        return ((DoubleValue)this[PrognosisTrainingDirectionalSymmetryResultName].Value).Value;
     299      }
     300      private set {
     301        if (!ContainsKey(PrognosisTrainingDirectionalSymmetryResultName)) Add(new Result(PrognosisTrainingDirectionalSymmetryResultName, PrognosisTrainingDirectionalSymmetryResultDescription, new DoubleValue()));
     302        ((DoubleValue)this[PrognosisTrainingDirectionalSymmetryResultName].Value).Value = value;
     303      }
     304    }
     305    public double PrognosisTestDirectionalSymmetry {
     306      get {
     307        if (!ContainsKey(PrognosisTestDirectionalSymmetryResultName)) return double.NaN;
     308        return ((DoubleValue)this[PrognosisTestDirectionalSymmetryResultName].Value).Value;
     309      }
     310      private set {
     311        if (!ContainsKey(PrognosisTestDirectionalSymmetryResultName)) Add(new Result(PrognosisTestDirectionalSymmetryResultName, PrognosisTestDirectionalSymmetryResultDescription, new DoubleValue()));
     312        ((DoubleValue)this[PrognosisTestDirectionalSymmetryResultName].Value).Value = value;
     313      }
     314    }
     315    public double PrognosisTrainingWeightedDirectionalSymmetry {
     316      get {
     317        if (!ContainsKey(PrognosisTrainingWeightedDirectionalSymmetryResultName)) return double.NaN;
     318        return ((DoubleValue)this[PrognosisTrainingWeightedDirectionalSymmetryResultName].Value).Value;
     319      }
     320      private set {
     321        if (!ContainsKey(PrognosisTrainingWeightedDirectionalSymmetryResultName)) Add(new Result(PrognosisTrainingWeightedDirectionalSymmetryResultName, PrognosisTrainingWeightedDirectionalSymmetryResultDescription, new DoubleValue()));
     322        ((DoubleValue)this[PrognosisTrainingWeightedDirectionalSymmetryResultName].Value).Value = value;
     323      }
     324    }
     325    public double PrognosisTestWeightedDirectionalSymmetry {
     326      get {
     327        if (!ContainsKey(PrognosisTestWeightedDirectionalSymmetryResultName)) return double.NaN;
     328        return ((DoubleValue)this[PrognosisTestWeightedDirectionalSymmetryResultName].Value).Value;
     329      }
     330      private set {
     331        if (!ContainsKey(PrognosisTestWeightedDirectionalSymmetryResultName)) Add(new Result(PrognosisTestWeightedDirectionalSymmetryResultName, PrognosisTestWeightedDirectionalSymmetryResultDescription, new DoubleValue()));
     332        ((DoubleValue)this[PrognosisTestWeightedDirectionalSymmetryResultName].Value).Value = value;
     333      }
     334    }
     335    public double PrognosisTrainingTheilsUStatisticAR1 {
     336      get {
     337        if (!ContainsKey(PrognosisTrainingTheilsUStatisticAR1ResultName)) return double.NaN;
     338        return ((DoubleValue)this[PrognosisTrainingTheilsUStatisticAR1ResultName].Value).Value;
     339      }
     340      private set {
     341        if (!ContainsKey(PrognosisTrainingTheilsUStatisticAR1ResultName)) Add(new Result(PrognosisTrainingTheilsUStatisticAR1ResultName, PrognosisTrainingTheilsUStatisticAR1ResultDescription, new DoubleValue()));
     342        ((DoubleValue)this[PrognosisTrainingTheilsUStatisticAR1ResultName].Value).Value = value;
     343      }
     344    }
     345    public double PrognosisTestTheilsUStatisticAR1 {
     346      get {
     347        if (!ContainsKey(PrognosisTestTheilsUStatisticAR1ResultName)) return double.NaN;
     348        return ((DoubleValue)this[PrognosisTestTheilsUStatisticAR1ResultName].Value).Value;
     349      }
     350      private set {
     351        if (!ContainsKey(PrognosisTestTheilsUStatisticAR1ResultName)) Add(new Result(PrognosisTestTheilsUStatisticAR1ResultName, PrognosisTestTheilsUStatisticAR1ResultDescription, new DoubleValue()));
     352        ((DoubleValue)this[PrognosisTestTheilsUStatisticAR1ResultName].Value).Value = value;
     353      }
     354    }
     355    public double PrognosisTrainingTheilsUStatisticMean {
     356      get {
     357        if (!ContainsKey(PrognosisTrainingTheilsUStatisticMeanResultName)) return double.NaN;
     358        return ((DoubleValue)this[PrognosisTrainingTheilsUStatisticMeanResultName].Value).Value;
     359      }
     360      private set {
     361        if (!ContainsKey(PrognosisTrainingTheilsUStatisticMeanResultName)) Add(new Result(PrognosisTrainingTheilsUStatisticMeanResultName, PrognosisTrainingTheilsUStatisticMeanResultDescription, new DoubleValue()));
     362        ((DoubleValue)this[PrognosisTrainingTheilsUStatisticMeanResultName].Value).Value = value;
     363      }
     364    }
     365    public double PrognosisTestTheilsUStatisticMean {
     366      get {
     367        if (!ContainsKey(PrognosisTestTheilsUStatisticMeanResultName)) return double.NaN;
     368        return ((DoubleValue)this[PrognosisTestTheilsUStatisticMeanResultName].Value).Value;
     369      }
     370      private set {
     371        if (!ContainsKey(PrognosisTestTheilsUStatisticMeanResultName)) Add(new Result(PrognosisTestTheilsUStatisticMeanResultName, PrognosisTestTheilsUStatisticMeanResultDescription, new DoubleValue()));
     372        ((DoubleValue)this[PrognosisTestTheilsUStatisticMeanResultName].Value).Value = value;
     373      }
     374    }
     375    public double PrognosisTrainingTheilsUStatisticMovingAverage {
     376      get {
     377        if (!ContainsKey(PrognosisTrainingTheilsUStatisticMovingAverageResultName)) return double.NaN;
     378        return ((DoubleValue)this[PrognosisTrainingTheilsUStatisticMovingAverageResultName].Value).Value;
     379      }
     380      private set {
     381        if (!ContainsKey(PrognosisTrainingTheilsUStatisticMovingAverageResultName)) Add(new Result(PrognosisTrainingTheilsUStatisticMovingAverageResultName, PrognosisTrainingTheilsUStatisticMovingAverageResultDescription, new DoubleValue()));
     382        ((DoubleValue)this[PrognosisTrainingTheilsUStatisticMovingAverageResultName].Value).Value = value;
     383      }
     384    }
     385    public double PrognosisTestTheilsUStatisticMovingAverage {
     386      get {
     387        if (!ContainsKey(PrognosisTestTheilsUStatisticMovingAverageResultName)) return double.NaN;
     388        return ((DoubleValue)this[PrognosisTestTheilsUStatisticMovingAverageResultName].Value).Value;
     389      }
     390      private set {
     391        if (!ContainsKey(PrognosisTestTheilsUStatisticMovingAverageResultName)) Add(new Result(PrognosisTestTheilsUStatisticMovingAverageResultName, PrognosisTestTheilsUStatisticMovingAverageResultDescription, new DoubleValue()));
     392        ((DoubleValue)this[PrognosisTestTheilsUStatisticMovingAverageResultName].Value).Value = value;
     393      }
    108394    }
    109395    #endregion
     
    124410    [StorableConstructor]
    125411    protected TimeSeriesPrognosisSolutionBase(bool deserializing) : base(deserializing) { }
    126     protected TimeSeriesPrognosisSolutionBase(TimeSeriesPrognosisSolutionBase original, Cloner cloner)
    127       : base(original, cloner) {
    128       this.horizon = original.horizon;
    129     }
     412    protected TimeSeriesPrognosisSolutionBase(TimeSeriesPrognosisSolutionBase original, Cloner cloner) : base(original, cloner) { }
    130413    protected TimeSeriesPrognosisSolutionBase(ITimeSeriesPrognosisModel model, ITimeSeriesPrognosisProblemData problemData)
    131414      : base(model, problemData) {
    132       Add(new Result(TrainingDirectionalSymmetryResultName, "The average directional symmetry of the forecasts of the model on the training partition", new DoubleValue()));
    133       Add(new Result(TestDirectionalSymmetryResultName, "The average directional symmetry of the forecasts of the model on the test partition", new DoubleValue()));
    134       Add(new Result(TrainingWeightedDirectionalSymmetryResultName, "The average weighted directional symmetry of the forecasts of the model on the training partition", new DoubleValue()));
    135       Add(new Result(TestWeightedDirectionalSymmetryResultName, "The average weighted directional symmetry of the forecasts of the model on the test partition", new DoubleValue()));
    136       Add(new Result(TrainingTheilsUStatisticLastResultName, "The average Theil's U statistic (reference: previous value) of the forecasts of the model on the training partition", new DoubleValue()));
    137       Add(new Result(TestTheilsUStatisticLastResultName, "The average Theil's U statistic (reference: previous value) of the forecasts of the model on the test partition", new DoubleValue()));
    138       Add(new Result(TrainingTheilsUStatisticMeanResultName, "The average Theil's U statistic (reference: mean value) of the forecasts of the model on the training partition", new DoubleValue()));
    139       Add(new Result(TestTheilsUStatisticMeanResultName, "The average Theil's U statistic (reference: mean value) of the forecasts of the model on the test partition", new DoubleValue()));
    140       Add(new Result(TrainingTheilsUStatisticMaResultName, "The average Theil's U statistic (reference: moving average) of the forecasts of the model on the training partition", new DoubleValue()));
    141       Add(new Result(TestTheilsUStatisticMaResultName, "The average Theil's U statistic (reference: moving average) of the forecasts of the model on the test partition", new DoubleValue()));
    142       horizon = 1;
     415      Add(new Result(TrainingDirectionalSymmetryResultName, TrainingDirectionalSymmetryResultDescription, new DoubleValue()));
     416      Add(new Result(TestDirectionalSymmetryResultName, TestDirectionalSymmetryResultDescription, new DoubleValue()));
     417      Add(new Result(TrainingWeightedDirectionalSymmetryResultName, TrainingWeightedDirectionalSymmetryResultDescription, new DoubleValue()));
     418      Add(new Result(TestWeightedDirectionalSymmetryResultName, TestWeightedDirectionalSymmetryResultDescription, new DoubleValue()));
     419      Add(new Result(TrainingTheilsUStatisticAR1ResultName, TrainingTheilsUStatisticAR1ResultDescription, new DoubleValue()));
     420      Add(new Result(TestTheilsUStatisticLastResultName, TestTheilsUStatisticAR1ResultDescription, new DoubleValue()));
     421      Add(new Result(TrainingTheilsUStatisticMeanResultName, TrainingTheilsUStatisticMeanResultDescription, new DoubleValue()));
     422      Add(new Result(TestTheilsUStatisticMeanResultName, TestTheilsUStatisticMeanResultDescription, new DoubleValue()));
     423      Add(new Result(TrainingTheilsUStatisticMovingAverageResultName, TrainingTheilsUStatisticMovingAverageResultDescription, new DoubleValue()));
     424      Add(new Result(TestTheilsUStatisticMovingAverageResultName, TestTheilsUStatisticMovingAverageResultDescription, new DoubleValue()));
    143425    }
    144426
     
    146428      base.RecalculateResults();
    147429      CalculateTimeSeriesResults();
     430      CalculateTimeSeriesResults(ProblemData.TrainingHorizon, ProblemData.TestHorizon);
    148431    }
    149432
    150433    private void CalculateTimeSeriesResults() {
     434      OnlineCalculatorError errorState;
     435      double trainingMean = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices).Average();
     436      var meanModel = new ConstantTimeSeriesPrognosisModel(trainingMean);
     437
     438      double alpha, beta;
     439      IEnumerable<double> trainingStartValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices.Select(r => r - 1).Where(r => r > 0)).ToList();
     440      OnlineLinearScalingParameterCalculator.Calculate(ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices.Where(x => x > 0)), trainingStartValues, out alpha, out beta, out errorState);
     441      var AR1model = new TimeSeriesPrognosisAutoRegressiveModel(ProblemData.TargetVariable, new double[] { beta }, alpha);
     442
     443      //MA model
     444      const int movingAverageWindowSize = 10;
     445      var movingAverageModel = new TimeSeriesPrognosisMovingAverageModel(movingAverageWindowSize, ProblemData.TargetVariable);
     446
     447      #region Calculate training quality measures
     448      IEnumerable<double> trainingTargetValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices).ToList();
     449      IEnumerable<double> trainingEstimatedValues = EstimatedTrainingValues.ToList();
     450      IEnumerable<double> trainingMeanModelPredictions = meanModel.GetEstimatedValues(ProblemData.Dataset, ProblemData.TrainingIndices).ToList();
     451      IEnumerable<double> trainingAR1ModelPredictions = AR1model.GetEstimatedValues(ProblemData.Dataset, ProblemData.TrainingIndices).ToList();
     452      IEnumerable<double> trainingMovingAverageModelPredictions = movingAverageModel.GetEstimatedValues(ProblemData.Dataset, ProblemData.TrainingIndices).ToList();
     453
     454      TrainingDirectionalSymmetry = OnlineDirectionalSymmetryCalculator.Calculate(trainingTargetValues.First(), trainingTargetValues, trainingEstimatedValues, out errorState);
     455      TrainingDirectionalSymmetry = errorState == OnlineCalculatorError.None ? TrainingDirectionalSymmetry : 0.0;
     456      TrainingWeightedDirectionalSymmetry = OnlineWeightedDirectionalSymmetryCalculator.Calculate(trainingTargetValues.First(), trainingTargetValues, trainingEstimatedValues, out errorState);
     457      TrainingWeightedDirectionalSymmetry = errorState == OnlineCalculatorError.None ? TrainingWeightedDirectionalSymmetry : 0.0;
     458      TrainingTheilsUStatisticAR1 = OnlineTheilsUStatisticCalculator.Calculate(trainingTargetValues.First(), trainingTargetValues, trainingAR1ModelPredictions, trainingEstimatedValues, out errorState);
     459      TrainingTheilsUStatisticAR1 = errorState == OnlineCalculatorError.None ? TrainingTheilsUStatisticAR1 : double.PositiveInfinity;
     460      TrainingTheilsUStatisticMean = OnlineTheilsUStatisticCalculator.Calculate(trainingTargetValues.First(), trainingTargetValues, trainingMeanModelPredictions, trainingEstimatedValues, out errorState);
     461      TrainingTheilsUStatisticMean = errorState == OnlineCalculatorError.None ? TrainingTheilsUStatisticMean : double.PositiveInfinity;
     462      TrainingTheilsUStatisticMovingAverage = OnlineTheilsUStatisticCalculator.Calculate(trainingTargetValues.First(), trainingTargetValues, trainingMovingAverageModelPredictions, trainingEstimatedValues, out errorState);
     463      TrainingTheilsUStatisticMovingAverage = errorState == OnlineCalculatorError.None ? TrainingTheilsUStatisticMovingAverage : double.PositiveInfinity;
     464      #endregion
     465
     466      #region Calculate test quality measures
     467      IEnumerable<double> testTargetValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TestIndices).ToList();
     468      IEnumerable<double> testEstimatedValues = EstimatedTestValues.ToList();
     469      IEnumerable<double> testMeanModelPredictions = meanModel.GetEstimatedValues(ProblemData.Dataset, ProblemData.TestIndices).ToList();
     470      IEnumerable<double> testAR1ModelPredictions = AR1model.GetEstimatedValues(ProblemData.Dataset, ProblemData.TestIndices).ToList();
     471      IEnumerable<double> testMovingAverageModelPredictions = movingAverageModel.GetEstimatedValues(ProblemData.Dataset, ProblemData.TestIndices).ToList();
     472
     473      TestDirectionalSymmetry = OnlineDirectionalSymmetryCalculator.Calculate(testTargetValues.First(), testTargetValues, testEstimatedValues, out errorState);
     474      TestDirectionalSymmetry = errorState == OnlineCalculatorError.None ? TestDirectionalSymmetry : 0.0;
     475      TestWeightedDirectionalSymmetry = OnlineWeightedDirectionalSymmetryCalculator.Calculate(testTargetValues.First(), testTargetValues, testEstimatedValues, out errorState);
     476      TestWeightedDirectionalSymmetry = errorState == OnlineCalculatorError.None ? TestWeightedDirectionalSymmetry : 0.0;
     477      TestTheilsUStatisticAR1 = OnlineTheilsUStatisticCalculator.Calculate(testTargetValues.First(), testTargetValues, testAR1ModelPredictions, testEstimatedValues, out errorState);
     478      TestTheilsUStatisticAR1 = errorState == OnlineCalculatorError.None ? TestTheilsUStatisticAR1 : double.PositiveInfinity;
     479      TestTheilsUStatisticMean = OnlineTheilsUStatisticCalculator.Calculate(testTargetValues.First(), testTargetValues, testMeanModelPredictions, testEstimatedValues, out errorState);
     480      TestTheilsUStatisticMean = errorState == OnlineCalculatorError.None ? TestTheilsUStatisticMean : double.PositiveInfinity;
     481      TestTheilsUStatisticMovingAverage = OnlineTheilsUStatisticCalculator.Calculate(testTargetValues.First(), testTargetValues, testMovingAverageModelPredictions, testEstimatedValues, out errorState);
     482      TestTheilsUStatisticMovingAverage = errorState == OnlineCalculatorError.None ? TestTheilsUStatisticMovingAverage : double.PositiveInfinity;
     483      #endregion
     484    }
     485
     486    private void CalculateTimeSeriesResults(int trainingHorizon, int testHorizon) {
    151487      OnlineCalculatorError errorState;
    152488      //mean model
     
    158494      IEnumerable<double> trainingStartValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices.Select(r => r - 1).Where(r => r > 0)).ToList();
    159495      OnlineLinearScalingParameterCalculator.Calculate(ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices.Where(x => x > 0)), trainingStartValues, out alpha, out beta, out errorState);
    160       var AR1model = new TimeSeriesPrognosisAutoRegressiveModel(alpha, beta, ProblemData.TargetVariable);
     496      var AR1model = new TimeSeriesPrognosisAutoRegressiveModel(ProblemData.TargetVariable, new double[] { beta }, alpha);
    161497
    162498      //MA model
    163       int movingAverageWindowSize = 10 + horizon;
     499      const int movingAverageWindowSize = 10;
    164500      var MovingAverageModel = new TimeSeriesPrognosisMovingAverageModel(movingAverageWindowSize, ProblemData.TargetVariable);
    165501
    166502      #region Calculate training quality measures
    167       var trainingHorizions = ProblemData.TrainingIndices.Select(r => Math.Min(horizon, ProblemData.TrainingPartition.End - r)).ToList();
    168       IEnumerable<IEnumerable<double>> trainingTargetValues = ProblemData.TrainingIndices.Zip(trainingHorizions, Enumerable.Range).Select(r => ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, r)).ToList();
    169       IEnumerable<IEnumerable<double>> trainingEstimatedValues = Model.GetPrognosedValues(ProblemData.Dataset, ProblemData.TrainingIndices, trainingHorizions).ToList();
    170       IEnumerable<IEnumerable<double>> trainingMeanModelPredictions = meanModel.GetPrognosedValues(ProblemData.Dataset, ProblemData.TrainingIndices, trainingHorizions);
    171       IEnumerable<IEnumerable<double>> trainingAR1ModelPredictions = AR1model.GetPrognosedValues(ProblemData.Dataset, ProblemData.TrainingIndices, trainingHorizions);
    172       IEnumerable<IEnumerable<double>> trainingMovingAverageModelPredictions = MovingAverageModel.GetPrognosedValues(ProblemData.Dataset, ProblemData.TrainingIndices, trainingHorizions);
    173 
    174       TrainingDirectionalSymmetry = OnlineDirectionalSymmetryCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingEstimatedValues, out errorState);
    175       TrainingDirectionalSymmetry = errorState == OnlineCalculatorError.None ? TrainingDirectionalSymmetry : 0.0;
    176       TrainingWeightedDirectionalSymmetry = OnlineWeightedDirectionalSymmetryCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingEstimatedValues, out errorState);
    177       TrainingWeightedDirectionalSymmetry = errorState == OnlineCalculatorError.None ? TrainingWeightedDirectionalSymmetry : 0.0;
    178       TrainingTheilsUStatisticLast = OnlineTheilsUStatisticCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingAR1ModelPredictions, trainingEstimatedValues, out errorState);
    179       TrainingTheilsUStatisticLast = errorState == OnlineCalculatorError.None ? TrainingTheilsUStatisticLast : double.PositiveInfinity; ;
    180       TrainingTheilsUStatisticMean = OnlineTheilsUStatisticCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingMeanModelPredictions, trainingEstimatedValues, out errorState);
    181       TrainingTheilsUStatisticMean = errorState == OnlineCalculatorError.None ? TrainingTheilsUStatisticMean : double.PositiveInfinity; ;
    182       TrainingTheilsUStatisticMovingAverage = OnlineTheilsUStatisticCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingMovingAverageModelPredictions, trainingEstimatedValues, out errorState);
    183       TrainingTheilsUStatisticMovingAverage = errorState == OnlineCalculatorError.None ? TrainingTheilsUStatisticMovingAverage : double.PositiveInfinity; ; ;
     503      if (trainingHorizon != 1) {
     504        var trainingHorizions = ProblemData.TrainingIndices.Select(r => Math.Min(trainingHorizon, ProblemData.TrainingPartition.End - r)).ToList();
     505        IEnumerable<IEnumerable<double>> trainingTargetValues = ProblemData.TrainingIndices.Zip(trainingHorizions, Enumerable.Range).Select(r => ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, r)).ToList();
     506        IEnumerable<IEnumerable<double>> trainingEstimatedValues = Model.GetPrognosedValues(ProblemData.Dataset, ProblemData.TrainingIndices, trainingHorizions).ToList();
     507        IEnumerable<IEnumerable<double>> trainingMeanModelPredictions = meanModel.GetPrognosedValues(ProblemData.Dataset, ProblemData.TrainingIndices, trainingHorizions).ToList();
     508        IEnumerable<IEnumerable<double>> trainingAR1ModelPredictions = AR1model.GetPrognosedValues(ProblemData.Dataset, ProblemData.TrainingIndices, trainingHorizions).ToList();
     509        IEnumerable<IEnumerable<double>> trainingMovingAverageModelPredictions = MovingAverageModel.GetPrognosedValues(ProblemData.Dataset, ProblemData.TrainingIndices, trainingHorizions).ToList();
     510
     511        IEnumerable<double> originalTrainingValues = trainingTargetValues.SelectMany(x => x).ToList();
     512        IEnumerable<double> estimatedTrainingValues = trainingEstimatedValues.SelectMany(x => x).ToList();
     513
     514        double trainingMSE = OnlineMeanSquaredErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
     515        PrognosisTrainingMeanSquaredError = errorState == OnlineCalculatorError.None ? trainingMSE : double.NaN;
     516        double trainingMAE = OnlineMeanAbsoluteErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
     517        PrognosisTrainingMeanAbsoluteError = errorState == OnlineCalculatorError.None ? trainingMAE : double.NaN;
     518        double trainingR2 = OnlinePearsonsRSquaredCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
     519        PrognosisTrainingRSquared = errorState == OnlineCalculatorError.None ? trainingR2 : double.NaN;
     520        double trainingRelError = OnlineMeanAbsolutePercentageErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
     521        PrognosisTrainingRelativeError = errorState == OnlineCalculatorError.None ? trainingRelError : double.NaN;
     522        double trainingNMSE = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
     523        PrognosisTrainingNormalizedMeanSquaredError = errorState == OnlineCalculatorError.None ? trainingNMSE : double.NaN;
     524        double trainingME = OnlineMeanErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
     525        PrognosisTrainingMeanError = errorState == OnlineCalculatorError.None ? trainingME : double.NaN;
     526
     527        PrognosisTrainingDirectionalSymmetry = OnlineDirectionalSymmetryCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingEstimatedValues, out errorState);
     528        PrognosisTrainingDirectionalSymmetry = errorState == OnlineCalculatorError.None ? PrognosisTrainingDirectionalSymmetry : 0.0;
     529        PrognosisTrainingWeightedDirectionalSymmetry = OnlineWeightedDirectionalSymmetryCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingEstimatedValues, out errorState);
     530        PrognosisTrainingWeightedDirectionalSymmetry = errorState == OnlineCalculatorError.None ? PrognosisTrainingWeightedDirectionalSymmetry : 0.0;
     531        PrognosisTrainingTheilsUStatisticAR1 = OnlineTheilsUStatisticCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingAR1ModelPredictions, trainingEstimatedValues, out errorState);
     532        PrognosisTrainingTheilsUStatisticAR1 = errorState == OnlineCalculatorError.None ? PrognosisTrainingTheilsUStatisticAR1 : double.PositiveInfinity;
     533        PrognosisTrainingTheilsUStatisticMean = OnlineTheilsUStatisticCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingMeanModelPredictions, trainingEstimatedValues, out errorState);
     534        PrognosisTrainingTheilsUStatisticMean = errorState == OnlineCalculatorError.None ? PrognosisTrainingTheilsUStatisticMean : double.PositiveInfinity;
     535        PrognosisTrainingTheilsUStatisticMovingAverage = OnlineTheilsUStatisticCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingMovingAverageModelPredictions, trainingEstimatedValues, out errorState);
     536        PrognosisTrainingTheilsUStatisticMovingAverage = errorState == OnlineCalculatorError.None ? PrognosisTrainingTheilsUStatisticMovingAverage : double.PositiveInfinity;
     537      }
     538
    184539      #endregion
    185540
    186541      #region  Calculate test quality measures
    187       var testHorizions = ProblemData.TestIndices.Select(r => Math.Min(horizon, ProblemData.TestPartition.End - r)).ToList();
    188       IEnumerable<IEnumerable<double>> testTargetValues = ProblemData.TestIndices.Zip(testHorizions, Enumerable.Range).Select(r => ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, r)).ToList();
    189       IEnumerable<IEnumerable<double>> testEstimatedValues = Model.GetPrognosedValues(ProblemData.Dataset, ProblemData.TestIndices, testHorizions).ToList();
    190       IEnumerable<double> testStartValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TestIndices.Select(r => r - 1).Where(r => r > 0)).ToList();
    191       IEnumerable<IEnumerable<double>> testMeanModelPredictions = meanModel.GetPrognosedValues(ProblemData.Dataset, ProblemData.TestIndices, testHorizions);
    192       IEnumerable<IEnumerable<double>> testAR1ModelPredictions = AR1model.GetPrognosedValues(ProblemData.Dataset, ProblemData.TestIndices, testHorizions);
    193       IEnumerable<IEnumerable<double>> testMovingAverageModelPredictions = MovingAverageModel.GetPrognosedValues(ProblemData.Dataset, ProblemData.TestIndices, testHorizions);
    194 
    195       TestDirectionalSymmetry = OnlineDirectionalSymmetryCalculator.Calculate(testStartValues, testTargetValues, testEstimatedValues, out errorState);
    196       TestDirectionalSymmetry = errorState == OnlineCalculatorError.None ? TestDirectionalSymmetry : 0.0;
    197       TestWeightedDirectionalSymmetry = OnlineWeightedDirectionalSymmetryCalculator.Calculate(testStartValues, testTargetValues, testEstimatedValues, out errorState);
    198       TestWeightedDirectionalSymmetry = errorState == OnlineCalculatorError.None ? TestWeightedDirectionalSymmetry : 0.0;
    199       TestTheilsUStatisticLast = OnlineTheilsUStatisticCalculator.Calculate(testStartValues, testTargetValues, testAR1ModelPredictions, testEstimatedValues, out errorState);
    200       TestTheilsUStatisticLast = errorState == OnlineCalculatorError.None ? TestTheilsUStatisticLast : double.PositiveInfinity; ;
    201       TestTheilsUStatisticMean = OnlineTheilsUStatisticCalculator.Calculate(testStartValues, testTargetValues, testMeanModelPredictions, testEstimatedValues, out errorState);
    202       TestTheilsUStatisticMean = errorState == OnlineCalculatorError.None ? TestTheilsUStatisticMean : double.PositiveInfinity; ;
    203       TestTheilsUStatisticMovingAverage = OnlineTheilsUStatisticCalculator.Calculate(testStartValues, testTargetValues, testMovingAverageModelPredictions, testEstimatedValues, out errorState);
    204       TestTheilsUStatisticMovingAverage = errorState == OnlineCalculatorError.None ? TestTheilsUStatisticMovingAverage : double.PositiveInfinity; ; ;
     542      if (testHorizon != 1) {
     543        var testHorizions = ProblemData.TestIndices.Select(r => Math.Min(testHorizon, ProblemData.TestPartition.End - r)).ToList();
     544        IEnumerable<IEnumerable<double>> testTargetValues = ProblemData.TestIndices.Zip(testHorizions, Enumerable.Range).Select(r => ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, r)).ToList();
     545        IEnumerable<IEnumerable<double>> testEstimatedValues = Model.GetPrognosedValues(ProblemData.Dataset, ProblemData.TestIndices, testHorizions).ToList();
     546        IEnumerable<double> testStartValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TestIndices.Select(r => r - 1).Where(r => r > 0)).ToList();
     547        IEnumerable<IEnumerable<double>> testMeanModelPredictions = meanModel.GetPrognosedValues(ProblemData.Dataset, ProblemData.TestIndices, testHorizions).ToList();
     548        IEnumerable<IEnumerable<double>> testAR1ModelPredictions = AR1model.GetPrognosedValues(ProblemData.Dataset, ProblemData.TestIndices, testHorizions).ToList();
     549        IEnumerable<IEnumerable<double>> testMovingAverageModelPredictions = MovingAverageModel.GetPrognosedValues(ProblemData.Dataset, ProblemData.TestIndices, testHorizions).ToList();
     550
     551        IEnumerable<double> originalTestValues = testTargetValues.SelectMany(x => x).ToList();
     552        IEnumerable<double> estimatedTestValues = testEstimatedValues.SelectMany(x => x).ToList();
     553
     554        double testMSE = OnlineMeanSquaredErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
     555        PrognosisTestMeanSquaredError = errorState == OnlineCalculatorError.None ? testMSE : double.NaN;
     556        double testMAE = OnlineMeanAbsoluteErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
     557        PrognosisTestMeanAbsoluteError = errorState == OnlineCalculatorError.None ? testMAE : double.NaN;
     558        double testR2 = OnlinePearsonsRSquaredCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
     559        PrognosisTestRSquared = errorState == OnlineCalculatorError.None ? testR2 : double.NaN;
     560        double testRelError = OnlineMeanAbsolutePercentageErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
     561        PrognosisTestRelativeError = errorState == OnlineCalculatorError.None ? testRelError : double.NaN;
     562        double testNMSE = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
     563        PrognosisTestNormalizedMeanSquaredError = errorState == OnlineCalculatorError.None ? testNMSE : double.NaN;
     564        double testME = OnlineMeanErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
     565        PrognosisTestMeanError = errorState == OnlineCalculatorError.None ? testME : double.NaN;
     566
     567        PrognosisTestDirectionalSymmetry = OnlineDirectionalSymmetryCalculator.Calculate(testStartValues, testTargetValues, testEstimatedValues, out errorState);
     568        PrognosisTestDirectionalSymmetry = errorState == OnlineCalculatorError.None ? PrognosisTestDirectionalSymmetry : 0.0;
     569        PrognosisTestWeightedDirectionalSymmetry = OnlineWeightedDirectionalSymmetryCalculator.Calculate(testStartValues, testTargetValues, testEstimatedValues, out errorState);
     570        PrognosisTestWeightedDirectionalSymmetry = errorState == OnlineCalculatorError.None ? PrognosisTestWeightedDirectionalSymmetry : 0.0;
     571        PrognosisTestTheilsUStatisticAR1 = OnlineTheilsUStatisticCalculator.Calculate(testStartValues, testTargetValues, testAR1ModelPredictions, testEstimatedValues, out errorState);
     572        PrognosisTestTheilsUStatisticAR1 = errorState == OnlineCalculatorError.None ? PrognosisTestTheilsUStatisticAR1 : double.PositiveInfinity;
     573        PrognosisTestTheilsUStatisticMean = OnlineTheilsUStatisticCalculator.Calculate(testStartValues, testTargetValues, testMeanModelPredictions, testEstimatedValues, out errorState);
     574        PrognosisTestTheilsUStatisticMean = errorState == OnlineCalculatorError.None ? PrognosisTestTheilsUStatisticMean : double.PositiveInfinity;
     575        PrognosisTestTheilsUStatisticMovingAverage = OnlineTheilsUStatisticCalculator.Calculate(testStartValues, testTargetValues, testMovingAverageModelPredictions, testEstimatedValues, out errorState);
     576        PrognosisTestTheilsUStatisticMovingAverage = errorState == OnlineCalculatorError.None ? PrognosisTestTheilsUStatisticMovingAverage : double.PositiveInfinity;
     577      }
     578
    205579      #endregion
    206580    }
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisSolution.cs

    r8458 r8468  
    2323namespace HeuristicLab.Problems.DataAnalysis {
    2424  public interface ITimeSeriesPrognosisSolution : IRegressionSolution {
    25     int Horizon { get; set; }
    2625    new ITimeSeriesPrognosisModel Model { get; }
    2726    new ITimeSeriesPrognosisProblemData ProblemData { get; set; }
     
    2928    IEnumerable<IEnumerable<double>> GetPrognosedValues(IEnumerable<int> rows, IEnumerable<int> horizon);
    3029
    31     double TrainingTheilsUStatisticLast { get; }
    32     double TestTheilsUStatisticLast { get; }
     30    double TrainingTheilsUStatisticAR1 { get; }
     31    double TestTheilsUStatisticAR1 { get; }
    3332    double TrainingTheilsUStatisticMean { get; }
    3433    double TestTheilsUStatisticMean { get; }
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineDirectionalSymmetryCalculator.cs

    r7099 r8468  
    8888    }
    8989
    90 
     90    public static double Calculate(double startValue, IEnumerable<double> actualContinuation, IEnumerable<double> predictedContinuation, out OnlineCalculatorError errorState) {
     91      OnlineDirectionalSymmetryCalculator dsCalculator = new OnlineDirectionalSymmetryCalculator();
     92      dsCalculator.Add(startValue, actualContinuation, predictedContinuation);
     93      errorState = dsCalculator.ErrorState;
     94      return dsCalculator.DirectionalSymmetry;
     95    }
     96   
    9197    public static double Calculate(IEnumerable<double> startValues, IEnumerable<IEnumerable<double>> actualContinuations, IEnumerable<IEnumerable<double>> predictedContinuations, out OnlineCalculatorError errorState) {
    9298      IEnumerator<double> startValueEnumerator = startValues.GetEnumerator();
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineTheilsUStatisticCalculator.cs

    r8430 r8468  
    2222using System;
    2323using System.Collections.Generic;
    24 using System.Linq;
    2524
    2625namespace HeuristicLab.Problems.DataAnalysis {
     
    5251
    5352    public void Add(double startValue, IEnumerable<double> actualContinuation, IEnumerable<double> predictedContinuation) {
    54       Add(startValue, actualContinuation.Select(x => startValue), actualContinuation, predictedContinuation);
     53      throw new NotSupportedException();
    5554    }
    5655
     
    9695    #endregion
    9796
     97    public static double Calculate(double startValue, IEnumerable<double> actualContinuation, IEnumerable<double> referenceContinuation, IEnumerable<double> predictedContinuation, out OnlineCalculatorError errorState) {
     98      OnlineTheilsUStatisticCalculator calculator = new OnlineTheilsUStatisticCalculator();
     99      calculator.Add(startValue, actualContinuation, referenceContinuation, predictedContinuation);
     100      errorState = calculator.ErrorState;
     101      return calculator.TheilsUStatistic;
     102    }
     103
    98104    public static double Calculate(IEnumerable<double> startValues, IEnumerable<IEnumerable<double>> actualContinuations, IEnumerable<IEnumerable<double>> referenceContinuations, IEnumerable<IEnumerable<double>> predictedContinuations, out OnlineCalculatorError errorState) {
    99105      IEnumerator<double> startValueEnumerator = startValues.GetEnumerator();
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineWeightedDirectionalSymmetryCalculator.cs

    r7463 r8468  
    9090    }
    9191
     92    public static double Calculate(double startValue, IEnumerable<double> actualContinuation, IEnumerable<double> predictedContinuation, out OnlineCalculatorError errorState) {
     93      OnlineWeightedDirectionalSymmetryCalculator calculator = new OnlineWeightedDirectionalSymmetryCalculator();
     94      calculator.Add(startValue, actualContinuation, predictedContinuation);
     95      errorState = calculator.ErrorState;
     96      return calculator.WeightedDirectionalSymmetry;
     97    }
    9298
    9399    public static double Calculate(IEnumerable<double> startValues, IEnumerable<IEnumerable<double>> actualContinuations, IEnumerable<IEnumerable<double>> predictedContinuations, out OnlineCalculatorError errorState) {
Note: See TracChangeset for help on using the changeset viewer.