Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views-3.4.csproj
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views-3.4.csproj	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views-3.4.csproj	(revision 8915)
@@ -95,49 +95,65 @@
     <Reference Include="HeuristicLab.Collections-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Collections-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Common-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Common-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Common.Resources-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Common.Resources-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Core-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Core-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Core.Views-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Core.Views-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Data-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Data-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Data.Views-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Data.Views-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.MainForm-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.MainForm-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.MainForm.WindowsForms-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.MainForm.WindowsForms-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Operators-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Operators-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Optimization-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Optimization-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Optimization.Views-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Optimization.Views-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.PluginInfrastructure-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Random-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Random-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Visualization.ChartControlsExtensions-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Visualization.ChartControlsExtensions-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="System" />
@@ -242,5 +258,5 @@
   -->
   <PropertyGroup>
-    <PreBuildEvent>set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+    <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
 set ProjectDir=$(ProjectDir)
 set SolutionDir=$(SolutionDir)
@@ -249,4 +265,10 @@
 call PreBuildEvent.cmd
 </PreBuildEvent>
+    <PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
+export ProjectDir=$(ProjectDir)
+export SolutionDir=$(SolutionDir)
+
+$SolutionDir/PreBuildEvent.sh
+</PreBuildEvent>
   </PropertyGroup>
 </Project>
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/SymbolView.Designer.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/SymbolView.Designer.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/SymbolView.Designer.cs	(revision 8915)
@@ -175,5 +175,5 @@
     protected System.Windows.Forms.Label initialFrequencyLabel;
     protected System.Windows.Forms.TextBox initialFrequencyTextBox;
-    private System.Windows.Forms.CheckBox enabledCheckBox;
+    protected System.Windows.Forms.CheckBox enabledCheckBox;
     protected System.Windows.Forms.Label minimumArityLabel;
     protected System.Windows.Forms.Label maximumArityLabel;
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification-3.4.csproj
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification-3.4.csproj	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification-3.4.csproj	(revision 8915)
@@ -93,45 +93,64 @@
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="ALGLIB-3.5.0">
-      <HintPath>..\..\..\..\Trunk\sources\bin\ALGLIB-3.5.0.dll</HintPath>
+    <Reference Include="ALGLIB-3.6.0">
+      <HintPath>..\..\..\..\Trunk\sources\bin\ALGLIB-3.6.0.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Analysis-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Analysis-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Collections-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Collections-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Common-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Common-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Common.Resources-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Common.Resources-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Core-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Core-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Data-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Data-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Operators-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Operators-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Optimization-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Optimization-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Parameters-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Parameters-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Persistence-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Persistence-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.PluginInfrastructure-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Problems.DataAnalysis-3.4">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Problems.DataAnalysis-3.4.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Problems.Instances-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Problems.Instances-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="System" />
@@ -150,7 +169,15 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="Interfaces\ISymbolicClassificationModelCreatorOperator.cs" />
+    <Compile Include="Interfaces\ISymbolicDiscriminantFunctionClassificationModelCreator.cs" />
+    <Compile Include="Interfaces\ISymbolicClassificationModelCreator.cs" />
     <Compile Include="Interfaces\ISymbolicDiscriminantFunctionClassificationModel.cs" />
+    <Compile Include="ModelCreators\AccuracyMaximizingThresholdsModelCreator.cs" />
+    <Compile Include="ModelCreators\NearestNeighborModelCreator.cs" />
+    <Compile Include="ModelCreators\NormalDistributedThresholdsModelCreator.cs" />
     <Compile Include="MultiObjective\SymbolicClassificationMultiObjectiveValidationBestSolutionAnalyzer.cs" />
+    <Compile Include="SymbolicNearestNeighbourClassificationModel.cs" />
     <Compile Include="Plugin.cs" />
+    <Compile Include="SingleObjective\SymbolicClassificationSingleObjectivePenaltyScoreEvaluator.cs" />
     <Compile Include="SingleObjective\SymbolicClassificationSingleObjectiveBoundedMeanSquaredErrorEvaluator.cs" />
     <Compile Include="SingleObjective\SymbolicClassificationSingleObjectiveOverfittingAnalyzer.cs" />
@@ -178,5 +205,4 @@
       <SubType>Code</SubType>
     </Compile>
-    <Compile Include="SymbolicDiscriminantFunctionClassificationSolutionValuesCalculator.cs" />
     <None Include="HeuristicLab.snk" />
     <None Include="Plugin.cs.frame" />
@@ -220,5 +246,5 @@
   -->
   <PropertyGroup>
-    <PreBuildEvent>set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+    <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
 set ProjectDir=$(ProjectDir)
 set SolutionDir=$(SolutionDir)
@@ -227,4 +253,10 @@
 call PreBuildEvent.cmd
 </PreBuildEvent>
+    <PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
+export ProjectDir=$(ProjectDir)
+export SolutionDir=$(SolutionDir)
+
+$SolutionDir/PreBuildEvent.sh
+</PreBuildEvent>
   </PropertyGroup>
 </Project>
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/Interfaces/ISymbolicClassificationModel.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/Interfaces/ISymbolicClassificationModel.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/Interfaces/ISymbolicClassificationModel.cs	(revision 8915)
@@ -20,7 +20,11 @@
 #endregion
 
-using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using System.Collections.Generic;
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Classification {
   public interface ISymbolicClassificationModel : IClassificationModel, ISymbolicDataAnalysisModel {
+    double LowerEstimationLimit { get; }
+    double UpperEstimationLimit { get; }
+    void RecalculateModelParameters(IClassificationProblemData problemData, IEnumerable<int> rows);
+    new ISymbolicClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData);
   }
 }
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/Interfaces/ISymbolicClassificationModelCreator.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/Interfaces/ISymbolicClassificationModelCreator.cs	(revision 8915)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/Interfaces/ISymbolicClassificationModelCreator.cs	(revision 8915)
@@ -0,0 +1,30 @@
+﻿#region License Information
+
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#endregion
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Classification {
+  public interface ISymbolicClassificationModelCreator : IItem {
+    ISymbolicClassificationModel CreateSymbolicClassificationModel(ISymbolicExpressionTree tree, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, double lowerEstimationLimit, double upperEstimationLimit);
+  }
+}
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/Interfaces/ISymbolicClassificationModelCreatorOperator.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/Interfaces/ISymbolicClassificationModelCreatorOperator.cs	(revision 8915)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/Interfaces/ISymbolicClassificationModelCreatorOperator.cs	(revision 8915)
@@ -0,0 +1,30 @@
+﻿#region License Information
+
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Classification {
+  public interface ISymbolicClassificationModelCreatorOperator : IOperator {
+    ILookupParameter<ISymbolicClassificationModelCreator> ModelCreatorParameter { get; }
+  }
+}
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/Interfaces/ISymbolicDiscriminantFunctionClassificationModel.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/Interfaces/ISymbolicDiscriminantFunctionClassificationModel.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/Interfaces/ISymbolicDiscriminantFunctionClassificationModel.cs	(revision 8915)
@@ -20,9 +20,7 @@
 #endregion
 
-using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Classification {
   public interface ISymbolicDiscriminantFunctionClassificationModel : IDiscriminantFunctionClassificationModel, ISymbolicClassificationModel {
-    double LowerEstimationLimit { get; }
-    double UpperEstimationLimit { get; }
+
   }
 }
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/Interfaces/ISymbolicDiscriminantFunctionClassificationModelCreator.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/Interfaces/ISymbolicDiscriminantFunctionClassificationModelCreator.cs	(revision 8915)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/Interfaces/ISymbolicDiscriminantFunctionClassificationModelCreator.cs	(revision 8915)
@@ -0,0 +1,29 @@
+﻿#region License Information
+
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#endregion
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Classification {
+  public interface ISymbolicDiscriminantFunctionClassificationModelCreator : ISymbolicClassificationModelCreator {
+    ISymbolicDiscriminantFunctionClassificationModel CreateSymbolicDiscriminantFunctionClassificationModel(ISymbolicExpressionTree tree, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, double lowerEstimationLimit, double upperEstimationLimit);
+  }
+}
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/MultiObjective/SymbolicClassificationMultiObjectiveMeanSquaredErrorTreeSizeEvaluator.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/MultiObjective/SymbolicClassificationMultiObjectiveMeanSquaredErrorTreeSizeEvaluator.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/MultiObjective/SymbolicClassificationMultiObjectiveMeanSquaredErrorTreeSizeEvaluator.cs	(revision 8915)
@@ -65,4 +65,5 @@
       SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = context;
       EstimationLimitsParameter.ExecutionContext = context;
+      ApplyLinearScalingParameter.ExecutionContext = context;
 
       double[] quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows);
@@ -70,4 +71,5 @@
       SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
       EstimationLimitsParameter.ExecutionContext = null;
+      ApplyLinearScalingParameter.ExecutionContext = null;
 
       return quality;
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/MultiObjective/SymbolicClassificationMultiObjectivePearsonRSquaredTreeSizeEvaluator.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/MultiObjective/SymbolicClassificationMultiObjectivePearsonRSquaredTreeSizeEvaluator.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/MultiObjective/SymbolicClassificationMultiObjectivePearsonRSquaredTreeSizeEvaluator.cs	(revision 8915)
@@ -26,16 +26,27 @@
       IEnumerable<int> rows = GenerateRowsToEvaluate();
       var solution = SymbolicExpressionTreeParameter.ActualValue;
-      double[] qualities = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows);
+      double[] qualities = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows, ApplyLinearScalingParameter.ActualValue.Value);
       QualitiesParameter.ActualValue = new DoubleArray(qualities);
       return base.Apply();
     }
 
-    public static double[] Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IClassificationProblemData problemData, IEnumerable<int> rows) {
+    public static double[] Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IClassificationProblemData problemData, IEnumerable<int> rows, bool applyLinearScaling) {
       IEnumerable<double> estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, rows);
-      IEnumerable<double> originalValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
+      IEnumerable<double> targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
       OnlineCalculatorError errorState;
-      double r2 = OnlinePearsonsRSquaredCalculator.Calculate(estimatedValues, originalValues, out errorState);
-      if (errorState != OnlineCalculatorError.None) r2 = 0.0;
-      return new double[] { r2, solution.Length };
+
+      double r2;
+      if (applyLinearScaling) {
+        var r2Calculator = new OnlinePearsonsRSquaredCalculator();
+        CalculateWithScaling(targetValues, estimatedValues, lowerEstimationLimit, upperEstimationLimit, r2Calculator, problemData.Dataset.Rows);
+        errorState = r2Calculator.ErrorState;
+        r2 = r2Calculator.RSquared;
+      } else {
+        IEnumerable<double> boundedEstimatedValues = estimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit);
+        r2 = OnlinePearsonsRSquaredCalculator.Calculate(targetValues, boundedEstimatedValues, out errorState);
+      }
+
+      if (errorState != OnlineCalculatorError.None) r2 = double.NaN;
+      return new double[2] { r2, solution.Length };
 
     }
@@ -45,5 +56,5 @@
       EstimationLimitsParameter.ExecutionContext = context;
 
-      double[] quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows);
+      double[] quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, ApplyLinearScalingParameter.ActualValue.Value);
 
       SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/MultiObjective/SymbolicClassificationMultiObjectiveProblem.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/MultiObjective/SymbolicClassificationMultiObjectiveProblem.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/MultiObjective/SymbolicClassificationMultiObjectiveProblem.cs	(revision 8915)
@@ -36,4 +36,6 @@
     private const string EstimationLimitsParameterName = "EstimationLimits";
     private const string EstimationLimitsParameterDescription = "The lower and upper limit for the estimated value that can be returned by the symbolic classification model.";
+    private const string ModelCreatorParameterName = "ModelCreator";
+
 
     #region parameter properties
@@ -41,8 +43,14 @@
       get { return (IFixedValueParameter<DoubleLimit>)Parameters[EstimationLimitsParameterName]; }
     }
+    public IValueParameter<ISymbolicClassificationModelCreator> ModelCreatorParameter {
+      get { return (IValueParameter<ISymbolicClassificationModelCreator>)Parameters[ModelCreatorParameterName]; }
+    }
     #endregion
     #region properties
     public DoubleLimit EstimationLimits {
       get { return EstimationLimitsParameter.Value; }
+    }
+    public ISymbolicClassificationModelCreator ModelCreator {
+      get { return ModelCreatorParameter.Value; }
     }
     #endregion
@@ -58,5 +66,7 @@
       : base(new ClassificationProblemData(), new SymbolicClassificationMultiObjectiveMeanSquaredErrorTreeSizeEvaluator(), new SymbolicDataAnalysisExpressionTreeCreator()) {
       Parameters.Add(new FixedValueParameter<DoubleLimit>(EstimationLimitsParameterName, EstimationLimitsParameterDescription));
+      Parameters.Add(new ValueParameter<ISymbolicClassificationModelCreator>(ModelCreatorParameterName, "", new AccuracyMaximizingThresholdsModelCreator()));
 
+      ApplyLinearScalingParameter.Value.Value = false;
       EstimationLimitsParameter.Hidden = true;
 
@@ -74,4 +84,9 @@
     [StorableHook(HookType.AfterDeserialization)]
     private void AfterDeserialization() {
+      // BackwardsCompatibility3.4
+      #region Backwards compatible code, remove with 3.5
+      if (!Parameters.ContainsKey(ModelCreatorParameterName))
+        Parameters.Add(new ValueParameter<ISymbolicClassificationModelCreator>(ModelCreatorParameterName, "", new AccuracyMaximizingThresholdsModelCreator()));
+      #endregion
       RegisterEventHandlers();
     }
@@ -79,4 +94,5 @@
     private void RegisterEventHandlers() {
       SymbolicExpressionTreeGrammarParameter.ValueChanged += (o, e) => ConfigureGrammarSymbols();
+      ModelCreatorParameter.NameChanged += (o, e) => ParameterizeOperators();
     }
 
@@ -110,11 +126,12 @@
     }
 
-    protected new void ParameterizeOperators() {
+    protected override void ParameterizeOperators() {
       base.ParameterizeOperators();
       if (Parameters.ContainsKey(EstimationLimitsParameterName)) {
         var operators = Parameters.OfType<IValueParameter>().Select(p => p.Value).OfType<IOperator>().Union(Operators);
-        foreach (var op in operators.OfType<ISymbolicDataAnalysisBoundedOperator>()) {
-          op.EstimationLimitsParameter.ActualName = EstimationLimitsParameterName;
-        }
+        foreach (var op in operators.OfType<ISymbolicDataAnalysisBoundedOperator>())
+          op.EstimationLimitsParameter.ActualName = EstimationLimitsParameter.Name;
+        foreach (var op in operators.OfType<ISymbolicClassificationModelCreatorOperator>())
+          op.ModelCreatorParameter.ActualName = ModelCreatorParameter.Name;
       }
     }
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/MultiObjective/SymbolicClassificationMultiObjectiveTrainingBestSolutionAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/MultiObjective/SymbolicClassificationMultiObjectiveTrainingBestSolutionAnalyzer.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/MultiObjective/SymbolicClassificationMultiObjectiveTrainingBestSolutionAnalyzer.cs	(revision 8915)
@@ -22,5 +22,4 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Data;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 using HeuristicLab.Parameters;
@@ -34,13 +33,19 @@
   [StorableClass]
   public sealed class SymbolicClassificationMultiObjectiveTrainingBestSolutionAnalyzer : SymbolicDataAnalysisMultiObjectiveTrainingBestSolutionAnalyzer<ISymbolicClassificationSolution>,
-    ISymbolicDataAnalysisInterpreterOperator, ISymbolicDataAnalysisBoundedOperator {
+    ISymbolicDataAnalysisInterpreterOperator, ISymbolicDataAnalysisBoundedOperator, ISymbolicClassificationModelCreatorOperator {
     private const string ProblemDataParameterName = "ProblemData";
+    private const string ModelCreatorParameterName = "ModelCreator";
     private const string SymbolicDataAnalysisTreeInterpreterParameterName = "SymbolicDataAnalysisTreeInterpreter";
     private const string EstimationLimitsParameterName = "EstimationLimits";
-    private const string ApplyLinearScalingParameterName = "ApplyLinearScaling";
 
     #region parameter properties
     public ILookupParameter<IClassificationProblemData> ProblemDataParameter {
       get { return (ILookupParameter<IClassificationProblemData>)Parameters[ProblemDataParameterName]; }
+    }
+    public IValueLookupParameter<ISymbolicClassificationModelCreator> ModelCreatorParameter {
+      get { return (IValueLookupParameter<ISymbolicClassificationModelCreator>)Parameters[ModelCreatorParameterName]; }
+    }
+    ILookupParameter<ISymbolicClassificationModelCreator> ISymbolicClassificationModelCreatorOperator.ModelCreatorParameter {
+      get { return ModelCreatorParameter; }
     }
     public ILookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter> SymbolicDataAnalysisTreeInterpreterParameter {
@@ -49,13 +54,4 @@
     public IValueLookupParameter<DoubleLimit> EstimationLimitsParameter {
       get { return (IValueLookupParameter<DoubleLimit>)Parameters[EstimationLimitsParameterName]; }
-    }
-    public IValueParameter<BoolValue> ApplyLinearScalingParameter {
-      get { return (IValueParameter<BoolValue>)Parameters[ApplyLinearScalingParameterName]; }
-    }
-    #endregion
-
-    #region properties
-    public BoolValue ApplyLinearScaling {
-      get { return ApplyLinearScalingParameter.Value; }
     }
     #endregion
@@ -67,7 +63,7 @@
       : base() {
       Parameters.Add(new LookupParameter<IClassificationProblemData>(ProblemDataParameterName, "The problem data for the symbolic classification solution."));
+      Parameters.Add(new ValueLookupParameter<ISymbolicClassificationModelCreator>(ModelCreatorParameterName, ""));
       Parameters.Add(new LookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>(SymbolicDataAnalysisTreeInterpreterParameterName, "The symbolic data analysis tree interpreter for the symbolic expression tree."));
       Parameters.Add(new ValueLookupParameter<DoubleLimit>(EstimationLimitsParameterName, "The lower and upper limit for the estimated values produced by the symbolic classification model."));
-      Parameters.Add(new ValueParameter<BoolValue>(ApplyLinearScalingParameterName, "Flag that indicates if the produced symbolic classification solution should be linearly scaled.", new BoolValue(false)));
     }
     public override IDeepCloneable Clone(Cloner cloner) {
@@ -75,10 +71,19 @@
     }
 
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      // BackwardsCompatibility3.4
+      #region Backwards compatible code, remove with 3.5
+      if (!Parameters.ContainsKey(ModelCreatorParameterName))
+        Parameters.Add(new ValueLookupParameter<ISymbolicClassificationModelCreator>(ModelCreatorParameterName, ""));
+      #endregion
+    }
+
     protected override ISymbolicClassificationSolution CreateSolution(ISymbolicExpressionTree bestTree, double[] bestQuality) {
-      var model = new SymbolicDiscriminantFunctionClassificationModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
-      if (ApplyLinearScaling.Value) {
-        SymbolicDiscriminantFunctionClassificationModel.Scale(model, ProblemDataParameter.ActualValue);
-      }
-      return new SymbolicDiscriminantFunctionClassificationSolution(model, (IClassificationProblemData)ProblemDataParameter.ActualValue.Clone());
+      var model = ModelCreatorParameter.ActualValue.CreateSymbolicClassificationModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
+      if (ApplyLinearScalingParameter.ActualValue.Value) SymbolicClassificationModel.Scale(model, ProblemDataParameter.ActualValue, ProblemDataParameter.ActualValue.TargetVariable);
+
+      model.RecalculateModelParameters(ProblemDataParameter.ActualValue, ProblemDataParameter.ActualValue.TrainingIndices);
+      return model.CreateClassificationSolution((IClassificationProblemData)ProblemDataParameter.ActualValue.Clone());
     }
   }
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/MultiObjective/SymbolicClassificationMultiObjectiveValidationBestSolutionAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/MultiObjective/SymbolicClassificationMultiObjectiveValidationBestSolutionAnalyzer.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/MultiObjective/SymbolicClassificationMultiObjectiveValidationBestSolutionAnalyzer.cs	(revision 8915)
@@ -22,5 +22,4 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Data;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 using HeuristicLab.Parameters;
@@ -34,7 +33,7 @@
   [StorableClass]
   public sealed class SymbolicClassificationMultiObjectiveValidationBestSolutionAnalyzer : SymbolicDataAnalysisMultiObjectiveValidationBestSolutionAnalyzer<ISymbolicClassificationSolution, ISymbolicClassificationMultiObjectiveEvaluator, IClassificationProblemData>,
-  ISymbolicDataAnalysisBoundedOperator {
+  ISymbolicDataAnalysisBoundedOperator, ISymbolicClassificationModelCreatorOperator {
+    private const string ModelCreatorParameterName = "ModelCreator";
     private const string EstimationLimitsParameterName = "EstimationLimits";
-    private const string ApplyLinearScalingParameterName = "ApplyLinearScaling";
 
     #region parameter properties
@@ -42,14 +41,12 @@
       get { return (IValueLookupParameter<DoubleLimit>)Parameters[EstimationLimitsParameterName]; }
     }
-    public IValueParameter<BoolValue> ApplyLinearScalingParameter {
-      get { return (IValueParameter<BoolValue>)Parameters[ApplyLinearScalingParameterName]; }
+    public IValueLookupParameter<ISymbolicClassificationModelCreator> ModelCreatorParameter {
+      get { return (IValueLookupParameter<ISymbolicClassificationModelCreator>)Parameters[ModelCreatorParameterName]; }
+    }
+    ILookupParameter<ISymbolicClassificationModelCreator> ISymbolicClassificationModelCreatorOperator.ModelCreatorParameter {
+      get { return ModelCreatorParameter; }
     }
     #endregion
 
-    #region properties
-    public BoolValue ApplyLinearScaling {
-      get { return ApplyLinearScalingParameter.Value; }
-    }
-    #endregion
     [StorableConstructor]
     private SymbolicClassificationMultiObjectiveValidationBestSolutionAnalyzer(bool deserializing) : base(deserializing) { }
@@ -58,5 +55,5 @@
       : base() {
       Parameters.Add(new ValueLookupParameter<DoubleLimit>(EstimationLimitsParameterName, "The loewr and upper limit for the estimated values produced by the symbolic classification model."));
-      Parameters.Add(new ValueParameter<BoolValue>(ApplyLinearScalingParameterName, "Flag that indicates if the produced symbolic classification solution should be linearly scaled.", new BoolValue(false)));
+      Parameters.Add(new ValueLookupParameter<ISymbolicClassificationModelCreator>(ModelCreatorParameterName, ""));
     }
     public override IDeepCloneable Clone(Cloner cloner) {
@@ -64,10 +61,19 @@
     }
 
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      // BackwardsCompatibility3.4
+      #region Backwards compatible code, remove with 3.5
+      if (!Parameters.ContainsKey(ModelCreatorParameterName))
+        Parameters.Add(new ValueLookupParameter<ISymbolicClassificationModelCreator>(ModelCreatorParameterName, ""));
+      #endregion
+    }
+
     protected override ISymbolicClassificationSolution CreateSolution(ISymbolicExpressionTree bestTree, double[] bestQualities) {
-      var model = new SymbolicDiscriminantFunctionClassificationModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
-      if (ApplyLinearScaling.Value) {
-        SymbolicDiscriminantFunctionClassificationModel.Scale(model, ProblemDataParameter.ActualValue);
-      }
-      return new SymbolicDiscriminantFunctionClassificationSolution(model, (IClassificationProblemData)ProblemDataParameter.ActualValue.Clone());
+      var model = ModelCreatorParameter.ActualValue.CreateSymbolicClassificationModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
+      if (ApplyLinearScalingParameter.ActualValue.Value) SymbolicClassificationModel.Scale(model, ProblemDataParameter.ActualValue, ProblemDataParameter.ActualValue.TargetVariable);
+
+      model.RecalculateModelParameters(ProblemDataParameter.ActualValue, ProblemDataParameter.ActualValue.TrainingIndices);
+      return model.CreateClassificationSolution((IClassificationProblemData)ProblemDataParameter.ActualValue.Clone());
     }
   }
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/Plugin.cs.frame
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/Plugin.cs.frame	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/Plugin.cs.frame	(revision 8915)
@@ -28,7 +28,8 @@
   [Plugin("HeuristicLab.Problems.DataAnalysis.Symbolic.Classification","Provides classes to perform symbolic classification (single- or multiobjective).", "3.4.3.$WCREV$")]
   [PluginFile("HeuristicLab.Problems.DataAnalysis.Symbolic.Classification-3.4.dll", PluginFileType.Assembly)]
-  [PluginDependency("HeuristicLab.ALGLIB", "3.5")]
+  [PluginDependency("HeuristicLab.ALGLIB", "3.6.0")]
   [PluginDependency("HeuristicLab.Analysis", "3.3")]
   [PluginDependency("HeuristicLab.Common", "3.3")]
+  [PluginDependency("HeuristicLab.Common.Resources", "3.3")]
   [PluginDependency("HeuristicLab.Collections", "3.3")]
   [PluginDependency("HeuristicLab.Core", "3.3")]
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationSingleObjectiveBoundedMeanSquaredErrorEvaluator.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationSingleObjectiveBoundedMeanSquaredErrorEvaluator.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationSingleObjectiveBoundedMeanSquaredErrorEvaluator.cs	(revision 8915)
@@ -47,41 +47,29 @@
       IEnumerable<int> rows = GenerateRowsToEvaluate();
       var solution = SymbolicExpressionTreeParameter.ActualValue;
-      double quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows);
+      double quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows, ApplyLinearScalingParameter.ActualValue.Value);
       QualityParameter.ActualValue = new DoubleValue(quality);
       return base.Apply();
     }
 
-    public static double Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IClassificationProblemData problemData, IEnumerable<int> rows) {
+    public static double Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IClassificationProblemData problemData, IEnumerable<int> rows, bool applyLinearScaling) {
       IEnumerable<double> estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, rows);
-      IEnumerable<double> originalValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
-      IEnumerable<double> boundedEstimationValues = estimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit);
+      IEnumerable<double> targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
+      OnlineCalculatorError errorState;
 
-      double minClassValue = problemData.ClassValues.OrderBy(x => x).First();
-      double maxClassValue = problemData.ClassValues.OrderBy(x => x).Last();
+      double lowestClassValue = problemData.ClassValues.OrderBy(x => x).First();
+      double upmostClassValue = problemData.ClassValues.OrderByDescending(x => x).First();
 
-      IEnumerator<double> originalEnumerator = originalValues.GetEnumerator();
-      IEnumerator<double> estimatedEnumerator = estimatedValues.GetEnumerator();
-      double errorSum = 0.0;
-      int n = 0;
-
-      // always move forward both enumerators (do not use short-circuit evaluation!)
-      while (originalEnumerator.MoveNext() & estimatedEnumerator.MoveNext()) {
-        double estimated = estimatedEnumerator.Current;
-        double original = originalEnumerator.Current;
-        double error = estimated - original;
-
-        if (estimated < minClassValue || estimated > maxClassValue)
-          errorSum += Math.Abs(error);
-        else
-          errorSum += Math.Pow(error, 2);
-        n++;
+      double boundedMse;
+      if (applyLinearScaling) {
+        var boundedMseCalculator = new OnlineBoundedMeanSquaredErrorCalculator(lowestClassValue, upmostClassValue);
+        CalculateWithScaling(targetValues, estimatedValues, lowerEstimationLimit, upperEstimationLimit, boundedMseCalculator, problemData.Dataset.Rows);
+        errorState = boundedMseCalculator.ErrorState;
+        boundedMse = boundedMseCalculator.BoundedMeanSquaredError;
+      } else {
+        IEnumerable<double> boundedEstimatedValues = estimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit);
+        boundedMse = OnlineBoundedMeanSquaredErrorCalculator.Calculate(targetValues, boundedEstimatedValues, lowestClassValue, upmostClassValue, out errorState);
       }
-
-      // check if both enumerators are at the end to make sure both enumerations have the same length
-      if (estimatedEnumerator.MoveNext() || originalEnumerator.MoveNext()) {
-        throw new ArgumentException("Number of elements in first and second enumeration doesn't match.");
-      } else {
-        return errorSum / n;
-      }
+      if (errorState != OnlineCalculatorError.None) return Double.NaN;
+      return boundedMse;
     }
 
@@ -89,9 +77,11 @@
       SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = context;
       EstimationLimitsParameter.ExecutionContext = context;
+      ApplyLinearScalingParameter.ExecutionContext = context;
 
-      double mse = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows);
+      double mse = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, ApplyLinearScalingParameter.ActualValue.Value);
 
       SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
       EstimationLimitsParameter.ExecutionContext = null;
+      ApplyLinearScalingParameter.ExecutionContext = null;
 
       return mse;
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationSingleObjectiveMeanSquaredErrorEvaluator.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationSingleObjectiveMeanSquaredErrorEvaluator.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationSingleObjectiveMeanSquaredErrorEvaluator.cs	(revision 8915)
@@ -20,4 +20,5 @@
 #endregion
 
+using System;
 using System.Collections.Generic;
 using HeuristicLab.Common;
@@ -47,17 +48,26 @@
       IEnumerable<int> rows = GenerateRowsToEvaluate();
       var solution = SymbolicExpressionTreeParameter.ActualValue;
-      double quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows);
+      double quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows, ApplyLinearScalingParameter.ActualValue.Value);
       QualityParameter.ActualValue = new DoubleValue(quality);
       return base.Apply();
     }
 
-    public static double Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IClassificationProblemData problemData, IEnumerable<int> rows) {
+    public static double Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IClassificationProblemData problemData, IEnumerable<int> rows, bool applyLinearScaling) {
       IEnumerable<double> estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, rows);
-      IEnumerable<double> originalValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
-      IEnumerable<double> boundedEstimationValues = estimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit);
+      IEnumerable<double> targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
       OnlineCalculatorError errorState;
-      double mse = OnlineMeanSquaredErrorCalculator.Calculate(originalValues, boundedEstimationValues, out errorState);
-      if (errorState != OnlineCalculatorError.None) return double.NaN;
-      else return mse;
+
+      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) return Double.NaN;
+      return mse;
     }
 
@@ -65,9 +75,11 @@
       SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = context;
       EstimationLimitsParameter.ExecutionContext = context;
+      ApplyLinearScalingParameter.ExecutionContext = context;
 
-      double mse = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows);
+      double mse = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, ApplyLinearScalingParameter.ActualValue.Value);
 
       SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
       EstimationLimitsParameter.ExecutionContext = null;
+      ApplyLinearScalingParameter.ExecutionContext = null;
 
       return mse;
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationSingleObjectivePearsonRSquaredEvaluator.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationSingleObjectivePearsonRSquaredEvaluator.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationSingleObjectivePearsonRSquaredEvaluator.cs	(revision 8915)
@@ -47,16 +47,26 @@
       IEnumerable<int> rows = GenerateRowsToEvaluate();
       var solution = SymbolicExpressionTreeParameter.ActualValue;
-      double quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows);
+      double quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows, ApplyLinearScalingParameter.ActualValue.Value);
       QualityParameter.ActualValue = new DoubleValue(quality);
       return base.Apply();
     }
 
-    public static double Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IClassificationProblemData problemData, IEnumerable<int> rows) {
+    public static double Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IClassificationProblemData problemData, IEnumerable<int> rows, bool applyLinearScaling) {
       IEnumerable<double> estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, rows);
-      IEnumerable<double> originalValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
+      IEnumerable<double> targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
       OnlineCalculatorError errorState;
-      double r2 = OnlinePearsonsRSquaredCalculator.Calculate(estimatedValues, originalValues, out errorState);
-      if (errorState != OnlineCalculatorError.None) return 0.0;
-      else return r2;
+
+      double r2;
+      if (applyLinearScaling) {
+        var r2Calculator = new OnlinePearsonsRSquaredCalculator();
+        CalculateWithScaling(targetValues, estimatedValues, lowerEstimationLimit, upperEstimationLimit, r2Calculator, problemData.Dataset.Rows);
+        errorState = r2Calculator.ErrorState;
+        r2 = r2Calculator.RSquared;
+      } else {
+        IEnumerable<double> boundedEstimatedValues = estimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit);
+        r2 = OnlinePearsonsRSquaredCalculator.Calculate(targetValues, boundedEstimatedValues, out errorState);
+      }
+      if (errorState != OnlineCalculatorError.None) return double.NaN;
+      return r2;
     }
 
@@ -64,9 +74,11 @@
       SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = context;
       EstimationLimitsParameter.ExecutionContext = context;
+      ApplyLinearScalingParameter.ExecutionContext = context;
 
-      double r2 = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows);
+      double r2 = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, ApplyLinearScalingParameter.ActualValue.Value);
 
       SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
       EstimationLimitsParameter.ExecutionContext = null;
+      ApplyLinearScalingParameter.ExecutionContext = null;
 
       return r2;
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationSingleObjectivePenaltyScoreEvaluator.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationSingleObjectivePenaltyScoreEvaluator.cs	(revision 8915)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationSingleObjectivePenaltyScoreEvaluator.cs	(revision 8915)
@@ -0,0 +1,106 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Classification {
+  [Item("Penalty Score Evaluator", "Calculates the penalty score of a symbolic classification solution.")]
+  [StorableClass]
+  public class SymbolicClassificationSingleObjectivePenaltyScoreEvaluator : SymbolicClassificationSingleObjectiveEvaluator, ISymbolicClassificationModelCreatorOperator {
+    private const string ModelCreatorParameterName = "ModelCreator";
+    public override bool Maximization { get { return false; } }
+
+    public IValueLookupParameter<ISymbolicClassificationModelCreator> ModelCreatorParameter {
+      get { return (IValueLookupParameter<ISymbolicClassificationModelCreator>)Parameters[ModelCreatorParameterName]; }
+    }
+    ILookupParameter<ISymbolicClassificationModelCreator> ISymbolicClassificationModelCreatorOperator.ModelCreatorParameter {
+      get { return ModelCreatorParameter; }
+    }
+
+    [StorableConstructor]
+    protected SymbolicClassificationSingleObjectivePenaltyScoreEvaluator(bool deserializing) : base(deserializing) { }
+    protected SymbolicClassificationSingleObjectivePenaltyScoreEvaluator(SymbolicClassificationSingleObjectivePenaltyScoreEvaluator original, Cloner cloner) : base(original, cloner) { }
+    public SymbolicClassificationSingleObjectivePenaltyScoreEvaluator()
+      : base() {
+      Parameters.Add(new ValueLookupParameter<ISymbolicClassificationModelCreator>(ModelCreatorParameterName, ""));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SymbolicClassificationSingleObjectivePenaltyScoreEvaluator(this, cloner);
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      // BackwardsCompatibility3.4
+      #region Backwards compatible code, remove with 3.5
+      if (!Parameters.ContainsKey(ModelCreatorParameterName))
+        Parameters.Add(new ValueLookupParameter<ISymbolicClassificationModelCreator>(ModelCreatorParameterName, ""));
+      #endregion
+    }
+
+
+    public override IOperation Apply() {
+      double quality = Evaluate(ExecutionContext, SymbolicExpressionTreeParameter.ActualValue, ProblemDataParameter.ActualValue, GenerateRowsToEvaluate());
+      QualityParameter.ActualValue = new DoubleValue(quality);
+      return base.Apply();
+    }
+
+    public static double Calculate(IClassificationModel model, IClassificationProblemData problemData, IEnumerable<int> rows) {
+      var estimations = model.GetEstimatedClassValues(problemData.Dataset, rows).GetEnumerator();
+      if (!estimations.MoveNext()) return double.NaN;
+
+      var penalty = 0.0;
+      var count = 0;
+      foreach (var r in rows) {
+        var actualClass = problemData.Dataset.GetDoubleValue(problemData.TargetVariable, r);
+        penalty += problemData.GetClassificationPenalty(actualClass, estimations.Current);
+        estimations.MoveNext();
+        count++;
+      }
+      return penalty / count;
+    }
+
+    public override double Evaluate(IExecutionContext context, ISymbolicExpressionTree tree, IClassificationProblemData problemData, IEnumerable<int> rows) {
+      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = context;
+      EstimationLimitsParameter.ExecutionContext = context;
+      ModelCreatorParameter.ExecutionContext = context;
+      ApplyLinearScalingParameter.ExecutionContext = context;
+
+      var model = ModelCreatorParameter.ActualValue.CreateSymbolicClassificationModel(tree, SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
+      if (ApplyLinearScalingParameter.ActualValue.Value) SymbolicClassificationModel.Scale(model, problemData, problemData.TargetVariable);
+      model.RecalculateModelParameters(problemData, rows);
+      double penalty = Calculate(model, problemData, rows);
+
+      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
+      EstimationLimitsParameter.ExecutionContext = null;
+      ModelCreatorParameter.ExecutionContext = null;
+      ApplyLinearScalingParameter.ExecutionContext = null;
+
+      return penalty;
+    }
+  }
+}
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationSingleObjectiveProblem.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationSingleObjectiveProblem.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationSingleObjectiveProblem.cs	(revision 8915)
@@ -35,4 +35,5 @@
     private const string EstimationLimitsParameterName = "EstimationLimits";
     private const string EstimationLimitsParameterDescription = "The lower and upper limit for the estimated value that can be returned by the symbolic classification model.";
+    private const string ModelCreatorParameterName = "ModelCreator";
 
     #region parameter properties
@@ -40,8 +41,14 @@
       get { return (IFixedValueParameter<DoubleLimit>)Parameters[EstimationLimitsParameterName]; }
     }
+    public IValueParameter<ISymbolicClassificationModelCreator> ModelCreatorParameter {
+      get { return (IValueParameter<ISymbolicClassificationModelCreator>)Parameters[ModelCreatorParameterName]; }
+    }
     #endregion
     #region properties
     public DoubleLimit EstimationLimits {
       get { return EstimationLimitsParameter.Value; }
+    }
+    public ISymbolicClassificationModelCreator ModelCreator {
+      get { return ModelCreatorParameter.Value; }
     }
     #endregion
@@ -57,5 +64,7 @@
       : base(new ClassificationProblemData(), new SymbolicClassificationSingleObjectiveMeanSquaredErrorEvaluator(), new SymbolicDataAnalysisExpressionTreeCreator()) {
       Parameters.Add(new FixedValueParameter<DoubleLimit>(EstimationLimitsParameterName, EstimationLimitsParameterDescription));
+      Parameters.Add(new ValueParameter<ISymbolicClassificationModelCreator>(ModelCreatorParameterName, "", new AccuracyMaximizingThresholdsModelCreator()));
 
+      ApplyLinearScalingParameter.Value.Value = false;
       EstimationLimitsParameter.Hidden = true;
 
@@ -71,6 +80,9 @@
     [StorableHook(HookType.AfterDeserialization)]
     private void AfterDeserialization() {
-      RegisterEventHandlers();
-      // compatibility
+      // BackwardsCompatibility3.4
+      #region Backwards compatible code, remove with 3.5
+      if (!Parameters.ContainsKey(ModelCreatorParameterName))
+        Parameters.Add(new ValueParameter<ISymbolicClassificationModelCreator>(ModelCreatorParameterName, "", new AccuracyMaximizingThresholdsModelCreator()));
+
       bool changed = false;
       if (!Operators.OfType<SymbolicClassificationSingleObjectiveTrainingParetoBestSolutionAnalyzer>().Any()) {
@@ -83,8 +95,11 @@
       }
       if (changed) ParameterizeOperators();
+      #endregion
+      RegisterEventHandlers();
     }
 
     private void RegisterEventHandlers() {
       SymbolicExpressionTreeGrammarParameter.ValueChanged += (o, e) => ConfigureGrammarSymbols();
+      ModelCreatorParameter.NameChanged += (o, e) => ParameterizeOperators();
     }
 
@@ -125,7 +140,8 @@
       if (Parameters.ContainsKey(EstimationLimitsParameterName)) {
         var operators = Parameters.OfType<IValueParameter>().Select(p => p.Value).OfType<IOperator>().Union(Operators);
-        foreach (var op in operators.OfType<ISymbolicDataAnalysisBoundedOperator>()) {
+        foreach (var op in operators.OfType<ISymbolicDataAnalysisBoundedOperator>())
           op.EstimationLimitsParameter.ActualName = EstimationLimitsParameter.Name;
-        }
+        foreach (var op in operators.OfType<ISymbolicClassificationModelCreatorOperator>())
+          op.ModelCreatorParameter.ActualName = ModelCreatorParameter.Name;
       }
     }
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationSingleObjectiveTrainingBestSolutionAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationSingleObjectiveTrainingBestSolutionAnalyzer.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationSingleObjectiveTrainingBestSolutionAnalyzer.cs	(revision 8915)
@@ -22,5 +22,4 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Data;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 using HeuristicLab.Parameters;
@@ -34,12 +33,18 @@
   [StorableClass]
   public sealed class SymbolicClassificationSingleObjectiveTrainingBestSolutionAnalyzer : SymbolicDataAnalysisSingleObjectiveTrainingBestSolutionAnalyzer<ISymbolicClassificationSolution>,
-    ISymbolicDataAnalysisInterpreterOperator, ISymbolicDataAnalysisBoundedOperator {
+    ISymbolicDataAnalysisInterpreterOperator, ISymbolicDataAnalysisBoundedOperator, ISymbolicClassificationModelCreatorOperator {
     private const string ProblemDataParameterName = "ProblemData";
+    private const string ModelCreatorParameterName = "ModelCreator";
     private const string SymbolicDataAnalysisTreeInterpreterParameterName = "SymbolicDataAnalysisTreeInterpreter";
     private const string EstimationLimitsParameterName = "UpperEstimationLimit";
-    private const string ApplyLinearScalingParameterName = "ApplyLinearScaling";
     #region parameter properties
     public ILookupParameter<IClassificationProblemData> ProblemDataParameter {
       get { return (ILookupParameter<IClassificationProblemData>)Parameters[ProblemDataParameterName]; }
+    }
+    public IValueLookupParameter<ISymbolicClassificationModelCreator> ModelCreatorParameter {
+      get { return (IValueLookupParameter<ISymbolicClassificationModelCreator>)Parameters[ModelCreatorParameterName]; }
+    }
+    ILookupParameter<ISymbolicClassificationModelCreator> ISymbolicClassificationModelCreatorOperator.ModelCreatorParameter {
+      get { return ModelCreatorParameter; }
     }
     public ILookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter> SymbolicDataAnalysisTreeInterpreterParameter {
@@ -49,13 +54,6 @@
       get { return (IValueLookupParameter<DoubleLimit>)Parameters[EstimationLimitsParameterName]; }
     }
-    public IValueParameter<BoolValue> ApplyLinearScalingParameter {
-      get { return (IValueParameter<BoolValue>)Parameters[ApplyLinearScalingParameterName]; }
-    }
     #endregion
-    #region properties
-    public BoolValue ApplyLinearScaling {
-      get { return ApplyLinearScalingParameter.Value; }
-    }
-    #endregion
+
 
     [StorableConstructor]
@@ -65,18 +63,27 @@
       : base() {
       Parameters.Add(new LookupParameter<IClassificationProblemData>(ProblemDataParameterName, "The problem data for the symbolic classification solution."));
+      Parameters.Add(new ValueLookupParameter<ISymbolicClassificationModelCreator>(ModelCreatorParameterName, ""));
       Parameters.Add(new LookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>(SymbolicDataAnalysisTreeInterpreterParameterName, "The symbolic data analysis tree interpreter for the symbolic expression tree."));
       Parameters.Add(new ValueLookupParameter<DoubleLimit>(EstimationLimitsParameterName, "The lower and upper limit for the estimated values produced by the symbolic classification model."));
-      Parameters.Add(new ValueParameter<BoolValue>(ApplyLinearScalingParameterName, "Flag that indicates if the produced symbolic classification solution should be linearly scaled.", new BoolValue(false)));
     }
+
     public override IDeepCloneable Clone(Cloner cloner) {
       return new SymbolicClassificationSingleObjectiveTrainingBestSolutionAnalyzer(this, cloner);
     }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      // BackwardsCompatibility3.4
+      #region Backwards compatible code, remove with 3.5
+      if (!Parameters.ContainsKey(ModelCreatorParameterName))
+        Parameters.Add(new ValueLookupParameter<ISymbolicClassificationModelCreator>(ModelCreatorParameterName, ""));
+      #endregion
+    }
 
     protected override ISymbolicClassificationSolution CreateSolution(ISymbolicExpressionTree bestTree, double bestQuality) {
-      var model = new SymbolicDiscriminantFunctionClassificationModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
-      if (ApplyLinearScaling.Value) {
-        SymbolicDiscriminantFunctionClassificationModel.Scale(model, ProblemDataParameter.ActualValue);
-      }
-      return new SymbolicDiscriminantFunctionClassificationSolution(model, (IClassificationProblemData)ProblemDataParameter.ActualValue.Clone());
+      var model = ModelCreatorParameter.ActualValue.CreateSymbolicClassificationModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
+      if (ApplyLinearScalingParameter.ActualValue.Value) SymbolicClassificationModel.Scale(model, ProblemDataParameter.ActualValue, ProblemDataParameter.ActualValue.TargetVariable);
+
+      model.RecalculateModelParameters(ProblemDataParameter.ActualValue, ProblemDataParameter.ActualValue.TrainingIndices);
+      return model.CreateClassificationSolution((IClassificationProblemData)ProblemDataParameter.ActualValue.Clone());
     }
   }
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationSingleObjectiveTrainingParetoBestSolutionAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationSingleObjectiveTrainingParetoBestSolutionAnalyzer.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationSingleObjectiveTrainingParetoBestSolutionAnalyzer.cs	(revision 8915)
@@ -22,5 +22,4 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Data;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 using HeuristicLab.Parameters;
@@ -33,15 +32,12 @@
   [Item("SymbolicClassificationSingleObjectiveTrainingParetoBestSolutionAnalyzer", "An operator that collects the training Pareto-best symbolic classification solutions for single objective symbolic classification problems.")]
   [StorableClass]
-  public sealed class SymbolicClassificationSingleObjectiveTrainingParetoBestSolutionAnalyzer : SymbolicDataAnalysisSingleObjectiveTrainingParetoBestSolutionAnalyzer<IClassificationProblemData, ISymbolicClassificationSolution> {
-    private const string ApplyLinearScalingParameterName = "ApplyLinearScaling";
+  public sealed class SymbolicClassificationSingleObjectiveTrainingParetoBestSolutionAnalyzer : SymbolicDataAnalysisSingleObjectiveTrainingParetoBestSolutionAnalyzer<IClassificationProblemData, ISymbolicClassificationSolution>, ISymbolicClassificationModelCreatorOperator {
+    private const string ModelCreatorParameterName = "ModelCreator";
     #region parameter properties
-    public IValueParameter<BoolValue> ApplyLinearScalingParameter {
-      get { return (IValueParameter<BoolValue>)Parameters[ApplyLinearScalingParameterName]; }
+    public IValueLookupParameter<ISymbolicClassificationModelCreator> ModelCreatorParameter {
+      get { return (IValueLookupParameter<ISymbolicClassificationModelCreator>)Parameters[ModelCreatorParameterName]; }
     }
-    #endregion
-
-    #region properties
-    public BoolValue ApplyLinearScaling {
-      get { return ApplyLinearScalingParameter.Value; }
+    ILookupParameter<ISymbolicClassificationModelCreator> ISymbolicClassificationModelCreatorOperator.ModelCreatorParameter {
+      get { return ModelCreatorParameter; }
     }
     #endregion
@@ -52,5 +48,5 @@
     public SymbolicClassificationSingleObjectiveTrainingParetoBestSolutionAnalyzer()
       : base() {
-      Parameters.Add(new ValueParameter<BoolValue>(ApplyLinearScalingParameterName, "Flag that indicates if the produced symbolic classification solution should be linearly scaled.", new BoolValue(false)));
+      Parameters.Add(new ValueLookupParameter<ISymbolicClassificationModelCreator>(ModelCreatorParameterName, ""));
     }
     public override IDeepCloneable Clone(Cloner cloner) {
@@ -58,9 +54,19 @@
     }
 
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      // BackwardsCompatibility3.4
+      #region Backwards compatible code, remove with 3.5
+      if (!Parameters.ContainsKey(ModelCreatorParameterName))
+        Parameters.Add(new ValueLookupParameter<ISymbolicClassificationModelCreator>(ModelCreatorParameterName, ""));
+      #endregion
+    }
+
     protected override ISymbolicClassificationSolution CreateSolution(ISymbolicExpressionTree bestTree) {
-      var model = new SymbolicDiscriminantFunctionClassificationModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
-      if (ApplyLinearScaling.Value)
-        SymbolicDiscriminantFunctionClassificationModel.Scale(model, ProblemDataParameter.ActualValue);
-      return new SymbolicDiscriminantFunctionClassificationSolution(model, (IClassificationProblemData)ProblemDataParameter.ActualValue.Clone());
+      var model = ModelCreatorParameter.ActualValue.CreateSymbolicClassificationModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
+      if (ApplyLinearScalingParameter.ActualValue.Value) SymbolicClassificationModel.Scale(model, ProblemDataParameter.ActualValue, ProblemDataParameter.ActualValue.TargetVariable);
+
+      model.RecalculateModelParameters(ProblemDataParameter.ActualValue, ProblemDataParameter.ActualValue.TrainingIndices);
+      return model.CreateClassificationSolution((IClassificationProblemData)ProblemDataParameter.ActualValue.Clone());
     }
   }
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationSingleObjectiveValidationBestSolutionAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationSingleObjectiveValidationBestSolutionAnalyzer.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationSingleObjectiveValidationBestSolutionAnalyzer.cs	(revision 8915)
@@ -22,5 +22,4 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Data;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 using HeuristicLab.Parameters;
@@ -34,7 +33,7 @@
   [StorableClass]
   public sealed class SymbolicClassificationSingleObjectiveValidationBestSolutionAnalyzer : SymbolicDataAnalysisSingleObjectiveValidationBestSolutionAnalyzer<ISymbolicClassificationSolution, ISymbolicClassificationSingleObjectiveEvaluator, IClassificationProblemData>,
-  ISymbolicDataAnalysisBoundedOperator {
+  ISymbolicDataAnalysisBoundedOperator, ISymbolicClassificationModelCreatorOperator {
     private const string EstimationLimitsParameterName = "EstimationLimits";
-    private const string ApplyLinearScalingParameterName = "ApplyLinearScaling";
+    private const string ModelCreatorParameterName = "ModelCreator";
 
     #region parameter properties
@@ -42,14 +41,12 @@
       get { return (IValueLookupParameter<DoubleLimit>)Parameters[EstimationLimitsParameterName]; }
     }
-    public IValueParameter<BoolValue> ApplyLinearScalingParameter {
-      get { return (IValueParameter<BoolValue>)Parameters[ApplyLinearScalingParameterName]; }
+    public IValueLookupParameter<ISymbolicClassificationModelCreator> ModelCreatorParameter {
+      get { return (IValueLookupParameter<ISymbolicClassificationModelCreator>)Parameters[ModelCreatorParameterName]; }
+    }
+    ILookupParameter<ISymbolicClassificationModelCreator> ISymbolicClassificationModelCreatorOperator.ModelCreatorParameter {
+      get { return ModelCreatorParameter; }
     }
     #endregion
 
-    #region properties
-    public BoolValue ApplyLinearScaling {
-      get { return ApplyLinearScalingParameter.Value; }
-    }
-    #endregion
     [StorableConstructor]
     private SymbolicClassificationSingleObjectiveValidationBestSolutionAnalyzer(bool deserializing) : base(deserializing) { }
@@ -58,5 +55,5 @@
       : base() {
       Parameters.Add(new ValueLookupParameter<DoubleLimit>(EstimationLimitsParameterName, "The lower and upper limit for the estimated values produced by the symbolic classification model."));
-      Parameters.Add(new ValueParameter<BoolValue>(ApplyLinearScalingParameterName, "Flag that indicates if the produced symbolic classification solution should be linearly scaled.", new BoolValue(false)));
+      Parameters.Add(new ValueLookupParameter<ISymbolicClassificationModelCreator>(ModelCreatorParameterName, ""));
     }
     public override IDeepCloneable Clone(Cloner cloner) {
@@ -64,10 +61,19 @@
     }
 
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      // BackwardsCompatibility3.4
+      #region Backwards compatible code, remove with 3.5
+      if (!Parameters.ContainsKey(ModelCreatorParameterName))
+        Parameters.Add(new ValueLookupParameter<ISymbolicClassificationModelCreator>(ModelCreatorParameterName, ""));
+      #endregion
+    }
+
     protected override ISymbolicClassificationSolution CreateSolution(ISymbolicExpressionTree bestTree, double bestQuality) {
-      var model = new SymbolicDiscriminantFunctionClassificationModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
-      if (ApplyLinearScaling.Value) {
-        SymbolicDiscriminantFunctionClassificationModel.Scale(model, ProblemDataParameter.ActualValue);
-      }
-      return new SymbolicDiscriminantFunctionClassificationSolution(model, (IClassificationProblemData)ProblemDataParameter.ActualValue.Clone());
+      var model = ModelCreatorParameter.ActualValue.CreateSymbolicClassificationModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
+      if (ApplyLinearScalingParameter.ActualValue.Value) SymbolicClassificationModel.Scale(model, ProblemDataParameter.ActualValue, ProblemDataParameter.ActualValue.TargetVariable);
+
+      model.RecalculateModelParameters(ProblemDataParameter.ActualValue, ProblemDataParameter.ActualValue.TrainingIndices);
+      return model.CreateClassificationSolution((IClassificationProblemData)ProblemDataParameter.ActualValue.Clone());
     }
   }
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationSingleObjectiveValidationParetoBestSolutionAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationSingleObjectiveValidationParetoBestSolutionAnalyzer.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SingleObjective/SymbolicClassificationSingleObjectiveValidationParetoBestSolutionAnalyzer.cs	(revision 8915)
@@ -22,5 +22,4 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Data;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 using HeuristicLab.Parameters;
@@ -33,15 +32,12 @@
   [Item("SymbolicClassificationSingleObjectiveValidationParetoBestSolutionAnalyzer", "An operator that collects the validation Pareto-best symbolic classification solutions for single objective symbolic classification problems.")]
   [StorableClass]
-  public sealed class SymbolicClassificationSingleObjectiveValidationParetoBestSolutionAnalyzer : SymbolicDataAnalysisSingleObjectiveValidationParetoBestSolutionAnalyzer<ISymbolicClassificationSolution, ISymbolicClassificationSingleObjectiveEvaluator, IClassificationProblemData> {
-    private const string ApplyLinearScalingParameterName = "ApplyLinearScaling";
+  public sealed class SymbolicClassificationSingleObjectiveValidationParetoBestSolutionAnalyzer : SymbolicDataAnalysisSingleObjectiveValidationParetoBestSolutionAnalyzer<ISymbolicClassificationSolution, ISymbolicClassificationSingleObjectiveEvaluator, IClassificationProblemData>, ISymbolicClassificationModelCreatorOperator {
+    private const string ModelCreatorParameterName = "ModelCreator";
     #region parameter properties
-    public IValueParameter<BoolValue> ApplyLinearScalingParameter {
-      get { return (IValueParameter<BoolValue>)Parameters[ApplyLinearScalingParameterName]; }
+    public IValueLookupParameter<ISymbolicClassificationModelCreator> ModelCreatorParameter {
+      get { return (IValueLookupParameter<ISymbolicClassificationModelCreator>)Parameters[ModelCreatorParameterName]; }
     }
-    #endregion
-
-    #region properties
-    public BoolValue ApplyLinearScaling {
-      get { return ApplyLinearScalingParameter.Value; }
+    ILookupParameter<ISymbolicClassificationModelCreator> ISymbolicClassificationModelCreatorOperator.ModelCreatorParameter {
+      get { return ModelCreatorParameter; }
     }
     #endregion
@@ -52,5 +48,5 @@
     public SymbolicClassificationSingleObjectiveValidationParetoBestSolutionAnalyzer()
       : base() {
-      Parameters.Add(new ValueParameter<BoolValue>(ApplyLinearScalingParameterName, "Flag that indicates if the produced symbolic classification solution should be linearly scaled.", new BoolValue(false)));
+      Parameters.Add(new ValueLookupParameter<ISymbolicClassificationModelCreator>(ModelCreatorParameterName, ""));
     }
     public override IDeepCloneable Clone(Cloner cloner) {
@@ -58,9 +54,19 @@
     }
 
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      // BackwardsCompatibility3.4
+      #region Backwards compatible code, remove with 3.5
+      if (!Parameters.ContainsKey(ModelCreatorParameterName))
+        Parameters.Add(new ValueLookupParameter<ISymbolicClassificationModelCreator>(ModelCreatorParameterName, ""));
+      #endregion
+    }
+
     protected override ISymbolicClassificationSolution CreateSolution(ISymbolicExpressionTree bestTree) {
-      var model = new SymbolicDiscriminantFunctionClassificationModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
-      if (ApplyLinearScaling.Value)
-        SymbolicDiscriminantFunctionClassificationModel.Scale(model, ProblemDataParameter.ActualValue);
-      return new SymbolicDiscriminantFunctionClassificationSolution(model, (IClassificationProblemData)ProblemDataParameter.ActualValue.Clone());
+      var model = ModelCreatorParameter.ActualValue.CreateSymbolicClassificationModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
+      if (ApplyLinearScalingParameter.ActualValue.Value) SymbolicClassificationModel.Scale(model, ProblemDataParameter.ActualValue, ProblemDataParameter.ActualValue.TargetVariable);
+
+      model.RecalculateModelParameters(ProblemDataParameter.ActualValue, ProblemDataParameter.ActualValue.TrainingIndices);
+      return model.CreateClassificationSolution((IClassificationProblemData)ProblemDataParameter.ActualValue.Clone());
     }
   }
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SymbolicClassificationModel.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SymbolicClassificationModel.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SymbolicClassificationModel.cs	(revision 8915)
@@ -32,30 +32,34 @@
   [StorableClass]
   [Item(Name = "SymbolicClassificationModel", Description = "Represents a symbolic classification model.")]
-  public class SymbolicClassificationModel : SymbolicDataAnalysisModel, ISymbolicClassificationModel {
+  public abstract class
+    SymbolicClassificationModel : SymbolicDataAnalysisModel, ISymbolicClassificationModel {
+    [Storable]
+    private double lowerEstimationLimit;
+    public double LowerEstimationLimit { get { return lowerEstimationLimit; } }
+    [Storable]
+    private double upperEstimationLimit;
+    public double UpperEstimationLimit { get { return upperEstimationLimit; } }
+
     [StorableConstructor]
     protected SymbolicClassificationModel(bool deserializing) : base(deserializing) { }
     protected SymbolicClassificationModel(SymbolicClassificationModel original, Cloner cloner)
       : base(original, cloner) {
+      lowerEstimationLimit = original.lowerEstimationLimit;
+      upperEstimationLimit = original.upperEstimationLimit;
     }
-    public SymbolicClassificationModel(ISymbolicExpressionTree tree, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter)
+    protected SymbolicClassificationModel(ISymbolicExpressionTree tree, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, double lowerEstimationLimit = double.MinValue, double upperEstimationLimit = double.MaxValue)
       : base(tree, interpreter) {
+      this.lowerEstimationLimit = lowerEstimationLimit;
+      this.upperEstimationLimit = upperEstimationLimit;
     }
 
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new SymbolicClassificationModel(this, cloner);
-    }
+    public abstract IEnumerable<double> GetEstimatedClassValues(Dataset dataset, IEnumerable<int> rows);
+    public abstract void RecalculateModelParameters(IClassificationProblemData problemData, IEnumerable<int> rows);
 
-    public IEnumerable<double> GetEstimatedClassValues(Dataset dataset, IEnumerable<int> rows) {
-      return Interpreter.GetSymbolicExpressionTreeValues(SymbolicExpressionTree, dataset, rows);
-    }
+    public abstract ISymbolicClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData);
 
-    public ISymbolicClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData) {
-      return new SymbolicClassificationSolution(this, problemData);
-    }
     IClassificationSolution IClassificationModel.CreateClassificationSolution(IClassificationProblemData problemData) {
       return CreateClassificationSolution(problemData);
     }
-
-
   }
 }
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SymbolicClassificationSolution.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SymbolicClassificationSolution.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SymbolicClassificationSolution.cs	(revision 8915)
@@ -71,7 +71,7 @@
 
     protected override void RecalculateResults() {
+      base.RecalculateResults();
       ModelLength = Model.SymbolicExpressionTree.Length;
       ModelDepth = Model.SymbolicExpressionTree.Depth;
-      CalculateResults();
     }
   }
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SymbolicDiscriminantFunctionClassificationModel.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SymbolicDiscriminantFunctionClassificationModel.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SymbolicDiscriminantFunctionClassificationModel.cs	(revision 8915)
@@ -34,5 +34,5 @@
   [StorableClass]
   [Item(Name = "SymbolicDiscriminantFunctionClassificationModel", Description = "Represents a symbolic classification model unsing a discriminant function.")]
-  public class SymbolicDiscriminantFunctionClassificationModel : SymbolicDataAnalysisModel, ISymbolicDiscriminantFunctionClassificationModel {
+  public class SymbolicDiscriminantFunctionClassificationModel : SymbolicClassificationModel, ISymbolicDiscriminantFunctionClassificationModel {
 
     [Storable]
@@ -48,10 +48,12 @@
       private set { classValues = value.ToArray(); }
     }
+
+    private IDiscriminantFunctionThresholdCalculator thresholdCalculator;
     [Storable]
-    private double lowerEstimationLimit;
-    public double LowerEstimationLimit { get { return lowerEstimationLimit; } }
-    [Storable]
-    private double upperEstimationLimit;
-    public double UpperEstimationLimit { get { return upperEstimationLimit; } }
+    public IDiscriminantFunctionThresholdCalculator ThresholdCalculator {
+      get { return thresholdCalculator; }
+      private set { thresholdCalculator = value; }
+    }
+
 
     [StorableConstructor]
@@ -61,14 +63,20 @@
       classValues = (double[])original.classValues.Clone();
       thresholds = (double[])original.thresholds.Clone();
-      lowerEstimationLimit = original.lowerEstimationLimit;
-      upperEstimationLimit = original.upperEstimationLimit;
+      thresholdCalculator = cloner.Clone(original.thresholdCalculator);
     }
-    public SymbolicDiscriminantFunctionClassificationModel(ISymbolicExpressionTree tree, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
+    public SymbolicDiscriminantFunctionClassificationModel(ISymbolicExpressionTree tree, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, IDiscriminantFunctionThresholdCalculator thresholdCalculator,
       double lowerEstimationLimit = double.MinValue, double upperEstimationLimit = double.MaxValue)
-      : base(tree, interpreter) {
-      thresholds = new double[] { double.NegativeInfinity };
-      classValues = new double[] { 0.0 };
-      this.lowerEstimationLimit = lowerEstimationLimit;
-      this.upperEstimationLimit = upperEstimationLimit;
+      : base(tree, interpreter, lowerEstimationLimit, upperEstimationLimit) {
+      this.thresholds = new double[0];
+      this.classValues = new double[0];
+      this.ThresholdCalculator = thresholdCalculator;
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      // BackwardsCompatibility3.4
+      #region Backwards compatible code, remove with 3.5
+      if (ThresholdCalculator == null) ThresholdCalculator = new AccuracyMaximizationThresholdCalculator();
+      #endregion
     }
 
@@ -87,10 +95,19 @@
     }
 
-    public IEnumerable<double> GetEstimatedValues(Dataset dataset, IEnumerable<int> rows) {
-      return Interpreter.GetSymbolicExpressionTreeValues(SymbolicExpressionTree, dataset, rows)
-        .LimitToRange(lowerEstimationLimit, upperEstimationLimit);
+    public override void RecalculateModelParameters(IClassificationProblemData problemData, IEnumerable<int> rows) {
+      double[] classValues;
+      double[] thresholds;
+      var targetClassValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
+      var estimatedTrainingValues = GetEstimatedValues(problemData.Dataset, rows);
+      thresholdCalculator.Calculate(problemData, estimatedTrainingValues, targetClassValues, out classValues, out thresholds);
+      SetThresholdsAndClassValues(thresholds, classValues);
     }
 
-    public IEnumerable<double> GetEstimatedClassValues(Dataset dataset, IEnumerable<int> rows) {
+    public IEnumerable<double> GetEstimatedValues(Dataset dataset, IEnumerable<int> rows) {
+      return Interpreter.GetSymbolicExpressionTreeValues(SymbolicExpressionTree, dataset, rows).LimitToRange(LowerEstimationLimit, UpperEstimationLimit);
+    }
+
+    public override IEnumerable<double> GetEstimatedClassValues(Dataset dataset, IEnumerable<int> rows) {
+      if (!Thresholds.Any() && !ClassValues.Any()) throw new ArgumentException("No thresholds and class values were set for the current symbolic classification model.");
       foreach (var x in GetEstimatedValues(dataset, rows)) {
         int classIndex = 0;
@@ -104,12 +121,16 @@
     }
 
-    public SymbolicDiscriminantFunctionClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData) {
-      return new SymbolicDiscriminantFunctionClassificationSolution(this, problemData);
+
+    public override ISymbolicClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData) {
+      return CreateDiscriminantClassificationSolution(problemData);
+    }
+    public SymbolicDiscriminantFunctionClassificationSolution CreateDiscriminantClassificationSolution(IClassificationProblemData problemData) {
+      return new SymbolicDiscriminantFunctionClassificationSolution(this, new ClassificationProblemData(problemData));
     }
     IClassificationSolution IClassificationModel.CreateClassificationSolution(IClassificationProblemData problemData) {
-      return CreateClassificationSolution(problemData);
+      return CreateDiscriminantClassificationSolution(problemData);
     }
     IDiscriminantFunctionClassificationSolution IDiscriminantFunctionClassificationModel.CreateDiscriminantFunctionClassificationSolution(IClassificationProblemData problemData) {
-      return CreateClassificationSolution(problemData);
+      return CreateDiscriminantClassificationSolution(problemData);
     }
 
@@ -121,75 +142,4 @@
     }
     #endregion
-
-    public static void Scale(SymbolicDiscriminantFunctionClassificationModel model, IClassificationProblemData problemData) {
-      var dataset = problemData.Dataset;
-      var targetVariable = problemData.TargetVariable;
-      var rows = problemData.TrainingIndices;
-      var estimatedValues = model.Interpreter.GetSymbolicExpressionTreeValues(model.SymbolicExpressionTree, dataset, rows);
-      var targetValues = dataset.GetDoubleValues(targetVariable, rows);
-      double alpha;
-      double beta;
-      OnlineCalculatorError errorState;
-      OnlineLinearScalingParameterCalculator.Calculate(estimatedValues, targetValues, out alpha, out beta, out errorState);
-      if (errorState != OnlineCalculatorError.None) return;
-
-      ConstantTreeNode alphaTreeNode = null;
-      ConstantTreeNode betaTreeNode = null;
-      // check if model has been scaled previously by analyzing the structure of the tree
-      var startNode = model.SymbolicExpressionTree.Root.GetSubtree(0);
-      if (startNode.GetSubtree(0).Symbol is Addition) {
-        var addNode = startNode.GetSubtree(0);
-        if (addNode.SubtreeCount == 2 && addNode.GetSubtree(0).Symbol is Multiplication && addNode.GetSubtree(1).Symbol is Constant) {
-          alphaTreeNode = addNode.GetSubtree(1) as ConstantTreeNode;
-          var mulNode = addNode.GetSubtree(0);
-          if (mulNode.SubtreeCount == 2 && mulNode.GetSubtree(1).Symbol is Constant) {
-            betaTreeNode = mulNode.GetSubtree(1) as ConstantTreeNode;
-          }
-        }
-      }
-      // if tree structure matches the structure necessary for linear scaling then reuse the existing tree nodes
-      if (alphaTreeNode != null && betaTreeNode != null) {
-        betaTreeNode.Value *= beta;
-        alphaTreeNode.Value *= beta;
-        alphaTreeNode.Value += alpha;
-      } else {
-        var mainBranch = startNode.GetSubtree(0);
-        startNode.RemoveSubtree(0);
-        var scaledMainBranch = MakeSum(MakeProduct(mainBranch, beta), alpha);
-        startNode.AddSubtree(scaledMainBranch);
-      }
-    }
-
-    private static ISymbolicExpressionTreeNode MakeSum(ISymbolicExpressionTreeNode treeNode, double alpha) {
-      if (alpha.IsAlmost(0.0)) {
-        return treeNode;
-      } else {
-        var addition = new Addition();
-        var node = addition.CreateTreeNode();
-        var alphaConst = MakeConstant(alpha);
-        node.AddSubtree(treeNode);
-        node.AddSubtree(alphaConst);
-        return node;
-      }
-    }
-
-    private static ISymbolicExpressionTreeNode MakeProduct(ISymbolicExpressionTreeNode treeNode, double beta) {
-      if (beta.IsAlmost(1.0)) {
-        return treeNode;
-      } else {
-        var multipliciation = new Multiplication();
-        var node = multipliciation.CreateTreeNode();
-        var betaConst = MakeConstant(beta);
-        node.AddSubtree(treeNode);
-        node.AddSubtree(betaConst);
-        return node;
-      }
-    }
-
-    private static ISymbolicExpressionTreeNode MakeConstant(double c) {
-      var node = (ConstantTreeNode)(new Constant()).CreateTreeNode();
-      node.Value = c;
-      return node;
-    }
   }
 }
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SymbolicDiscriminantFunctionClassificationSolution.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SymbolicDiscriminantFunctionClassificationSolution.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SymbolicDiscriminantFunctionClassificationSolution.cs	(revision 8915)
@@ -20,4 +20,5 @@
 #endregion
 
+using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -35,4 +36,13 @@
     private const string ModelLengthResultName = "Model Length";
     private const string ModelDepthResultName = "Model Depth";
+
+    private const string EstimationLimitsResultsResultName = "Estimation Limits Results";
+    private const string EstimationLimitsResultName = "Estimation Limits";
+    private const string TrainingUpperEstimationLimitHitsResultName = "Training Upper Estimation Limit Hits";
+    private const string TestLowerEstimationLimitHitsResultName = "Test Lower Estimation Limit Hits";
+    private const string TrainingLowerEstimationLimitHitsResultName = "Training Lower Estimation Limit Hits";
+    private const string TestUpperEstimationLimitHitsResultName = "Test Upper Estimation Limit Hits";
+    private const string TrainingNaNEvaluationsResultName = "Training NaN Evaluations";
+    private const string TestNaNEvaluationsResultName = "Test NaN Evaluations";
 
     public new ISymbolicDiscriminantFunctionClassificationModel Model {
@@ -57,4 +67,37 @@
       private set { ((IntValue)this[ModelDepthResultName].Value).Value = value; }
     }
+
+    private ResultCollection EstimationLimitsResultCollection {
+      get { return (ResultCollection)this[EstimationLimitsResultsResultName].Value; }
+    }
+    public DoubleLimit EstimationLimits {
+      get { return (DoubleLimit)EstimationLimitsResultCollection[EstimationLimitsResultName].Value; }
+    }
+
+    public int TrainingUpperEstimationLimitHits {
+      get { return ((IntValue)EstimationLimitsResultCollection[TrainingUpperEstimationLimitHitsResultName].Value).Value; }
+      private set { ((IntValue)EstimationLimitsResultCollection[TrainingUpperEstimationLimitHitsResultName].Value).Value = value; }
+    }
+    public int TestUpperEstimationLimitHits {
+      get { return ((IntValue)EstimationLimitsResultCollection[TestUpperEstimationLimitHitsResultName].Value).Value; }
+      private set { ((IntValue)EstimationLimitsResultCollection[TestUpperEstimationLimitHitsResultName].Value).Value = value; }
+    }
+    public int TrainingLowerEstimationLimitHits {
+      get { return ((IntValue)EstimationLimitsResultCollection[TrainingLowerEstimationLimitHitsResultName].Value).Value; }
+      private set { ((IntValue)EstimationLimitsResultCollection[TrainingLowerEstimationLimitHitsResultName].Value).Value = value; }
+    }
+    public int TestLowerEstimationLimitHits {
+      get { return ((IntValue)EstimationLimitsResultCollection[TestLowerEstimationLimitHitsResultName].Value).Value; }
+      private set { ((IntValue)EstimationLimitsResultCollection[TestLowerEstimationLimitHitsResultName].Value).Value = value; }
+    }
+    public int TrainingNaNEvaluations {
+      get { return ((IntValue)EstimationLimitsResultCollection[TrainingNaNEvaluationsResultName].Value).Value; }
+      private set { ((IntValue)EstimationLimitsResultCollection[TrainingNaNEvaluationsResultName].Value).Value = value; }
+    }
+    public int TestNaNEvaluations {
+      get { return ((IntValue)EstimationLimitsResultCollection[TestNaNEvaluationsResultName].Value).Value; }
+      private set { ((IntValue)EstimationLimitsResultCollection[TestNaNEvaluationsResultName].Value).Value = value; }
+    }
+
     [StorableConstructor]
     private SymbolicDiscriminantFunctionClassificationSolution(bool deserializing) : base(deserializing) { }
@@ -66,5 +109,17 @@
       Add(new Result(ModelLengthResultName, "Length of the symbolic classification model.", new IntValue()));
       Add(new Result(ModelDepthResultName, "Depth of the symbolic classification model.", new IntValue()));
-      RecalculateResults();
+
+
+      ResultCollection estimationLimitResults = new ResultCollection();
+      estimationLimitResults.Add(new Result(EstimationLimitsResultName, "", new DoubleLimit()));
+      estimationLimitResults.Add(new Result(TrainingUpperEstimationLimitHitsResultName, "", new IntValue()));
+      estimationLimitResults.Add(new Result(TestUpperEstimationLimitHitsResultName, "", new IntValue()));
+      estimationLimitResults.Add(new Result(TrainingLowerEstimationLimitHitsResultName, "", new IntValue()));
+      estimationLimitResults.Add(new Result(TestLowerEstimationLimitHitsResultName, "", new IntValue()));
+      estimationLimitResults.Add(new Result(TrainingNaNEvaluationsResultName, "", new IntValue()));
+      estimationLimitResults.Add(new Result(TestNaNEvaluationsResultName, "", new IntValue()));
+      Add(new Result(EstimationLimitsResultsResultName, "Results concerning the estimation limits of symbolic regression solution", estimationLimitResults));
+
+      CalculateResults();
     }
 
@@ -73,9 +128,39 @@
     }
 
-    protected override void RecalculateResults() {
-      CalculateResults();
-      CalculateRegressionResults();
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (!ContainsKey(EstimationLimitsResultsResultName)) {
+        ResultCollection estimationLimitResults = new ResultCollection();
+        estimationLimitResults.Add(new Result(EstimationLimitsResultName, "", new DoubleLimit()));
+        estimationLimitResults.Add(new Result(TrainingUpperEstimationLimitHitsResultName, "", new IntValue()));
+        estimationLimitResults.Add(new Result(TestUpperEstimationLimitHitsResultName, "", new IntValue()));
+        estimationLimitResults.Add(new Result(TrainingLowerEstimationLimitHitsResultName, "", new IntValue()));
+        estimationLimitResults.Add(new Result(TestLowerEstimationLimitHitsResultName, "", new IntValue()));
+        estimationLimitResults.Add(new Result(TrainingNaNEvaluationsResultName, "", new IntValue()));
+        estimationLimitResults.Add(new Result(TestNaNEvaluationsResultName, "", new IntValue()));
+        Add(new Result(EstimationLimitsResultsResultName, "Results concerning the estimation limits of symbolic regression solution", estimationLimitResults));
+        CalculateResults();
+      }
+    }
+
+
+    private void CalculateResults() {
       ModelLength = Model.SymbolicExpressionTree.Length;
       ModelDepth = Model.SymbolicExpressionTree.Depth;
+
+      EstimationLimits.Lower = Model.LowerEstimationLimit;
+      EstimationLimits.Upper = Model.UpperEstimationLimit;
+
+      TrainingUpperEstimationLimitHits = EstimatedTrainingValues.Count(x => x.IsAlmost(Model.UpperEstimationLimit));
+      TestUpperEstimationLimitHits = EstimatedTestValues.Count(x => x.IsAlmost(Model.UpperEstimationLimit));
+      TrainingLowerEstimationLimitHits = EstimatedTrainingValues.Count(x => x.IsAlmost(Model.LowerEstimationLimit));
+      TestLowerEstimationLimitHits = EstimatedTestValues.Count(x => x.IsAlmost(Model.LowerEstimationLimit));
+      TrainingNaNEvaluations = Model.Interpreter.GetSymbolicExpressionTreeValues(Model.SymbolicExpressionTree, ProblemData.Dataset, ProblemData.TrainingIndices).Count(double.IsNaN);
+      TestNaNEvaluations = Model.Interpreter.GetSymbolicExpressionTreeValues(Model.SymbolicExpressionTree, ProblemData.Dataset, ProblemData.TestIndices).Count(double.IsNaN);
+    }
+
+    protected override void RecalculateResults() {
+      base.RecalculateResults();
+      CalculateResults();
     }
   }
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SymbolicNearestNeighbourClassificationModel.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SymbolicNearestNeighbourClassificationModel.cs	(revision 8915)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SymbolicNearestNeighbourClassificationModel.cs	(revision 8915)
@@ -0,0 +1,118 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Classification {
+  /// <summary>
+  /// Represents a nearest neighbour model for regression and classification
+  /// </summary>
+  [StorableClass]
+  [Item("SymbolicNearestNeighbourClassificationModel", "Represents a nearest neighbour model for symbolic classification.")]
+  public sealed class SymbolicNearestNeighbourClassificationModel : SymbolicClassificationModel {
+
+    [Storable]
+    private int k;
+    [Storable]
+    private List<KeyValuePair<double, double>> trainedTargetPair;
+
+    [StorableConstructor]
+    private SymbolicNearestNeighbourClassificationModel(bool deserializing) : base(deserializing) { }
+    private SymbolicNearestNeighbourClassificationModel(SymbolicNearestNeighbourClassificationModel original, Cloner cloner)
+      : base(original, cloner) {
+      k = original.k;
+      trainedTargetPair = new List<KeyValuePair<double, double>>(original.trainedTargetPair);
+    }
+    public SymbolicNearestNeighbourClassificationModel(int k, ISymbolicExpressionTree tree, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, double lowerEstimationLimit = double.MinValue, double upperEstimationLimit = double.MaxValue)
+      : base(tree, interpreter, lowerEstimationLimit, upperEstimationLimit) {
+      this.k = k;
+      this.trainedTargetPair = new List<KeyValuePair<double, double>>();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SymbolicNearestNeighbourClassificationModel(this, cloner);
+    }
+
+    public override IEnumerable<double> GetEstimatedClassValues(Dataset dataset, IEnumerable<int> rows) {
+      var estimatedValues = Interpreter.GetSymbolicExpressionTreeValues(SymbolicExpressionTree, dataset, rows);
+      var neighbors = new Dictionary<double, int>();
+      foreach (var ev in estimatedValues) {
+        int lower = 0, upper = 1;
+        double sdist = Math.Abs(ev - trainedTargetPair[0].Key);
+        for (int i = 1; i < trainedTargetPair.Count; i++) {
+          double d = Math.Abs(ev - trainedTargetPair[i].Key);
+          if (d > sdist) break;
+          lower = i;
+          upper = i + 1;
+          sdist = d;
+        }
+        neighbors.Clear();
+        neighbors[trainedTargetPair[lower].Value] = 1;
+        lower--;
+        for (int i = 1; i < Math.Min(k, trainedTargetPair.Count); i++) {
+          if (upper >= trainedTargetPair.Count || (lower > 0 && ev - trainedTargetPair[lower].Key < trainedTargetPair[upper].Key - ev)) {
+            if (!neighbors.ContainsKey(trainedTargetPair[lower].Value))
+              neighbors[trainedTargetPair[lower].Value] = 1;
+            else neighbors[trainedTargetPair[lower].Value]++;
+            lower--;
+          } else {
+            if (!neighbors.ContainsKey(trainedTargetPair[upper].Value))
+              neighbors[trainedTargetPair[upper].Value] = 1;
+            else neighbors[trainedTargetPair[upper].Value]++;
+            upper++;
+          }
+        }
+        yield return neighbors.MaxItems(x => x.Value).First().Key;
+      }
+    }
+
+    public override void RecalculateModelParameters(IClassificationProblemData problemData, IEnumerable<int> rows) {
+      var estimatedValues = Interpreter.GetSymbolicExpressionTreeValues(SymbolicExpressionTree, problemData.Dataset, rows);
+      var targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
+      var pair = estimatedValues.Zip(targetValues, (e, t) => new { Estimated = e, Target = t });
+
+      // there could be more than one target value per estimated value
+      var dict = new Dictionary<double, Dictionary<double, int>>();
+      foreach (var p in pair) {
+        if (!dict.ContainsKey(p.Estimated)) dict[p.Estimated] = new Dictionary<double, int>();
+        if (!dict[p.Estimated].ContainsKey(p.Target)) dict[p.Estimated][p.Target] = 0;
+        dict[p.Estimated][p.Target]++;
+      }
+
+      trainedTargetPair = new List<KeyValuePair<double, double>>();
+      foreach (var ev in dict) {
+        var target = ev.Value.MaxItems(x => x.Value).First().Key;
+        trainedTargetPair.Add(new KeyValuePair<double, double>(ev.Key, target));
+      }
+      trainedTargetPair = trainedTargetPair.OrderBy(x => x.Key).ToList();
+    }
+
+    public override ISymbolicClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData) {
+      return new SymbolicClassificationSolution((ISymbolicClassificationModel)this.Clone(), problemData);
+    }
+  }
+}
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.csproj
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.csproj	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.csproj	(revision 8915)
@@ -93,45 +93,64 @@
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="ALGLIB-3.5.0">
-      <HintPath>..\..\..\..\Trunk\sources\bin\ALGLIB-3.5.0.dll</HintPath>
+    <Reference Include="ALGLIB-3.6.0, Version=3.6.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\ALGLIB-3.6.0.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="AutoDiff-1.0, Version=1.0.0.14388, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <HintPath>..\..\bin\AutoDiff-1.0.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Analysis-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Analysis-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Collections-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Collections-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Common-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Common-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Core-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Core-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Data-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Data-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Operators-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Operators-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Optimization-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Optimization-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Parameters-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Parameters-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Persistence-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Persistence-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.PluginInfrastructure-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Problems.DataAnalysis-3.4">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Problems.DataAnalysis-3.4.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Problems.Instances-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Problems.Instances-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="System" />
@@ -152,4 +171,5 @@
     <Compile Include="MultiObjective\SymbolicRegressionMultiObjectiveValidationBestSolutionAnalyzer.cs" />
     <Compile Include="Plugin.cs" />
+    <Compile Include="SingleObjective\ConstantOptimizationAnalyzer.cs" />
     <Compile Include="SingleObjective\SymbolicRegressionSingleObjectiveValidationParetoBestSolutionAnalyzer.cs" />
     <Compile Include="SingleObjective\SymbolicRegressionSingleObjectiveTrainingParetoBestSolutionAnalyzer.cs" />
@@ -176,5 +196,4 @@
     <Compile Include="SingleObjective\Evaluators\SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.cs" />
     <Compile Include="SymbolicRegressionSolution.cs" />
-    <Compile Include="SymbolicRegressionSolutionValuesCalculator.cs" />
     <None Include="HeuristicLab.snk" />
     <None Include="Plugin.cs.frame" />
@@ -215,5 +234,5 @@
   -->
   <PropertyGroup>
-    <PreBuildEvent>set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+    <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
 set ProjectDir=$(ProjectDir)
 set SolutionDir=$(SolutionDir)
@@ -222,4 +241,10 @@
 call PreBuildEvent.cmd
 </PreBuildEvent>
+    <PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
+export ProjectDir=$(ProjectDir)
+export SolutionDir=$(SolutionDir)
+
+$SolutionDir/PreBuildEvent.sh
+</PreBuildEvent>
   </PropertyGroup>
 </Project>
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/Interfaces/ISymbolicRegressionModel.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/Interfaces/ISymbolicRegressionModel.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/Interfaces/ISymbolicRegressionModel.cs	(revision 8915)
@@ -20,7 +20,8 @@
 #endregion
 
-using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
   public interface ISymbolicRegressionModel : IRegressionModel, ISymbolicDataAnalysisModel {
+    double LowerEstimationLimit { get; }
+    double UpperEstimationLimit { get; }
   }
 }
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectiveMeanSquaredErrorTreeSizeEvaluator.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectiveMeanSquaredErrorTreeSizeEvaluator.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectiveMeanSquaredErrorTreeSizeEvaluator.cs	(revision 8915)
@@ -47,15 +47,24 @@
       IEnumerable<int> rows = GenerateRowsToEvaluate();
       var solution = SymbolicExpressionTreeParameter.ActualValue;
-      double[] qualities = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows);
+      double[] qualities = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows, ApplyLinearScalingParameter.ActualValue.Value);
       QualitiesParameter.ActualValue = new DoubleArray(qualities);
       return base.Apply();
     }
 
-    public static double[] Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable<int> rows) {
+    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> originalValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
-      IEnumerable<double> boundedEstimationValues = estimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit);
+      IEnumerable<double> targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
       OnlineCalculatorError errorState;
-      double mse = OnlineMeanSquaredErrorCalculator.Calculate(originalValues, boundedEstimationValues, out errorState);
+
+      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;
       return new double[2] { mse, solution.Length };
@@ -65,9 +74,11 @@
       SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = context;
       EstimationLimitsParameter.ExecutionContext = context;
+      ApplyLinearScalingParameter.ExecutionContext = context;
 
-      double[] quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows);
+      double[] quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, ApplyLinearScalingParameter.ActualValue.Value);
 
       SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
       EstimationLimitsParameter.ExecutionContext = null;
+      ApplyLinearScalingParameter.ExecutionContext = null;
 
       return quality;
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectivePearsonRSquaredTreeSizeEvaluator.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectivePearsonRSquaredTreeSizeEvaluator.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectivePearsonRSquaredTreeSizeEvaluator.cs	(revision 8915)
@@ -47,16 +47,27 @@
       IEnumerable<int> rows = GenerateRowsToEvaluate();
       var solution = SymbolicExpressionTreeParameter.ActualValue;
-      double[] qualities = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows);
+      double[] qualities = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows, ApplyLinearScalingParameter.ActualValue.Value);
       QualitiesParameter.ActualValue = new DoubleArray(qualities);
       return base.Apply();
     }
 
-    public static double[] Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable<int> rows) {
+    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> originalValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
+      IEnumerable<double> targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
       OnlineCalculatorError errorState;
-      double r2 = OnlinePearsonsRSquaredCalculator.Calculate(estimatedValues, originalValues, out errorState);
-      if (errorState != OnlineCalculatorError.None) r2 = 0.0;
-      return new double[] { r2, solution.Length };
+
+      double r2;
+      if (applyLinearScaling) {
+        var r2Calculator = new OnlinePearsonsRSquaredCalculator();
+        CalculateWithScaling(targetValues, estimatedValues, lowerEstimationLimit, upperEstimationLimit, r2Calculator, problemData.Dataset.Rows);
+        errorState = r2Calculator.ErrorState;
+        r2 = r2Calculator.RSquared;
+      } else {
+        IEnumerable<double> boundedEstimatedValues = estimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit);
+        r2 = OnlinePearsonsRSquaredCalculator.Calculate(targetValues, boundedEstimatedValues, out errorState);
+      }
+
+      if (errorState != OnlineCalculatorError.None) r2 = double.NaN;
+      return new double[2] { r2, solution.Length };
     }
 
@@ -64,9 +75,11 @@
       SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = context;
       EstimationLimitsParameter.ExecutionContext = context;
+      ApplyLinearScalingParameter.ExecutionContext = context;
 
-      double[] quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows);
+      double[] quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, ApplyLinearScalingParameter.ActualValue.Value);
 
       SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
       EstimationLimitsParameter.ExecutionContext = null;
+      ApplyLinearScalingParameter.ExecutionContext = null;
 
       return quality;
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectiveProblem.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectiveProblem.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectiveProblem.cs	(revision 8915)
@@ -65,4 +65,5 @@
       EstimationLimitsParameter.Hidden = true;
 
+      ApplyLinearScalingParameter.Value.Value = true;
       Maximization = new BoolArray(new bool[] { true, false });
       MaximumSymbolicExpressionTreeDepth.Value = InitialMaximumTreeDepth;
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectiveTrainingBestSolutionAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectiveTrainingBestSolutionAnalyzer.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectiveTrainingBestSolutionAnalyzer.cs	(revision 8915)
@@ -22,5 +22,4 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Data;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 using HeuristicLab.Parameters;
@@ -38,5 +37,4 @@
     private const string SymbolicDataAnalysisTreeInterpreterParameterName = "SymbolicDataAnalysisTreeInterpreter";
     private const string EstimationLimitsParameterName = "EstimationLimits";
-    private const string ApplyLinearScalingParameterName = "ApplyLinearScaling";
     #region parameter properties
     public ILookupParameter<IRegressionProblemData> ProblemDataParameter {
@@ -48,13 +46,4 @@
     public IValueLookupParameter<DoubleLimit> EstimationLimitsParameter {
       get { return (IValueLookupParameter<DoubleLimit>)Parameters[EstimationLimitsParameterName]; }
-    }
-    public IValueParameter<BoolValue> ApplyLinearScalingParameter {
-      get { return (IValueParameter<BoolValue>)Parameters[ApplyLinearScalingParameterName]; }
-    }
-    #endregion
-
-    #region properties
-    public BoolValue ApplyLinearScaling {
-      get { return ApplyLinearScalingParameter.Value; }
     }
     #endregion
@@ -68,5 +57,4 @@
       Parameters.Add(new LookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>(SymbolicDataAnalysisTreeInterpreterParameterName, "The symbolic data analysis tree interpreter for the symbolic expression tree."));
       Parameters.Add(new ValueLookupParameter<DoubleLimit>(EstimationLimitsParameterName, "The lower and upper limit for the estimated values produced by the symbolic regression model."));
-      Parameters.Add(new ValueParameter<BoolValue>(ApplyLinearScalingParameterName, "Flag that indicates if the produced symbolic regression solution should be linearly scaled.", new BoolValue(true)));
     }
 
@@ -77,6 +65,5 @@
     protected override ISymbolicRegressionSolution CreateSolution(ISymbolicExpressionTree bestTree, double[] bestQuality) {
       var model = new SymbolicRegressionModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
-      if (ApplyLinearScaling.Value)
-        SymbolicRegressionModel.Scale(model, ProblemDataParameter.ActualValue);
+      if (ApplyLinearScalingParameter.ActualValue.Value) SymbolicRegressionModel.Scale(model, ProblemDataParameter.ActualValue, ProblemDataParameter.ActualValue.TargetVariable);
       return new SymbolicRegressionSolution(model, (IRegressionProblemData)ProblemDataParameter.ActualValue.Clone());
     }
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectiveValidationBestSolutionAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectiveValidationBestSolutionAnalyzer.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectiveValidationBestSolutionAnalyzer.cs	(revision 8915)
@@ -22,5 +22,4 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Data;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 using HeuristicLab.Parameters;
@@ -36,5 +35,4 @@
     ISymbolicDataAnalysisBoundedOperator {
     private const string EstimationLimitsParameterName = "EstimationLimits";
-    private const string ApplyLinearScalingParameterName = "ApplyLinearScaling";
 
     #region parameter properties
@@ -42,14 +40,6 @@
       get { return (IValueLookupParameter<DoubleLimit>)Parameters[EstimationLimitsParameterName]; }
     }
-    public IValueParameter<BoolValue> ApplyLinearScalingParameter {
-      get { return (IValueParameter<BoolValue>)Parameters[ApplyLinearScalingParameterName]; }
-    }
     #endregion
 
-    #region properties
-    public BoolValue ApplyLinearScaling {
-      get { return ApplyLinearScalingParameter.Value; }
-    }
-    #endregion
     [StorableConstructor]
     private SymbolicRegressionMultiObjectiveValidationBestSolutionAnalyzer(bool deserializing) : base(deserializing) { }
@@ -58,5 +48,4 @@
       : base() {
       Parameters.Add(new ValueLookupParameter<DoubleLimit>(EstimationLimitsParameterName, "The lower and upper limit for the estimated values produced by the symbolic regression model."));
-      Parameters.Add(new ValueParameter<BoolValue>(ApplyLinearScalingParameterName, "Flag that indicates if the produced symbolic regression solution should be linearly scaled.", new BoolValue(true)));
     }
     public override IDeepCloneable Clone(Cloner cloner) {
@@ -66,6 +55,5 @@
     protected override ISymbolicRegressionSolution CreateSolution(ISymbolicExpressionTree bestTree, double[] bestQuality) {
       var model = new SymbolicRegressionModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
-      if (ApplyLinearScaling.Value)
-        SymbolicRegressionModel.Scale(model, ProblemDataParameter.ActualValue);
+      if (ApplyLinearScalingParameter.ActualValue.Value) SymbolicRegressionModel.Scale(model, ProblemDataParameter.ActualValue, ProblemDataParameter.ActualValue.TargetVariable);
       return new SymbolicRegressionSolution(model, (IRegressionProblemData)ProblemDataParameter.ActualValue.Clone());
     }
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/Plugin.cs.frame
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/Plugin.cs.frame	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/Plugin.cs.frame	(revision 8915)
@@ -28,5 +28,6 @@
   [Plugin("HeuristicLab.Problems.DataAnalysis.Symbolic.Regression","Provides classes to perform symbolic regression (single- or multiobjective).", "3.4.3.$WCREV$")]
   [PluginFile("HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.dll", PluginFileType.Assembly)]
-  [PluginDependency("HeuristicLab.ALGLIB", "3.5")]
+  [PluginDependency("HeuristicLab.ALGLIB", "3.6.0")]
+  [PluginDependency("HeuristicLab.AutoDiff", "1.0")]
   [PluginDependency("HeuristicLab.Analysis", "3.3")]
   [PluginDependency("HeuristicLab.Common", "3.3")]
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/ConstantOptimizationAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/ConstantOptimizationAnalyzer.cs	(revision 8915)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/ConstantOptimizationAnalyzer.cs	(revision 8915)
@@ -0,0 +1,176 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using HeuristicLab.Analysis;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
+  /// <summary>
+  /// An operator that optimizes the constants for the best symbolic expression tress in the current generation.
+  /// </summary>
+  [Item("ConstantOptimizationAnalyzer", "An operator that performs a constant optimization on the best symbolic expression trees.")]
+  [StorableClass]
+  public sealed class ConstantOptimizationAnalyzer : SymbolicDataAnalysisSingleObjectiveAnalyzer, IStatefulItem {
+    private const string PercentageOfBestSolutionsParameterName = "PercentageOfBestSolutions";
+    private const string ConstantOptimizationEvaluatorParameterName = "ConstantOptimizationOperator";
+
+    private const string DataTableNameConstantOptimizationImprovement = "Constant Optimization Improvement";
+    private const string DataRowNameMinimumImprovement = "Minimum improvement";
+    private const string DataRowNameMedianImprovement = "Median improvement";
+    private const string DataRowNameAverageImprovement = "Average improvement";
+    private const string DataRowNameMaximumImprovement = "Maximum improvement";
+
+    #region parameter properties
+    public IFixedValueParameter<PercentValue> PercentageOfBestSolutionsParameter {
+      get { return (IFixedValueParameter<PercentValue>)Parameters[PercentageOfBestSolutionsParameterName]; }
+    }
+
+    public IFixedValueParameter<SymbolicRegressionConstantOptimizationEvaluator> ConstantOptimizationEvaluatorParameter {
+      get { return (IFixedValueParameter<SymbolicRegressionConstantOptimizationEvaluator>)Parameters[ConstantOptimizationEvaluatorParameterName]; }
+    }
+    #endregion
+
+    #region properties
+    public SymbolicRegressionConstantOptimizationEvaluator ConstantOptimizationEvaluator {
+      get { return ConstantOptimizationEvaluatorParameter.Value; }
+    }
+    public double PercentageOfBestSolutions {
+      get { return PercentageOfBestSolutionsParameter.Value.Value; }
+    }
+
+    private DataTable ConstantOptimizationImprovementDataTable {
+      get {
+        IResult result;
+        ResultCollection.TryGetValue("Constant Optimization Improvement", out result);
+        if (result == null) return null;
+        return (DataTable)result.Value;
+      }
+    }
+    private DataRow MinimumImprovement {
+      get { return ConstantOptimizationImprovementDataTable.Rows[DataRowNameMinimumImprovement]; }
+    }
+    private DataRow MedianImprovement {
+      get { return ConstantOptimizationImprovementDataTable.Rows[DataRowNameMedianImprovement]; }
+    }
+    private DataRow AverageImprovement {
+      get { return ConstantOptimizationImprovementDataTable.Rows[DataRowNameAverageImprovement]; }
+    }
+    private DataRow MaximumImprovement {
+      get { return ConstantOptimizationImprovementDataTable.Rows[DataRowNameMaximumImprovement]; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    private ConstantOptimizationAnalyzer(bool deserializing) : base(deserializing) { }
+    private ConstantOptimizationAnalyzer(ConstantOptimizationAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) { return new ConstantOptimizationAnalyzer(this, cloner); }
+    public ConstantOptimizationAnalyzer()
+      : base() {
+      Parameters.Add(new FixedValueParameter<PercentValue>(PercentageOfBestSolutionsParameterName, "The percentage of the top solutions which should be analyzed.", new PercentValue(0.1)));
+      Parameters.Add(new FixedValueParameter<SymbolicRegressionConstantOptimizationEvaluator>(ConstantOptimizationEvaluatorParameterName, "The operator used to perform the constant optimization"));
+
+      //Changed the ActualName of the EvaluationPartitionParameter so that it matches the parameter name of symbolic regression problems.
+      ConstantOptimizationEvaluator.EvaluationPartitionParameter.ActualName = "FitnessCalculationPartition";
+    }
+
+
+    private double[] qualitiesBeforeCoOp = null;
+    private int[] scopeIndexes = null;
+    void IStatefulItem.InitializeState() {
+      qualitiesBeforeCoOp = null;
+      scopeIndexes = null;
+    }
+    void IStatefulItem.ClearState() {
+      qualitiesBeforeCoOp = null;
+      scopeIndexes = null;
+    }
+
+    public override IOperation Apply() {
+      //code executed for first call of analyzer
+      if (qualitiesBeforeCoOp == null) {
+
+        double[] trainingQuality;
+        // sort is ascending and we take the first n% => order so that best solutions are smallest
+        // sort order is determined by maximization parameter
+        if (Maximization.Value) {
+          // largest values must be sorted first
+          trainingQuality = Quality.Select(x => -x.Value).ToArray();
+        } else {
+          // smallest values must be sorted first
+          trainingQuality = Quality.Select(x => x.Value).ToArray();
+        }
+        // sort trees by training qualities
+        int topN = (int)Math.Max(trainingQuality.Length * PercentageOfBestSolutions, 1);
+        scopeIndexes = Enumerable.Range(0, trainingQuality.Length).ToArray();
+        Array.Sort(trainingQuality, scopeIndexes);
+        scopeIndexes = scopeIndexes.Take(topN).ToArray();
+        qualitiesBeforeCoOp = scopeIndexes.Select(x => Quality[x].Value).ToArray();
+
+        OperationCollection operationCollection = new OperationCollection();
+        operationCollection.Parallel = true;
+        foreach (var scopeIndex in scopeIndexes) {
+          var childOperation = ExecutionContext.CreateChildOperation(ConstantOptimizationEvaluator, ExecutionContext.Scope.SubScopes[scopeIndex]);
+          operationCollection.Add(childOperation);
+        }
+
+        return new OperationCollection { operationCollection, ExecutionContext.CreateOperation(this) };
+      }
+
+      //code executed to analyze results of constant optimization
+      double[] qualitiesAfterCoOp = scopeIndexes.Select(x => Quality[x].Value).ToArray();
+      var qualityImprovement = qualitiesBeforeCoOp.Zip(qualitiesAfterCoOp, (b, a) => a - b).ToArray();
+
+      if (!ResultCollection.ContainsKey(DataTableNameConstantOptimizationImprovement)) {
+        var dataTable = new DataTable(DataTableNameConstantOptimizationImprovement);
+        ResultCollection.Add(new Result(DataTableNameConstantOptimizationImprovement, dataTable));
+        dataTable.VisualProperties.YAxisTitle = "R²";
+
+        dataTable.Rows.Add(new DataRow(DataRowNameMinimumImprovement));
+        MinimumImprovement.VisualProperties.StartIndexZero = true;
+
+        dataTable.Rows.Add(new DataRow(DataRowNameMedianImprovement));
+        MedianImprovement.VisualProperties.StartIndexZero = true;
+
+        dataTable.Rows.Add(new DataRow(DataRowNameAverageImprovement));
+        AverageImprovement.VisualProperties.StartIndexZero = true;
+
+        dataTable.Rows.Add(new DataRow(DataRowNameMaximumImprovement));
+        MaximumImprovement.VisualProperties.StartIndexZero = true;
+      }
+
+      MinimumImprovement.Values.Add(qualityImprovement.Min());
+      MedianImprovement.Values.Add(qualityImprovement.Median());
+      AverageImprovement.Values.Add(qualityImprovement.Average());
+      MaximumImprovement.Values.Add(qualityImprovement.Max());
+
+      qualitiesBeforeCoOp = null;
+      scopeIndexes = null;
+      return base.Apply();
+    }
+  }
+}
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionConstantOptimizationEvaluator.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionConstantOptimizationEvaluator.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionConstantOptimizationEvaluator.cs	(revision 8915)
@@ -20,6 +20,8 @@
 #endregion
 
+using System;
 using System.Collections.Generic;
 using System.Linq;
+using AutoDiff;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -37,4 +39,5 @@
     private const string ConstantOptimizationProbabilityParameterName = "ConstantOptimizationProbability";
     private const string ConstantOptimizationRowsPercentageParameterName = "ConstantOptimizationRowsPercentage";
+    private const string UpdateConstantsInTreeParameterName = "UpdateConstantsInSymbolicExpressionTree";
 
     private const string EvaluatedTreesResultName = "EvaluatedTrees";
@@ -60,4 +63,7 @@
       get { return (IFixedValueParameter<PercentValue>)Parameters[ConstantOptimizationRowsPercentageParameterName]; }
     }
+    public IFixedValueParameter<BoolValue> UpdateConstantsInTreeParameter {
+      get { return (IFixedValueParameter<BoolValue>)Parameters[UpdateConstantsInTreeParameterName]; }
+    }
 
     public IntValue ConstantOptimizationIterations {
@@ -72,4 +78,8 @@
     public PercentValue ConstantOptimizationRowsPercentage {
       get { return ConstantOptimizationRowsPercentageParameter.Value; }
+    }
+    public bool UpdateConstantsInTree {
+      get { return UpdateConstantsInTreeParameter.Value.Value; }
+      set { UpdateConstantsInTreeParameter.Value.Value = value; }
     }
 
@@ -89,4 +99,5 @@
       Parameters.Add(new FixedValueParameter<PercentValue>(ConstantOptimizationProbabilityParameterName, "Determines the probability that the constants are optimized", new PercentValue(1), true));
       Parameters.Add(new FixedValueParameter<PercentValue>(ConstantOptimizationRowsPercentageParameterName, "Determines the percentage of the rows which should be used for constant optimization", new PercentValue(1), true));
+      Parameters.Add(new FixedValueParameter<BoolValue>(UpdateConstantsInTreeParameterName, "Determines if the constants in the tree should be overwritten by the optimized constants.", new BoolValue(true)));
 
       Parameters.Add(new LookupParameter<IntValue>(EvaluatedTreesResultName));
@@ -98,7 +109,12 @@
     }
 
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (!Parameters.ContainsKey(UpdateConstantsInTreeParameterName))
+        Parameters.Add(new FixedValueParameter<BoolValue>(UpdateConstantsInTreeParameterName, "Determines if the constants in the tree should be overwritten by the optimized constants.", new BoolValue(true)));
+    }
+
     public override IOperation Apply() {
       AddResults();
-      int seed = RandomParameter.ActualValue.Next();
       var solution = SymbolicExpressionTreeParameter.ActualValue;
       double quality;
@@ -106,18 +122,20 @@
         IEnumerable<int> constantOptimizationRows = GenerateRowsToEvaluate(ConstantOptimizationRowsPercentage.Value);
         quality = OptimizeConstants(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, ProblemDataParameter.ActualValue,
-           constantOptimizationRows, ConstantOptimizationImprovement.Value, ConstantOptimizationIterations.Value, 0.001,
-           EstimationLimitsParameter.ActualValue.Upper, EstimationLimitsParameter.ActualValue.Lower,
+           constantOptimizationRows, ApplyLinearScalingParameter.ActualValue.Value, ConstantOptimizationIterations.Value,
+           EstimationLimitsParameter.ActualValue.Upper, EstimationLimitsParameter.ActualValue.Lower, UpdateConstantsInTree,
           EvaluatedTreesParameter.ActualValue, EvaluatedTreeNodesParameter.ActualValue);
         if (ConstantOptimizationRowsPercentage.Value != RelativeNumberOfEvaluatedSamplesParameter.ActualValue.Value) {
           var evaluationRows = GenerateRowsToEvaluate();
-          quality = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, evaluationRows);
+          quality = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, evaluationRows, ApplyLinearScalingParameter.ActualValue.Value);
         }
       } else {
         var evaluationRows = GenerateRowsToEvaluate();
-        quality = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, evaluationRows);
+        quality = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, evaluationRows, ApplyLinearScalingParameter.ActualValue.Value);
       }
       QualityParameter.ActualValue = new DoubleValue(quality);
-      EvaluatedTreesParameter.ActualValue.Value += 1;
-      EvaluatedTreeNodesParameter.ActualValue.Value += solution.Length;
+      lock (locker) {
+        EvaluatedTreesParameter.ActualValue.Value += 1;
+        EvaluatedTreeNodesParameter.ActualValue.Value += solution.Length;
+      }
 
       if (Successor != null)
@@ -127,16 +145,19 @@
     }
 
+    private object locker = new object();
     private void AddResults() {
-      if (EvaluatedTreesParameter.ActualValue == null) {
-        var scope = ExecutionContext.Scope;
-        while (scope.Parent != null)
-          scope = scope.Parent;
-        scope.Variables.Add(new Core.Variable(EvaluatedTreesResultName, new IntValue()));
-      }
-      if (EvaluatedTreeNodesParameter.ActualValue == null) {
-        var scope = ExecutionContext.Scope;
-        while (scope.Parent != null)
-          scope = scope.Parent;
-        scope.Variables.Add(new Core.Variable(EvaluatedTreeNodesResultName, new IntValue()));
+      lock (locker) {
+        if (EvaluatedTreesParameter.ActualValue == null) {
+          var scope = ExecutionContext.Scope;
+          while (scope.Parent != null)
+            scope = scope.Parent;
+          scope.Variables.Add(new Core.Variable(EvaluatedTreesResultName, new IntValue()));
+        }
+        if (EvaluatedTreeNodesParameter.ActualValue == null) {
+          var scope = ExecutionContext.Scope;
+          while (scope.Parent != null)
+            scope = scope.Parent;
+          scope.Variables.Add(new Core.Variable(EvaluatedTreeNodesResultName, new IntValue()));
+        }
       }
     }
@@ -145,70 +166,341 @@
       SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = context;
       EstimationLimitsParameter.ExecutionContext = context;
-
-      double r2 = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows);
+      ApplyLinearScalingParameter.ExecutionContext = context;
+
+      double r2 = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, ApplyLinearScalingParameter.ActualValue.Value);
 
       SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
       EstimationLimitsParameter.ExecutionContext = null;
+      ApplyLinearScalingParameter.ExecutionContext = context;
 
       return r2;
     }
 
+    #region derivations of functions
+    // create function factory for arctangent
+    private readonly Func<Term, UnaryFunc> arctan = UnaryFunc.Factory(
+      eval: Math.Atan,
+      diff: x => 1 / (1 + x * x));
+    private static readonly Func<Term, UnaryFunc> sin = UnaryFunc.Factory(
+      eval: Math.Sin,
+      diff: Math.Cos);
+    private static readonly Func<Term, UnaryFunc> cos = UnaryFunc.Factory(
+       eval: Math.Cos,
+       diff: x => -Math.Sin(x));
+    private static readonly Func<Term, UnaryFunc> tan = UnaryFunc.Factory(
+      eval: Math.Tan,
+      diff: x => 1 + Math.Tan(x) * Math.Tan(x));
+    private static readonly Func<Term, UnaryFunc> square = UnaryFunc.Factory(
+       eval: x => x * x,
+       diff: x => 2 * x);
+    private static readonly Func<Term, UnaryFunc> erf = UnaryFunc.Factory(
+      eval: alglib.errorfunction,
+      diff: x => 2.0 * Math.Exp(-(x * x)) / Math.Sqrt(Math.PI));
+    private static readonly Func<Term, UnaryFunc> norm = UnaryFunc.Factory(
+      eval: alglib.normaldistribution,
+      diff: x => -(Math.Exp(-(x * x)) * Math.Sqrt(Math.Exp(x * x)) * x) / Math.Sqrt(2 * Math.PI));
+    #endregion
+
+
     public static double OptimizeConstants(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree tree, IRegressionProblemData problemData,
-      IEnumerable<int> rows, double improvement, int iterations, double differentialStep, double upperEstimationLimit = double.MaxValue, double lowerEstimationLimit = double.MinValue, IntValue evaluatedTrees = null, IntValue evaluatedTreeNodes = null) {
+      IEnumerable<int> rows, bool applyLinearScaling, int maxIterations, double upperEstimationLimit = double.MaxValue, double lowerEstimationLimit = double.MinValue, bool updateConstantsInTree = true, IntValue evaluatedTrees = null, IntValue evaluatedTreeNodes = null) {
+
+      List<AutoDiff.Variable> variables = new List<AutoDiff.Variable>();
+      List<AutoDiff.Variable> parameters = new List<AutoDiff.Variable>();
+      List<string> variableNames = new List<string>();
+
+      AutoDiff.Term func;
+      if (!TryTransformToAutoDiff(tree.Root.GetSubtree(0), variables, parameters, variableNames, out func))
+        throw new NotSupportedException("Could not optimize constants of symbolic expression tree due to not supported symbols used in the tree.");
+      if (variableNames.Count == 0) return 0.0;
+
+      AutoDiff.IParametricCompiledTerm compiledFunc = AutoDiff.TermUtils.Compile(func, variables.ToArray(), parameters.ToArray());
+
       List<SymbolicExpressionTreeTerminalNode> terminalNodes = tree.Root.IterateNodesPrefix().OfType<SymbolicExpressionTreeTerminalNode>().ToList();
-      double[] c = new double[terminalNodes.Count];
-      int treeLength = tree.Length;
-
-      //extract inital constants
-      for (int i = 0; i < terminalNodes.Count; i++) {
-        ConstantTreeNode constantTreeNode = terminalNodes[i] as ConstantTreeNode;
-        if (constantTreeNode != null) c[i] = constantTreeNode.Value;
-        VariableTreeNode variableTreeNode = terminalNodes[i] as VariableTreeNode;
-        if (variableTreeNode != null) c[i] = variableTreeNode.Weight;
-      }
-
-      double epsg = 0;
-      double epsf = improvement;
-      double epsx = 0;
-      int maxits = iterations;
-      double diffstep = differentialStep;
-
-      alglib.minlmstate state;
-      alglib.minlmreport report;
-
-      alglib.minlmcreatev(1, c, diffstep, out state);
-      alglib.minlmsetcond(state, epsg, epsf, epsx, maxits);
-      alglib.minlmoptimize(state, CreateCallBack(interpreter, tree, problemData, rows, upperEstimationLimit, lowerEstimationLimit, treeLength, evaluatedTrees, evaluatedTreeNodes), null, terminalNodes);
-      alglib.minlmresults(state, out c, out report);
-
-      for (int i = 0; i < c.Length; i++) {
-        ConstantTreeNode constantTreeNode = terminalNodes[i] as ConstantTreeNode;
-        if (constantTreeNode != null) constantTreeNode.Value = c[i];
-        VariableTreeNode variableTreeNode = terminalNodes[i] as VariableTreeNode;
-        if (variableTreeNode != null) variableTreeNode.Weight = c[i];
-      }
-
-      return (state.fi[0] - 1) * -1;
-    }
-
-    private static alglib.ndimensional_fvec CreateCallBack(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree tree, IRegressionProblemData problemData, IEnumerable<int> rows, double upperEstimationLimit, double lowerEstimationLimit, int treeLength, IntValue evaluatedTrees = null, IntValue evaluatedTreeNodes = null) {
-      return (double[] arg, double[] fi, object obj) => {
-        // update constants of tree
-        List<SymbolicExpressionTreeTerminalNode> terminalNodes = (List<SymbolicExpressionTreeTerminalNode>)obj;
-        for (int i = 0; i < terminalNodes.Count; i++) {
-          ConstantTreeNode constantTreeNode = terminalNodes[i] as ConstantTreeNode;
-          if (constantTreeNode != null) constantTreeNode.Value = arg[i];
-          VariableTreeNode variableTreeNode = terminalNodes[i] as VariableTreeNode;
-          if (variableTreeNode != null) variableTreeNode.Weight = arg[i];
-        }
-
-        double quality = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(interpreter, tree, lowerEstimationLimit, upperEstimationLimit, problemData, rows);
-
-        fi[0] = 1 - quality;
-        if (evaluatedTrees != null) evaluatedTrees.Value++;
-        if (evaluatedTreeNodes != null) evaluatedTreeNodes.Value += treeLength;
+      double[] c = new double[variables.Count];
+
+      {
+        c[0] = 0.0;
+        c[1] = 1.0;
+        //extract inital constants
+        int i = 2;
+        foreach (var node in terminalNodes) {
+          ConstantTreeNode constantTreeNode = node as ConstantTreeNode;
+          VariableTreeNode variableTreeNode = node as VariableTreeNode;
+          if (constantTreeNode != null)
+            c[i++] = constantTreeNode.Value;
+          else if (variableTreeNode != null)
+            c[i++] = variableTreeNode.Weight;
+        }
+      }
+
+      alglib.lsfitstate state;
+      alglib.lsfitreport rep;
+      int info;
+
+      Dataset ds = problemData.Dataset;
+      double[,] x = new double[rows.Count(), variableNames.Count];
+      int row = 0;
+      foreach (var r in rows) {
+        for (int col = 0; col < variableNames.Count; col++) {
+          x[row, col] = ds.GetDoubleValue(variableNames[col], r);
+        }
+        row++;
+      }
+      double[] y = ds.GetDoubleValues(problemData.TargetVariable, rows).ToArray();
+      int n = x.GetLength(0);
+      int m = x.GetLength(1);
+      int k = c.Length;
+
+      alglib.ndimensional_pfunc function_cx_1_func = CreatePFunc(compiledFunc);
+      alglib.ndimensional_pgrad function_cx_1_grad = CreatePGrad(compiledFunc);
+
+      try {
+        alglib.lsfitcreatefg(x, y, c, n, m, k, false, out state);
+        alglib.lsfitsetcond(state, 0, 0, maxIterations);
+        alglib.lsfitfit(state, function_cx_1_func, function_cx_1_grad, null, null);
+        alglib.lsfitresults(state, out info, out c, out rep);
+
+      }
+      catch (ArithmeticException) {
+        return 0.0;
+      }
+      catch (alglib.alglibexception) {
+        return 0.0;
+      }
+      var newTree = tree;
+      if (!updateConstantsInTree) newTree = (ISymbolicExpressionTree)tree.Clone();
+      {
+        // only when no error occurred
+        // set constants in tree
+        int i = 2;
+        foreach (var node in newTree.Root.IterateNodesPrefix().OfType<SymbolicExpressionTreeTerminalNode>()) {
+          ConstantTreeNode constantTreeNode = node as ConstantTreeNode;
+          VariableTreeNode variableTreeNode = node as VariableTreeNode;
+          if (constantTreeNode != null)
+            constantTreeNode.Value = c[i++];
+          else if (variableTreeNode != null)
+            variableTreeNode.Weight = c[i++];
+        }
+
+      }
+      return SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(interpreter, newTree, lowerEstimationLimit, upperEstimationLimit, problemData, rows, applyLinearScaling);
+    }
+
+    private static alglib.ndimensional_pfunc CreatePFunc(AutoDiff.IParametricCompiledTerm compiledFunc) {
+      return (double[] c, double[] x, ref double func, object o) => {
+        func = compiledFunc.Evaluate(c, x);
       };
     }
 
+    private static alglib.ndimensional_pgrad CreatePGrad(AutoDiff.IParametricCompiledTerm compiledFunc) {
+      return (double[] c, double[] x, ref double func, double[] grad, object o) => {
+        var tupel = compiledFunc.Differentiate(c, x);
+        func = tupel.Item2;
+        Array.Copy(tupel.Item1, grad, grad.Length);
+      };
+    }
+
+    private static bool TryTransformToAutoDiff(ISymbolicExpressionTreeNode node, List<AutoDiff.Variable> variables, List<AutoDiff.Variable> parameters, List<string> variableNames, out AutoDiff.Term term) {
+      if (node.Symbol is Constant) {
+        var var = new AutoDiff.Variable();
+        variables.Add(var);
+        term = var;
+        return true;
+      }
+      if (node.Symbol is Variable) {
+        var varNode = node as VariableTreeNode;
+        var par = new AutoDiff.Variable();
+        parameters.Add(par);
+        variableNames.Add(varNode.VariableName);
+        var w = new AutoDiff.Variable();
+        variables.Add(w);
+        term = AutoDiff.TermBuilder.Product(w, par);
+        return true;
+      }
+      if (node.Symbol is Addition) {
+        List<AutoDiff.Term> terms = new List<Term>();
+        foreach (var subTree in node.Subtrees) {
+          AutoDiff.Term t;
+          if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, out t)) {
+            term = null;
+            return false;
+          }
+          terms.Add(t);
+        }
+        term = AutoDiff.TermBuilder.Sum(terms);
+        return true;
+      }
+      if (node.Symbol is Subtraction) {
+        List<AutoDiff.Term> terms = new List<Term>();
+        for (int i = 0; i < node.SubtreeCount; i++) {
+          AutoDiff.Term t;
+          if (!TryTransformToAutoDiff(node.GetSubtree(i), variables, parameters, variableNames, out t)) {
+            term = null;
+            return false;
+          }
+          if (i > 0) t = -t;
+          terms.Add(t);
+        }
+        term = AutoDiff.TermBuilder.Sum(terms);
+        return true;
+      }
+      if (node.Symbol is Multiplication) {
+        AutoDiff.Term a, b;
+        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out a) ||
+          !TryTransformToAutoDiff(node.GetSubtree(1), variables, parameters, variableNames, out b)) {
+          term = null;
+          return false;
+        } else {
+          List<AutoDiff.Term> factors = new List<Term>();
+          foreach (var subTree in node.Subtrees.Skip(2)) {
+            AutoDiff.Term f;
+            if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, out f)) {
+              term = null;
+              return false;
+            }
+            factors.Add(f);
+          }
+          term = AutoDiff.TermBuilder.Product(a, b, factors.ToArray());
+          return true;
+        }
+      }
+      if (node.Symbol is Division) {
+        // only works for at least two subtrees
+        AutoDiff.Term a, b;
+        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out a) ||
+          !TryTransformToAutoDiff(node.GetSubtree(1), variables, parameters, variableNames, out b)) {
+          term = null;
+          return false;
+        } else {
+          List<AutoDiff.Term> factors = new List<Term>();
+          foreach (var subTree in node.Subtrees.Skip(2)) {
+            AutoDiff.Term f;
+            if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, out f)) {
+              term = null;
+              return false;
+            }
+            factors.Add(1.0 / f);
+          }
+          term = AutoDiff.TermBuilder.Product(a, 1.0 / b, factors.ToArray());
+          return true;
+        }
+      }
+      if (node.Symbol is Logarithm) {
+        AutoDiff.Term t;
+        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
+          term = null;
+          return false;
+        } else {
+          term = AutoDiff.TermBuilder.Log(t);
+          return true;
+        }
+      }
+      if (node.Symbol is Exponential) {
+        AutoDiff.Term t;
+        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
+          term = null;
+          return false;
+        } else {
+          term = AutoDiff.TermBuilder.Exp(t);
+          return true;
+        }
+      } if (node.Symbol is Sine) {
+        AutoDiff.Term t;
+        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
+          term = null;
+          return false;
+        } else {
+          term = sin(t);
+          return true;
+        }
+      } if (node.Symbol is Cosine) {
+        AutoDiff.Term t;
+        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
+          term = null;
+          return false;
+        } else {
+          term = cos(t);
+          return true;
+        }
+      } if (node.Symbol is Tangent) {
+        AutoDiff.Term t;
+        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
+          term = null;
+          return false;
+        } else {
+          term = tan(t);
+          return true;
+        }
+      }
+      if (node.Symbol is Square) {
+        AutoDiff.Term t;
+        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
+          term = null;
+          return false;
+        } else {
+          term = square(t);
+          return true;
+        }
+      } if (node.Symbol is Erf) {
+        AutoDiff.Term t;
+        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
+          term = null;
+          return false;
+        } else {
+          term = erf(t);
+          return true;
+        }
+      } if (node.Symbol is Norm) {
+        AutoDiff.Term t;
+        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
+          term = null;
+          return false;
+        } else {
+          term = norm(t);
+          return true;
+        }
+      }
+      if (node.Symbol is StartSymbol) {
+        var alpha = new AutoDiff.Variable();
+        var beta = new AutoDiff.Variable();
+        variables.Add(beta);
+        variables.Add(alpha);
+        AutoDiff.Term branchTerm;
+        if (TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out branchTerm)) {
+          term = branchTerm * alpha + beta;
+          return true;
+        } else {
+          term = null;
+          return false;
+        }
+      }
+      term = null;
+      return false;
+    }
+
+    public static bool CanOptimizeConstants(ISymbolicExpressionTree tree) {
+      var containsUnknownSymbol = (
+        from n in tree.Root.GetSubtree(0).IterateNodesPrefix()
+        where
+         !(n.Symbol is Variable) &&
+         !(n.Symbol is Constant) &&
+         !(n.Symbol is Addition) &&
+         !(n.Symbol is Subtraction) &&
+         !(n.Symbol is Multiplication) &&
+         !(n.Symbol is Division) &&
+         !(n.Symbol is Logarithm) &&
+         !(n.Symbol is Exponential) &&
+         !(n.Symbol is Sine) &&
+         !(n.Symbol is Cosine) &&
+         !(n.Symbol is Tangent) &&
+         !(n.Symbol is Square) &&
+         !(n.Symbol is Erf) &&
+         !(n.Symbol is Norm) &&
+         !(n.Symbol is StartSymbol)
+        select n).
+      Any();
+      return !containsUnknownSymbol;
+    }
   }
 }
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveEvaluator.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveEvaluator.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveEvaluator.cs	(revision 8915)
@@ -30,67 +30,9 @@
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
   [StorableClass]
-  public abstract class SymbolicRegressionSingleObjectiveEvaluator : SymbolicDataAnalysisSingleObjectiveEvaluator<IRegressionProblemData>, ISymbolicRegressionSingleObjectiveEvaluator {
-    private const string ApplyLinearScalingParameterName = "ApplyLinearScaling";
-    public IFixedValueParameter<BoolValue> ApplyLinearScalingParameter {
-      get { return (IFixedValueParameter<BoolValue>)Parameters[ApplyLinearScalingParameterName]; }
-    }
-    public bool ApplyLinearScaling {
-      get { return ApplyLinearScalingParameter.Value.Value; }
-      set { ApplyLinearScalingParameter.Value.Value = value; }
-    }
-
+  public abstract class SymbolicRegressionSingleObjectiveEvaluator : SymbolicDataAnalysisSingleObjectiveEvaluator<IRegressionProblemData>, ISymbolicRegressionSingleObjectiveEvaluator {  
     [StorableConstructor]
     protected SymbolicRegressionSingleObjectiveEvaluator(bool deserializing) : base(deserializing) { }
     protected SymbolicRegressionSingleObjectiveEvaluator(SymbolicRegressionSingleObjectiveEvaluator original, Cloner cloner) : base(original, cloner) { }
-    protected SymbolicRegressionSingleObjectiveEvaluator()
-      : base() {
-      Parameters.Add(new FixedValueParameter<BoolValue>(ApplyLinearScalingParameterName, "Flag that indicates if the individual should be linearly scaled before evaluating.", new BoolValue(true)));
-      ApplyLinearScalingParameter.Hidden = true;
-    }
-
-    [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserialization() {
-      if (!Parameters.ContainsKey(ApplyLinearScalingParameterName)) {
-        Parameters.Add(new FixedValueParameter<BoolValue>(ApplyLinearScalingParameterName, "Flag that indicates if the individual should be linearly scaled before evaluating.", new BoolValue(false)));
-        ApplyLinearScalingParameter.Hidden = true;
-      }
-    }
-
-    [ThreadStatic]
-    private static double[] cache;
-
-    protected static void CalculateWithScaling(IEnumerable<double> targetValues, IEnumerable<double> estimatedValues,
-      double lowerEstimationLimit, double upperEstimationLimit,
-      IOnlineCalculator calculator, int maxRows) {
-      if (cache == null || cache.GetLength(0) < maxRows) {
-        cache = new double[maxRows];
-      }
-
-      //calculate linear scaling
-      //the static methods of the calculator could not be used as it performs a check if the enumerators have an equal amount of elements
-      //this is not true if the cache is used
-      int i = 0;
-      var linearScalingCalculator = new OnlineLinearScalingParameterCalculator();
-      var targetValuesEnumerator = targetValues.GetEnumerator();
-      var estimatedValuesEnumerator = estimatedValues.GetEnumerator();
-      while (targetValuesEnumerator.MoveNext() && estimatedValuesEnumerator.MoveNext()) {
-        double target = targetValuesEnumerator.Current;
-        double estimated = estimatedValuesEnumerator.Current;
-        cache[i] = estimated;
-        linearScalingCalculator.Add(estimated, target);
-        i++;
-      }
-      double alpha = linearScalingCalculator.Alpha;
-      double beta = linearScalingCalculator.Beta;
-
-      //calculate the quality by using the passed online calculator
-      targetValuesEnumerator = targetValues.GetEnumerator();
-      var scaledBoundedEstimatedValuesEnumerator = Enumerable.Range(0, i).Select(x => cache[x] * beta + alpha)
-        .LimitToRange(lowerEstimationLimit, upperEstimationLimit).GetEnumerator();
-
-      while (targetValuesEnumerator.MoveNext() & scaledBoundedEstimatedValuesEnumerator.MoveNext()) {
-        calculator.Add(targetValuesEnumerator.Current, scaledBoundedEstimatedValuesEnumerator.Current);
-      }
-    }
+    protected SymbolicRegressionSingleObjectiveEvaluator(): base() {}    
   }
 }
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveMaxAbsoluteErrorEvaluator.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveMaxAbsoluteErrorEvaluator.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveMaxAbsoluteErrorEvaluator.cs	(revision 8915)
@@ -20,5 +20,4 @@
 #endregion
 
-using System;
 using System.Collections.Generic;
 using HeuristicLab.Common;
@@ -47,5 +46,5 @@
       IEnumerable<int> rows = GenerateRowsToEvaluate();
 
-      double quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows, ApplyLinearScaling);
+      double quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows, ApplyLinearScalingParameter.ActualValue.Value);
       QualityParameter.ActualValue = new DoubleValue(quality);
 
@@ -68,6 +67,6 @@
         mse = OnlineMaxAbsoluteErrorCalculator.Calculate(targetValues, boundedEstimatedValues, out errorState);
       }
-      if (errorState != OnlineCalculatorError.None) return Double.NaN;
-      else return mse;
+      if (errorState != OnlineCalculatorError.None) return double.NaN;
+      return mse;
     }
 
@@ -75,9 +74,11 @@
       SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = context;
       EstimationLimitsParameter.ExecutionContext = context;
+      ApplyLinearScalingParameter.ExecutionContext = context;
 
-      double mse = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, ApplyLinearScaling);
+      double mse = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, ApplyLinearScalingParameter.ActualValue.Value);
 
       SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
       EstimationLimitsParameter.ExecutionContext = null;
+      ApplyLinearScalingParameter.ExecutionContext = null;
 
       return mse;
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveMeanAbsoluteErrorEvaluator.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveMeanAbsoluteErrorEvaluator.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveMeanAbsoluteErrorEvaluator.cs	(revision 8915)
@@ -20,5 +20,4 @@
 #endregion
 
-using System;
 using System.Collections.Generic;
 using HeuristicLab.Common;
@@ -47,5 +46,5 @@
       IEnumerable<int> rows = GenerateRowsToEvaluate();
 
-      double quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows, ApplyLinearScaling);
+      double quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows, ApplyLinearScalingParameter.ActualValue.Value);
       QualityParameter.ActualValue = new DoubleValue(quality);
 
@@ -58,17 +57,16 @@
       OnlineCalculatorError errorState;
 
-      double mse;
+      double mae;
       if (applyLinearScaling) {
         var maeCalculator = new OnlineMeanAbsoluteErrorCalculator();
         CalculateWithScaling(targetValues, estimatedValues, lowerEstimationLimit, upperEstimationLimit, maeCalculator, problemData.Dataset.Rows);
         errorState = maeCalculator.ErrorState;
-        mse = maeCalculator.MeanAbsoluteError;
+        mae = maeCalculator.MeanAbsoluteError;
       } else {
-        IEnumerable<double> boundedEstimatedValues = estimatedValues.LimitToRange(lowerEstimationLimit,
-                                                                                  upperEstimationLimit);
-        mse = OnlineMeanSquaredErrorCalculator.Calculate(targetValues, boundedEstimatedValues, out errorState);
+        IEnumerable<double> boundedEstimatedValues = estimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit);
+        mae = OnlineMeanAbsoluteErrorCalculator.Calculate(targetValues, boundedEstimatedValues, out errorState);
       }
-      if (errorState != OnlineCalculatorError.None) return Double.NaN;
-      else return mse;
+      if (errorState != OnlineCalculatorError.None) return double.NaN;
+      return mae;
     }
 
@@ -76,9 +74,11 @@
       SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = context;
       EstimationLimitsParameter.ExecutionContext = context;
+      ApplyLinearScalingParameter.ExecutionContext = context;
 
-      double mse = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, ApplyLinearScaling);
+      double mse = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, ApplyLinearScalingParameter.ActualValue.Value);
 
       SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
       EstimationLimitsParameter.ExecutionContext = null;
+      ApplyLinearScalingParameter.ExecutionContext = null;
 
       return mse;
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveMeanSquaredErrorEvaluator.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveMeanSquaredErrorEvaluator.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveMeanSquaredErrorEvaluator.cs	(revision 8915)
@@ -20,5 +20,4 @@
 #endregion
 
-using System;
 using System.Collections.Generic;
 using HeuristicLab.Common;
@@ -47,5 +46,5 @@
       IEnumerable<int> rows = GenerateRowsToEvaluate();
 
-      double quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows, ApplyLinearScaling);
+      double quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows, ApplyLinearScalingParameter.ActualValue.Value);
       QualityParameter.ActualValue = new DoubleValue(quality);
 
@@ -68,6 +67,6 @@
         mse = OnlineMeanSquaredErrorCalculator.Calculate(targetValues, boundedEstimatedValues, out errorState);
       }
-      if (errorState != OnlineCalculatorError.None) return Double.NaN;
-      else return mse;
+      if (errorState != OnlineCalculatorError.None) return double.NaN;
+      return mse;
     }
 
@@ -75,9 +74,11 @@
       SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = context;
       EstimationLimitsParameter.ExecutionContext = context;
+      ApplyLinearScalingParameter.ExecutionContext = context;
 
-      double mse = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, ApplyLinearScaling);
+      double mse = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, ApplyLinearScalingParameter.ActualValue.Value);
 
       SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
       EstimationLimitsParameter.ExecutionContext = null;
+      ApplyLinearScalingParameter.ExecutionContext = null;
 
       return mse;
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.cs	(revision 8915)
@@ -48,5 +48,5 @@
       IEnumerable<int> rows = GenerateRowsToEvaluate();
 
-      double quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows);
+      double quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows, ApplyLinearScalingParameter.ActualValue.Value);
       QualityParameter.ActualValue = new DoubleValue(quality);
 
@@ -54,11 +54,21 @@
     }
 
-    public static double Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable<int> rows) {
+    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> originalValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
+      IEnumerable<double> targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
       OnlineCalculatorError errorState;
-      double r2 = OnlinePearsonsRSquaredCalculator.Calculate(estimatedValues, originalValues, out errorState);
-      if (errorState != OnlineCalculatorError.None) return 0.0;
-      else return r2;
+
+      double r2;
+      if (applyLinearScaling) {
+        var r2Calculator = new OnlinePearsonsRSquaredCalculator();
+        CalculateWithScaling(targetValues, estimatedValues, lowerEstimationLimit, upperEstimationLimit, r2Calculator, problemData.Dataset.Rows);
+        errorState = r2Calculator.ErrorState;
+        r2 = r2Calculator.RSquared;
+      } else {
+        IEnumerable<double> boundedEstimatedValues = estimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit);
+        r2 = OnlinePearsonsRSquaredCalculator.Calculate(targetValues, boundedEstimatedValues, out errorState);
+      }
+      if (errorState != OnlineCalculatorError.None) return double.NaN;
+      return r2;
     }
 
@@ -66,9 +76,11 @@
       SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = context;
       EstimationLimitsParameter.ExecutionContext = context;
+      ApplyLinearScalingParameter.ExecutionContext = context;
 
-      double r2 = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows);
+      double r2 = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, ApplyLinearScalingParameter.ActualValue.Value);
 
       SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
       EstimationLimitsParameter.ExecutionContext = null;
+      ApplyLinearScalingParameter.ExecutionContext = null;
 
       return r2;
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveProblem.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveProblem.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveProblem.cs	(revision 8915)
@@ -61,4 +61,6 @@
       EstimationLimitsParameter.Hidden = true;
 
+
+      ApplyLinearScalingParameter.Value.Value = true;
       Maximization.Value = true;
       MaximumSymbolicExpressionTreeDepth.Value = InitialMaximumTreeDepth;
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveTrainingBestSolutionAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveTrainingBestSolutionAnalyzer.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveTrainingBestSolutionAnalyzer.cs	(revision 8915)
@@ -22,5 +22,4 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Data;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 using HeuristicLab.Parameters;
@@ -38,5 +37,4 @@
     private const string SymbolicDataAnalysisTreeInterpreterParameterName = "SymbolicDataAnalysisTreeInterpreter";
     private const string EstimationLimitsParameterName = "EstimationLimits";
-    private const string ApplyLinearScalingParameterName = "ApplyLinearScaling";
     #region parameter properties
     public ILookupParameter<IRegressionProblemData> ProblemDataParameter {
@@ -48,13 +46,4 @@
     public IValueLookupParameter<DoubleLimit> EstimationLimitsParameter {
       get { return (IValueLookupParameter<DoubleLimit>)Parameters[EstimationLimitsParameterName]; }
-    }
-    public IValueParameter<BoolValue> ApplyLinearScalingParameter {
-      get { return (IValueParameter<BoolValue>)Parameters[ApplyLinearScalingParameterName]; }
-    }
-    #endregion
-
-    #region properties
-    public BoolValue ApplyLinearScaling {
-      get { return ApplyLinearScalingParameter.Value; }
     }
     #endregion
@@ -68,5 +57,4 @@
       Parameters.Add(new LookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>(SymbolicDataAnalysisTreeInterpreterParameterName, "The symbolic data analysis tree interpreter for the symbolic expression tree."));
       Parameters.Add(new ValueLookupParameter<DoubleLimit>(EstimationLimitsParameterName, "The lower and upper limit for the estimated values produced by the symbolic regression model."));
-      Parameters.Add(new ValueParameter<BoolValue>(ApplyLinearScalingParameterName, "Flag that indicates if the produced symbolic regression solution should be linearly scaled.", new BoolValue(true)));
     }
     public override IDeepCloneable Clone(Cloner cloner) {
@@ -76,6 +64,5 @@
     protected override ISymbolicRegressionSolution CreateSolution(ISymbolicExpressionTree bestTree, double bestQuality) {
       var model = new SymbolicRegressionModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
-      if (ApplyLinearScaling.Value)
-        SymbolicRegressionModel.Scale(model, ProblemDataParameter.ActualValue);
+      if (ApplyLinearScalingParameter.ActualValue.Value) SymbolicRegressionModel.Scale(model, ProblemDataParameter.ActualValue, ProblemDataParameter.ActualValue.TargetVariable);
       return new SymbolicRegressionSolution(model, (IRegressionProblemData)ProblemDataParameter.ActualValue.Clone());
     }
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveTrainingParetoBestSolutionAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveTrainingParetoBestSolutionAnalyzer.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveTrainingParetoBestSolutionAnalyzer.cs	(revision 8915)
@@ -22,7 +22,5 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Data;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
@@ -34,24 +32,9 @@
   [StorableClass]
   public sealed class SymbolicRegressionSingleObjectiveTrainingParetoBestSolutionAnalyzer : SymbolicDataAnalysisSingleObjectiveTrainingParetoBestSolutionAnalyzer<IRegressionProblemData, ISymbolicRegressionSolution> {
-    private const string ApplyLinearScalingParameterName = "ApplyLinearScaling";
-    #region parameter properties
-    public IValueParameter<BoolValue> ApplyLinearScalingParameter {
-      get { return (IValueParameter<BoolValue>)Parameters[ApplyLinearScalingParameterName]; }
-    }
-    #endregion
-
-    #region properties
-    public BoolValue ApplyLinearScaling {
-      get { return ApplyLinearScalingParameter.Value; }
-    }
-    #endregion
 
     [StorableConstructor]
     private SymbolicRegressionSingleObjectiveTrainingParetoBestSolutionAnalyzer(bool deserializing) : base(deserializing) { }
     private SymbolicRegressionSingleObjectiveTrainingParetoBestSolutionAnalyzer(SymbolicRegressionSingleObjectiveTrainingParetoBestSolutionAnalyzer original, Cloner cloner) : base(original, cloner) { }
-    public SymbolicRegressionSingleObjectiveTrainingParetoBestSolutionAnalyzer()
-      : base() {
-      Parameters.Add(new ValueParameter<BoolValue>(ApplyLinearScalingParameterName, "Flag that indicates if the produced symbolic regression solution should be linearly scaled.", new BoolValue(true)));
-    }
+    public SymbolicRegressionSingleObjectiveTrainingParetoBestSolutionAnalyzer() : base() { }
     public override IDeepCloneable Clone(Cloner cloner) {
       return new SymbolicRegressionSingleObjectiveTrainingParetoBestSolutionAnalyzer(this, cloner);
@@ -60,6 +43,5 @@
     protected override ISymbolicRegressionSolution CreateSolution(ISymbolicExpressionTree bestTree) {
       var model = new SymbolicRegressionModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
-      if (ApplyLinearScaling.Value)
-        SymbolicRegressionModel.Scale(model, ProblemDataParameter.ActualValue);
+      if (ApplyLinearScalingParameter.ActualValue.Value) SymbolicRegressionModel.Scale(model, ProblemDataParameter.ActualValue, ProblemDataParameter.ActualValue.TargetVariable);
       return new SymbolicRegressionSolution(model, (IRegressionProblemData)ProblemDataParameter.ActualValue.Clone());
     }
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveValidationBestSolutionAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveValidationBestSolutionAnalyzer.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveValidationBestSolutionAnalyzer.cs	(revision 8915)
@@ -22,5 +22,4 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Data;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 using HeuristicLab.Parameters;
@@ -36,18 +35,8 @@
     ISymbolicDataAnalysisBoundedOperator {
     private const string EstimationLimitsParameterName = "EstimationLimits";
-    private const string ApplyLinearScalingParameterName = "ApplyLinearScaling";
 
     #region parameter properties
     public IValueLookupParameter<DoubleLimit> EstimationLimitsParameter {
       get { return (IValueLookupParameter<DoubleLimit>)Parameters[EstimationLimitsParameterName]; }
-    }
-    public IValueParameter<BoolValue> ApplyLinearScalingParameter {
-      get { return (IValueParameter<BoolValue>)Parameters[ApplyLinearScalingParameterName]; }
-    }
-    #endregion
-
-    #region properties
-    public BoolValue ApplyLinearScaling {
-      get { return ApplyLinearScalingParameter.Value; }
     }
     #endregion
@@ -59,5 +48,4 @@
       : base() {
       Parameters.Add(new ValueLookupParameter<DoubleLimit>(EstimationLimitsParameterName, "The lower and upper limit for the estimated values produced by the symbolic regression model."));
-      Parameters.Add(new ValueParameter<BoolValue>(ApplyLinearScalingParameterName, "Flag that indicates if the produced symbolic regression solution should be linearly scaled.", new BoolValue(true)));
     }
 
@@ -68,6 +56,5 @@
     protected override ISymbolicRegressionSolution CreateSolution(ISymbolicExpressionTree bestTree, double bestQuality) {
       var model = new SymbolicRegressionModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
-      if (ApplyLinearScaling.Value)
-        SymbolicRegressionModel.Scale(model, ProblemDataParameter.ActualValue);
+      if (ApplyLinearScalingParameter.ActualValue.Value) SymbolicRegressionModel.Scale(model, ProblemDataParameter.ActualValue, ProblemDataParameter.ActualValue.TargetVariable);
       return new SymbolicRegressionSolution(model, (IRegressionProblemData)ProblemDataParameter.ActualValue.Clone());
     }
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveValidationParetoBestSolutionAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveValidationParetoBestSolutionAnalyzer.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveValidationParetoBestSolutionAnalyzer.cs	(revision 8915)
@@ -22,7 +22,5 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Data;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
@@ -34,24 +32,9 @@
   [StorableClass]
   public sealed class SymbolicRegressionSingleObjectiveValidationParetoBestSolutionAnalyzer : SymbolicDataAnalysisSingleObjectiveValidationParetoBestSolutionAnalyzer<ISymbolicRegressionSolution, ISymbolicRegressionSingleObjectiveEvaluator, IRegressionProblemData> {
-    private const string ApplyLinearScalingParameterName = "ApplyLinearScaling";
-    #region parameter properties
-    public IValueParameter<BoolValue> ApplyLinearScalingParameter {
-      get { return (IValueParameter<BoolValue>)Parameters[ApplyLinearScalingParameterName]; }
-    }
-    #endregion
-
-    #region properties
-    public BoolValue ApplyLinearScaling {
-      get { return ApplyLinearScalingParameter.Value; }
-    }
-    #endregion
-
     [StorableConstructor]
     private SymbolicRegressionSingleObjectiveValidationParetoBestSolutionAnalyzer(bool deserializing) : base(deserializing) { }
     private SymbolicRegressionSingleObjectiveValidationParetoBestSolutionAnalyzer(SymbolicRegressionSingleObjectiveValidationParetoBestSolutionAnalyzer original, Cloner cloner) : base(original, cloner) { }
-    public SymbolicRegressionSingleObjectiveValidationParetoBestSolutionAnalyzer()
-      : base() {
-      Parameters.Add(new ValueParameter<BoolValue>(ApplyLinearScalingParameterName, "Flag that indicates if the produced symbolic regression solution should be linearly scaled.", new BoolValue(true)));
-    }
+    public SymbolicRegressionSingleObjectiveValidationParetoBestSolutionAnalyzer() : base() { }
+
     public override IDeepCloneable Clone(Cloner cloner) {
       return new SymbolicRegressionSingleObjectiveValidationParetoBestSolutionAnalyzer(this, cloner);
@@ -60,6 +43,5 @@
     protected override ISymbolicRegressionSolution CreateSolution(ISymbolicExpressionTree bestTree) {
       var model = new SymbolicRegressionModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
-      if (ApplyLinearScaling.Value)
-        SymbolicRegressionModel.Scale(model, ProblemDataParameter.ActualValue);
+      if (ApplyLinearScalingParameter.ActualValue.Value) SymbolicRegressionModel.Scale(model, ProblemDataParameter.ActualValue, ProblemDataParameter.ActualValue.TargetVariable);
       return new SymbolicRegressionSolution(model, (IRegressionProblemData)ProblemDataParameter.ActualValue.Clone());
     }
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionModel.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionModel.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionModel.cs	(revision 8915)
@@ -64,80 +64,9 @@
 
     public ISymbolicRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
-      return new SymbolicRegressionSolution(this, problemData);
+      return new SymbolicRegressionSolution(this, new RegressionProblemData(problemData));
     }
     IRegressionSolution IRegressionModel.CreateRegressionSolution(IRegressionProblemData problemData) {
       return CreateRegressionSolution(problemData);
     }
-
-    public static void Scale(SymbolicRegressionModel model, IRegressionProblemData problemData) {
-      var dataset = problemData.Dataset;
-      var targetVariable = problemData.TargetVariable;
-      var rows = problemData.TrainingIndices;
-      var estimatedValues = model.Interpreter.GetSymbolicExpressionTreeValues(model.SymbolicExpressionTree, dataset, rows);
-      var targetValues = dataset.GetDoubleValues(targetVariable, rows);
-      double alpha;
-      double beta;
-      OnlineCalculatorError errorState;
-      OnlineLinearScalingParameterCalculator.Calculate(estimatedValues, targetValues, out alpha, out beta, out errorState);
-      if (errorState != OnlineCalculatorError.None) return;
-
-      ConstantTreeNode alphaTreeNode = null;
-      ConstantTreeNode betaTreeNode = null;
-      // check if model has been scaled previously by analyzing the structure of the tree
-      var startNode = model.SymbolicExpressionTree.Root.GetSubtree(0);
-      if (startNode.GetSubtree(0).Symbol is Addition) {
-        var addNode = startNode.GetSubtree(0);
-        if (addNode.SubtreeCount == 2 && addNode.GetSubtree(0).Symbol is Multiplication && addNode.GetSubtree(1).Symbol is Constant) {
-          alphaTreeNode = addNode.GetSubtree(1) as ConstantTreeNode;
-          var mulNode = addNode.GetSubtree(0);
-          if (mulNode.SubtreeCount == 2 && mulNode.GetSubtree(1).Symbol is Constant) {
-            betaTreeNode = mulNode.GetSubtree(1) as ConstantTreeNode;
-          }
-        }
-      }
-      // if tree structure matches the structure necessary for linear scaling then reuse the existing tree nodes
-      if (alphaTreeNode != null && betaTreeNode != null) {
-        betaTreeNode.Value *= beta;
-        alphaTreeNode.Value *= beta;
-        alphaTreeNode.Value += alpha;
-      } else {
-        var mainBranch = startNode.GetSubtree(0);
-        startNode.RemoveSubtree(0);
-        var scaledMainBranch = MakeSum(MakeProduct(mainBranch, beta), alpha);
-        startNode.AddSubtree(scaledMainBranch);
-      }
-    }
-
-    private static ISymbolicExpressionTreeNode MakeSum(ISymbolicExpressionTreeNode treeNode, double alpha) {
-      if (alpha.IsAlmost(0.0)) {
-        return treeNode;
-      } else {
-        var addition = new Addition();
-        var node = addition.CreateTreeNode();
-        var alphaConst = MakeConstant(alpha);
-        node.AddSubtree(treeNode);
-        node.AddSubtree(alphaConst);
-        return node;
-      }
-    }
-
-    private static ISymbolicExpressionTreeNode MakeProduct(ISymbolicExpressionTreeNode treeNode, double beta) {
-      if (beta.IsAlmost(1.0)) {
-        return treeNode;
-      } else {
-        var multipliciation = new Multiplication();
-        var node = multipliciation.CreateTreeNode();
-        var betaConst = MakeConstant(beta);
-        node.AddSubtree(treeNode);
-        node.AddSubtree(betaConst);
-        return node;
-      }
-    }
-
-    private static ISymbolicExpressionTreeNode MakeConstant(double c) {
-      var node = (ConstantTreeNode)(new Constant()).CreateTreeNode();
-      node.Value = c;
-      return node;
-    }
   }
 }
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionSolution.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionSolution.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionSolution.cs	(revision 8915)
@@ -20,4 +20,5 @@
 #endregion
 
+using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -35,4 +36,13 @@
     private const string ModelLengthResultName = "Model Length";
     private const string ModelDepthResultName = "Model Depth";
+
+    private const string EstimationLimitsResultsResultName = "Estimation Limits Results";
+    private const string EstimationLimitsResultName = "Estimation Limits";
+    private const string TrainingUpperEstimationLimitHitsResultName = "Training Upper Estimation Limit Hits";
+    private const string TestLowerEstimationLimitHitsResultName = "Test Lower Estimation Limit Hits";
+    private const string TrainingLowerEstimationLimitHitsResultName = "Training Lower Estimation Limit Hits";
+    private const string TestUpperEstimationLimitHitsResultName = "Test Upper Estimation Limit Hits";
+    private const string TrainingNaNEvaluationsResultName = "Training NaN Evaluations";
+    private const string TestNaNEvaluationsResultName = "Test NaN Evaluations";
 
     public new ISymbolicRegressionModel Model {
@@ -53,4 +63,36 @@
     }
 
+    private ResultCollection EstimationLimitsResultCollection {
+      get { return (ResultCollection)this[EstimationLimitsResultsResultName].Value; }
+    }
+    public DoubleLimit EstimationLimits {
+      get { return (DoubleLimit)EstimationLimitsResultCollection[EstimationLimitsResultName].Value; }
+    }
+
+    public int TrainingUpperEstimationLimitHits {
+      get { return ((IntValue)EstimationLimitsResultCollection[TrainingUpperEstimationLimitHitsResultName].Value).Value; }
+      private set { ((IntValue)EstimationLimitsResultCollection[TrainingUpperEstimationLimitHitsResultName].Value).Value = value; }
+    }
+    public int TestUpperEstimationLimitHits {
+      get { return ((IntValue)EstimationLimitsResultCollection[TestUpperEstimationLimitHitsResultName].Value).Value; }
+      private set { ((IntValue)EstimationLimitsResultCollection[TestUpperEstimationLimitHitsResultName].Value).Value = value; }
+    }
+    public int TrainingLowerEstimationLimitHits {
+      get { return ((IntValue)EstimationLimitsResultCollection[TrainingLowerEstimationLimitHitsResultName].Value).Value; }
+      private set { ((IntValue)EstimationLimitsResultCollection[TrainingLowerEstimationLimitHitsResultName].Value).Value = value; }
+    }
+    public int TestLowerEstimationLimitHits {
+      get { return ((IntValue)EstimationLimitsResultCollection[TestLowerEstimationLimitHitsResultName].Value).Value; }
+      private set { ((IntValue)EstimationLimitsResultCollection[TestLowerEstimationLimitHitsResultName].Value).Value = value; }
+    }
+    public int TrainingNaNEvaluations {
+      get { return ((IntValue)EstimationLimitsResultCollection[TrainingNaNEvaluationsResultName].Value).Value; }
+      private set { ((IntValue)EstimationLimitsResultCollection[TrainingNaNEvaluationsResultName].Value).Value = value; }
+    }
+    public int TestNaNEvaluations {
+      get { return ((IntValue)EstimationLimitsResultCollection[TestNaNEvaluationsResultName].Value).Value; }
+      private set { ((IntValue)EstimationLimitsResultCollection[TestNaNEvaluationsResultName].Value).Value = value; }
+    }
+
     [StorableConstructor]
     private SymbolicRegressionSolution(bool deserializing) : base(deserializing) { }
@@ -62,4 +104,15 @@
       Add(new Result(ModelLengthResultName, "Length of the symbolic regression model.", new IntValue()));
       Add(new Result(ModelDepthResultName, "Depth of the symbolic regression model.", new IntValue()));
+
+      ResultCollection estimationLimitResults = new ResultCollection();
+      estimationLimitResults.Add(new Result(EstimationLimitsResultName, "", new DoubleLimit()));
+      estimationLimitResults.Add(new Result(TrainingUpperEstimationLimitHitsResultName, "", new IntValue()));
+      estimationLimitResults.Add(new Result(TestUpperEstimationLimitHitsResultName, "", new IntValue()));
+      estimationLimitResults.Add(new Result(TrainingLowerEstimationLimitHitsResultName, "", new IntValue()));
+      estimationLimitResults.Add(new Result(TestLowerEstimationLimitHitsResultName, "", new IntValue()));
+      estimationLimitResults.Add(new Result(TrainingNaNEvaluationsResultName, "", new IntValue()));
+      estimationLimitResults.Add(new Result(TestNaNEvaluationsResultName, "", new IntValue()));
+      Add(new Result(EstimationLimitsResultsResultName, "Results concerning the estimation limits of symbolic regression solution", estimationLimitResults));
+
       RecalculateResults();
     }
@@ -69,8 +122,38 @@
     }
 
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (!ContainsKey(EstimationLimitsResultsResultName)) {
+        ResultCollection estimationLimitResults = new ResultCollection();
+        estimationLimitResults.Add(new Result(EstimationLimitsResultName, "", new DoubleLimit()));
+        estimationLimitResults.Add(new Result(TrainingUpperEstimationLimitHitsResultName, "", new IntValue()));
+        estimationLimitResults.Add(new Result(TestUpperEstimationLimitHitsResultName, "", new IntValue()));
+        estimationLimitResults.Add(new Result(TrainingLowerEstimationLimitHitsResultName, "", new IntValue()));
+        estimationLimitResults.Add(new Result(TestLowerEstimationLimitHitsResultName, "", new IntValue()));
+        estimationLimitResults.Add(new Result(TrainingNaNEvaluationsResultName, "", new IntValue()));
+        estimationLimitResults.Add(new Result(TestNaNEvaluationsResultName, "", new IntValue()));
+        Add(new Result(EstimationLimitsResultsResultName, "Results concerning the estimation limits of symbolic regression solution", estimationLimitResults));
+        CalculateResults();
+      }
+    }
+
     protected override void RecalculateResults() {
       base.RecalculateResults();
+      CalculateResults();
+    }
+
+    private void CalculateResults() {
       ModelLength = Model.SymbolicExpressionTree.Length;
       ModelDepth = Model.SymbolicExpressionTree.Depth;
+
+      EstimationLimits.Lower = Model.LowerEstimationLimit;
+      EstimationLimits.Upper = Model.UpperEstimationLimit;
+
+      TrainingUpperEstimationLimitHits = EstimatedTrainingValues.Count(x => x.IsAlmost(Model.UpperEstimationLimit));
+      TestUpperEstimationLimitHits = EstimatedTestValues.Count(x => x.IsAlmost(Model.UpperEstimationLimit));
+      TrainingLowerEstimationLimitHits = EstimatedTrainingValues.Count(x => x.IsAlmost(Model.LowerEstimationLimit));
+      TestLowerEstimationLimitHits = EstimatedTestValues.Count(x => x.IsAlmost(Model.LowerEstimationLimit));
+      TrainingNaNEvaluations = Model.Interpreter.GetSymbolicExpressionTreeValues(Model.SymbolicExpressionTree, ProblemData.Dataset, ProblemData.TrainingIndices).Count(double.IsNaN);
+      TestNaNEvaluations = Model.Interpreter.GetSymbolicExpressionTreeValues(Model.SymbolicExpressionTree, ProblemData.Dataset, ProblemData.TestIndices).Count(double.IsNaN);
     }
   }
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Views-3.4.csproj
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Views-3.4.csproj	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Views-3.4.csproj	(revision 8915)
@@ -93,60 +93,80 @@
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="ALGLIB-3.5.0">
-      <HintPath>..\..\..\..\Trunk\sources\bin\ALGLIB-3.5.0.dll</HintPath>
+    <Reference Include="ALGLIB-3.6.0, Version=3.6.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\ALGLIB-3.6.0.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Collections-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Collections-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Common-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Common-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Common.Resources-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Common.Resources-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Core-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Core-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Core.Views-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Core.Views-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Data-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Data-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Data.Views-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Data.Views-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.MainForm-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.MainForm-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.MainForm.WindowsForms-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.MainForm.WindowsForms-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Operators-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Operators-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Optimization-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Optimization-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Optimization.Views-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Optimization.Views-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Parameters-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Parameters-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Persistence-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Persistence-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.PluginInfrastructure-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Problems.DataAnalysis-3.4">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Problems.DataAnalysis-3.4.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Visualization.ChartControlsExtensions-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Visualization.ChartControlsExtensions-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="System" />
@@ -255,4 +275,5 @@
       <Project>{423BD94F-963A-438E-BA45-3BB3D61CD03B}</Project>
       <Name>HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views-3.4</Name>
+      <Private>False</Private>
     </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Problems.DataAnalysis.Symbolic\3.4\HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj">
@@ -293,5 +314,5 @@
   -->
   <PropertyGroup>
-    <PreBuildEvent>set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+    <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
 set ProjectDir=$(ProjectDir)
 set SolutionDir=$(SolutionDir)
@@ -300,4 +321,10 @@
 call PreBuildEvent.cmd
 </PreBuildEvent>
+    <PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
+export ProjectDir=$(ProjectDir)
+export SolutionDir=$(SolutionDir)
+
+$SolutionDir/PreBuildEvent.sh
+</PreBuildEvent>
   </PropertyGroup>
 </Project>
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.Designer.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.Designer.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.Designer.cs	(revision 8915)
@@ -172,5 +172,4 @@
       this.treeChart.SymbolicExpressionTreeChanged += new System.EventHandler(this.treeChart_SymbolicExpressionTreeChanged);
       this.treeChart.SymbolicExpressionTreeNodeChanged += new System.EventHandler(this.treeChart_SymbolicExpressionTreeNodeChanged);
-      this.treeChart.SymbolicExpressionTreeNodeInserted += new System.EventHandler(this.treeChart_SymbolicExpressionTreeNodeInserted);
       this.treeChart.SymbolicExpressionTreeNodeClicked += new System.Windows.Forms.MouseEventHandler(this.treeChart_SymbolicExpressionTreeNodeClicked);
       this.treeChart.SymbolicExpressionTreeNodeDoubleClicked += new System.Windows.Forms.MouseEventHandler(this.treeChart_SymbolicExpressionTreeNodeDoubleClicked);
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicExpressionTreeChart.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicExpressionTreeChart.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicExpressionTreeChart.cs	(revision 8915)
@@ -147,5 +147,4 @@
 
     public event EventHandler SymbolicExpressionTreeNodeChanged;
-    public event EventHandler SymbolicExpressionTreeNodeInserted;
 
     private void OnChangeValueDialogValidated(object sender, EventArgs e) {
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/Plugin.cs.frame
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/Plugin.cs.frame	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/Plugin.cs.frame	(revision 8915)
@@ -29,5 +29,5 @@
   [PluginFile("HeuristicLab.Problems.DataAnalysis.Symbolic.Views-3.4.dll", PluginFileType.Assembly)]
   [PluginFile("displayModelFrame.html", PluginFileType.Data)]
-  [PluginDependency("HeuristicLab.ALGLIB", "3.5")]
+  [PluginDependency("HeuristicLab.ALGLIB", "3.6.0")]
   [PluginDependency("HeuristicLab.Collections", "3.3")]
   [PluginDependency("HeuristicLab.Common", "3.3")]
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/Symbols/VariableConditionView.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/Symbols/VariableConditionView.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/Symbols/VariableConditionView.cs	(revision 8915)
@@ -124,13 +124,10 @@
         RegisterVariableNamesViewContentEvents();
       } else {
-        var existingEntries = variableNamesView.Content.ToList();
-
         // temporarily deregister to prevent circular calling of events
         DeregisterVariableNamesViewContentEvents();
-        // add additional entries
-        foreach (var variableName in Content.VariableNames.Except(existingEntries.Select(x => x.Value)))
-          variableNamesView.Content.Add(new StringValue(variableName), true);
-        foreach (var oldEntry in existingEntries.Where(x => !Content.VariableNames.Contains(x.Value)))
-          variableNamesView.Content.Remove(oldEntry);
+        variableNamesView.Content.Clear();
+        foreach (var variableName in Content.AllVariableNames) {
+          variableNamesView.Content.Add(new StringValue(variableName), Content.VariableNames.Contains(variableName));
+        }
         RegisterVariableNamesViewContentEvents();
 
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/Symbols/VariableView.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/Symbols/VariableView.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/Symbols/VariableView.cs	(revision 8915)
@@ -92,4 +92,5 @@
     protected override void SetEnabledStateOfControls() {
       base.SetEnabledStateOfControls();
+      enabledCheckBox.Enabled = Content != null && Content.VariableNames.Any() && !Locked && !ReadOnly;
       weightInitializationMuTextBox.Enabled = Content != null;
       weightInitializationMuTextBox.ReadOnly = ReadOnly;
@@ -180,13 +181,10 @@
         RegisterVariableNamesViewContentEvents();
       } else {
-        var existingEntries = variableNamesView.Content.ToList();
-
         // temporarily deregister to prevent circular calling of events
         DeregisterVariableNamesViewContentEvents();
-        // add additional entries
-        foreach (var variableName in Content.VariableNames.Except(existingEntries.Select(x => x.Value)))
-          variableNamesView.Content.Add(new StringValue(variableName), true);
-        foreach (var oldEntry in existingEntries.Where(x => !Content.VariableNames.Contains(x.Value)))
-          variableNamesView.Content.Remove(oldEntry);
+        variableNamesView.Content.Clear();
+        foreach (var variableName in Content.AllVariableNames) {
+          variableNamesView.Content.Add(new StringValue(variableName), Content.VariableNames.Contains(variableName));
+        }
         RegisterVariableNamesViewContentEvents();
 
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisMultiObjectiveAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisMultiObjectiveAnalyzer.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisMultiObjectiveAnalyzer.cs	(revision 8915)
@@ -20,14 +20,9 @@
 #endregion
 
-using System.Collections.Generic;
-using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Data;
-using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-using HeuristicLab.Operators;
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.Optimization;
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
@@ -39,4 +34,5 @@
     private const string QualitiesParameterName = "Qualities";
     private const string MaximizationParameterName = "Maximization";
+    private const string ApplyLinearScalingParameterName = "ApplyLinearScaling";
     #region parameter properties
     public IScopeTreeLookupParameter<DoubleArray> QualitiesParameter {
@@ -45,4 +41,7 @@
     public ILookupParameter<BoolArray> MaximizationParameter {
       get { return (ILookupParameter<BoolArray>)Parameters[MaximizationParameterName]; }
+    }
+    public ILookupParameter<BoolValue> ApplyLinearScalingParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters[ApplyLinearScalingParameterName]; }
     }
     #endregion
@@ -64,4 +63,13 @@
       Parameters.Add(new ScopeTreeLookupParameter<DoubleArray>(QualitiesParameterName, "The qualities of the trees that should be analyzed."));
       Parameters.Add(new LookupParameter<BoolArray>(MaximizationParameterName, "The directions of optimization for each dimension."));
+      Parameters.Add(new LookupParameter<BoolValue>(ApplyLinearScalingParameterName, "Flag that indicates if the individual should be linearly scaled before evaluating."));
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (Parameters.ContainsKey(ApplyLinearScalingParameterName) && Parameters[ApplyLinearScalingParameterName] is LookupParameter<BoolValue>)
+        Parameters.Remove(ApplyLinearScalingParameterName);
+      if (!Parameters.ContainsKey(ApplyLinearScalingParameterName))
+        Parameters.Add(new LookupParameter<BoolValue>(ApplyLinearScalingParameterName, "Flag that indicates if the individual should be linearly scaled before evaluating."));
     }
   }
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectiveAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectiveAnalyzer.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectiveAnalyzer.cs	(revision 8915)
@@ -20,14 +20,9 @@
 #endregion
 
-using System.Collections.Generic;
-using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Data;
-using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-using HeuristicLab.Operators;
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.Optimization;
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
@@ -39,4 +34,6 @@
     private const string QualityParameterName = "Quality";
     private const string MaximizationParameterName = "Maximization";
+    private const string ApplyLinearScalingParameterName = "ApplyLinearScaling";
+
     #region parameter properties
     public IScopeTreeLookupParameter<DoubleValue> QualityParameter {
@@ -45,4 +42,7 @@
     public ILookupParameter<BoolValue> MaximizationParameter {
       get { return (ILookupParameter<BoolValue>)Parameters[MaximizationParameterName]; }
+    }
+    public ILookupParameter<BoolValue> ApplyLinearScalingParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters[ApplyLinearScalingParameterName]; }
     }
     #endregion
@@ -64,4 +64,13 @@
       Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>(QualityParameterName, "The qualities of the trees that should be analyzed."));
       Parameters.Add(new LookupParameter<BoolValue>(MaximizationParameterName, "The direction of optimization."));
+      Parameters.Add(new LookupParameter<BoolValue>(ApplyLinearScalingParameterName, "Flag that indicates if the individual should be linearly scaled before evaluating."));
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (Parameters.ContainsKey(ApplyLinearScalingParameterName) && !(Parameters[ApplyLinearScalingParameterName] is LookupParameter<BoolValue>))
+        Parameters.Remove(ApplyLinearScalingParameterName);
+      if (!Parameters.ContainsKey(ApplyLinearScalingParameterName))
+        Parameters.Add(new LookupParameter<BoolValue>(ApplyLinearScalingParameterName, "Flag that indicates if the individual should be linearly scaled before evaluating."));
     }
   }
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectiveTrainingBestSolutionAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectiveTrainingBestSolutionAnalyzer.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectiveTrainingBestSolutionAnalyzer.cs	(revision 8915)
@@ -85,6 +85,6 @@
 
       var results = ResultCollection;
-      if (TrainingBestSolutionQuality == null ||
-        IsBetter(bestQuality, TrainingBestSolutionQuality.Value, Maximization.Value)) {
+      if (bestTree != null && (TrainingBestSolutionQuality == null ||
+        IsBetter(bestQuality, TrainingBestSolutionQuality.Value, Maximization.Value))) {
         TrainingBestSolution = CreateSolution(bestTree, bestQuality);
         TrainingBestSolutionQuality = new DoubleValue(bestQuality);
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectiveValidationAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectiveValidationAnalyzer.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectiveValidationAnalyzer.cs	(revision 8915)
@@ -76,11 +76,11 @@
       : base(original, cloner) {
     }
-    public SymbolicDataAnalysisSingleObjectiveValidationAnalyzer()
-      : base() {
+
+    protected SymbolicDataAnalysisSingleObjectiveValidationAnalyzer(): base() {
       Parameters.Add(new LookupParameter<IRandom>(RandomParameterName, "The random generator."));
       Parameters.Add(new LookupParameter<U>(ProblemDataParameterName, "The problem data of the symbolic data analysis problem."));
       Parameters.Add(new LookupParameter<T>(EvaluatorParameterName, "The operator to use for fitness evaluation on the validation partition."));
       Parameters.Add(new LookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>(SymbolicDataAnalysisTreeInterpreterParameterName, "The interpreter for symbolic data analysis expression trees."));
-      Parameters.Add(new ValueLookupParameter<IntRange>(ValidationPartitionParameterName, "Thes validation partition."));
+      Parameters.Add(new ValueLookupParameter<IntRange>(ValidationPartitionParameterName, "The validation partition."));
       Parameters.Add(new ValueLookupParameter<PercentValue>(RelativeNumberOfEvaluatedSamplesParameterName, "The relative number of samples of the dataset partition, which should be randomly chosen for evaluation between the start and end index."));
       Parameters.Add(new ValueLookupParameter<PercentValue>(PercentageOfBestSolutionsParameterName,
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisVariableFrequencyAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisVariableFrequencyAnalyzer.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisVariableFrequencyAnalyzer.cs	(revision 8915)
@@ -109,5 +109,5 @@
       // update variable impacts matrix
       var orderedImpacts = (from row in datatable.Rows
-                            select new { Name = row.Name, Impact = datatable.Rows[row.Name].Values.Average() })
+                            select new { Name = row.Name, Impact = Math.Round(datatable.Rows[row.Name].Values.Average(), 3) })
                            .OrderByDescending(p => p.Impact)
                            .ToList();
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Evaluators/SymbolicDataAnalysisEvaluator.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Evaluators/SymbolicDataAnalysisEvaluator.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Evaluators/SymbolicDataAnalysisEvaluator.cs	(revision 8915)
@@ -44,4 +44,6 @@
     private const string EvaluationPartitionParameterName = "EvaluationPartition";
     private const string RelativeNumberOfEvaluatedSamplesParameterName = "RelativeNumberOfEvaluatedSamples";
+    private const string ApplyLinearScalingParameterName = "ApplyLinearScaling";
+    private const string ValidRowIndicatorParameterName = "ValidRowIndicator";
 
     public override bool CanChangeName { get { return false; } }
@@ -70,4 +72,10 @@
       get { return (IValueLookupParameter<PercentValue>)Parameters[RelativeNumberOfEvaluatedSamplesParameterName]; }
     }
+    public ILookupParameter<BoolValue> ApplyLinearScalingParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters[ApplyLinearScalingParameterName]; }
+    }
+    public IValueLookupParameter<StringValue> ValidRowIndicatorParameter {
+      get { return (IValueLookupParameter<StringValue>)Parameters[ValidRowIndicatorParameterName]; }
+    }
     #endregion
 
@@ -87,4 +95,16 @@
       Parameters.Add(new ValueLookupParameter<DoubleLimit>(EstimationLimitsParameterName, "The upper and lower limit that should be used as cut off value for the output values of symbolic data analysis trees."));
       Parameters.Add(new ValueLookupParameter<PercentValue>(RelativeNumberOfEvaluatedSamplesParameterName, "The relative number of samples of the dataset partition, which should be randomly chosen for evaluation between the start and end index."));
+      Parameters.Add(new LookupParameter<BoolValue>(ApplyLinearScalingParameterName, "Flag that indicates if the individual should be linearly scaled before evaluating."));
+      Parameters.Add(new ValueLookupParameter<StringValue>(ValidRowIndicatorParameterName, "An indicator variable in the data set that specifies which rows should be evaluated (those for which the indicator <> 0) (optional)."));
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (Parameters.ContainsKey(ApplyLinearScalingParameterName) && !(Parameters[ApplyLinearScalingParameterName] is LookupParameter<BoolValue>))
+        Parameters.Remove(ApplyLinearScalingParameterName);
+      if (!Parameters.ContainsKey(ApplyLinearScalingParameterName))
+        Parameters.Add(new LookupParameter<BoolValue>(ApplyLinearScalingParameterName, "Flag that indicates if the individual should be linearly scaled before evaluating."));
+      if (!Parameters.ContainsKey(ValidRowIndicatorParameterName))
+        Parameters.Add(new ValueLookupParameter<StringValue>(ValidRowIndicatorParameterName, "An indicator variable in the data set that specifies which rows should be evaluated (those for which the indicator <> 0) (optional)."));
     }
 
@@ -94,6 +114,4 @@
 
     protected IEnumerable<int> GenerateRowsToEvaluate(double percentageOfRows) {
-
-
       IEnumerable<int> rows;
       int samplesStart = EvaluationPartitionParameter.ActualValue.Start;
@@ -101,5 +119,4 @@
       int testPartitionStart = ProblemDataParameter.ActualValue.TestPartition.Start;
       int testPartitionEnd = ProblemDataParameter.ActualValue.TestPartition.End;
-
       if (samplesEnd < samplesStart) throw new ArgumentException("Start value is larger than end value.");
 
@@ -113,5 +130,55 @@
       }
 
-      return rows.Where(i => i < testPartitionStart || testPartitionEnd <= i);
+      rows = rows.Where(i => i < testPartitionStart || testPartitionEnd <= i);
+      if (ValidRowIndicatorParameter.ActualValue != null) {
+        string indicatorVar = ValidRowIndicatorParameter.ActualValue.Value;
+        var problemData = ProblemDataParameter.ActualValue;
+        var indicatorRow = problemData.Dataset.GetReadOnlyDoubleValues(indicatorVar);
+        rows = rows.Where(r => !indicatorRow[r].IsAlmost(0.0));
+      }
+      return rows;
+    }
+
+    [ThreadStatic]
+    private static double[] cache;
+    protected static void CalculateWithScaling(IEnumerable<double> targetValues, IEnumerable<double> estimatedValues,
+      double lowerEstimationLimit, double upperEstimationLimit,
+      IOnlineCalculator calculator, int maxRows) {
+      if (cache == null || cache.GetLength(0) < maxRows) {
+        cache = new double[maxRows];
+      }
+
+      // calculate linear scaling
+      // the static methods of the calculator are not used because the evaluated values should be cached for performance reasons
+      int i = 0;
+      var linearScalingCalculator = new OnlineLinearScalingParameterCalculator();
+      var targetValuesEnumerator = targetValues.GetEnumerator();
+      var estimatedValuesEnumerator = estimatedValues.GetEnumerator();
+      while (targetValuesEnumerator.MoveNext() & estimatedValuesEnumerator.MoveNext()) {
+        double target = targetValuesEnumerator.Current;
+        double estimated = estimatedValuesEnumerator.Current;
+        cache[i] = estimated;
+        if (!double.IsNaN(estimated) && !double.IsInfinity(estimated))
+          linearScalingCalculator.Add(estimated, target);
+        i++;
+      }
+      if (linearScalingCalculator.ErrorState == OnlineCalculatorError.None && (targetValuesEnumerator.MoveNext() || estimatedValuesEnumerator.MoveNext()))
+        throw new ArgumentException("Number of elements in target and estimated values enumeration do not match.");
+
+      double alpha = linearScalingCalculator.Alpha;
+      double beta = linearScalingCalculator.Beta;
+      if (linearScalingCalculator.ErrorState != OnlineCalculatorError.None) {
+        alpha = 0.0;
+        beta = 1.0;
+      }
+
+      //calculate the quality by using the passed online calculator
+      targetValuesEnumerator = targetValues.GetEnumerator();
+      var scaledBoundedEstimatedValuesEnumerator = Enumerable.Range(0, i).Select(x => cache[x] * beta + alpha)
+        .LimitToRange(lowerEstimationLimit, upperEstimationLimit).GetEnumerator();
+
+      while (targetValuesEnumerator.MoveNext() & scaledBoundedEstimatedValuesEnumerator.MoveNext()) {
+        calculator.Add(targetValuesEnumerator.Current, scaledBoundedEstimatedValuesEnumerator.Current);
+      }
     }
   }
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionLatexFormatter.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionLatexFormatter.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionLatexFormatter.cs	(revision 8915)
@@ -33,5 +33,6 @@
   [StorableClass]
   public sealed class SymbolicDataAnalysisExpressionLatexFormatter : NamedItem, ISymbolicExpressionTreeStringFormatter {
-    private List<double> constants;
+    private readonly List<double> constants;
+    private int targetCount;
     private int currentLag;
 
@@ -98,5 +99,5 @@
       } else if (node.Symbol is Division) {
         if (node.SubtreeCount == 1) {
-          strBuilder.Append(@" \cfrac{1}{");
+          strBuilder.Append(@" \cfrac{1");
         } else {
           strBuilder.Append(@" \cfrac{ ");
@@ -196,5 +197,5 @@
         strBuilder.Append(invokeNode.Symbol.FunctionName + @" \left( ");
       } else if (node.Symbol is StartSymbol) {
-        strBuilder.Append("Result & = ");
+        strBuilder.Append("target_" + (targetCount++) + "(t) & = ");
       } else if (node.Symbol is Argument) {
         var argSym = node.Symbol as Argument;
@@ -301,5 +302,6 @@
         strBuilder.Append(" , ");
       } else if (node.Symbol is StartSymbol) {
-        strBuilder.Append(@"\\" + Environment.NewLine + " & ");
+        strBuilder.Append(@"\\" + Environment.NewLine);
+        strBuilder.Append("target_" + (targetCount++) + "(t) & = ");
       } else if (node.Symbol is Power) {
         strBuilder.Append(@"\right) ^ { \operatorname{round} \left(");
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Grammars/FullFunctionalExpressionGrammar.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Grammars/FullFunctionalExpressionGrammar.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Grammars/FullFunctionalExpressionGrammar.cs	(revision 8915)
@@ -116,8 +116,11 @@
       var laggedVariable = new LaggedVariable();
       laggedVariable.InitialFrequency = 0.0;
+      var autoregressiveVariable = new AutoregressiveTargetVariable();
+      autoregressiveVariable.InitialFrequency = 0.0;
+      autoregressiveVariable.Enabled = false;
 
       var allSymbols = new List<Symbol>() { add, sub, mul, div, mean, sin, cos, tan, log, square, pow, sqrt, root, exp,
         airyA, airyB, bessel, cosineIntegral, dawson, erf, expIntegralEi, fresnelCosineIntegral, fresnelSineIntegral, gamma, hypCosineIntegral, hypSineIntegral, norm, psi, sineIntegral,
-        @if, gt, lt, and, or, not, timeLag, integral, derivative, constant, variableSymbol, laggedVariable, variableCondition };
+        @if, gt, lt, and, or, not, timeLag, integral, derivative, constant, variableSymbol, laggedVariable,autoregressiveVariable, variableCondition };
       var unaryFunctionSymbols = new List<Symbol>() { square, sqrt, sin, cos, tan, log, exp, not, timeLag, integral, derivative,
         airyA, airyB, bessel, cosineIntegral, dawson, erf, expIntegralEi, fresnelCosineIntegral, fresnelSineIntegral, gamma, hypCosineIntegral, hypSineIntegral, norm, psi, sineIntegral
@@ -126,5 +129,5 @@
       var binaryFunctionSymbols = new List<Symbol>() { pow, root, gt, lt, variableCondition };
       var ternarySymbols = new List<Symbol>() { add, sub, mul, div, mean, and, or };
-      var terminalSymbols = new List<Symbol>() { variableSymbol, constant, laggedVariable };
+      var terminalSymbols = new List<Symbol>() { variableSymbol, constant, laggedVariable, autoregressiveVariable };
 
       foreach (var symb in allSymbols)
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Grammars/TypeCoherentExpressionGrammar.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Grammars/TypeCoherentExpressionGrammar.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Grammars/TypeCoherentExpressionGrammar.cs	(revision 8915)
@@ -104,4 +104,5 @@
       var variableSymbol = new Variable();
       var laggedVariable = new LaggedVariable();
+      var autoregressiveVariable = new AutoregressiveTargetVariable();
       #endregion
 
@@ -122,5 +123,5 @@
       var conditionalSymbols = new GroupSymbol(ConditionalSymbolsName, new List<ISymbol> { conditionSymbols, comparisonSymbols, booleanOperationSymbols });
 
-      var timeSeriesSymbols = new GroupSymbol(TimeSeriesSymbolsName, new List<ISymbol> { timeLag, integral, derivative, laggedVariable });
+      var timeSeriesSymbols = new GroupSymbol(TimeSeriesSymbolsName, new List<ISymbol> { timeLag, integral, derivative, laggedVariable, autoregressiveVariable });
       #endregion
 
@@ -152,4 +153,5 @@
       SetSubtreeCount(derivative, 1, 1);
       SetSubtreeCount(laggedVariable, 0, 0);
+      SetSubtreeCount(autoregressiveVariable, 0, 0);
       #endregion
 
@@ -225,4 +227,17 @@
       Symbols.First(s => s.Name == TimeSeriesSymbolsName).Enabled = false;
     }
+
+    public void ConfigureAsDefaultTimeSeriesPrognosisGrammar() {
+      Symbols.First(s => s is Average).Enabled = false;
+      Symbols.First(s => s.Name == TrigonometricFunctionsName).Enabled = false;
+      Symbols.First(s => s.Name == PowerFunctionsName).Enabled = false;
+      Symbols.First(s => s.Name == ConditionalSymbolsName).Enabled = false;
+      Symbols.First(s => s.Name == SpecialFunctionsName).Enabled = false;
+
+      Symbols.First(s => s.Name == TimeSeriesSymbolsName).Enabled = true;
+      Symbols.First(s => s is Derivative).Enabled = false;
+      Symbols.First(s => s is Integral).Enabled = false;
+      Symbols.First(s => s is TimeLag).Enabled = false;
+    }
   }
 }
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj	(revision 8915)
@@ -93,54 +93,72 @@
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="ALGLIB-3.5.0">
-      <HintPath>..\..\..\..\Trunk\sources\bin\ALGLIB-3.5.0.dll</HintPath>
+    <Reference Include="ALGLIB-3.6.0, Version=3.6.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\ALGLIB-3.6.0.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Analysis-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Analysis-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Collections-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Collections-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Common-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Common-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Common.Resources-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Common.Resources-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Core-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Core-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Data-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Data-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Operators-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Operators-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Optimization-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Optimization-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Optimization.Operators-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Optimization.Operators-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Parameters-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Parameters-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Persistence-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Persistence-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.PluginInfrastructure-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Problems.DataAnalysis-3.4">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Problems.DataAnalysis-3.4.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Problems.Instances-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Problems.Instances-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Random-3.3">
       <HintPath>..\..\..\..\Trunk\sources\bin\HeuristicLab.Random-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="System" />
@@ -187,6 +205,9 @@
     <Compile Include="Crossovers\SymbolicDataAnalysisExpressionSemanticSimilarityCrossover.cs" />
     <Compile Include="Interfaces\ISymbolicDataAnalysisExpressionCrossover.cs" />
+    <Compile Include="Interpreter\InterpreterState.cs" />
+    <Compile Include="Interpreter\OpCodes.cs" />
+    <Compile Include="Interpreter\SymbolicDataAnalysisExpressionTreeILEmittingInterpreter.cs" />
+    <Compile Include="Interpreter\SymbolicDataAnalysisExpressionTreeInterpreter.cs" />
     <Compile Include="Plugin.cs" />
-    <Compile Include="SymbolicDataAnalysisExpressionTreeILEmittingInterpreter.cs" />
     <Compile Include="Formatters\SymbolicDataAnalysisExpressionLatexFormatter.cs" />
     <Compile Include="Formatters\SymbolicDataAnalysisExpressionMATLABFormatter.cs" />
@@ -206,10 +227,10 @@
     <Compile Include="Interfaces\ISymbolicDataAnalysisAnalyzer.cs" />
     <Compile Include="SymbolicDataAnalysisSingleObjectiveProblem.cs" />
-    <Compile Include="SymbolicDataAnalysisExpressionTreeInterpreter.cs" />
     <Compile Include="SymbolicDataAnalysisExpressionTreeSimplifier.cs" />
     <Compile Include="SymbolicDataAnalysisProblem.cs" />
-    <Compile Include="SymbolicDataAnalysisSolutionValuesCalculator.cs" />
+    <Compile Include="SymbolicDataAnalysisSolutionImpactValuesCalculator.cs" />
     <Compile Include="Symbols\Addition.cs" />
     <Compile Include="Symbols\And.cs" />
+    <Compile Include="Symbols\AutoregressiveVariable.cs" />
     <Compile Include="Symbols\Average.cs" />
     <Compile Include="Symbols\Constant.cs" />
@@ -301,5 +322,5 @@
   -->
   <PropertyGroup>
-    <PreBuildEvent>set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+    <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
 set ProjectDir=$(ProjectDir)
 set SolutionDir=$(SolutionDir)
@@ -308,4 +329,10 @@
 call PreBuildEvent.cmd
 </PreBuildEvent>
+    <PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
+export ProjectDir=$(ProjectDir)
+export SolutionDir=$(SolutionDir)
+
+$SolutionDir/PreBuildEvent.sh
+</PreBuildEvent>
   </PropertyGroup>
 </Project>
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/ISymbolicDataAnalysisEvaluator.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/ISymbolicDataAnalysisEvaluator.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/ISymbolicDataAnalysisEvaluator.cs	(revision 8915)
@@ -29,4 +29,5 @@
     IValueLookupParameter<IntRange> EvaluationPartitionParameter { get; }
     IValueLookupParameter<PercentValue> RelativeNumberOfEvaluatedSamplesParameter { get; }
+    ILookupParameter<BoolValue> ApplyLinearScalingParameter { get; }
 
     IValueLookupParameter<T> ProblemDataParameter { get; }
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/ISymbolicDataAnalysisMultiObjectiveAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/ISymbolicDataAnalysisMultiObjectiveAnalyzer.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/ISymbolicDataAnalysisMultiObjectiveAnalyzer.cs	(revision 8915)
@@ -21,11 +21,9 @@
 using HeuristicLab.Core;
 using HeuristicLab.Data;
-using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-using HeuristicLab.Optimization;
-using HeuristicLab.Parameters;
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
   public interface ISymbolicDataAnalysisMultiObjectiveAnalyzer : ISymbolicDataAnalysisAnalyzer {
     IScopeTreeLookupParameter<DoubleArray> QualitiesParameter { get; }
     ILookupParameter<BoolArray> MaximizationParameter { get; }
+    ILookupParameter<BoolValue> ApplyLinearScalingParameter { get; }
 
   }
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/ISymbolicDataAnalysisSingleObjectiveAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/ISymbolicDataAnalysisSingleObjectiveAnalyzer.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/ISymbolicDataAnalysisSingleObjectiveAnalyzer.cs	(revision 8915)
@@ -28,4 +28,5 @@
     IScopeTreeLookupParameter<DoubleValue> QualityParameter { get; }
     ILookupParameter<BoolValue> MaximizationParameter { get; }
+    ILookupParameter<BoolValue> ApplyLinearScalingParameter { get; }
   }
 }
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Plugin.cs.frame
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Plugin.cs.frame	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Plugin.cs.frame	(revision 8915)
@@ -28,5 +28,5 @@
   [Plugin("HeuristicLab.Problems.DataAnalysis.Symbolic","Provides base classes for symbolic data analysis tasks.", "3.4.3.$WCREV$")]
   [PluginFile("HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.dll", PluginFileType.Assembly)]
-  [PluginDependency("HeuristicLab.ALGLIB", "3.5.0")]
+  [PluginDependency("HeuristicLab.ALGLIB", "3.6.0")]
   [PluginDependency("HeuristicLab.Analysis", "3.3")]
   [PluginDependency("HeuristicLab.Collections", "3.3")]
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeSimplifier.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeSimplifier.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeSimplifier.cs	(revision 8915)
@@ -52,4 +52,7 @@
     private GreaterThan gtSymbol = new GreaterThan();
     private LessThan ltSymbol = new LessThan();
+    private Integral integralSymbol = new Integral();
+    private LaggedVariable laggedVariableSymbol = new LaggedVariable();
+    private TimeLag timeLagSymbol = new TimeLag();
 
     public ISymbolicExpressionTree Simplify(ISymbolicExpressionTree originalTree) {
@@ -182,4 +185,12 @@
     private bool IsConstant(ISymbolicExpressionTreeNode node) {
       return node.Symbol is Constant;
+    }
+
+    // dynamic
+    private bool IsTimeLag(ISymbolicExpressionTreeNode node) {
+      return node.Symbol is TimeLag;
+    }
+    private bool IsIntegral(ISymbolicExpressionTreeNode node) {
+      return node.Symbol is Integral;
     }
 
@@ -234,4 +245,8 @@
       } else if (IsNot(original)) {
         return SimplifyNot(original);
+      } else if (IsTimeLag(original)) {
+        return SimplifyTimeLag(original);
+      } else if (IsIntegral(original)) {
+        return SimplifyIntegral(original);
       } else {
         return SimplifyAny(original);
@@ -376,7 +391,47 @@
       return MakePower(GetSimplifiedTree(original.GetSubtree(0)), GetSimplifiedTree(original.GetSubtree(1)));
     }
+    private ISymbolicExpressionTreeNode SimplifyTimeLag(ISymbolicExpressionTreeNode original) {
+      var laggedTreeNode = original as ILaggedTreeNode;
+      var simplifiedSubtree = GetSimplifiedTree(original.GetSubtree(0));
+      if (!ContainsVariableCondition(simplifiedSubtree)) {
+        return AddLagToDynamicNodes(simplifiedSubtree, laggedTreeNode.Lag);
+      } else {
+        return MakeTimeLag(simplifiedSubtree, laggedTreeNode.Lag);
+      }
+    }
+    private ISymbolicExpressionTreeNode SimplifyIntegral(ISymbolicExpressionTreeNode original) {
+      var laggedTreeNode = original as ILaggedTreeNode;
+      var simplifiedSubtree = GetSimplifiedTree(original.GetSubtree(0));
+      if (IsConstant(simplifiedSubtree)) {
+        return GetSimplifiedTree(MakeProduct(simplifiedSubtree, MakeConstant(-laggedTreeNode.Lag)));
+      } else {
+        return MakeIntegral(simplifiedSubtree, laggedTreeNode.Lag);
+      }
+    }
+
     #endregion
 
     #region low level tree restructuring
+    private ISymbolicExpressionTreeNode MakeTimeLag(ISymbolicExpressionTreeNode subtree, int lag) {
+      if (lag == 0) return subtree;
+      if (IsConstant(subtree)) return subtree;
+      var lagNode = (LaggedTreeNode)timeLagSymbol.CreateTreeNode();
+      lagNode.Lag = lag;
+      lagNode.AddSubtree(subtree);
+      return lagNode;
+    }
+
+    private ISymbolicExpressionTreeNode MakeIntegral(ISymbolicExpressionTreeNode subtree, int lag) {
+      if (lag == 0) return subtree;
+      else if (lag == -1 || lag == 1) {
+        return MakeSum(subtree, AddLagToDynamicNodes((ISymbolicExpressionTreeNode)subtree.Clone(), lag));
+      } else {
+        var node = (LaggedTreeNode)integralSymbol.CreateTreeNode();
+        node.Lag = lag;
+        node.AddSubtree(subtree);
+        return node;
+      }
+    }
+
     private ISymbolicExpressionTreeNode MakeNot(ISymbolicExpressionTreeNode t) {
       if (IsConstant(t)) {
@@ -847,4 +902,32 @@
 
     #region helper functions
+    private bool ContainsVariableCondition(ISymbolicExpressionTreeNode node) {
+      if (node.Symbol is VariableCondition) return true;
+      foreach (var subtree in node.Subtrees)
+        if (ContainsVariableCondition(subtree)) return true;
+      return false;
+    }
+
+    private ISymbolicExpressionTreeNode AddLagToDynamicNodes(ISymbolicExpressionTreeNode node, int lag) {
+      var laggedTreeNode = node as ILaggedTreeNode;
+      var variableNode = node as VariableTreeNode;
+      var variableConditionNode = node as VariableConditionTreeNode;
+      if (laggedTreeNode != null)
+        laggedTreeNode.Lag += lag;
+      else if (variableNode != null) {
+        var laggedVariableNode = (LaggedVariableTreeNode)laggedVariableSymbol.CreateTreeNode();
+        laggedVariableNode.Lag = lag;
+        laggedVariableNode.VariableName = variableNode.VariableName;
+        return laggedVariableNode;
+      } else if (variableConditionNode != null) {
+        throw new NotSupportedException("Removal of time lags around variable condition symbols is not allowed.");
+      }
+      var subtrees = new List<ISymbolicExpressionTreeNode>(node.Subtrees);
+      while (node.SubtreeCount > 0) node.RemoveSubtree(0);
+      foreach (var subtree in subtrees) {
+        node.AddSubtree(AddLagToDynamicNodes(subtree, lag));
+      }
+      return node;
+    }
 
     private bool AreSameVariable(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisModel.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisModel.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisModel.cs	(revision 8915)
@@ -20,4 +20,5 @@
 #endregion
 
+using System;
 using System.Drawing;
 using HeuristicLab.Common;
@@ -66,4 +67,87 @@
       this.interpreter = interpreter;
     }
+
+    #region Scaling
+    public static void Scale(ISymbolicDataAnalysisModel model, IDataAnalysisProblemData problemData, string targetVariable) {
+      var dataset = problemData.Dataset;
+      var rows = problemData.TrainingIndices;
+      var estimatedValues = model.Interpreter.GetSymbolicExpressionTreeValues(model.SymbolicExpressionTree, dataset, rows);
+      var targetValues = dataset.GetDoubleValues(targetVariable, rows);
+
+      var linearScalingCalculator = new OnlineLinearScalingParameterCalculator();
+      var targetValuesEnumerator = targetValues.GetEnumerator();
+      var estimatedValuesEnumerator = estimatedValues.GetEnumerator();
+      while (targetValuesEnumerator.MoveNext() & estimatedValuesEnumerator.MoveNext()) {
+        double target = targetValuesEnumerator.Current;
+        double estimated = estimatedValuesEnumerator.Current;
+        if (!double.IsNaN(estimated) && !double.IsInfinity(estimated))
+          linearScalingCalculator.Add(estimated, target);
+      }
+      if (linearScalingCalculator.ErrorState == OnlineCalculatorError.None && (targetValuesEnumerator.MoveNext() || estimatedValuesEnumerator.MoveNext()))
+        throw new ArgumentException("Number of elements in target and estimated values enumeration do not match.");
+
+      double alpha = linearScalingCalculator.Alpha;
+      double beta = linearScalingCalculator.Beta;
+      if (linearScalingCalculator.ErrorState != OnlineCalculatorError.None) return;
+
+      ConstantTreeNode alphaTreeNode = null;
+      ConstantTreeNode betaTreeNode = null;
+      // check if model has been scaled previously by analyzing the structure of the tree
+      var startNode = model.SymbolicExpressionTree.Root.GetSubtree(0);
+      if (startNode.GetSubtree(0).Symbol is Addition) {
+        var addNode = startNode.GetSubtree(0);
+        if (addNode.SubtreeCount == 2 && addNode.GetSubtree(0).Symbol is Multiplication && addNode.GetSubtree(1).Symbol is Constant) {
+          alphaTreeNode = addNode.GetSubtree(1) as ConstantTreeNode;
+          var mulNode = addNode.GetSubtree(0);
+          if (mulNode.SubtreeCount == 2 && mulNode.GetSubtree(1).Symbol is Constant) {
+            betaTreeNode = mulNode.GetSubtree(1) as ConstantTreeNode;
+          }
+        }
+      }
+      // if tree structure matches the structure necessary for linear scaling then reuse the existing tree nodes
+      if (alphaTreeNode != null && betaTreeNode != null) {
+        betaTreeNode.Value *= beta;
+        alphaTreeNode.Value *= beta;
+        alphaTreeNode.Value += alpha;
+      } else {
+        var mainBranch = startNode.GetSubtree(0);
+        startNode.RemoveSubtree(0);
+        var scaledMainBranch = MakeSum(MakeProduct(mainBranch, beta), alpha);
+        startNode.AddSubtree(scaledMainBranch);
+      }
+    }
+
+    private static ISymbolicExpressionTreeNode MakeSum(ISymbolicExpressionTreeNode treeNode, double alpha) {
+      if (alpha.IsAlmost(0.0)) {
+        return treeNode;
+      } else {
+        var addition = new Addition();
+        var node = addition.CreateTreeNode();
+        var alphaConst = MakeConstant(alpha);
+        node.AddSubtree(treeNode);
+        node.AddSubtree(alphaConst);
+        return node;
+      }
+    }
+
+    private static ISymbolicExpressionTreeNode MakeProduct(ISymbolicExpressionTreeNode treeNode, double beta) {
+      if (beta.IsAlmost(1.0)) {
+        return treeNode;
+      } else {
+        var multipliciation = new Multiplication();
+        var node = multipliciation.CreateTreeNode();
+        var betaConst = MakeConstant(beta);
+        node.AddSubtree(treeNode);
+        node.AddSubtree(betaConst);
+        return node;
+      }
+    }
+
+    private static ISymbolicExpressionTreeNode MakeConstant(double c) {
+      var node = (ConstantTreeNode)(new Constant()).CreateTreeNode();
+      node.Value = c;
+      return node;
+    }
+    #endregion
   }
 }
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisProblem.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisProblem.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisProblem.cs	(revision 8915)
@@ -53,4 +53,5 @@
     private const string FitnessCalculationPartitionParameterName = "FitnessCalculationPartition";
     private const string ValidationPartitionParameterName = "ValidationPartition";
+    private const string ApplyLinearScalingParameterName = "ApplyLinearScaling";
 
     private const string ProblemDataParameterDescription = "";
@@ -64,4 +65,5 @@
     private const string FitnessCalculationPartitionParameterDescription = "The partition of the problem data training partition, that should be used to calculate the fitness of an individual.";
     private const string ValidationPartitionParameterDescription = "The partition of the problem data training partition, that should be used to select the best model from (optional).";
+    private const string ApplyLinearScalingParameterDescription = "Flag that indicates if the individual should be linearly scaled before evaluating.";
     #endregion
 
@@ -100,4 +102,7 @@
       get { return (IFixedValueParameter<IntRange>)Parameters[ValidationPartitionParameterName]; }
     }
+    public IFixedValueParameter<BoolValue> ApplyLinearScalingParameter {
+      get { return (IFixedValueParameter<BoolValue>)Parameters[ApplyLinearScalingParameterName]; }
+    }
     #endregion
 
@@ -144,4 +149,7 @@
     public IntRange ValidationPartition {
       get { return ValidationPartitionParameter.Value; }
+    }
+    public BoolValue ApplyLinearScaling {
+      get { return ApplyLinearScalingParameter.Value; }
     }
     #endregion
@@ -151,4 +159,14 @@
     [StorableHook(HookType.AfterDeserialization)]
     private void AfterDeserialization() {
+      if (!Parameters.ContainsKey(ApplyLinearScalingParameterName)) {
+        Parameters.Add(new FixedValueParameter<BoolValue>(ApplyLinearScalingParameterName, ApplyLinearScalingParameterDescription, new BoolValue(false)));
+        ApplyLinearScalingParameter.Hidden = true;
+
+        //it is assumed that for all symbolic regression algorithms linear scaling was set to true
+        //there is no possibility to determine the previous value of the parameter as it was stored in the evaluator
+        if (GetType().Name.Contains("SymbolicRegression"))
+          ApplyLinearScaling.Value = true;
+      }
+
       RegisterEventHandlers();
     }
@@ -170,8 +188,10 @@
       Parameters.Add(new FixedValueParameter<IntRange>(ValidationPartitionParameterName, ValidationPartitionParameterDescription));
       Parameters.Add(new FixedValueParameter<PercentValue>(RelativeNumberOfEvaluatedSamplesParameterName, RelativeNumberOfEvaluatedSamplesParameterDescription, new PercentValue(1)));
+      Parameters.Add(new FixedValueParameter<BoolValue>(ApplyLinearScalingParameterName, ApplyLinearScalingParameterDescription, new BoolValue(false)));
 
       SymbolicExpressionTreeInterpreterParameter.Hidden = true;
       MaximumFunctionArgumentsParameter.Hidden = true;
       MaximumFunctionDefinitionsParameter.Hidden = true;
+      ApplyLinearScalingParameter.Hidden = true;
 
       SymbolicExpressionTreeGrammar = new TypeCoherentExpressionGrammar();
@@ -191,8 +211,8 @@
       SymbolicExpressionTreeGrammar.MaximumFunctionDefinitions = MaximumFunctionDefinitions.Value;
       foreach (var varSymbol in SymbolicExpressionTreeGrammar.Symbols.OfType<HeuristicLab.Problems.DataAnalysis.Symbolic.Variable>()) {
-        if (!varSymbol.Fixed) varSymbol.VariableNames = ProblemData.AllowedInputVariables;
+        if (!varSymbol.Fixed) varSymbol.AllVariableNames = ProblemData.AllowedInputVariables;
       }
       foreach (var varSymbol in SymbolicExpressionTreeGrammar.Symbols.OfType<HeuristicLab.Problems.DataAnalysis.Symbolic.VariableCondition>()) {
-        if (!varSymbol.Fixed) varSymbol.VariableNames = ProblemData.AllowedInputVariables;
+        if (!varSymbol.Fixed) varSymbol.AllVariableNames = ProblemData.AllowedInputVariables;
       }
     }
@@ -274,13 +294,13 @@
 
       foreach (var op in operators.OfType<ISymbolicExpressionTreeGrammarBasedOperator>()) {
-        op.SymbolicExpressionTreeGrammarParameter.ActualName = SymbolicExpressionTreeGrammarParameterName;
+        op.SymbolicExpressionTreeGrammarParameter.ActualName = SymbolicExpressionTreeGrammarParameter.Name;
       }
       foreach (var op in operators.OfType<ISymbolicExpressionTreeSizeConstraintOperator>()) {
-        op.MaximumSymbolicExpressionTreeDepthParameter.ActualName = MaximumSymbolicExpressionTreeDepthParameterName;
-        op.MaximumSymbolicExpressionTreeLengthParameter.ActualName = MaximumSymbolicExpressionTreeLengthParameterName;
+        op.MaximumSymbolicExpressionTreeDepthParameter.ActualName = MaximumSymbolicExpressionTreeDepthParameter.Name;
+        op.MaximumSymbolicExpressionTreeLengthParameter.ActualName = MaximumSymbolicExpressionTreeLengthParameter.Name;
       }
       foreach (var op in operators.OfType<ISymbolicExpressionTreeArchitectureAlteringOperator>()) {
-        op.MaximumFunctionArgumentsParameter.ActualName = MaximumFunctionArgumentsParameterName;
-        op.MaximumFunctionDefinitionsParameter.ActualName = MaximumFunctionDefinitionsParameterName;
+        op.MaximumFunctionArgumentsParameter.ActualName = MaximumFunctionArgumentsParameter.Name;
+        op.MaximumFunctionDefinitionsParameter.ActualName = MaximumFunctionDefinitionsParameter.Name;
       }
       foreach (var op in operators.OfType<ISymbolicDataAnalysisEvaluator<T>>()) {
@@ -289,4 +309,5 @@
         op.EvaluationPartitionParameter.ActualName = FitnessCalculationPartitionParameter.Name;
         op.RelativeNumberOfEvaluatedSamplesParameter.ActualName = RelativeNumberOfEvaluatedSamplesParameter.Name;
+        op.ApplyLinearScalingParameter.ActualName = ApplyLinearScalingParameter.Name;
       }
       foreach (var op in operators.OfType<ISymbolicExpressionTreeCrossover>()) {
@@ -300,4 +321,10 @@
         op.SymbolicExpressionTreeParameter.ActualName = SolutionCreator.SymbolicExpressionTreeParameter.ActualName;
       }
+      foreach (var op in operators.OfType<ISymbolicDataAnalysisSingleObjectiveAnalyzer>()) {
+        op.ApplyLinearScalingParameter.ActualName = ApplyLinearScalingParameter.Name;
+      }
+      foreach (var op in operators.OfType<ISymbolicDataAnalysisMultiObjectiveAnalyzer>()) {
+        op.ApplyLinearScalingParameter.ActualName = ApplyLinearScalingParameter.Name;
+      }
       foreach (var op in operators.OfType<ISymbolicDataAnalysisAnalyzer>()) {
         op.SymbolicExpressionTreeParameter.ActualName = SolutionCreator.SymbolicExpressionTreeParameter.ActualName;
@@ -308,8 +335,8 @@
       }
       foreach (var op in operators.OfType<ISymbolicDataAnalysisInterpreterOperator>()) {
-        op.SymbolicDataAnalysisTreeInterpreterParameter.ActualName = SymbolicExpressionTreeInterpreterParameterName;
+        op.SymbolicDataAnalysisTreeInterpreterParameter.ActualName = SymbolicExpressionTreeInterpreterParameter.Name;
       }
       foreach (var op in operators.OfType<ISymbolicDataAnalysisExpressionCrossover<T>>()) {
-        op.EvaluationPartitionParameter.ActualName = FitnessCalculationPartitionParameterName;
+        op.EvaluationPartitionParameter.ActualName = FitnessCalculationPartitionParameter.Name;
         op.ProblemDataParameter.ActualName = ProblemDataParameter.Name;
         op.EvaluationPartitionParameter.ActualName = FitnessCalculationPartitionParameter.Name;
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/AutoregressiveVariable.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/AutoregressiveVariable.cs	(revision 8915)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/AutoregressiveVariable.cs	(revision 8915)
@@ -0,0 +1,39 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+  [StorableClass]
+  [Item("AutoregressiveTargetVariable", "Represents a variable value with a time offset.")]
+  public sealed class AutoregressiveTargetVariable : LaggedVariable {
+    [StorableConstructor]
+    private AutoregressiveTargetVariable(bool deserializing) : base(deserializing) { }
+    private AutoregressiveTargetVariable(AutoregressiveTargetVariable original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public AutoregressiveTargetVariable() : base("Autoregressive Target Variable", "Represents the target variable with a time offset.") { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new AutoregressiveTargetVariable(this, cloner);
+    }
+  }
+}
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/LaggedVariable.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/LaggedVariable.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/LaggedVariable.cs	(revision 8915)
@@ -27,5 +27,5 @@
   [StorableClass]
   [Item("LaggedVariable", "Represents a variable value with a time offset.")]
-  public sealed class LaggedVariable : Variable {
+  public class LaggedVariable : Variable {
     [Storable]
     private int minLag;
@@ -41,13 +41,15 @@
     }
     [StorableConstructor]
-    private LaggedVariable(bool deserializing) : base(deserializing) { }
-    private LaggedVariable(LaggedVariable original, Cloner cloner)
+    protected LaggedVariable(bool deserializing) : base(deserializing) { }
+    protected LaggedVariable(LaggedVariable original, Cloner cloner)
       : base(original, cloner) {
       minLag = original.minLag;
       maxLag = original.maxLag;
     }
-    public LaggedVariable()
-      : base("LaggedVariable", "Represents a variable value with a time offset.") {
-      minLag = -1; maxLag = -1;
+    public LaggedVariable() : this("LaggedVariable", "Represents a variable value with a time offset.") { }
+    protected LaggedVariable(string name, string description)
+      : base(name, description) {
+      MinLag = -1;
+      MaxLag = -1;
     }
 
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/LaggedVariableTreeNode.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/LaggedVariableTreeNode.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/LaggedVariableTreeNode.cs	(revision 8915)
@@ -37,4 +37,8 @@
     }
 
+    public override bool HasLocalParameters {
+      get { return true; }
+    }
+
     [StorableConstructor]
     private LaggedVariableTreeNode(bool deserializing) : base(deserializing) { }
@@ -43,13 +47,7 @@
       lag = original.lag;
     }
-    private LaggedVariableTreeNode() { }
 
     public LaggedVariableTreeNode(LaggedVariable variableSymbol) : base(variableSymbol) { }
 
-    public override bool HasLocalParameters {
-      get {
-        return true;
-      }
-    }
 
     public override void ResetLocalParameters(IRandom random) {
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/Variable.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/Variable.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/Variable.cs	(revision 8915)
@@ -101,4 +101,27 @@
     }
 
+    private List<string> allVariableNames;
+    [Storable]
+    public IEnumerable<string> AllVariableNames {
+      get { return allVariableNames; }
+      set {
+        if (value == null) throw new ArgumentNullException();
+        allVariableNames.Clear();
+        allVariableNames.AddRange(value);
+        VariableNames = value;
+      }
+    }
+
+    public override bool Enabled {
+      get {
+        if (variableNames.Count == 0) return false;
+        return base.Enabled;
+      }
+      set {
+        if (variableNames.Count == 0) base.Enabled = false;
+        else base.Enabled = value;
+      }
+    }
+
     private const int minimumArity = 0;
     private const int maximumArity = 0;
@@ -112,8 +135,16 @@
     #endregion
 
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (allVariableNames == null || (allVariableNames.Count == 0 && variableNames.Count > 0)) {
+        allVariableNames = variableNames;
+      }
+    }
+
     [StorableConstructor]
     protected Variable(bool deserializing)
       : base(deserializing) {
       variableNames = new List<string>();
+      allVariableNames = new List<string>();
     }
     protected Variable(Variable original, Cloner cloner)
@@ -122,4 +153,5 @@
       weightSigma = original.weightSigma;
       variableNames = new List<string>(original.variableNames);
+      allVariableNames = new List<string>(original.allVariableNames);
       weightManipulatorMu = original.weightManipulatorMu;
       weightManipulatorSigma = original.weightManipulatorSigma;
@@ -135,4 +167,5 @@
       multiplicativeWeightManipulatorSigma = 0.03;
       variableNames = new List<string>();
+      allVariableNames = new List<string>();
     }
 
Index: /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/VariableCondition.cs
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/VariableCondition.cs	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/VariableCondition.cs	(revision 8915)
@@ -86,6 +86,19 @@
       set {
         if (value == null) throw new ArgumentNullException();
-        variableNames = new List<string>(value);
+        variableNames.Clear();
+        variableNames.AddRange(value);
         OnChanged(EventArgs.Empty);
+      }
+    }
+
+    private List<string> allVariableNames;
+    [Storable]
+    public IEnumerable<string> AllVariableNames {
+      get { return allVariableNames; }
+      set {
+        if (value == null) throw new ArgumentNullException();
+        allVariableNames.Clear();
+        allVariableNames.AddRange(value);
+        VariableNames = value;
       }
     }
@@ -151,6 +164,17 @@
 
     #region persistence and cloning
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (allVariableNames == null || (allVariableNames.Count == 0 && variableNames.Count > 0)) {
+        allVariableNames = variableNames;
+      }
+    }
+
     [StorableConstructor]
-    private VariableCondition(bool deserializing) : base(deserializing) { }
+    private VariableCondition(bool deserializing)
+      : base(deserializing) {
+      variableNames = new List<string>();
+      allVariableNames = new List<string>();
+    }
     private VariableCondition(VariableCondition original, Cloner cloner)
       : base(original, cloner) {
@@ -161,4 +185,5 @@
 
       variableNames = new List<string>(original.variableNames);
+      allVariableNames = new List<string>(original.allVariableNames);
 
       slopeInitializerMu = original.slopeInitializerMu;
@@ -181,4 +206,5 @@
 
       variableNames = new List<string>();
+      allVariableNames = new List<string>();
 
       slopeInitializerMu = 0.0;
Index: /branches/HeuristicLab.TreeSimplifier/PreBuildEvent.cmd
===================================================================
--- /branches/HeuristicLab.TreeSimplifier/PreBuildEvent.cmd	(revision 8914)
+++ /branches/HeuristicLab.TreeSimplifier/PreBuildEvent.cmd	(revision 8915)
@@ -1,1 +1,2 @@
-SubWCRev "%ProjectDir%\." "%ProjectDir%\Properties\AssemblyInfo.cs.frame" "%ProjectDir%\Properties\AssemblyInfo.cs"
+IF EXIST "%ProjectDir%\Properties\AssemblyInfo.cs.frame" SubWCRev "%ProjectDir%\" "%ProjectDir%\Properties\AssemblyInfo.cs.frame" "%ProjectDir%\Properties\AssemblyInfo.cs"
+IF EXIST "%ProjectDir%\Plugin.cs.frame" SubWCRev "%ProjectDir%\" "%ProjectDir%\Plugin.cs.frame" "%ProjectDir%\Plugin.cs"
