Index: trunk/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/NMSESingleObjectiveConstraintsEvaluator.cs
===================================================================
--- trunk/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/NMSESingleObjectiveConstraintsEvaluator.cs	(revision 18132)
+++ trunk/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/NMSESingleObjectiveConstraintsEvaluator.cs	(revision 18220)
@@ -125,44 +125,5 @@
       var applyLinearScaling = ApplyLinearScalingParameter.ActualValue.Value;
 
-      if (OptimizeParameters) {
-        SymbolicRegressionParameterOptimizationEvaluator.OptimizeParameters(interpreter, tree, problemData, rows,
-          false, ParameterOptimizationIterations, true,
-          estimationLimits.Lower, estimationLimits.Upper);
-      } else {
-        if (applyLinearScaling) {
-          var rootNode = new ProgramRootSymbol().CreateTreeNode();
-          var startNode = new StartSymbol().CreateTreeNode();
-          var offset = tree.Root.GetSubtree(0) //Start
-                                .GetSubtree(0); //Offset
-          var scaling = offset.GetSubtree(0);
-
-          //Check if tree contains offset and scaling nodes
-          if (!(offset.Symbol is Addition) || !(scaling.Symbol is Multiplication))
-            throw new ArgumentException($"{ItemName} can only be used with LinearScalingGrammar.");
-
-          var t = (ISymbolicExpressionTreeNode)scaling.GetSubtree(0).Clone();
-          rootNode.AddSubtree(startNode);
-          startNode.AddSubtree(t);
-          var newTree = new SymbolicExpressionTree(rootNode);
-
-          //calculate alpha and beta for scaling
-          var estimatedValues = interpreter.GetSymbolicExpressionTreeValues(newTree, problemData.Dataset, rows);
-
-          var targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
-          OnlineLinearScalingParameterCalculator.Calculate(estimatedValues, targetValues, out var alpha, out var beta,
-            out var errorState);
-
-          if (errorState == OnlineCalculatorError.None) {
-            //Set alpha and beta to the scaling nodes from ia grammar
-            var offsetParameter = offset.GetSubtree(1) as NumberTreeNode;
-            offsetParameter.Value = alpha;
-            var scalingParameter = scaling.GetSubtree(1) as NumberTreeNode;
-            scalingParameter.Value = beta;
-          }
-        } // else: alpha and beta are evolved
-      }
-
-      var quality = Calculate(interpreter, tree, estimationLimits.Lower, estimationLimits.Upper, problemData, rows,
-        BoundsEstimator, UseSoftConstraints, PenalityFactor);
+      var quality = Evaluate(tree, problemData, rows, interpreter, applyLinearScaling, estimationLimits.Lower, estimationLimits.Upper);
       QualityParameter.ActualValue = new DoubleValue(quality);
 
@@ -170,48 +131,85 @@
     }
 
+    private static void CalcLinearScalingTerms(
+      ISymbolicExpressionTree tree,
+      IRegressionProblemData problemData,
+      IEnumerable<int> rows,
+      ISymbolicDataAnalysisExpressionTreeInterpreter interpreter) {
+      var rootNode = new ProgramRootSymbol().CreateTreeNode();
+      var startNode = new StartSymbol().CreateTreeNode();
+      var offset = tree.Root.GetSubtree(0) //Start
+                            .GetSubtree(0); //Offset
+      var scaling = offset.GetSubtree(0);
+
+      //Check if tree contains offset and scaling nodes
+      if (!(offset.Symbol is Addition) || !(scaling.Symbol is Multiplication))
+        throw new ArgumentException($"Scaling can only be used with LinearScalingGrammar.");
+
+      var t = (ISymbolicExpressionTreeNode)scaling.GetSubtree(0).Clone();
+      rootNode.AddSubtree(startNode);
+      startNode.AddSubtree(t);
+      var newTree = new SymbolicExpressionTree(rootNode);
+
+      //calculate alpha and beta for scaling
+      var estimatedValues = interpreter.GetSymbolicExpressionTreeValues(newTree, problemData.Dataset, rows);
+
+      var targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
+      OnlineLinearScalingParameterCalculator.Calculate(estimatedValues, targetValues, out var alpha, out var beta,
+        out var errorState);
+
+      if (errorState == OnlineCalculatorError.None) {
+        //Set alpha and beta to the scaling nodes from grammar
+        var offsetParameter = offset.GetSubtree(1) as NumberTreeNode;
+        offsetParameter.Value = alpha;
+        var scalingParameter = scaling.GetSubtree(1) as NumberTreeNode;
+        scalingParameter.Value = beta;
+      }
+    }
+
     public static double Calculate(
+      ISymbolicExpressionTree tree,
+      IRegressionProblemData problemData, IEnumerable<int> rows,
       ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
-      ISymbolicExpressionTree tree,
       double lowerEstimationLimit, double upperEstimationLimit,
-      IRegressionProblemData problemData, IEnumerable<int> rows,
       IBoundsEstimator estimator,
       bool useSoftConstraints = false, double penaltyFactor = 1.0) {
 
+      var constraints = Enumerable.Empty<ShapeConstraint>();
+      if (problemData is ShapeConstrainedRegressionProblemData scProbData)
+        constraints = scProbData.ShapeConstraints.EnabledConstraints;
+
       var estimatedValues = interpreter.GetSymbolicExpressionTreeValues(tree, problemData.Dataset, rows);
+      var boundedEstimatedValues = estimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit);
       var targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
-      var constraints = Enumerable.Empty<ShapeConstraint>();
-      if (problemData is ShapeConstrainedRegressionProblemData scProbData) {
-        constraints = scProbData.ShapeConstraints.EnabledConstraints;
-      } 
+      var nmse = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(targetValues, boundedEstimatedValues, out var errorState);
+      if (errorState != OnlineCalculatorError.None)
+        return 1.0;
+
+      if (!constraints.Any())
+        return nmse;
+
       var intervalCollection = problemData.VariableRanges;
-
-      var boundedEstimatedValues = estimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit);
-      var nmse = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(targetValues, boundedEstimatedValues,
-        out var errorState);
-
-      if (errorState != OnlineCalculatorError.None) {
+      var constraintViolations = IntervalUtil.GetConstraintViolations(constraints, estimator, intervalCollection, tree);
+
+      // infinite/NaN constraints
+      if (constraintViolations.Any(x => double.IsNaN(x) || double.IsInfinity(x)))
         return 1.0;
-      }
-
-      var constraintViolations = IntervalUtil.GetConstraintViolations(constraints, estimator, intervalCollection, tree);
-
-      if (constraintViolations.Any(x => double.IsNaN(x) || double.IsInfinity(x))) {
-        return 1.0;
-      }
-
-      if (useSoftConstraints) {
-        if (penaltyFactor < 0.0)
-          throw new ArgumentException("The parameter has to be >= 0.0.", nameof(penaltyFactor));
-
-        var weightedViolationsAvg = constraints
-          .Zip(constraintViolations, (c, v) => c.Weight * v)
-          .Average();
-
-        return Math.Min(nmse, 1.0) + penaltyFactor * weightedViolationsAvg;
-      } else if (constraintViolations.Any(x => x > 0.0)) {
-        return 1.0;
-      }
-
-      return nmse;
+
+      // hard constraints
+      if (!useSoftConstraints) {
+        if (constraintViolations.Any(x => x > 0.0))
+          return 1.0;
+        return nmse;
+      }
+
+      // soft constraints
+      if (penaltyFactor < 0.0)
+        throw new ArgumentException("The parameter has to be >= 0.0.", nameof(penaltyFactor));
+
+      var weightedViolationsAvg = constraints
+        .Zip(constraintViolations, (c, v) => c.Weight * v)
+        .Average();
+
+      return Math.Min(nmse, 1.0) + penaltyFactor * weightedViolationsAvg;
     }
 
@@ -223,7 +221,12 @@
       ApplyLinearScalingParameter.ExecutionContext = context;
 
-      var nmse = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree,
-        EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper,
-        problemData, rows, BoundsEstimator, UseSoftConstraints, PenalityFactor);
+      var nmse = Calculate(
+        tree, problemData, rows,
+        SymbolicDataAnalysisTreeInterpreterParameter.ActualValue,
+        EstimationLimitsParameter.ActualValue.Lower,
+        EstimationLimitsParameter.ActualValue.Upper,
+        BoundsEstimator,
+        UseSoftConstraints,
+        PenalityFactor);
 
       SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
@@ -233,4 +236,196 @@
       return nmse;
     }
+
+    public override double Evaluate(
+      ISymbolicExpressionTree tree,
+      IRegressionProblemData problemData,
+      IEnumerable<int> rows,
+      ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
+      bool applyLinearScaling = true,
+      double lowerEstimationLimit = double.MinValue,
+      double upperEstimationLimit = double.MaxValue) {
+
+      if (OptimizeParameters)
+        Optimize(
+          interpreter, tree,
+          problemData, rows,
+          ParameterOptimizationIterations,
+          updateVariableWeights: true,
+          lowerEstimationLimit,
+          upperEstimationLimit);
+      else if (applyLinearScaling) // extra scaling terms, which are included in tree
+        CalcLinearScalingTerms(tree, problemData, rows, interpreter);
+
+      return Calculate(
+        tree, problemData,
+        rows, interpreter,
+        lowerEstimationLimit,
+        upperEstimationLimit,
+        BoundsEstimator,
+        UseSoftConstraints,
+        PenalityFactor);
+    }
+
+    public static double Optimize(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
+          ISymbolicExpressionTree tree, IRegressionProblemData problemData, IEnumerable<int> rows,
+          int maxIterations, bool updateVariableWeights = true,
+          double lowerEstimationLimit = double.MinValue, double upperEstimationLimit = double.MaxValue,
+          bool updateParametersInTree = true, Action<double[], double, object> iterationCallback = null, EvaluationsCounter counter = null) {
+
+      // Numeric parameters in the tree become variables for parameter optimization.
+      // Variables in the tree become parameters (fixed values) for parameter optimization.
+      // For each parameter (variable in the original tree) we store the 
+      // variable name, variable value (for factor vars) and lag as a DataForVariable object.
+      // A dictionary is used to find parameters
+      double[] initialParameters;
+      var parameters = new List<TreeToAutoDiffTermConverter.DataForVariable>();
+
+      TreeToAutoDiffTermConverter.ParametricFunction func;
+      TreeToAutoDiffTermConverter.ParametricFunctionGradient func_grad;
+      if (!TreeToAutoDiffTermConverter.TryConvertToAutoDiff(tree, updateVariableWeights, addLinearScalingTerms: false, out parameters, out initialParameters, out func, out func_grad))
+        throw new NotSupportedException("Could not optimize parameters of symbolic expression tree due to not supported symbols used in the tree.");
+      var parameterEntries = parameters.ToArray(); // order of entries must be the same for x
+
+      // extract initial parameters
+      double[] c = (double[])initialParameters.Clone();
+
+      double originalQuality = SymbolicRegressionSingleObjectiveMeanSquaredErrorEvaluator.Calculate(
+        tree, problemData, rows,
+        interpreter, applyLinearScaling: false,
+        lowerEstimationLimit,
+        upperEstimationLimit);
+
+      if (counter == null) counter = new EvaluationsCounter();
+      var rowEvaluationsCounter = new EvaluationsCounter();
+
+      alglib.minlmreport rep;
+
+      IDataset ds = problemData.Dataset;
+      int n = rows.Count();
+      int k = parameters.Count;
+
+      double[,] x = new double[n, k];
+      int row = 0;
+      foreach (var r in rows) {
+        int col = 0;
+        foreach (var info in parameterEntries) {
+          if (ds.VariableHasType<double>(info.variableName)) {
+            x[row, col] = ds.GetDoubleValue(info.variableName, r + info.lag);
+          } else if (ds.VariableHasType<string>(info.variableName)) {
+            x[row, col] = ds.GetStringValue(info.variableName, r) == info.variableValue ? 1 : 0;
+          } else throw new InvalidProgramException("found a variable of unknown type");
+          col++;
+        }
+        row++;
+      }
+      double[] y = ds.GetDoubleValues(problemData.TargetVariable, rows).ToArray();
+
+
+      alglib.ndimensional_rep xrep = (p, f, obj) => iterationCallback(p, f, obj);
+
+      try {
+        alglib.minlmcreatevj(y.Length, c, out var lmstate);
+        alglib.minlmsetcond(lmstate, 0.0, maxIterations);
+        alglib.minlmsetxrep(lmstate, iterationCallback != null);
+        // alglib.minlmoptguardgradient(lmstate, 1e-5); // for debugging gradient calculation
+        alglib.minlmoptimize(lmstate, CreateFunc(func, x, y), CreateJac(func_grad, x, y), xrep, rowEvaluationsCounter);
+        alglib.minlmresults(lmstate, out c, out rep);
+        // alglib.minlmoptguardresults(lmstate, out var optGuardReport);
+      } catch (ArithmeticException) {
+        return originalQuality;
+      } catch (alglib.alglibexception) {
+        return originalQuality;
+      }
+
+      counter.FunctionEvaluations += rowEvaluationsCounter.FunctionEvaluations / n;
+      counter.GradientEvaluations += rowEvaluationsCounter.GradientEvaluations / n;
+
+      // * TerminationType, completion code:
+      //     * -8    optimizer detected NAN/INF values either in the function itself,
+      //             or in its Jacobian
+      //     * -5    inappropriate solver was used:
+      //             * solver created with minlmcreatefgh() used  on  problem  with
+      //               general linear constraints (set with minlmsetlc() call).
+      //     * -3    constraints are inconsistent
+      //     *  2    relative step is no more than EpsX.
+      //     *  5    MaxIts steps was taken
+      //     *  7    stopping conditions are too stringent,
+      //             further improvement is impossible
+      //     *  8    terminated   by  user  who  called  MinLMRequestTermination().
+      //             X contains point which was "current accepted" when termination
+      //             request was submitted.
+      if (rep.terminationtype > 0) {
+        UpdateParameters(tree, c, updateVariableWeights);
+      }
+      var quality = SymbolicRegressionSingleObjectiveMeanSquaredErrorEvaluator.Calculate(
+        tree, problemData, rows,
+        interpreter, applyLinearScaling: false,
+        lowerEstimationLimit, upperEstimationLimit);
+
+      if (!updateParametersInTree) UpdateParameters(tree, initialParameters, updateVariableWeights);
+
+      if (originalQuality < quality || double.IsNaN(quality)) {
+        UpdateParameters(tree, initialParameters, updateVariableWeights);
+        return originalQuality;
+      }
+      return quality;
+    }
+
+    private static void UpdateParameters(ISymbolicExpressionTree tree, double[] parameters, bool updateVariableWeights) {
+      int i = 0;
+      foreach (var node in tree.Root.IterateNodesPrefix().OfType<SymbolicExpressionTreeTerminalNode>()) {
+        NumberTreeNode numberTreeNode = node as NumberTreeNode;
+        VariableTreeNodeBase variableTreeNodeBase = node as VariableTreeNodeBase;
+        FactorVariableTreeNode factorVarTreeNode = node as FactorVariableTreeNode;
+        if (numberTreeNode != null) {
+          if (numberTreeNode.Parent.Symbol is Power
+              && numberTreeNode.Parent.GetSubtree(1) == numberTreeNode) continue; // exponents in powers are not optimized (see TreeToAutoDiffTermConverter)
+          numberTreeNode.Value = parameters[i++];
+        } else if (updateVariableWeights && variableTreeNodeBase != null)
+          variableTreeNodeBase.Weight = parameters[i++];
+        else if (factorVarTreeNode != null) {
+          for (int j = 0; j < factorVarTreeNode.Weights.Length; j++)
+            factorVarTreeNode.Weights[j] = parameters[i++];
+        }
+      }
+    }
+
+    private static alglib.ndimensional_fvec CreateFunc(TreeToAutoDiffTermConverter.ParametricFunction func, double[,] x, double[] y) {
+      int d = x.GetLength(1);
+      // row buffer
+      var xi = new double[d];
+      // function must return residuals, alglib optimizes resid²
+      return (double[] c, double[] resid, object o) => {
+        for (int i = 0; i < y.Length; i++) {
+          Buffer.BlockCopy(x, i * d * sizeof(double), xi, 0, d * sizeof(double)); // copy row. We are using BlockCopy instead of Array.Copy because x has rank 2
+          resid[i] = func(c, xi) - y[i];
+        }
+        var counter = (EvaluationsCounter)o;
+        counter.FunctionEvaluations += y.Length;
+      };
+    }
+
+    private static alglib.ndimensional_jac CreateJac(TreeToAutoDiffTermConverter.ParametricFunctionGradient func_grad, double[,] x, double[] y) {
+      int numParams = x.GetLength(1);
+      // row buffer
+      var xi = new double[numParams];
+      return (double[] c, double[] resid, double[,] jac, object o) => {
+        int numVars = c.Length;
+        for (int i = 0; i < y.Length; i++) {
+          Buffer.BlockCopy(x, i * numParams * sizeof(double), xi, 0, numParams * sizeof(double)); // copy row
+          var tuple = func_grad(c, xi);
+          resid[i] = tuple.Item2 - y[i];
+          Buffer.BlockCopy(tuple.Item1, 0, jac, i * numVars * sizeof(double), numVars * sizeof(double)); // copy the gradient to jac. BlockCopy because jac has rank 2.
+        }
+        var counter = (EvaluationsCounter)o;
+        counter.FunctionEvaluations += y.Length;
+        counter.GradientEvaluations += y.Length;
+      };
+    }
+
+    public class EvaluationsCounter {
+      public int FunctionEvaluations = 0;
+      public int GradientEvaluations = 0;
+    }
   }
 }
Index: trunk/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionLogResidualEvaluator.cs
===================================================================
--- trunk/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionLogResidualEvaluator.cs	(revision 18132)
+++ trunk/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionLogResidualEvaluator.cs	(revision 18220)
@@ -54,8 +54,12 @@
 
     public override IOperation InstrumentedApply() {
-      var solution = SymbolicExpressionTreeParameter.ActualValue;
+      var tree = SymbolicExpressionTreeParameter.ActualValue;
       IEnumerable<int> rows = GenerateRowsToEvaluate();
 
-      double quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows);
+      double quality = Calculate(
+        tree, ProblemDataParameter.ActualValue, 
+        rows, SymbolicDataAnalysisTreeInterpreterParameter.ActualValue,
+        EstimationLimitsParameter.ActualValue.Lower, 
+        EstimationLimitsParameter.ActualValue.Upper);
       QualityParameter.ActualValue = new DoubleValue(quality);
 
@@ -63,6 +67,12 @@
     }
 
-    public static double Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable<int> rows) {
-      IEnumerable<double> estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, rows);
+    public static double Calculate(
+      ISymbolicExpressionTree tree,
+      IRegressionProblemData problemData,
+      IEnumerable<int> rows,
+      ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
+      double lowerEstimationLimit, 
+      double upperEstimationLimit) {
+      IEnumerable<double> estimatedValues = interpreter.GetSymbolicExpressionTreeValues(tree, problemData.Dataset, rows);
       IEnumerable<double> targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
       IEnumerable<double> boundedEstimatedValues = estimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit);
@@ -83,5 +93,9 @@
       EstimationLimitsParameter.ExecutionContext = context;
 
-      double mlr = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows);
+      double mlr = Calculate(
+        tree, problemData, rows, 
+        SymbolicDataAnalysisTreeInterpreterParameter.ActualValue,
+        EstimationLimitsParameter.ActualValue.Lower, 
+        EstimationLimitsParameter.ActualValue.Upper);
 
       SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
@@ -90,4 +104,15 @@
       return mlr;
     }
+
+    public override double Evaluate(
+      ISymbolicExpressionTree tree,
+      IRegressionProblemData problemData,
+      IEnumerable<int> rows,
+      ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
+      bool applyLinearScaling = true,
+      double lowerEstimationLimit = double.MinValue,
+      double upperEstimationLimit = double.MaxValue) {
+      return Calculate(tree, problemData, rows, interpreter, lowerEstimationLimit, upperEstimationLimit);
+    }
   }
 }
Index: trunk/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionMeanRelativeErrorEvaluator.cs
===================================================================
--- trunk/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionMeanRelativeErrorEvaluator.cs	(revision 18132)
+++ trunk/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionMeanRelativeErrorEvaluator.cs	(revision 18220)
@@ -47,8 +47,12 @@
 
     public override IOperation InstrumentedApply() {
-      var solution = SymbolicExpressionTreeParameter.ActualValue;
+      var tree = SymbolicExpressionTreeParameter.ActualValue;
       IEnumerable<int> rows = GenerateRowsToEvaluate();
 
-      double quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows);
+      double quality = Calculate(
+        tree, ProblemDataParameter.ActualValue, rows,
+        SymbolicDataAnalysisTreeInterpreterParameter.ActualValue,
+        EstimationLimitsParameter.ActualValue.Lower, 
+        EstimationLimitsParameter.ActualValue.Upper);
       QualityParameter.ActualValue = new DoubleValue(quality);
 
@@ -56,6 +60,11 @@
     }
 
-    public static double Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable<int> rows) {
-      IEnumerable<double> estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, rows);
+    public static double Calculate(
+      ISymbolicExpressionTree tree, 
+      IRegressionProblemData problemData, 
+      IEnumerable<int> rows, 
+      ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
+      double lowerEstimationLimit, double upperEstimationLimit) {
+      IEnumerable<double> estimatedValues = interpreter.GetSymbolicExpressionTreeValues(tree, problemData.Dataset, rows);
       IEnumerable<double> targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
       IEnumerable<double> boundedEstimatedValues = estimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit);
@@ -76,5 +85,9 @@
       EstimationLimitsParameter.ExecutionContext = context;
 
-      double mre = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows);
+      double mre = Calculate(
+        tree, problemData, rows,
+        SymbolicDataAnalysisTreeInterpreterParameter.ActualValue,
+        EstimationLimitsParameter.ActualValue.Lower, 
+        EstimationLimitsParameter.ActualValue.Upper);
 
       SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
@@ -83,4 +96,15 @@
       return mre;
     }
+
+    public override double Evaluate(
+      ISymbolicExpressionTree tree,
+      IRegressionProblemData problemData,
+      IEnumerable<int> rows,
+      ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
+      bool applyLinearScaling = true,
+      double lowerEstimationLimit = double.MinValue,
+      double upperEstimationLimit = double.MaxValue) {
+      return Calculate(tree, problemData, rows, interpreter, lowerEstimationLimit, upperEstimationLimit);
+    }
   }
 }
Index: trunk/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionParameterOptimizationEvaluator.cs
===================================================================
--- trunk/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionParameterOptimizationEvaluator.cs	(revision 18132)
+++ trunk/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionParameterOptimizationEvaluator.cs	(revision 18220)
@@ -197,5 +197,5 @@
           Parameters.Add(new FixedValueParameter<PercentValue>(ParameterOptimizationRowsPercentageParameterName, "Determines the percentage of the rows which should be used for parameter optimization", new PercentValue(1)));
         }
-        
+
       }
     }
@@ -203,15 +203,20 @@
     private static readonly object locker = new object();
     public override IOperation InstrumentedApply() {
-      var solution = SymbolicExpressionTreeParameter.ActualValue;
+      var tree = SymbolicExpressionTreeParameter.ActualValue;
       double quality;
       if (RandomParameter.ActualValue.NextDouble() < ParameterOptimizationProbability.Value) {
         IEnumerable<int> parameterOptimizationRows = GenerateRowsToEvaluate(ParameterOptimizationRowsPercentage.Value);
         var counter = new EvaluationsCounter();
-        quality = OptimizeParameters(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, ProblemDataParameter.ActualValue,
+        quality = OptimizeParameters(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, ProblemDataParameter.ActualValue,
            parameterOptimizationRows, ApplyLinearScalingParameter.ActualValue.Value, ParameterOptimizationIterations.Value, updateVariableWeights: UpdateVariableWeights, lowerEstimationLimit: EstimationLimitsParameter.ActualValue.Lower, upperEstimationLimit: EstimationLimitsParameter.ActualValue.Upper, updateParametersInTree: UpdateParametersInTree, counter: counter);
 
         if (ParameterOptimizationRowsPercentage.Value != RelativeNumberOfEvaluatedSamplesParameter.ActualValue.Value) {
           var evaluationRows = GenerateRowsToEvaluate();
-          quality = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, evaluationRows, ApplyLinearScalingParameter.ActualValue.Value);
+          quality = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(
+            tree, ProblemDataParameter.ActualValue,
+            evaluationRows, SymbolicDataAnalysisTreeInterpreterParameter.ActualValue,
+            ApplyLinearScalingParameter.ActualValue.Value,
+            EstimationLimitsParameter.ActualValue.Lower,
+            EstimationLimitsParameter.ActualValue.Upper);
         }
 
@@ -225,9 +230,49 @@
       } else {
         var evaluationRows = GenerateRowsToEvaluate();
-        quality = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, evaluationRows, ApplyLinearScalingParameter.ActualValue.Value);
+        quality = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(
+          tree, ProblemDataParameter.ActualValue,
+          evaluationRows, SymbolicDataAnalysisTreeInterpreterParameter.ActualValue,
+          ApplyLinearScalingParameter.ActualValue.Value,
+          EstimationLimitsParameter.ActualValue.Lower,
+          EstimationLimitsParameter.ActualValue.Upper);
       }
       QualityParameter.ActualValue = new DoubleValue(quality);
 
       return base.InstrumentedApply();
+    }
+
+    public override double Evaluate(
+      ISymbolicExpressionTree tree,
+      IRegressionProblemData problemData,
+      IEnumerable<int> rows,
+      ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
+      bool applyLinearScaling = true,
+      double lowerEstimationLimit = double.MinValue,
+      double upperEstimationLimit = double.MaxValue) {
+
+      var random = RandomParameter.ActualValue;
+      double quality = double.NaN;
+
+      var propability = random.NextDouble();
+      if (propability < ParameterOptimizationProbability.Value) {
+        quality = OptimizeParameters(
+          interpreter, tree,
+          problemData, rows,
+          applyLinearScaling,
+          ParameterOptimizationIterations.Value,
+          updateVariableWeights: UpdateVariableWeights,
+          lowerEstimationLimit: lowerEstimationLimit,
+          upperEstimationLimit: upperEstimationLimit,
+          updateParametersInTree: UpdateParametersInTree);
+      }
+      if (double.IsNaN(quality) || ParameterOptimizationRowsPercentage.Value != RelativeNumberOfEvaluatedSamplesParameter.ActualValue.Value) {
+        quality = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(
+          tree, problemData,
+          rows, interpreter,
+          applyLinearScaling,
+          lowerEstimationLimit,
+          upperEstimationLimit);
+      }
+      return quality;
     }
 
@@ -242,5 +287,10 @@
       // because Evaluate() is used to get the quality of evolved models on 
       // different partitions of the dataset (e.g., best validation model)
-      double r2 = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, ApplyLinearScalingParameter.ActualValue.Value);
+      double r2 = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(
+        tree, problemData, rows,
+        SymbolicDataAnalysisTreeInterpreterParameter.ActualValue,
+        ApplyLinearScalingParameter.ActualValue.Value,
+        EstimationLimitsParameter.ActualValue.Lower,
+        EstimationLimitsParameter.ActualValue.Upper);
 
       SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
@@ -290,5 +340,9 @@
       }
 
-      double originalQuality = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(interpreter, tree, lowerEstimationLimit, upperEstimationLimit, problemData, rows, applyLinearScaling);
+      double originalQuality = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(
+        tree, problemData, rows,
+        interpreter, applyLinearScaling,
+        lowerEstimationLimit,
+        upperEstimationLimit);
 
       if (counter == null) counter = new EvaluationsCounter();
@@ -348,5 +402,8 @@
         } else UpdateParameters(tree, c, updateVariableWeights);
       }
-      var quality = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(interpreter, tree, lowerEstimationLimit, upperEstimationLimit, problemData, rows, applyLinearScaling);
+      var quality = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(
+        tree, problemData, rows,
+        interpreter, applyLinearScaling,
+        lowerEstimationLimit, upperEstimationLimit);
 
       if (!updateParametersInTree) UpdateParameters(tree, initialParameters, updateVariableWeights);
@@ -366,5 +423,5 @@
         FactorVariableTreeNode factorVarTreeNode = node as FactorVariableTreeNode;
         if (numberTreeNode != null) {
-          if (numberTreeNode.Parent.Symbol is Power 
+          if (numberTreeNode.Parent.Symbol is Power
               && numberTreeNode.Parent.GetSubtree(1) == numberTreeNode) continue; // exponents in powers are not optimizated (see TreeToAutoDiffTermConverter)
           numberTreeNode.Value = parameters[i++];
Index: trunk/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveEvaluator.cs
===================================================================
--- trunk/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveEvaluator.cs	(revision 18132)
+++ trunk/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveEvaluator.cs	(revision 18220)
@@ -22,4 +22,7 @@
 using HeuristicLab.Common;
 using HEAL.Attic;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using System.Collections.Generic;
+
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
   [StorableType("7EB90F03-4385-474F-BDE7-3B133E8FEAAB")]
@@ -28,5 +31,13 @@
     protected SymbolicRegressionSingleObjectiveEvaluator(StorableConstructorFlag _) : base(_) { }
     protected SymbolicRegressionSingleObjectiveEvaluator(SymbolicRegressionSingleObjectiveEvaluator original, Cloner cloner) : base(original, cloner) { }
-    protected SymbolicRegressionSingleObjectiveEvaluator(): base() {}    
+    protected SymbolicRegressionSingleObjectiveEvaluator(): base() {}
+    public abstract double Evaluate(
+      ISymbolicExpressionTree tree,
+      IRegressionProblemData problemData,
+      IEnumerable<int> rows,
+      ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
+      bool applyLinearScaling = true,
+      double lowerEstimationLimit = double.MinValue,
+      double upperEstimationLimit = double.MaxValue);
   }
 }
Index: trunk/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveMaxAbsoluteErrorEvaluator.cs
===================================================================
--- trunk/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveMaxAbsoluteErrorEvaluator.cs	(revision 18132)
+++ trunk/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveMaxAbsoluteErrorEvaluator.cs	(revision 18220)
@@ -43,8 +43,13 @@
 
     public override IOperation InstrumentedApply() {
-      var solution = SymbolicExpressionTreeParameter.ActualValue;
+      var tree = SymbolicExpressionTreeParameter.ActualValue;
       IEnumerable<int> rows = GenerateRowsToEvaluate();
 
-      double quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows, ApplyLinearScalingParameter.ActualValue.Value);
+      double quality = Calculate(
+        tree, ProblemDataParameter.ActualValue,
+        rows, SymbolicDataAnalysisTreeInterpreterParameter.ActualValue,
+        ApplyLinearScalingParameter.ActualValue.Value,
+        EstimationLimitsParameter.ActualValue.Lower, 
+        EstimationLimitsParameter.ActualValue.Upper);
       QualityParameter.ActualValue = new DoubleValue(quality);
 
@@ -52,6 +57,13 @@
     }
 
-    public static double Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable<int> rows, bool applyLinearScaling) {
-      IEnumerable<double> estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, rows);
+    public static double Calculate(
+      ISymbolicExpressionTree tree,
+      IRegressionProblemData problemData,
+      IEnumerable<int> rows,
+      ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
+      bool applyLinearScaling,
+      double lowerEstimationLimit, 
+      double upperEstimationLimit) {
+      IEnumerable<double> estimatedValues = interpreter.GetSymbolicExpressionTreeValues(tree, problemData.Dataset, rows);
       IEnumerable<double> targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
       OnlineCalculatorError errorState;
@@ -76,5 +88,10 @@
       ApplyLinearScalingParameter.ExecutionContext = context;
 
-      double mse = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, ApplyLinearScalingParameter.ActualValue.Value);
+      double mse = Calculate(
+        tree, problemData, rows,
+        SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, 
+        ApplyLinearScalingParameter.ActualValue.Value,
+        EstimationLimitsParameter.ActualValue.Lower, 
+        EstimationLimitsParameter.ActualValue.Upper);
 
       SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
@@ -84,4 +101,15 @@
       return mse;
     }
+
+    public override double Evaluate(
+      ISymbolicExpressionTree tree,
+      IRegressionProblemData problemData,
+      IEnumerable<int> rows,
+      ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
+      bool applyLinearScaling = true,
+      double lowerEstimationLimit = double.MinValue,
+      double upperEstimationLimit = double.MaxValue) {
+      return Calculate(tree, problemData, rows, interpreter, applyLinearScaling, lowerEstimationLimit, upperEstimationLimit);
+    }
   }
 }
Index: trunk/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveMeanAbsoluteErrorEvaluator.cs
===================================================================
--- trunk/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveMeanAbsoluteErrorEvaluator.cs	(revision 18132)
+++ trunk/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveMeanAbsoluteErrorEvaluator.cs	(revision 18220)
@@ -43,8 +43,13 @@
 
     public override IOperation InstrumentedApply() {
-      var solution = SymbolicExpressionTreeParameter.ActualValue;
+      var tree = SymbolicExpressionTreeParameter.ActualValue;
       IEnumerable<int> rows = GenerateRowsToEvaluate();
 
-      double quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows, ApplyLinearScalingParameter.ActualValue.Value);
+      double quality = Calculate(tree, 
+        ProblemDataParameter.ActualValue, rows, 
+        SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, 
+        ApplyLinearScalingParameter.ActualValue.Value,
+        EstimationLimitsParameter.ActualValue.Lower, 
+        EstimationLimitsParameter.ActualValue.Upper);
       QualityParameter.ActualValue = new DoubleValue(quality);
 
@@ -52,6 +57,13 @@
     }
 
-    public static double Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable<int> rows, bool applyLinearScaling) {
-      IEnumerable<double> estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, rows);
+    public static double Calculate(
+      ISymbolicExpressionTree tree, 
+      IRegressionProblemData problemData, 
+      IEnumerable<int> rows,
+      ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, 
+      bool applyLinearScaling,
+      double lowerEstimationLimit, 
+      double upperEstimationLimit) {
+      IEnumerable<double> estimatedValues = interpreter.GetSymbolicExpressionTreeValues(tree, problemData.Dataset, rows);
       IEnumerable<double> targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
       OnlineCalculatorError errorState;
@@ -76,5 +88,10 @@
       ApplyLinearScalingParameter.ExecutionContext = context;
 
-      double mse = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, ApplyLinearScalingParameter.ActualValue.Value);
+      double mse = Calculate(
+        tree, problemData, rows, 
+        SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, 
+        ApplyLinearScalingParameter.ActualValue.Value,
+        EstimationLimitsParameter.ActualValue.Lower, 
+        EstimationLimitsParameter.ActualValue.Upper);
 
       SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
@@ -84,4 +101,15 @@
       return mse;
     }
+
+    public override double Evaluate(
+      ISymbolicExpressionTree tree,
+      IRegressionProblemData problemData,
+      IEnumerable<int> rows,
+      ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
+      bool applyLinearScaling = true,
+      double lowerEstimationLimit = double.MinValue,
+      double upperEstimationLimit = double.MaxValue) {
+      return Calculate(tree, problemData, rows, interpreter, applyLinearScaling, lowerEstimationLimit, upperEstimationLimit);
+    }
   }
 }
Index: trunk/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveMeanSquaredErrorEvaluator.cs
===================================================================
--- trunk/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveMeanSquaredErrorEvaluator.cs	(revision 18132)
+++ trunk/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveMeanSquaredErrorEvaluator.cs	(revision 18220)
@@ -43,8 +43,13 @@
 
     public override IOperation InstrumentedApply() {
-      var solution = SymbolicExpressionTreeParameter.ActualValue;
+      var tree = SymbolicExpressionTreeParameter.ActualValue;
       IEnumerable<int> rows = GenerateRowsToEvaluate();
 
-      double quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows, ApplyLinearScalingParameter.ActualValue.Value);
+      double quality = Calculate(
+        tree, ProblemDataParameter.ActualValue, 
+        rows, SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, 
+        ApplyLinearScalingParameter.ActualValue.Value,         
+        EstimationLimitsParameter.ActualValue.Lower, 
+        EstimationLimitsParameter.ActualValue.Upper);
       QualityParameter.ActualValue = new DoubleValue(quality);
 
@@ -52,6 +57,12 @@
     }
 
-    public static double Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable<int> rows, bool applyLinearScaling) {
-      IEnumerable<double> estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, rows);
+    public static double Calculate(
+      ISymbolicExpressionTree tree, 
+      IRegressionProblemData problemData, 
+      IEnumerable<int> rows, 
+      ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, 
+      bool applyLinearScaling,
+      double lowerEstimationLimit, double upperEstimationLimit) {
+      IEnumerable<double> estimatedValues = interpreter.GetSymbolicExpressionTreeValues(tree, problemData.Dataset, rows);
       IEnumerable<double> targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
       OnlineCalculatorError errorState;
@@ -76,5 +87,10 @@
       ApplyLinearScalingParameter.ExecutionContext = context;
 
-      double mse = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, ApplyLinearScalingParameter.ActualValue.Value);
+      double mse = Calculate(        
+        tree, problemData, rows, 
+        SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, 
+        ApplyLinearScalingParameter.ActualValue.Value,
+        EstimationLimitsParameter.ActualValue.Lower, 
+        EstimationLimitsParameter.ActualValue.Upper);
 
       SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
@@ -84,4 +100,15 @@
       return mse;
     }
+
+    public override double Evaluate(
+      ISymbolicExpressionTree tree,
+      IRegressionProblemData problemData,
+      IEnumerable<int> rows,
+      ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
+      bool applyLinearScaling = true,
+      double lowerEstimationLimit = double.MinValue,
+      double upperEstimationLimit = double.MaxValue) {
+      return Calculate(tree, problemData, rows, interpreter, applyLinearScaling, lowerEstimationLimit, upperEstimationLimit);
+    }
   }
 }
Index: trunk/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.cs
===================================================================
--- trunk/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.cs	(revision 18132)
+++ trunk/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.cs	(revision 18220)
@@ -48,5 +48,10 @@
       IEnumerable<int> rows = GenerateRowsToEvaluate();
 
-      double quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows, ApplyLinearScalingParameter.ActualValue.Value);
+      double quality = Calculate(
+        solution, ProblemDataParameter.ActualValue,
+        rows, SymbolicDataAnalysisTreeInterpreterParameter.ActualValue,
+        ApplyLinearScalingParameter.ActualValue.Value,
+        EstimationLimitsParameter.ActualValue.Lower, 
+        EstimationLimitsParameter.ActualValue.Upper);
       QualityParameter.ActualValue = new DoubleValue(quality);
 
@@ -54,6 +59,13 @@
     }
 
-    public static double Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable<int> rows, bool applyLinearScaling) {
-      IEnumerable<double> estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, rows);
+    public static double Calculate(
+      ISymbolicExpressionTree tree, 
+      IRegressionProblemData problemData, 
+      IEnumerable<int> rows,
+      ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
+      bool applyLinearScaling,
+      double lowerEstimationLimit, 
+      double upperEstimationLimit) {
+      IEnumerable<double> estimatedValues = interpreter.GetSymbolicExpressionTreeValues(tree, problemData.Dataset, rows);
       IEnumerable<double> targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
       OnlineCalculatorError errorState;
@@ -78,5 +90,10 @@
       ApplyLinearScalingParameter.ExecutionContext = context;
 
-      double r2 = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, ApplyLinearScalingParameter.ActualValue.Value);
+      double r2 = Calculate(
+         tree, problemData, rows, 
+         SymbolicDataAnalysisTreeInterpreterParameter.ActualValue,
+         ApplyLinearScalingParameter.ActualValue.Value,
+         EstimationLimitsParameter.ActualValue.Lower, 
+         EstimationLimitsParameter.ActualValue.Upper);
 
       SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
@@ -86,4 +103,18 @@
       return r2;
     }
+
+    public override double Evaluate(
+      ISymbolicExpressionTree tree,
+      IRegressionProblemData problemData,
+      IEnumerable<int> rows,
+      ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
+      bool applyLinearScaling = true,
+      double lowerEstimationLimit = double.MinValue,
+      double upperEstimationLimit = double.MaxValue) {
+      return Calculate(
+        tree, problemData, rows, 
+        interpreter, applyLinearScaling, 
+        lowerEstimationLimit, upperEstimationLimit);
+    }
   }
 }
