Index: branches/1772_HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/DerivativeCalculator.cs
===================================================================
--- branches/1772_HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/DerivativeCalculator.cs	(revision 17434)
+++ branches/1772_HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/DerivativeCalculator.cs	(revision 17434)
@@ -0,0 +1,275 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+  public static class DerivativeCalculator {
+    public static ISymbolicExpressionTree Derive(ISymbolicExpressionTree tree, string variableName) {
+      if (tree.Root.SubtreeCount != 1)
+        throw new NotImplementedException("Derive is not implemented for symbolic expressions with automatically defined functions (ADF)");
+      if (tree.Root.GetSubtree(0).SubtreeCount != 1)
+        throw new NotImplementedException("Derive is not implemented for multi-variate symbolic expressions");
+      var mainBranch = tree.Root.GetSubtree(0).GetSubtree(0);
+      var root = new ProgramRootSymbol().CreateTreeNode();
+      root.AddSubtree(new StartSymbol().CreateTreeNode());
+      var dTree = TreeSimplifier.GetSimplifiedTree(Derive(mainBranch, variableName));
+      //var dTree = Derive(mainBranch, variableName);
+      root.GetSubtree(0).AddSubtree(dTree);
+      return new SymbolicExpressionTree(root);
+    }
+
+    private static readonly Constant constantSy = new Constant();
+    private static readonly Addition addSy = new Addition();
+    private static readonly Subtraction subSy = new Subtraction();
+    private static readonly Multiplication mulSy = new Multiplication();
+    private static readonly Division divSy = new Division();
+    private static readonly Cosine cosSy = new Cosine();
+    private static readonly Square sqrSy = new Square();
+    private static readonly Absolute absSy = new Absolute();
+    private static readonly SquareRoot sqrtSy = new SquareRoot();
+
+    public static ISymbolicExpressionTreeNode Derive(ISymbolicExpressionTreeNode branch, string variableName) {
+      if (branch.Symbol is Constant) {
+        return CreateConstant(0.0);
+      }
+      if (branch.Symbol is Variable) {
+        var varNode = branch as VariableTreeNode;
+        if (varNode.VariableName == variableName) {
+          return CreateConstant(varNode.Weight);
+        } else {
+          return CreateConstant(0.0);
+        }
+      }
+      if (branch.Symbol is Addition) {
+        var sum = addSy.CreateTreeNode();
+        foreach (var subTree in branch.Subtrees) {
+          sum.AddSubtree(Derive(subTree, variableName));
+        }
+        return sum;
+      }
+      if (branch.Symbol is Subtraction) {
+        var sum = subSy.CreateTreeNode();
+        foreach (var subTree in branch.Subtrees) {
+          sum.AddSubtree(Derive(subTree, variableName));
+        }
+        return sum;
+      }
+      if (branch.Symbol is Multiplication) {
+        // (f * g)' = f'*g + f*g'
+        // for multiple factors: (f * g * h)' = ((f*g) * h)' = (f*g)' * h + (f*g) * h' 
+
+        if (branch.SubtreeCount >= 2) {
+          var f = (ISymbolicExpressionTreeNode)branch.GetSubtree(0).Clone();
+          var fprime = Derive(f, variableName);
+          for (int i = 1; i < branch.SubtreeCount; i++) {
+            var g = (ISymbolicExpressionTreeNode)branch.GetSubtree(i).Clone();
+            var fg = Product((ISymbolicExpressionTreeNode)f.Clone(), (ISymbolicExpressionTreeNode)g.Clone());
+            var gPrime = Derive(g, variableName);
+            var fgPrime = Sum(Product(fprime, g), Product(gPrime, f));
+            // prepare for next iteration
+            f = fg;
+            fprime = fgPrime;
+          }
+          return fprime;
+        } else
+          // multiplication with only one argument has no effect -> derive the argument
+          return Derive(branch.GetSubtree(0), variableName);
+      }
+      if (branch.Symbol is Division) {
+        // (f/g)' = (f'g - g'f) / g²
+        if (branch.SubtreeCount == 1) {
+          var g = (ISymbolicExpressionTreeNode)branch.GetSubtree(0).Clone();
+          var gPrime = Product(CreateConstant(-1.0), Derive(g, variableName));
+          var sqrNode = new Square().CreateTreeNode();
+          sqrNode.AddSubtree(g);
+          return Div(gPrime, sqrNode);
+        } else {
+          // for two subtrees:
+          // (f/g)' = (f'g - fg')/g²
+
+          // if there are more than 2 subtrees
+          // div(x,y,z) is interpretered as (x/y)/z
+          // which is the same as x / (y*z)
+
+          // --> make a product of all but the first subtree and differentiate as for the 2-argument case above
+          var f = (ISymbolicExpressionTreeNode)branch.GetSubtree(0).Clone();
+          var g = Product(branch.Subtrees.Skip(1).Select(n => (ISymbolicExpressionTreeNode)n.Clone()));
+          var fprime = Derive(f, variableName);
+          var gprime = Derive(g, variableName);
+          var gSqr = Square(g);
+          return Div(Subtract(Product(fprime, g), Product(f, gprime)), gSqr);
+        }
+      }
+      if (branch.Symbol is Logarithm) {
+        var f = (ISymbolicExpressionTreeNode)branch.GetSubtree(0).Clone();
+        return Product(Div(CreateConstant(1.0), f), Derive(f, variableName));
+      }
+      if (branch.Symbol is Exponential) {
+        var f = (ISymbolicExpressionTreeNode)branch.Clone();
+        return Product(f, Derive(branch.GetSubtree(0), variableName));
+      }
+      if (branch.Symbol is Square) {
+        var f = (ISymbolicExpressionTreeNode)branch.GetSubtree(0).Clone();
+        return Product(Product(CreateConstant(2.0), f), Derive(f, variableName));
+      }
+      if (branch.Symbol is SquareRoot) {
+        var f = (ISymbolicExpressionTreeNode)branch.Clone();
+        var u = (ISymbolicExpressionTreeNode)branch.GetSubtree(0).Clone();
+        return Product(Div(CreateConstant(1.0), Product(CreateConstant(2.0), f)), Derive(u, variableName));
+      }
+      if (branch.Symbol is CubeRoot) {
+        var f = (ISymbolicExpressionTreeNode)branch.Clone();
+        var u = (ISymbolicExpressionTreeNode)branch.GetSubtree(0).Clone();
+        return Product(Div(CreateConstant(1.0), Product(CreateConstant(3.0), Square(f))), Derive(u, variableName));  // 1/3 1/cbrt(f(x))^2 d/dx f(x)
+      }
+      if (branch.Symbol is Cube) {
+        var f = (ISymbolicExpressionTreeNode)branch.GetSubtree(0).Clone();
+        return Product(Product(CreateConstant(3.0), Square(f)), Derive(f, variableName));
+      }
+      if (branch.Symbol is Absolute) {
+        var f = (ISymbolicExpressionTreeNode)branch.GetSubtree(0).Clone();
+        var absf = Abs((ISymbolicExpressionTreeNode)f.Clone());
+        return Product(Div(f, absf), Derive(f, variableName));
+      }
+      if (branch.Symbol is AnalyticQuotient) {
+        // aq(a(x), b(x)) = a(x) / sqrt(b(x)²+1)
+        var a = (ISymbolicExpressionTreeNode)branch.GetSubtree(0).Clone();
+        var b = (ISymbolicExpressionTreeNode)branch.GetSubtree(1).Clone();
+
+        var definition = Div(a, SquareRoot(Sum(Square(b), CreateConstant(1.0))));
+        return Derive(definition, variableName);
+      }
+      if (branch.Symbol is Sine) {
+        var u = (ISymbolicExpressionTreeNode)branch.GetSubtree(0).Clone();
+        var cos = (new Cosine()).CreateTreeNode();
+        cos.AddSubtree(u);
+        return Product(cos, Derive(u, variableName));
+      }
+      if (branch.Symbol is Cosine) {
+        var u = (ISymbolicExpressionTreeNode)branch.GetSubtree(0).Clone();
+        var sin = (new Sine()).CreateTreeNode();
+        sin.AddSubtree(u);
+        return Product(CreateConstant(-1.0), Product(sin, Derive(u, variableName)));
+      }
+      if (branch.Symbol is Tangent) {
+        // tan(x)' = 1 / cos²(x)
+        var fxp = Derive(branch.GetSubtree(0), variableName);
+        var u = (ISymbolicExpressionTreeNode)branch.GetSubtree(0).Clone();
+        return Div(fxp, Square(Cosine(u)));
+      }
+      if (branch.Symbol is HyperbolicTangent) {
+        // tanh(f(x))' = f(x)'sech²(f(x)) = f(x)'(1 - tanh²(f(x)))
+        var fxp = Derive(branch.GetSubtree(0), variableName);
+        var tanh = (ISymbolicExpressionTreeNode)branch.Clone();
+        return Product(fxp, Subtract(CreateConstant(1.0), Square(tanh)));
+      }
+      throw new NotSupportedException(string.Format("Symbol {0} is not supported.", branch.Symbol));
+    }
+
+
+    private static ISymbolicExpressionTreeNode Product(ISymbolicExpressionTreeNode f, ISymbolicExpressionTreeNode g) {
+      var product = mulSy.CreateTreeNode();
+      product.AddSubtree(f);
+      product.AddSubtree(g);
+      return product;
+    }
+    private static ISymbolicExpressionTreeNode Product(IEnumerable<ISymbolicExpressionTreeNode> fs) {
+      var product = mulSy.CreateTreeNode();
+      foreach (var f in fs) product.AddSubtree(f);
+      return product;
+    }
+    private static ISymbolicExpressionTreeNode Div(ISymbolicExpressionTreeNode f, ISymbolicExpressionTreeNode g) {
+      var div = divSy.CreateTreeNode();
+      div.AddSubtree(f);
+      div.AddSubtree(g);
+      return div;
+    }
+
+    private static ISymbolicExpressionTreeNode Sum(ISymbolicExpressionTreeNode f, ISymbolicExpressionTreeNode g) {
+      var sum = addSy.CreateTreeNode();
+      sum.AddSubtree(f);
+      sum.AddSubtree(g);
+      return sum;
+    }
+    private static ISymbolicExpressionTreeNode Subtract(ISymbolicExpressionTreeNode f, ISymbolicExpressionTreeNode g) {
+      var sum = subSy.CreateTreeNode();
+      sum.AddSubtree(f);
+      sum.AddSubtree(g);
+      return sum;
+    }
+    private static ISymbolicExpressionTreeNode Cosine(ISymbolicExpressionTreeNode f) {
+      var cos = cosSy.CreateTreeNode();
+      cos.AddSubtree(f);
+      return cos;
+    }
+    private static ISymbolicExpressionTreeNode Abs(ISymbolicExpressionTreeNode f) {
+      var abs = absSy.CreateTreeNode();
+      abs.AddSubtree(f);
+      return abs;
+    }
+    private static ISymbolicExpressionTreeNode Square(ISymbolicExpressionTreeNode f) {
+      var sqr = sqrSy.CreateTreeNode();
+      sqr.AddSubtree(f);
+      return sqr;
+    }
+    private static ISymbolicExpressionTreeNode SquareRoot(ISymbolicExpressionTreeNode f) {
+      var sqrt = sqrtSy.CreateTreeNode();
+      sqrt.AddSubtree(f);
+      return sqrt;
+    }
+
+    private static ISymbolicExpressionTreeNode CreateConstant(double v) {
+      var constNode = (ConstantTreeNode)constantSy.CreateTreeNode();
+      constNode.Value = v;
+      return constNode;
+    }
+
+    public static bool IsCompatible(ISymbolicExpressionTree tree) {
+      var containsUnknownSymbol = (
+        from n in tree.Root.GetSubtree(0).IterateNodesPrefix()
+        where
+          !(n.Symbol is Variable) &&
+          !(n.Symbol is Constant) &&
+          !(n.Symbol is Addition) &&
+          !(n.Symbol is Subtraction) &&
+          !(n.Symbol is Multiplication) &&
+          !(n.Symbol is Division) &&
+          !(n.Symbol is Logarithm) &&
+          !(n.Symbol is Exponential) &&
+          !(n.Symbol is Square) &&
+          !(n.Symbol is SquareRoot) &&
+          !(n.Symbol is Cube) &&
+          !(n.Symbol is CubeRoot) &&
+          !(n.Symbol is Absolute) &&
+          !(n.Symbol is AnalyticQuotient) &&
+          !(n.Symbol is Sine) &&
+          !(n.Symbol is Cosine) &&
+          !(n.Symbol is Tangent) &&
+          !(n.Symbol is StartSymbol)
+        select n).Any();
+      return !containsUnknownSymbol;
+    }
+  }
+}
Index: branches/1772_HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/LinearModelToTreeConverter.cs
===================================================================
--- branches/1772_HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/LinearModelToTreeConverter.cs	(revision 16132)
+++ branches/1772_HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/LinearModelToTreeConverter.cs	(revision 17434)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -38,27 +38,34 @@
       double @const = 0) {
 
-      if (factorCoefficients.Length == 0 && coefficients.Length == 0) throw new ArgumentException();
+      if (factorCoefficients.Length == 0 && coefficients.Length == 0 && @const==0) throw new ArgumentException();
+
+      // Combine both trees
+      ISymbolicExpressionTreeNode add = (new Addition()).CreateTreeNode();
 
       // Create tree for double variables
-      ISymbolicExpressionTree tree = null;      
       if (coefficients.Length > 0) {
-        tree = CreateTree(variableNames, new int[variableNames.Length], coefficients, @const);
-        if (factorCoefficients.Length == 0) return tree;
+        var varTree = CreateTree(variableNames, new int[variableNames.Length], coefficients);
+        foreach (var varNode in varTree.IterateNodesPrefix().OfType<VariableTreeNode>())
+          add.AddSubtree(varNode);
       }
 
       // Create tree for string variables
-      ISymbolicExpressionTree factorTree = null;      
       if (factorCoefficients.Length > 0) {
-        factorTree = CreateTree(factors, factorCoefficients, @const);
-        if (tree == null) return factorTree;  
+        var factorTree = CreateTree(factors, factorCoefficients);
+        foreach (var binFactorNode in factorTree.IterateNodesPrefix().OfType<BinaryFactorVariableTreeNode>())
+          add.AddSubtree(binFactorNode);
       }
 
-      // Combine both trees
-      ISymbolicExpressionTreeNode add = tree.Root.GetSubtree(0).GetSubtree(0);
-      foreach (var binFactorNode in factorTree.IterateNodesPrefix().OfType<BinaryFactorVariableTreeNode>())
-        add.InsertSubtree(add.SubtreeCount - 1, binFactorNode);
+      if (@const!=0.0) {
+        ConstantTreeNode cNode = (ConstantTreeNode)new Constant().CreateTreeNode();
+        cNode.Value = @const;
+        add.AddSubtree(cNode);
+      }
+
+      ISymbolicExpressionTree tree = new SymbolicExpressionTree(new ProgramRootSymbol().CreateTreeNode());
+      ISymbolicExpressionTreeNode startNode = new StartSymbol().CreateTreeNode();
+      tree.Root.AddSubtree(startNode);
+      startNode.AddSubtree(add);
       return tree;
-
-      throw new ArgumentException();
     }
 
Index: branches/1772_HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeSimplifier.cs
===================================================================
--- branches/1772_HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeSimplifier.cs	(revision 16132)
+++ branches/1772_HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeSimplifier.cs	(revision 17434)
@@ -2,5 +2,5 @@
 
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -37,4 +37,5 @@
     private static readonly Division divSymbol = new Division();
     private static readonly Constant constSymbol = new Constant();
+    private static readonly Absolute absSymbol = new Absolute();
     private static readonly Logarithm logSymbol = new Logarithm();
     private static readonly Exponential expSymbol = new Exponential();
@@ -42,4 +43,7 @@
     private static readonly Square sqrSymbol = new Square();
     private static readonly SquareRoot sqrtSymbol = new SquareRoot();
+    private static readonly AnalyticQuotient aqSymbol = new AnalyticQuotient();
+    private static readonly Cube cubeSymbol = new Cube();
+    private static readonly CubeRoot cubeRootSymbol = new CubeRoot();
     private static readonly Power powSymbol = new Power();
     private static readonly Sine sineSymbol = new Sine();
@@ -131,4 +135,8 @@
     }
 
+    private static bool IsAbsolute(ISymbolicExpressionTreeNode node) {
+      return node.Symbol is Absolute;
+    }
+
     // exponential
     private static bool IsLog(ISymbolicExpressionTreeNode node) {
@@ -152,4 +160,12 @@
     }
 
+    private static bool IsCube(ISymbolicExpressionTreeNode node) {
+      return node.Symbol is Cube;
+    }
+
+    private static bool IsCubeRoot(ISymbolicExpressionTreeNode node) {
+      return node.Symbol is CubeRoot;
+    }
+
     private static bool IsPower(ISymbolicExpressionTreeNode node) {
       return node.Symbol is Power;
@@ -167,4 +183,8 @@
     private static bool IsTangent(ISymbolicExpressionTreeNode node) {
       return node.Symbol is Tangent;
+    }
+
+    private static bool IsAnalyticalQuotient(ISymbolicExpressionTreeNode node) {
+      return node.Symbol is AnalyticQuotient;
     }
 
@@ -243,4 +263,6 @@
       if (IsConstant(original) || IsVariableBase(original)) {
         return (ISymbolicExpressionTreeNode)original.Clone();
+      } else if (IsAbsolute(original)) {
+        return SimplifyAbsolute(original);
       } else if (IsAddition(original)) {
         return SimplifyAddition(original);
@@ -261,4 +283,8 @@
       } else if (IsSquareRoot(original)) {
         return SimplifySquareRoot(original);
+      } else if (IsCube(original)) {
+        return SimplifyCube(original);
+      } else if (IsCubeRoot(original)) {
+        return SimplifyCubeRoot(original);
       } else if (IsPower(original)) {
         return SimplifyPower(original);
@@ -271,4 +297,6 @@
       } else if (IsTangent(original)) {
         return SimplifyTangent(original);
+      } else if (IsAnalyticalQuotient(original)) {
+        return SimplifyAnalyticalQuotient(original);
       } else if (IsIfThenElse(original)) {
         return SimplifyIfThenElse(original);
@@ -380,4 +408,8 @@
     }
 
+    private static ISymbolicExpressionTreeNode SimplifyAbsolute(ISymbolicExpressionTreeNode original) {
+      return MakeAbs(GetSimplifiedTree(original.GetSubtree(0)));
+    }
+
     private static ISymbolicExpressionTreeNode SimplifyNot(ISymbolicExpressionTreeNode original) {
       return MakeNot(GetSimplifiedTree(original.GetSubtree(0)));
@@ -432,4 +464,11 @@
       return MakeSquareRoot(GetSimplifiedTree(original.GetSubtree(0)));
     }
+    private static ISymbolicExpressionTreeNode SimplifyCube(ISymbolicExpressionTreeNode original) {
+      return MakeCube(GetSimplifiedTree(original.GetSubtree(0)));
+    }
+
+    private static ISymbolicExpressionTreeNode SimplifyCubeRoot(ISymbolicExpressionTreeNode original) {
+      return MakeCubeRoot(GetSimplifiedTree(original.GetSubtree(0)));
+    }
 
     private static ISymbolicExpressionTreeNode SimplifyLog(ISymbolicExpressionTreeNode original) {
@@ -443,4 +482,8 @@
     private static ISymbolicExpressionTreeNode SimplifyPower(ISymbolicExpressionTreeNode original) {
       return MakePower(GetSimplifiedTree(original.GetSubtree(0)), GetSimplifiedTree(original.GetSubtree(1)));
+    }
+
+    private static ISymbolicExpressionTreeNode SimplifyAnalyticalQuotient(ISymbolicExpressionTreeNode original) {
+      return MakeAnalyticalQuotient(GetSimplifiedTree(original.GetSubtree(0)), GetSimplifiedTree(original.GetSubtree(1)));
     }
 
@@ -730,8 +773,94 @@
       } else if (IsSquareRoot(node)) {
         return node.GetSubtree(0);
+      } else if (IsMultiplication(node)) {
+        // sqr( x * y ) = sqr(x) * sqr(y)
+        var mulNode = mulSymbol.CreateTreeNode();
+        foreach (var subtree in node.Subtrees) {
+          mulNode.AddSubtree(MakeSquare(subtree));
+        }
+        return mulNode;
+      } else if (IsAbsolute(node)) {
+        return MakeSquare(node.GetSubtree(0)); // sqr(abs(x)) = sqr(x)
+      } else if (IsExp(node)) {
+        return MakeExp(MakeProduct(node.GetSubtree(0), MakeConstant(2.0))); // sqr(exp(x)) = exp(2x)
+      } else if (IsCube(node)) {
+        return MakePower(node.GetSubtree(0), MakeConstant(6));
       } else {
         var sqrNode = sqrSymbol.CreateTreeNode();
         sqrNode.AddSubtree(node);
         return sqrNode;
+      }
+    }
+
+    private static ISymbolicExpressionTreeNode MakeCube(ISymbolicExpressionTreeNode node) {
+      if (IsConstant(node)) {
+        var constT = node as ConstantTreeNode;
+        return MakeConstant(constT.Value * constT.Value * constT.Value);
+      } else if (IsFactor(node)) {
+        var factNode = node as FactorVariableTreeNode;
+        return MakeFactor(factNode.Symbol, factNode.VariableName, factNode.Weights.Select(w => w * w * w));
+      } else if (IsBinFactor(node)) {
+        var binFactor = node as BinaryFactorVariableTreeNode;
+        return MakeBinFactor(binFactor.Symbol, binFactor.VariableName, binFactor.VariableValue, binFactor.Weight * binFactor.Weight * binFactor.Weight);
+      } else if (IsCubeRoot(node)) {
+        return node.GetSubtree(0); // NOTE: not really accurate because cuberoot(x) with negative x is evaluated to NaN and after this simplification we evaluate as x
+      } else if (IsExp(node)) {
+        return MakeExp(MakeProduct(node.GetSubtree(0), MakeConstant(3)));
+      } else if (IsSquare(node)) {
+        return MakePower(node.GetSubtree(0), MakeConstant(6));
+      } else {
+        var cubeNode = cubeSymbol.CreateTreeNode();
+        cubeNode.AddSubtree(node);
+        return cubeNode;
+      }
+    }
+
+    private static ISymbolicExpressionTreeNode MakeAbs(ISymbolicExpressionTreeNode node) {
+      if (IsConstant(node)) {
+        var constT = node as ConstantTreeNode;
+        return MakeConstant(Math.Abs(constT.Value));
+      } else if (IsFactor(node)) {
+        var factNode = node as FactorVariableTreeNode;
+        return MakeFactor(factNode.Symbol, factNode.VariableName, factNode.Weights.Select(w => Math.Abs(w)));
+      } else if (IsBinFactor(node)) {
+        var binFactor = node as BinaryFactorVariableTreeNode;
+        return MakeBinFactor(binFactor.Symbol, binFactor.VariableName, binFactor.VariableValue, Math.Abs(binFactor.Weight));
+      } else if (IsSquare(node) || IsExp(node) || IsSquareRoot(node) || IsCubeRoot(node)) {
+        return node; // abs(sqr(x)) = sqr(x), abs(exp(x)) = exp(x) ...
+      } else if (IsMultiplication(node)) {
+        var mul = mulSymbol.CreateTreeNode();
+        foreach (var st in node.Subtrees) {
+          mul.AddSubtree(MakeAbs(st));
+        }
+        return mul;
+      } else if (IsDivision(node)) {
+        var div = divSymbol.CreateTreeNode();
+        foreach (var st in node.Subtrees) {
+          div.AddSubtree(MakeAbs(st));
+        }
+        return div;
+      } else {
+        var absNode = absSymbol.CreateTreeNode();
+        absNode.AddSubtree(node);
+        return absNode;
+      }
+    }
+
+    // constant folding only
+    private static ISymbolicExpressionTreeNode MakeAnalyticalQuotient(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {
+      if (IsConstant(b)) {
+        var c = b as ConstantTreeNode;
+        return MakeFraction(a, MakeConstant(Math.Sqrt(1.0 + c.Value * c.Value)));
+      } else if (IsFactor(b)) {
+        var factNode = b as FactorVariableTreeNode;
+        return MakeFraction(a, MakeFactor(factNode.Symbol, factNode.VariableName, factNode.Weights.Select(w => Math.Sqrt(1.0 + w * w))));
+      } else if (IsBinFactor(b)) {
+        var binFactor = b as BinaryFactorVariableTreeNode;
+        return MakeFraction(a, MakeBinFactor(binFactor.Symbol, binFactor.VariableName, binFactor.VariableValue, Math.Sqrt(1.0 + binFactor.Weight * binFactor.Weight)));
+      } else {
+        var aqNode = aqSymbol.CreateTreeNode();
+        aqNode.AddSubtree(a);
+        aqNode.AddSubtree(b);
+        return aqNode;
       }
     }
@@ -748,9 +877,28 @@
         return MakeBinFactor(binFactor.Symbol, binFactor.VariableName, binFactor.VariableValue, Math.Sqrt(binFactor.Weight));
       } else if (IsSquare(node)) {
-        return node.GetSubtree(0);
+        return node.GetSubtree(0); // NOTE: not really accurate because sqrt(x) with negative x is evaluated to NaN and after this simplification we evaluate as x
       } else {
         var sqrtNode = sqrtSymbol.CreateTreeNode();
         sqrtNode.AddSubtree(node);
         return sqrtNode;
+      }
+    }
+
+    private static ISymbolicExpressionTreeNode MakeCubeRoot(ISymbolicExpressionTreeNode node) {
+      if (IsConstant(node)) {
+        var constT = node as ConstantTreeNode;
+        return MakeConstant(Math.Pow(constT.Value, 1.0 / 3.0));
+      } else if (IsFactor(node)) {
+        var factNode = node as FactorVariableTreeNode;
+        return MakeFactor(factNode.Symbol, factNode.VariableName, factNode.Weights.Select(w => Math.Pow(w, 1.0 / 3.0)));
+      } else if (IsBinFactor(node)) {
+        var binFactor = node as BinaryFactorVariableTreeNode;
+        return MakeBinFactor(binFactor.Symbol, binFactor.VariableName, binFactor.VariableValue, Math.Sqrt(Math.Pow(binFactor.Weight, 1.0 / 3.0)));
+      } else if (IsCube(node)) {
+        return node.GetSubtree(0);
+      } else {
+        var cubeRootNode = cubeRootSymbol.CreateTreeNode();
+        cubeRootNode.AddSubtree(node);
+        return cubeRootNode;
       }
     }
@@ -927,4 +1075,6 @@
         // a / (b1 / b2) => (a * b2) / b1
         return MakeFraction(MakeProduct(a, b.GetSubtree(1)), b.GetSubtree(0));
+      } else if (IsAnalyticalQuotient(a)) {
+        return MakeAnalyticalQuotient(a.GetSubtree(0), MakeProduct(a.GetSubtree(1), b));
       } else {
         var div = divSymbol.CreateTreeNode();
@@ -1121,4 +1271,6 @@
         // $ * 1.0 => $
         return a;
+      } else if (IsConstant(b) && ((ConstantTreeNode)b).Value.IsAlmost(0.0)) {
+        return MakeConstant(0);
       } else if (IsConstant(b) && IsVariableBase(a)) {
         // multiply constants into variables weights
@@ -1153,4 +1305,19 @@
         MergeVariablesAndConstantsInProduct(a);
         return a;
+      } else if (IsAbsolute(a) && IsAbsolute(b)) {
+        return MakeAbs(MakeProduct(a.GetSubtree(0), b.GetSubtree(0)));
+      } else if (IsAbsolute(a) && IsConstant(b)) {
+        var constNode = b as ConstantTreeNode;
+        var posF = Math.Abs(constNode.Value);
+        if (constNode.Value > 0) {
+          return MakeAbs(MakeProduct(a.GetSubtree(0), MakeConstant(posF)));
+        } else {
+          var mul = mulSymbol.CreateTreeNode();
+          mul.AddSubtree(MakeAbs(MakeProduct(a.GetSubtree(0), MakeConstant(posF))));
+          mul.AddSubtree(MakeConstant(-1.0));
+          return mul;
+        }
+      } else if (IsAnalyticalQuotient(a)) {
+        return MakeAnalyticalQuotient(MakeProduct(a.GetSubtree(0), b), a.GetSubtree(1));
       } else {
         var mul = mulSymbol.CreateTreeNode();
Index: branches/1772_HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeToAutoDiffTermConverter.cs
===================================================================
--- branches/1772_HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeToAutoDiffTermConverter.cs	(revision 16132)
+++ branches/1772_HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeToAutoDiffTermConverter.cs	(revision 17434)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -76,5 +76,7 @@
       eval: Math.Tan,
       diff: x => 1 + Math.Tan(x) * Math.Tan(x));
-
+    private static readonly Func<Term, UnaryFunc> tanh = UnaryFunc.Factory(
+      eval: Math.Tanh,
+      diff: x => 1 - Math.Tanh(x) * Math.Tanh(x));
     private static readonly Func<Term, UnaryFunc> erf = UnaryFunc.Factory(
       eval: alglib.errorfunction,
@@ -84,4 +86,16 @@
       eval: alglib.normaldistribution,
       diff: x => -(Math.Exp(-(x * x)) * Math.Sqrt(Math.Exp(x * x)) * x) / Math.Sqrt(2 * Math.PI));
+
+    private static readonly Func<Term, UnaryFunc> abs = UnaryFunc.Factory(
+      eval: Math.Abs,
+      diff: x => Math.Sign(x)
+      );
+
+    private static readonly Func<Term, UnaryFunc> cbrt = UnaryFunc.Factory(
+      eval: x => x < 0 ? -Math.Pow(-x, 1.0 / 3) : Math.Pow(x, 1.0 / 3),
+      diff: x => { var cbrt_x = x < 0 ? -Math.Pow(-x, 1.0 / 3) : Math.Pow(x, 1.0 / 3); return 1.0 / (3 * cbrt_x * cbrt_x); }
+      );
+
+
 
     #endregion
@@ -213,4 +227,13 @@
         else return terms.Aggregate((a, b) => new AutoDiff.Product(a, 1.0 / b));
       }
+      if (node.Symbol is Absolute) {
+        var x1 = ConvertToAutoDiff(node.GetSubtree(0));
+        return abs(x1);
+      }
+      if (node.Symbol is AnalyticQuotient) {
+        var x1 = ConvertToAutoDiff(node.GetSubtree(0));
+        var x2 = ConvertToAutoDiff(node.GetSubtree(1));
+        return x1 / (TermBuilder.Power(1 + x2 * x2, 0.5));
+      }
       if (node.Symbol is Logarithm) {
         return AutoDiff.TermBuilder.Log(
@@ -229,4 +252,11 @@
           ConvertToAutoDiff(node.GetSubtree(0)), 0.5);
       }
+      if (node.Symbol is Cube) {
+        return AutoDiff.TermBuilder.Power(
+          ConvertToAutoDiff(node.GetSubtree(0)), 3.0);
+      }
+      if (node.Symbol is CubeRoot) {
+        return cbrt(ConvertToAutoDiff(node.GetSubtree(0)));
+      }
       if (node.Symbol is Sine) {
         return sin(
@@ -239,4 +269,8 @@
       if (node.Symbol is Tangent) {
         return tan(
+          ConvertToAutoDiff(node.GetSubtree(0)));
+      }
+      if (node.Symbol is HyperbolicTangent) {
+        return tanh(
           ConvertToAutoDiff(node.GetSubtree(0)));
       }
@@ -299,7 +333,12 @@
           !(n.Symbol is Cosine) &&
           !(n.Symbol is Tangent) &&
+          !(n.Symbol is HyperbolicTangent) &&
           !(n.Symbol is Erf) &&
           !(n.Symbol is Norm) &&
-          !(n.Symbol is StartSymbol)
+          !(n.Symbol is StartSymbol) &&
+          !(n.Symbol is Absolute) &&
+          !(n.Symbol is AnalyticQuotient) &&
+          !(n.Symbol is Cube) &&
+          !(n.Symbol is CubeRoot)
         select n).Any();
       return !containsUnknownSymbol;
