Index: /branches/2904_CalculateImpacts/HeuristicLab.Tests/HeuristicLab-3.3/Samples/GPSymbolicRegressionSampleWithOSTest.cs
===================================================================
--- /branches/2904_CalculateImpacts/HeuristicLab.Tests/HeuristicLab-3.3/Samples/GPSymbolicRegressionSampleWithOSTest.cs	(revision 16401)
+++ /branches/2904_CalculateImpacts/HeuristicLab.Tests/HeuristicLab-3.3/Samples/GPSymbolicRegressionSampleWithOSTest.cs	(revision 16402)
@@ -104,4 +104,6 @@
       var squareroot = grammar.Symbols.OfType<SquareRoot>().Single();
       var root = grammar.Symbols.OfType<Root>().Single();
+      var cube = grammar.Symbols.OfType<Cube>().Single();
+      var cuberoot = grammar.Symbols.OfType<CubeRoot>().Single();
       var log = grammar.Symbols.OfType<Logarithm>().Single();
       var exp = grammar.Symbols.OfType<Exponential>().Single();
@@ -130,4 +132,6 @@
       grammar.AddAllowedChildSymbol(squareroot, variable);
 
+      cube.Enabled = false;
+      cuberoot.Enabled = false;
       root.Enabled = false;
 
Index: /branches/2904_CalculateImpacts/HeuristicLab.Tests/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4/SubtreeCrossoverTest.cs
===================================================================
--- /branches/2904_CalculateImpacts/HeuristicLab.Tests/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4/SubtreeCrossoverTest.cs	(revision 16401)
+++ /branches/2904_CalculateImpacts/HeuristicLab.Tests/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4/SubtreeCrossoverTest.cs	(revision 16402)
@@ -46,4 +46,6 @@
           SubroutineCreater.CreateSubroutine(random, trees[i], 100, 10, 3, 3);
       }
+      var children = new List<ISymbolicExpressionTree>(trees);
+
       Stopwatch stopwatch = new Stopwatch();
       stopwatch.Start();
@@ -52,6 +54,7 @@
           var par0 = (ISymbolicExpressionTree)trees.SampleRandom(random).Clone();
           var par1 = (ISymbolicExpressionTree)trees.SampleRandom(random).Clone();
-          SubtreeCrossover.Cross(random, par0, par1, 0.9, 100, 10);
+          children[i] = SubtreeCrossover.Cross(random, par0, par1, 0.9, 100, 10);
         }
+        trees = children;
       }
       stopwatch.Stop();
Index: /branches/2904_CalculateImpacts/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/DeriveTest.cs
===================================================================
--- /branches/2904_CalculateImpacts/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/DeriveTest.cs	(revision 16402)
+++ /branches/2904_CalculateImpacts/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/DeriveTest.cs	(revision 16402)
@@ -0,0 +1,136 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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 HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Tests {
+
+
+  [TestClass]
+  public class DerivativeTest {
+    [TestMethod]
+    [TestCategory("Problems.DataAnalysis.Symbolic")]
+    [TestProperty("Time", "short")]
+    public void DeriveExpressions() {
+      var formatter = new InfixExpressionFormatter();
+      var parser = new InfixExpressionParser();
+      Assert.AreEqual("0", Derive("3", "x"));
+      Assert.AreEqual("1", Derive("x", "x"));
+      Assert.AreEqual("10", Derive("10*x", "x"));
+      Assert.AreEqual("10", Derive("x*10", "x"));
+      Assert.AreEqual("(2*'x')", Derive("x*x", "x"));
+      Assert.AreEqual("((('x' * 'x') * 2) + ('x' * 'x'))", Derive("x*x*x", "x")); // simplifier does not merge (x*x)*2 + x*x  to 3*x*x
+      Assert.AreEqual("0", Derive("10*x", "y"));
+      Assert.AreEqual("20", Derive("10*x+20*y", "y"));
+      Assert.AreEqual("6", Derive("2*3*x", "x"));
+      Assert.AreEqual("(10*'y')", Derive("10*x*y+20*y", "x"));
+      Assert.AreEqual("(1 / (SQR('x') * (-1)))", Derive("1/x", "x"));
+      Assert.AreEqual("('y' / (SQR('x') * (-1)))", Derive("y/x", "x"));
+      Assert.AreEqual("((((-2*'x') + (-1)) * ('a' + 'b')) / SQR(('x' + ('x' * 'x'))))",
+        Derive("(a+b)/(x+x*x)", "x"));
+      Assert.AreEqual("((((-2*'x') + (-1)) * ('a' + 'b')) / SQR(('x' + SQR('x'))))", Derive("(a+b)/(x+SQR(x))", "x"));
+      Assert.AreEqual("EXP('x')", Derive("exp(x)", "x"));
+      Assert.AreEqual("(EXP((3*'x')) * 3)", Derive("exp(3*x)", "x"));
+      Assert.AreEqual("(1 / 'x')", Derive("log(x)", "x"));
+      Assert.AreEqual("(1 / 'x')", Derive("log(3*x)", "x"));   // 3 * 1/(3*x)
+      Assert.AreEqual("(1 / ('x' + (0.333333333333333*'y')))", Derive("log(3*x+y)", "x"));  // simplifier does not try to keep fractions
+      Assert.AreEqual("(1 / (SQRT(((3*'x') + 'y')) * 0.666666666666667))", Derive("sqrt(3*x+y)", "x"));   // 3 / (2 * sqrt(3*x+y)) = 1 / ((2/3) * sqrt(3*x+y)) 
+      Assert.AreEqual("(COS((3*'x')) * 3)", Derive("sin(3*x)", "x"));
+      Assert.AreEqual("(SIN((3*'x')) * (-3))", Derive("cos(3*x)", "x"));
+      Assert.AreEqual("(1 / (SQR(COS((3*'x'))) * 0.333333333333333))", Derive("tan(3*x)", "x")); // diff(tan(f(x)), x) = 1.0 / cos²(f(x)), simplifier puts constant factor into the denominator
+
+      {
+        // special case: Inv(x) using only one argument to the division symbol
+        // f(x) = 1/x
+        var root = new ProgramRootSymbol().CreateTreeNode();
+        var start = new StartSymbol().CreateTreeNode();
+        var div = new Division().CreateTreeNode();
+        var varNode = (VariableTreeNode)(new Variable().CreateTreeNode());
+        varNode.Weight = 1.0;
+        varNode.VariableName = "x";
+        div.AddSubtree(varNode);
+        start.AddSubtree(div);
+        root.AddSubtree(start);
+        var t = new SymbolicExpressionTree(root);
+        Assert.AreEqual("(1 / (SQR('x') * (-1)))",
+          formatter.Format(DerivativeCalculator.Derive(t, "x")));
+      }
+
+      {
+        // special case: multiplication with only one argument
+        var root = new ProgramRootSymbol().CreateTreeNode();
+        var start = new StartSymbol().CreateTreeNode();
+        var mul = new Multiplication().CreateTreeNode();
+        var varNode = (VariableTreeNode)(new Variable().CreateTreeNode());
+        varNode.Weight = 3.0;
+        varNode.VariableName = "x";
+        mul.AddSubtree(varNode);
+        start.AddSubtree(mul);
+        root.AddSubtree(start);
+        var t = new SymbolicExpressionTree(root);
+        Assert.AreEqual("3",
+          formatter.Format(DerivativeCalculator.Derive(t, "x")));
+      }
+
+      {
+        // division with multiple arguments
+        // div(x, y, z) is interpreted as (x / y) / z
+        var root = new ProgramRootSymbol().CreateTreeNode();
+        var start = new StartSymbol().CreateTreeNode();
+        var div = new Division().CreateTreeNode();
+        var varNode1 = (VariableTreeNode)(new Variable().CreateTreeNode());
+        varNode1.Weight = 3.0;
+        varNode1.VariableName = "x";
+        var varNode2 = (VariableTreeNode)(new Variable().CreateTreeNode());
+        varNode2.Weight = 4.0;
+        varNode2.VariableName = "y";
+        var varNode3 = (VariableTreeNode)(new Variable().CreateTreeNode());
+        varNode3.Weight = 5.0;
+        varNode3.VariableName = "z";
+        div.AddSubtree(varNode1); div.AddSubtree(varNode2); div.AddSubtree(varNode3);
+        start.AddSubtree(div);
+        root.AddSubtree(start);
+        var t = new SymbolicExpressionTree(root);
+
+        Assert.AreEqual("(('y' * 'z' * 60) / (SQR('y') * SQR('z') * 400))", // actually 3 / (4y  5z) but simplifier is not smart enough to cancel numerator and denominator
+                                                                             // 60 y z / y² z² 20² == 6 / y z 40 == 3 / y z 20
+          formatter.Format(DerivativeCalculator.Derive(t, "x")));
+        Assert.AreEqual("(('x' * 'z' * (-60)) / (SQR('y') * SQR('z') * 400))", // actually 3x * -(4 5 z) / (4y 5z)² = -3x / (20 y² z)
+                                                                         // -3 4 5 x z / 4² y² 5² z² = -60 x z / 20² z² y² ==    -60 x z / y² z² 20² 
+          formatter.Format(DerivativeCalculator.Derive(t, "y")));
+        Assert.AreEqual("(('x' * 'y' * (-60)) / (SQR('y') * SQR('z') * 400))",
+          formatter.Format(DerivativeCalculator.Derive(t, "z")));
+      }
+    }
+
+    private string Derive(string expr, string variable) {
+      var parser = new InfixExpressionParser();
+      var formatter = new InfixExpressionFormatter();
+
+      var t = parser.Parse(expr);
+      var tPrime = DerivativeCalculator.Derive(t, variable);
+
+      return formatter.Format(tPrime);
+    }
+  }
+}
Index: /branches/2904_CalculateImpacts/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/InfixExpressionParserTest.cs
===================================================================
--- /branches/2904_CalculateImpacts/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/InfixExpressionParserTest.cs	(revision 16401)
+++ /branches/2904_CalculateImpacts/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/InfixExpressionParserTest.cs	(revision 16402)
@@ -61,15 +61,15 @@
 
       Console.WriteLine(formatter.Format(parser.Parse("log(3)")));
-      Console.WriteLine(formatter.Format(parser.Parse("log(-3)")));
+      Console.WriteLine(formatter.Format(parser.Parse("log(-3)")));   // should produce log(-3) as output
       Console.WriteLine(formatter.Format(parser.Parse("exp(3)")));
-      Console.WriteLine(formatter.Format(parser.Parse("exp(-3)")));
+      Console.WriteLine(formatter.Format(parser.Parse("exp(-3)")));  // should produce exp(-3) as output
       Console.WriteLine(formatter.Format(parser.Parse("sqrt(3)")));
 
-      Console.WriteLine(formatter.Format(parser.Parse("sqr((-3))")));
+      Console.WriteLine(formatter.Format(parser.Parse("sqr((-3))")));  // should produce sqr((-3)) as output
 
-      Console.WriteLine(formatter.Format(parser.Parse("3/3+2/2+1/1")));
-      Console.WriteLine(formatter.Format(parser.Parse("-3+30-2+20-1+10")));
+      Console.WriteLine(formatter.Format(parser.Parse("3/3+2/2+1/1"))); // ((3 * 1 / 3) + (2 * 1 / 2) + (1 * 1 / 1))
+      Console.WriteLine(formatter.Format(parser.Parse("-3+30-2+20-1+10")));   //  not (30 + 20 + 10 + ((-1) * (3 + 2 + 1)))
       // round trip
-      Console.WriteLine(formatter.Format(parser.Parse(formatter.Format(parser.Parse("-3+30-2+20-1+10")))));
+      Console.WriteLine(formatter.Format(parser.Parse(formatter.Format(parser.Parse("-3+30-2+20-1+10")))));   // not (30 + 20 + 10 + ((-(1)) * (3 + 2 + 1)))
 
       Console.WriteLine(formatter.Format(parser.Parse("\"x1\"")));
Index: /branches/2904_CalculateImpacts/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/SymbolicDataAnalysisExpressionTreeInterpreterTest.cs
===================================================================
--- /branches/2904_CalculateImpacts/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/SymbolicDataAnalysisExpressionTreeInterpreterTest.cs	(revision 16401)
+++ /branches/2904_CalculateImpacts/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/SymbolicDataAnalysisExpressionTreeInterpreterTest.cs	(revision 16402)
@@ -119,4 +119,17 @@
     public void LinearInterpreterTestArithmeticGrammarPerformance() {
       TestArithmeticGrammarPerformance(new SymbolicDataAnalysisExpressionTreeLinearInterpreter(), 12.5e6);
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.DataAnalysis.Symbolic")]
+    [TestProperty("Time", "long")]
+    public void BatchInterpreterTestTypeCoherentGrammarPerformance() {
+      TestTypeCoherentGrammarPerformance(new SymbolicDataAnalysisExpressionTreeBatchInterpreter(), 12.5e6);
+    }
+    [TestMethod]
+    [TestCategory("Problems.DataAnalysis.Symbolic")]
+    [TestProperty("Time", "long")]
+    public void BatchInterpreterTestArithmeticGrammarPerformance() {
+      TestArithmeticGrammarPerformance(new SymbolicDataAnalysisExpressionTreeBatchInterpreter(), 12.5e6);
     }
 
Index: /branches/2904_CalculateImpacts/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/SymbolicDataAnalysisExpressionTreeSimplifierTest.cs
===================================================================
--- /branches/2904_CalculateImpacts/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/SymbolicDataAnalysisExpressionTreeSimplifierTest.cs	(revision 16401)
+++ /branches/2904_CalculateImpacts/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/SymbolicDataAnalysisExpressionTreeSimplifierTest.cs	(revision 16402)
@@ -228,4 +228,45 @@
       AssertEqualAfterSimplification("(- (factor a 2.0 3.0) (binfactor a x0 2.0))", "(factor a 0.0 3.0)");
       #endregion
+
+      #region abs
+      AssertEqualAfterSimplification("(abs 2.0)", "2.0");
+      AssertEqualAfterSimplification("(abs -2.0)", "2.0"); // constant folding
+      AssertEqualAfterSimplification("(abs (exp (variable 2.0 x)))", "(exp (variable 2.0 x)))"); // exp is always positive
+      AssertEqualAfterSimplification("(abs (exp (variable 2.0 x)))", "(exp (variable 2.0 x)))"); // exp is always positive
+      AssertEqualAfterSimplification("(abs (sqr (variable 2.0 a)))", "(sqr (variable 2.0 a))"); // sqr is always positive
+      AssertEqualAfterSimplification("(abs (sqrt (variable 2.0 a)))", "(sqrt (variable 2.0 a))"); // sqrt is always positive (for our cases)
+      AssertEqualAfterSimplification("(abs (cuberoot (variable 2.0 a)))", "(cuberoot (variable 2.0 a))"); // cuberoot is always positive (for our cases)
+
+      AssertEqualAfterSimplification("(* (abs (variable 2.0 x)) 2.0)", "(abs (variable 4.0 x))");  // can multiply positive constants into abs
+      AssertEqualAfterSimplification("(* (abs (variable 2.0 x)) -2.0)", "(* (abs (variable 4.0 x)) -1.0)"); // for negative constants keep the sign
+
+      AssertEqualAfterSimplification("(abs (* (variable 1.0 a) (variable 2.0 b)))", "(* (abs (variable 1.0 a)) (abs (variable 1.0 b)) 2.0))");
+      AssertEqualAfterSimplification("(abs (/ (variable 1.0 a) (variable 2.0 b)))", "(/ (abs (variable 1.0 a)) (abs (variable 2.0 b))))");
+      #endregion
+
+      #region square and sqrt
+      AssertEqualAfterSimplification("(sqr (sqrt (variable 2.0 x)))", "(variable 2.0 x)");
+      AssertEqualAfterSimplification("(sqrt (sqr (variable 2.0 x)))", "(variable 2.0 x)");
+      AssertEqualAfterSimplification("(sqr (abs (variable 2.0 a)))", "(sqr (variable 2.0 a))");
+      AssertEqualAfterSimplification("(sqr (exp (variable 2.0 x)))", "(exp (variable 4.0 x))");
+
+      AssertEqualAfterSimplification("(sqr (* (variable 2.0 a) (variable 3.0 b) (variable 4.0 c)))",
+        "(* (sqr (variable 1.0 a)) (sqr (variable 1.0 b)) (sqr (variable 1.0 c)) 576)"); // 2²*3²*4²
+      #endregion
+
+      #region cube and cuberoot
+      AssertEqualAfterSimplification("(cube (cuberoot (variable 2.0 x)))", "(variable 2.0 x)");
+      AssertEqualAfterSimplification("(cuberoot (cube (variable 2.0 x)))", "(variable 2.0 x)");
+      AssertEqualAfterSimplification("(cube (exp (variable 2.0 x)))", "(exp (variable 6.0 x))");
+
+      AssertEqualAfterSimplification("(sqr (cube (variable 2.0 x)))", "(pow (variable 2.0 x) 6)");
+      AssertEqualAfterSimplification("(cube (sqr (variable 2.0 x)))", "(pow (variable 2.0 x) 6)");
+      #endregion
+
+      #region AQ
+      AssertEqualAfterSimplification("(* (aq (variable 1.0 x) (variable 1.0 y)) 2.0)", "(aq (variable 2.0 x) (variable 1.0 y))");
+      AssertEqualAfterSimplification("(/ (aq (variable 1.0 x) (variable 1.0 y)) 2.0)", "(aq (variable 0.5 x) (variable 1.0 y))");
+
+      #endregion
     }
 
Index: /branches/2904_CalculateImpacts/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/SymbolicExpressionTreeBottomUpSimilarityCalculatorTest.cs
===================================================================
--- /branches/2904_CalculateImpacts/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/SymbolicExpressionTreeBottomUpSimilarityCalculatorTest.cs	(revision 16401)
+++ /branches/2904_CalculateImpacts/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/SymbolicExpressionTreeBottomUpSimilarityCalculatorTest.cs	(revision 16402)
@@ -7,14 +7,13 @@
   [TestClass]
   public class BottomUpSimilarityCalculatorTest {
-    private readonly SymbolicExpressionTreeBottomUpSimilarityCalculator busCalculator;
-    private readonly SymbolicExpressionImporter importer;
+    private readonly SymbolicExpressionTreeBottomUpSimilarityCalculator similarityCalculator = new SymbolicExpressionTreeBottomUpSimilarityCalculator() { MatchConstantValues = false, MatchVariableWeights = false };
+    private readonly SymbolicExpressionImporter importer = new SymbolicExpressionImporter();
 
-    private const int N = 150;
+    private const int N = 1000;
     private const int Rows = 1;
     private const int Columns = 10;
 
     public BottomUpSimilarityCalculatorTest() {
-      busCalculator = new SymbolicExpressionTreeBottomUpSimilarityCalculator();
-      importer = new SymbolicExpressionImporter();
+      var parser = new InfixExpressionParser();
     }
 
@@ -23,39 +22,24 @@
     [TestProperty("Time", "short")]
     public void BottomUpTreeSimilarityCalculatorTestMapping() {
-      TestMatchedNodes("(+ 1 2)", "(+ 2 1)", 5);
-      TestMatchedNodes("(- 2 1)", "(- 1 2)", 2);
-      TestMatchedNodes("(* (variable 1 X1) (variable 1 X2))", "(* (+ (variable 1 X1) 1) (+ (variable 1 X2) 1))", 2);
+      TestMatchedNodes("(+ 1 1)", "(+ 2 2)", 0, strict: true);
+      TestMatchedNodes("(+ 1 1)", "(+ 2 2)", 3, strict: false);
+      TestMatchedNodes("(+ 1 1)", "(+ 1 2)", 1, strict: true);
+      TestMatchedNodes("(+ 2 1)", "(+ 1 2)", 3, strict: true);
 
-      TestMatchedNodes("(* (variable 1 X1) (variable 1 X2))", "(* (+ (variable 1 X1) 1) (variable 1 X2))", 2);
+      TestMatchedNodes("(- 1 1)", "(- 2 2)", 0, strict: true);
+      TestMatchedNodes("(- 1 1)", "(- 2 2)", 3, strict: false);
 
-      TestMatchedNodes("(+ (variable 1 a) (variable 1 b))", "(+ (variable 1 a) (variable 1 a))", 1);
-      TestMatchedNodes("(+ (+ (variable 1 a) (variable 1 b)) (variable 1 b))", "(+ (* (+ (variable 1 a) (variable 1 b)) (variable 1 b)) (+ (+ (variable 1 a) (variable 1 b)) (variable 1 b)))", 5);
-
-      TestMatchedNodes(
-        "(* (+ 2.84 (exp (+ (log (/ (variable 2.0539 X5) (variable -9.2452e-1 X6))) (/ (variable 2.0539 X5) (variable -9.2452e-1 X6))))) 2.9081)",
-        "(* (- (variable 9.581e-1 X6) (+ (- (variable 5.1491e-1 X5) 1.614e+1) (+ (/ (variable 2.0539 X5) (variable -9.2452e-1 X6)) (log (/ (variable 2.0539 X5) (variable -9.2452e-1 X6)))))) 2.9081)",
-        9);
-
-      TestMatchedNodes("(* (* (* (variable 1.68 x) (* (variable 1.68 x) (variable 2.55 x))) (variable 1.68 x)) (* (* (variable 1.68 x) (* (variable 1.68 x) (* (variable 1.68 x) (variable 2.55 x)))) (variable 2.55 x)))", "(* (variable 2.55 x) (* (variable 1.68 x) (* (variable 1.68 x) (* (variable 1.68 x) (variable 2.55 x)))))", 9);
-
-      TestMatchedNodes("(+ (exp 2.1033) (/ -4.3072 (variable 2.4691 X7)))", "(/ 1 (+ (/ -4.3072 (variable 2.4691 X7)) (exp 2.1033)))", 6);
-      TestMatchedNodes("(+ (exp 2.1033) (/ -4.3072 (variable 2.4691 X7)))", "(/ 1 (+ (/ (variable 2.4691 X7) -4.3072) (exp 2.1033)))", 4);
-
-      const string expr1 = "(* (- 1.2175e+1 (+ (/ (exp -1.4134e+1) (exp 9.2013)) (exp (log (exp (/ (exp (- (* -4.2461 (variable 2.2634 X5)) (- -9.6267e-1 3.3243))) (- (/ (/ (variable 1.0883 X1) (variable 6.9620e-1 X2)) (log 1.3011e+1)) (variable -4.3098e-1 X7)))))))) (log 1.3011e+1))";
-      const string expr2 = "(* (- 1.2175e+1 (+ (/ (/ (+ (variable 3.0140 X9) (variable 1.3430 X8)) -1.0864e+1) (exp 9.2013)) (exp (log (exp (/ (exp (- (* -4.2461 (variable 2.2634 X5)) (- -9.6267e-1 3.3243))) (- (/ (/ (variable 1.0883 X1) (variable 6.9620e-1 X2)) (log 1.3011e+1)) (variable -4.3098e-1 X7)))))))) (exp (variable 4.0899e-1 X7)))";
-
-      TestMatchedNodes(expr1, expr2, 23);
-
+      TestMatchedNodes("(- 2 1)", "(- 1 2)", 2, strict: true);
+      TestMatchedNodes("(- 2 1)", "(- 1 2)", 3, strict: false);
     }
 
-    private void TestMatchedNodes(string expr1, string expr2, int expected) {
+    private void TestMatchedNodes(string expr1, string expr2, int expected, bool strict) {
       var t1 = importer.Import(expr1);
       var t2 = importer.Import(expr2);
 
-      var mapping = busCalculator.ComputeBottomUpMapping(t1.Root, t2.Root);
-      var c = mapping.Count;
+      var map = SymbolicExpressionTreeBottomUpSimilarityCalculator.ComputeBottomUpMapping(t1, t2, strict);
 
-      if (c != expected) {
-        throw new Exception("Match count " + c + " is different than expected value " + expected);
+      if (map.Count != expected) {
+        throw new Exception($"Match count {map.Count} is different than expected value {expected} for expressions:\n{expr1} and {expr2} (strict = {strict})");
       }
     }
@@ -77,5 +61,5 @@
       for (int i = 0; i < trees.Length - 1; ++i) {
         for (int j = i + 1; j < trees.Length; ++j) {
-          s += busCalculator.CalculateSimilarity(trees[i], trees[j]);
+          s += similarityCalculator.CalculateSimilarity(trees[i], trees[j]);
         }
       }
Index: /branches/2904_CalculateImpacts/HeuristicLab.Tests/HeuristicLab.Tests.csproj
===================================================================
--- /branches/2904_CalculateImpacts/HeuristicLab.Tests/HeuristicLab.Tests.csproj	(revision 16401)
+++ /branches/2904_CalculateImpacts/HeuristicLab.Tests/HeuristicLab.Tests.csproj	(revision 16402)
@@ -588,4 +588,5 @@
     <Compile Include="HeuristicLab.Problems.DataAnalysis-3.4\StatisticCalculatorsTest.cs" />
     <Compile Include="HeuristicLab.Problems.DataAnalysis-3.4\RegressionVariableImpactCalculationTest.cs" />
+    <Compile Include="HeuristicLab.Problems.DataAnalysis.Symbolic-3.4\DeriveTest.cs" />
     <Compile Include="HeuristicLab.Problems.DataAnalysis.Symbolic-3.4\InfixExpressionParserTest.cs" />
     <Compile Include="HeuristicLab.Problems.DataAnalysis.Symbolic-3.4\SymbolicExpressionTreeBottomUpSimilarityCalculatorTest.cs" />
