Index: branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/TreeMatching/SymbolicExpressionTreeBottomUpSimilarityCalculator.cs
===================================================================
--- branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/TreeMatching/SymbolicExpressionTreeBottomUpSimilarityCalculator.cs	(revision 11926)
+++ branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/TreeMatching/SymbolicExpressionTreeBottomUpSimilarityCalculator.cs	(revision 11927)
@@ -34,5 +34,5 @@
   [StorableClass]
   [Item("SymbolicExpressionTreeBottomUpSimilarityCalculator", "A similarity calculator which uses the tree bottom-up distance as a similarity metric.")]
-  public class SymbolicExpressionTreeBottomUpSimilarityCalculator : SingleObjectiveSolutionSimilarityCalculator {
+  public class SymbolicExpressionTreeBottomUpSimilarityCalculator : SingleObjectiveSolutionSimilarityCalculator, ISymbolicDataAnalysisExpressionSimilarityCalculator {
     private readonly HashSet<string> commutativeSymbols = new HashSet<string> { "Addition", "Multiplication", "Average", "And", "Or", "Xor" };
     public bool MatchVariableWeights { get; set; }
Index: branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/TreeMatching/SymbolicExpressionTreeMatching.cs
===================================================================
--- branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/TreeMatching/SymbolicExpressionTreeMatching.cs	(revision 11926)
+++ branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/TreeMatching/SymbolicExpressionTreeMatching.cs	(revision 11927)
@@ -30,12 +30,12 @@
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
   public static class SymbolicExpressionTreeMatching {
-    public static bool ContainsSubtree(this ISymbolicExpressionTreeNode root, ISymbolicExpressionTreeNode subtree, SymbolicExpressionTreeNodeEqualityComparer comparer) {
+    public static bool ContainsSubtree(this ISymbolicExpressionTreeNode root, ISymbolicExpressionTreeNode subtree, ISymbolicExpressionTreeNodeEqualityComparer comparer) {
       return FindMatches(root, subtree, comparer).Any();
     }
-    public static IEnumerable<ISymbolicExpressionTreeNode> FindMatches(ISymbolicExpressionTree tree, ISymbolicExpressionTreeNode subtree, SymbolicExpressionTreeNodeEqualityComparer comparer) {
+    public static IEnumerable<ISymbolicExpressionTreeNode> FindMatches(ISymbolicExpressionTree tree, ISymbolicExpressionTreeNode subtree, ISymbolicExpressionTreeNodeEqualityComparer comparer) {
       return FindMatches(tree.Root, subtree, comparer);
     }
 
-    public static IEnumerable<ISymbolicExpressionTreeNode> FindMatches(ISymbolicExpressionTreeNode root, ISymbolicExpressionTreeNode subtree, SymbolicExpressionTreeNodeEqualityComparer comp) {
+    public static IEnumerable<ISymbolicExpressionTreeNode> FindMatches(ISymbolicExpressionTreeNode root, ISymbolicExpressionTreeNode subtree, ISymbolicExpressionTreeNodeEqualityComparer comp) {
       var fragmentLength = subtree.GetLength();
       // below, we use ">=" for Match(n, subtree, comp) >= fragmentLength because in case of relaxed conditions, 
@@ -52,5 +52,5 @@
     /// </summary>
     /// <returns>Number of pairs that were matched</returns>
-    public static int Match(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b, ISymbolicExpressionTreeNodeSimilarityComparer comp) {
+    public static int Match(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b, ISymbolicExpressionTreeNodeEqualityComparer comp) {
       if (!comp.Equals(a, b)) return 0;
       int m = a.SubtreeCount;
Index: branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/TreeMatching/SymbolicExpressionTreeMaxCommonSubtreeSimilarityCalculator.cs
===================================================================
--- branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/TreeMatching/SymbolicExpressionTreeMaxCommonSubtreeSimilarityCalculator.cs	(revision 11926)
+++ branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/TreeMatching/SymbolicExpressionTreeMaxCommonSubtreeSimilarityCalculator.cs	(revision 11927)
@@ -30,5 +30,5 @@
   [StorableClass]
   [Item("SymbolicExpressionTreeMaxCommonSubtreeSimilarityCalculator", "A similarity calculator based on the size of the maximum common subtree between two trees")]
-  public class SymbolicExpressionTreeMaxCommonSubtreeSimilarityCalculator : SingleObjectiveSolutionSimilarityCalculator {
+  public class SymbolicExpressionTreeMaxCommonSubtreeSimilarityCalculator : SingleObjectiveSolutionSimilarityCalculator, ISymbolicDataAnalysisExpressionSimilarityCalculator {
     [Storable]
     private readonly SymbolicExpressionTreeNodeEqualityComparer comparer;
@@ -85,5 +85,5 @@
     }
 
-    public static double MaxCommonSubtreeSimilarity(ISymbolicExpressionTree a, ISymbolicExpressionTree b, ISymbolicExpressionTreeNodeSimilarityComparer comparer) {
+    public static double MaxCommonSubtreeSimilarity(ISymbolicExpressionTree a, ISymbolicExpressionTree b, ISymbolicExpressionTreeNodeEqualityComparer comparer) {
       int max = 0;
       var rootA = a.Root.GetSubtree(0).GetSubtree(0);
Index: branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/TreeMatching/SymbolicExpressionTreeNodeEqualityComparer.cs
===================================================================
--- branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/TreeMatching/SymbolicExpressionTreeNodeEqualityComparer.cs	(revision 11926)
+++ branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/TreeMatching/SymbolicExpressionTreeNodeEqualityComparer.cs	(revision 11927)
@@ -28,5 +28,5 @@
   [Item("SymbolicExpressionTreeNodeEqualityComparer", "An operator that checks node equality based on different similarity measures.")]
   [StorableClass]
-  public class SymbolicExpressionTreeNodeEqualityComparer : Item, ISymbolicExpressionTreeNodeSimilarityComparer {
+  public class SymbolicExpressionTreeNodeEqualityComparer : Item, ISymbolicExpressionTreeNodeEqualityComparer {
     [StorableConstructor]
     protected SymbolicExpressionTreeNodeEqualityComparer(bool deserializing) : base(deserializing) { }
Index: branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/TreeMatching/SymbolicExpressionTreePhenotypicSimilarityCalculator.cs
===================================================================
--- branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/TreeMatching/SymbolicExpressionTreePhenotypicSimilarityCalculator.cs	(revision 11927)
+++ branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/TreeMatching/SymbolicExpressionTreePhenotypicSimilarityCalculator.cs	(revision 11927)
@@ -0,0 +1,74 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2014 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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Optimization.Operators;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+  [Item("PhenotypicSimilarityCalculator", "An operator that calculates the similarity betweeon two trees based on the correlation of their outputs.")]
+  [StorableClass]
+  public class PhenotypicSimilarityCalculator : SingleObjectiveSolutionSimilarityCalculator, ISymbolicDataAnalysisExpressionSimilarityCalculator {
+    public IDataAnalysisProblemData ProblemData { get; set; }
+    public ISymbolicDataAnalysisExpressionTreeInterpreter Interpreter { get; set; }
+
+    public PhenotypicSimilarityCalculator(PhenotypicSimilarityCalculator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+
+    public PhenotypicSimilarityCalculator() { }
+
+    [StorableConstructor]
+    protected PhenotypicSimilarityCalculator(bool deserializing) : base(deserializing) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PhenotypicSimilarityCalculator(this, cloner);
+    }
+
+    public double CalculateSimilarity(ISymbolicExpressionTree t1, ISymbolicExpressionTree t2) {
+      var v1 = Interpreter.GetSymbolicExpressionTreeValues(t1, ProblemData.Dataset, ProblemData.TrainingIndices);
+      var v2 = Interpreter.GetSymbolicExpressionTreeValues(t2, ProblemData.Dataset, ProblemData.TrainingIndices);
+
+      OnlineCalculatorError error;
+      var r2 = OnlinePearsonsRSquaredCalculator.Calculate(v1, v2, out error);
+
+      if (r2 > 1.0)
+        r2 = 1.0;
+
+      return error == OnlineCalculatorError.None ? r2 : 0;
+    }
+
+    public override double CalculateSolutionSimilarity(IScope leftSolution, IScope rightSolution) {
+      var leftValues = (DoubleArray)leftSolution.Variables["EstimatedValues"].Value;
+      var rightValues = (DoubleArray)rightSolution.Variables["EstimatedValues"].Value;
+      OnlineCalculatorError error;
+      var r2 = OnlinePearsonsRSquaredCalculator.Calculate(leftValues, rightValues, out error);
+
+      if (r2 > 1.0)
+        r2 = 1.0; // sometimes due to fp errors it can happen that the r2 is over 1 (like 1.0000000009)
+
+      return error == OnlineCalculatorError.None ? r2 : 0;
+    }
+  }
+}
