Index: trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/Analyzers/BestSymbolicRegressionSolutionAnalyzer.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/Analyzers/BestSymbolicRegressionSolutionAnalyzer.cs	(revision 3995)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/Analyzers/BestSymbolicRegressionSolutionAnalyzer.cs	(revision 3996)
@@ -99,25 +99,35 @@
           SymbolicExpressionTree[i]);
         var solution = new SymbolicRegressionSolution(ProblemData, model, lowerEstimationLimit, upperEstimationLimit);
-
+        solution.Name = BestSolutionParameterName;
+        solution.Description = "Best solution on validation partition found over the whole run.";
         BestSolutionParameter.ActualValue = solution;
         BestSolutionQualityParameter.ActualValue = Quality[i];
-
-        if (Results.ContainsKey(BestSolutionInputvariableCountResultName)) {
-          Results[BestSolutionInputvariableCountResultName].Value = new IntValue(model.InputVariables.Count());
-          Results[VariableImpactsResultName].Value = CalculateVariableImpacts();
-        } else {
-          Results.Add(new Result(BestSolutionInputvariableCountResultName, new IntValue(model.InputVariables.Count())));
-          Results.Add(new Result(VariableImpactsResultName, CalculateVariableImpacts()));
-        }
+        BestSymbolicRegressionSolutionAnalyzer.UpdateSymbolicRegressionBestSolutionResults(solution, ProblemData, Results, VariableFrequencies);
       }
       return BestSolutionParameter.ActualValue;
     }
 
-    private DoubleMatrix CalculateVariableImpacts() {
-      if (VariableFrequencies != null) {
-        var impacts = new DoubleMatrix(VariableFrequencies.Rows.Count, 1, new string[] { "Impact" }, VariableFrequencies.Rows.Select(x => x.Name));
+    public static void UpdateBestSolutionResults(SymbolicRegressionSolution bestSolution, DataAnalysisProblemData problemData, ResultCollection results, IntValue currentGeneration, DataTable variableFrequencies) {
+      RegressionSolutionAnalyzer.UpdateBestSolutionResults(bestSolution, problemData, results, currentGeneration);
+      UpdateSymbolicRegressionBestSolutionResults(bestSolution, problemData, results, variableFrequencies);
+    }
+
+    private static void UpdateSymbolicRegressionBestSolutionResults(SymbolicRegressionSolution bestSolution, DataAnalysisProblemData problemData, ResultCollection results, DataTable variableFrequencies) {
+      if (results.ContainsKey(BestSolutionInputvariableCountResultName)) {
+        results[BestSolutionInputvariableCountResultName].Value = new IntValue(bestSolution.Model.InputVariables.Count());
+        results[VariableImpactsResultName].Value = CalculateVariableImpacts(variableFrequencies);
+      } else {
+        results.Add(new Result(BestSolutionInputvariableCountResultName, new IntValue(bestSolution.Model.InputVariables.Count())));
+        results.Add(new Result(VariableImpactsResultName, CalculateVariableImpacts(variableFrequencies)));
+      }
+    }
+
+
+    private static DoubleMatrix CalculateVariableImpacts(DataTable variableFrequencies) {
+      if (variableFrequencies != null) {
+        var impacts = new DoubleMatrix(variableFrequencies.Rows.Count, 1, new string[] { "Impact" }, variableFrequencies.Rows.Select(x => x.Name));
         impacts.SortableView = true;
         int rowIndex = 0;
-        foreach (var dataRow in VariableFrequencies.Rows) {
+        foreach (var dataRow in variableFrequencies.Rows) {
           string variableName = dataRow.Name;
           double integral = 0;
@@ -134,5 +144,4 @@
       } else return new DoubleMatrix(1, 1);
     }
-
   }
 }
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/Analyzers/FixedValidationBestScaledSymbolicRegressionSolutionAnalyzer.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/Analyzers/FixedValidationBestScaledSymbolicRegressionSolutionAnalyzer.cs	(revision 3996)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/Analyzers/FixedValidationBestScaledSymbolicRegressionSolutionAnalyzer.cs	(revision 3996)
@@ -0,0 +1,334 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 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.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Problems.DataAnalysis.Regression.Symbolic;
+using HeuristicLab.Problems.DataAnalysis.Symbolic;
+using System.Collections.Generic;
+using HeuristicLab.Problems.DataAnalysis.Symbolic.Symbols;
+using HeuristicLab.Problems.DataAnalysis;
+using HeuristicLab.Analysis;
+using System;
+using HeuristicLab.Optimization.Operators;
+using HeuristicLab.Problems.DataAnalysis.Evaluators;
+
+namespace HeuristicLab.Problems.DataAnalysis.Regression.Symbolic.Analyzers {
+  /// <summary>
+  /// An operator that analyzes the validation best scaled symbolic regression solution.
+  /// </summary>
+  [Item("FixedValidationBestScaledSymbolicRegressionSolutionAnalyzer", "An operator that analyzes the validation best scaled symbolic regression solution.")]
+  [StorableClass]
+  public sealed class FixedValidationBestScaledSymbolicRegressionSolutionAnalyzer : SingleSuccessorOperator, ISymbolicRegressionAnalyzer {
+    private const string SymbolicExpressionTreeParameterName = "SymbolicExpressionTree";
+    private const string SymbolicExpressionTreeInterpreterParameterName = "SymbolicExpressionTreeInterpreter";
+    private const string ProblemDataParameterName = "ProblemData";
+    private const string ValidationSamplesStartParameterName = "SamplesStart";
+    private const string ValidationSamplesEndParameterName = "SamplesEnd";
+    private const string QualityParameterName = "Quality";
+    private const string ScaledQualityParameterName = "ScaledQuality";
+    private const string UpperEstimationLimitParameterName = "UpperEstimationLimit";
+    private const string LowerEstimationLimitParameterName = "LowerEstimationLimit";
+    private const string AlphaParameterName = "Alpha";
+    private const string BetaParameterName = "Beta";
+    private const string BestSolutionParameterName = "Best solution (validation)";
+    private const string BestSolutionQualityParameterName = "Best solution quality (validation)";
+    private const string CurrentBestValidationQualityParameterName = "Current best validation quality";
+    private const string BestSolutionQualityValuesParameterName = "Validation Quality";
+    private const string ResultsParameterName = "Results";
+    private const string VariableFrequenciesParameterName = "VariableFrequencies";
+    private const string BestKnownQualityParameterName = "BestKnownQuality";
+    private const string GenerationsParameterName = "Generations";
+
+    private const string TrainingMeanSquaredErrorQualityParameterName = "Mean squared error (training)";
+    private const string MinTrainingMeanSquaredErrorQualityParameterName = "Min mean squared error (training)";
+    private const string MaxTrainingMeanSquaredErrorQualityParameterName = "Max mean squared error (training)";
+    private const string AverageTrainingMeanSquaredErrorQualityParameterName = "Average mean squared error (training)";
+    private const string BestTrainingMeanSquaredErrorQualityParameterName = "Best mean squared error (training)";
+
+    private const string TrainingAverageRelativeErrorQualityParameterName = "Average relative error (training)";
+    private const string MinTrainingAverageRelativeErrorQualityParameterName = "Min average relative error (training)";
+    private const string MaxTrainingAverageRelativeErrorQualityParameterName = "Max average relative error (training)";
+    private const string AverageTrainingAverageRelativeErrorQualityParameterName = "Average average relative error (training)";
+    private const string BestTrainingAverageRelativeErrorQualityParameterName = "Best average relative error (training)";
+
+    private const string TrainingRSquaredQualityParameterName = "R² (training)";
+    private const string MinTrainingRSquaredQualityParameterName = "Min R² (training)";
+    private const string MaxTrainingRSquaredQualityParameterName = "Max R² (training)";
+    private const string AverageTrainingRSquaredQualityParameterName = "Average R² (training)";
+    private const string BestTrainingRSquaredQualityParameterName = "Best R² (training)";
+
+    private const string TestMeanSquaredErrorQualityParameterName = "Mean squared error (test)";
+    private const string MinTestMeanSquaredErrorQualityParameterName = "Min mean squared error (test)";
+    private const string MaxTestMeanSquaredErrorQualityParameterName = "Max mean squared error (test)";
+    private const string AverageTestMeanSquaredErrorQualityParameterName = "Average mean squared error (test)";
+    private const string BestTestMeanSquaredErrorQualityParameterName = "Best mean squared error (test)";
+
+    private const string TestAverageRelativeErrorQualityParameterName = "Average relative error (test)";
+    private const string MinTestAverageRelativeErrorQualityParameterName = "Min average relative error (test)";
+    private const string MaxTestAverageRelativeErrorQualityParameterName = "Max average relative error (test)";
+    private const string AverageTestAverageRelativeErrorQualityParameterName = "Average average relative error (test)";
+    private const string BestTestAverageRelativeErrorQualityParameterName = "Best average relative error (test)";
+
+    private const string TestRSquaredQualityParameterName = "R² (test)";
+    private const string MinTestRSquaredQualityParameterName = "Min R² (test)";
+    private const string MaxTestRSquaredQualityParameterName = "Max R² (test)";
+    private const string AverageTestRSquaredQualityParameterName = "Average R² (test)";
+    private const string BestTestRSquaredQualityParameterName = "Best R² (test)";
+
+    private const string RSquaredValuesParameterName = "R²";
+    private const string MeanSquaredErrorValuesParameterName = "Mean squared error";
+    private const string RelativeErrorValuesParameterName = "Average relative error";
+
+    #region parameter properties
+    public ScopeTreeLookupParameter<SymbolicExpressionTree> SymbolicExpressionTreeParameter {
+      get { return (ScopeTreeLookupParameter<SymbolicExpressionTree>)Parameters[SymbolicExpressionTreeParameterName]; }
+    }
+    public ScopeTreeLookupParameter<DoubleValue> QualityParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters[QualityParameterName]; }
+    }
+    public ScopeTreeLookupParameter<DoubleValue> AlphaParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters[AlphaParameterName]; }
+    }
+    public ScopeTreeLookupParameter<DoubleValue> BetaParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters[BetaParameterName]; }
+    }
+    public IValueLookupParameter<ISymbolicExpressionTreeInterpreter> SymbolicExpressionTreeInterpreterParameter {
+      get { return (IValueLookupParameter<ISymbolicExpressionTreeInterpreter>)Parameters[SymbolicExpressionTreeInterpreterParameterName]; }
+    }
+    public IValueLookupParameter<DataAnalysisProblemData> ProblemDataParameter {
+      get { return (IValueLookupParameter<DataAnalysisProblemData>)Parameters[ProblemDataParameterName]; }
+    }
+    public IValueLookupParameter<IntValue> ValidationSamplesStartParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters[ValidationSamplesStartParameterName]; }
+    }
+    public IValueLookupParameter<IntValue> ValidationSamplesEndParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters[ValidationSamplesEndParameterName]; }
+    }
+    public IValueLookupParameter<DoubleValue> UpperEstimationLimitParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters[UpperEstimationLimitParameterName]; }
+    }
+    public IValueLookupParameter<DoubleValue> LowerEstimationLimitParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters[LowerEstimationLimitParameterName]; }
+    }
+    public ILookupParameter<SymbolicRegressionSolution> BestSolutionParameter {
+      get { return (ILookupParameter<SymbolicRegressionSolution>)Parameters[BestSolutionParameterName]; }
+    }
+    public ILookupParameter<IntValue> GenerationsParameter {
+      get { return (ILookupParameter<IntValue>)Parameters[GenerationsParameterName]; }
+    }
+    public ILookupParameter<DoubleValue> BestSolutionQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters[BestSolutionQualityParameterName]; }
+    }
+    public ILookupParameter<ResultCollection> ResultsParameter {
+      get { return (ILookupParameter<ResultCollection>)Parameters[ResultsParameterName]; }
+    }
+    public ILookupParameter<DoubleValue> BestKnownQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters[BestKnownQualityParameterName]; }
+    }
+    public ILookupParameter<DataTable> VariableFrequenciesParameter {
+      get { return (ILookupParameter<DataTable>)Parameters[VariableFrequenciesParameterName]; }
+    }
+
+    #endregion
+    #region properties
+    public ItemArray<SymbolicExpressionTree> SymbolicExpressionTree {
+      get { return SymbolicExpressionTreeParameter.ActualValue; }
+    }
+    public ItemArray<DoubleValue> Quality {
+      get { return QualityParameter.ActualValue; }
+    }
+    public ItemArray<DoubleValue> Alpha {
+      get { return AlphaParameter.ActualValue; }
+    }
+    public ItemArray<DoubleValue> Beta {
+      get { return BetaParameter.ActualValue; }
+    }
+    public ISymbolicExpressionTreeInterpreter SymbolicExpressionTreeInterpreter {
+      get { return SymbolicExpressionTreeInterpreterParameter.ActualValue; }
+    }
+    public DataAnalysisProblemData ProblemData {
+      get { return ProblemDataParameter.ActualValue; }
+    }
+    public IntValue ValidiationSamplesStart {
+      get { return ValidationSamplesStartParameter.ActualValue; }
+    }
+    public IntValue ValidationSamplesEnd {
+      get { return ValidationSamplesEndParameter.ActualValue; }
+    }
+    public DoubleValue UpperEstimationLimit {
+      get { return UpperEstimationLimitParameter.ActualValue; }
+    }
+    public DoubleValue LowerEstimationLimit {
+      get { return LowerEstimationLimitParameter.ActualValue; }
+    }
+    public ResultCollection Results {
+      get { return ResultsParameter.ActualValue; }
+    }
+    public DataTable VariableFrequencies {
+      get { return VariableFrequenciesParameter.ActualValue; }
+    }
+    public IntValue Generations {
+      get { return GenerationsParameter.ActualValue; }
+    }
+
+    #endregion
+
+    public FixedValidationBestScaledSymbolicRegressionSolutionAnalyzer()
+      : base() {
+      Parameters.Add(new ScopeTreeLookupParameter<SymbolicExpressionTree>(SymbolicExpressionTreeParameterName, "The symbolic expression trees to analyze."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>(QualityParameterName, "The quality of the symbolic expression trees to analyze."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>(AlphaParameterName, "The alpha parameter for linear scaling."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>(BetaParameterName, "The beta parameter for linear scaling."));
+      Parameters.Add(new ValueLookupParameter<ISymbolicExpressionTreeInterpreter>(SymbolicExpressionTreeInterpreterParameterName, "The interpreter that should be used for the analysis of symbolic expression trees."));
+      Parameters.Add(new ValueLookupParameter<DataAnalysisProblemData>(ProblemDataParameterName, "The problem data for which the symbolic expression tree is a solution."));
+      Parameters.Add(new ValueLookupParameter<IntValue>(ValidationSamplesStartParameterName, "The first index of the validation partition of the data set."));
+      Parameters.Add(new ValueLookupParameter<IntValue>(ValidationSamplesEndParameterName, "The last index of the validation partition of the data set."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>(UpperEstimationLimitParameterName, "The upper estimation limit that was set for the evaluation of the symbolic expression trees."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>(LowerEstimationLimitParameterName, "The lower estimation limit that was set for the evaluation of the symbolic expression trees."));
+      Parameters.Add(new LookupParameter<SymbolicRegressionSolution>(BestSolutionParameterName, "The best symbolic regression solution."));
+      Parameters.Add(new LookupParameter<IntValue>(GenerationsParameterName, "The number of generations calculated so far."));
+      Parameters.Add(new LookupParameter<DoubleValue>(BestSolutionQualityParameterName, "The quality of the best symbolic regression solution."));
+      Parameters.Add(new LookupParameter<ResultCollection>(ResultsParameterName, "The result collection where the best symbolic regression solution should be stored."));
+      Parameters.Add(new LookupParameter<DoubleValue>(BestKnownQualityParameterName, "The best known (validation) quality achieved on the data set."));
+      Parameters.Add(new LookupParameter<DataTable>(VariableFrequenciesParameterName, "The variable frequencies table to use for the calculation of variable impacts"));
+    }
+
+    [StorableConstructor]
+    private FixedValidationBestScaledSymbolicRegressionSolutionAnalyzer(bool deserializing) : base() { }
+
+    public override IOperation Apply() {
+      var alphas = Alpha;
+      var betas = Beta;
+      var trees = SymbolicExpressionTree;
+
+      IEnumerable<SymbolicExpressionTree> scaledTrees;
+      if (alphas.Length == trees.Length) {
+        scaledTrees = from i in Enumerable.Range(0, trees.Length)
+                      select SymbolicRegressionSolutionLinearScaler.Scale(trees[i], alphas[i].Value, betas[i].Value);
+      } else {
+        scaledTrees = trees;
+      }
+
+      int trainingStart = ProblemData.TrainingSamplesStart.Value;
+      int trainingEnd = ProblemData.TrainingSamplesEnd.Value;
+      int testStart = ProblemData.TestSamplesStart.Value;
+      int testEnd = ProblemData.TestSamplesEnd.Value;
+
+      SymbolicRegressionModelQualityAnalyzer.Analyze(scaledTrees, SymbolicExpressionTreeInterpreter,
+        UpperEstimationLimit.Value, LowerEstimationLimit.Value,
+        ProblemData, trainingStart, trainingEnd, testStart, testEnd, Results);
+
+      #region validation best model
+      int targetVariableIndex = ProblemData.Dataset.GetVariableIndex(ProblemData.TargetVariable.Value);
+      int validationStart = ValidiationSamplesStart.Value;
+      int validationEnd = ValidationSamplesEnd.Value;
+      double upperEstimationLimit = UpperEstimationLimit != null ? UpperEstimationLimit.Value : double.PositiveInfinity;
+      double lowerEstimationLimit = LowerEstimationLimit != null ? LowerEstimationLimit.Value : double.NegativeInfinity;
+
+      double bestValidationMse = double.MaxValue;
+      SymbolicExpressionTree bestTree = null;
+
+      OnlineMeanSquaredErrorEvaluator mseEvaluator = new OnlineMeanSquaredErrorEvaluator();
+      foreach (var scaledTree in scaledTrees) {
+        mseEvaluator.Reset();
+        IEnumerable<double> estimatedValidationValues = SymbolicExpressionTreeInterpreter.GetSymbolicExpressionTreeValues(scaledTree, ProblemData.Dataset, Enumerable.Range(validationStart, validationEnd - validationStart));
+        IEnumerable<double> originalValidationValues = ProblemData.Dataset.GetEnumeratedVariableValues(targetVariableIndex, validationStart, validationEnd);
+        var estimatedEnumerator = estimatedValidationValues.GetEnumerator();
+        var originalEnumerator = originalValidationValues.GetEnumerator();
+        while (estimatedEnumerator.MoveNext() & originalEnumerator.MoveNext()) {
+          double estimated = estimatedEnumerator.Current;
+          if (double.IsNaN(estimated)) estimated = upperEstimationLimit;
+          else estimated = Math.Min(upperEstimationLimit, Math.Max(lowerEstimationLimit, estimated));
+          mseEvaluator.Add(originalEnumerator.Current, estimated);
+        }
+        double validationMse = mseEvaluator.MeanSquaredError;
+        if (validationMse < bestValidationMse) {
+          bestValidationMse = validationMse;
+          bestTree = scaledTree;
+        }
+      }
+
+
+      if (BestSolutionQualityParameter.ActualValue == null || BestSolutionQualityParameter.ActualValue.Value > bestValidationMse) {
+        var model = new SymbolicRegressionModel((ISymbolicExpressionTreeInterpreter)SymbolicExpressionTreeInterpreter.Clone(),
+          bestTree);
+        var solution = new SymbolicRegressionSolution(ProblemData, model, lowerEstimationLimit, upperEstimationLimit);
+        solution.Name = BestSolutionParameterName;
+        solution.Description = "Best solution on validation partition found over the whole run.";
+
+        BestSolutionParameter.ActualValue = solution;
+        BestSolutionQualityParameter.ActualValue = new DoubleValue(bestValidationMse);
+
+        BestSymbolicRegressionSolutionAnalyzer.UpdateBestSolutionResults(solution, ProblemData, Results, Generations, VariableFrequencies);
+      }
+
+      if (!Results.ContainsKey(BestSolutionQualityValuesParameterName)) {
+        Results.Add(new Result(BestSolutionQualityValuesParameterName, new DataTable(BestSolutionQualityValuesParameterName, BestSolutionQualityValuesParameterName)));
+        Results.Add(new Result(BestSolutionQualityParameterName, new DoubleValue()));
+        Results.Add(new Result(CurrentBestValidationQualityParameterName, new DoubleValue()));
+      }
+      Results[BestSolutionQualityParameterName].Value = new DoubleValue(BestSolutionQualityParameter.ActualValue.Value);
+      Results[CurrentBestValidationQualityParameterName].Value = new DoubleValue(bestValidationMse);
+
+      DataTable validationValues = (DataTable)Results[BestSolutionQualityValuesParameterName].Value;
+      AddValue(validationValues, BestSolutionQualityParameter.ActualValue.Value, BestSolutionQualityParameterName, BestSolutionQualityParameterName);
+      AddValue(validationValues, bestValidationMse, CurrentBestValidationQualityParameterName, CurrentBestValidationQualityParameterName);
+      #endregion
+      return base.Apply();
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void Initialize() {
+      if (!Parameters.ContainsKey(AlphaParameterName)) {
+        Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>(AlphaParameterName, "The alpha parameter for linear scaling."));
+      }
+      if (!Parameters.ContainsKey(BetaParameterName)) {
+        Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>(BetaParameterName, "The beta parameter for linear scaling."));
+      }
+      if (!Parameters.ContainsKey(VariableFrequenciesParameterName)) {
+        Parameters.Add(new LookupParameter<DataTable>(VariableFrequenciesParameterName, "The variable frequencies table to use for the calculation of variable impacts"));
+      }
+      if (!Parameters.ContainsKey(GenerationsParameterName)) {
+        Parameters.Add(new LookupParameter<IntValue>(GenerationsParameterName, "The number of generations calculated so far."));
+      }
+    }
+
+    private static void AddValue(DataTable table, double data, string name, string description) {
+      DataRow row;
+      table.Rows.TryGetValue(name, out row);
+      if (row == null) {
+        row = new DataRow(name, description);
+        row.Values.Add(data);
+        table.Rows.Add(row);
+      } else {
+        row.Values.Add(data);
+      }
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/Analyzers/SymbolicRegressionModelQualityAnalyzer.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/Analyzers/SymbolicRegressionModelQualityAnalyzer.cs	(revision 3995)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/Analyzers/SymbolicRegressionModelQualityAnalyzer.cs	(revision 3996)
@@ -45,5 +45,5 @@
   [Item("SymbolicRegressionModelQualityAnalyzer", "An operator for analyzing the quality of symbolic regression solutions symbolic expression tree encoding.")]
   [StorableClass]
-  public sealed class SymbolicRegressionModelQualityAnalyzer : AlgorithmOperator, ISymbolicRegressionAnalyzer {
+  public sealed class SymbolicRegressionModelQualityAnalyzer : SingleSuccessorOperator, ISymbolicRegressionAnalyzer {
     private const string SymbolicExpressionTreeInterpreterParameterName = "SymbolicExpressionTreeInterpreter";
     private const string SymbolicExpressionTreeParameterName = "SymbolicExpressionTree";
@@ -130,19 +130,12 @@
     }
     #endregion
-
-    [Storable]
-    private UniformSubScopesProcessor subScopesProcessor;
-    [Storable]
-    private MinAverageMaxValueAnalyzer minAvgMaxTrainingMseAnalyzer;
-    [Storable]
-    private MinAverageMaxValueAnalyzer minAvgMaxTestMseAnalyzer;
-    [Storable]
-    private MinAverageMaxValueAnalyzer minAvgMaxTrainingRSquaredAnalyzer;
-    [Storable]
-    private MinAverageMaxValueAnalyzer minAvgMaxTestRSquaredAnalyzer;
-    [Storable]
-    private MinAverageMaxValueAnalyzer minAvgMaxTrainingRelErrorAnalyzer;
-    [Storable]
-    private MinAverageMaxValueAnalyzer minAvgMaxTestRelErrorAnalyzer;
+    #region properties
+    public DoubleValue UpperEstimationLimit {
+      get { return UpperEstimationLimitParameter.ActualValue; }
+    }
+    public DoubleValue LowerEstimationLimit {
+      get { return LowerEstimationLimitParameter.ActualValue; }
+    }
+    #endregion
 
     public SymbolicRegressionModelQualityAnalyzer()
@@ -161,131 +154,4 @@
       Parameters.Add(new ValueLookupParameter<DataTable>(RelativeErrorValuesParameterName, "The data table to collect relative error values."));
       Parameters.Add(new LookupParameter<ResultCollection>(ResultsParameterName, "The result collection where the best symbolic regression solution should be stored."));
-
-      #region operator initialization
-      subScopesProcessor = new UniformSubScopesProcessor();
-      SymbolicRegressionModelQualityCalculator trainingQualityCalculator = new SymbolicRegressionModelQualityCalculator();
-      SymbolicRegressionModelQualityCalculator testQualityCalculator = new SymbolicRegressionModelQualityCalculator();
-      minAvgMaxTrainingMseAnalyzer = new MinAverageMaxValueAnalyzer();
-      minAvgMaxTestMseAnalyzer = new MinAverageMaxValueAnalyzer();
-
-      minAvgMaxTrainingRSquaredAnalyzer = new MinAverageMaxValueAnalyzer();
-      minAvgMaxTestRSquaredAnalyzer = new MinAverageMaxValueAnalyzer();
-
-      minAvgMaxTrainingRelErrorAnalyzer = new MinAverageMaxValueAnalyzer();
-      minAvgMaxTestRelErrorAnalyzer = new MinAverageMaxValueAnalyzer();
-      #endregion
-
-      #region parameter wiring
-      subScopesProcessor.Depth.Value = SymbolicExpressionTreeParameter.Depth;
-      trainingQualityCalculator.LowerEstimationLimitParameter.ActualName = LowerEstimationLimitParameter.Name;
-      trainingQualityCalculator.ProblemDataParameter.ActualName = ProblemDataParameter.Name;
-      trainingQualityCalculator.SamplesStartParameter.ActualName = TrainingSamplesStartParameter.Name;
-      trainingQualityCalculator.SamplesEndParameter.ActualName = TrainingSamplesEndParameter.Name;
-      trainingQualityCalculator.SymbolicExpressionTreeInterpreterParameter.ActualName = SymbolicExpressionTreeInterpreterParameter.Name;
-      trainingQualityCalculator.SymbolicExpressionTreeParameter.ActualName = SymbolicExpressionTreeParameter.Name;
-      trainingQualityCalculator.UpperEstimationLimitParameter.ActualName = UpperEstimationLimitParameter.Name;
-      trainingQualityCalculator.AverageRelativeErrorQualityParameter.ActualName = TrainingAverageRelativeErrorQualityParameterName;
-      trainingQualityCalculator.MeanSquaredErrorQualityParameter.ActualName = TrainingMeanSquaredErrorQualityParameterName;
-      trainingQualityCalculator.RSquaredQualityParameter.ActualName = TrainingRSquaredQualityParameterName;
-
-      testQualityCalculator.LowerEstimationLimitParameter.ActualName = LowerEstimationLimitParameter.Name;
-      testQualityCalculator.ProblemDataParameter.ActualName = ProblemDataParameter.Name;
-      testQualityCalculator.SamplesStartParameter.ActualName = TestSamplesStartParameter.Name;
-      testQualityCalculator.SamplesEndParameter.ActualName = TestSamplesEndParameter.Name;
-      testQualityCalculator.SymbolicExpressionTreeInterpreterParameter.ActualName = SymbolicExpressionTreeInterpreterParameter.Name;
-      testQualityCalculator.SymbolicExpressionTreeParameter.ActualName = SymbolicExpressionTreeParameter.Name;
-      testQualityCalculator.UpperEstimationLimitParameter.ActualName = UpperEstimationLimitParameter.Name;
-      testQualityCalculator.AverageRelativeErrorQualityParameter.ActualName = TestAverageRelativeErrorQualityParameterName;
-      testQualityCalculator.MeanSquaredErrorQualityParameter.ActualName = TestMeanSquaredErrorQualityParameterName;
-      testQualityCalculator.RSquaredQualityParameter.ActualName = TestRSquaredQualityParameterName;
-      #region training/test MSE
-      minAvgMaxTrainingMseAnalyzer.ValueParameter.ActualName = TrainingMeanSquaredErrorQualityParameterName;
-      minAvgMaxTrainingMseAnalyzer.ValueParameter.Depth = SymbolicExpressionTreeParameter.Depth;
-      minAvgMaxTrainingMseAnalyzer.AverageValueParameter.ActualName = AverageTrainingMeanSquaredErrorQualityParameterName;
-      minAvgMaxTrainingMseAnalyzer.MaxValueParameter.ActualName = MaxTrainingMeanSquaredErrorQualityParameterName;
-      minAvgMaxTrainingMseAnalyzer.MinValueParameter.ActualName = MinTrainingMeanSquaredErrorQualityParameterName;
-      minAvgMaxTrainingMseAnalyzer.ValuesParameter.ActualName = MeanSquaredErrorValuesParameterName;
-      minAvgMaxTrainingMseAnalyzer.ResultsParameter.ActualName = ResultsParameter.Name;
-      minAvgMaxTrainingMseAnalyzer.CollectMinValueInResultsParameter.Value = new BoolValue(false);
-      minAvgMaxTrainingMseAnalyzer.CollectAverageValueInResultsParameter.Value = new BoolValue(false);
-      minAvgMaxTrainingMseAnalyzer.CollectMaxValueInResultsParameter.Value = new BoolValue(false);
-
-      minAvgMaxTestMseAnalyzer.ValueParameter.ActualName = TestMeanSquaredErrorQualityParameterName;
-      minAvgMaxTestMseAnalyzer.ValueParameter.Depth = SymbolicExpressionTreeParameter.Depth;
-      minAvgMaxTestMseAnalyzer.AverageValueParameter.ActualName = AverageTestMeanSquaredErrorQualityParameterName;
-      minAvgMaxTestMseAnalyzer.MaxValueParameter.ActualName = MaxTestMeanSquaredErrorQualityParameterName;
-      minAvgMaxTestMseAnalyzer.MinValueParameter.ActualName = MinTestMeanSquaredErrorQualityParameterName;
-      minAvgMaxTestMseAnalyzer.ValuesParameter.ActualName = MeanSquaredErrorValuesParameterName;
-      minAvgMaxTestMseAnalyzer.ResultsParameter.ActualName = ResultsParameter.Name;
-      minAvgMaxTestMseAnalyzer.CollectMinValueInResultsParameter.Value = new BoolValue(false);
-      minAvgMaxTestMseAnalyzer.CollectAverageValueInResultsParameter.Value = new BoolValue(false);
-      minAvgMaxTestMseAnalyzer.CollectMaxValueInResultsParameter.Value = new BoolValue(false);
-
-      #endregion
-      #region training/test R²
-      minAvgMaxTrainingRSquaredAnalyzer.ValueParameter.ActualName = TrainingRSquaredQualityParameterName;
-      minAvgMaxTrainingRSquaredAnalyzer.ValueParameter.Depth = SymbolicExpressionTreeParameter.Depth;
-      minAvgMaxTrainingRSquaredAnalyzer.AverageValueParameter.ActualName = AverageTrainingRSquaredQualityParameterName;
-      minAvgMaxTrainingRSquaredAnalyzer.MaxValueParameter.ActualName = MaxTrainingRSquaredQualityParameterName;
-      minAvgMaxTrainingRSquaredAnalyzer.MinValueParameter.ActualName = MinTrainingRSquaredQualityParameterName;
-      minAvgMaxTrainingRSquaredAnalyzer.ValuesParameter.ActualName = RSquaredValuesParameterName;
-      minAvgMaxTrainingRSquaredAnalyzer.ResultsParameter.ActualName = ResultsParameter.Name;
-      minAvgMaxTrainingRSquaredAnalyzer.CollectMinValueInResultsParameter.Value = new BoolValue(false);
-      minAvgMaxTrainingRSquaredAnalyzer.CollectAverageValueInResultsParameter.Value = new BoolValue(false);
-      minAvgMaxTrainingRSquaredAnalyzer.CollectMaxValueInResultsParameter.Value = new BoolValue(false);
-
-
-      minAvgMaxTestRSquaredAnalyzer.ValueParameter.ActualName = TestRSquaredQualityParameterName;
-      minAvgMaxTestRSquaredAnalyzer.ValueParameter.Depth = SymbolicExpressionTreeParameter.Depth;
-      minAvgMaxTestRSquaredAnalyzer.AverageValueParameter.ActualName = AverageTestRSquaredQualityParameterName;
-      minAvgMaxTestRSquaredAnalyzer.MaxValueParameter.ActualName = MaxTestRSquaredQualityParameterName;
-      minAvgMaxTestRSquaredAnalyzer.MinValueParameter.ActualName = MinTestRSquaredQualityParameterName;
-      minAvgMaxTestRSquaredAnalyzer.ValuesParameter.ActualName = RSquaredValuesParameterName;
-      minAvgMaxTestRSquaredAnalyzer.ResultsParameter.ActualName = ResultsParameter.Name;
-      minAvgMaxTestRSquaredAnalyzer.CollectMinValueInResultsParameter.Value = new BoolValue(false);
-      minAvgMaxTestRSquaredAnalyzer.CollectAverageValueInResultsParameter.Value = new BoolValue(false);
-      minAvgMaxTestRSquaredAnalyzer.CollectMaxValueInResultsParameter.Value = new BoolValue(false);
-
-      #endregion
-      #region training/test avg. rel. error
-      minAvgMaxTrainingRelErrorAnalyzer.ValueParameter.ActualName = TrainingAverageRelativeErrorQualityParameterName;
-      minAvgMaxTrainingRelErrorAnalyzer.ValueParameter.Depth = SymbolicExpressionTreeParameter.Depth;
-      minAvgMaxTrainingRelErrorAnalyzer.AverageValueParameter.ActualName = AverageTrainingAverageRelativeErrorQualityParameterName;
-      minAvgMaxTrainingRelErrorAnalyzer.MaxValueParameter.ActualName = MaxTrainingAverageRelativeErrorQualityParameterName;
-      minAvgMaxTrainingRelErrorAnalyzer.MinValueParameter.ActualName = MinTrainingAverageRelativeErrorQualityParameterName;
-      minAvgMaxTrainingRelErrorAnalyzer.ValuesParameter.ActualName = RelativeErrorValuesParameterName;
-      minAvgMaxTrainingRelErrorAnalyzer.ResultsParameter.ActualName = ResultsParameter.Name;
-      minAvgMaxTrainingRelErrorAnalyzer.CollectMinValueInResultsParameter.Value = new BoolValue(false);
-      minAvgMaxTrainingRelErrorAnalyzer.CollectAverageValueInResultsParameter.Value = new BoolValue(false);
-      minAvgMaxTrainingRelErrorAnalyzer.CollectMaxValueInResultsParameter.Value = new BoolValue(false);
-
-      minAvgMaxTestRelErrorAnalyzer.ValueParameter.ActualName = TestAverageRelativeErrorQualityParameterName;
-      minAvgMaxTestRelErrorAnalyzer.ValueParameter.Depth = SymbolicExpressionTreeParameter.Depth;
-      minAvgMaxTestRelErrorAnalyzer.AverageValueParameter.ActualName = AverageTestAverageRelativeErrorQualityParameterName;
-      minAvgMaxTestRelErrorAnalyzer.MaxValueParameter.ActualName = MaxTestAverageRelativeErrorQualityParameterName;
-      minAvgMaxTestRelErrorAnalyzer.MinValueParameter.ActualName = MinTestAverageRelativeErrorQualityParameterName;
-      minAvgMaxTestRelErrorAnalyzer.ValuesParameter.ActualName = RelativeErrorValuesParameterName;
-      minAvgMaxTestRelErrorAnalyzer.ResultsParameter.ActualName = ResultsParameter.Name;
-      minAvgMaxTestRelErrorAnalyzer.CollectMinValueInResultsParameter.Value = new BoolValue(false);
-      minAvgMaxTestRelErrorAnalyzer.CollectAverageValueInResultsParameter.Value = new BoolValue(false);
-      minAvgMaxTestRelErrorAnalyzer.CollectMaxValueInResultsParameter.Value = new BoolValue(false);
-      #endregion
-      #endregion
-
-      #region operator graph
-      OperatorGraph.InitialOperator = subScopesProcessor;
-      subScopesProcessor.Operator = trainingQualityCalculator;
-      trainingQualityCalculator.Successor = testQualityCalculator;
-      testQualityCalculator.Successor = null;
-      subScopesProcessor.Successor = minAvgMaxTrainingMseAnalyzer;
-      minAvgMaxTrainingMseAnalyzer.Successor = minAvgMaxTestMseAnalyzer;
-      minAvgMaxTestMseAnalyzer.Successor = minAvgMaxTrainingRSquaredAnalyzer;
-      minAvgMaxTrainingRSquaredAnalyzer.Successor = minAvgMaxTestRSquaredAnalyzer;
-      minAvgMaxTestRSquaredAnalyzer.Successor = minAvgMaxTrainingRelErrorAnalyzer;
-      minAvgMaxTrainingRelErrorAnalyzer.Successor = minAvgMaxTestRelErrorAnalyzer;
-      minAvgMaxTestRelErrorAnalyzer.Successor = null;
-      #endregion
-
-      Initialize();
     }
 
@@ -293,23 +159,114 @@
     private SymbolicRegressionModelQualityAnalyzer(bool deserializing) : base() { }
 
-    [StorableHook(HookType.AfterDeserialization)]
-    private void Initialize() {
-      SymbolicExpressionTreeParameter.DepthChanged += new EventHandler(SymbolicExpressionTreeParameter_DepthChanged);
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      SymbolicRegressionModelQualityAnalyzer clone = (SymbolicRegressionModelQualityAnalyzer)base.Clone(cloner);
-      clone.Initialize();
-      return clone;
-    }
-
-    private void SymbolicExpressionTreeParameter_DepthChanged(object sender, EventArgs e) {
-      subScopesProcessor.Depth.Value = SymbolicExpressionTreeParameter.Depth;
-      minAvgMaxTrainingMseAnalyzer.ValueParameter.Depth = SymbolicExpressionTreeParameter.Depth;
-      minAvgMaxTrainingRelErrorAnalyzer.ValueParameter.Depth = SymbolicExpressionTreeParameter.Depth;
-      minAvgMaxTrainingRSquaredAnalyzer.ValueParameter.Depth = SymbolicExpressionTreeParameter.Depth;
-      minAvgMaxTestMseAnalyzer.ValueParameter.Depth = SymbolicExpressionTreeParameter.Depth;
-      minAvgMaxTestRelErrorAnalyzer.ValueParameter.Depth = SymbolicExpressionTreeParameter.Depth;
-      minAvgMaxTestRSquaredAnalyzer.ValueParameter.Depth = SymbolicExpressionTreeParameter.Depth;
+    public override IOperation Apply() {
+      Analyze(SymbolicExpressionTreeParameter.ActualValue, SymbolicExpressionTreeInterpreterParameter.ActualValue,
+        UpperEstimationLimit.Value, LowerEstimationLimit.Value, ProblemDataParameter.ActualValue,
+        TrainingSamplesStartParameter.ActualValue.Value, TrainingSamplesEndParameter.ActualValue.Value,
+        TestSamplesStartParameter.ActualValue.Value, TestSamplesEndParameter.ActualValue.Value,
+        ResultsParameter.ActualValue);
+      return base.Apply();
+    }
+
+    public static void Analyze(IEnumerable<SymbolicExpressionTree> trees, ISymbolicExpressionTreeInterpreter interpreter,
+      double upperEstimationLimit, double lowerEstimationLimit,
+      DataAnalysisProblemData problemData, int trainingStart, int trainingEnd, int testStart, int testEnd, ResultCollection results) {
+      int targetVariableIndex = problemData.Dataset.GetVariableIndex(problemData.TargetVariable.Value);
+      IEnumerable<double> originalTrainingValues = problemData.Dataset.GetEnumeratedVariableValues(targetVariableIndex, trainingStart, trainingEnd);
+      IEnumerable<double> originalTestValues = problemData.Dataset.GetEnumeratedVariableValues(targetVariableIndex, testStart, testEnd);
+      List<double> trainingMse = new List<double>();
+      List<double> trainingR2 = new List<double>();
+      List<double> trainingRelErr = new List<double>();
+      List<double> testMse = new List<double>();
+      List<double> testR2 = new List<double>();
+      List<double> testRelErr = new List<double>();
+
+      OnlineMeanSquaredErrorEvaluator mseEvaluator = new OnlineMeanSquaredErrorEvaluator();
+      OnlineMeanAbsolutePercentageErrorEvaluator relErrEvaluator = new OnlineMeanAbsolutePercentageErrorEvaluator();
+      OnlinePearsonsRSquaredEvaluator r2Evaluator = new OnlinePearsonsRSquaredEvaluator();
+
+      foreach (var tree in trees) {
+        #region training
+        var estimatedTrainingValues = interpreter.GetSymbolicExpressionTreeValues(tree, problemData.Dataset, Enumerable.Range(trainingStart, trainingEnd - trainingStart));
+        mseEvaluator.Reset();
+        r2Evaluator.Reset();
+        relErrEvaluator.Reset();
+        var estimatedEnumerator = estimatedTrainingValues.GetEnumerator();
+        var originalEnumerator = originalTrainingValues.GetEnumerator();
+        while (estimatedEnumerator.MoveNext() & originalEnumerator.MoveNext()) {
+          double estimated = estimatedEnumerator.Current;
+          if (double.IsNaN(estimated)) estimated = upperEstimationLimit;
+          else estimated = Math.Min(upperEstimationLimit, Math.Max(lowerEstimationLimit, estimated));
+          mseEvaluator.Add(originalEnumerator.Current, estimated);
+          r2Evaluator.Add(originalEnumerator.Current, estimated);
+          relErrEvaluator.Add(originalEnumerator.Current, estimated);
+        }
+        if (estimatedEnumerator.MoveNext() || originalEnumerator.MoveNext()) {
+          throw new InvalidOperationException("Number of elements in estimated and original enumeration doesn't match.");
+        }
+        trainingMse.Add(mseEvaluator.MeanSquaredError);
+        trainingR2.Add(r2Evaluator.RSquared);
+        trainingRelErr.Add(relErrEvaluator.MeanAbsolutePercentageError);
+        #endregion
+        #region test
+        var estimatedTestValues = interpreter.GetSymbolicExpressionTreeValues(tree, problemData.Dataset, Enumerable.Range(testStart, testEnd - testStart));
+
+        mseEvaluator.Reset();
+        r2Evaluator.Reset();
+        relErrEvaluator.Reset();
+        estimatedEnumerator = estimatedTestValues.GetEnumerator();
+        originalEnumerator = originalTestValues.GetEnumerator();
+        while (estimatedEnumerator.MoveNext() & originalEnumerator.MoveNext()) {
+          double estimated = estimatedEnumerator.Current;
+          if (double.IsNaN(estimated)) estimated = upperEstimationLimit;
+          else estimated = Math.Min(upperEstimationLimit, Math.Max(lowerEstimationLimit, estimated));
+          mseEvaluator.Add(originalEnumerator.Current, estimated);
+          r2Evaluator.Add(originalEnumerator.Current, estimated);
+          relErrEvaluator.Add(originalEnumerator.Current, estimated);
+        }
+        if (estimatedEnumerator.MoveNext() || originalEnumerator.MoveNext()) {
+          throw new InvalidOperationException("Number of elements in estimated and original enumeration doesn't match.");
+        }
+        testMse.Add(mseEvaluator.MeanSquaredError);
+        testR2.Add(r2Evaluator.RSquared);
+        testRelErr.Add(relErrEvaluator.MeanAbsolutePercentageError);
+        #endregion
+      }
+
+      AddResultTableValues(results, MeanSquaredErrorValuesParameterName, "mean squared error (training)", trainingMse.Min(), trainingMse.Average(), trainingMse.Max());
+      AddResultTableValues(results, MeanSquaredErrorValuesParameterName, "mean squared error (test)", testMse.Min(), testMse.Average(), testMse.Max());
+      AddResultTableValues(results, RelativeErrorValuesParameterName, "mean relative error (training)", trainingRelErr.Min(), trainingRelErr.Average(), trainingRelErr.Max());
+      AddResultTableValues(results, RelativeErrorValuesParameterName, "mean relative error (test)", testRelErr.Min(), testRelErr.Average(), testRelErr.Max());
+      AddResultTableValues(results, RSquaredValuesParameterName, "Pearson's R² (training)", trainingR2.Min(), trainingR2.Average(), trainingR2.Max());
+      AddResultTableValues(results, RSquaredValuesParameterName, "Pearson's R² (test)", testR2.Min(), testR2.Average(), testR2.Max());
+    }
+
+    private static void AddResultTableValues(ResultCollection results, string tableName, string valueName, double minValue, double avgValue, double maxValue) {
+      if (!results.ContainsKey(tableName)) {
+        results.Add(new Result(tableName, new DataTable(tableName)));
+      }
+      DataTable table = (DataTable)results[tableName].Value;
+      AddValue(table, minValue, "Min. " + valueName, string.Empty);
+      AddValue(table, avgValue, "Avg. " + valueName, string.Empty);
+      AddValue(table, maxValue, "Max. " + valueName, string.Empty);
+    }
+
+    private static void AddValue(DataTable table, double data, string name, string description) {
+      DataRow row;
+      table.Rows.TryGetValue(name, out row);
+      if (row == null) {
+        row = new DataRow(name, description);
+        row.Values.Add(data);
+        table.Rows.Add(row);
+      } else {
+        row.Values.Add(data);
+      }
+    }
+
+
+    private static void SetResultValue(ResultCollection results, string name, double value) {
+      if (results.ContainsKey(name))
+        results[name].Value = new DoubleValue(value);
+      else
+        results.Add(new Result(name, new DoubleValue(value)));
     }
   }
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SymbolicRegressionMeanSquaredErrorEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SymbolicRegressionMeanSquaredErrorEvaluator.cs	(revision 3995)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SymbolicRegressionMeanSquaredErrorEvaluator.cs	(revision 3996)
@@ -72,9 +72,25 @@
 
     public static double Calculate(ISymbolicExpressionTreeInterpreter interpreter, SymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, Dataset dataset, string targetVariable, int start, int end) {
-      var estimatedValues = from x in interpreter.GetSymbolicExpressionTreeValues(solution, dataset, Enumerable.Range(start, end - start))
-                            let boundedX = Math.Min(upperEstimationLimit, Math.Max(lowerEstimationLimit, x))
-                            select double.IsNaN(boundedX) ? upperEstimationLimit : boundedX;
-      var originalValues = dataset.GetEnumeratedVariableValues(targetVariable, start, end);
-      return SimpleMSEEvaluator.Calculate(originalValues, estimatedValues);
+      IEnumerable<double> estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, dataset, Enumerable.Range(start, end - start));
+      IEnumerable<double> originalValues = dataset.GetEnumeratedVariableValues(targetVariable, start, end);
+      IEnumerator<double> originalEnumerator = originalValues.GetEnumerator();
+      IEnumerator<double> estimatedEnumerator = estimatedValues.GetEnumerator();
+      OnlineMeanSquaredErrorEvaluator mseEvaluator = new OnlineMeanSquaredErrorEvaluator();
+
+      while (originalEnumerator.MoveNext() & estimatedEnumerator.MoveNext()) {
+        double estimated = estimatedEnumerator.Current;
+        double original = originalEnumerator.Current;
+        if (double.IsNaN(estimated))
+          estimated = upperEstimationLimit;
+        else
+          estimated = Math.Min(upperEstimationLimit, Math.Max(lowerEstimationLimit, estimated));
+        mseEvaluator.Add(original, estimated);
+      }
+
+      if (estimatedEnumerator.MoveNext() || originalEnumerator.MoveNext()) {
+        throw new ArgumentException("Number of elements in original and estimated enumeration doesn't match.");
+      } else {
+        return mseEvaluator.MeanSquaredError;
+      }
     }
   }
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SymbolicRegressionProblem.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SymbolicRegressionProblem.cs	(revision 3995)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SymbolicRegressionProblem.cs	(revision 3996)
@@ -340,7 +340,7 @@
       operators = new List<IOperator>();
       operators.AddRange(ApplicationManager.Manager.GetInstances<ISymbolicExpressionTreeOperator>().OfType<IOperator>());
-      operators.Add(new ValidationBestScaledSymbolicRegressionSolutionAnalyzer());
+      operators.Add(new SymbolicRegressionVariableFrequencyAnalyzer());
+      operators.Add(new FixedValidationBestScaledSymbolicRegressionSolutionAnalyzer());
       operators.Add(new MinAverageMaxSymbolicExpressionTreeSizeAnalyzer());
-      operators.Add(new SymbolicRegressionVariableFrequencyAnalyzer());
       ParameterizeOperators();
       ParameterizeAnalyzers();
@@ -365,5 +365,17 @@
       foreach (var analyzer in Analyzers) {
         analyzer.SymbolicExpressionTreeParameter.ActualName = SolutionCreator.SymbolicExpressionTreeParameter.ActualName;
-        var bestValidationSolutionAnalyzer = analyzer as ValidationBestScaledSymbolicRegressionSolutionAnalyzer;
+        var fixedBestValidationSolutionAnalyzer = analyzer as FixedValidationBestScaledSymbolicRegressionSolutionAnalyzer;
+        if (fixedBestValidationSolutionAnalyzer != null) {
+          fixedBestValidationSolutionAnalyzer.ProblemDataParameter.ActualName = DataAnalysisProblemDataParameter.Name;
+          fixedBestValidationSolutionAnalyzer.UpperEstimationLimitParameter.ActualName = UpperEstimationLimitParameter.Name;
+          fixedBestValidationSolutionAnalyzer.LowerEstimationLimitParameter.ActualName = LowerEstimationLimitParameter.Name;
+          fixedBestValidationSolutionAnalyzer.SymbolicExpressionTreeInterpreterParameter.ActualName = SymbolicExpressionTreeInterpreterParameter.Name;
+          fixedBestValidationSolutionAnalyzer.SymbolicExpressionTreeParameter.ActualName = SolutionCreator.SymbolicExpressionTreeParameter.ActualName;
+          fixedBestValidationSolutionAnalyzer.ValidationSamplesStartParameter.Value = ValidationSamplesStart;
+          fixedBestValidationSolutionAnalyzer.ValidationSamplesEndParameter.Value = ValidationSamplesEnd;
+          fixedBestValidationSolutionAnalyzer.BestKnownQualityParameter.ActualName = BestKnownQualityParameter.Name;
+          fixedBestValidationSolutionAnalyzer.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
+        }
+        var bestValidationSolutionAnalyzer = analyzer as FixedValidationBestScaledSymbolicRegressionSolutionAnalyzer;
         if (bestValidationSolutionAnalyzer != null) {
           bestValidationSolutionAnalyzer.ProblemDataParameter.ActualName = DataAnalysisProblemDataParameter.Name;
@@ -372,10 +384,6 @@
           bestValidationSolutionAnalyzer.SymbolicExpressionTreeInterpreterParameter.ActualName = SymbolicExpressionTreeInterpreterParameter.Name;
           bestValidationSolutionAnalyzer.SymbolicExpressionTreeParameter.ActualName = SolutionCreator.SymbolicExpressionTreeParameter.ActualName;
-          bestValidationSolutionAnalyzer.TrainingSamplesStartParameter.Value = TrainingSamplesStart;
-          bestValidationSolutionAnalyzer.TrainingSamplesEndParameter.Value = TrainingSamplesEnd;
           bestValidationSolutionAnalyzer.ValidationSamplesStartParameter.Value = ValidationSamplesStart;
           bestValidationSolutionAnalyzer.ValidationSamplesEndParameter.Value = ValidationSamplesEnd;
-          bestValidationSolutionAnalyzer.TestSamplesStartParameter.Value = TestSamplesStart;
-          bestValidationSolutionAnalyzer.TestSamplesEndParameter.Value = TestSamplesEnd;
           bestValidationSolutionAnalyzer.BestKnownQualityParameter.ActualName = BestKnownQualityParameter.Name;
           bestValidationSolutionAnalyzer.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SymbolicRegressionScaledMeanSquaredErrorEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SymbolicRegressionScaledMeanSquaredErrorEvaluator.cs	(revision 3995)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SymbolicRegressionScaledMeanSquaredErrorEvaluator.cs	(revision 3996)
@@ -83,35 +83,24 @@
 
     public static double CalculateWithScaling(ISymbolicExpressionTreeInterpreter interpreter, SymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, Dataset dataset, string targetVariable, int start, int end, double beta, double alpha) {
-      //IEnumerable<double> estimatedValues = from x in interpreter.GetSymbolicExpressionTreeValues(solution, dataset, Enumerable.Range(start, end - start))
-      //                                      let boundedX = Math.Min(upperEstimationLimit, Math.Max(lowerEstimationLimit, x * beta + alpha))
-      //                                      select double.IsNaN(boundedX) ? upperEstimationLimit : boundedX;
       IEnumerable<double> estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, dataset, Enumerable.Range(start, end - start));
       IEnumerable<double> originalValues = dataset.GetEnumeratedVariableValues(targetVariable, start, end);
       IEnumerator<double> originalEnumerator = originalValues.GetEnumerator();
       IEnumerator<double> estimatedEnumerator = estimatedValues.GetEnumerator();
-      double cnt = 0;
-      double sse = 0;
+      OnlineMeanSquaredErrorEvaluator mseEvaluator = new OnlineMeanSquaredErrorEvaluator();
 
       while (originalEnumerator.MoveNext() & estimatedEnumerator.MoveNext()) {
         double estimated = estimatedEnumerator.Current * beta + alpha;
         double original = originalEnumerator.Current;
-        estimated = Math.Min(upperEstimationLimit, Math.Max(lowerEstimationLimit, estimated));
         if (double.IsNaN(estimated))
           estimated = upperEstimationLimit;
-        if (!double.IsNaN(estimated) && !double.IsInfinity(estimated) &&
-            !double.IsNaN(original) && !double.IsInfinity(original)) {
-          double error = estimated - original;
-          sse += error * error;
-          cnt++;
-        }
+        else
+          estimated = Math.Min(upperEstimationLimit, Math.Max(lowerEstimationLimit, estimated));
+        mseEvaluator.Add(original, estimated);
       }
 
       if (estimatedEnumerator.MoveNext() || originalEnumerator.MoveNext()) {
         throw new ArgumentException("Number of elements in original and estimated enumeration doesn't match.");
-      } else if (cnt == 0) {
-        throw new ArgumentException("Mean squared errors is not defined for input vectors of NaN or Inf");
       } else {
-        double mse = sse / cnt;
-        return mse;
+        return mseEvaluator.MeanSquaredError;
       }
     }
