Index: branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/PearsonRSquaredNestedTreeSizeEvaluator.cs
===================================================================
--- branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/PearsonRSquaredNestedTreeSizeEvaluator.cs	(revision 12847)
+++ branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/PearsonRSquaredNestedTreeSizeEvaluator.cs	(revision 12848)
@@ -27,5 +27,4 @@
 using HeuristicLab.Data;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
@@ -34,13 +33,4 @@
   [StorableClass]
   public class PearsonRSquaredNestedTreeSizeEvaluator : SymbolicRegressionMultiObjectiveEvaluator {
-    private const string useConstantOptimizationParameterName = "Use constant optimization";
-    public IFixedValueParameter<BoolValue> UseConstantOptimizationParameter {
-      get { return (IFixedValueParameter<BoolValue>)Parameters[useConstantOptimizationParameterName]; }
-    }
-    public bool UseConstantOptimization {
-      get { return UseConstantOptimizationParameter.Value.Value; }
-      set { UseConstantOptimizationParameter.Value.Value = value; }
-    }
-
     [StorableConstructor]
     protected PearsonRSquaredNestedTreeSizeEvaluator(bool deserializing) : base(deserializing) { }
@@ -52,8 +42,5 @@
     }
 
-    public PearsonRSquaredNestedTreeSizeEvaluator()
-      : base() {
-      Parameters.Add(new FixedValueParameter<BoolValue>(useConstantOptimizationParameterName, "", new BoolValue(false)));
-    }
+    public PearsonRSquaredNestedTreeSizeEvaluator() : base() { }
 
     public override IEnumerable<bool> Maximization { get { return new bool[2] { true, false }; } }
@@ -71,12 +58,13 @@
       }
 
-      double[] qualities = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows, ApplyLinearScalingParameter.ActualValue.Value);
+      double[] qualities = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows, ApplyLinearScalingParameter.ActualValue.Value, DecimalPlaces);
       QualitiesParameter.ActualValue = new DoubleArray(qualities);
       return base.InstrumentedApply();
     }
 
-    public static double[] Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable<int> rows, bool applyLinearScaling) {
+    public static double[] Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable<int> rows, bool applyLinearScaling, int decimalPlaces) {
       double r2 = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(interpreter, solution, lowerEstimationLimit, upperEstimationLimit, problemData, rows, applyLinearScaling);
-      r2 = Math.Round(r2, 3);
+      if (decimalPlaces >= 0)
+        r2 = Math.Round(r2, decimalPlaces);
       return new double[2] { r2, solution.IterateNodesPostfix().Sum(n => n.GetLength()) };
     }
@@ -87,5 +75,5 @@
       ApplyLinearScalingParameter.ExecutionContext = context;
 
-      double[] quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, ApplyLinearScalingParameter.ActualValue.Value);
+      double[] quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, ApplyLinearScalingParameter.ActualValue.Value, DecimalPlaces);
 
       SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
Index: branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/PearsonRSquaredNumberOfVariablesEvaluator.cs
===================================================================
--- branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/PearsonRSquaredNumberOfVariablesEvaluator.cs	(revision 12847)
+++ branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/PearsonRSquaredNumberOfVariablesEvaluator.cs	(revision 12848)
@@ -23,10 +23,8 @@
 using System.Collections.Generic;
 using System.Linq;
-using System.Security.Cryptography;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Data;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
@@ -35,13 +33,4 @@
   [StorableClass]
   public class PearsonRSquaredNumberOfVariablesEvaluator : SymbolicRegressionMultiObjectiveEvaluator {
-    private const string useConstantOptimizationParameterName = "Use constant optimization";
-    public IFixedValueParameter<BoolValue> UseConstantOptimizationParameter {
-      get { return (IFixedValueParameter<BoolValue>)Parameters[useConstantOptimizationParameterName]; }
-    }
-    public bool UseConstantOptimization {
-      get { return UseConstantOptimizationParameter.Value.Value; }
-      set { UseConstantOptimizationParameter.Value.Value = value; }
-    }
-
     [StorableConstructor]
     protected PearsonRSquaredNumberOfVariablesEvaluator(bool deserializing) : base(deserializing) { }
@@ -53,8 +42,5 @@
     }
 
-    public PearsonRSquaredNumberOfVariablesEvaluator()
-      : base() {
-      Parameters.Add(new FixedValueParameter<BoolValue>(useConstantOptimizationParameterName, "", new BoolValue(false)));
-    }
+    public PearsonRSquaredNumberOfVariablesEvaluator() : base() { }
 
     public override IEnumerable<bool> Maximization { get { return new bool[2] { true, false }; } }
@@ -71,12 +57,13 @@
         SymbolicRegressionConstantOptimizationEvaluator.OptimizeConstants(interpreter, solution, problemData, rows, applyLinearScaling, 5, estimationLimits.Upper, estimationLimits.Lower);
       }
-      double[] qualities = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows, ApplyLinearScalingParameter.ActualValue.Value);
+      double[] qualities = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows, ApplyLinearScalingParameter.ActualValue.Value, DecimalPlaces);
       QualitiesParameter.ActualValue = new DoubleArray(qualities);
       return base.InstrumentedApply();
     }
 
-    public static double[] Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable<int> rows, bool applyLinearScaling) {
+    public static double[] Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable<int> rows, bool applyLinearScaling, int decimalPlaces) {
       double r2 = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(interpreter, solution, lowerEstimationLimit, upperEstimationLimit, problemData, rows, applyLinearScaling);
-      r2 = Math.Round(r2, 3);
+      if (decimalPlaces >= 0)
+        r2 = Math.Round(r2, decimalPlaces);
       return new double[2] { r2, solution.IterateNodesPostfix().OfType<VariableTreeNode>().Count() };
     }
@@ -87,5 +74,5 @@
       ApplyLinearScalingParameter.ExecutionContext = context;
 
-      double[] quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, ApplyLinearScalingParameter.ActualValue.Value);
+      double[] quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, ApplyLinearScalingParameter.ActualValue.Value, DecimalPlaces);
 
       SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
Index: branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/PearsonRSquaredTreeComplexityEvaluator.cs
===================================================================
--- branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/PearsonRSquaredTreeComplexityEvaluator.cs	(revision 12847)
+++ branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/PearsonRSquaredTreeComplexityEvaluator.cs	(revision 12848)
@@ -26,5 +26,4 @@
 using HeuristicLab.Data;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
@@ -33,13 +32,4 @@
   [StorableClass]
   public class PearsonRSquaredTreeComplexityEvaluator : SymbolicRegressionMultiObjectiveEvaluator {
-    private const string useConstantOptimizationParameterName = "Use constant optimization";
-    public IFixedValueParameter<BoolValue> UseConstantOptimizationParameter {
-      get { return (IFixedValueParameter<BoolValue>)Parameters[useConstantOptimizationParameterName]; }
-    }
-    public bool UseConstantOptimization {
-      get { return UseConstantOptimizationParameter.Value.Value; }
-      set { UseConstantOptimizationParameter.Value.Value = value; }
-    }
-
     [StorableConstructor]
     protected PearsonRSquaredTreeComplexityEvaluator(bool deserializing) : base(deserializing) { }
@@ -51,15 +41,5 @@
     }
 
-    public PearsonRSquaredTreeComplexityEvaluator()
-      : base() {
-      Parameters.Add(new FixedValueParameter<BoolValue>(useConstantOptimizationParameterName, "", new BoolValue(false)));
-    }
-
-    [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserialization() {
-      if (!Parameters.ContainsKey(useConstantOptimizationParameterName)) {
-        Parameters.Add(new FixedValueParameter<BoolValue>(useConstantOptimizationParameterName, "", new BoolValue(false)));
-      }
-    }
+    public PearsonRSquaredTreeComplexityEvaluator() : base() { }
 
     public override IEnumerable<bool> Maximization { get { return new bool[2] { true, false }; } }
@@ -76,12 +56,13 @@
         SymbolicRegressionConstantOptimizationEvaluator.OptimizeConstants(interpreter, solution, problemData, rows, applyLinearScaling, 5, estimationLimits.Upper, estimationLimits.Lower);
       }
-      double[] qualities = Calculate(interpreter, solution, estimationLimits.Lower, estimationLimits.Upper, problemData, rows, applyLinearScaling);
+      double[] qualities = Calculate(interpreter, solution, estimationLimits.Lower, estimationLimits.Upper, problemData, rows, applyLinearScaling, DecimalPlaces);
       QualitiesParameter.ActualValue = new DoubleArray(qualities);
       return base.InstrumentedApply();
     }
 
-    public static double[] Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable<int> rows, bool applyLinearScaling) {
+    public static double[] Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable<int> rows, bool applyLinearScaling, int decimalPlaces) {
       double r2 = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(interpreter, solution, lowerEstimationLimit, upperEstimationLimit, problemData, rows, applyLinearScaling);
-      r2 = Math.Round(r2, 3);
+      if (decimalPlaces >= 0)
+        r2 = Math.Round(r2, decimalPlaces);
       return new double[2] { r2, SymbolicDataAnalysisModelComplexityAnalyzer.CalculateComplexity(solution.Root.GetSubtree(0).GetSubtree(0)) };
     }
@@ -92,5 +73,5 @@
       ApplyLinearScalingParameter.ExecutionContext = context;
 
-      double[] quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, ApplyLinearScalingParameter.ActualValue.Value);
+      double[] quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, ApplyLinearScalingParameter.ActualValue.Value, DecimalPlaces);
 
       SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
Index: branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectiveEvaluator.cs
===================================================================
--- branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectiveEvaluator.cs	(revision 12847)
+++ branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectiveEvaluator.cs	(revision 12848)
@@ -22,7 +22,31 @@
 
 using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
+  [StorableClass]
   public abstract class SymbolicRegressionMultiObjectiveEvaluator : SymbolicDataAnalysisMultiObjectiveEvaluator<IRegressionProblemData>, ISymbolicRegressionMultiObjectiveEvaluator {
+    private const string DecimalPlacesParameterName = "Decimal Places";
+    private const string UseConstantOptimizationParameterName = "Use constant optimization";
+
+    public IFixedValueParameter<IntValue> DecimalPlacesParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[DecimalPlacesParameterName]; }
+    }
+    public IFixedValueParameter<BoolValue> UseConstantOptimizationParameter {
+      get { return (IFixedValueParameter<BoolValue>)Parameters[UseConstantOptimizationParameterName]; }
+    }
+
+    public int DecimalPlaces {
+      get { return DecimalPlacesParameter.Value.Value; }
+      set { DecimalPlacesParameter.Value.Value = value; }
+    }
+    public bool UseConstantOptimization {
+      get { return UseConstantOptimizationParameter.Value.Value; }
+      set { UseConstantOptimizationParameter.Value.Value = value; }
+    }
+
     [StorableConstructor]
     protected SymbolicRegressionMultiObjectiveEvaluator(bool deserializing) : base(deserializing) { }
@@ -31,5 +55,19 @@
     }
 
-    protected SymbolicRegressionMultiObjectiveEvaluator() : base() { }
+    protected SymbolicRegressionMultiObjectiveEvaluator()
+      : base() {
+      Parameters.Add(new FixedValueParameter<IntValue>(DecimalPlacesParameterName, "The number of decimal places used for rounding the quality values.", new IntValue(5)) { Hidden = true });
+      Parameters.Add(new FixedValueParameter<BoolValue>(UseConstantOptimizationParameterName, "", new BoolValue(false)));
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (!Parameters.ContainsKey(UseConstantOptimizationParameterName)) {
+        Parameters.Add(new FixedValueParameter<BoolValue>(UseConstantOptimizationParameterName, "", new BoolValue(false)));
+      }
+      if (!Parameters.ContainsKey(DecimalPlacesParameterName)) {
+        Parameters.Add(new FixedValueParameter<IntValue>(DecimalPlacesParameterName, "The number of decimal places used for rounding the quality values.", new IntValue(-1)) { Hidden = true });
+      }
+    }
   }
 }
Index: branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectiveMeanSquaredErrorTreeSizeEvaluator.cs
===================================================================
--- branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectiveMeanSquaredErrorTreeSizeEvaluator.cs	(revision 12847)
+++ branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectiveMeanSquaredErrorTreeSizeEvaluator.cs	(revision 12848)
@@ -20,4 +20,5 @@
 #endregion
 
+using System;
 using System.Collections.Generic;
 using HeuristicLab.Common;
@@ -47,25 +48,25 @@
       IEnumerable<int> rows = GenerateRowsToEvaluate();
       var solution = SymbolicExpressionTreeParameter.ActualValue;
-      double[] qualities = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows, ApplyLinearScalingParameter.ActualValue.Value);
+      var problemData = ProblemDataParameter.ActualValue;
+      var interpreter = SymbolicDataAnalysisTreeInterpreterParameter.ActualValue;
+      var estimationLimits = EstimationLimitsParameter.ActualValue;
+      var applyLinearScaling = ApplyLinearScalingParameter.ActualValue.Value;
+
+      if (UseConstantOptimization) {
+        SymbolicRegressionConstantOptimizationEvaluator.OptimizeConstants(interpreter, solution, problemData, rows, applyLinearScaling, 5, estimationLimits.Upper, estimationLimits.Lower);
+      }
+
+      double[] qualities = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows, ApplyLinearScalingParameter.ActualValue.Value, DecimalPlaces);
       QualitiesParameter.ActualValue = new DoubleArray(qualities);
       return base.InstrumentedApply();
     }
 
-    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);
-      IEnumerable<double> targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
-      OnlineCalculatorError errorState;
+    public static double[] Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable<int> rows, bool applyLinearScaling, int decimalPlaces) {
+      var mse = SymbolicRegressionSingleObjectiveMeanSquaredErrorEvaluator.Calculate(interpreter, solution, lowerEstimationLimit,
+        upperEstimationLimit, problemData, rows, applyLinearScaling);
 
-      double mse;
-      if (applyLinearScaling) {
-        var mseCalculator = new OnlineMeanSquaredErrorCalculator();
-        CalculateWithScaling(targetValues, estimatedValues, lowerEstimationLimit, upperEstimationLimit, mseCalculator, problemData.Dataset.Rows);
-        errorState = mseCalculator.ErrorState;
-        mse = mseCalculator.MeanSquaredError;
-      } else {
-        IEnumerable<double> boundedEstimatedValues = estimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit);
-        mse = OnlineMeanSquaredErrorCalculator.Calculate(targetValues, boundedEstimatedValues, out errorState);
-      }
-      if (errorState != OnlineCalculatorError.None) mse = double.NaN;
+      if (decimalPlaces >= 0)
+        mse = Math.Round(mse, decimalPlaces);
+
       return new double[2] { mse, solution.Length };
     }
@@ -76,5 +77,5 @@
       ApplyLinearScalingParameter.ExecutionContext = context;
 
-      double[] quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, ApplyLinearScalingParameter.ActualValue.Value);
+      double[] quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, ApplyLinearScalingParameter.ActualValue.Value, DecimalPlaces);
 
       SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
Index: branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectivePearsonRSquaredTreeSizeEvaluator.cs
===================================================================
--- branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectivePearsonRSquaredTreeSizeEvaluator.cs	(revision 12847)
+++ branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectivePearsonRSquaredTreeSizeEvaluator.cs	(revision 12848)
@@ -26,5 +26,4 @@
 using HeuristicLab.Data;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
@@ -33,13 +32,4 @@
   [StorableClass]
   public class SymbolicRegressionMultiObjectivePearsonRSquaredTreeSizeEvaluator : SymbolicRegressionMultiObjectiveEvaluator {
-    private const string useConstantOptimizationParameterName = "Use constant optimization";
-    public IFixedValueParameter<BoolValue> UseConstantOptimizationParameter {
-      get { return (IFixedValueParameter<BoolValue>)Parameters[useConstantOptimizationParameterName]; }
-    }
-    public bool UseConstantOptimization {
-      get { return UseConstantOptimizationParameter.Value.Value; }
-      set { UseConstantOptimizationParameter.Value.Value = value; }
-    }
-
     [StorableConstructor]
     protected SymbolicRegressionMultiObjectivePearsonRSquaredTreeSizeEvaluator(bool deserializing) : base(deserializing) { }
@@ -51,15 +41,5 @@
     }
 
-    public SymbolicRegressionMultiObjectivePearsonRSquaredTreeSizeEvaluator() : base()
-    {
-      Parameters.Add(new FixedValueParameter<BoolValue>(useConstantOptimizationParameterName, "", new BoolValue(false)));
-    }
-
-    [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserialization() {
-      if (!Parameters.ContainsKey(useConstantOptimizationParameterName)) {
-        Parameters.Add(new FixedValueParameter<BoolValue>(useConstantOptimizationParameterName, "", new BoolValue(false)));
-      }
-    }
+    public SymbolicRegressionMultiObjectivePearsonRSquaredTreeSizeEvaluator() : base() { }
 
     public override IEnumerable<bool> Maximization { get { return new bool[2] { true, false }; } }
@@ -76,12 +56,13 @@
         SymbolicRegressionConstantOptimizationEvaluator.OptimizeConstants(interpreter, solution, problemData, rows, applyLinearScaling, 5, estimationLimits.Upper, estimationLimits.Lower);
       }
-      double[] qualities = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows, ApplyLinearScalingParameter.ActualValue.Value);
+      double[] qualities = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows, ApplyLinearScalingParameter.ActualValue.Value, DecimalPlaces);
       QualitiesParameter.ActualValue = new DoubleArray(qualities);
       return base.InstrumentedApply();
     }
 
-    public static double[] Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable<int> rows, bool applyLinearScaling) {
+    public static double[] Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable<int> rows, bool applyLinearScaling, int decimalPlaces) {
       double r2 = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(interpreter, solution, lowerEstimationLimit, upperEstimationLimit, problemData, rows, applyLinearScaling);
-      r2 = Math.Round(r2, 3);
+      if (decimalPlaces >= 0)
+        r2 = Math.Round(r2, decimalPlaces);
       return new double[2] { r2, solution.Length };
     }
@@ -92,5 +73,5 @@
       ApplyLinearScalingParameter.ExecutionContext = context;
 
-      double[] quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, ApplyLinearScalingParameter.ActualValue.Value);
+      double[] quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, ApplyLinearScalingParameter.ActualValue.Value, DecimalPlaces);
 
       SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
Index: branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/Plugin.cs.frame
===================================================================
--- branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/Plugin.cs.frame	(revision 12847)
+++ branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/Plugin.cs.frame	(revision 12848)
@@ -26,5 +26,5 @@
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
-  [Plugin("HeuristicLab.Problems.DataAnalysis.Symbolic.Regression","Provides classes to perform symbolic regression (single- or multiobjective).", "3.4.7.$WCREV$")]
+  [Plugin("HeuristicLab.Problems.DataAnalysis.Symbolic.Regression","Provides classes to perform symbolic regression (single- or multiobjective).", "3.4.8.$WCREV$")]
   [PluginFile("HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.dll", PluginFileType.Assembly)]
   [PluginDependency("HeuristicLab.ALGLIB", "3.7.0")]
Index: branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/Properties/AssemblyInfo.cs.frame
===================================================================
--- branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/Properties/AssemblyInfo.cs.frame	(revision 12847)
+++ branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/Properties/AssemblyInfo.cs.frame	(revision 12848)
@@ -53,3 +53,3 @@
 // by using the '*' as shown below:
 [assembly: AssemblyVersion("3.4.0.0")]
-[assembly: AssemblyFileVersion("3.4.7.$WCREV$")]
+[assembly: AssemblyFileVersion("3.4.8.$WCREV$")]
Index: branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.cs
===================================================================
--- branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.cs	(revision 12847)
+++ branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.cs	(revision 12848)
@@ -59,16 +59,16 @@
       OnlineCalculatorError errorState;
 
-      double r2;
+      double r;
       if (applyLinearScaling) {
-        var r2Calculator = new OnlinePearsonsRSquaredCalculator();
-        CalculateWithScaling(targetValues, estimatedValues, lowerEstimationLimit, upperEstimationLimit, r2Calculator, problemData.Dataset.Rows);
-        errorState = r2Calculator.ErrorState;
-        r2 = r2Calculator.RSquared;
+        var rCalculator = new OnlinePearsonsRCalculator();
+        CalculateWithScaling(targetValues, estimatedValues, lowerEstimationLimit, upperEstimationLimit, rCalculator, problemData.Dataset.Rows);
+        errorState = rCalculator.ErrorState;
+        r = rCalculator.R;
       } else {
         IEnumerable<double> boundedEstimatedValues = estimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit);
-        r2 = OnlinePearsonsRSquaredCalculator.Calculate(targetValues, boundedEstimatedValues, out errorState);
+        r = OnlinePearsonsRCalculator.Calculate(targetValues, boundedEstimatedValues, out errorState);
       }
       if (errorState != OnlineCalculatorError.None) return double.NaN;
-      return r2;
+      return r*r;
     }
 
Index: branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionPruningAnalyzer.cs
===================================================================
--- branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionPruningAnalyzer.cs	(revision 12847)
+++ branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionPruningAnalyzer.cs	(revision 12848)
@@ -24,4 +24,5 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
+using HeuristicLab.Data;
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
@@ -49,4 +50,37 @@
       Parameters.Add(new ValueParameter<SymbolicRegressionPruningOperator>(PruningOperatorParameterName, "The operator used to prune trees", new SymbolicRegressionPruningOperator(new SymbolicRegressionSolutionImpactValuesCalculator())));
     }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      // BackwardsCompatibility3.3
+
+      #region Backwards compatible code, remove with 3.4
+      if (Parameters.ContainsKey(PruningOperatorParameterName)) {
+        var oldParam = Parameters[PruningOperatorParameterName] as ValueParameter<SymbolicDataAnalysisExpressionPruningOperator>;
+        if (oldParam != null) {
+          Parameters.Remove(oldParam);
+          Parameters.Add(new ValueParameter<SymbolicRegressionPruningOperator>(PruningOperatorParameterName, "The operator used to prune trees", new SymbolicRegressionPruningOperator(new SymbolicRegressionSolutionImpactValuesCalculator())));
+        }
+      } else {
+        // not yet contained
+        Parameters.Add(new ValueParameter<SymbolicRegressionPruningOperator>(PruningOperatorParameterName, "The operator used to prune trees", new SymbolicRegressionPruningOperator(new SymbolicRegressionSolutionImpactValuesCalculator())));
+      }
+
+
+      if (Parameters.ContainsKey("PruneOnlyZeroImpactNodes")) {
+        PruningOperator.PruneOnlyZeroImpactNodes = ((IFixedValueParameter<BoolValue>)Parameters["PruneOnlyZeroImpactNodes"]).Value.Value;
+        Parameters.Remove(Parameters["PruneOnlyZeroImpactNodes"]);
+      }
+      if (Parameters.ContainsKey("ImpactThreshold")) {
+        PruningOperator.NodeImpactThreshold = ((IFixedValueParameter<DoubleValue>)Parameters["ImpactThreshold"]).Value.Value;
+        Parameters.Remove(Parameters["ImpactThreshold"]);
+      }
+      if (Parameters.ContainsKey("ImpactValuesCalculator")) {
+        PruningOperator.ImpactValuesCalculator = ((ValueParameter<SymbolicDataAnalysisSolutionImpactValuesCalculator>)Parameters["ImpactValuesCalculator"]).Value;
+        Parameters.Remove(Parameters["ImpactValuesCalculator"]);
+      }
+
+      #endregion
+    }
   }
 }
Index: branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionPruningOperator.cs
===================================================================
--- branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionPruningOperator.cs	(revision 12847)
+++ branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionPruningOperator.cs	(revision 12848)
@@ -27,4 +27,5 @@
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
@@ -33,4 +34,12 @@
   [Item("SymbolicRegressionPruningOperator", "An operator which prunes symbolic regression trees.")]
   public class SymbolicRegressionPruningOperator : SymbolicDataAnalysisExpressionPruningOperator {
+    private const string EvaluatorParameterName = "Evaluator";
+
+    #region parameter properties
+    public ILookupParameter<ISymbolicRegressionSingleObjectiveEvaluator> EvaluatorParameter {
+      get { return (ILookupParameter<ISymbolicRegressionSingleObjectiveEvaluator>)Parameters[EvaluatorParameterName]; }
+    }
+    #endregion
+
     protected SymbolicRegressionPruningOperator(SymbolicRegressionPruningOperator original, Cloner cloner)
       : base(original, cloner) {
@@ -45,4 +54,16 @@
     public SymbolicRegressionPruningOperator(ISymbolicDataAnalysisSolutionImpactValuesCalculator impactValuesCalculator)
       : base(impactValuesCalculator) {
+      Parameters.Add(new LookupParameter<ISymbolicRegressionSingleObjectiveEvaluator>(EvaluatorParameterName));
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      // BackwardsCompatibility3.3
+      #region Backwards compatible code, remove with 3.4
+      base.ImpactValuesCalculator = new SymbolicRegressionSolutionImpactValuesCalculator();
+      if (!Parameters.ContainsKey(EvaluatorParameterName)) {
+        Parameters.Add(new LookupParameter<ISymbolicRegressionSingleObjectiveEvaluator>(EvaluatorParameterName));
+      }
+      #endregion
     }
 
@@ -52,18 +73,10 @@
 
     protected override double Evaluate(IDataAnalysisModel model) {
-      var regressionModel = (IRegressionModel)model;
+      var regressionModel = (ISymbolicRegressionModel)model;
       var regressionProblemData = (IRegressionProblemData)ProblemDataParameter.ActualValue;
-      var rows = Enumerable.Range(FitnessCalculationPartitionParameter.ActualValue.Start, FitnessCalculationPartitionParameter.ActualValue.Size);
-      return Evaluate(regressionModel, regressionProblemData, rows);
-    }
-
-    private static double Evaluate(IRegressionModel model, IRegressionProblemData problemData,
-      IEnumerable<int> rows) {
-      var estimatedValues = model.GetEstimatedValues(problemData.Dataset, rows); // also bounds the values
-      var targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
-      OnlineCalculatorError errorState;
-      var quality = OnlinePearsonsRSquaredCalculator.Calculate(targetValues, estimatedValues, out errorState);
-      if (errorState != OnlineCalculatorError.None) return double.NaN;
-      return quality;
+      var evaluator = EvaluatorParameter.ActualValue;
+      var fitnessEvaluationPartition = FitnessCalculationPartitionParameter.ActualValue;
+      var rows = Enumerable.Range(fitnessEvaluationPartition.Start, fitnessEvaluationPartition.Size);
+      return evaluator.Evaluate(this.ExecutionContext, regressionModel.SymbolicExpressionTree, regressionProblemData, rows);
     }
 
@@ -72,5 +85,6 @@
       var model = new SymbolicRegressionModel(clonedTree, interpreter, estimationLimits.Lower, estimationLimits.Upper);
       var nodes = clonedTree.Root.GetSubtree(0).GetSubtree(0).IterateNodesPrefix().ToList(); // skip the nodes corresponding to the ProgramRootSymbol and the StartSymbol
-      double quality = Evaluate(model, problemData, rows);
+
+      double qualityForImpactsCalculation = double.NaN; // pass a NaN value initially so the impact calculator will calculate the quality
 
       for (int i = 0; i < nodes.Count; ++i) {
@@ -79,5 +93,6 @@
 
         double impactValue, replacementValue;
-        impactValuesCalculator.CalculateImpactAndReplacementValues(model, node, problemData, rows, out impactValue, out replacementValue, quality);
+        double newQualityForImpactsCalculation;
+        impactValuesCalculator.CalculateImpactAndReplacementValues(model, node, problemData, rows, out impactValue, out replacementValue, out newQualityForImpactsCalculation, qualityForImpactsCalculation);
 
         if (pruneOnlyZeroImpactNodes && !impactValue.IsAlmost(0.0)) continue;
@@ -90,5 +105,5 @@
         i += node.GetLength() - 1; // skip subtrees under the node that was folded
 
-        quality -= impactValue;
+        qualityForImpactsCalculation = newQualityForImpactsCalculation;
       }
       return model.SymbolicExpressionTree;
Index: branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionSolutionImpactValuesCalculator.cs
===================================================================
--- branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionSolutionImpactValuesCalculator.cs	(revision 12847)
+++ branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionSolutionImpactValuesCalculator.cs	(revision 12848)
@@ -48,13 +48,13 @@
     }
 
-    public override double CalculateImpactValue(ISymbolicDataAnalysisModel model, ISymbolicExpressionTreeNode node, IDataAnalysisProblemData problemData, IEnumerable<int> rows, double originalQuality = double.NaN) {
-      double impactValue, replacementValue;
-      CalculateImpactAndReplacementValues(model, node, problemData, rows, out impactValue, out replacementValue, originalQuality);
+    public override double CalculateImpactValue(ISymbolicDataAnalysisModel model, ISymbolicExpressionTreeNode node, IDataAnalysisProblemData problemData, IEnumerable<int> rows, double qualityForImpactsCalculation = double.NaN) {
+      double impactValue, replacementValue, newQualityForImpactsCalculation;
+      CalculateImpactAndReplacementValues(model, node, problemData, rows, out impactValue, out replacementValue, out newQualityForImpactsCalculation, qualityForImpactsCalculation);
       return impactValue;
     }
 
     public override void CalculateImpactAndReplacementValues(ISymbolicDataAnalysisModel model, ISymbolicExpressionTreeNode node,
-      IDataAnalysisProblemData problemData, IEnumerable<int> rows, out double impactValue, out double replacementValue,
-      double originalQuality = Double.NaN) {
+      IDataAnalysisProblemData problemData, IEnumerable<int> rows, out double impactValue, out double replacementValue, out double newQualityForImpactsCalculation,
+      double qualityForImpactsCalculation = Double.NaN) {
       var regressionModel = (ISymbolicRegressionModel)model;
       var regressionProblemData = (IRegressionProblemData)problemData;
@@ -64,9 +64,6 @@
 
       OnlineCalculatorError errorState;
-      if (double.IsNaN(originalQuality)) {
-        var originalValues = regressionModel.GetEstimatedValues(dataset, rows);
-        originalQuality = OnlinePearsonsRSquaredCalculator.Calculate(targetValues, originalValues, out errorState);
-        if (errorState != OnlineCalculatorError.None) originalQuality = 0.0;
-      }
+      if (double.IsNaN(qualityForImpactsCalculation))
+        qualityForImpactsCalculation = CalculateQualityForImpacts(regressionModel, regressionProblemData, rows);
 
       replacementValue = CalculateReplacementValue(regressionModel, node, regressionProblemData, rows);
@@ -83,8 +80,19 @@
 
       var estimatedValues = tempModel.GetEstimatedValues(dataset, rows);
-      double newQuality = OnlinePearsonsRSquaredCalculator.Calculate(targetValues, estimatedValues, out errorState);
-      if (errorState != OnlineCalculatorError.None) newQuality = 0.0;
+      double r = OnlinePearsonsRCalculator.Calculate(targetValues, estimatedValues, out errorState);
+      if (errorState != OnlineCalculatorError.None) r = 0.0;
+      newQualityForImpactsCalculation = r * r;
 
-      impactValue = originalQuality - newQuality;
+      impactValue = qualityForImpactsCalculation - newQualityForImpactsCalculation;
+    }
+
+    public static double CalculateQualityForImpacts(ISymbolicRegressionModel model, IRegressionProblemData problemData, IEnumerable<int> rows) {
+      var estimatedValues = model.GetEstimatedValues(problemData.Dataset, rows); // also bounds the values
+      var targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
+      OnlineCalculatorError errorState;
+      var r = OnlinePearsonsRCalculator.Calculate(targetValues, estimatedValues, out errorState);
+      var quality = r * r;
+      if (errorState != OnlineCalculatorError.None) return double.NaN;
+      return quality;
     }
   }
Index: branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectivePruningAnalyzer.cs
===================================================================
--- branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectivePruningAnalyzer.cs	(revision 12847)
+++ branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectivePruningAnalyzer.cs	(revision 12848)
@@ -206,5 +206,6 @@
       var qualities = Quality.Select(x => x.Value).ToArray();
       var indices = Enumerable.Range(0, qualities.Length).ToArray();
-      Array.Sort(qualities, indices);
+      indices.StableSort((a, b) => qualities[a].CompareTo(qualities[b]));
+
       if (!Maximization.Value) Array.Reverse(indices);
 
@@ -214,5 +215,5 @@
       var empty = new EmptyOperator();
 
-      for (int i = 0; i < subscopes.Count; ++i) {
+      for (int i = 0; i < indices.Length; ++i) {
         IOperator @operator;
         if (range.Start <= i && i < range.End && random.NextDouble() <= PruningProbability)
Index: branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Plugin.cs.frame
===================================================================
--- branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Plugin.cs.frame	(revision 12847)
+++ branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Plugin.cs.frame	(revision 12848)
@@ -26,5 +26,5 @@
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
-  [Plugin("HeuristicLab.Problems.DataAnalysis.Symbolic","Provides base classes for symbolic data analysis tasks.", "3.4.7.$WCREV$")]
+  [Plugin("HeuristicLab.Problems.DataAnalysis.Symbolic","Provides base classes for symbolic data analysis tasks.", "3.4.8.$WCREV$")]
   [PluginFile("HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.dll", PluginFileType.Assembly)]
   [PluginDependency("HeuristicLab.ALGLIB", "3.7.0")]
Index: branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionPruningOperator.cs
===================================================================
--- branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionPruningOperator.cs	(revision 12847)
+++ branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionPruningOperator.cs	(revision 12848)
@@ -49,4 +49,5 @@
     private const string EstimationLimitsParameterName = "EstimationLimits";
     private const string InterpreterParameterName = "SymbolicExpressionTreeInterpreter";
+    private const string ApplyLinearScalingParameterName = "ApplyLinearScaling";
     #endregion
 
@@ -87,4 +88,7 @@
     public ILookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter> InterpreterParameter {
       get { return (ILookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>)Parameters[InterpreterParameterName]; }
+    }
+    public ILookupParameter<BoolValue> ApplyLinearScalingParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters[ApplyLinearScalingParameterName]; }
     }
     #endregion
@@ -124,5 +128,23 @@
       Parameters.Add(new LookupParameter<ISymbolicExpressionTree>(SymbolicExpressionTreeParameterName));
       Parameters.Add(new LookupParameter<DoubleValue>(QualityParameterName));
+      Parameters.Add(new LookupParameter<BoolValue>(ApplyLinearScalingParameterName));
       Parameters.Add(new ValueParameter<ISymbolicDataAnalysisSolutionImpactValuesCalculator>(ImpactValuesCalculatorParameterName, impactValuesCalculator));
+      #endregion
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      // BackwardsCompatibility3.3
+      #region Backwards compatible code, remove with 3.4
+      if (!Parameters.ContainsKey(PrunedNodesParameterName)) {
+        Parameters.Add(new LookupParameter<IntValue>(PrunedNodesParameterName, "A counter of how many nodes were pruned."));
+      }
+      if (!Parameters.ContainsKey(ApplyLinearScalingParameterName)) {
+        Parameters.Add(new LookupParameter<BoolValue>(ApplyLinearScalingParameterName));
+      }
+      if (!Parameters.ContainsKey(ImpactValuesCalculatorParameterName)) {
+        // value must be set by derived operators (regression/classification)
+        Parameters.Add(new ValueParameter<ISymbolicDataAnalysisSolutionImpactValuesCalculator>(ImpactValuesCalculatorParameterName));
+      }
       #endregion
     }
@@ -141,10 +163,10 @@
       var model = CreateModel(tree, interpreter, problemData, estimationLimits);
       var nodes = tree.Root.GetSubtree(0).GetSubtree(0).IterateNodesPrefix().ToList();
-      var rows = Enumerable.Range(fitnessCalculationPartition.Start, fitnessCalculationPartition.Size);
+      var rows = Enumerable.Range(fitnessCalculationPartition.Start, fitnessCalculationPartition.Size).ToList();
       var prunedSubtrees = 0;
       var prunedTrees = 0;
       var prunedNodes = 0;
 
-      double quality = Evaluate(model);
+      double qualityForImpactsCalculation = double.NaN;
 
       for (int i = 0; i < nodes.Count; ++i) {
@@ -153,5 +175,6 @@
 
         double impactValue, replacementValue;
-        ImpactValuesCalculator.CalculateImpactAndReplacementValues(model, node, problemData, rows, out impactValue, out replacementValue, quality);
+        double newQualityForImpacts;
+        ImpactValuesCalculator.CalculateImpactAndReplacementValues(model, node, problemData, rows, out impactValue, out replacementValue, out newQualityForImpacts, qualityForImpactsCalculation);
 
         if (PruneOnlyZeroImpactNodes && !impactValue.IsAlmost(0.0)) continue;
@@ -165,7 +188,8 @@
         i += length - 1; // skip subtrees under the node that was folded
 
-        quality -= impactValue;
         prunedSubtrees++;
         prunedNodes += length;
+
+        qualityForImpactsCalculation = newQualityForImpacts;
       }
 
@@ -174,5 +198,7 @@
       PrunedTreesParameter.ActualValue = new IntValue(prunedTrees);
       PrunedNodesParameter.ActualValue = new IntValue(prunedNodes);
-      QualityParameter.ActualValue.Value = quality;
+
+      if (prunedSubtrees > 0) // if nothing was pruned then there's no need to re-evaluate the tree
+        QualityParameter.ActualValue.Value = Evaluate(model);
 
       return base.Apply();
Index: branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisSolutionImpactValuesCalculator.cs
===================================================================
--- branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisSolutionImpactValuesCalculator.cs	(revision 12847)
+++ branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisSolutionImpactValuesCalculator.cs	(revision 12848)
@@ -37,6 +37,6 @@
     protected SymbolicDataAnalysisSolutionImpactValuesCalculator(bool deserializing) : base(deserializing) { }
     public abstract double CalculateReplacementValue(ISymbolicDataAnalysisModel model, ISymbolicExpressionTreeNode node, IDataAnalysisProblemData problemData, IEnumerable<int> rows);
-    public abstract double CalculateImpactValue(ISymbolicDataAnalysisModel model, ISymbolicExpressionTreeNode node, IDataAnalysisProblemData problemData, IEnumerable<int> rows, double originalQuality = double.NaN);
-    public abstract void CalculateImpactAndReplacementValues(ISymbolicDataAnalysisModel model, ISymbolicExpressionTreeNode node, IDataAnalysisProblemData problemData, IEnumerable<int> rows, out double impactValue, out double replacementValue, double originalQuality = double.NaN);
+    public abstract double CalculateImpactValue(ISymbolicDataAnalysisModel model, ISymbolicExpressionTreeNode node, IDataAnalysisProblemData problemData, IEnumerable<int> rows, double qualityForImpactsCalculation = double.NaN);
+    public abstract void CalculateImpactAndReplacementValues(ISymbolicDataAnalysisModel model, ISymbolicExpressionTreeNode node, IDataAnalysisProblemData problemData, IEnumerable<int> rows, out double impactValue, out double replacementValue, out double newQualityForImpactsCalculation, double qualityForImpactsCalculation = double.NaN);
 
     protected static double CalculateReplacementValue(ISymbolicExpressionTreeNode node, ISymbolicExpressionTree sourceTree, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
