Index: /branches/Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/SlidingWindowBestSolutionsCollectionHeatMapView.Designer.cs
===================================================================
--- /branches/Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/SlidingWindowBestSolutionsCollectionHeatMapView.Designer.cs	(revision 10720)
+++ /branches/Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/SlidingWindowBestSolutionsCollectionHeatMapView.Designer.cs	(revision 10721)
@@ -19,4 +19,6 @@
  */
 #endregion
+
+using System.Windows.Forms;
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Views {
@@ -76,4 +78,5 @@
       this.comboBox1.Text = "Pearson R2";
       this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged);
+      this.comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;
       // 
       // label1
Index: /branches/Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/SlidingWindowBestSolutionsCollectionHeatMapView.cs
===================================================================
--- /branches/Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/SlidingWindowBestSolutionsCollectionHeatMapView.cs	(revision 10720)
+++ /branches/Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/SlidingWindowBestSolutionsCollectionHeatMapView.cs	(revision 10721)
@@ -42,8 +42,16 @@
       base.OnContentChanged();
       if (Content != null) {
+        // set the dropdown value to the correct value
+        switch (Content.QualityMeasure) {
+          case SlidingWindowBestSolutionsCollection.QualityMeasures.PEARSON:
+            comboBox1.SelectedIndex = comboBox1.Items.IndexOf("Pearson R2");
+            break;
+          case SlidingWindowBestSolutionsCollection.QualityMeasures.MSE:
+            comboBox1.SelectedIndex = comboBox1.Items.IndexOf("Mean Squared Error");
+            break;
+        }
         if (Content.SlidingWindowQualities != null) {
           SetHeatmapContent(Content.SlidingWindowQualities);
         } else if (!Content.QualitiesCalculationInProgress) {
-          progress.Start("Calculating best solution qualities...");
           Content.CalculateQualities();
         }
@@ -64,4 +72,5 @@
       Content.QualitiesCalculationProgress -= bestSolutionCollectionQualitiesCalculationProgress;
       Content.QualitiesUpdated -= bestSolutionCollectionQualitiesUpdated;
+      Content.QualitiesCalculationStarted -= bestSolutionsCollectionQualtiesCalculationStarted;
       base.DeregisterContentEvents();
     }
@@ -73,4 +82,5 @@
       Content.QualitiesCalculationProgress += bestSolutionCollectionQualitiesCalculationProgress;
       Content.QualitiesUpdated += bestSolutionCollectionQualitiesUpdated;
+      Content.QualitiesCalculationStarted += bestSolutionsCollectionQualtiesCalculationStarted;
     }
 
@@ -90,7 +100,11 @@
     private void SetHeatmapContent(double[,] values) {
       double min = 0, max = 0;
-      foreach (var q in values) {
-        if (min > q) min = q;
-        if (max < q) max = q;
+      if (Content.QualityMeasure == SlidingWindowBestSolutionsCollection.QualityMeasures.PEARSON) {
+        max = 1.0;
+      } else {
+        foreach (var q in values) {
+          if (min > q) min = q;
+          if (max < q) max = q;
+        }
       }
       int rows = values.GetLength(0);
@@ -103,4 +117,8 @@
       }
       heatMapView.Content = new HeatMap(flipped, "Best Sliding Window Solutions", min, max);
+    }
+
+    private void bestSolutionsCollectionQualtiesCalculationStarted(object sender, EventArgs e) {
+      progress.Start("Calculating best solutions qualities...");
     }
 
Index: /branches/Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/SlidingWindowBestSolutionsCollectionView.Designer.cs
===================================================================
--- /branches/Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/SlidingWindowBestSolutionsCollectionView.Designer.cs	(revision 10720)
+++ /branches/Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/SlidingWindowBestSolutionsCollectionView.Designer.cs	(revision 10721)
@@ -19,4 +19,6 @@
  */
 #endregion
+
+using System.Windows.Forms;
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Views {
@@ -80,4 +82,5 @@
       this.comboBox1.Text = "Pearson R2";
       this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged);
+      this.comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;
       // 
       // label1
Index: /branches/Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/SlidingWindowBestSolutionsCollectionView.cs
===================================================================
--- /branches/Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/SlidingWindowBestSolutionsCollectionView.cs	(revision 10720)
+++ /branches/Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/SlidingWindowBestSolutionsCollectionView.cs	(revision 10721)
@@ -43,8 +43,15 @@
       base.OnContentChanged();
       if (Content != null) {
+        switch (Content.QualityMeasure) {
+          case SlidingWindowBestSolutionsCollection.QualityMeasures.PEARSON:
+            comboBox1.SelectedIndex = comboBox1.Items.IndexOf("Pearson R2");
+            break;
+          case SlidingWindowBestSolutionsCollection.QualityMeasures.MSE:
+            comboBox1.SelectedIndex = comboBox1.Items.IndexOf("Mean Squared Error");
+            break;
+        }
         if (Content.SlidingWindowQualities != null) {
           SetMatrixContent(Content.SlidingWindowQualities);
         } else if (!Content.QualitiesCalculationInProgress) {
-          progress.Start("Calculating best solution qualities...");
           Content.CalculateQualities();
         }
@@ -60,4 +67,5 @@
       Content.QualitiesCalculationProgress -= bestSolutionCollectionQualitiesCalculationProgress;
       Content.QualitiesUpdated -= bestSolutionCollectionQualitiesUpdated;
+      Content.QualitiesCalculationStarted -= bestSolutionsCollectionQualtiesCalculationStarted;
       base.DeregisterContentEvents();
     }
@@ -70,4 +78,5 @@
       Content.QualitiesCalculationProgress += bestSolutionCollectionQualitiesCalculationProgress;
       Content.QualitiesUpdated += bestSolutionCollectionQualitiesUpdated;
+      Content.QualitiesCalculationStarted += bestSolutionsCollectionQualtiesCalculationStarted;
     }
 
@@ -79,4 +88,8 @@
 
     #region Event Handlers (Content)
+    private void bestSolutionsCollectionQualtiesCalculationStarted(object sender, EventArgs e) {
+      progress.Start("Calculating best solutions qualities...");
+    }
+
     private void bestSolutionsCollectionQualitiesCalculated(object sender, RunWorkerCompletedEventArgs e) {
       if (e.Cancelled || e.Error != null) {
@@ -87,20 +100,4 @@
       SetMatrixContent(Content.SlidingWindowQualities);
       progress.Finish();
-    }
-
-    private void SetMatrixContent(double[,] values) {
-      var qualitiesMap = new DoubleMatrix(values); // add an extra columns for the training data
-      qualitiesMap.ColumnNames = Enumerable.Range(0, qualitiesMap.Columns - 1).Select(x => Content.SlidingWindowRanges[x].Start + " - " + Content.SlidingWindowRanges[x].End).Concat(new List<string> { "Training" });
-      qualitiesMap.RowNames = Enumerable.Range(1, qualitiesMap.Rows).Select(x => "M" + x);
-
-      double min = 0, max = 0;
-      foreach (var q in qualitiesMap) {
-        if (min > q) min = q;
-        if (max < q) max = q;
-      }
-
-      enhancedStringConvertibleMatrixView.Minimum = min;
-      enhancedStringConvertibleMatrixView.Maximum = max;
-      enhancedStringConvertibleMatrixView.Content = qualitiesMap;
     }
 
@@ -117,4 +114,23 @@
       base.SetEnabledStateOfControls();
       // TODO: Enable or disable controls based on whether the content is null or the view is set readonly
+    }
+
+    private void SetMatrixContent(double[,] values) {
+      var qualitiesMap = new DoubleMatrix(values); // add an extra columns for the training data
+      qualitiesMap.ColumnNames = Enumerable.Range(0, qualitiesMap.Columns - 1).Select(x => Content.SlidingWindowRanges[x].Start + " - " + Content.SlidingWindowRanges[x].End).Concat(new List<string> { "Training" });
+      qualitiesMap.RowNames = Enumerable.Range(1, qualitiesMap.Rows).Select(x => "M" + x);
+      double min = 0, max = 0;
+      if (Content.QualityMeasure == SlidingWindowBestSolutionsCollection.QualityMeasures.PEARSON) {
+        max = 1.0;
+      } else {
+        foreach (var q in qualitiesMap) {
+          if (min > q) min = q;
+          if (max < q) max = q;
+        }
+      }
+
+      enhancedStringConvertibleMatrixView.Minimum = min;
+      enhancedStringConvertibleMatrixView.Maximum = max;
+      enhancedStringConvertibleMatrixView.Content = qualitiesMap;
     }
 
Index: /branches/Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SlidingWindow/SlidingWindowBestSolutionsCollection.cs
===================================================================
--- /branches/Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SlidingWindow/SlidingWindowBestSolutionsCollection.cs	(revision 10720)
+++ /branches/Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SlidingWindow/SlidingWindowBestSolutionsCollection.cs	(revision 10721)
@@ -35,4 +35,5 @@
     [Storable]
     private List<SlidingWindowRange> slidingWindowRanges;
+
     public List<SlidingWindowRange> SlidingWindowRanges {
       get { return slidingWindowRanges; }
@@ -55,4 +56,5 @@
     [Storable]
     private Dictionary<SlidingWindowRange, ISymbolicExpressionTree> slidingWindowBestSolutions;
+
     public Dictionary<SlidingWindowRange, ISymbolicExpressionTree> SlidingWindowBestSolutions {
       get { return slidingWindowBestSolutions; }
@@ -62,4 +64,5 @@
     [Storable]
     private IDataAnalysisProblemData problemData;
+
     public IDataAnalysisProblemData ProblemData {
       get { return problemData; }
@@ -69,4 +72,5 @@
     [Storable]
     private ISymbolicDataAnalysisExpressionTreeInterpreter interpreter;
+
     public ISymbolicDataAnalysisExpressionTreeInterpreter Interpreter {
       get { return interpreter; }
@@ -76,4 +80,5 @@
     [Storable]
     private bool applyLinearScaling;
+
     public bool ApplyLinearScaling {
       get { return applyLinearScaling; }
@@ -98,4 +103,5 @@
 
     private QualityMeasures qualityMeasure;
+
     public QualityMeasures QualityMeasure {
       get { return qualityMeasure; }
@@ -122,12 +128,26 @@
     }
 
+    public event EventHandler QualitiesCalculationStarted;
+
+    private void OnQualitiesCalculationStarted(object sender, EventArgs e) {
+      var started = QualitiesCalculationStarted;
+      if (started != null) {
+        started(sender, e);
+      }
+    }
+
     public event EventHandler QualitiesUpdated;
     private void OnQualitiesUpdated(object sender, EventArgs e) {
       var updated = QualitiesUpdated;
-      if (updated != null) { updated(sender, e); }
+      if (updated != null) {
+        updated(sender, e);
+      }
     }
 
     [StorableConstructor]
-    protected SlidingWindowBestSolutionsCollection(bool deserializing) : base(deserializing) { }
+    protected SlidingWindowBestSolutionsCollection(bool deserializing)
+      : base(deserializing) {
+    }
+
     protected SlidingWindowBestSolutionsCollection(SlidingWindowBestSolutionsCollection original, Cloner cloner)
       : base(original, cloner) {
@@ -137,4 +157,5 @@
       this.applyLinearScaling = original.ApplyLinearScaling;
     }
+
     protected SlidingWindowBestSolutionsCollection() {
       slidingWindowBestSolutions = new Dictionary<SlidingWindowRange, ISymbolicExpressionTree>();
@@ -154,7 +175,5 @@
 
     public ISymbolicExpressionTree this[SlidingWindowRange key] {
-      get {
-        return slidingWindowBestSolutions[key];
-      }
+      get { return slidingWindowBestSolutions[key]; }
       set {
         AddSolution(key, value); // this should be fast so there's no need for a background worker
@@ -177,11 +196,12 @@
     }
 
-    public abstract ISymbolicDataAnalysisModel CreateModel(ISymbolicExpressionTree tree, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
-     double lowerEstimationLimit = double.MinValue, double upperEstimationLimit = double.MaxValue);
-
-    public abstract ISymbolicDataAnalysisSolution CreateSolution(ISymbolicDataAnalysisModel model, IDataAnalysisProblemData problemData);
+    public abstract ISymbolicDataAnalysisModel CreateModel(ISymbolicExpressionTree tree,
+      ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
+      double lowerEstimationLimit = double.MinValue, double upperEstimationLimit = double.MaxValue);
+
+    public abstract ISymbolicDataAnalysisSolution CreateSolution(ISymbolicDataAnalysisModel model,
+      IDataAnalysisProblemData problemData);
 
     private void AddSolution(SlidingWindowRange range, ISymbolicExpressionTree solution) {
-      // add a solution and update the qualities matrix
       Add(range, solution);
 
@@ -193,5 +213,5 @@
       var trainingIndices = problemData.TrainingIndices.ToList();
       var matrix = new double[nRows, nCols];
-      List<int> rows;
+
       // copy old qualities into the new matrix
       for (int i = 0; i < nRows - 1; ++i) {
@@ -201,7 +221,16 @@
       }
       // copy qualities of new solution into the new matrix
+      var rows = Enumerable.Range(slidingWindowRanges.First().Start, slidingWindowRanges.Last().End - slidingWindowRanges.First().Start).ToList();
+      var estimatedValues = Interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, rows).ToList();
+      var originalValues = ProblemData.Dataset.GetDoubleValues(GetTargetVariable(ProblemData), rows).ToList();
       for (int i = 0; i < nCols; ++i) {
-        rows = i == nCols - 1 ? trainingIndices : Enumerable.Range(slidingWindowRanges[i].Start, slidingWindowRanges[i].Size).ToList();
-        matrix[nRows - 1, i] = CalculateQuality(solution, rows);
+        if (i == nCols - 1) {
+          matrix[nRows - 1, i] = CalculateQuality(solution, trainingIndices);
+        } else {
+          var indices = Enumerable.Range(slidingWindowRanges[i].Start, slidingWindowRanges[i].Size).ToList();
+          var estimated = indices.Select(x => estimatedValues[x]);
+          var original = indices.Select(x => originalValues[x]);
+          matrix[nRows - 1, i] = CalculateQuality(estimated, original);
+        }
       }
       // shift old training qualities one column to the right
@@ -223,13 +252,17 @@
       }
 
+      OnQualitiesCalculationStarted(this, EventArgs.Empty);
+
       var ranges = SlidingWindowRanges;
       var solutions = ranges.Select(x => SlidingWindowBestSolutions[x]).ToList();
 
-      int rows = solutions.Count;
-      int columns = ranges.Count + 1;
-
-      SlidingWindowQualities = new double[rows, columns];
-
-      for (int i = 0; i < rows; ++i) {
+      int nRows = solutions.Count;
+      int nCols = ranges.Count + 1;
+
+      SlidingWindowQualities = new double[nRows, nCols];
+      var rows = Enumerable.Range(ranges.First().Start, ranges.Last().End - ranges.First().Start).ToList();
+      var originalValues = ProblemData.Dataset.GetDoubleValues(GetTargetVariable(ProblemData), rows).ToList();
+
+      for (int i = 0; i < nRows; ++i) {
         if (worker.CancellationPending) {
           e.Cancel = true;
@@ -238,12 +271,23 @@
 
         var solution = solutions[i];
-        for (int j = 0; j < columns; ++j) {
-          var range = (j == columns - 1) ? ProblemData.TrainingIndices : Enumerable.Range(ranges[j].Start, ranges[j].Size);
-          var q = CalculateQuality(solution, range);
+        var estimatedValues = Interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, rows).ToList();
+
+        for (int j = 0; j < nCols; ++j) {
+          double q;
+          if (j == nCols - 1) {
+            q = CalculateQuality(solution, problemData.TrainingIndices);
+          } else {
+            var range = ranges[j];
+            var indices = Enumerable.Range(range.Start, range.Size).ToList();
+            var estimated = indices.Select(x => estimatedValues[x]);
+            var original = indices.Select(x => originalValues[x]);
+
+            q = CalculateQuality(estimated, original);
+          }
 
           SlidingWindowQualities[i, j] = q;
         }
 
-        worker.ReportProgress((int)Math.Round(i * 100.0 / rows));
+        worker.ReportProgress((int)Math.Round(i * 100.0 / nRows));
       }
     }
@@ -259,4 +303,18 @@
       if (classificationProblemData != null) return classificationProblemData.TargetVariable;
       throw new NotSupportedException();
+    }
+
+    private double CalculateQuality(IEnumerable<double> estimatedValues, IEnumerable<double> originalValues) {
+      var errorState = OnlineCalculatorError.None;
+      double quality = 0.0;
+      switch (QualityMeasure) {
+        case QualityMeasures.PEARSON:
+          quality = OnlinePearsonsRSquaredCalculator.Calculate(estimatedValues, originalValues, out errorState);
+          break;
+        case QualityMeasures.MSE:
+          quality = OnlineMeanSquaredErrorCalculator.Calculate(estimatedValues, originalValues, out errorState);
+          break;
+      }
+      return errorState == OnlineCalculatorError.None ? quality : double.NaN;
     }
 
