Index: stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/DerivativeCalculator.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/DerivativeCalculator.cs	(revision 17066)
+++ stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/DerivativeCalculator.cs	(revision 17066)
@@ -0,0 +1,231 @@
+﻿#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 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();
+
+    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 g = (ISymbolicExpressionTreeNode)branch.GetSubtree(1).Clone();
+          var fprime = Derive(f, variableName);
+          var gprime = Derive(g, variableName);
+          var fgPrime = Sum(Product(f, gprime), Product(fprime, g));
+          for (int i = 2; i < branch.SubtreeCount; i++) {
+            var fg = Product((ISymbolicExpressionTreeNode)f.Clone(), (ISymbolicExpressionTreeNode)g.Clone());
+            var h = (ISymbolicExpressionTreeNode)branch.GetSubtree(i).Clone();
+            var hPrime = Derive(h, variableName);
+            fgPrime = Sum(Product(fgPrime, h), Product(fg, hPrime));
+          }
+          return fgPrime;
+        } 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 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)));
+      }
+      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 Square(ISymbolicExpressionTreeNode f) {
+      var sqr = sqrSy.CreateTreeNode();
+      sqr.AddSubtree(f);
+      return sqr;
+    }
+
+    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 Sine) &&
+          !(n.Symbol is Cosine) &&
+          !(n.Symbol is Tangent) &&
+          !(n.Symbol is StartSymbol)
+        select n).Any();
+      return !containsUnknownSymbol;
+    }
+  }
+}
Index: stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeSimplifier.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeSimplifier.cs	(revision 17065)
+++ stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeSimplifier.cs	(revision 17066)
@@ -1121,4 +1121,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
Index: stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj	(revision 17065)
+++ stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj	(revision 17066)
@@ -139,4 +139,5 @@
     <Compile Include="Converters\LinearModelToTreeConverter.cs" />
     <Compile Include="Converters\TreeSimplifier.cs" />
+    <Compile Include="Converters\DerivativeCalculator.cs" />
     <Compile Include="Converters\TreeToAutoDiffTermConverter.cs" />
     <Compile Include="Formatters\InfixExpressionFormatter.cs" />
Index: stable/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/DeriveTest.cs
===================================================================
--- stable/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/DeriveTest.cs	(revision 17066)
+++ stable/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/DeriveTest.cs	(revision 17066)
@@ -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' * 'z' * 20)))", // 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' * 'z' * 20)))", // 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' * 'z' * 20)))",
+          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: stable/HeuristicLab.Tests/HeuristicLab.Tests.csproj
===================================================================
--- stable/HeuristicLab.Tests/HeuristicLab.Tests.csproj	(revision 17065)
+++ stable/HeuristicLab.Tests/HeuristicLab.Tests.csproj	(revision 17066)
@@ -594,4 +594,5 @@
     <Compile Include="HeuristicLab.Problems.DataAnalysis-3.4\OnlineCalculatorPerformanceTest.cs" />
     <Compile Include="HeuristicLab.Problems.DataAnalysis-3.4\StatisticCalculatorsTest.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\IntervalInterpreterTest.cs" />
