Index: stable/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.csproj
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.csproj	(revision 15136)
+++ stable/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.csproj	(revision 15141)
@@ -102,8 +102,4 @@
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\bin\ALGLIB-3.7.0.dll</HintPath>
-      <Private>False</Private>
-    </Reference>
-    <Reference Include="AutoDiff-1.0, Version=1.0.0.14388, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
-      <HintPath>..\..\bin\AutoDiff-1.0.dll</HintPath>
       <Private>False</Private>
     </Reference>
Index: stable/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/Plugin.cs.frame
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/Plugin.cs.frame	(revision 15136)
+++ stable/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/Plugin.cs.frame	(revision 15141)
@@ -29,5 +29,4 @@
   [PluginFile("HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.dll", PluginFileType.Assembly)]
   [PluginDependency("HeuristicLab.ALGLIB", "3.7.0")]
-  [PluginDependency("HeuristicLab.AutoDiff", "1.0")]
   [PluginDependency("HeuristicLab.Analysis", "3.3")]
   [PluginDependency("HeuristicLab.Common", "3.3")]
Index: stable/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionConstantOptimizationEvaluator.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionConstantOptimizationEvaluator.cs	(revision 15136)
+++ stable/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionConstantOptimizationEvaluator.cs	(revision 15141)
@@ -23,5 +23,4 @@
 using System.Collections.Generic;
 using System.Linq;
-using AutoDiff;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -153,28 +152,4 @@
     }
 
-    #region derivations of functions
-    // create function factory for arctangent
-    private readonly Func<Term, UnaryFunc> arctan = UnaryFunc.Factory(
-      eval: Math.Atan,
-      diff: x => 1 / (1 + x * x));
-    private static readonly Func<Term, UnaryFunc> sin = UnaryFunc.Factory(
-      eval: Math.Sin,
-      diff: Math.Cos);
-    private static readonly Func<Term, UnaryFunc> cos = UnaryFunc.Factory(
-       eval: Math.Cos,
-       diff: x => -Math.Sin(x));
-    private static readonly Func<Term, UnaryFunc> tan = UnaryFunc.Factory(
-      eval: Math.Tan,
-      diff: x => 1 + Math.Tan(x) * Math.Tan(x));
-    private static readonly Func<Term, UnaryFunc> erf = UnaryFunc.Factory(
-      eval: alglib.errorfunction,
-      diff: x => 2.0 * Math.Exp(-(x * x)) / Math.Sqrt(Math.PI));
-    private static readonly Func<Term, UnaryFunc> norm = UnaryFunc.Factory(
-      eval: alglib.normaldistribution,
-      diff: x => -(Math.Exp(-(x * x)) * Math.Sqrt(Math.Exp(x * x)) * x) / Math.Sqrt(2 * Math.PI));
-    #endregion
-
-
-
     public static double OptimizeConstants(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
       ISymbolicExpressionTree tree, IRegressionProblemData problemData, IEnumerable<int> rows, bool applyLinearScaling,
@@ -188,46 +163,21 @@
       // variable name, variable value (for factor vars) and lag as a DataForVariable object.
       // A dictionary is used to find parameters
-      var variables = new List<AutoDiff.Variable>();
-      var parameters = new Dictionary<DataForVariable, AutoDiff.Variable>();
-
-      AutoDiff.Term func;
-      if (!TryTransformToAutoDiff(tree.Root.GetSubtree(0), variables, parameters, updateVariableWeights, out func))
+      double[] initialConstants;
+      var parameters = new List<TreeToAutoDiffTermTransformator.DataForVariable>();
+
+      TreeToAutoDiffTermTransformator.ParametricFunction func;
+      TreeToAutoDiffTermTransformator.ParametricFunctionGradient func_grad;
+      if (!TreeToAutoDiffTermTransformator.TryTransformToAutoDiff(tree, updateVariableWeights, out parameters, out initialConstants, out func, out func_grad))
         throw new NotSupportedException("Could not optimize constants of symbolic expression tree due to not supported symbols used in the tree.");
       if (parameters.Count == 0) return 0.0; // gkronber: constant expressions always have a R² of 0.0 
 
       var parameterEntries = parameters.ToArray(); // order of entries must be the same for x
-      AutoDiff.IParametricCompiledTerm compiledFunc = func.Compile(variables.ToArray(), parameterEntries.Select(kvp => kvp.Value).ToArray());
-
-      List<SymbolicExpressionTreeTerminalNode> terminalNodes = null; // gkronber only used for extraction of initial constants
-      if (updateVariableWeights)
-        terminalNodes = tree.Root.IterateNodesPrefix().OfType<SymbolicExpressionTreeTerminalNode>().ToList();
-      else
-        terminalNodes = new List<SymbolicExpressionTreeTerminalNode>
-          (tree.Root.IterateNodesPrefix()
-          .OfType<SymbolicExpressionTreeTerminalNode>()
-          .Where(node => node is ConstantTreeNode || node is FactorVariableTreeNode));
 
       //extract inital constants
-      double[] c = new double[variables.Count];
+      double[] c = new double[initialConstants.Length];
       {
         c[0] = 0.0;
         c[1] = 1.0;
-        int i = 2;
-        foreach (var node in terminalNodes) {
-          ConstantTreeNode constantTreeNode = node as ConstantTreeNode;
-          VariableTreeNode variableTreeNode = node as VariableTreeNode;
-          BinaryFactorVariableTreeNode binFactorVarTreeNode = node as BinaryFactorVariableTreeNode;
-          FactorVariableTreeNode factorVarTreeNode = node as FactorVariableTreeNode;
-          if (constantTreeNode != null)
-            c[i++] = constantTreeNode.Value;
-          else if (updateVariableWeights && variableTreeNode != null)
-            c[i++] = variableTreeNode.Weight;
-          else if (updateVariableWeights && binFactorVarTreeNode != null)
-            c[i++] = binFactorVarTreeNode.Weight;
-          else if (factorVarTreeNode != null) {
-            // gkronber: a factorVariableTreeNode holds a category-specific constant therefore we can consider factors to be the same as constants
-            foreach (var w in factorVarTreeNode.Weights) c[i++] = w;
-          }
-        }
+        Array.Copy(initialConstants, 0, c, 2, initialConstants.Length);
       }
       double[] originalConstants = (double[])c.Clone();
@@ -243,6 +193,5 @@
       foreach (var r in rows) {
         int col = 0;
-        foreach (var kvp in parameterEntries) {
-          var info = kvp.Key;
+        foreach (var info in parameterEntries) {
           if (ds.VariableHasType<double>(info.variableName)) {
             x[row, col] = ds.GetDoubleValue(info.variableName, r + info.lag);
@@ -259,6 +208,6 @@
       int k = c.Length;
 
-      alglib.ndimensional_pfunc function_cx_1_func = CreatePFunc(compiledFunc);
-      alglib.ndimensional_pgrad function_cx_1_grad = CreatePGrad(compiledFunc);
+      alglib.ndimensional_pfunc function_cx_1_func = CreatePFunc(func);
+      alglib.ndimensional_pgrad function_cx_1_grad = CreatePGrad(func_grad);
 
       try {
@@ -305,304 +254,20 @@
     }
 
-    private static alglib.ndimensional_pfunc CreatePFunc(AutoDiff.IParametricCompiledTerm compiledFunc) {
-      return (double[] c, double[] x, ref double func, object o) => {
-        func = compiledFunc.Evaluate(c, x);
+    private static alglib.ndimensional_pfunc CreatePFunc(TreeToAutoDiffTermTransformator.ParametricFunction func) {
+      return (double[] c, double[] x, ref double fx, object o) => {
+        fx = func(c, x);
       };
     }
 
-    private static alglib.ndimensional_pgrad CreatePGrad(AutoDiff.IParametricCompiledTerm compiledFunc) {
-      return (double[] c, double[] x, ref double func, double[] grad, object o) => {
-        var tupel = compiledFunc.Differentiate(c, x);
-        func = tupel.Item2;
+    private static alglib.ndimensional_pgrad CreatePGrad(TreeToAutoDiffTermTransformator.ParametricFunctionGradient func_grad) {
+      return (double[] c, double[] x, ref double fx, double[] grad, object o) => {
+        var tupel = func_grad(c, x);
+        fx = tupel.Item2;
         Array.Copy(tupel.Item1, grad, grad.Length);
       };
     }
-
-    private static bool TryTransformToAutoDiff(ISymbolicExpressionTreeNode node,
-      List<AutoDiff.Variable> variables, Dictionary<DataForVariable, AutoDiff.Variable> parameters,
-      bool updateVariableWeights, out AutoDiff.Term term) {
-      if (node.Symbol is Constant) {
-        var var = new AutoDiff.Variable();
-        variables.Add(var);
-        term = var;
-        return true;
-      }
-      if (node.Symbol is Variable || node.Symbol is BinaryFactorVariable) {
-        var varNode = node as VariableTreeNodeBase;
-        var factorVarNode = node as BinaryFactorVariableTreeNode;
-        // factor variable values are only 0 or 1 and set in x accordingly
-        var varValue = factorVarNode != null ? factorVarNode.VariableValue : string.Empty;
-        var par = FindOrCreateParameter(parameters, varNode.VariableName, varValue);
-
-        if (updateVariableWeights) {
-          var w = new AutoDiff.Variable();
-          variables.Add(w);
-          term = AutoDiff.TermBuilder.Product(w, par);
-        } else {
-          term = varNode.Weight * par;
-        }
-        return true;
-      }
-      if (node.Symbol is FactorVariable) {
-        var factorVarNode = node as FactorVariableTreeNode;
-        var products = new List<Term>();
-        foreach (var variableValue in factorVarNode.Symbol.GetVariableValues(factorVarNode.VariableName)) {
-          var par = FindOrCreateParameter(parameters, factorVarNode.VariableName, variableValue);
-
-          var wVar = new AutoDiff.Variable();
-          variables.Add(wVar);
-
-          products.Add(AutoDiff.TermBuilder.Product(wVar, par));
-        }
-        term = AutoDiff.TermBuilder.Sum(products);
-        return true;
-      }
-      if (node.Symbol is LaggedVariable) {
-        var varNode = node as LaggedVariableTreeNode;
-        var par = FindOrCreateParameter(parameters, varNode.VariableName, string.Empty, varNode.Lag);
-
-        if (updateVariableWeights) {
-          var w = new AutoDiff.Variable();
-          variables.Add(w);
-          term = AutoDiff.TermBuilder.Product(w, par);
-        } else {
-          term = varNode.Weight * par;
-        }
-        return true;
-      }
-      if (node.Symbol is Addition) {
-        List<AutoDiff.Term> terms = new List<Term>();
-        foreach (var subTree in node.Subtrees) {
-          AutoDiff.Term t;
-          if (!TryTransformToAutoDiff(subTree, variables, parameters, updateVariableWeights, out t)) {
-            term = null;
-            return false;
-          }
-          terms.Add(t);
-        }
-        term = AutoDiff.TermBuilder.Sum(terms);
-        return true;
-      }
-      if (node.Symbol is Subtraction) {
-        List<AutoDiff.Term> terms = new List<Term>();
-        for (int i = 0; i < node.SubtreeCount; i++) {
-          AutoDiff.Term t;
-          if (!TryTransformToAutoDiff(node.GetSubtree(i), variables, parameters, updateVariableWeights, out t)) {
-            term = null;
-            return false;
-          }
-          if (i > 0) t = -t;
-          terms.Add(t);
-        }
-        if (terms.Count == 1) term = -terms[0];
-        else term = AutoDiff.TermBuilder.Sum(terms);
-        return true;
-      }
-      if (node.Symbol is Multiplication) {
-        List<AutoDiff.Term> terms = new List<Term>();
-        foreach (var subTree in node.Subtrees) {
-          AutoDiff.Term t;
-          if (!TryTransformToAutoDiff(subTree, variables, parameters, updateVariableWeights, out t)) {
-            term = null;
-            return false;
-          }
-          terms.Add(t);
-        }
-        if (terms.Count == 1) term = terms[0];
-        else term = terms.Aggregate((a, b) => new AutoDiff.Product(a, b));
-        return true;
-
-      }
-      if (node.Symbol is Division) {
-        List<AutoDiff.Term> terms = new List<Term>();
-        foreach (var subTree in node.Subtrees) {
-          AutoDiff.Term t;
-          if (!TryTransformToAutoDiff(subTree, variables, parameters, updateVariableWeights, out t)) {
-            term = null;
-            return false;
-          }
-          terms.Add(t);
-        }
-        if (terms.Count == 1) term = 1.0 / terms[0];
-        else term = terms.Aggregate((a, b) => new AutoDiff.Product(a, 1.0 / b));
-        return true;
-      }
-      if (node.Symbol is Logarithm) {
-        AutoDiff.Term t;
-        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, updateVariableWeights, out t)) {
-          term = null;
-          return false;
-        } else {
-          term = AutoDiff.TermBuilder.Log(t);
-          return true;
-        }
-      }
-      if (node.Symbol is Exponential) {
-        AutoDiff.Term t;
-        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, updateVariableWeights, out t)) {
-          term = null;
-          return false;
-        } else {
-          term = AutoDiff.TermBuilder.Exp(t);
-          return true;
-        }
-      }
-      if (node.Symbol is Square) {
-        AutoDiff.Term t;
-        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, updateVariableWeights, out t)) {
-          term = null;
-          return false;
-        } else {
-          term = AutoDiff.TermBuilder.Power(t, 2.0);
-          return true;
-        }
-      }
-      if (node.Symbol is SquareRoot) {
-        AutoDiff.Term t;
-        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, updateVariableWeights, out t)) {
-          term = null;
-          return false;
-        } else {
-          term = AutoDiff.TermBuilder.Power(t, 0.5);
-          return true;
-        }
-      }
-      if (node.Symbol is Sine) {
-        AutoDiff.Term t;
-        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, updateVariableWeights, out t)) {
-          term = null;
-          return false;
-        } else {
-          term = sin(t);
-          return true;
-        }
-      }
-      if (node.Symbol is Cosine) {
-        AutoDiff.Term t;
-        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, updateVariableWeights, out t)) {
-          term = null;
-          return false;
-        } else {
-          term = cos(t);
-          return true;
-        }
-      }
-      if (node.Symbol is Tangent) {
-        AutoDiff.Term t;
-        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, updateVariableWeights, out t)) {
-          term = null;
-          return false;
-        } else {
-          term = tan(t);
-          return true;
-        }
-      }
-      if (node.Symbol is Erf) {
-        AutoDiff.Term t;
-        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, updateVariableWeights, out t)) {
-          term = null;
-          return false;
-        } else {
-          term = erf(t);
-          return true;
-        }
-      }
-      if (node.Symbol is Norm) {
-        AutoDiff.Term t;
-        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, updateVariableWeights, out t)) {
-          term = null;
-          return false;
-        } else {
-          term = norm(t);
-          return true;
-        }
-      }
-      if (node.Symbol is StartSymbol) {
-        var alpha = new AutoDiff.Variable();
-        var beta = new AutoDiff.Variable();
-        variables.Add(beta);
-        variables.Add(alpha);
-        AutoDiff.Term branchTerm;
-        if (TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, updateVariableWeights, out branchTerm)) {
-          term = branchTerm * alpha + beta;
-          return true;
-        } else {
-          term = null;
-          return false;
-        }
-      }
-      term = null;
-      return false;
-    }
-
-    // for each factor variable value we need a parameter which represents a binary indicator for that variable & value combination
-    // each binary indicator is only necessary once. So we only create a parameter if this combination is not yet available
-    private static Term FindOrCreateParameter(Dictionary<DataForVariable, AutoDiff.Variable> parameters,
-      string varName, string varValue = "", int lag = 0) {
-      var data = new DataForVariable(varName, varValue, lag);
-
-      AutoDiff.Variable par = null;
-      if (!parameters.TryGetValue(data, out par)) {
-        // not found -> create new parameter and entries in names and values lists
-        par = new AutoDiff.Variable();
-        parameters.Add(data, par);
-      }
-      return par;
-    }
-
     public static bool CanOptimizeConstants(ISymbolicExpressionTree tree) {
-      var containsUnknownSymbol = (
-        from n in tree.Root.GetSubtree(0).IterateNodesPrefix()
-        where
-         !(n.Symbol is Variable) &&
-         !(n.Symbol is BinaryFactorVariable) &&
-         !(n.Symbol is FactorVariable) &&
-         !(n.Symbol is LaggedVariable) &&
-         !(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 SquareRoot) &&
-         !(n.Symbol is Square) &&
-         !(n.Symbol is Sine) &&
-         !(n.Symbol is Cosine) &&
-         !(n.Symbol is Tangent) &&
-         !(n.Symbol is Erf) &&
-         !(n.Symbol is Norm) &&
-         !(n.Symbol is StartSymbol)
-        select n).
-      Any();
-      return !containsUnknownSymbol;
-    }
-
-
-    #region helper class
-    private class DataForVariable {
-      public readonly string variableName;
-      public readonly string variableValue; // for factor vars
-      public readonly int lag;
-
-      public DataForVariable(string varName, string varValue, int lag) {
-        this.variableName = varName;
-        this.variableValue = varValue;
-        this.lag = lag;
-      }
-
-      public override bool Equals(object obj) {
-        var other = obj as DataForVariable;
-        if (other == null) return false;
-        return other.variableName.Equals(this.variableName) &&
-               other.variableValue.Equals(this.variableValue) &&
-               other.lag == this.lag;
-      }
-
-      public override int GetHashCode() {
-        return variableName.GetHashCode() ^ variableValue.GetHashCode() ^ lag;
-      }
-    }
-    #endregion
+      return TreeToAutoDiffTermTransformator.IsCompatible(tree);
+    }
   }
 }
