Index: trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/HeuristicLab.Problems.DataAnalysis.Regression-3.3.csproj
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/HeuristicLab.Problems.DataAnalysis.Regression-3.3.csproj	(revision 3651)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/HeuristicLab.Problems.DataAnalysis.Regression-3.3.csproj	(revision 3652)
@@ -86,4 +86,5 @@
     <Compile Include="HeuristicLabProblemsDataAnalysisRegressionPlugin.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Symbolic\Analyzers\PopulationSymbolicRegressionModelQualityAnalyzer.cs" />
     <Compile Include="Symbolic\Analyzers\PopulationSymbolicRegressionVariableFrequencyAnalyzer.cs" />
     <Compile Include="Symbolic\Analyzers\PopulationValidationBestScaledSymbolicRegressionSolutionAnalyzer.cs" />
@@ -91,4 +92,5 @@
     <Compile Include="Symbolic\Analyzers\ISymbolicRegressionSolutionPopulationAnalyzer.cs" />
     <Compile Include="Symbolic\Analyzers\PopulationBestSymbolicRegressionSolutionAnalyzer.cs" />
+    <Compile Include="Symbolic\SimpleSymbolicRegressionEvaluator.cs" />
     <Compile Include="Symbolic\SymbolicRegressionScaledMeanSquaredErrorEvaluator.cs" />
     <Compile Include="Symbolic\SymbolicRegressionSolution.cs" />
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/Analyzers/PopulationSymbolicRegressionModelQualityAnalyzer.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/Analyzers/PopulationSymbolicRegressionModelQualityAnalyzer.cs	(revision 3652)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/Analyzers/PopulationSymbolicRegressionModelQualityAnalyzer.cs	(revision 3652)
@@ -0,0 +1,137 @@
+#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 HeuristicLab.Problems.DataAnalysis.Evaluators;
+
+namespace HeuristicLab.Problems.DataAnalysis.Regression.Symbolic.Analyzers {
+  /// <summary>
+  /// "An operator for analyzing the quality of symbolic regression solutions symbolic expression tree encoding."
+  /// </summary>
+  [Item("PopulationSymbolicRegressionModelQualityAnalyzer", "An operator for analyzing the quality of symbolic regression solutions symbolic expression tree encoding.")]
+  [StorableClass]
+  public sealed class PopulationSymbolicRegressionModelQualityAnalyzer : AlgorithmOperator, ISymbolicRegressionSolutionPopulationAnalyzer {
+    private const string SymbolicExpressionTreeInterpreterParameterName = "SymbolicExpressionTreeInterpreter";
+    private const string SymbolicExpressionTreeParameterName = "SymbolicExpressionTree";
+    private const string ProblemDataParameterName = "ProblemData";
+    private const string ResultsParameterName = "Results";
+    private const string TrainingValuesParameterName = "TrainingValues";
+    private const string TrainingRSQuaredParameterName = "TrainingRSquared";
+    private const string MinRSQuaredParameterName = "MinRSquared";
+    private const string AvgRSQuaredParameterName = "AvgRSquared";
+    private const string MaxRSQuaredParameterName = "MaxRSquared";
+    private const string TrainingRSquaredValuesParameterName = "TrainingRSquaredValues";
+    private const string SamplesStartParameterName = "SamplesStart";
+    private const string SamplesEndParameterName = "SamplesEnd";
+    private const string UpperEstimationLimitParameterName = "UpperEstimationLimit";
+    private const string LowerEstimationLimitParameterName = "LowerEstimationLimit";
+
+    #region parameter properties
+    public ILookupParameter<ISymbolicExpressionTreeInterpreter> SymbolicExpressionTreeInterpreterParameter {
+      get { return (ILookupParameter<ISymbolicExpressionTreeInterpreter>)Parameters[SymbolicExpressionTreeInterpreterParameterName]; }
+    }
+    public ILookupParameter<ItemArray<SymbolicExpressionTree>> SymbolicExpressionTreeParameter {
+      get { return (ILookupParameter<ItemArray<SymbolicExpressionTree>>)Parameters[SymbolicExpressionTreeParameterName]; }
+    }
+    public ILookupParameter<DataAnalysisProblemData> ProblemDataParameter {
+      get { return (ILookupParameter<DataAnalysisProblemData>)Parameters[ProblemDataParameterName]; }
+    }
+    public ILookupParameter<ResultCollection> ResultsParameter {
+      get { return (ILookupParameter<ResultCollection>)Parameters[ResultsParameterName]; }
+    }
+    public IValueLookupParameter<IntValue> SamplesStartParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters[SamplesStartParameterName]; }
+    }
+    public IValueLookupParameter<IntValue> SamplesEndParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters[SamplesEndParameterName]; }
+    }
+    public IValueLookupParameter<DoubleValue> UpperEstimationLimitParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters[UpperEstimationLimitParameterName]; }
+    }
+    public IValueLookupParameter<DoubleValue> LowerEstimationLimitParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters[LowerEstimationLimitParameterName]; }
+    }
+    #endregion
+
+    public PopulationSymbolicRegressionModelQualityAnalyzer()
+      : base() {
+      Parameters.Add(new LookupParameter<ISymbolicExpressionTreeInterpreter>(SymbolicExpressionTreeInterpreterParameterName, "The interpreter that should be used to calculate the output values of the symbolic expression tree."));
+      Parameters.Add(new SubScopesLookupParameter<SymbolicExpressionTree>(SymbolicExpressionTreeParameterName, "The symbolic expression trees to analyze."));
+      Parameters.Add(new LookupParameter<DataAnalysisProblemData>(ProblemDataParameterName, "The problem data containing the input varaibles for the symbolic regression problem."));
+      Parameters.Add(new LookupParameter<ResultCollection>(ResultsParameterName, "The result collection where the best symbolic regression solution should be stored."));
+      Parameters.Add(new ValueLookupParameter<IntValue>(SamplesStartParameterName, "The first index of the data set partition on which the model quality values should be calculated."));
+      Parameters.Add(new ValueLookupParameter<IntValue>(SamplesEndParameterName, "The first index of the data set partition on which the model quality values should be calculated."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>(UpperEstimationLimitParameterName, "The upper limit that should be used as cut off value for the output values of symbolic expression trees."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>(LowerEstimationLimitParameterName, "The lower limit that should be used as cut off value for the output values of symbolic expression trees."));
+
+      #region operator initialization
+      // should be extended to calculate MSE, rel. Error and R² on the training (validation) and test set
+      UniformSubScopesProcessor subScopesProcessor = new UniformSubScopesProcessor();
+      SimpleSymbolicRegressionEvaluator simpleEvaluator = new SimpleSymbolicRegressionEvaluator();
+      SimpleRSquaredEvaluator simpleR2Evalator = new SimpleRSquaredEvaluator();
+      PopulationMinAverageMaxValueAnalyzer minAvgMaxAnalyzer = new PopulationMinAverageMaxValueAnalyzer();
+      #endregion
+
+      #region parameter wiring
+      simpleEvaluator.SymbolicExpressionTreeParameter.ActualName = SymbolicExpressionTreeParameter.Name;
+      simpleEvaluator.RegressionProblemDataParameter.ActualName = ProblemDataParameter.Name;
+      simpleEvaluator.SamplesStartParameter.ActualName = SamplesStartParameter.Name;
+      simpleEvaluator.SamplesEndParameter.ActualName = SamplesEndParameter.Name;
+      simpleEvaluator.LowerEstimationLimitParameter.ActualName = LowerEstimationLimitParameter.Name;
+      simpleEvaluator.UpperEstimationLimitParameter.ActualName = UpperEstimationLimitParameter.Name;
+      simpleEvaluator.SymbolicExpressionTreeInterpreterParameter.ActualName = SymbolicExpressionTreeInterpreterParameter.Name;
+      simpleEvaluator.ValuesParameter.ActualName = TrainingValuesParameterName;
+      simpleR2Evalator.ValuesParameter.ActualName = TrainingValuesParameterName;
+      simpleR2Evalator.RSquaredParameter.ActualName = TrainingRSQuaredParameterName;
+      minAvgMaxAnalyzer.ValueParameter.ActualName = TrainingRSQuaredParameterName;
+      minAvgMaxAnalyzer.AverageValueParameter.ActualName = AvgRSQuaredParameterName;
+      minAvgMaxAnalyzer.MaxValueParameter.ActualName = MaxRSQuaredParameterName;
+      minAvgMaxAnalyzer.MinValueParameter.ActualName = MinRSQuaredParameterName;
+      minAvgMaxAnalyzer.ResultsParameter.ActualName = ResultsParameter.Name;
+      minAvgMaxAnalyzer.ValuesParameter.ActualName = TrainingRSquaredValuesParameterName;
+      #endregion
+
+      #region operator graph
+      OperatorGraph.InitialOperator = subScopesProcessor;
+      subScopesProcessor.Operator = simpleEvaluator;
+      simpleEvaluator.Successor = simpleR2Evalator;
+      simpleR2Evalator.Successor = null;
+      subScopesProcessor.Successor = minAvgMaxAnalyzer;
+      minAvgMaxAnalyzer.Successor = null;
+      #endregion
+
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SimpleSymbolicRegressionEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SimpleSymbolicRegressionEvaluator.cs	(revision 3652)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SimpleSymbolicRegressionEvaluator.cs	(revision 3652)
@@ -0,0 +1,139 @@
+#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;
+using System.Collections.Generic;
+using System.Linq;
+using System.Drawing;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Problems.DataAnalysis;
+using HeuristicLab.Operators;
+using HeuristicLab.Problems.DataAnalysis.Symbolic;
+
+namespace HeuristicLab.Problems.DataAnalysis.Regression.Symbolic {
+  [Item("SimpleSymbolicRegressionEvaluator", "Evaluates a symbolic regression solution and outputs a matrix of target and estimated values.")]
+  [StorableClass]
+  public class SimpleSymbolicRegressionEvaluator : SingleSuccessorOperator {
+    private const string SymbolicExpressionTreeInterpreterParameterName = "SymbolicExpressionTreeInterpreter";
+    private const string FunctionTreeParameterName = "FunctionTree";
+    private const string RegressionProblemDataParameterName = "RegressionProblemData";
+    private const string SamplesStartParameterName = "SamplesStart";
+    private const string SamplesEndParameterName = "SamplesEnd";
+    private const string ValuesParameterName = "Values";
+    private const string UpperEstimationLimitParameterName = "UpperEstimationLimit";
+    private const string LowerEstimationLimitParameterName = "LowerEstimationLimit";
+
+    #region ISymbolicRegressionEvaluator Members
+    public ILookupParameter<ISymbolicExpressionTreeInterpreter> SymbolicExpressionTreeInterpreterParameter {
+      get { return (ILookupParameter<ISymbolicExpressionTreeInterpreter>)Parameters[SymbolicExpressionTreeInterpreterParameterName]; }
+    }
+
+    public ILookupParameter<SymbolicExpressionTree> SymbolicExpressionTreeParameter {
+      get { return (ILookupParameter<SymbolicExpressionTree>)Parameters[FunctionTreeParameterName]; }
+    }
+
+    public ILookupParameter<DataAnalysisProblemData> RegressionProblemDataParameter {
+      get { return (ILookupParameter<DataAnalysisProblemData>)Parameters[RegressionProblemDataParameterName]; }
+    }
+
+    public IValueLookupParameter<IntValue> SamplesStartParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters[SamplesStartParameterName]; }
+    }
+
+    public IValueLookupParameter<IntValue> SamplesEndParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters[SamplesEndParameterName]; }
+    }
+    public IValueLookupParameter<DoubleValue> UpperEstimationLimitParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters[UpperEstimationLimitParameterName]; }
+    }
+    public IValueLookupParameter<DoubleValue> LowerEstimationLimitParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters[LowerEstimationLimitParameterName]; }
+    }
+
+    public ILookupParameter<DoubleMatrix> ValuesParameter {
+      get { return (ILookupParameter<DoubleMatrix>)Parameters[ValuesParameterName]; }
+    }
+
+    #endregion
+    #region properties
+    public ISymbolicExpressionTreeInterpreter SymbolicExpressionTreeInterpreter {
+      get { return SymbolicExpressionTreeInterpreterParameter.ActualValue; }
+    }
+    public SymbolicExpressionTree SymbolicExpressionTree {
+      get { return SymbolicExpressionTreeParameter.ActualValue; }
+    }
+    public DataAnalysisProblemData RegressionProblemData {
+      get { return RegressionProblemDataParameter.ActualValue; }
+    }
+    public IntValue SamplesStart {
+      get { return SamplesStartParameter.ActualValue; }
+    }
+    public IntValue SamplesEnd {
+      get { return SamplesEndParameter.ActualValue; }
+    }
+    public DoubleValue UpperEstimationLimit {
+      get { return UpperEstimationLimitParameter.ActualValue; }
+    }
+    public DoubleValue LowerEstimationLimit {
+      get { return LowerEstimationLimitParameter.ActualValue; }
+    }
+
+    #endregion
+
+    public SimpleSymbolicRegressionEvaluator()
+      : base() {
+      Parameters.Add(new LookupParameter<ISymbolicExpressionTreeInterpreter>(SymbolicExpressionTreeInterpreterParameterName, "The interpreter that should be used to calculate the output values of the symbolic expression tree."));
+      Parameters.Add(new LookupParameter<SymbolicExpressionTree>(FunctionTreeParameterName, "The symbolic regression solution encoded as a symbolic expression tree."));
+      Parameters.Add(new LookupParameter<DataAnalysisProblemData>(RegressionProblemDataParameterName, "The problem data on which the symbolic regression solution should be evaluated."));
+      Parameters.Add(new ValueLookupParameter<IntValue>(SamplesStartParameterName, "The start index of the dataset partition on which the symbolic regression solution should be evaluated."));
+      Parameters.Add(new ValueLookupParameter<IntValue>(SamplesEndParameterName, "The end index of the dataset partition on which the symbolic regression solution should be evaluated."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>(UpperEstimationLimitParameterName, "The upper limit that should be used as cut off value for the output values of symbolic expression trees."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>(LowerEstimationLimitParameterName, "The lower limit that should be used as cut off value for the output values of symbolic expression trees."));
+      Parameters.Add(new LookupParameter<DoubleMatrix>(ValuesParameterName, "The matrix of target and estimated values as generated by the symbolic regression solution."));
+    }
+
+    public override IOperation Apply() {
+      Dataset dataset = RegressionProblemData.Dataset;
+      string targetVariable = RegressionProblemData.TargetVariable.Value;
+      ISymbolicExpressionTreeInterpreter interpreter = SymbolicExpressionTreeInterpreter;
+      SymbolicExpressionTree tree = SymbolicExpressionTree;
+      int start = SamplesStart.Value;
+      int end = SamplesEnd.Value;
+      double lowerEstimationLimit = LowerEstimationLimit.Value;
+      double upperEstimationLimit = UpperEstimationLimit.Value;
+      int targetVariableIndex = dataset.GetVariableIndex(targetVariable);
+      var estimatedValues = from x in interpreter.GetSymbolicExpressionTreeValues(tree, dataset, Enumerable.Range(start, end - start))
+                            let boundedX = Math.Min(upperEstimationLimit, Math.Max(lowerEstimationLimit, x))
+                            select double.IsNaN(boundedX) ? upperEstimationLimit : boundedX;
+      var originalValues = from row in Enumerable.Range(start, end - start) select dataset[row, targetVariableIndex];
+      // NB: indexes must match SimpleEvaluator.ORIGINAL_INDEX and SimpleEvaluator.ESTIMATED_INDEX
+      ValuesParameter.ActualValue = new DoubleMatrix(MatrixExtensions<double>.Create(originalValues.ToArray(), estimatedValues.ToArray()));
+      return base.Apply();
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SymbolicRegressionProblem.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SymbolicRegressionProblem.cs	(revision 3651)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SymbolicRegressionProblem.cs	(revision 3652)
@@ -353,4 +353,5 @@
       operators.Add(new PopulationMinAvgMaxTreeSizeAnalyzer());
       operators.Add(new PopulationSymbolicRegressionVariableFrequencyAnalyzer());
+      operators.Add(new PopulationSymbolicRegressionModelQualityAnalyzer());
       ParameterizeOperators();
       ParameterizeAnalyzers();
@@ -389,4 +390,14 @@
           varFreqAnalyzer.ProblemDataParameter.ActualName = DataAnalysisProblemDataParameter.Name;
         }
+        var modelQualityAnalyzer = analyzer as PopulationSymbolicRegressionModelQualityAnalyzer;
+        if (modelQualityAnalyzer != null) {
+          modelQualityAnalyzer.ProblemDataParameter.ActualName = DataAnalysisProblemDataParameter.Name;
+          modelQualityAnalyzer.SymbolicExpressionTreeParameter.ActualName = SolutionCreator.SymbolicExpressionTreeParameter.ActualName;
+          modelQualityAnalyzer.UpperEstimationLimitParameter.ActualName = UpperEstimationLimitParameter.Name;
+          modelQualityAnalyzer.LowerEstimationLimitParameter.ActualName = LowerEstimationLimitParameter.Name;
+          modelQualityAnalyzer.SymbolicExpressionTreeInterpreterParameter.ActualName = SymbolicExpressionTreeInterpreterParameter.Name;
+          modelQualityAnalyzer.SamplesStartParameter.Value = TrainingSamplesStart;
+          modelQualityAnalyzer.SamplesEndParameter.Value = ValidationSamplesEnd;
+        }
       }
       foreach (ISymbolicExpressionTreePopulationAnalyzer analyzer in Operators.OfType<ISymbolicExpressionTreePopulationAnalyzer>()) {
