Index: /branches/3040_VectorBasedGP/HeuristicLab.DiffSharp/HeuristicLab.DiffSharp.csproj
===================================================================
--- /branches/3040_VectorBasedGP/HeuristicLab.DiffSharp/HeuristicLab.DiffSharp.csproj	(revision 17785)
+++ /branches/3040_VectorBasedGP/HeuristicLab.DiffSharp/HeuristicLab.DiffSharp.csproj	(revision 17786)
@@ -68,4 +68,7 @@
       <PrivateAssets>all</PrivateAssets>
     </PackageReference>
+    <PackageReference Include="StrongNamer">
+      <Version>0.2.5</Version>
+    </PackageReference>
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
Index: /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/InteractiveSymbolicRegressionSolutionSimplifierView.cs
===================================================================
--- /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/InteractiveSymbolicRegressionSolutionSimplifierView.cs	(revision 17785)
+++ /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/InteractiveSymbolicRegressionSolutionSimplifierView.cs	(revision 17786)
@@ -46,4 +46,6 @@
       btnVectorOptimizeConstants.Enabled = tree != null && TensorFlowConstantOptimizationEvaluator.CanOptimizeConstants(tree);
       nudLearningRate.Enabled = tree != null && TensorFlowConstantOptimizationEvaluator.CanOptimizeConstants(tree);
+      btnUnrollingVectorOptimizeConstants.Enabled = tree != null && VectorUnrollingNonlinearLeastSquaresConstantOptimizationEvaluator.CanOptimizeConstants(tree);
+      btnDiffSharpOptimizeConstants.Enabled = tree != null && NonlinearLeastSquaresVectorConstantOptimizationEvaluator.CanOptimizeConstants(tree);
     }
 
@@ -102,4 +104,67 @@
     }
 
+    protected override ISymbolicExpressionTree UnrollingVectorOptimizeConstants(ISymbolicExpressionTree tree, CancellationToken cancellationToken, IProgress progress) {
+      const int constOptIterations = 50;
+      const int maxRepetitions = 100;
+      const double minimumImprovement = 1e-10;
+      var regressionProblemData = Content.ProblemData;
+      var model = Content.Model;
+      progress.CanBeStopped = true;
+      double prevResult = 0.0, improvement = 0.0;
+      var result = 0.0;
+      int reps = 0;
+      var interpreter = new SymbolicDataAnalysisExpressionTreeVectorInterpreter();
+
+      do {
+        prevResult = result;
+        tree = VectorUnrollingNonlinearLeastSquaresConstantOptimizationEvaluator.OptimizeTree(
+          tree, interpreter,
+          regressionProblemData, regressionProblemData.TrainingIndices,
+          applyLinearScaling: true, maxIterations: constOptIterations, updateVariableWeights: true,
+          cancellationToken: cancellationToken, iterationCallback: (args, func, obj) => {
+            double newProgressValue = progress.ProgressValue + (1.0 / (constOptIterations + 2) / maxRepetitions); // (constOptIterations + 2) iterations are reported
+            progress.ProgressValue = Math.Min(newProgressValue, 1.0);
+          });
+        result = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(model.Interpreter, tree,
+          model.LowerEstimationLimit, model.UpperEstimationLimit, regressionProblemData, regressionProblemData.TrainingIndices, applyLinearScaling: true);
+        reps++;
+        improvement = result - prevResult;
+      } while (improvement > minimumImprovement && reps < maxRepetitions &&
+               progress.ProgressState != ProgressState.StopRequested &&
+               progress.ProgressState != ProgressState.CancelRequested);
+      return tree;
+    }
+
+
+    protected override ISymbolicExpressionTree DiffSharpVectorOptimizeConstants(ISymbolicExpressionTree tree, CancellationToken cancellationToken, IProgress progress) {
+      const int constOptIterations = 50;
+      const int maxRepetitions = 100;
+      const double minimumImprovement = 1e-10;
+      var regressionProblemData = Content.ProblemData;
+      var model = Content.Model;
+      progress.CanBeStopped = true;
+      double prevResult = 0.0, improvement = 0.0;
+      var result = 0.0;
+      int reps = 0;
+
+      do {
+        prevResult = result;
+        tree = NonlinearLeastSquaresVectorConstantOptimizationEvaluator.OptimizeTree(tree, regressionProblemData, regressionProblemData.TrainingIndices,
+          applyLinearScaling: true, maxIterations: constOptIterations, updateVariableWeights: true,
+          cancellationToken: cancellationToken, iterationCallback: (args, func, obj) => {
+            double newProgressValue = progress.ProgressValue + (1.0 / (constOptIterations + 2) / maxRepetitions); // (constOptIterations + 2) iterations are reported
+            progress.ProgressValue = Math.Min(newProgressValue, 1.0);
+          });
+        result = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(model.Interpreter, tree,
+          model.LowerEstimationLimit, model.UpperEstimationLimit, regressionProblemData, regressionProblemData.TrainingIndices, applyLinearScaling: true);
+        reps++;
+        improvement = result - prevResult;
+      } while (improvement > minimumImprovement && reps < maxRepetitions &&
+               progress.ProgressState != ProgressState.StopRequested &&
+               progress.ProgressState != ProgressState.CancelRequested);
+      return tree;
+    }
+
+
     internal class SynchronousProgress<T> : IProgress<T> {
       private readonly Action<T> callback;
Index: /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.csproj
===================================================================
--- /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.csproj	(revision 17785)
+++ /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.csproj	(revision 17786)
@@ -110,4 +110,8 @@
       <Private>False</Private>
     </Reference>
+    <Reference Include="DiffSharp, Version=0.7.7.0, Culture=neutral, processorArchitecture=AMD64">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\bin\DiffSharp.dll</HintPath>
+    </Reference>
     <Reference Include="MathNet.Numerics">
       <HintPath>..\..\bin\MathNet.Numerics.dll</HintPath>
@@ -141,4 +145,5 @@
     <Compile Include="Plugin.cs" />
     <Compile Include="SingleObjective\ConstantOptimizationAnalyzer.cs" />
+    <Compile Include="SingleObjective\Evaluators\NonlinearLeastSquaresVectorConstantOptimizationEvaluator.cs" />
     <Compile Include="SingleObjective\Evaluators\VectorUnrollingNonlinearLeastSquaresConstantOptimizationEvaluator.cs" />
     <Compile Include="SingleObjective\Evaluators\NonlinearLeastSquaresConstantOptimizationEvaluator.cs" />
Index: /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/Plugin.cs.frame
===================================================================
--- /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/Plugin.cs.frame	(revision 17785)
+++ /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/Plugin.cs.frame	(revision 17786)
@@ -43,4 +43,5 @@
   [PluginDependency("HeuristicLab.MathNet.Numerics", "4.9.0")]
   [PluginDependency("HeuristicLab.TensorFlowNet", "0.15.0")]
+  [PluginDependency("HeuristicLab.DiffSharp", "0.7.7")]
   public class HeuristicLabProblemsDataAnalysisSymbolicRegressionPlugin : PluginBase {
   }
Index: /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/NonlinearLeastSquaresVectorConstantOptimizationEvaluator.cs
===================================================================
--- /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/NonlinearLeastSquaresVectorConstantOptimizationEvaluator.cs	(revision 17786)
+++ /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/NonlinearLeastSquaresVectorConstantOptimizationEvaluator.cs	(revision 17786)
@@ -0,0 +1,195 @@
+#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 System.Threading;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Parameters;
+using HEAL.Attic;
+using DiffSharp.Interop.Float64;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
+  [StorableType("7BC8666F-DB02-405A-9567-8378C7BBDE9A")]
+  [Item("NonlinearLeastSquaresVectorConstantOptimizationEvaluator", "")]
+  public class NonlinearLeastSquaresVectorConstantOptimizationEvaluator : SymbolicRegressionConstantOptimizationEvaluator {
+
+    private const string ConstantOptimizationIterationsName = "ConstantOptimizationIterations";
+
+    #region Parameter Properties
+    public IFixedValueParameter<IntValue> ConstantOptimizationIterationsParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[ConstantOptimizationIterationsName]; }
+    }
+    #endregion
+
+    #region Properties
+    public int ConstantOptimizationIterations {
+      get { return ConstantOptimizationIterationsParameter.Value.Value; }
+      set { ConstantOptimizationIterationsParameter.Value.Value = value; }
+    }
+    #endregion
+
+    public NonlinearLeastSquaresVectorConstantOptimizationEvaluator()
+      : base() {
+      Parameters.Add(new FixedValueParameter<IntValue>(ConstantOptimizationIterationsName, "Determines how many iterations should be calculated while optimizing the constant of a symbolic expression tree(0 indicates other or default stopping criterion).", new IntValue(10)));
+    }
+
+    protected NonlinearLeastSquaresVectorConstantOptimizationEvaluator(NonlinearLeastSquaresVectorConstantOptimizationEvaluator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new NonlinearLeastSquaresVectorConstantOptimizationEvaluator(this, cloner);
+    }
+    [StorableConstructor]
+    protected NonlinearLeastSquaresVectorConstantOptimizationEvaluator(StorableConstructorFlag _) : base(_) { }
+
+    protected override ISymbolicExpressionTree OptimizeConstants(
+      ISymbolicExpressionTree tree, IRegressionProblemData problemData, IEnumerable<int> rows,
+      CancellationToken cancellationToken = default(CancellationToken), EvaluationsCounter counter = null) {
+      return OptimizeTree(tree,
+        problemData, rows,
+        ApplyLinearScalingParameter.ActualValue.Value, ConstantOptimizationIterations, UpdateVariableWeights,
+        cancellationToken, counter);
+    }
+
+    public static ISymbolicExpressionTree OptimizeTree(
+      ISymbolicExpressionTree tree,
+      IRegressionProblemData problemData, IEnumerable<int> rows,
+      bool applyLinearScaling, int maxIterations, bool updateVariableWeights,
+      CancellationToken cancellationToken = default(CancellationToken), EvaluationsCounter counter = null, Action<double[], double, object> iterationCallback = null) {
+
+
+
+      DV targets = new DV(problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows).ToArray());
+      DV Predictions(DV variables) {
+        var predictions = rows.Select(row => {
+          var scalarParams = problemData.AllowedInputVariables.Intersect(problemData.Dataset.DoubleVariables)
+            .ToDictionary(var => var, var => new D(problemData.Dataset.GetDoubleValue(var, row)));
+          var vectorParams = problemData.AllowedInputVariables.Intersect(problemData.Dataset.DoubleVectorVariables)
+            .ToDictionary(var => var, var => new DV(problemData.Dataset.GetDoubleVectorValue(var, row).ToArray()));
+
+          return TreeToDiffSharpConverter.Evaluate(tree,
+            updateVariableWeights, applyLinearScaling,
+            variables,
+            scalarParams, vectorParams);
+        }).ToArray();
+        return new DV(predictions);
+      }
+      D Mse(DV vars) => DV.Mean(DV.Pow(targets - Predictions(vars), 2));
+
+      Func<DV, D> loss = Mse;
+      Func<DV, DV> lossGrad = AD.Grad(loss);
+      Func<DV, DM> lossHess = AD.Hessian(loss);
+
+      var initialConstants = TreeToDiffSharpConverter.GetInitialConstants(tree,
+        updateVariableWeights, applyLinearScaling,
+        problemData.AllowedInputVariables.Intersect(problemData.Dataset.DoubleVariables)
+          .ToDictionary(var => var, var => new D(problemData.Dataset.GetDoubleValue(var, rows.First()))),
+        problemData.AllowedInputVariables.Intersect(problemData.Dataset.DoubleVectorVariables)
+          .ToDictionary(var => var, var => new DV(problemData.Dataset.GetDoubleVectorValue(var, rows.First()).ToArray())));
+
+
+      //extract initial constants
+      double[] c = initialConstants.ToArray();
+
+      alglib.ndimensional_func alglib_func = (double[] x, ref double func, object o) => {
+        var vars = new DV(x);
+        func = loss(vars);
+        var cnt = (EvaluationsCounter)o;
+        cnt.FunctionEvaluations++;
+      };
+      alglib.ndimensional_grad alglib_grad = (double[] x, ref double func, double[] grad, object o) => {
+        var vars = new DV(x);
+        func = loss(vars);
+        Array.Copy(lossGrad(vars), grad, x.Length);
+        var cnt = (EvaluationsCounter)o;
+        cnt.GradientEvaluations++;
+      };
+      alglib.ndimensional_hess alglib_hess = (double[] x, ref double func, double[] grad, double[,] hess, object o) => {
+        var vars = new DV(x);
+        func = loss(vars);
+        Array.Copy(lossGrad(vars), grad, x.Length);
+        Array.Copy(lossHess(vars), hess, x.Length * x.Length);
+        var cnt = (EvaluationsCounter)o;
+        cnt.HessianEvaluations++;
+      };
+      alglib.ndimensional_rep xrep = (p, f, obj) => {
+        iterationCallback?.Invoke(p, f, obj);
+        cancellationToken.ThrowIfCancellationRequested();
+      };
+      var rowEvaluationsCounter = new EvaluationsCounter();
+
+      try {
+
+        alglib.minlmcreatefgh(c, out var state);
+        alglib.minlmsetcond(state, 0.0, 0.0, 0.0, maxIterations);
+        alglib.minlmsetxrep(state, iterationCallback != null || cancellationToken != default(CancellationToken));
+        alglib.minlmoptimize(state, alglib_func, alglib_grad, alglib_hess, xrep, rowEvaluationsCounter);
+        alglib.minlmresults(state, out c, out var rep);
+
+        ////retVal == -7  => constant optimization failed due to wrong gradient
+        //if (retVal == -1)
+        //  return (ISymbolicExpressionTree)tree.Clone();
+      } catch (ArithmeticException) {
+        return (ISymbolicExpressionTree)tree.Clone();
+      } catch (alglib.alglibexception) {
+        return (ISymbolicExpressionTree)tree.Clone();
+      }
+
+      if (counter != null) {
+        int n = rows.Count();
+        counter.FunctionEvaluations += rowEvaluationsCounter.FunctionEvaluations / n;
+        counter.GradientEvaluations += rowEvaluationsCounter.GradientEvaluations / n;
+        counter.HessianEvaluations += rowEvaluationsCounter.HessianEvaluations / n;
+      }
+
+      var newTree = (ISymbolicExpressionTree)tree.Clone();
+      UpdateConstants(newTree, c, updateVariableWeights);
+
+      return newTree;
+    }
+
+    private static void UpdateConstants(ISymbolicExpressionTree tree, double[] constants, bool updateVariableWeights) {
+      int i = 0;
+      foreach (var node in tree.Root.IterateNodesPrefix().OfType<SymbolicExpressionTreeTerminalNode>()) {
+        ConstantTreeNode constantTreeNode = node as ConstantTreeNode;
+        VariableTreeNodeBase variableTreeNodeBase = node as VariableTreeNodeBase;
+        FactorVariableTreeNode factorVarTreeNode = node as FactorVariableTreeNode;
+        if (constantTreeNode != null)
+          constantTreeNode.Value = constants[i++];
+        else if (updateVariableWeights && variableTreeNodeBase != null)
+          variableTreeNodeBase.Weight = constants[i++];
+        else if (factorVarTreeNode != null) {
+          for (int j = 0; j < factorVarTreeNode.Weights.Length; j++)
+            factorVarTreeNode.Weights[j] = constants[i++];
+        }
+      }
+    }
+
+    public static bool CanOptimizeConstants(ISymbolicExpressionTree tree) {
+      return TreeToDiffSharpConverter.IsCompatible(tree);
+    }
+  }
+}
Index: /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionConstantOptimizationEvaluator.cs
===================================================================
--- /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionConstantOptimizationEvaluator.cs	(revision 17785)
+++ /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionConstantOptimizationEvaluator.cs	(revision 17786)
@@ -42,4 +42,5 @@
     private const string FunctionEvaluationsResultParameterName = "Constants Optimization Function Evaluations";
     private const string GradientEvaluationsResultParameterName = "Constants Optimization Gradient Evaluations";
+    private const string HessianEvaluationsResultParameterName = "Constants Optimization Hessian Evaluations";
     private const string CountEvaluationsParameterName = "Count Function and Gradient Evaluations";
 
@@ -66,4 +67,7 @@
     public IResultParameter<IntValue> GradientEvaluationsResultParameter {
       get { return (IResultParameter<IntValue>)Parameters[GradientEvaluationsResultParameterName]; }
+    }
+    public IResultParameter<IntValue> HessianEvaluationsResultParameter {
+      get { return (IResultParameter<IntValue>)Parameters[HessianEvaluationsResultParameterName]; }
     }
     public IFixedValueParameter<BoolValue> CountEvaluationsParameter {
@@ -116,4 +120,5 @@
       Parameters.Add(new ResultParameter<IntValue>(FunctionEvaluationsResultParameterName, "The number of function evaluations performed by the constants optimization evaluator", "Results", new IntValue()));
       Parameters.Add(new ResultParameter<IntValue>(GradientEvaluationsResultParameterName, "The number of gradient evaluations performed by the constants optimization evaluator", "Results", new IntValue()));
+      Parameters.Add(new ResultParameter<IntValue>(HessianEvaluationsResultParameterName, "The number of hessian evaluations performed by the constants optimization evaluator", "Results", new IntValue()));
     }
 
@@ -132,4 +137,6 @@
       if (!Parameters.ContainsKey(GradientEvaluationsResultParameterName))
         Parameters.Add(new ResultParameter<IntValue>(GradientEvaluationsResultParameterName, "The number of gradient evaluations performed by the constants optimization evaluator", "Results", new IntValue()));
+      if (!Parameters.ContainsKey(HessianEvaluationsResultParameterName))
+        Parameters.Add(new ResultParameter<IntValue>(HessianEvaluationsResultParameterName, "The number of hessian evaluations performed by the constants optimization evaluator", "Results", new IntValue()));
     }
 
@@ -164,4 +171,5 @@
             FunctionEvaluationsResultParameter.ActualValue.Value += counter.FunctionEvaluations;
             GradientEvaluationsResultParameter.ActualValue.Value += counter.GradientEvaluations;
+            HessianEvaluationsResultParameter.ActualValue.Value += counter.HessianEvaluations;
           }
         }
@@ -184,4 +192,5 @@
       FunctionEvaluationsResultParameter.ExecutionContext = context;
       GradientEvaluationsResultParameter.ExecutionContext = context;
+      HessianEvaluationsResultParameter.ExecutionContext = context;
 
       // Pearson R² evaluator is used on purpose instead of the const-opt evaluator, 
@@ -195,4 +204,5 @@
       FunctionEvaluationsResultParameter.ExecutionContext = null;
       GradientEvaluationsResultParameter.ExecutionContext = null;
+      HessianEvaluationsResultParameter.ExecutionContext = null;
 
       return r2;
@@ -206,4 +216,5 @@
       public int FunctionEvaluations = 0;
       public int GradientEvaluations = 0;
+      public int HessianEvaluations = 0;
     }
   }
Index: /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.Designer.cs
===================================================================
--- /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.Designer.cs	(revision 17785)
+++ /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.Designer.cs	(revision 17786)
@@ -57,4 +57,6 @@
       this.btnVectorOptimizeConstants = new System.Windows.Forms.Button();
       this.nudLearningRate = new System.Windows.Forms.NumericUpDown();
+      this.btnUnrollingVectorOptimizeConstants = new System.Windows.Forms.Button();
+      this.btnDiffSharpOptimizeConstants = new System.Windows.Forms.Button();
       this.grpViewHost = new System.Windows.Forms.GroupBox();
       this.toolTip = new System.Windows.Forms.ToolTip(this.components);
@@ -131,5 +133,5 @@
       // flowLayoutPanel
       // 
-      this.flowLayoutPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) 
+      this.flowLayoutPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
             | System.Windows.Forms.AnchorStyles.Right)));
       this.flowLayoutPanel.Controls.Add(this.btnSimplify);
@@ -137,4 +139,6 @@
       this.flowLayoutPanel.Controls.Add(this.btnVectorOptimizeConstants);
       this.flowLayoutPanel.Controls.Add(this.nudLearningRate);
+      this.flowLayoutPanel.Controls.Add(this.btnUnrollingVectorOptimizeConstants);
+      this.flowLayoutPanel.Controls.Add(this.btnDiffSharpOptimizeConstants);
       this.flowLayoutPanel.Location = new System.Drawing.Point(6, 370);
       this.flowLayoutPanel.Name = "flowLayoutPanel";
@@ -182,5 +186,5 @@
       this.btnVectorOptimizeConstants.Size = new System.Drawing.Size(107, 24);
       this.btnVectorOptimizeConstants.TabIndex = 3;
-      this.btnVectorOptimizeConstants.Text = "Vector-Optimize";
+      this.btnVectorOptimizeConstants.Text = "Optimize (TensorFlow)";
       this.btnVectorOptimizeConstants.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText;
       this.toolTip.SetToolTip(this.btnVectorOptimizeConstants, "Optimizes the numerical constants of the model. \r\nIf the algorithm converges, opt" +
@@ -211,4 +215,32 @@
             0,
             -2147483648});
+      // 
+      // btnUnrollingVectorOptimizeConstants
+      // 
+      this.btnUnrollingVectorOptimizeConstants.AutoSize = true;
+      this.btnUnrollingVectorOptimizeConstants.Enabled = false;
+      this.btnUnrollingVectorOptimizeConstants.Image = HeuristicLab.Common.Resources.VSImageLibrary.Performance;
+      this.btnUnrollingVectorOptimizeConstants.Location = new System.Drawing.Point(175, 3);
+      this.btnUnrollingVectorOptimizeConstants.Name = "btnUnrollingVectorOptimizeConstants";
+      this.btnUnrollingVectorOptimizeConstants.Size = new System.Drawing.Size(107, 24);
+      this.btnUnrollingVectorOptimizeConstants.TabIndex = 3;
+      this.btnUnrollingVectorOptimizeConstants.Text = "Unrolled-Vector-Optimize";
+      this.btnUnrollingVectorOptimizeConstants.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText;
+      this.btnUnrollingVectorOptimizeConstants.UseVisualStyleBackColor = true;
+      this.btnUnrollingVectorOptimizeConstants.Click += new System.EventHandler(this.btnUnrollingVectorOptimizeConstants_Click);
+      // 
+      // btnDiffSharpOptimizeConstants
+      // 
+      this.btnDiffSharpOptimizeConstants.AutoSize = true;
+      this.btnDiffSharpOptimizeConstants.Enabled = false;
+      this.btnDiffSharpOptimizeConstants.Image = HeuristicLab.Common.Resources.VSImageLibrary.Performance;
+      this.btnDiffSharpOptimizeConstants.Location = new System.Drawing.Point(89, 3);
+      this.btnDiffSharpOptimizeConstants.Name = "btnDiffSharpOptimizeConstants";
+      this.btnDiffSharpOptimizeConstants.Size = new System.Drawing.Size(80, 24);
+      this.btnDiffSharpOptimizeConstants.TabIndex = 2;
+      this.btnDiffSharpOptimizeConstants.Text = "Optimize (DiffSharp)";
+      this.btnDiffSharpOptimizeConstants.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText;
+      this.btnDiffSharpOptimizeConstants.UseVisualStyleBackColor = true;
+      this.btnDiffSharpOptimizeConstants.Click += new System.EventHandler(this.btnDiffSharpOptimizeConstants_Click);
       // 
       // grpViewHost
@@ -276,4 +308,6 @@
     protected System.Windows.Forms.Button btnVectorOptimizeConstants;
     protected System.Windows.Forms.NumericUpDown nudLearningRate;
+    protected System.Windows.Forms.Button btnUnrollingVectorOptimizeConstants;
+    protected System.Windows.Forms.Button btnDiffSharpOptimizeConstants;
   }
 }
Index: /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.cs
===================================================================
--- /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.cs	(revision 17785)
+++ /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.cs	(revision 17786)
@@ -135,4 +135,6 @@
         btnVectorOptimizeConstants.Enabled = true;
         nudLearningRate.Enabled = true;
+        btnUnrollingVectorOptimizeConstants.Enabled = true;
+        btnDiffSharpOptimizeConstants.Enabled = true;
         btnSimplify.Enabled = true;
         treeStatusValue.Visible = false;
@@ -141,4 +143,6 @@
         btnVectorOptimizeConstants.Enabled = false;
         nudLearningRate.Enabled = false;
+        btnUnrollingVectorOptimizeConstants.Enabled = false;
+        btnDiffSharpOptimizeConstants.Enabled = false;
         btnSimplify.Enabled = false;
         treeStatusValue.Visible = true;
@@ -232,5 +236,5 @@
     }
 
-    protected abstract void UpdateModel(ISymbolicExpressionTree tree);
+    protected virtual void UpdateModel(ISymbolicExpressionTree tree) { }
 
     protected virtual ISymbolicExpressionTree OptimizeConstants(ISymbolicExpressionTree tree, CancellationToken cancellationToken, IProgress progress) {
@@ -238,4 +242,10 @@
     }
     protected virtual ISymbolicExpressionTree VectorOptimizeConstants(ISymbolicExpressionTree tree, CancellationToken cancellationToken, IProgress progress) {
+      return tree;
+    }
+    protected virtual ISymbolicExpressionTree UnrollingVectorOptimizeConstants(ISymbolicExpressionTree tree, CancellationToken cancellationToken, IProgress progress) {
+      return tree;
+    }
+    protected virtual ISymbolicExpressionTree DiffSharpVectorOptimizeConstants(ISymbolicExpressionTree tree, CancellationToken cancellationToken, IProgress progress) {
       return tree;
     }
@@ -364,4 +374,38 @@
       }
     }
+
+    private async void btnUnrollingVectorOptimizeConstants_Click(object sender, EventArgs e) {
+      progress.Start("Optimizing Constants ...");
+      cancellationTokenSource = new CancellationTokenSource();
+      progress.CanBeStopped = true;
+      try {
+        var tree = (ISymbolicExpressionTree)Content.Model.SymbolicExpressionTree.Clone();
+
+        var newTree = await Task.Run(() => UnrollingVectorOptimizeConstants(tree, cancellationTokenSource.Token, progress), cancellationTokenSource.Token);
+        try {
+          await Task.Delay(300, cancellationTokenSource.Token); // wait for progressbar to finish animation
+        } catch (OperationCanceledException) { }
+        UpdateModel(newTree); // triggers progress.Finish after calculating the node impacts when model is changed
+      } catch {
+        progress.Finish();
+      }
+    }
+
+    private async void btnDiffSharpOptimizeConstants_Click(object sender, EventArgs e) {
+      progress.Start("Optimizing Constants ...");
+      cancellationTokenSource = new CancellationTokenSource();
+      progress.CanBeStopped = true;
+      try {
+        var tree = (ISymbolicExpressionTree)Content.Model.SymbolicExpressionTree.Clone();
+
+        var newTree = await Task.Run(() => DiffSharpVectorOptimizeConstants(tree, cancellationTokenSource.Token, progress), cancellationTokenSource.Token);
+        try {
+          await Task.Delay(300, cancellationTokenSource.Token); // wait for progressbar to finish animation
+        } catch (OperationCanceledException) { }
+        UpdateModel(newTree); // triggers progress.Finish after calculating the node impacts when model is changed
+      } catch {
+        progress.Finish();
+      }
+    }
   }
 }
Index: /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeToDiffSharpConverter.cs
===================================================================
--- /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeToDiffSharpConverter.cs	(revision 17786)
+++ /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeToDiffSharpConverter.cs	(revision 17786)
@@ -0,0 +1,506 @@
+﻿#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 System.Runtime.Serialization;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using DiffSharp.Interop.Float64;
+using DoubleVector = MathNet.Numerics.LinearAlgebra.Vector<double>;
+
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+  public class TreeToDiffSharpConverter {
+    public delegate D ParametricFunction(D[] vars, D[] @params, DV[] vectorParams);
+
+    #region helper class
+    public 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) {
+        if (obj is DataForVariable other) {
+          return other.variableName.Equals(this.variableName) &&
+                 other.variableValue.Equals(this.variableValue) &&
+                 other.lag == this.lag;
+        }
+        return false;
+      }
+
+      public override int GetHashCode() {
+        return variableName.GetHashCode() ^ variableValue.GetHashCode() ^ lag;
+      }
+    }
+
+    public class EvaluationResult {
+      public D Scalar { get; }
+      public bool IsScalar => !ReferenceEquals(Scalar, NanScalar);
+
+      public DV Vector { get; }
+      public bool IsVector => !ReferenceEquals(Vector, NaNVector);
+
+      public bool IsNaN => !IsScalar && !IsVector;
+
+      public EvaluationResult(D scalar) {
+        if (scalar == null) throw new ArgumentNullException(nameof(scalar));
+        Scalar = scalar;
+        Vector = NaNVector;
+      }
+      public EvaluationResult(DV vector) {
+        if (vector == null) throw new ArgumentNullException(nameof(vector));
+        Scalar = NanScalar;
+        Vector = vector;
+      }
+      private EvaluationResult() {
+        Scalar = NanScalar;
+        Vector = NaNVector;
+      }
+
+      private static readonly DV NaNVector = new DV(new[] { double.NaN });
+      private static readonly D NanScalar = new D(double.NaN);
+      public static readonly EvaluationResult NaN = new EvaluationResult();
+    }
+    #endregion
+
+    public static D Evaluate(ISymbolicExpressionTree tree,
+      bool makeVariableWeightsVariable, bool addLinearScalingTerms,
+      DV variables,
+      IDictionary<string, D> scalarParameters, IDictionary<string, DV> vectorsParameters) {
+
+      var transformator = new TreeToDiffSharpConverter(
+        variables,
+        scalarParameters, vectorsParameters,
+        makeVariableWeightsVariable, addLinearScalingTerms);
+
+      var result = transformator.ConvertNode(tree.Root.GetSubtree(0));
+      if (!result.IsScalar) throw new InvalidOperationException("Result of evaluation is not a scalar.");
+      return result.Scalar;
+    }
+
+    //public static bool TryConvert(ISymbolicExpressionTree tree, IDataset dataset,
+    //  bool makeVariableWeightsVariable, bool addLinearScalingTerms,
+    //  out double[] initialConstants, out List<DataForVariable> scalarParameters, out List<DataForVariable> vectorParameters,
+    //  out D func) {
+
+    //  var transformator = new TreeToDiffSharpConverter(dataset, makeVariableWeightsVariable, addLinearScalingTerms);
+    //  try {
+    //    D term = transformator.ConvertNode(tree.Root.GetSubtree(0));
+    //    initialConstants = transformator.initialConstants.ToArray();
+    //    var scalarParameterEntries = transformator.scalarParameters.ToArray(); // guarantee same order for keys and values
+    //    var vectorParameterEntries = transformator.vectorParameters.ToArray(); // guarantee same order for keys and values
+    //    scalarParameters = scalarParameterEntries.Select(kvp => kvp.Key).ToList();
+    //    vectorParameters = vectorParameterEntries.Select(kvp => kvp.Key).ToList();
+    //    func = term;
+    //    return true;
+    //  } catch (ConversionException) {
+    //    initialConstants = null;
+    //    scalarParameters = null;
+    //    vectorParameters = null;
+    //    func = null;
+    //  }
+    //  return false;
+    //}
+
+    public static List<double> GetInitialConstants(ISymbolicExpressionTree tree,
+      bool makeVariableWeightsVariable, bool addLinearScalingTerms,
+      IDictionary<string, D> scalarParameters, IDictionary<string, DV> vectorsParameters) {
+
+      var transformator = new TreeToDiffSharpConverter( /*dataset, */
+        null,
+        scalarParameters, vectorsParameters,
+        makeVariableWeightsVariable, addLinearScalingTerms);
+
+      transformator.ConvertNode(tree.Root.GetSubtree(0));
+      return transformator.initialConstants;
+    }
+
+    /*private readonly IDataset dataset;*/
+    private readonly IDictionary<string, D> scalarParameters;
+    private readonly IDictionary<string, DV> vectorsParameters;
+    private readonly bool makeVariableWeightsVariable;
+    private readonly bool addLinearScalingTerms;
+
+    private readonly List<double> initialConstants;
+    private readonly DV variables;
+    private int variableIdx;
+    //private readonly Dictionary<DataForVariable, D> scalarParameters;
+    //private readonly Dictionary<DataForVariable, DV> vectorParameters;
+
+    private TreeToDiffSharpConverter(/*IDataset dataset,*/
+      DV variables,
+      IDictionary<string, D> scalarParameters, IDictionary<string, DV> vectorsParameters,
+      bool makeVariableWeightsVariable, bool addLinearScalingTerms) {
+      /*this.dataset = dataset;*/
+      this.scalarParameters = scalarParameters;
+      this.vectorsParameters = vectorsParameters;
+      this.makeVariableWeightsVariable = makeVariableWeightsVariable;
+      this.addLinearScalingTerms = addLinearScalingTerms;
+
+      initialConstants = new List<double>();
+      this.variables = variables;
+      variableIdx = 0;
+      //scalarParameters = new Dictionary<DataForVariable, D>();
+      //vectorParameters = new Dictionary<DataForVariable, DV>();
+    }
+
+    #region Evaluation helpers
+    private static EvaluationResult ArithmeticApply(EvaluationResult lhs, EvaluationResult rhs,
+      /*Func<DV, DV, (DV, DV)> lengthStrategy,*/
+      Func<D, D, D> ssFunc = null,
+      Func<D, DV, DV> svFunc = null,
+      Func<DV, D, DV> vsFunc = null,
+      Func<DV, DV, DV> vvFunc = null) {
+
+      if (lhs.IsScalar && rhs.IsScalar && ssFunc != null) return new EvaluationResult(ssFunc(lhs.Scalar, rhs.Scalar));
+      if (lhs.IsScalar && rhs.IsVector && svFunc != null) return new EvaluationResult(svFunc(lhs.Scalar, rhs.Vector));
+      if (lhs.IsVector && rhs.IsScalar && vsFunc != null) return new EvaluationResult(vsFunc(lhs.Vector, rhs.Scalar));
+      if (lhs.IsVector && rhs.IsVector && vvFunc != null) return new EvaluationResult(vvFunc(lhs.Vector, rhs.Vector));
+      /* }
+      if (lhs.Vector.Count == rhs.Vector.Count) {
+        return new EvaluationResult(vvFunc(lhs.Vector, rhs.Vector));
+      } else {
+        var (lhsVector, rhsVector) = lengthStrategy(lhs.Vector, rhs.Vector);
+        return new EvaluationResult(vvFunc(lhsVector, rhsVector));
+      }*/
+      return EvaluationResult.NaN;
+    }
+
+    private static EvaluationResult FunctionApply(EvaluationResult val,
+      Func<D, D> sFunc = null,
+      Func<DV, DV> vFunc = null) {
+      if (val.IsScalar && sFunc != null) return new EvaluationResult(sFunc(val.Scalar));
+      if (val.IsVector && vFunc != null) return new EvaluationResult(vFunc(val.Vector));
+      return EvaluationResult.NaN;
+    }
+    private static EvaluationResult AggregateApply(EvaluationResult val,
+      Func<D, D> sFunc = null,
+      Func<DV, D> vFunc = null) {
+      if (val.IsScalar && sFunc != null) return new EvaluationResult(sFunc(val.Scalar));
+      if (val.IsVector && vFunc != null) return new EvaluationResult(vFunc(val.Vector));
+      return EvaluationResult.NaN;
+    }
+    #endregion
+
+    private EvaluationResult ConvertNode(ISymbolicExpressionTreeNode node) {
+
+      if (node.Symbol is Constant) {
+        // assume scalar constant
+        var constant = ((ConstantTreeNode)node).Value;
+        initialConstants.Add(constant);
+
+        var c = variables?[variableIdx++] ?? constant;
+
+        return new EvaluationResult(c);
+      }
+
+      if (node.Symbol is Variable) {
+        var varNode = node as VariableTreeNodeBase;
+        if (scalarParameters.ContainsKey(varNode.VariableName)) {
+          var par = scalarParameters[varNode.VariableName];
+          if (makeVariableWeightsVariable) {
+            var weight = varNode.Weight;
+            initialConstants.Add(weight);
+            var w = variables?[variableIdx++] ?? weight;
+            return new EvaluationResult(w * par);
+          } else {
+            return new EvaluationResult(varNode.Weight * par);
+          }
+        } else if (vectorsParameters.ContainsKey(varNode.VariableName)) {
+          var par = vectorsParameters[varNode.VariableName];
+          if (makeVariableWeightsVariable) {
+            var weight = varNode.Weight;
+            initialConstants.Add(weight);
+            var w = variables?[variableIdx++] ?? weight;
+            return new EvaluationResult(w * par);
+          } else {
+            return new EvaluationResult(varNode.Weight * par);
+          }
+        }
+      }
+      //if (node.Symbol is FactorVariable) {
+      //  var factorVarNode = node as FactorVariableTreeNode;
+      //  var products = new List<D>();
+      //  foreach (var variableValue in factorVarNode.Symbol.GetVariableValues(factorVarNode.VariableName)) {
+      //    var par = FindOrCreateParameter(parameters, factorVarNode.VariableName, variableValue);
+
+      //    var wVar = new D(factorVarNode.GetValue(variableValue));
+      //    variables.Add(wVar);
+      //    products.Add(wVar * par);
+      //  }
+
+      //  return products.Aggregate((x, y) => x + y);
+      //}
+
+      if (node.Symbol is Addition) {
+        var terms = node.Subtrees.Select(ConvertNode).ToList();
+        return terms.Aggregate((a, b) =>
+          ArithmeticApply(a, b,
+            (s1, s2) => s1 + s2,
+            (s1, v2) => s1 + v2,
+            (v1, s2) => v1 + s2,
+            (v1, v2) => v1 + v2
+          ));
+      }
+      if (node.Symbol is Subtraction) {
+        var terms = node.Subtrees.Select(ConvertNode).ToList();
+        if (terms.Count == 1) return FunctionApply(terms[0],
+            s => -s,
+            v => DV.Neg(v));
+        return terms.Aggregate((a, b) =>
+          ArithmeticApply(a, b,
+            (s1, s2) => s1 - s2,
+            (s1, v2) => s1 - v2,
+            (v1, s2) => v1 - s2,
+            (v1, v2) => v1 - v2
+          ));
+      }
+      if (node.Symbol is Multiplication) {
+        var terms = node.Subtrees.Select(ConvertNode).ToList();
+        return terms.Aggregate((a, b) =>
+          ArithmeticApply(a, b,
+            (s1, s2) => s1 * s2,
+            (s1, v2) => s1 * v2,
+            (v1, s2) => v1 * s2,
+            (v1, v2) => DV.op_DotMultiply(v1, v2)
+          ));
+      }
+      if (node.Symbol is Division) {
+        var terms = node.Subtrees.Select(ConvertNode).ToList();
+        if (terms.Count == 1) return FunctionApply(terms[0],
+          s => 1.0 / s,
+          v => 1.0 / v);
+        return terms.Aggregate((a, b) =>
+          ArithmeticApply(a, b,
+            (s1, s2) => s1 / s2,
+            (s1, v2) => s1 / v2,
+            (v1, s2) => v1 / s2,
+            (v1, v2) => DV.op_DotDivide(v1, v2)
+          ));
+      }
+
+      if (node.Symbol is Absolute) {
+        return FunctionApply(ConvertNode(node.GetSubtree(0)),
+          s => D.Abs(s),
+          v => DV.Abs(v)
+        );
+      }
+
+      if (node.Symbol is Logarithm) {
+        return FunctionApply(ConvertNode(node.GetSubtree(0)),
+          s => D.Log(s),
+          v => DV.Log(v)
+        );
+      }
+      if (node.Symbol is Exponential) {
+        return FunctionApply(ConvertNode(node.GetSubtree(0)),
+          s => D.Pow(Math.E, s),
+          v => DV.Pow(Math.E, v)
+        );
+      }
+      if (node.Symbol is Square) {
+        return FunctionApply(ConvertNode(node.GetSubtree(0)),
+          s => D.Pow(s, 2),
+          v => DV.Pow(v, 2)
+        );
+      }
+      if (node.Symbol is SquareRoot) {
+        return FunctionApply(ConvertNode(node.GetSubtree(0)),
+          s => D.Sqrt(s),
+          v => DV.Sqrt(v)
+        );
+      }
+      if (node.Symbol is Cube) {
+        return FunctionApply(ConvertNode(node.GetSubtree(0)),
+          s => D.Pow(s, 3),
+          v => DV.Pow(v, 3)
+        );
+      }
+      if (node.Symbol is CubeRoot) {
+        return FunctionApply(ConvertNode(node.GetSubtree(0)),
+          s => D.Sign(s) * D.Pow(D.Abs(s), 1.0 / 3.0),
+          v => DV.op_DotMultiply(DV.Sign(v), DV.Pow(DV.Abs(v), 1.0 / 3.0))
+        );
+      }
+
+      if (node.Symbol is Sine) {
+        return FunctionApply(ConvertNode(node.GetSubtree(0)),
+          s => D.Sin(s),
+          v => DV.Sin(v)
+        );
+      }
+      if (node.Symbol is Cosine) {
+        return FunctionApply(ConvertNode(node.GetSubtree(0)),
+          s => D.Cos(s),
+          v => DV.Cos(v)
+        );
+      }
+      if (node.Symbol is Tangent) {
+        return FunctionApply(ConvertNode(node.GetSubtree(0)),
+          s => D.Tan(s),
+          v => DV.Tan(v)
+        );
+      }
+      if (node.Symbol is HyperbolicTangent) {
+        return FunctionApply(ConvertNode(node.GetSubtree(0)),
+          s => D.Tanh(s),
+          v => DV.Tanh(v)
+        );
+      }
+
+      if (node.Symbol is Sum) {
+        return AggregateApply(ConvertNode(node.GetSubtree(0)),
+          s => s,
+          v => DV.Sum(v)
+        );
+      }
+      if (node.Symbol is Mean) {
+        return AggregateApply(ConvertNode(node.GetSubtree(0)),
+          s => s,
+          v => DV.Mean(v)
+        );
+      }
+      if (node.Symbol is StandardDeviation) {
+        return AggregateApply(ConvertNode(node.GetSubtree(0)),
+          s => 0,
+          v => DV.StandardDev(v) //TODO: use pop-stdev instead
+        );
+      }
+      if (node.Symbol is Length) {
+        return AggregateApply(ConvertNode(node.GetSubtree(0)),
+          s => 1,
+          v => DV.Sum(v) / DV.Mean(v) // TODO: no length?
+        );
+      }
+      if (node.Symbol is Min) {
+        return AggregateApply(ConvertNode(node.GetSubtree(0)),
+          s => s,
+          v => DV.Min(v)
+        );
+      }
+      if (node.Symbol is Max) {
+        return AggregateApply(ConvertNode(node.GetSubtree(0)),
+          s => s,
+          v => DV.Max(v)
+        );
+      }
+      if (node.Symbol is Variance) {
+        return AggregateApply(ConvertNode(node.GetSubtree(0)),
+          s => s,
+          v => DV.Variance(v)
+        );
+      }
+      //if (node.Symbol is Skewness) {
+      //}
+      //if (node.Symbol is Kurtosis) {
+      //}
+      //if (node.Symbol is EuclideanDistance) {
+      //}
+      //if (node.Symbol is Covariance) {
+      //}
+
+      if (node.Symbol is StartSymbol) {
+        if (addLinearScalingTerms) {
+          // scaling variables α, β are given at the beginning of the parameter vector
+          initialConstants.Add(0.0);
+          initialConstants.Add(1.0);
+          var beta = variables?[variableIdx++] ?? 0.0;
+          var alpha = variables?[variableIdx++] ?? 1.0;
+          var t = ConvertNode(node.GetSubtree(0));
+          if (!t.IsScalar) throw new InvalidOperationException("Must be a scalar result");
+          return new EvaluationResult(t.Scalar * alpha + beta);
+        } else return ConvertNode(node.GetSubtree(0));
+      }
+
+      throw new ConversionException();
+    }
+
+    public static bool IsCompatible(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 HyperbolicTangent) &&
+          //!(n.Symbol is Erf) &&
+          //!(n.Symbol is Norm) &&
+          !(n.Symbol is StartSymbol) &&
+          !(n.Symbol is Absolute) &&
+          //!(n.Symbol is AnalyticQuotient) &&
+          !(n.Symbol is Cube) &&
+          !(n.Symbol is CubeRoot) &&
+          !(n.Symbol is Sum) &&
+          !(n.Symbol is Mean) &&
+          !(n.Symbol is StandardDeviation) &&
+          //!(n.Symbol is Length) &&
+          !(n.Symbol is Min) &&
+          !(n.Symbol is Max) &&
+          !(n.Symbol is Variance)
+        //!(n.Symbol is Skewness) &&
+        //!(n.Symbol is Kurtosis) &&
+        //!(n.Symbol is EuclideanDistance) &&
+        //!(n.Symbol is Covariance)
+        select n).Any();
+      return !containsUnknownSymbol;
+    }
+
+    #region exception class
+    [Serializable]
+    public class ConversionException : Exception {
+
+      public ConversionException() {
+      }
+
+      public ConversionException(string message) : base(message) {
+      }
+
+      public ConversionException(string message, Exception inner) : base(message, inner) {
+      }
+
+      protected ConversionException(
+        SerializationInfo info,
+        StreamingContext context) : base(info, context) {
+      }
+    }
+    #endregion
+  }
+}
Index: /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj
===================================================================
--- /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj	(revision 17785)
+++ /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj	(revision 17786)
@@ -113,4 +113,8 @@
       <Private>False</Private>
     </Reference>
+    <Reference Include="DiffSharp, Version=0.7.7.0, Culture=neutral, processorArchitecture=AMD64">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\bin\DiffSharp.dll</HintPath>
+    </Reference>
     <Reference Include="HEAL.Attic, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
@@ -161,4 +165,5 @@
     </Compile>
     <Compile Include="Converters\LinearModelToTreeConverter.cs" />
+    <Compile Include="Converters\TreeToDiffSharpConverter.cs" />
     <Compile Include="Converters\VectorUnrollingTreeToAutoDiffTermConverter.cs" />
     <Compile Include="Converters\VectorTreeSimplifier.cs" />
Index: /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeVectorInterpreter.cs
===================================================================
--- /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeVectorInterpreter.cs	(revision 17785)
+++ /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeVectorInterpreter.cs	(revision 17786)
@@ -469,4 +469,8 @@
                 (v1, v2) => v1 - v2);
             }
+            if (currentInstr.nArguments == 1)
+              cur = FunctionApply(cur,
+                s => -s,
+                v => -v);
             TraceEvaluation(currentInstr, cur);
             return cur;
@@ -497,4 +501,8 @@
                 (v1, v2) => v1 / v2);
             }
+            if (currentInstr.nArguments == 1)
+              cur = FunctionApply(cur,
+                s => 1 / s,
+                v => 1 / v);
             TraceEvaluation(currentInstr, cur);
             return cur;
Index: /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Plugin.cs.frame
===================================================================
--- /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Plugin.cs.frame	(revision 17785)
+++ /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Plugin.cs.frame	(revision 17786)
@@ -49,4 +49,5 @@
   [PluginDependency("HeuristicLab.MathNet.Numerics", "4.9.0")]
   [PluginDependency("HeuristicLab.TensorFlowNet", "0.15.0")]
+  [PluginDependency("HeuristicLab.DiffSharp", "0.7.7")]
   public class HeuristicLabProblemsDataAnalysisSymbolicPlugin : PluginBase {
   }
Index: /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis/3.4/Dataset.cs
===================================================================
--- /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis/3.4/Dataset.cs	(revision 17785)
+++ /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis/3.4/Dataset.cs	(revision 17786)
@@ -406,8 +406,5 @@
       var value = variableValues[variableNames[columnIndex]][rowIndex];
       if (value is DoubleVector vector) {
-        return $"[{vector.ToVectorString(10, 80)}]";
-        //const int maxCount = 10;
-        //string extension = vector.Count > maxCount ? ", ..." : "";
-        //return $"[{string.Join(", ", vector.Cast<object>().Take(Math.Min(vector.Count, maxCount)))}{extension}]";
+        return $"[{vector.ToVectorString(10, 80, "..", " ", " ", d => d.ToString("G6", null))}]";
       }
 
Index: /branches/3040_VectorBasedGP/HeuristicLab.Problems.Instances.DataAnalysis/3.3/HeuristicLab.Problems.Instances.DataAnalysis-3.3.csproj
===================================================================
--- /branches/3040_VectorBasedGP/HeuristicLab.Problems.Instances.DataAnalysis/3.3/HeuristicLab.Problems.Instances.DataAnalysis-3.3.csproj	(revision 17785)
+++ /branches/3040_VectorBasedGP/HeuristicLab.Problems.Instances.DataAnalysis/3.3/HeuristicLab.Problems.Instances.DataAnalysis-3.3.csproj	(revision 17786)
@@ -24,5 +24,5 @@
     <WarningLevel>4</WarningLevel>
     <Prefer32Bit>false</Prefer32Bit>
-    <LangVersion>7</LangVersion>
+    <LangVersion>default</LangVersion>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
@@ -34,5 +34,5 @@
     <WarningLevel>4</WarningLevel>
     <Prefer32Bit>false</Prefer32Bit>
-    <LangVersion>7</LangVersion>
+    <LangVersion>default</LangVersion>
   </PropertyGroup>
   <PropertyGroup>
@@ -56,5 +56,5 @@
     <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
     <Prefer32Bit>false</Prefer32Bit>
-    <LangVersion>7</LangVersion>
+    <LangVersion>default</LangVersion>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
@@ -74,5 +74,5 @@
     <CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
     <Prefer32Bit>false</Prefer32Bit>
-    <LangVersion>7</LangVersion>
+    <LangVersion>default</LangVersion>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
@@ -90,5 +90,5 @@
     <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
     <Prefer32Bit>false</Prefer32Bit>
-    <LangVersion>7</LangVersion>
+    <LangVersion>default</LangVersion>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
@@ -108,5 +108,5 @@
     <CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
     <Prefer32Bit>false</Prefer32Bit>
-    <LangVersion>7</LangVersion>
+    <LangVersion>default</LangVersion>
   </PropertyGroup>
   <ItemGroup>
