Index: /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionEstimatedClassValuesView.cs
===================================================================
--- /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionEstimatedClassValuesView.cs	(revision 8275)
+++ /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionEstimatedClassValuesView.cs	(revision 8276)
@@ -73,20 +73,20 @@
       }
 
-      int[] indizes;
+      int[] indices;
       double[] estimatedClassValues;
 
       switch (SamplesComboBox.SelectedItem.ToString()) {
         case SamplesComboBoxAllSamples: {
-            indizes = Enumerable.Range(0, Content.ProblemData.Dataset.Rows).ToArray();
+            indices = Enumerable.Range(0, Content.ProblemData.Dataset.Rows).ToArray();
             estimatedClassValues = Content.EstimatedClassValues.ToArray();
             break;
           }
         case SamplesComboBoxTrainingSamples: {
-            indizes = Content.ProblemData.TrainingIndizes.ToArray();
+            indices = Content.ProblemData.TrainingIndices.ToArray();
             estimatedClassValues = Content.EstimatedTrainingClassValues.ToArray();
             break;
           }
         case SamplesComboBoxTestSamples: {
-            indizes = Content.ProblemData.TestIndizes.ToArray();
+            indices = Content.ProblemData.TestIndices.ToArray();
             estimatedClassValues = Content.EstimatedTestClassValues.ToArray();
             break;
@@ -98,11 +98,11 @@
       int classValuesCount = Content.ProblemData.ClassValues.Count;
       int solutionsCount = Content.ClassificationSolutions.Count();
-      string[,] values = new string[indizes.Length, 5 + classValuesCount + solutionsCount];
+      string[,] values = new string[indices.Length, 5 + classValuesCount + solutionsCount];
       double[] target = Content.ProblemData.Dataset.GetDoubleValues(Content.ProblemData.TargetVariable).ToArray();
-      List<List<double?>> estimatedValuesVector = GetEstimatedValues(SamplesComboBox.SelectedItem.ToString(), indizes,
+      List<List<double?>> estimatedValuesVector = GetEstimatedValues(SamplesComboBox.SelectedItem.ToString(), indices,
                                                             Content.ClassificationSolutions);
 
-      for (int i = 0; i < indizes.Length; i++) {
-        int row = indizes[i];
+      for (int i = 0; i < indices.Length; i++) {
+        int row = indices[i];
         values[i, 0] = row.ToString();
         values[i, 1] = target[i].ToString();
Index: /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionConfusionMatrixView.cs
===================================================================
--- /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionConfusionMatrixView.cs	(revision 8275)
+++ /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionConfusionMatrixView.cs	(revision 8276)
@@ -107,8 +107,8 @@
         double[] predictedValues;
         if (cmbSamples.SelectedItem.ToString() == TrainingSamples) {
-          rows = Content.ProblemData.TrainingIndizes;
+          rows = Content.ProblemData.TrainingIndices;
           predictedValues = Content.EstimatedTrainingClassValues.ToArray();
         } else if (cmbSamples.SelectedItem.ToString() == TestSamples) {
-          rows = Content.ProblemData.TestIndizes;
+          rows = Content.ProblemData.TestIndices;
           predictedValues = Content.EstimatedTestClassValues.ToArray();
         } else throw new InvalidOperationException();
Index: /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionEstimatedClassValuesView.cs
===================================================================
--- /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionEstimatedClassValuesView.cs	(revision 8275)
+++ /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionEstimatedClassValuesView.cs	(revision 8276)
@@ -96,5 +96,5 @@
           var estimatedTraining = Content.EstimatedTrainingClassValues.GetEnumerator();
           estimatedTraining.MoveNext();
-          foreach (var trainingRow in Content.ProblemData.TrainingIndizes) {
+          foreach (var trainingRow in Content.ProblemData.TrainingIndices) {
             values[trainingRow, 3] = estimatedTraining.Current.ToString();
             estimatedTraining.MoveNext();
@@ -102,5 +102,5 @@
           var estimatedTest = Content.EstimatedTestClassValues.GetEnumerator();
           estimatedTest.MoveNext();
-          foreach (var testRow in Content.ProblemData.TestIndizes) {
+          foreach (var testRow in Content.ProblemData.TestIndices) {
             values[testRow, 4] = estimatedTest.Current.ToString();
             estimatedTest.MoveNext();
Index: /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationRocCurvesView.cs
===================================================================
--- /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationRocCurvesView.cs	(revision 8275)
+++ /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationRocCurvesView.cs	(revision 8276)
@@ -101,7 +101,7 @@
 
         if (cmbSamples.SelectedItem.ToString() == TrainingSamples) {
-          rows = Content.ProblemData.TrainingIndizes;
+          rows = Content.ProblemData.TrainingIndices;
         } else if (cmbSamples.SelectedItem.ToString() == TestSamples) {
-          rows = Content.ProblemData.TestIndizes;
+          rows = Content.ProblemData.TestIndices;
         } else throw new InvalidOperationException();
 
Index: /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationSolutionThresholdView.cs
===================================================================
--- /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationSolutionThresholdView.cs	(revision 8275)
+++ /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationSolutionThresholdView.cs	(revision 8276)
@@ -137,5 +137,5 @@
       var targetValues = Content.ProblemData.Dataset.GetDoubleValues(Content.ProblemData.TargetVariable).ToList();
 
-      foreach (int row in Content.ProblemData.TrainingIndizes) {
+      foreach (int row in Content.ProblemData.TrainingIndices) {
         double estimatedValue = estimatedValues[row];
         double targetValue = targetValues[row];
@@ -150,5 +150,5 @@
       }
 
-      foreach (int row in Content.ProblemData.TestIndizes) {
+      foreach (int row in Content.ProblemData.TestIndices) {
         double estimatedValue = estimatedValues[row];
         double targetValue = targetValues[row];
Index: /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/CorrelationHeatMapView.Designer.cs
===================================================================
--- /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/CorrelationHeatMapView.Designer.cs	(revision 8276)
+++ /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/CorrelationHeatMapView.Designer.cs	(revision 8276)
@@ -0,0 +1,120 @@
+﻿namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class CorrelationHeatMapView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.CorrelationCalcComboBox = new System.Windows.Forms.ComboBox();
+      this.CorrelationCalcLabel = new System.Windows.Forms.Label();
+      this.PartitionLabel = new System.Windows.Forms.Label();
+      this.PartitionComboBox = new System.Windows.Forms.ComboBox();
+      this.ExtendedHeatMap = new HeuristicLab.Problems.DataAnalysis.Views.ExtendedHeatMapView();
+      this.HeatMapProgressBar = new System.Windows.Forms.ProgressBar();
+      this.SuspendLayout();
+      // 
+      // CorrelationCalcComboBox
+      // 
+      this.CorrelationCalcComboBox.FormattingEnabled = true;
+      this.CorrelationCalcComboBox.Location = new System.Drawing.Point(119, 3);
+      this.CorrelationCalcComboBox.Name = "CorrelationCalcComboBox";
+      this.CorrelationCalcComboBox.Size = new System.Drawing.Size(169, 21);
+      this.CorrelationCalcComboBox.TabIndex = 0;
+      this.CorrelationCalcComboBox.SelectedIndexChanged += new System.EventHandler(this.CorrelationCalcComboBox_SelectedIndexChanged);
+      // 
+      // CorrelationCalcLabel
+      // 
+      this.CorrelationCalcLabel.AutoSize = true;
+      this.CorrelationCalcLabel.Location = new System.Drawing.Point(3, 6);
+      this.CorrelationCalcLabel.Name = "CorrelationCalcLabel";
+      this.CorrelationCalcLabel.Size = new System.Drawing.Size(110, 13);
+      this.CorrelationCalcLabel.TabIndex = 1;
+      this.CorrelationCalcLabel.Text = "Correlation Calculator:";
+      // 
+      // PartitionLabel
+      // 
+      this.PartitionLabel.AutoSize = true;
+      this.PartitionLabel.Location = new System.Drawing.Point(294, 6);
+      this.PartitionLabel.Name = "PartitionLabel";
+      this.PartitionLabel.Size = new System.Drawing.Size(48, 13);
+      this.PartitionLabel.TabIndex = 2;
+      this.PartitionLabel.Text = "Partition:";
+      // 
+      // PartitionComboBox
+      // 
+      this.PartitionComboBox.FormattingEnabled = true;
+      this.PartitionComboBox.Location = new System.Drawing.Point(348, 3);
+      this.PartitionComboBox.Name = "PartitionComboBox";
+      this.PartitionComboBox.Size = new System.Drawing.Size(145, 21);
+      this.PartitionComboBox.TabIndex = 3;
+      this.PartitionComboBox.SelectedIndexChanged += new System.EventHandler(this.PartitionComboBox_SelectedIndexChanged);
+      // 
+      // ExtendedHeatMap
+      // 
+      this.ExtendedHeatMap.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+                  | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.ExtendedHeatMap.Caption = "ExtendedHeatMap View";
+      this.ExtendedHeatMap.Content = null;
+      this.ExtendedHeatMap.Location = new System.Drawing.Point(3, 30);
+      this.ExtendedHeatMap.Name = "ExtendedHeatMap";
+      this.ExtendedHeatMap.ReadOnly = false;
+      this.ExtendedHeatMap.Size = new System.Drawing.Size(627, 275);
+      this.ExtendedHeatMap.TabIndex = 4;
+      // 
+      // HeatMapProgressBar
+      // 
+      this.HeatMapProgressBar.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.HeatMapProgressBar.Location = new System.Drawing.Point(499, 3);
+      this.HeatMapProgressBar.Name = "HeatMapProgressBar";
+      this.HeatMapProgressBar.RightToLeft = System.Windows.Forms.RightToLeft.No;
+      this.HeatMapProgressBar.Size = new System.Drawing.Size(131, 21);
+      this.HeatMapProgressBar.TabIndex = 5;
+      this.HeatMapProgressBar.Visible = false;
+      // 
+      // CorrelationHeatMapView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.HeatMapProgressBar);
+      this.Controls.Add(this.PartitionComboBox);
+      this.Controls.Add(this.PartitionLabel);
+      this.Controls.Add(this.CorrelationCalcLabel);
+      this.Controls.Add(this.CorrelationCalcComboBox);
+      this.Controls.Add(this.ExtendedHeatMap);
+      this.Name = "CorrelationHeatMapView";
+      this.Size = new System.Drawing.Size(633, 308);
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    protected System.Windows.Forms.ComboBox CorrelationCalcComboBox;
+    protected System.Windows.Forms.Label CorrelationCalcLabel;
+    protected System.Windows.Forms.Label PartitionLabel;
+    protected System.Windows.Forms.ComboBox PartitionComboBox;
+    protected HeuristicLab.Problems.DataAnalysis.Views.ExtendedHeatMapView ExtendedHeatMap;
+    private System.Windows.Forms.ProgressBar HeatMapProgressBar;
+  }
+}
Index: /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/CorrelationHeatMapView.cs
===================================================================
--- /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/CorrelationHeatMapView.cs	(revision 8276)
+++ /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/CorrelationHeatMapView.cs	(revision 8276)
@@ -0,0 +1,81 @@
+﻿#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.ComponentModel;
+using System.Windows.Forms;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("CorrelationHeatMap View")]
+  [Content(typeof(ExtendedHeatMap), true)]
+  public partial class CorrelationHeatMapView : ItemView {
+
+    public new ExtendedHeatMap Content {
+      get { return (ExtendedHeatMap)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public CorrelationHeatMapView() {
+      InitializeComponent();
+    }
+
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.ProgressCalculation += new DataAnalysis.ExtendedHeatMap.ProgressCalculationHandler(Content_ProgressCalculation);
+    }
+
+    protected void Content_ProgressCalculation(object sender, ProgressChangedEventArgs e) {
+      if (!HeatMapProgressBar.Visible && e.ProgressPercentage != HeatMapProgressBar.Maximum) {
+        HeatMapProgressBar.Show();
+      } else if (e.ProgressPercentage == HeatMapProgressBar.Maximum) {
+        HeatMapProgressBar.Hide();
+      }
+      HeatMapProgressBar.Value = e.ProgressPercentage;
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      ExtendedHeatMap.Content = Content;
+      if (Content != null) {
+        CorrelationCalcComboBox.DataSource = Content.CorrelationCalculators;
+        PartitionComboBox.DataSource = Content.Partitions;
+      }
+    }
+
+    private void CorrelationCalcComboBox_SelectedIndexChanged(object sender, System.EventArgs e) {
+      CalculateHeatMap();
+    }
+
+    private void PartitionComboBox_SelectedIndexChanged(object sender, System.EventArgs e) {
+      CalculateHeatMap();
+    }
+
+    private void CalculateHeatMap() {
+      string calc = (string)CorrelationCalcComboBox.SelectedItem;
+      string partition = (string)PartitionComboBox.SelectedItem;
+      if (calc != null && partition != null) {
+        Content.Recalculate(calc, partition);
+        base.OnContentChanged();
+      }
+    }
+  }
+}
Index: /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/ExtendedHeatMapView.Designer.cs
===================================================================
--- /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/ExtendedHeatMapView.Designer.cs	(revision 8276)
+++ /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/ExtendedHeatMapView.Designer.cs	(revision 8276)
@@ -0,0 +1,32 @@
+﻿namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class ExtendedHeatMapView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      components = new System.ComponentModel.Container();
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+    }
+
+    #endregion
+  }
+}
Index: /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/ExtendedHeatMapView.cs
===================================================================
--- /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/ExtendedHeatMapView.cs	(revision 8276)
+++ /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/ExtendedHeatMapView.cs	(revision 8276)
@@ -0,0 +1,96 @@
+﻿#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 System.Windows.Forms;
+using HeuristicLab.Analysis.Views;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("ExtendedHeatMap View")]
+  [Content(typeof(ExtendedHeatMap), false)]
+  public partial class ExtendedHeatMapView : HeatMapView {
+    public new ExtendedHeatMap Content {
+      get { return (ExtendedHeatMap)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public ExtendedHeatMapView() {
+      InitializeComponent();
+      chart.ChartAreas[0].AxisX.Title = "";
+      chart.ChartAreas[0].AxisY.Title = "";
+    }
+
+    protected override void OnResize(EventArgs e) {
+      base.OnResize(e);
+      SetMarkerSize();
+    }
+
+    private void SetMarkerSize() {
+      if (chart != null && chart.ChartAreas.Count > 0 && chart.Series.Count > 0) {
+        int height = (chart.Size.Height / 4) * 3;
+        double max = chart.ChartAreas[0].AxisY.Maximum;
+        chart.Series[0].MarkerSize = (int)Math.Floor(height / max);
+      }
+    }
+
+    protected override void UpdatePoints() {
+      base.UpdatePoints();
+      UpdateLabels();
+      SetMarkerSize();
+    }
+
+    protected virtual void UpdateLabels() {
+      chart.ChartAreas[0].AxisX.CustomLabels.Clear();
+      IList<string> names = Content.ColumnNames.ToList();
+      for (int i = 0; i < names.Count; i++) {
+        chart.ChartAreas[0].AxisX.CustomLabels.Add(i + 0.5, i + 1.5, names[i]);
+        chart.ChartAreas[0].AxisY.CustomLabels.Add(i + 0.5, i + 1.5, names[i]);
+      }
+    }
+
+    protected override void DeregisterContentEvents() {
+      Content.ColumnNamesChanged -= new EventHandler(Content_ColumnNamesChanged);
+      Content.Reset -= new EventHandler(Content_Reset);
+      base.DeregisterContentEvents();
+    }
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      // only column names event is required. Row names are the same.
+      Content.ColumnNamesChanged += new EventHandler(Content_ColumnNamesChanged);
+      Content.Reset += new EventHandler(Content_Reset);
+    }
+
+    protected virtual void Content_ColumnNamesChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_ColumnNamesChanged), sender, e);
+      else {
+        UpdateLabels();
+      }
+    }
+
+    protected void Content_Reset(object sender, EventArgs e) {
+      UpdatePoints();
+    }
+  }
+}
Index: /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj
===================================================================
--- /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj	(revision 8275)
+++ /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj	(revision 8276)
@@ -93,4 +93,6 @@
   </PropertyGroup>
   <ItemGroup>
+    <Reference Include="HeuristicLab.Analysis-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Analysis.Views-3.3, Version=3.3.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">
       <Private>False</Private>
@@ -170,4 +172,10 @@
       <DependentUpon>ClassificationEnsembleSolutionModelView.cs</DependentUpon>
     </Compile>
+    <Compile Include="CorrelationHeatMapView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="CorrelationHeatMapView.Designer.cs">
+      <DependentUpon>CorrelationHeatMapView.cs</DependentUpon>
+    </Compile>
     <Compile Include="DataAnalysisSolutionEvaluationView.cs">
       <SubType>UserControl</SubType>
@@ -175,4 +183,10 @@
     <Compile Include="DataAnalysisSolutionEvaluationView.Designer.cs">
       <DependentUpon>DataAnalysisSolutionEvaluationView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="ExtendedHeatMapView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="ExtendedHeatMapView.Designer.cs">
+      <DependentUpon>ExtendedHeatMapView.cs</DependentUpon>
     </Compile>
     <Compile Include="Plugin.cs" />
Index: /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionErrorCharacteristicsCurveView.Designer.cs
===================================================================
--- /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionErrorCharacteristicsCurveView.Designer.cs	(revision 8275)
+++ /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionErrorCharacteristicsCurveView.Designer.cs	(revision 8276)
@@ -36,6 +36,6 @@
       // 
       this.chart.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
-            | System.Windows.Forms.AnchorStyles.Left)
-            | System.Windows.Forms.AnchorStyles.Right)));
+                  | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
       chartArea1.Name = "ChartArea1";
       this.chart.ChartAreas.Add(chartArea1);
@@ -73,5 +73,4 @@
       // RegressionSolutionErrorCharacteristicsCurveView
       // 
-      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
       this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
       this.Controls.Add(this.label1);
Index: /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionErrorCharacteristicsCurveView.cs
===================================================================
--- /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionErrorCharacteristicsCurveView.cs	(revision 8275)
+++ /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionErrorCharacteristicsCurveView.cs	(revision 8276)
@@ -26,5 +26,4 @@
 using System.Windows.Forms.DataVisualization.Charting;
 using HeuristicLab.MainForm;
-using HeuristicLab.MainForm.WindowsForms;
 
 namespace HeuristicLab.Problems.DataAnalysis.Views {
@@ -32,5 +31,4 @@
   [Content(typeof(IRegressionSolution))]
   public partial class RegressionSolutionErrorCharacteristicsCurveView : DataAnalysisSolutionEvaluationView {
-    private IRegressionSolution constantModel;
     protected const string TrainingSamples = "Training";
     protected const string TestSamples = "Test";
@@ -103,6 +101,6 @@
       if (Content == null) return;
 
+      var constantModel = CreateConstantModel();
       var originalValues = GetOriginalValues().ToList();
-      constantModel = CreateConstantModel();
       var baselineEstimatedValues = GetEstimatedValues(constantModel);
       var baselineResiduals = GetResiduals(originalValues, baselineEstimatedValues);
@@ -117,4 +115,5 @@
       baselineSeries.ToolTip = "Area over Curve: " + CalculateAreaOverCurve(baselineSeries);
       baselineSeries.Tag = constantModel;
+      baselineSeries.LegendToolTip = "Double-click to open model";
       chart.Series.Add(baselineSeries);
 
@@ -131,4 +130,5 @@
       UpdateSeries(estimatedValues, solutionSeries);
       solutionSeries.ToolTip = "Area over Curve: " + CalculateAreaOverCurve(solutionSeries);
+      solutionSeries.LegendToolTip = "Double-click to open model";
       chart.Series.Add(solutionSeries);
     }
@@ -169,8 +169,8 @@
       switch (cmbSamples.SelectedItem.ToString()) {
         case TrainingSamples:
-          originalValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndizes);
+          originalValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices);
           break;
         case TestSamples:
-          originalValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TestIndizes);
+          originalValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TestIndices);
           break;
         case AllSamples:
@@ -201,9 +201,4 @@
     }
 
-    protected IEnumerable<double> GetbaselineEstimatedValues(IEnumerable<double> originalValues) {
-      double averageTrainingTarget = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndizes).Average();
-      return Enumerable.Repeat(averageTrainingTarget, originalValues.Count());
-    }
-
     protected virtual List<double> GetResiduals(IEnumerable<double> originalValues, IEnumerable<double> estimatedValues) {
       return originalValues.Zip(estimatedValues, (x, y) => Math.Abs(x - y)).ToList();
@@ -239,5 +234,5 @@
 
     private IRegressionSolution CreateConstantModel() {
-      double averageTrainingTarget = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndizes).Average();
+      double averageTrainingTarget = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices).Average();
       var solution = new ConstantRegressionModel(averageTrainingTarget).CreateRegressionSolution(ProblemData);
       solution.Name = "Baseline";
@@ -248,8 +243,9 @@
     private void chart_MouseMove(object sender, MouseEventArgs e) {
       HitTestResult result = chart.HitTest(e.X, e.Y);
-      if (result.ChartElementType == ChartElementType.LegendItem)
+      if (result.ChartElementType == ChartElementType.LegendItem) {
         Cursor = Cursors.Hand;
-      else
+      } else {
         Cursor = Cursors.Default;
+      }
     }
   }
Index: /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionEstimatedValuesView.cs
===================================================================
--- /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionEstimatedValuesView.cs	(revision 8275)
+++ /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionEstimatedValuesView.cs	(revision 8276)
@@ -93,10 +93,10 @@
           var estimated_test = Content.EstimatedTestValues.GetEnumerator();
 
-          foreach (var row in Content.ProblemData.TrainingIndizes) {
+          foreach (var row in Content.ProblemData.TrainingIndices) {
             estimated_training.MoveNext();
             values[row, 3] = estimated_training.Current.ToString();
           }
 
-          foreach (var row in Content.ProblemData.TestIndizes) {
+          foreach (var row in Content.ProblemData.TestIndices) {
             estimated_test.MoveNext();
             values[row, 4] = estimated_test.Current.ToString();
Index: /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionLineChartView.cs
===================================================================
--- /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionLineChartView.cs	(revision 8275)
+++ /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionLineChartView.cs	(revision 8276)
@@ -72,5 +72,5 @@
         this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].ChartType = SeriesChartType.FastLine;
         this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].EmptyPointStyle.Color = this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].Color;
-        this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].Points.DataBindXY(Content.ProblemData.TrainingIndizes.ToArray(), Content.EstimatedTrainingValues.ToArray());
+        this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].Points.DataBindXY(Content.ProblemData.TrainingIndices.ToArray(), Content.EstimatedTrainingValues.ToArray());
         this.InsertEmptyPoints(this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME]);
         this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].Tag = Content;
@@ -79,15 +79,15 @@
         this.chart.Series[ESTIMATEDVALUES_TEST_SERIES_NAME].LegendText = ESTIMATEDVALUES_TEST_SERIES_NAME;
         this.chart.Series[ESTIMATEDVALUES_TEST_SERIES_NAME].ChartType = SeriesChartType.FastLine;
-        this.chart.Series[ESTIMATEDVALUES_TEST_SERIES_NAME].Points.DataBindXY(Content.ProblemData.TestIndizes.ToArray(), Content.EstimatedTestValues.ToArray());
+        this.chart.Series[ESTIMATEDVALUES_TEST_SERIES_NAME].Points.DataBindXY(Content.ProblemData.TestIndices.ToArray(), Content.EstimatedTestValues.ToArray());
         this.InsertEmptyPoints(this.chart.Series[ESTIMATEDVALUES_TEST_SERIES_NAME]);
         this.chart.Series[ESTIMATEDVALUES_TEST_SERIES_NAME].Tag = Content;
         // series of remaining points
-        int[] allIndizes = Enumerable.Range(0, Content.ProblemData.Dataset.Rows).Except(Content.ProblemData.TrainingIndizes).Except(Content.ProblemData.TestIndizes).ToArray();
+        int[] allIndices = Enumerable.Range(0, Content.ProblemData.Dataset.Rows).Except(Content.ProblemData.TrainingIndices).Except(Content.ProblemData.TestIndices).ToArray();
         var estimatedValues = Content.EstimatedValues.ToArray();
-        List<double> allEstimatedValues = allIndizes.Select(index => estimatedValues[index]).ToList();
+        List<double> allEstimatedValues = allIndices.Select(index => estimatedValues[index]).ToList();
         this.chart.Series.Add(ESTIMATEDVALUES_ALL_SERIES_NAME);
         this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].LegendText = ESTIMATEDVALUES_ALL_SERIES_NAME;
         this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].ChartType = SeriesChartType.FastLine;
-        this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].Points.DataBindXY(allIndizes, allEstimatedValues);
+        this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].Points.DataBindXY(allIndices, allEstimatedValues);
         this.InsertEmptyPoints(this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME]);
         this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].Tag = Content;
@@ -170,8 +170,8 @@
 
       int[] attr = new int[Content.ProblemData.Dataset.Rows + 1]; // add a virtual last row that is again empty to simplify loop further down
-      foreach (var row in Content.ProblemData.TrainingIndizes) {
+      foreach (var row in Content.ProblemData.TrainingIndices) {
         attr[row] += 1;
       }
-      foreach (var row in Content.ProblemData.TestIndizes) {
+      foreach (var row in Content.ProblemData.TestIndices) {
         attr[row] += 2;
       }
@@ -223,22 +223,22 @@
         string targetVariableName = Content.ProblemData.TargetVariable;
 
-        IEnumerable<int> indizes = null;
+        IEnumerable<int> indices = null;
         IEnumerable<double> predictedValues = null;
         switch (series.Name) {
           case ESTIMATEDVALUES_ALL_SERIES_NAME:
-            indizes = Enumerable.Range(0, Content.ProblemData.Dataset.Rows).Except(Content.ProblemData.TrainingIndizes).Except(Content.ProblemData.TestIndizes).ToArray();
+            indices = Enumerable.Range(0, Content.ProblemData.Dataset.Rows).Except(Content.ProblemData.TrainingIndices).Except(Content.ProblemData.TestIndices).ToArray();
             var estimatedValues = Content.EstimatedValues.ToArray();
-            predictedValues = indizes.Select(index => estimatedValues[index]).ToList();
+            predictedValues = indices.Select(index => estimatedValues[index]).ToList();
             break;
           case ESTIMATEDVALUES_TRAINING_SERIES_NAME:
-            indizes = Content.ProblemData.TrainingIndizes.ToArray();
+            indices = Content.ProblemData.TrainingIndices.ToArray();
             predictedValues = Content.EstimatedTrainingValues.ToArray();
             break;
           case ESTIMATEDVALUES_TEST_SERIES_NAME:
-            indizes = Content.ProblemData.TestIndizes.ToArray();
+            indices = Content.ProblemData.TestIndices.ToArray();
             predictedValues = Content.EstimatedTestValues.ToArray();
             break;
         }
-        series.Points.DataBindXY(indizes, predictedValues);
+        series.Points.DataBindXY(indices, predictedValues);
         this.InsertEmptyPoints(series);
         chart.Legends[series.Legend].ForeColor = Color.Black;
Index: /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionResidualHistogram.Designer.cs
===================================================================
--- /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionResidualHistogram.Designer.cs	(revision 8275)
+++ /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionResidualHistogram.Designer.cs	(revision 8276)
@@ -41,5 +41,5 @@
       this.chart.Location = new System.Drawing.Point(0, 0);
       this.chart.Name = "chart";
-      this.chart.Size = new System.Drawing.Size(358, 225);
+      this.chart.Size = new System.Drawing.Size(289, 220);
       this.chart.TabIndex = 0;
       this.chart.CustomizeLegend += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.CustomizeLegendEventArgs>(this.chart_CustomizeLegend);
@@ -50,5 +50,4 @@
       // 
       this.AllowDrop = true;
-      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
       this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
       this.Controls.Add(this.chart);
Index: /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionResidualHistogram.cs
===================================================================
--- /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionResidualHistogram.cs	(revision 8275)
+++ /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionResidualHistogram.cs	(revision 8276)
@@ -39,16 +39,7 @@
     protected const string TEST_SAMPLES = "Test samples";
     /// <summary>
-    /// used to reduce code duplication
-    /// </summary>
-    protected static string[] ALL_SERIES = new string[] { ALL_SAMPLES, TRAINING_SAMPLES, TEST_SAMPLES };
-    /// <summary>
     /// approximate amount of bins 
     /// </summary>
     protected const double bins = 25;
-    /// <summary>
-    ///  keeps for all series a list for every bin with the position of the bin, the relative frequency of the
-    ///  residuals and the beginning and the end of the interval of the bin
-    ///  </summary>
-    protected Dictionary<string, List<List<double>>> relativeFrequencies;
     #endregion
 
@@ -61,6 +52,5 @@
       : base() {
       InitializeComponent();
-      relativeFrequencies = new Dictionary<string, List<List<double>>>();
-      foreach (string series in ALL_SERIES) {
+      foreach (string series in new List<String>() { ALL_SAMPLES, TRAINING_SAMPLES, TEST_SAMPLES }) {
         chart.Series.Add(series);
         chart.Series[series].LegendText = series;
@@ -71,5 +61,4 @@
         chart.Series[series].BorderColor = Color.Black;
         chart.Series[series].ToolTip = series + " Y = #VALY from #CUSTOMPROPERTY(from) to #CUSTOMPROPERTY(to)";
-        relativeFrequencies[series] = new List<List<double>>();
       }
       //configure axis 
@@ -87,24 +76,22 @@
 
     private void RedrawChart() {
-      foreach (string series in ALL_SERIES) {
-        chart.Series[series].Points.Clear();
-        relativeFrequencies[series].Clear();
+      foreach (Series series in chart.Series) {
+        series.Points.Clear();
       }
       if (Content != null) {
-        Dictionary<string, List<double>> residuals = CalculateResiduals();
-        double realMax = Math.Max(Math.Abs(residuals[ALL_SAMPLES].Min()), Math.Abs(residuals[ALL_SAMPLES].Max()));
-        double roundedMax = HumanRoundMax(realMax);
-        double intervalWidth = (roundedMax * 2.0) / bins;
-        intervalWidth = HumanRoundMax(intervalWidth);
-        // sets roundedMax to a value, so that zero will be in the middle of the x axis
-        double help = realMax / intervalWidth;
-        help = help % 1 < 0.5 ? (int)help : (int)help + 1;
-        roundedMax = help * intervalWidth;
-
-        foreach (string series in ALL_SERIES) {
-          CalculateFrequencies(residuals[series], series, roundedMax, intervalWidth);
-          if (!series.Equals(ALL_SAMPLES))
-            ShowValues(chart.Series[series], relativeFrequencies[series]);
+        List<double> residuals = CalculateResiduals(Content);
+
+        double max = 0.0;
+        foreach (Series series in chart.Series) {
+          CalculateFrequencies(residuals, series);
+          double seriesMax = series.Points.Select(p => p.YValues.First()).Max();
+          max = max < seriesMax ? seriesMax : max;
         }
+
+        // ALL_SAMPLES has to be calculated to know its highest frequency, but it is not shown in the beginning
+        chart.Series.First(s => s.Name.Equals(ALL_SAMPLES)).Points.Clear();
+
+        double roundedMax, intervalWidth;
+        CalculateResidualParameters(residuals, out roundedMax, out intervalWidth);
 
         ChartArea chartArea = chart.ChartAreas[0];
@@ -112,7 +99,5 @@
         chartArea.AxisX.Maximum = roundedMax + intervalWidth;
         // get the highest frequency of a residual of any series
-        chartArea.AxisY.Maximum = (from series in relativeFrequencies.Values
-                                   select (from residual in series
-                                           select residual.ElementAt(1)).Max()).Max();
+        chartArea.AxisY.Maximum = max;
         if (chartArea.AxisY.Maximum < 0.1) {
           chartArea.AxisY.Interval = 0.01;
@@ -132,38 +117,69 @@
     }
 
-    private Dictionary<string, List<double>> CalculateResiduals() {
-      Dictionary<string, List<double>> residuals = new Dictionary<string, List<double>>();
-
-      foreach (string series in ALL_SERIES) {
-        residuals[series] = new List<double>();
-      }
+    private List<double> CalculateResiduals(IRegressionSolution solution) {
+      List<double> residuals = new List<double>();
+
+      IRegressionProblemData problemdata = solution.ProblemData;
+      List<double> targetValues = problemdata.Dataset.GetDoubleValues(Content.ProblemData.TargetVariable).ToList();
+      List<double> estimatedValues = solution.EstimatedValues.ToList();
+
+      for (int i = 0; i < solution.ProblemData.Dataset.Rows; i++) {
+        double residual = estimatedValues[i] - targetValues[i];
+        residuals.Add(residual);
+      }
+      return residuals;
+    }
+
+    private void CalculateFrequencies(List<double> residualValues, Series series) {
+      double roundedMax, intervalWidth;
+      CalculateResidualParameters(residualValues, out roundedMax, out intervalWidth);
+
+      IEnumerable<double> relevantResiduals = residualValues;
       IRegressionProblemData problemdata = Content.ProblemData;
-      List<double> targetValues = problemdata.Dataset.GetDoubleValues(Content.ProblemData.TargetVariable).ToList();
-      List<double> estimatedValues = Content.EstimatedValues.ToList();
-
-      for (int i = 0; i < Content.ProblemData.Dataset.Rows; i++) {
-        double residual = estimatedValues[i] - targetValues[i];
-        residuals[ALL_SAMPLES].Add(residual);
-        if (i >= problemdata.TrainingPartition.Start && i < problemdata.TrainingPartition.End)
-          residuals[TRAINING_SAMPLES].Add(residual);
-        if (i >= problemdata.TestPartition.Start && i < problemdata.TestPartition.End)
-          residuals[TEST_SAMPLES].Add(residual);
-      }
-      return residuals;
-    }
-
-    private void CalculateFrequencies(List<double> residualValues, string series, double max, double intervalWidth) {
+      if (series.Name.Equals(TRAINING_SAMPLES)) {
+        relevantResiduals = residualValues.Skip(problemdata.TrainingPartition.Start).Take(problemdata.TrainingPartition.Size);
+      } else if (series.Name.Equals(TEST_SAMPLES)) {
+        relevantResiduals = residualValues.Skip(problemdata.TestPartition.Start).Take(problemdata.TestPartition.Size);
+      }
+
       double intervalCenter = intervalWidth / 2.0;
-      double sampleCount = residualValues.Count();
-      double current = -max;
+      double sampleCount = relevantResiduals.Count();
+      double current = -roundedMax;
+      DataPointCollection seriesPoints = series.Points;
 
       for (int i = 0; i <= bins; i++) {
-        IEnumerable<double> help = residualValues.Where(x => x >= (current - intervalCenter) && x < (current + intervalCenter));
-        relativeFrequencies[series].Add(new List<double>() { current, help.Count() / sampleCount, current - intervalCenter, current + intervalCenter });
+        IEnumerable<double> help = relevantResiduals.Where(x => x >= (current - intervalCenter) && x < (current + intervalCenter));
+        seriesPoints.AddXY(current, help.Count() / sampleCount);
+        seriesPoints[seriesPoints.Count - 1]["from"] = (current - intervalCenter).ToString();
+        seriesPoints[seriesPoints.Count - 1]["to"] = (current + intervalCenter).ToString();
         current += intervalWidth;
       }
     }
 
-    private double HumanRoundMax(double max) {
+    private void ToggleSeriesData(Series series) {
+      if (series.Points.Count > 0) {  //checks if series is shown
+        if (chart.Series.Any(s => s != series && s.Points.Count > 0)) {
+          series.Points.Clear();
+        }
+      } else if (Content != null) {
+        List<double> residuals = CalculateResiduals(Content);
+        CalculateFrequencies(residuals, series);
+        chart.Legends[series.Legend].ForeColor = Color.Black;
+        chart.Refresh();
+      }
+    }
+
+    private static void CalculateResidualParameters(List<double> residuals, out double roundedMax, out double intervalWidth) {
+      double realMax = Math.Max(Math.Abs(residuals.Min()), Math.Abs(residuals.Max()));
+      roundedMax = HumanRoundMax(realMax);
+      intervalWidth = (roundedMax * 2.0) / bins;
+      intervalWidth = HumanRoundMax(intervalWidth);
+      // sets roundedMax to a value, so that zero will be in the middle of the x axis
+      double help = realMax / intervalWidth;
+      help = help % 1 < 0.5 ? (int)help : (int)help + 1;
+      roundedMax = help * intervalWidth;
+    }
+
+    private static double HumanRoundMax(double max) {
       double base10;
       if (max > 0) base10 = Math.Pow(10.0, Math.Floor(Math.Log10(max)));
@@ -216,25 +232,4 @@
     }
     #endregion
-
-    private void ToggleSeriesData(Series series) {
-      if (series.Points.Count > 0) {  //checks if series is shown
-        if (chart.Series.Any(s => s != series && s.Points.Count > 0)) {
-          series.Points.Clear();
-        }
-      } else if (Content != null) {
-        ShowValues(series, relativeFrequencies[series.Name]);
-        chart.Legends[series.Legend].ForeColor = Color.Black;
-        chart.Refresh();
-      }
-    }
-    private void ShowValues(Series series, List<List<double>> relativeSeriesFrequencies) {
-      DataPointCollection seriesPoints = series.Points;
-
-      foreach (var valueList in relativeSeriesFrequencies) {
-        seriesPoints.AddXY(valueList[0], valueList[1]);
-        seriesPoints[seriesPoints.Count - 1]["from"] = valueList[2].ToString();
-        seriesPoints[seriesPoints.Count - 1]["to"] = valueList[3].ToString();
-      }
-    }
   }
 }
Index: /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionScatterPlotView.cs
===================================================================
--- /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionScatterPlotView.cs	(revision 8275)
+++ /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionScatterPlotView.cs	(revision 8276)
@@ -148,8 +148,8 @@
         if (this.chart.Series[TRAINING_SERIES].Points.Count > 0)
           this.chart.Series[TRAINING_SERIES].Points.DataBindXY(Content.EstimatedTrainingValues.ToArray(), "",
-            dataset.GetDoubleValues(targetVariableName, Content.ProblemData.TrainingIndizes).ToArray(), "");
+            dataset.GetDoubleValues(targetVariableName, Content.ProblemData.TrainingIndices).ToArray(), "");
         if (this.chart.Series[TEST_SERIES].Points.Count > 0)
           this.chart.Series[TEST_SERIES].Points.DataBindXY(Content.EstimatedTestValues.ToArray(), "",
-           dataset.GetDoubleValues(targetVariableName, Content.ProblemData.TestIndizes).ToArray(), "");
+           dataset.GetDoubleValues(targetVariableName, Content.ProblemData.TestIndices).ToArray(), "");
 
         double max = Content.EstimatedTrainingValues.Concat(Content.EstimatedTestValues.Concat(Content.EstimatedValues.Concat(dataset.GetDoubleValues(targetVariableName)))).Max();
@@ -196,9 +196,9 @@
           case TRAINING_SERIES:
             predictedValues = Content.EstimatedTrainingValues.ToArray();
-            targetValues = Content.ProblemData.Dataset.GetDoubleValues(targetVariableName, Content.ProblemData.TrainingIndizes).ToArray();
+            targetValues = Content.ProblemData.Dataset.GetDoubleValues(targetVariableName, Content.ProblemData.TrainingIndices).ToArray();
             break;
           case TEST_SERIES:
             predictedValues = Content.EstimatedTestValues.ToArray();
-            targetValues = Content.ProblemData.Dataset.GetDoubleValues(targetVariableName, Content.ProblemData.TestIndizes).ToArray();
+            targetValues = Content.ProblemData.Dataset.GetDoubleValues(targetVariableName, Content.ProblemData.TestIndices).ToArray();
             break;
         }
Index: /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/DataAnalysisSolutionView.cs
===================================================================
--- /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/DataAnalysisSolutionView.cs	(revision 8275)
+++ /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/DataAnalysisSolutionView.cs	(revision 8276)
@@ -137,4 +137,14 @@
     }
 
+    protected override void showDetailsCheckBox_CheckedChanged(object sender, EventArgs e) {
+      if (showDetailsCheckBox.Checked && itemsListView.SelectedItems.Count == 1 && itemsListView.SelectedItems[0].Tag is Type) {
+        Type viewType = (Type)itemsListView.SelectedItems[0].Tag;
+        viewHost.ViewType = viewType;
+        viewHost.Content = Content;
+        splitContainer.Panel2Collapsed = false;
+        detailsGroupBox.Enabled = true;
+      } else base.showDetailsCheckBox_CheckedChanged(sender, e);
+    }
+
     #region drag and drop
     protected override void itemsListView_DragEnter(object sender, DragEventArgs e) {
Index: /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj
===================================================================
--- /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj	(revision 8275)
+++ /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj	(revision 8276)
@@ -155,4 +155,5 @@
     <Compile Include="Implementation\Clustering\ClusteringProblemData.cs" />
     <Compile Include="Implementation\Clustering\ClusteringSolution.cs" />
+    <Compile Include="Implementation\ExtendedHeatMap.cs" />
     <Compile Include="Implementation\Regression\ConstantRegressionModel.cs" />
     <Compile Include="Implementation\Regression\ConstantRegressionSolution.cs" />
@@ -213,4 +214,5 @@
     <Compile Include="OnlineCalculators\OnlinePearsonsRSquaredCalculator.cs" />
     <Compile Include="Implementation\Regression\RegressionSolution.cs" />
+    <Compile Include="OnlineCalculators\SpearmansRankCorrelationCoefficientCalculator.cs" />
     <Compile Include="Plugin.cs" />
     <Compile Include="Implementation\Classification\ThresholdCalculators\AccuracyMaximizationThresholdCalculator.cs" />
Index: /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleSolution.cs
===================================================================
--- /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleSolution.cs	(revision 8275)
+++ /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleSolution.cs	(revision 8276)
@@ -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/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationProblemData.cs
===================================================================
--- /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationProblemData.cs	(revision 8275)
+++ /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationProblemData.cs	(revision 8276)
@@ -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/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolution.cs
===================================================================
--- /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolution.cs	(revision 8275)
+++ /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolution.cs	(revision 8276)
@@ -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/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolutionBase.cs
===================================================================
--- /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolutionBase.cs	(revision 8275)
+++ /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolutionBase.cs	(revision 8276)
@@ -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/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationSolution.cs
===================================================================
--- /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationSolution.cs	(revision 8275)
+++ /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationSolution.cs	(revision 8276)
@@ -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/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationSolutionBase.cs
===================================================================
--- /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationSolutionBase.cs	(revision 8275)
+++ /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationSolutionBase.cs	(revision 8276)
@@ -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/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ThresholdCalculators/AccuracyMaximizationThresholdCalculator.cs
===================================================================
--- /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ThresholdCalculators/AccuracyMaximizationThresholdCalculator.cs	(revision 8275)
+++ /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ThresholdCalculators/AccuracyMaximizationThresholdCalculator.cs	(revision 8276)
@@ -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/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringSolution.cs
===================================================================
--- /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringSolution.cs	(revision 8275)
+++ /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringSolution.cs	(revision 8276)
@@ -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/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisProblemData.cs
===================================================================
--- /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisProblemData.cs	(revision 8275)
+++ /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisProblemData.cs	(revision 8276)
@@ -23,5 +23,4 @@
 using System.Collections.Generic;
 using System.Linq;
-using HeuristicLab.Analysis;
 using HeuristicLab.Collections;
 using HeuristicLab.Common;
@@ -53,6 +52,6 @@
       get { return (IFixedValueParameter<IntRange>)Parameters[TestPartitionParameterName]; }
     }
-    public IFixedValueParameter<HeatMap> DatasetHeatMapParameter {
-      get { return (IFixedValueParameter<HeatMap>)Parameters[DatasetHeatMapParameterName]; }
+    public IFixedValueParameter<ExtendedHeatMap> DatasetHeatMapParameter {
+      get { return (IFixedValueParameter<ExtendedHeatMap>)Parameters[DatasetHeatMapParameterName]; }
     }
     #endregion
@@ -79,9 +78,9 @@
       get { return TestPartitionParameter.Value; }
     }
-    public HeatMap DatasetHeatMap {
+    public ExtendedHeatMap DatasetHeatMap {
       get { return DatasetHeatMapParameter.Value; }
     }
 
-    public virtual IEnumerable<int> TrainingIndizes {
+    public virtual IEnumerable<int> TrainingIndices {
       get {
         return Enumerable.Range(TrainingPartition.Start, Math.Max(0, TrainingPartition.End - TrainingPartition.Start))
@@ -89,5 +88,5 @@
       }
     }
-    public virtual IEnumerable<int> TestIndizes {
+    public virtual IEnumerable<int> TestIndices {
       get {
         return Enumerable.Range(TestPartition.Start, Math.Max(0, TestPartition.End - TestPartition.Start))
@@ -140,26 +139,8 @@
       Parameters.Add(new FixedValueParameter<IntRange>(TrainingPartitionParameterName, "", new IntRange(trainingPartitionStart, trainingPartitionEnd)));
       Parameters.Add(new FixedValueParameter<IntRange>(TestPartitionParameterName, "", new IntRange(testPartitionStart, testPartitionEnd)));
-      Parameters.Add(new FixedValueParameter<HeatMap>(DatasetHeatMapParameterName, "", CalculateHeatMap(dataset)));
+      Parameters.Add(new FixedValueParameter<ExtendedHeatMap>(DatasetHeatMapParameterName, "", new ExtendedHeatMap(this)));
 
       ((ValueParameter<Dataset>)DatasetParameter).ReactOnValueToStringChangedAndValueItemImageChanged = false;
       RegisterEventHandlers();
-    }
-
-    private HeatMap CalculateHeatMap(Dataset dataset) {
-      IList<string> doubleVariableNames = dataset.DoubleVariables.ToList();
-      OnlineCalculatorError error;
-      int length = doubleVariableNames.Count;
-      double[,] elements = new double[length, length];
-
-      for (int i = 0; i < length; i++) {
-        for (int j = 0; j < i + 1; j++) {
-          elements[i, j] = OnlinePearsonsRSquaredCalculator.Calculate(dataset.GetDoubleValues(doubleVariableNames[length - 1 - i]), dataset.GetDoubleValues(doubleVariableNames[j]), out error);
-          elements[j, i] = elements[i, j];
-          if (!error.Equals(OnlineCalculatorError.None)) {
-            throw new ArgumentException("Calculator returned " + error);
-          }
-        }
-      }
-      return new HeatMap(elements, "Hoeffdings Dependence");
     }
 
Index: /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/ExtendedHeatMap.cs
===================================================================
--- /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/ExtendedHeatMap.cs	(revision 8276)
+++ /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/ExtendedHeatMap.cs	(revision 8276)
@@ -0,0 +1,166 @@
+﻿#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.ComponentModel;
+using System.Linq;
+using HeuristicLab.Analysis;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [Item("HeatMap", "Represents a heat map of double values.")]
+  [StorableClass]
+  public class ExtendedHeatMap : HeatMap {
+
+    private IDataAnalysisProblemData problemData;
+
+    private BackgroundWorker bw;
+
+    public delegate void ProgressCalculationHandler(object sender, ProgressChangedEventArgs e);
+    public event ProgressCalculationHandler ProgressCalculation;
+
+    public ExtendedHeatMap()
+      : base() {
+      columnNames = Enumerable.Range(1, 2).Select(x => x.ToString()).ToList();
+      rowNames = Enumerable.Range(1, 2).Select(x => x.ToString()).ToList();
+    }
+
+    public ExtendedHeatMap(IDataAnalysisProblemData problemData) {
+      this.problemData = problemData;
+      this.Title = "Feature Correlation";
+      this.columnNames = problemData.Dataset.DoubleVariables.ToList();
+      this.rowNames = problemData.Dataset.DoubleVariables.ToList();
+
+      CalculateElements(problemData.Dataset);
+    }
+
+    public IEnumerable<string> CorrelationCalculators {
+      get { return new List<string>() { "OnlinePearsonsRSquaredCalculator", "HoeffdingsDependenceCalculator", "SpearmansRankCorrelationCoefficientCalculator" }; }
+    }
+
+    public IEnumerable<string> Partitions {
+      get { return new List<string>() { "All Samples", "Training Partition", "Test Partition" }; }
+    }
+
+    public void Recalculate(string calc, string partition) {
+      CalculateElements(problemData.Dataset, calc, partition);
+    }
+
+    private void CalculateElements(Dataset dataset) {
+      CalculateElements(dataset, CorrelationCalculators.First(), Partitions.First());
+    }
+
+    private void CalculateElements(Dataset dataset, string calc, string partition) {
+      if (bw == null || bw.IsBusy) {
+        if (bw != null) {
+          bw.CancelAsync();
+        }
+        bw = new BackgroundWorker();
+        bw.WorkerReportsProgress = true;
+        bw.WorkerSupportsCancellation = true;
+        bw.DoWork += new DoWorkEventHandler(bw_DoWork);
+        bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
+        bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
+      }
+      bw.RunWorkerAsync(new BackgroundWorkerInfo { Dataset = dataset, Calculator = calc, Partition = partition });
+    }
+
+    private void bw_DoWork(object sender, DoWorkEventArgs e) {
+      BackgroundWorker worker = sender as BackgroundWorker;
+
+      BackgroundWorkerInfo bwInfo = (BackgroundWorkerInfo)e.Argument;
+      Dataset dataset = bwInfo.Dataset;
+      string partition = bwInfo.Partition;
+      string calc = bwInfo.Calculator;
+
+      IList<string> doubleVariableNames = dataset.DoubleVariables.ToList();
+      OnlineCalculatorError error;
+      int length = doubleVariableNames.Count;
+      double[,] elements = new double[length, length];
+
+      double calculations = (Math.Pow(length, 2) + length) / 2;
+
+      for (int i = 0; i < length; i++) {
+        for (int j = 0; j < i + 1; j++) {
+          if (worker.CancellationPending) {
+            e.Cancel = true;
+            return;
+          }
+
+          IEnumerable<double> var1 = dataset.GetDoubleValues(doubleVariableNames[i]);
+          IEnumerable<double> var2 = dataset.GetDoubleValues(doubleVariableNames[j]);
+          if (partition.Equals(Partitions.ElementAt(1))) {
+            var1 = var1.Skip(problemData.TrainingPartition.Start).Take(problemData.TrainingPartition.End - problemData.TrainingPartition.Start);
+            var2 = var2.Skip(problemData.TrainingPartition.Start).Take(problemData.TrainingPartition.End - problemData.TrainingPartition.Start);
+          } else if (partition.Equals(Partitions.ElementAt(2))) {
+            var1 = var1.Skip(problemData.TestPartition.Start).Take(problemData.TestPartition.End - problemData.TestPartition.Start);
+            var2 = var2.Skip(problemData.TestPartition.Start).Take(problemData.TestPartition.End - problemData.TestPartition.Start);
+          }
+
+          if (calc.Equals(CorrelationCalculators.ElementAt(1))) {
+            elements[i, j] = HoeffdingsDependenceCalculator.Calculate(var1, var2, out error);
+          } else if (calc.Equals(CorrelationCalculators.ElementAt(2))) {
+            elements[i, j] = SpearmansRankCorrelationCoefficientCalculator.Calculate(var1, var2, out error);
+          } else {
+            elements[i, j] = OnlinePearsonsRSquaredCalculator.Calculate(var1, var2, out error);
+          }
+          elements[j, i] = elements[i, j];
+          if (!error.Equals(OnlineCalculatorError.None)) {
+            throw new ArgumentException("Calculator returned " + error);
+          }
+          worker.ReportProgress((int)Math.Round((((Math.Pow(i, 2) + i) / 2 + j + 1.0) / calculations) * 100));
+        }
+      }
+      e.Result = elements;
+    }
+
+    private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e) {
+      BackgroundWorker worker = sender as BackgroundWorker;
+      if (!worker.CancellationPending && ProgressCalculation != null) {
+        ProgressCalculation(sender, e);
+      }
+    }
+
+    private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
+      BackgroundWorker worker = sender as BackgroundWorker;
+      if (!e.Cancelled && !worker.CancellationPending) {
+        if (!(e.Error == null)) {
+          ErrorHandling.ShowErrorDialog(e.Error);
+        } else {
+          matrix = (double[,])e.Result;
+          OnReset();
+        }
+      } else {
+        Console.WriteLine("Backgroundworker canceled");
+      }
+    }
+
+    private class BackgroundWorkerInfo {
+      public Dataset Dataset { get; set; }
+      public string Calculator { get; set; }
+      public string Partition { get; set; }
+    }
+  }
+}
Index: /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleSolution.cs
===================================================================
--- /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleSolution.cs	(revision 8275)
+++ /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleSolution.cs	(revision 8276)
@@ -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/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionProblemData.cs
===================================================================
--- /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionProblemData.cs	(revision 8275)
+++ /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionProblemData.cs	(revision 8276)
@@ -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/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolution.cs
===================================================================
--- /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolution.cs	(revision 8275)
+++ /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolution.cs	(revision 8276)
@@ -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/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolutionBase.cs
===================================================================
--- /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolutionBase.cs	(revision 8275)
+++ /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolutionBase.cs	(revision 8276)
@@ -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/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisProblemData.cs
===================================================================
--- /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisProblemData.cs	(revision 8275)
+++ /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisProblemData.cs	(revision 8276)
@@ -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/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IOnlineCalculator.cs
===================================================================
--- /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IOnlineCalculator.cs	(revision 8275)
+++ /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IOnlineCalculator.cs	(revision 8276)
@@ -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/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/HoeffdingsDependenceCalculator.cs
===================================================================
--- /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/HoeffdingsDependenceCalculator.cs	(revision 8275)
+++ /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/HoeffdingsDependenceCalculator.cs	(revision 8276)
@@ -23,5 +23,4 @@
 using System.Collections.Generic;
 using System.Linq;
-using HeuristicLab.Common;
 
 namespace HeuristicLab.Problems.DataAnalysis {
Index: /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineLinearScalingParameterCalculator.cs
===================================================================
--- /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineLinearScalingParameterCalculator.cs	(revision 8275)
+++ /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineLinearScalingParameterCalculator.cs	(revision 8276)
@@ -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/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/SpearmansRankCorrelationCoefficientCalculator.cs
===================================================================
--- /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/SpearmansRankCorrelationCoefficientCalculator.cs	(revision 8276)
+++ /branches/DatasetFeatureCorrelation/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/SpearmansRankCorrelationCoefficientCalculator.cs	(revision 8276)
@@ -0,0 +1,105 @@
+﻿#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;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public class SpearmansRankCorrelationCoefficientCalculator {
+
+    public static double Calculate(IEnumerable<double> originalValues, IEnumerable<double> estimatedValues, out OnlineCalculatorError errorState) {
+      double rs = Math.Abs(Spear(originalValues, estimatedValues, out errorState));
+      if (errorState != OnlineCalculatorError.None) return double.NaN;
+      return rs;
+    }
+
+    /// <summary>
+    /// Calculates Spearmans Rank Correlation Coefficient. Source: Numerical Recipes in C.
+    /// </summary>
+    private static double Spear(IEnumerable<double> xs, IEnumerable<double> ys, out OnlineCalculatorError errorState) {
+      double[] xsArr = xs.ToArray();
+      double[] ysArr = ys.ToArray();
+      if (xsArr.Length != ysArr.Length) throw new ArgumentException("The number of elements in xs and ys does not match");
+
+      int n = xsArr.Length;
+      Array.Sort(xsArr, ysArr);
+      double sf = CRank(xsArr);
+      Array.Sort(ysArr, xsArr);
+      double sg = CRank(ysArr);
+
+      double d = 0.0;
+      for (int j = 0; j < n; j++) //Sum the squared difference of ranks.
+        d += Math.Pow(xsArr[j] - ysArr[j], 2);
+
+      double en, en3n, aved, fac, rs; // vard, zd, t, df, probd, probrs;
+      en = n;
+      en3n = en * en * en - en;
+      aved = en3n / 6.0 - (sf + sg) / 12.0;
+      fac = (1.0 - sf / en3n) * (1.0 - sg / en3n);
+      //vard = ((en - 1.0) * en * en * Math.Pow(en + 1.0, 2) / 36.0) * fac;
+      //zd = (d - aved) / Math.Sqrt(vard);
+      //probd = erfcc(Math.Abs(zd) / 1.4142136);
+      rs = (1.0 - (6.0 / en3n) * (d + (sf + sg) / 12.0)) / Math.Sqrt(fac);
+      //fac = (rs + 1.0) * (1.0 - rs);
+      //if (fac > 0.0) {
+      //  t = rs * Math.Sqrt((en - 2.0) / fac);
+      //  df = en - 2.0;
+      //  probrs = betai(0.5 * df, 0.5, df / (df + t * t));
+      //} else {
+      //  probrs = 0.0;
+      //}
+      errorState = OnlineCalculatorError.None;
+      return rs;
+    }
+
+    /// <summary>
+    /// Calculates midranks. Source: Numerical Recipes in C.
+    /// </summary>
+    /// <param name="w">Sorted array of elements, replaces the elements by their rank, including midranking of ties</param>
+    /// <returns></returns>
+    private static double CRank(double[] w) {
+      int i = 0;
+      int n = w.Length;
+      double s = 0.0;
+      double t;
+      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)
+          double rank = 0.5 * (i + j - 1);
+          int k;
+          for (k = i; k <= j - 1; k++) w[k] = rank; // set the rank for all tied entries
+          t = j - i;
+          s += t * t * t - t;
+          i = j;
+        }
+      }
+
+      if (i == n - 1) w[n - 1] = n - 1;   // if the last element was not tied, this is its rank
+      return s;
+    }
+  }
+}
