Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Dataset.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Dataset.cs	(revision 8010)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Dataset.cs	(revision 8430)
@@ -131,6 +131,6 @@
         for (int col = 0; col < storableData.GetLength(1); col++) {
           string columName = variableNames[col];
-          var values = new List<double>();
-          for (int row = 0; row < storableData.GetLength(0); row++) {
+          var values = new List<double>(rows);
+          for (int row = 0; row < rows; row++) {
             values.Add(storableData[row, col]);
           }
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj	(revision 8010)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj	(revision 8430)
@@ -93,4 +93,6 @@
   </PropertyGroup>
   <ItemGroup>
+    <Reference Include="ALGLIB-3.5.0, Version=3.5.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.ALGLIB-3.5.0, Version=3.5.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
     <Reference Include="HeuristicLab.Collections-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
     <Reference Include="HeuristicLab.Common-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
@@ -140,5 +142,5 @@
     </Compile>
     <Compile Include="Implementation\Regression\RegressionEnsembleSolution.cs" />
-    <Compile Include="Implementation\TimeSeriesPrognosis\Models\TimeSeriesPrognosisConstantModel.cs" />
+    <Compile Include="Implementation\TimeSeriesPrognosis\Models\ConstantTimeSeriesPrognosisModel.cs" />
     <Compile Include="Implementation\TimeSeriesPrognosis\Models\TimeSeriesPrognosisMovingAverageModel.cs" />
     <Compile Include="Implementation\TimeSeriesPrognosis\Models\TimeSeriesPrognosisAutoRegressiveModel.cs" />
@@ -159,4 +161,6 @@
     <Compile Include="Interfaces\Regression\IRegressionEnsembleSolution.cs" />
     <Compile Include="Implementation\Regression\RegressionSolutionBase.cs" />
+    <Compile Include="OnlineCalculators\AutoCorrelationCalculator.cs" />
+    <Compile Include="OnlineCalculators\HoeffdingsDependenceCalculator.cs" />
     <Compile Include="OnlineCalculators\OnlineMaxAbsoluteErrorCalculator.cs" />
     <Compile Include="OnlineCalculators\OnlineMeanErrorCalculator.cs" />
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleSolution.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleSolution.cs	(revision 8010)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleSolution.cs	(revision 8430)
@@ -37,4 +37,7 @@
   [Creatable("Data Analysis - Ensembles")]
   public sealed class ClassificationEnsembleSolution : ClassificationSolution, IClassificationEnsembleSolution {
+    private readonly Dictionary<int, double> trainingEvaluationCache = new Dictionary<int, double>();
+    private readonly Dictionary<int, double> testEvaluationCache = new Dictionary<int, double>();
+
     public new IClassificationEnsembleModel Model {
       get { return (IClassificationEnsembleModel)base.Model; }
@@ -85,4 +88,7 @@
       }
 
+      trainingEvaluationCache = new Dictionary<int, double>(original.ProblemData.TrainingIndices.Count());
+      testEvaluationCache = new Dictionary<int, double>(original.ProblemData.TestIndices.Count());
+
       classificationSolutions = cloner.Clone(original.classificationSolutions);
       RegisterClassificationSolutionsEventHandler();
@@ -128,4 +134,7 @@
       }
 
+      trainingEvaluationCache = new Dictionary<int, double>(problemData.TrainingIndices.Count());
+      testEvaluationCache = new Dictionary<int, double>(problemData.TestIndices.Count());
+
       RegisterClassificationSolutionsEventHandler();
       classificationSolutions.AddRange(solutions);
@@ -148,18 +157,14 @@
     public override IEnumerable<double> EstimatedTrainingClassValues {
       get {
-        var rows = ProblemData.TrainingIndizes;
-        var estimatedValuesEnumerators = (from model in Model.Models
-                                          select new { Model = model, EstimatedValuesEnumerator = model.GetEstimatedClassValues(ProblemData.Dataset, rows).GetEnumerator() })
-                                         .ToList();
-        var rowsEnumerator = rows.GetEnumerator();
-        // aggregate to make sure that MoveNext is called for all enumerators 
-        while (rowsEnumerator.MoveNext() & estimatedValuesEnumerators.Select(en => en.EstimatedValuesEnumerator.MoveNext()).Aggregate(true, (acc, b) => acc & b)) {
-          int currentRow = rowsEnumerator.Current;
-
-          var selectedEnumerators = from pair in estimatedValuesEnumerators
-                                    where RowIsTrainingForModel(currentRow, pair.Model) && !RowIsTestForModel(currentRow, pair.Model)
-                                    select pair.EstimatedValuesEnumerator;
-          yield return AggregateEstimatedClassValues(selectedEnumerators.Select(x => x.Current));
+        var rows = ProblemData.TrainingIndices;
+        var rowsToEvaluate = rows.Except(trainingEvaluationCache.Keys);
+        var rowsEnumerator = rowsToEvaluate.GetEnumerator();
+        var valuesEnumerator = GetEstimatedValues(rowsToEvaluate, (r, m) => RowIsTrainingForModel(r, m) && !RowIsTestForModel(r, m)).GetEnumerator();
+
+        while (rowsEnumerator.MoveNext() & valuesEnumerator.MoveNext()) {
+          trainingEvaluationCache.Add(rowsEnumerator.Current, valuesEnumerator.Current);
         }
+
+        return rows.Select(row => trainingEvaluationCache[row]);
       }
     }
@@ -167,19 +172,31 @@
     public override IEnumerable<double> EstimatedTestClassValues {
       get {
-        var rows = ProblemData.TestIndizes;
-        var estimatedValuesEnumerators = (from model in Model.Models
-                                          select new { Model = model, EstimatedValuesEnumerator = model.GetEstimatedClassValues(ProblemData.Dataset, rows).GetEnumerator() })
-                                         .ToList();
-        var rowsEnumerator = ProblemData.TestIndizes.GetEnumerator();
-        // aggregate to make sure that MoveNext is called for all enumerators 
-        while (rowsEnumerator.MoveNext() & estimatedValuesEnumerators.Select(en => en.EstimatedValuesEnumerator.MoveNext()).Aggregate(true, (acc, b) => acc & b)) {
-          int currentRow = rowsEnumerator.Current;
-
-          var selectedEnumerators = from pair in estimatedValuesEnumerators
-                                    where RowIsTestForModel(currentRow, pair.Model)
-                                    select pair.EstimatedValuesEnumerator;
-
-          yield return AggregateEstimatedClassValues(selectedEnumerators.Select(x => x.Current));
+        var rows = ProblemData.TestIndices;
+        var rowsToEvaluate = rows.Except(testEvaluationCache.Keys);
+        var rowsEnumerator = rowsToEvaluate.GetEnumerator();
+        var valuesEnumerator = GetEstimatedValues(rowsToEvaluate, RowIsTestForModel).GetEnumerator();
+
+        while (rowsEnumerator.MoveNext() & valuesEnumerator.MoveNext()) {
+          testEvaluationCache.Add(rowsEnumerator.Current, valuesEnumerator.Current);
         }
+
+        return rows.Select(row => testEvaluationCache[row]);
+      }
+    }
+
+    private IEnumerable<double> GetEstimatedValues(IEnumerable<int> rows, Func<int, IClassificationModel, bool> modelSelectionPredicate) {
+      var estimatedValuesEnumerators = (from model in Model.Models
+                                        select new { Model = model, EstimatedValuesEnumerator = model.GetEstimatedClassValues(ProblemData.Dataset, rows).GetEnumerator() })
+                                       .ToList();
+      var rowsEnumerator = rows.GetEnumerator();
+      // aggregate to make sure that MoveNext is called for all enumerators 
+      while (rowsEnumerator.MoveNext() & estimatedValuesEnumerators.Select(en => en.EstimatedValuesEnumerator.MoveNext()).Aggregate(true, (acc, b) => acc & b)) {
+        int currentRow = rowsEnumerator.Current;
+
+        var selectedEnumerators = from pair in estimatedValuesEnumerators
+                                  where modelSelectionPredicate(currentRow, pair.Model)
+                                  select pair.EstimatedValuesEnumerator;
+
+        yield return AggregateEstimatedClassValues(selectedEnumerators.Select(x => x.Current));
       }
     }
@@ -196,6 +213,15 @@
 
     public override IEnumerable<double> GetEstimatedClassValues(IEnumerable<int> rows) {
-      return from xs in GetEstimatedClassValueVectors(ProblemData.Dataset, rows)
-             select AggregateEstimatedClassValues(xs);
+      var rowsToEvaluate = rows.Except(evaluationCache.Keys);
+      var rowsEnumerator = rowsToEvaluate.GetEnumerator();
+      var valuesEnumerator = (from xs in GetEstimatedClassValueVectors(ProblemData.Dataset, rowsToEvaluate)
+                              select AggregateEstimatedClassValues(xs))
+                             .GetEnumerator();
+
+      while (rowsEnumerator.MoveNext() & valuesEnumerator.MoveNext()) {
+        evaluationCache.Add(rowsEnumerator.Current, valuesEnumerator.Current);
+      }
+
+      return rows.Select(row => evaluationCache[row]);
     }
 
@@ -223,4 +249,8 @@
 
     protected override void OnProblemDataChanged() {
+      trainingEvaluationCache.Clear();
+      testEvaluationCache.Clear();
+      evaluationCache.Clear();
+
       IClassificationProblemData problemData = new ClassificationProblemData(ProblemData.Dataset,
                                                                      ProblemData.AllowedInputVariables,
@@ -251,7 +281,15 @@
     public void AddClassificationSolutions(IEnumerable<IClassificationSolution> solutions) {
       classificationSolutions.AddRange(solutions);
+
+      trainingEvaluationCache.Clear();
+      testEvaluationCache.Clear();
+      evaluationCache.Clear();
     }
     public void RemoveClassificationSolutions(IEnumerable<IClassificationSolution> solutions) {
       classificationSolutions.RemoveRange(solutions);
+
+      trainingEvaluationCache.Clear();
+      testEvaluationCache.Clear();
+      evaluationCache.Clear();
     }
 
@@ -275,4 +313,8 @@
       trainingPartitions[solution.Model] = solution.ProblemData.TrainingPartition;
       testPartitions[solution.Model] = solution.ProblemData.TestPartition;
+
+      trainingEvaluationCache.Clear();
+      testEvaluationCache.Clear();
+      evaluationCache.Clear();
     }
 
@@ -282,4 +324,8 @@
       trainingPartitions.Remove(solution.Model);
       testPartitions.Remove(solution.Model);
+
+      trainingEvaluationCache.Clear();
+      testEvaluationCache.Clear();
+      evaluationCache.Clear();
     }
   }
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationProblemData.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationProblemData.cs	(revision 8010)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationProblemData.cs	(revision 8430)
@@ -207,6 +207,6 @@
 
     #region parameter properties
-    public ConstrainedValueParameter<StringValue> TargetVariableParameter {
-      get { return (ConstrainedValueParameter<StringValue>)Parameters[TargetVariableParameterName]; }
+    public IConstrainedValueParameter<StringValue> TargetVariableParameter {
+      get { return (IConstrainedValueParameter<StringValue>)Parameters[TargetVariableParameterName]; }
     }
     public IFixedValueParameter<StringMatrix> ClassNamesParameter {
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolution.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolution.cs	(revision 8010)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolution.cs	(revision 8430)
@@ -44,5 +44,5 @@
     public ClassificationSolution(IClassificationModel model, IClassificationProblemData problemData)
       : base(model, problemData) {
-      evaluationCache = new Dictionary<int, double>();
+      evaluationCache = new Dictionary<int, double>(problemData.Dataset.Rows);
     }
 
@@ -51,8 +51,8 @@
     }
     public override IEnumerable<double> EstimatedTrainingClassValues {
-      get { return GetEstimatedClassValues(ProblemData.TrainingIndizes); }
+      get { return GetEstimatedClassValues(ProblemData.TrainingIndices); }
     }
     public override IEnumerable<double> EstimatedTestClassValues {
-      get { return GetEstimatedClassValues(ProblemData.TestIndizes); }
+      get { return GetEstimatedClassValues(ProblemData.TestIndices); }
     }
 
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolutionBase.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolutionBase.cs	(revision 8010)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolutionBase.cs	(revision 8430)
@@ -87,7 +87,7 @@
     protected void CalculateResults() {
       double[] estimatedTrainingClassValues = EstimatedTrainingClassValues.ToArray(); // cache values
-      double[] originalTrainingClassValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndizes).ToArray();
+      double[] originalTrainingClassValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices).ToArray();
       double[] estimatedTestClassValues = EstimatedTestClassValues.ToArray(); // cache values
-      double[] originalTestClassValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TestIndizes).ToArray();
+      double[] originalTestClassValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TestIndices).ToArray();
 
       OnlineCalculatorError errorState;
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationSolution.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationSolution.cs	(revision 8010)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationSolution.cs	(revision 8430)
@@ -59,8 +59,8 @@
     }
     public override IEnumerable<double> EstimatedTrainingClassValues {
-      get { return GetEstimatedClassValues(ProblemData.TrainingIndizes); }
+      get { return GetEstimatedClassValues(ProblemData.TrainingIndices); }
     }
     public override IEnumerable<double> EstimatedTestClassValues {
-      get { return GetEstimatedClassValues(ProblemData.TestIndizes); }
+      get { return GetEstimatedClassValues(ProblemData.TestIndices); }
     }
 
@@ -82,8 +82,8 @@
     }
     public override IEnumerable<double> EstimatedTrainingValues {
-      get { return GetEstimatedValues(ProblemData.TrainingIndizes); }
+      get { return GetEstimatedValues(ProblemData.TrainingIndices); }
     }
     public override IEnumerable<double> EstimatedTestValues {
-      get { return GetEstimatedValues(ProblemData.TestIndizes); }
+      get { return GetEstimatedValues(ProblemData.TestIndices); }
     }
 
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationSolutionBase.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationSolutionBase.cs	(revision 8010)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationSolutionBase.cs	(revision 8430)
@@ -103,7 +103,7 @@
     protected void CalculateRegressionResults() {
       double[] estimatedTrainingValues = EstimatedTrainingValues.ToArray(); // cache values
-      double[] originalTrainingValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndizes).ToArray();
+      double[] originalTrainingValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices).ToArray();
       double[] estimatedTestValues = EstimatedTestValues.ToArray(); // cache values
-      double[] originalTestValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TestIndizes).ToArray();
+      double[] originalTestValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TestIndices).ToArray();
 
       OnlineCalculatorError errorState;
@@ -140,5 +140,5 @@
       double[] classValues;
       double[] thresholds;
-      var targetClassValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndizes);
+      var targetClassValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices);
       AccuracyMaximizationThresholdCalculator.CalculateThresholds(ProblemData, EstimatedTrainingValues, targetClassValues, out classValues, out thresholds);
 
@@ -149,5 +149,5 @@
       double[] classValues;
       double[] thresholds;
-      var targetClassValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndizes);
+      var targetClassValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices);
       NormalDistributionCutPointsThresholdCalculator.CalculateThresholds(ProblemData, EstimatedTrainingValues, targetClassValues, out classValues, out thresholds);
 
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ThresholdCalculators/AccuracyMaximizationThresholdCalculator.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ThresholdCalculators/AccuracyMaximizationThresholdCalculator.cs	(revision 8010)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ThresholdCalculators/AccuracyMaximizationThresholdCalculator.cs	(revision 8430)
@@ -54,8 +54,9 @@
     public static void CalculateThresholds(IClassificationProblemData problemData, IEnumerable<double> estimatedValues, IEnumerable<double> targetClassValues, out double[] classValues, out double[] thresholds) {
       int slices = 100;
+      double minThresholdInc = 10e-5; // necessary to prevent infinite loop when maxEstimated - minEstimated is effectively zero (constant model)
       List<double> estimatedValuesList = estimatedValues.ToList();
       double maxEstimatedValue = estimatedValuesList.Max();
       double minEstimatedValue = estimatedValuesList.Min();
-      double thresholdIncrement = (maxEstimatedValue - minEstimatedValue) / slices;
+      double thresholdIncrement = Math.Max((maxEstimatedValue - minEstimatedValue) / slices, minThresholdInc);
       var estimatedAndTargetValuePairs =
         estimatedValuesList.Zip(targetClassValues, (x, y) => new { EstimatedValue = x, TargetClassValue = y })
@@ -70,6 +71,4 @@
 
       // incrementally calculate accuracy of all possible thresholds
-      int[,] confusionMatrix = new int[nClasses, nClasses];
-
       for (int i = 1; i < thresholds.Length; i++) {
         double lowerThreshold = thresholds[i - 1];
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringSolution.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringSolution.cs	(revision 8010)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringSolution.cs	(revision 8430)
@@ -68,5 +68,5 @@
     public virtual IEnumerable<int> TrainingClusterValues {
       get {
-        return GetClusterValues(ProblemData.TrainingIndizes);
+        return GetClusterValues(ProblemData.TrainingIndices);
       }
     }
@@ -74,5 +74,5 @@
     public virtual IEnumerable<int> TestClusterValues {
       get {
-        return GetClusterValues(ProblemData.TestIndizes);
+        return GetClusterValues(ProblemData.TestIndices);
       }
     }
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisProblemData.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisProblemData.cs	(revision 8010)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisProblemData.cs	(revision 8430)
@@ -75,5 +75,5 @@
     }
 
-    public virtual IEnumerable<int> TrainingIndizes {
+    public virtual IEnumerable<int> TrainingIndices {
       get {
         return Enumerable.Range(TrainingPartition.Start, Math.Max(0, TrainingPartition.End - TrainingPartition.Start))
@@ -81,5 +81,5 @@
       }
     }
-    public virtual IEnumerable<int> TestIndizes {
+    public virtual IEnumerable<int> TestIndices {
       get {
         return Enumerable.Range(TestPartition.Start, Math.Max(0, TestPartition.End - TestPartition.Start))
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleSolution.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleSolution.cs	(revision 8010)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleSolution.cs	(revision 8430)
@@ -37,4 +37,7 @@
   [Creatable("Data Analysis - Ensembles")]
   public sealed class RegressionEnsembleSolution : RegressionSolution, IRegressionEnsembleSolution {
+    private readonly Dictionary<int, double> trainingEvaluationCache = new Dictionary<int, double>();
+    private readonly Dictionary<int, double> testEvaluationCache = new Dictionary<int, double>();
+
     public new IRegressionEnsembleModel Model {
       get { return (IRegressionEnsembleModel)base.Model; }
@@ -52,7 +55,7 @@
 
     [Storable]
-    private Dictionary<IRegressionModel, IntRange> trainingPartitions;
+    private readonly Dictionary<IRegressionModel, IntRange> trainingPartitions;
     [Storable]
-    private Dictionary<IRegressionModel, IntRange> testPartitions;
+    private readonly Dictionary<IRegressionModel, IntRange> testPartitions;
 
     [StorableConstructor]
@@ -86,4 +89,7 @@
       }
 
+      trainingEvaluationCache = new Dictionary<int, double>(original.ProblemData.TrainingIndices.Count());
+      testEvaluationCache = new Dictionary<int, double>(original.ProblemData.TestIndices.Count());
+
       regressionSolutions = cloner.Clone(original.regressionSolutions);
       RegisterRegressionSolutionsEventHandler();
@@ -133,4 +139,7 @@
       }
 
+      trainingEvaluationCache = new Dictionary<int, double>(problemData.TrainingIndices.Count());
+      testEvaluationCache = new Dictionary<int, double>(problemData.TestIndices.Count());
+
       RegisterRegressionSolutionsEventHandler();
       regressionSolutions.AddRange(solutions);
@@ -153,18 +162,14 @@
     public override IEnumerable<double> EstimatedTrainingValues {
       get {
-        var rows = ProblemData.TrainingIndizes;
-        var estimatedValuesEnumerators = (from model in Model.Models
-                                          select new { Model = model, EstimatedValuesEnumerator = model.GetEstimatedValues(ProblemData.Dataset, rows).GetEnumerator() })
-                                         .ToList();
-        var rowsEnumerator = rows.GetEnumerator();
-        // aggregate to make sure that MoveNext is called for all enumerators 
-        while (rowsEnumerator.MoveNext() & estimatedValuesEnumerators.Select(en => en.EstimatedValuesEnumerator.MoveNext()).Aggregate(true, (acc, b) => acc & b)) {
-          int currentRow = rowsEnumerator.Current;
-
-          var selectedEnumerators = from pair in estimatedValuesEnumerators
-                                    where RowIsTrainingForModel(currentRow, pair.Model) && !RowIsTestForModel(currentRow, pair.Model)
-                                    select pair.EstimatedValuesEnumerator;
-          yield return AggregateEstimatedValues(selectedEnumerators.Select(x => x.Current));
+        var rows = ProblemData.TrainingIndices;
+        var rowsToEvaluate = rows.Except(trainingEvaluationCache.Keys);
+        var rowsEnumerator = rowsToEvaluate.GetEnumerator();
+        var valuesEnumerator = GetEstimatedValues(rowsToEvaluate, (r, m) => RowIsTrainingForModel(r, m) && !RowIsTestForModel(r, m)).GetEnumerator();
+
+        while (rowsEnumerator.MoveNext() & valuesEnumerator.MoveNext()) {
+          trainingEvaluationCache.Add(rowsEnumerator.Current, valuesEnumerator.Current);
         }
+
+        return rows.Select(row => trainingEvaluationCache[row]);
       }
     }
@@ -172,19 +177,31 @@
     public override IEnumerable<double> EstimatedTestValues {
       get {
-        var rows = ProblemData.TestIndizes;
-        var estimatedValuesEnumerators = (from model in Model.Models
-                                          select new { Model = model, EstimatedValuesEnumerator = model.GetEstimatedValues(ProblemData.Dataset, rows).GetEnumerator() })
-                                         .ToList();
-        var rowsEnumerator = ProblemData.TestIndizes.GetEnumerator();
-        // aggregate to make sure that MoveNext is called for all enumerators 
-        while (rowsEnumerator.MoveNext() & estimatedValuesEnumerators.Select(en => en.EstimatedValuesEnumerator.MoveNext()).Aggregate(true, (acc, b) => acc & b)) {
-          int currentRow = rowsEnumerator.Current;
-
-          var selectedEnumerators = from pair in estimatedValuesEnumerators
-                                    where RowIsTestForModel(currentRow, pair.Model)
-                                    select pair.EstimatedValuesEnumerator;
-
-          yield return AggregateEstimatedValues(selectedEnumerators.Select(x => x.Current));
+        var rows = ProblemData.TestIndices;
+        var rowsToEvaluate = rows.Except(testEvaluationCache.Keys);
+        var rowsEnumerator = rowsToEvaluate.GetEnumerator();
+        var valuesEnumerator = GetEstimatedValues(rowsToEvaluate, RowIsTestForModel).GetEnumerator();
+
+        while (rowsEnumerator.MoveNext() & valuesEnumerator.MoveNext()) {
+          testEvaluationCache.Add(rowsEnumerator.Current, valuesEnumerator.Current);
         }
+
+        return rows.Select(row => testEvaluationCache[row]);
+      }
+    }
+
+    private IEnumerable<double> GetEstimatedValues(IEnumerable<int> rows, Func<int, IRegressionModel, bool> modelSelectionPredicate) {
+      var estimatedValuesEnumerators = (from model in Model.Models
+                                        select new { Model = model, EstimatedValuesEnumerator = model.GetEstimatedValues(ProblemData.Dataset, rows).GetEnumerator() })
+                                       .ToList();
+      var rowsEnumerator = rows.GetEnumerator();
+      // aggregate to make sure that MoveNext is called for all enumerators 
+      while (rowsEnumerator.MoveNext() & estimatedValuesEnumerators.Select(en => en.EstimatedValuesEnumerator.MoveNext()).Aggregate(true, (acc, b) => acc & b)) {
+        int currentRow = rowsEnumerator.Current;
+
+        var selectedEnumerators = from pair in estimatedValuesEnumerators
+                                  where modelSelectionPredicate(currentRow, pair.Model)
+                                  select pair.EstimatedValuesEnumerator;
+
+        yield return AggregateEstimatedValues(selectedEnumerators.Select(x => x.Current));
       }
     }
@@ -201,6 +218,15 @@
 
     public override IEnumerable<double> GetEstimatedValues(IEnumerable<int> rows) {
-      return from xs in GetEstimatedValueVectors(ProblemData.Dataset, rows)
-             select AggregateEstimatedValues(xs);
+      var rowsToEvaluate = rows.Except(evaluationCache.Keys);
+      var rowsEnumerator = rowsToEvaluate.GetEnumerator();
+      var valuesEnumerator = (from xs in GetEstimatedValueVectors(ProblemData.Dataset, rowsToEvaluate)
+                              select AggregateEstimatedValues(xs))
+                             .GetEnumerator();
+
+      while (rowsEnumerator.MoveNext() & valuesEnumerator.MoveNext()) {
+        evaluationCache.Add(rowsEnumerator.Current, valuesEnumerator.Current);
+      }
+
+      return rows.Select(row => evaluationCache[row]);
     }
 
@@ -223,4 +249,7 @@
 
     protected override void OnProblemDataChanged() {
+      trainingEvaluationCache.Clear();
+      testEvaluationCache.Clear();
+      evaluationCache.Clear();
       IRegressionProblemData problemData = new RegressionProblemData(ProblemData.Dataset,
                                                                      ProblemData.AllowedInputVariables,
@@ -251,7 +280,15 @@
     public void AddRegressionSolutions(IEnumerable<IRegressionSolution> solutions) {
       regressionSolutions.AddRange(solutions);
+
+      trainingEvaluationCache.Clear();
+      testEvaluationCache.Clear();
+      evaluationCache.Clear();
     }
     public void RemoveRegressionSolutions(IEnumerable<IRegressionSolution> solutions) {
       regressionSolutions.RemoveRange(solutions);
+
+      trainingEvaluationCache.Clear();
+      testEvaluationCache.Clear();
+      evaluationCache.Clear();
     }
 
@@ -275,4 +312,8 @@
       trainingPartitions[solution.Model] = solution.ProblemData.TrainingPartition;
       testPartitions[solution.Model] = solution.ProblemData.TestPartition;
+
+      trainingEvaluationCache.Clear();
+      testEvaluationCache.Clear();
+      evaluationCache.Clear();
     }
 
@@ -282,4 +323,8 @@
       trainingPartitions.Remove(solution.Model);
       testPartitions.Remove(solution.Model);
+
+      trainingEvaluationCache.Clear();
+      testEvaluationCache.Clear();
+      evaluationCache.Clear();
     }
   }
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionProblemData.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionProblemData.cs	(revision 8010)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionProblemData.cs	(revision 8430)
@@ -95,6 +95,6 @@
     #endregion
 
-    public ConstrainedValueParameter<StringValue> TargetVariableParameter {
-      get { return (ConstrainedValueParameter<StringValue>)Parameters[TargetVariableParameterName]; }
+    public IConstrainedValueParameter<StringValue> TargetVariableParameter {
+      get { return (IConstrainedValueParameter<StringValue>)Parameters[TargetVariableParameterName]; }
     }
     public string TargetVariable {
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolution.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolution.cs	(revision 8010)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolution.cs	(revision 8430)
@@ -55,8 +55,8 @@
     }
     public override IEnumerable<double> EstimatedTrainingValues {
-      get { return GetEstimatedValues(ProblemData.TrainingIndizes); }
+      get { return GetEstimatedValues(ProblemData.TrainingIndices); }
     }
     public override IEnumerable<double> EstimatedTestValues {
-      get { return GetEstimatedValues(ProblemData.TestIndizes); }
+      get { return GetEstimatedValues(ProblemData.TestIndices); }
     }
 
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolutionBase.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolutionBase.cs	(revision 8010)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolutionBase.cs	(revision 8430)
@@ -138,5 +138,5 @@
         OnlineCalculatorError errorState;
         Add(new Result(TrainingMeanAbsoluteErrorResultName, "Mean of absolute errors of the model on the training partition", new DoubleValue()));
-        double trainingMAE = OnlineMeanAbsoluteErrorCalculator.Calculate(EstimatedTrainingValues, ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndizes), out errorState);
+        double trainingMAE = OnlineMeanAbsoluteErrorCalculator.Calculate(EstimatedTrainingValues, ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices), out errorState);
         TrainingMeanAbsoluteError = errorState == OnlineCalculatorError.None ? trainingMAE : double.NaN;
       }
@@ -145,5 +145,5 @@
         OnlineCalculatorError errorState;
         Add(new Result(TestMeanAbsoluteErrorResultName, "Mean of absolute errors of the model on the test partition", new DoubleValue()));
-        double testMAE = OnlineMeanAbsoluteErrorCalculator.Calculate(EstimatedTestValues, ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TestIndizes), out errorState);
+        double testMAE = OnlineMeanAbsoluteErrorCalculator.Calculate(EstimatedTestValues, ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TestIndices), out errorState);
         TestMeanAbsoluteError = errorState == OnlineCalculatorError.None ? testMAE : double.NaN;
       }
@@ -152,5 +152,5 @@
         OnlineCalculatorError errorState;
         Add(new Result(TrainingMeanErrorResultName, "Mean of errors of the model on the training partition", new DoubleValue()));
-        double trainingME = OnlineMeanErrorCalculator.Calculate(EstimatedTrainingValues, ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndizes), out errorState);
+        double trainingME = OnlineMeanErrorCalculator.Calculate(EstimatedTrainingValues, ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices), out errorState);
         TrainingMeanError = errorState == OnlineCalculatorError.None ? trainingME : double.NaN;
       }
@@ -158,5 +158,5 @@
         OnlineCalculatorError errorState;
         Add(new Result(TestMeanErrorResultName, "Mean of errors of the model on the test partition", new DoubleValue()));
-        double testME = OnlineMeanErrorCalculator.Calculate(EstimatedTestValues, ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TestIndizes), out errorState);
+        double testME = OnlineMeanErrorCalculator.Calculate(EstimatedTestValues, ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TestIndices), out errorState);
         TestMeanError = errorState == OnlineCalculatorError.None ? testME : double.NaN;
       }
@@ -166,7 +166,7 @@
     protected void CalculateResults() {
       IEnumerable<double> estimatedTrainingValues = EstimatedTrainingValues; // cache values
-      IEnumerable<double> originalTrainingValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndizes);
+      IEnumerable<double> originalTrainingValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices);
       IEnumerable<double> estimatedTestValues = EstimatedTestValues; // cache values
-      IEnumerable<double> originalTestValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TestIndizes);
+      IEnumerable<double> originalTestValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TestIndices);
 
       OnlineCalculatorError errorState;
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/Models/ConstantTimeSeriesPrognosisModel.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/Models/ConstantTimeSeriesPrognosisModel.cs	(revision 8430)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/Models/ConstantTimeSeriesPrognosisModel.cs	(revision 8430)
@@ -0,0 +1,57 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("Constant TimeSeries Model", "A time series model that returns for all prediciton the same constant value.")]
+  public class ConstantTimeSeriesPrognosisModel : NamedItem, ITimeSeriesPrognosisModel {
+    [Storable]
+    public double Constant { get; private set; }
+
+    [StorableConstructor]
+    protected ConstantTimeSeriesPrognosisModel(bool deserializing) : base(deserializing) { }
+    protected ConstantTimeSeriesPrognosisModel(ConstantTimeSeriesPrognosisModel original, Cloner cloner)
+      : base(original, cloner) {
+      Constant = original.Constant;
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ConstantTimeSeriesPrognosisModel(this, cloner);
+    }
+
+    public ConstantTimeSeriesPrognosisModel(double constant) {
+      Constant = constant;
+    }
+
+    public IEnumerable<IEnumerable<double>> GetPrognosedValues(Dataset dataset, IEnumerable<int> rows, IEnumerable<int> horizons) {
+      return horizons.Select(horizon => Enumerable.Repeat(Constant, horizon));
+    }
+
+    public ITimeSeriesPrognosisSolution CreateTimeSeriesPrognosisSolution(ITimeSeriesPrognosisProblemData problemData) {
+      return new TimeSeriesPrognosisSolution(this, problemData);
+    }
+  }
+}
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/Models/TimeSeriesPrognosisAutoRegressiveModel.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/Models/TimeSeriesPrognosisAutoRegressiveModel.cs	(revision 8010)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/Models/TimeSeriesPrognosisAutoRegressiveModel.cs	(revision 8430)
@@ -30,11 +30,8 @@
   [Item("Autoregressive TimeSeries Model", "A linear autoregressive time series model used to predict future values.")]
   public class TimeSeriesPrognosisAutoRegressiveModel : NamedItem, ITimeSeriesPrognosisModel {
-    //Currently it is only possible to calculate AR(1)
-    //The paramater calculation for AR(p) is described in http://en.wikipedia.org/wiki/Autoregressive_model and should be inserted in the future
-
     [Storable]
-    public double Alpha { get; private set; }
+    public double[] Phi { get; private set; }
     [Storable]
-    public double Beta { get; private set; }
+    public double Constant { get; private set; }
     [Storable]
     public string TargetVariable { get; private set; }
@@ -46,6 +43,6 @@
     protected TimeSeriesPrognosisAutoRegressiveModel(TimeSeriesPrognosisAutoRegressiveModel original, Cloner cloner)
       : base(original, cloner) {
-      this.Alpha = original.Alpha;
-      this.Beta = original.Beta;
+      this.Phi = (double[])original.Phi.Clone();
+      this.Constant = original.Constant;
       this.TargetVariable = original.TargetVariable;
       this.TimeOffset = original.TimeOffset;
@@ -56,8 +53,8 @@
     public TimeSeriesPrognosisAutoRegressiveModel(double alpha, double beta, string targetVariable)
       : base() {
-      Alpha = alpha;
-      Beta = beta;
+      //Alpha = alpha;
+      //Beta = beta;
       TargetVariable = targetVariable;
-      TimeOffset = -1;
+      TimeOffset = 1;
     }
 
@@ -71,8 +68,7 @@
         double[] prognosis = new double[horizon];
 
-        if (row == 0) continue;
-        prognosis[0] = dataset.GetDoubleValue(TargetVariable, row + TimeOffset);
+        prognosis[0] = dataset.GetDoubleValue(TargetVariable, row - TimeOffset);
         for (int i = 1; i < horizon; i++) {
-          prognosis[i] = Beta * prognosis[i - 1] + Alpha;
+          //prognosis[i] = Beta * prognosis[i - 1] + Alpha;
         }
         yield return prognosis;
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/Models/TimeSeriesPrognosisConstantModel.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/Models/TimeSeriesPrognosisConstantModel.cs	(revision 8010)
+++ 	(revision )
@@ -1,57 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System.Collections.Generic;
-using System.Linq;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
-  [Item("Constant TimeSeries Model", "A time series model that returns for all prediciton the same constant value.")]
-  public class TimeSeriesPrognosisConstantModel : NamedItem, ITimeSeriesPrognosisModel {
-    [Storable]
-    public double Constant { get; private set; }
-
-    [StorableConstructor]
-    protected TimeSeriesPrognosisConstantModel(bool deserializing) : base(deserializing) { }
-    protected TimeSeriesPrognosisConstantModel(TimeSeriesPrognosisConstantModel original, Cloner cloner)
-      : base(original, cloner) {
-      Constant = original.Constant;
-    }
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new TimeSeriesPrognosisConstantModel(this, cloner);
-    }
-
-    public TimeSeriesPrognosisConstantModel(double constant) {
-      Constant = constant;
-    }
-
-    public IEnumerable<IEnumerable<double>> GetPrognosedValues(Dataset dataset, IEnumerable<int> rows, IEnumerable<int> horizons) {
-      return horizons.Select(horizon => Enumerable.Repeat(Constant, horizon));
-    }
-
-    public ITimeSeriesPrognosisSolution CreateTimeSeriesPrognosisSolution(ITimeSeriesPrognosisProblemData problemData) {
-      return new TimeSeriesPrognosisSolution(this, problemData);
-    }
-  }
-}
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/Models/TimeSeriesPrognosisMovingAverageModel.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/Models/TimeSeriesPrognosisMovingAverageModel.cs	(revision 8010)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/Models/TimeSeriesPrognosisMovingAverageModel.cs	(revision 8430)
@@ -61,5 +61,4 @@
         int startIndex = row - WindowSize;
 
-        if (row == 0) continue;
         if (startIndex < 0) startIndex = 0;
         int count = row - startIndex - 1;
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionBase.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionBase.cs	(revision 8010)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionBase.cs	(revision 8430)
@@ -194,11 +194,11 @@
       OnlineCalculatorError errorState;
       //mean model
-      double trainingMean = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndizes).Average();
-      var meanModel = new TimeSeriesPrognosisConstantModel(trainingMean);
+      double trainingMean = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices).Average();
+      var meanModel = new ConstantTimeSeriesPrognosisModel(trainingMean);
 
       //AR1 model
       double alpha, beta;
-      IEnumerable<double> trainingStartValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndizes.Select(r => r - 1).Where(r => r > 0)).ToList();
-      OnlineLinearScalingParameterCalculator.Calculate(ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndizes.Where(x => x > 0)), trainingStartValues, out alpha, out beta, out errorState);
+      IEnumerable<double> trainingStartValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices.Select(r => r - 1).Where(r => r > 0)).ToList();
+      OnlineLinearScalingParameterCalculator.Calculate(ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices.Where(x => x > 0)), trainingStartValues, out alpha, out beta, out errorState);
       var AR1model = new TimeSeriesPrognosisAutoRegressiveModel(alpha, beta, ProblemData.TargetVariable);
 
@@ -208,7 +208,7 @@
 
       #region Calculate training quality measures
-      var trainingHorizions = ProblemData.TrainingIndizes.Select(r => Math.Min(horizon, ProblemData.TrainingPartition.End - r)).ToList();
-      IEnumerable<IEnumerable<double>> trainingTargetValues = ProblemData.TrainingIndizes.Zip(trainingHorizions, Enumerable.Range).Select(r => ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, r)).ToList();
-      IEnumerable<IEnumerable<double>> trainingEstimatedValues = Model.GetPrognosedValues(ProblemData.Dataset, ProblemData.TrainingIndizes, trainingHorizions).ToList();
+      var trainingHorizions = ProblemData.TrainingIndices.Select(r => Math.Min(horizon, ProblemData.TrainingPartition.End - r)).ToList();
+      IEnumerable<IEnumerable<double>> trainingTargetValues = ProblemData.TrainingIndices.Zip(trainingHorizions, Enumerable.Range).Select(r => ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, r)).ToList();
+      IEnumerable<IEnumerable<double>> trainingEstimatedValues = Model.GetPrognosedValues(ProblemData.Dataset, ProblemData.TrainingIndices, trainingHorizions).ToList();
 
       TrainingMeanSquaredError = OnlineMeanSquaredErrorCalculator.Calculate(trainingTargetValues.SelectMany(x => x), trainingEstimatedValues.SelectMany(x => x), out errorState);
@@ -223,7 +223,7 @@
       TrainingNormalizedMeanSquaredError = errorState == OnlineCalculatorError.None ? TrainingNormalizedMeanSquaredError : double.PositiveInfinity;
 
-      IEnumerable<IEnumerable<double>> trainingMeanModelPredictions = meanModel.GetPrognosedValues(ProblemData.Dataset, ProblemData.TrainingIndizes, trainingHorizions);
-      IEnumerable<IEnumerable<double>> trainingAR1ModelPredictions = AR1model.GetPrognosedValues(ProblemData.Dataset, ProblemData.TrainingIndizes, trainingHorizions);
-      IEnumerable<IEnumerable<double>> trainingMovingAverageModelPredictions = MovingAverageModel.GetPrognosedValues(ProblemData.Dataset, ProblemData.TrainingIndizes, trainingHorizions);
+      IEnumerable<IEnumerable<double>> trainingMeanModelPredictions = meanModel.GetPrognosedValues(ProblemData.Dataset, ProblemData.TrainingIndices, trainingHorizions);
+      IEnumerable<IEnumerable<double>> trainingAR1ModelPredictions = AR1model.GetPrognosedValues(ProblemData.Dataset, ProblemData.TrainingIndices, trainingHorizions);
+      IEnumerable<IEnumerable<double>> trainingMovingAverageModelPredictions = MovingAverageModel.GetPrognosedValues(ProblemData.Dataset, ProblemData.TrainingIndices, trainingHorizions);
 
       TrainingDirectionalSymmetry = OnlineDirectionalSymmetryCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingEstimatedValues, out errorState);
@@ -240,7 +240,7 @@
 
       #region  Calculate test quality measures
-      var testHorizions = ProblemData.TestIndizes.Select(r => Math.Min(horizon, ProblemData.TestPartition.End - r)).ToList();
-      IEnumerable<IEnumerable<double>> testTargetValues = ProblemData.TestIndizes.Zip(testHorizions, Enumerable.Range).Select(r => ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, r)).ToList();
-      IEnumerable<IEnumerable<double>> testEstimatedValues = Model.GetPrognosedValues(ProblemData.Dataset, ProblemData.TestIndizes, testHorizions).ToList();
+      var testHorizions = ProblemData.TestIndices.Select(r => Math.Min(horizon, ProblemData.TestPartition.End - r)).ToList();
+      IEnumerable<IEnumerable<double>> testTargetValues = ProblemData.TestIndices.Zip(testHorizions, Enumerable.Range).Select(r => ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, r)).ToList();
+      IEnumerable<IEnumerable<double>> testEstimatedValues = Model.GetPrognosedValues(ProblemData.Dataset, ProblemData.TestIndices, testHorizions).ToList();
 
       TestMeanSquaredError = OnlineMeanSquaredErrorCalculator.Calculate(testTargetValues.SelectMany(x => x), testEstimatedValues.SelectMany(x => x), out errorState);
@@ -255,8 +255,8 @@
       TestNormalizedMeanSquaredError = errorState == OnlineCalculatorError.None ? TestNormalizedMeanSquaredError : double.PositiveInfinity;
 
-      IEnumerable<double> testStartValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TestIndizes.Select(r => r - 1).Where(r => r > 0)).ToList();
-      IEnumerable<IEnumerable<double>> testMeanModelPredictions = meanModel.GetPrognosedValues(ProblemData.Dataset, ProblemData.TestIndizes, testHorizions);
-      IEnumerable<IEnumerable<double>> testAR1ModelPredictions = AR1model.GetPrognosedValues(ProblemData.Dataset, ProblemData.TestIndizes, testHorizions);
-      IEnumerable<IEnumerable<double>> testMovingAverageModelPredictions = MovingAverageModel.GetPrognosedValues(ProblemData.Dataset, ProblemData.TestIndizes, testHorizions);
+      IEnumerable<double> testStartValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TestIndices.Select(r => r - 1).Where(r => r > 0)).ToList();
+      IEnumerable<IEnumerable<double>> testMeanModelPredictions = meanModel.GetPrognosedValues(ProblemData.Dataset, ProblemData.TestIndices, testHorizions);
+      IEnumerable<IEnumerable<double>> testAR1ModelPredictions = AR1model.GetPrognosedValues(ProblemData.Dataset, ProblemData.TestIndices, testHorizions);
+      IEnumerable<IEnumerable<double>> testMovingAverageModelPredictions = MovingAverageModel.GetPrognosedValues(ProblemData.Dataset, ProblemData.TestIndices, testHorizions);
 
       TestDirectionalSymmetry = OnlineDirectionalSymmetryCalculator.Calculate(testStartValues, testTargetValues, testEstimatedValues, out errorState);
@@ -270,5 +270,5 @@
       TestTheilsUStatisticMovingAverage = OnlineTheilsUStatisticCalculator.Calculate(testStartValues, testTargetValues, testMovingAverageModelPredictions, testEstimatedValues, out errorState);
       TestTheilsUStatisticMovingAverage = errorState == OnlineCalculatorError.None ? TestTheilsUStatisticMovingAverage : double.PositiveInfinity; ; ;
-      #endregion     
+      #endregion
     }
   }
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisProblemData.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisProblemData.cs	(revision 8010)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisProblemData.cs	(revision 8430)
@@ -36,6 +36,6 @@
     IntRange TestPartition { get; }
 
-    IEnumerable<int> TrainingIndizes { get; }
-    IEnumerable<int> TestIndizes { get; }
+    IEnumerable<int> TrainingIndices { get; }
+    IEnumerable<int> TestIndices { get; }
 
     bool IsTrainingSample(int index);
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IOnlineCalculator.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IOnlineCalculator.cs	(revision 8010)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IOnlineCalculator.cs	(revision 8430)
@@ -24,13 +24,13 @@
 namespace HeuristicLab.Problems.DataAnalysis {
   [Flags]
-  public enum OnlineCalculatorError { 
+  public enum OnlineCalculatorError {
     /// <summary>
     /// No error occurred
     /// </summary>
-    None = 0, 
+    None = 0,
     /// <summary>
     /// An invalid value has been added (often +/- Infinity and NaN are invalid values)
     /// </summary>
-    InvalidValueAdded = 1, 
+    InvalidValueAdded = 1,
     /// <summary>
     /// The number of elements added to the evaluator is not sufficient to calculate the result value
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/AutoCorrelationCalculator.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/AutoCorrelationCalculator.cs	(revision 8430)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/AutoCorrelationCalculator.cs	(revision 8430)
@@ -0,0 +1,38 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Linq;
+
+namespace HeuristicLab.Problems.DataAnalysis.OnlineCalculators {
+  public class AutoCorrelationCalculator {
+    public static double[] Calculate(double[] values, out OnlineCalculatorError error) {
+      error = OnlineCalculatorError.None;
+      if (values.Any(x => double.IsNaN(x) || double.IsInfinity(x))) {
+        error = OnlineCalculatorError.InvalidValueAdded;
+        return new double[0];
+      }
+
+      double[] correlations = new double[values.Length];
+      alglib.corr.corrr1dcircular(values, values.Length, values, values.Length, ref correlations);
+      return correlations;
+    }
+  }
+}
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/HoeffdingsDependenceCalculator.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/HoeffdingsDependenceCalculator.cs	(revision 8430)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/HoeffdingsDependenceCalculator.cs	(revision 8430)
@@ -0,0 +1,130 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public class HoeffdingsDependenceCalculator {
+
+    public static double Calculate(IEnumerable<double> originalValues, IEnumerable<double> estimatedValues, out OnlineCalculatorError errorState) {
+      double d = HoeffD(originalValues, estimatedValues, out errorState);
+      if (errorState != OnlineCalculatorError.None) return double.NaN;
+      return d;
+    }
+
+    /// <summary>
+    /// computes Hoeffding's dependence coefficient. 
+    /// Source: hoeffd.r from R package hmisc http://cran.r-project.org/web/packages/Hmisc/index.html
+    /// </summary>
+    private static double HoeffD(IEnumerable<double> xs, IEnumerable<double> ys, out OnlineCalculatorError errorState) {
+      double[] rx = TiedRank(xs);
+      double[] ry = TiedRank(ys);
+      if (rx.Length != ry.Length) throw new ArgumentException("The number of elements in xs and ys does not match");
+      double[] rxy = TiedRank(xs, ys);
+
+      int n = rx.Length;
+      double q = 0, r = 0, s = 0;
+      double scaling = 1.0 / (n * (n - 1));
+      for (int i = 0; i < n; i++) {
+        q += (rx[i] - 1) * (rx[i] - 2) * (ry[i] - 1) * (ry[i] - 2) * scaling;
+        r += (rx[i] - 2) * (ry[i] - 2) * rxy[i] * scaling;
+        s += rxy[i] * (rxy[i] - 1) * scaling;
+      }
+      errorState = OnlineCalculatorError.None;
+      // return 30.0 * (q - 2 * (n - 2) * r + (n - 2) * (n - 3) * s) / n / (n - 1) / (n - 2) / (n - 3) / (n - 4);
+      double t0 = q / (n - 2) / (n - 3) / (n - 4);
+      double t1 = 2 * r / (n - 3) / (n - 4);
+      double t2 = s / (n - 4);
+      return 30.0 * (t0 - t1 + t2);
+    }
+
+    private static double[] TiedRank(IEnumerable<double> xs) {
+      var xsArr = xs.ToArray();
+      var idx = Enumerable.Range(1, xsArr.Length).ToArray();
+      Array.Sort(xsArr, idx);
+      CRank(xsArr);
+      Array.Sort(idx, xsArr);
+      return xsArr;
+    }
+
+    /// <summary>
+    /// Calculates the joint rank with midranks for ties. Source: hoeffd.r from R package hmisc http://cran.r-project.org/web/packages/Hmisc/index.html
+    /// </summary>
+    /// <param name="xs"></param>
+    /// <param name="ys"></param>
+    /// <returns></returns>
+    private static double[] TiedRank(IEnumerable<double> xs, IEnumerable<double> ys) {
+      var xsArr = xs.ToArray();
+      var ysArr = ys.ToArray();
+      var r = new double[xsArr.Length];
+      int n = r.Length;
+      for (int i = 0; i < n; i++) {
+        var xi = xsArr[i];
+        var yi = ysArr[i];
+        double ri = 0.0;
+        for (int j = 0; j < n; j++) {
+          if (i != j) {
+            double cx;
+            if (xsArr[j] < xi) cx = 1.0;
+            else if (xsArr[j] > xi) cx = 0.0;
+            else cx = 0.5;  // eq
+            double cy;
+            if (ysArr[j] < yi) cy = 1.0;
+            else if (ysArr[j] > yi) cy = 0.0;
+            else cy = 0.5; // eq
+            ri = ri + cx * cy;
+          }
+        }
+        r[i] = ri;
+      }
+      return r;
+    }
+
+    /// <summary>
+    /// Calculates midranks. Source: Numerical Recipes in C. p 642
+    /// </summary>
+    /// <param name="w">Sorted array of elements, replaces the elements by their rank, including midranking of ties</param>
+    /// <returns></returns>
+    private static void CRank(double[] w) {
+      int i = 0;
+      int n = w.Length;
+      while (i < n - 1) {
+        if (w[i + 1] > w[i]) {    // w[i+1] must be larger or equal w[i] as w must be sorted
+          // not a tie
+          w[i] = i + 1;
+          i++;
+        } else {
+          int j;
+          for (j = i + 1; j < n && w[j] <= w[i]; j++) ; // how far does it go (<= effectively means == as w must be sorted, side-step equality for double values)
+          double rank = 1 + 0.5 * (i + j - 1);
+          int k;
+          for (k = i; k < j; k++) w[k] = rank; // set the rank for all tied entries
+          i = j;
+        }
+      }
+
+      if (i == n - 1) w[n - 1] = n;   // if the last element was not tied, this is its rank
+    }
+  }
+}
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineLinearScalingParameterCalculator.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineLinearScalingParameterCalculator.cs	(revision 8010)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineLinearScalingParameterCalculator.cs	(revision 8430)
@@ -55,5 +55,4 @@
     }
 
-    private int cnt;
     private OnlineMeanAndVarianceCalculator targetMeanCalculator;
     private OnlineMeanAndVarianceCalculator originalMeanAndVarianceCalculator;
@@ -68,5 +67,4 @@
 
     public void Reset() {
-      cnt = 0;
       targetMeanCalculator.Reset();
       originalMeanAndVarianceCalculator.Reset();
@@ -85,5 +83,4 @@
       originalTargetCovarianceCalculator.Add(original, target);
 
-      cnt++;
     }
 
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineTheilsUStatisticCalculator.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineTheilsUStatisticCalculator.cs	(revision 8010)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineTheilsUStatisticCalculator.cs	(revision 8430)
@@ -55,5 +55,5 @@
     }
 
-    public void Add(double startValue, IEnumerable<double> referenceContinuation, IEnumerable<double> actualContinuation, IEnumerable<double> predictedContinuation) {
+    public void Add(double startValue, IEnumerable<double> actualContinuation, IEnumerable<double> referenceContinuation, IEnumerable<double> predictedContinuation) {
       if (double.IsNaN(startValue) || (errorState & OnlineCalculatorError.InvalidValueAdded) > 0) {
         errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Plugin.cs.frame
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Plugin.cs.frame	(revision 8010)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Plugin.cs.frame	(revision 8430)
@@ -26,6 +26,7 @@
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  [Plugin("HeuristicLab.Problems.DataAnalysis","Provides base classes for data analysis tasks.", "3.4.2.$WCREV$")]
+  [Plugin("HeuristicLab.Problems.DataAnalysis","Provides base classes for data analysis tasks.", "3.4.3.$WCREV$")]
   [PluginFile("HeuristicLab.Problems.DataAnalysis-3.4.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.ALGLIB","3.5")]
   [PluginDependency("HeuristicLab.Collections", "3.3")]
   [PluginDependency("HeuristicLab.Common", "3.3")]
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Properties/AssemblyInfo.cs.frame
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Properties/AssemblyInfo.cs.frame	(revision 8010)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Properties/AssemblyInfo.cs.frame	(revision 8430)
@@ -53,3 +53,3 @@
 // by using the '*' as shown below:
 [assembly: AssemblyVersion("3.4.0.0")]
-[assembly: AssemblyFileVersion("3.4.2.$WCREV$")]
+[assembly: AssemblyFileVersion("3.4.3.$WCREV$")]
