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 17632)
+++ branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/InteractiveSymbolicRegressionSolutionSimplifierView.cs	(revision 17633)
@@ -43,6 +43,7 @@
 
       var tree = Content?.Model?.SymbolicExpressionTree;
-      //btnOptimizeConstants.Enabled = tree != null && NonlinearLeastSquaresConstantOptimizationEvaluator.CanOptimizeConstants(tree);
-      btnOptimizeConstants.Enabled = tree != null && TensorFlowConstantOptimizationEvaluator.CanOptimizeConstants(tree);
+      btnOptimizeConstants.Enabled = tree != null && NonlinearLeastSquaresConstantOptimizationEvaluator.CanOptimizeConstants(tree);
+      btnVectorOptimizeConstants.Enabled = tree != null && TensorFlowConstantOptimizationEvaluator.CanOptimizeConstants(tree);
+      nudLearningRate.Enabled = tree != null && TensorFlowConstantOptimizationEvaluator.CanOptimizeConstants(tree);
     }
 
@@ -64,24 +65,32 @@
       int reps = 0;
 
-      //do {
-      //  prevResult = result;
-      //  tree = NonlinearLeastSquaresConstantOptimizationEvaluator.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;
+      do {
+        prevResult = result;
+        tree = NonlinearLeastSquaresConstantOptimizationEvaluator.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;
+    }
+
+    protected override ISymbolicExpressionTree VectorOptimizeConstants(ISymbolicExpressionTree tree, CancellationToken cancellationToken, IProgress progress) {
       const int maxIterations = 1000;
+      var regressionProblemData = Content.ProblemData;
+      progress.CanBeStopped = true;
+
+      var learningRate = Math.Pow(10, (double)nudLearningRate.Value);
+
       return TensorFlowConstantOptimizationEvaluator.OptimizeTree(tree, regressionProblemData,
         regressionProblemData.TrainingIndices,
-        applyLinearScaling: false, updateVariableWeights: true, maxIterations: maxIterations, learningRate: 0.0001,
+        applyLinearScaling: false, updateVariableWeights: true, maxIterations: maxIterations, learningRate: learningRate,
         cancellationToken: cancellationToken,
         progress: new SynchronousProgress<double>(cost => {
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 17632)
+++ branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.Designer.cs	(revision 17633)
@@ -55,7 +55,9 @@
       this.btnSimplify = new System.Windows.Forms.Button();
       this.btnOptimizeConstants = new System.Windows.Forms.Button();
+      this.btnVectorOptimizeConstants = new System.Windows.Forms.Button();
+      this.nudLearningRate = new System.Windows.Forms.NumericUpDown();
       this.grpViewHost = new System.Windows.Forms.GroupBox();
+      this.toolTip = new System.Windows.Forms.ToolTip(this.components);
       this.treeChart = new HeuristicLab.Problems.DataAnalysis.Symbolic.Views.InteractiveSymbolicExpressionTreeChart();
-      this.toolTip = new System.Windows.Forms.ToolTip(this.components);
       ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
       this.splitContainer.Panel1.SuspendLayout();
@@ -129,8 +131,10 @@
       // 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);
       this.flowLayoutPanel.Controls.Add(this.btnOptimizeConstants);
+      this.flowLayoutPanel.Controls.Add(this.btnVectorOptimizeConstants);
+      this.flowLayoutPanel.Controls.Add(this.nudLearningRate);
       this.flowLayoutPanel.Location = new System.Drawing.Point(6, 370);
       this.flowLayoutPanel.Name = "flowLayoutPanel";
@@ -168,4 +172,43 @@
       this.btnOptimizeConstants.UseVisualStyleBackColor = true;
       this.btnOptimizeConstants.Click += new System.EventHandler(this.btnOptimizeConstants_Click);
+      // 
+      // btnVectorOptimizeConstants
+      // 
+      this.btnVectorOptimizeConstants.AutoSize = true;
+      this.btnVectorOptimizeConstants.Enabled = false;
+      this.btnVectorOptimizeConstants.Image = HeuristicLab.Common.Resources.VSImageLibrary.Performance;
+      this.btnVectorOptimizeConstants.Location = new System.Drawing.Point(175, 3);
+      this.btnVectorOptimizeConstants.Name = "btnVectorOptimizeConstants";
+      this.btnVectorOptimizeConstants.Size = new System.Drawing.Size(107, 24);
+      this.btnVectorOptimizeConstants.TabIndex = 3;
+      this.btnVectorOptimizeConstants.Text = "Vector-Optimize";
+      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" +
+        "imization is stopped.");
+      this.btnVectorOptimizeConstants.UseVisualStyleBackColor = true;
+      this.btnVectorOptimizeConstants.Click += new System.EventHandler(this.btnVectorOptimizeConstants_Click);
+      // 
+      // nudLearningRate
+      // 
+      this.nudLearningRate.Location = new System.Drawing.Point(288, 3);
+      this.nudLearningRate.Maximum = new decimal(new int[] {
+            20,
+            0,
+            0,
+            0});
+      this.nudLearningRate.Minimum = new decimal(new int[] {
+            20,
+            0,
+            0,
+            -2147483648});
+      this.nudLearningRate.Name = "nudLearningRate";
+      this.nudLearningRate.Size = new System.Drawing.Size(45, 20);
+      this.nudLearningRate.TabIndex = 4;
+      this.toolTip.SetToolTip(this.nudLearningRate, "Learning Rate (logarithmic)");
+      this.nudLearningRate.Value = new decimal(new int[] {
+            2,
+            0,
+            0,
+            -2147483648});
       // 
       // grpViewHost
@@ -231,4 +274,6 @@
     private System.Windows.Forms.Label treeStatusValue;
     private System.Windows.Forms.ToolTip toolTip;
+    protected System.Windows.Forms.Button btnVectorOptimizeConstants;
+    protected System.Windows.Forms.NumericUpDown nudLearningRate;
   }
 }
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 17632)
+++ branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.cs	(revision 17633)
@@ -133,8 +133,12 @@
       if (valid) {
         btnOptimizeConstants.Enabled = true;
+        btnVectorOptimizeConstants.Enabled = true;
+        nudLearningRate.Enabled = true;
         btnSimplify.Enabled = true;
         treeStatusValue.Visible = false;
       } else {
         btnOptimizeConstants.Enabled = false;
+        btnVectorOptimizeConstants.Enabled = false;
+        nudLearningRate.Enabled = false;
         btnSimplify.Enabled = false;
         treeStatusValue.Visible = true;
@@ -231,4 +235,7 @@
 
     protected virtual ISymbolicExpressionTree OptimizeConstants(ISymbolicExpressionTree tree, CancellationToken cancellationToken, IProgress progress) {
+      return tree;
+    }
+    protected virtual ISymbolicExpressionTree VectorOptimizeConstants(ISymbolicExpressionTree tree, CancellationToken cancellationToken, IProgress progress) {
       return tree;
     }
@@ -340,4 +347,21 @@
       }
     }
+
+    private async void btnVectorOptimizeConstants_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(() => VectorOptimizeConstants(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();
+      }
+    }
   }
 }
