Index: /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.Classification/AccuracyEvaluator.cs
===================================================================
--- /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.Classification/AccuracyEvaluator.cs	(revision 646)
+++ /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.Classification/AccuracyEvaluator.cs	(revision 646)
@@ -0,0 +1,93 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 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.Text;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.GP.StructureIdentification;
+
+namespace HeuristicLab.GP.Classification {
+  public class AccuracyEvaluator : GPEvaluatorBase {
+    private const double EPSILON = 1.0E-6;
+    private double[] classesArr;
+    private double[] thresholds;
+    private DoubleData accuracy;
+    public override string Description {
+      get {
+        return @"Calculates the total accuracy of the model (ratio of correctly classified instances to total number of instances) given a model and the list of possible target class values.";
+      }
+    }
+
+    public AccuracyEvaluator()
+      : base() {
+      AddVariableInfo(new VariableInfo("Accuracy", "The total accuracy of the model (ratio of correctly classified instances to total number of instances)", typeof(DoubleData), VariableKind.New));
+      AddVariableInfo(new VariableInfo("TargetClassValues", "The original class values of target variable (for instance negative=0 and positive=1).", typeof(ItemList<DoubleData>), VariableKind.In));
+    }
+
+    public override IOperation Apply(IScope scope) {
+      accuracy = GetVariableValue<DoubleData>("Accuracy", scope, false, false);
+      if(accuracy == null) {
+        accuracy = new DoubleData();
+        scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("Accuracy"), accuracy));
+      }
+
+      ItemList<DoubleData> classes = GetVariableValue<ItemList<DoubleData>>("TargetClassValues", scope, true);
+      classesArr = new double[classes.Count];
+      for(int i = 0; i < classesArr.Length; i++) classesArr[i] = classes[i].Data;
+      Array.Sort(classesArr);
+      thresholds = new double[classes.Count - 1];
+      for(int i = 0; i < classesArr.Length - 1; i++) {
+        thresholds[i] = (classesArr[i] + classesArr[i + 1]) / 2.0;
+      }
+
+      return base.Apply(scope);
+    }
+
+    public override void Evaluate(int start, int end) {
+      int nSamples = end - start;
+      int nCorrect = 0;
+      for(int sample = start; sample < end; sample++) {
+        double est = GetEstimatedValue(sample);
+        double origClass = GetOriginalValue(sample);
+        double estClass = double.NaN;
+        // if estimation is lower than the smallest threshold value -> estimated class is the lower class
+        if(est < thresholds[0]) estClass = classesArr[0];
+        // if estimation is larger (or equal) than the largest threshold value -> estimated class is the upper class
+        else if(est >= thresholds[thresholds.Length - 1]) estClass = classesArr[classesArr.Length - 1];
+        else {
+          // otherwise the estimated class is the class which upper threshold is larger than the estimated value
+          for(int k = 0; k < thresholds.Length; k++) {
+            if(thresholds[k] > est) {
+              estClass = classesArr[k];
+              break;
+            }
+          }
+        }
+        SetOriginalValue(sample, estClass);
+        if(Math.Abs(estClass - origClass) < EPSILON) nCorrect++;
+      }
+      accuracy.Data = nCorrect / (double)nSamples;
+    }
+  }
+}
Index: /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.Classification/ClassificationMatrixEvaluator.cs
===================================================================
--- /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.Classification/ClassificationMatrixEvaluator.cs	(revision 646)
+++ /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.Classification/ClassificationMatrixEvaluator.cs	(revision 646)
@@ -0,0 +1,99 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 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.Text;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.GP.StructureIdentification;
+
+namespace HeuristicLab.GP.Classification {
+  public class ClassificationMatrixEvaluator : GPEvaluatorBase {
+    private const double EPSILON = 1.0E-6;
+    private double[] classesArr;
+    private double[] thresholds;
+    private IntMatrixData matrix;
+    public override string Description {
+      get {
+        return @"Calculates the classifcation matrix of the model.";
+      }
+    }
+
+    public ClassificationMatrixEvaluator()
+      : base() {
+      AddVariableInfo(new VariableInfo("ClassificationMatrix", "The resulting classification matrix of the model", typeof(IntMatrixData), VariableKind.New));
+      AddVariableInfo(new VariableInfo("TargetClassValues", "The original class values of target variable (for instance negative=0 and positive=1).", typeof(ItemList<DoubleData>), VariableKind.In));
+    }
+
+    public override IOperation Apply(IScope scope) {
+      ItemList<DoubleData> classes = GetVariableValue<ItemList<DoubleData>>("TargetClassValues", scope, true);
+      classesArr = new double[classes.Count];
+      for(int i = 0; i < classesArr.Length; i++) classesArr[i] = classes[i].Data;
+      Array.Sort(classesArr);
+      thresholds = new double[classes.Count - 1];
+      for(int i = 0; i < classesArr.Length - 1; i++) {
+        thresholds[i] = (classesArr[i] + classesArr[i + 1]) / 2.0;
+      }
+
+      matrix = GetVariableValue<IntMatrixData>("ClassificationMatrix", scope, false, false);
+      if(matrix == null) {
+        matrix = new IntMatrixData(new int[classesArr.Length, classesArr.Length]);
+        scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("ClassificationMatrix"), matrix));
+      }
+      return base.Apply(scope);
+    }
+
+    public override void Evaluate(int start, int end) {
+      int nSamples = end - start;
+      for(int sample = start; sample < end; sample++) {
+        double est = GetEstimatedValue(sample);
+        double origClass = GetOriginalValue(sample);
+        int estClassIndex = -1;
+        // if estimation is lower than the smallest threshold value -> estimated class is the lower class
+        if(est < thresholds[0]) estClassIndex = 0;
+        // if estimation is larger (or equal) than the largest threshold value -> estimated class is the upper class
+        else if(est >= thresholds[thresholds.Length - 1]) estClassIndex = classesArr.Length - 1;
+        else {
+          // otherwise the estimated class is the class which upper threshold is larger than the estimated value
+          for(int k = 0; k < thresholds.Length; k++) {
+            if(thresholds[k] > est) {
+              estClassIndex = k;
+              break;
+            }
+          }
+        }
+        SetOriginalValue(sample, classesArr[estClassIndex]);
+
+        int origClassIndex = -1;
+        for(int i = 0; i < classesArr.Length; i++) {
+          if(IsEqual(origClass, classesArr[i])) origClassIndex = i;
+        }
+        matrix.Data[origClassIndex, estClassIndex]++;
+      }
+    }
+
+    private bool IsEqual(double x, double y) {
+      return Math.Abs(x - y) < EPSILON;
+    }
+  }
+}
Index: /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.Classification/ClassificationMeanSquaredErrorEvaluator.cs
===================================================================
--- /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.Classification/ClassificationMeanSquaredErrorEvaluator.cs	(revision 646)
+++ /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.Classification/ClassificationMeanSquaredErrorEvaluator.cs	(revision 646)
@@ -0,0 +1,85 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 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.Text;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.GP.StructureIdentification;
+
+namespace HeuristicLab.GP.Classification {
+  public class ClassificationMeanSquaredErrorEvaluator : MeanSquaredErrorEvaluator {
+    private const double EPSILON = 1.0E-6;
+    private double[] classesArr;
+    public override string Description {
+      get {
+        return @"Evaluates 'FunctionTree' for all samples of 'DataSet' and calculates the mean-squared-error
+for the estimated values vs. the real values of 'TargetVariable'.";
+      }
+    }
+
+    public ClassificationMeanSquaredErrorEvaluator()
+      : base() {
+      AddVariableInfo(new VariableInfo("TargetClassValues", "The original class values of target variable (for instance negative=0 and positive=1).", typeof(ItemList<DoubleData>), VariableKind.In));
+    }
+
+    public override IOperation Apply(IScope scope) {
+      ItemList<DoubleData> classes = GetVariableValue<ItemList<DoubleData>>("TargetClassValues", scope, true);
+      classesArr = new double[classes.Count];
+      for(int i = 0; i < classesArr.Length; i++) classesArr[i] = classes[i].Data;
+      Array.Sort(classesArr);
+      return base.Apply(scope);
+    }
+
+    public override void Evaluate(int start, int end) {
+      double errorsSquaredSum = 0;
+      for(int sample = start; sample < end; sample++) {
+        double estimated = GetEstimatedValue(sample);
+        double original = GetOriginalValue(sample);
+        SetOriginalValue(sample, estimated);
+        if(!double.IsNaN(original) && !double.IsInfinity(original)) {
+          double error = estimated - original;
+          // between classes use squared error
+          // on the lower end and upper end only add linear error if the absolute error is larger than 1
+          // the error>1.0 constraint is needed for balance because in the interval ]-1, 1[ the squared error is smaller than the absolute error
+          if((IsEqual(original, classesArr[0]) && error < -1.0) ||
+            (IsEqual(original, classesArr[classesArr.Length - 1]) && error > 1.0)) {
+            errorsSquaredSum += Math.Abs(error); // only add linear error below the smallest class or above the largest class
+          } else {
+            errorsSquaredSum += error * error;
+          }
+        }
+      }
+
+      errorsSquaredSum /= (end - start);
+      if(double.IsNaN(errorsSquaredSum) || double.IsInfinity(errorsSquaredSum)) {
+        errorsSquaredSum = double.MaxValue;
+      }
+      mse.Data = errorsSquaredSum;
+    }
+
+    private bool IsEqual(double x, double y) {
+      return Math.Abs(x - y) < EPSILON;
+    }
+  }
+}
Index: /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.Classification/CrossValidation.cs
===================================================================
--- /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.Classification/CrossValidation.cs	(revision 646)
+++ /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.Classification/CrossValidation.cs	(revision 646)
@@ -0,0 +1,109 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 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.Text;
+using System.Xml;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.DataAnalysis;
+
+namespace HeuristicLab.GP.Classification {
+  public class CrossValidation : OperatorBase {
+
+    private const string DATASET = "Dataset";
+    private const string NFOLD = "n-Fold";
+    private const string TRAININGSAMPLESSTART = "TrainingSamplesStart";
+    private const string TRAININGSAMPLESEND = "TrainingSamplesEnd";
+    private const string VALIDATIONSAMPLESSTART = "ValidationSamplesStart";
+    private const string VALIDATIONSAMPLESEND = "ValidationSamplesEnd";
+    private const string TESTSAMPLESSTART = "TestSamplesStart";
+    private const string TESTSAMPLESEND = "TestSamplesEnd";
+
+    public override string Description {
+      get { return @"TASK"; }
+    }
+
+    public CrossValidation()
+      : base() {
+      AddVariableInfo(new VariableInfo(DATASET, "The original dataset and the new datasets in the newly created subscopes", typeof(Dataset), VariableKind.In));
+      AddVariableInfo(new VariableInfo(NFOLD, "Number of folds for the cross-validation", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo(TRAININGSAMPLESSTART, "The start of training samples in the original dataset and starts of training samples in the new datasets", typeof(IntData), VariableKind.In | VariableKind.New));
+      AddVariableInfo(new VariableInfo(TRAININGSAMPLESEND, "The end of training samples in the original dataset and ends of training samples in the new datasets", typeof(IntData), VariableKind.In | VariableKind.New));
+      AddVariableInfo(new VariableInfo(VALIDATIONSAMPLESSTART, "The start of validation samples in the original dataset and starts of validation samples in the new datasets", typeof(IntData), VariableKind.In | VariableKind.New));
+      AddVariableInfo(new VariableInfo(VALIDATIONSAMPLESEND, "The end of validation samples in the original dataset and ends of validation samples in the new datasets", typeof(IntData), VariableKind.In | VariableKind.New));
+      AddVariableInfo(new VariableInfo(TESTSAMPLESSTART, "The start of the test samples in the new datasets", typeof(IntData), VariableKind.New));
+      AddVariableInfo(new VariableInfo(TESTSAMPLESEND, "The end of the test samples in the new datasets", typeof(IntData), VariableKind.New));
+    }
+
+    public override IOperation Apply(IScope scope) {
+      Dataset origDataset = GetVariableValue<Dataset>(DATASET, scope, true);
+      int nFolds = GetVariableValue<IntData>(NFOLD, scope, true).Data;
+      int origTrainingSamplesStart = GetVariableValue<IntData>(TRAININGSAMPLESSTART, scope, true).Data;
+      int origTrainingSamplesEnd = GetVariableValue<IntData>(TRAININGSAMPLESEND, scope, true).Data;
+      int origValidationSamplesStart = GetVariableValue<IntData>(VALIDATIONSAMPLESSTART, scope, true).Data;
+      int origValidationSamplesEnd = GetVariableValue<IntData>(VALIDATIONSAMPLESEND, scope, true).Data;
+      int n=origDataset.Rows;
+      int origTrainingSamples = (origTrainingSamplesEnd-origTrainingSamplesStart);
+      int origValidationSamples = (origValidationSamplesEnd-origValidationSamplesStart);
+
+      double percentTrainingSamples = origTrainingSamples / (double)(origValidationSamples + origTrainingSamples);
+      int nTestSamples = n / nFolds;
+
+      int newTrainingSamplesStart = 0;
+      int newTrainingSamplesEnd = (int)((n - nTestSamples) * percentTrainingSamples);
+      int newValidationSamplesStart = newTrainingSamplesEnd;
+      int newValidationSamplesEnd = n - nTestSamples;
+      int newTestSamplesStart = n - nTestSamples;
+      int newTestSamplesEnd = n;
+
+      for(int i = 0; i < nFolds; i++) {
+        Scope childScope = new Scope(i.ToString());
+        Dataset rotatedSet = new Dataset();
+
+        double[] samples = new double[origDataset.Samples.Length];
+        Array.Copy(origDataset.Samples, samples, samples.Length);
+        RotateArray(samples, i * nTestSamples * origDataset.Columns);
+
+        rotatedSet.Rows = origDataset.Rows;
+        rotatedSet.Columns = origDataset.Columns;
+        rotatedSet.Samples = samples;
+        childScope.AddVariable(new Variable(scope.TranslateName(DATASET), rotatedSet));
+        childScope.AddVariable(new Variable(scope.TranslateName(TRAININGSAMPLESSTART), new IntData(newTrainingSamplesStart)));
+        childScope.AddVariable(new Variable(scope.TranslateName(TRAININGSAMPLESEND), new IntData(newTrainingSamplesEnd)));
+        childScope.AddVariable(new Variable(scope.TranslateName(VALIDATIONSAMPLESSTART), new IntData(newValidationSamplesStart)));
+        childScope.AddVariable(new Variable(scope.TranslateName(VALIDATIONSAMPLESEND), new IntData(newValidationSamplesEnd)));
+        childScope.AddVariable(new Variable(scope.TranslateName(TESTSAMPLESSTART), new IntData(newTestSamplesStart)));
+        childScope.AddVariable(new Variable(scope.TranslateName(TESTSAMPLESEND), new IntData(newTestSamplesEnd)));
+
+        scope.AddSubScope(childScope);
+      }
+      return null;
+    }
+
+    private void RotateArray(double[] samples, int p) {
+      Array.Reverse(samples, 0, p);
+      Array.Reverse(samples, p, samples.Length - p);
+      Array.Reverse(samples);
+    }
+  }
+}
Index: /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.Classification/FunctionLibraryInjector.cs
===================================================================
--- /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.Classification/FunctionLibraryInjector.cs	(revision 646)
+++ /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.Classification/FunctionLibraryInjector.cs	(revision 646)
@@ -0,0 +1,207 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 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.Text;
+using System.Xml;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.DataAnalysis;
+using HeuristicLab.Constraints;
+using StructId = HeuristicLab.GP.StructureIdentification;
+
+namespace HeuristicLab.GP.Classification {
+  public class FunctionLibraryInjector : OperatorBase {
+    private const string TARGETVARIABLE = "TargetVariable";
+    private const string ALLOWEDFEATURES = "AllowedFeatures";
+    private const string FUNCTIONLIBRARY = "FunctionLibrary";
+
+    private StructId.Variable variable;
+    private GPOperatorLibrary operatorLibrary;
+
+    public override string Description {
+      get { return @"Injects a default function library for classification problems."; }
+    }
+
+    public FunctionLibraryInjector()
+      : base() {
+      AddVariableInfo(new VariableInfo(TARGETVARIABLE, "The target variable", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo(ALLOWEDFEATURES, "List of indexes of allowed features", typeof(ItemList<IntData>), VariableKind.In));
+      AddVariableInfo(new VariableInfo(FUNCTIONLIBRARY, "Preconfigured default operator library", typeof(GPOperatorLibrary), VariableKind.New));
+    }
+
+    public override IOperation Apply(IScope scope) {
+      ItemList<IntData> allowedFeatures = GetVariableValue<ItemList<IntData>>(ALLOWEDFEATURES, scope, true);
+      int targetVariable = GetVariableValue<IntData>(TARGETVARIABLE, scope, true).Data;
+
+      // remove the target-variable in case it occures in allowed features
+      List<IntData> ts = allowedFeatures.FindAll(d => d.Data == targetVariable);
+      foreach(IntData t in ts) allowedFeatures.Remove(t);
+
+      InitDefaultOperatorLibrary();
+
+      int[] allowedIndexes = new int[allowedFeatures.Count];
+      for(int i = 0; i < allowedIndexes.Length; i++) {
+        allowedIndexes[i] = allowedFeatures[i].Data;
+      }
+
+      scope.AddVariable(new Variable(scope.TranslateName(FUNCTIONLIBRARY), operatorLibrary));
+      return null;
+    }
+
+    private void InitDefaultOperatorLibrary() {
+      variable = new StructId.Variable();
+      StructId.Constant constant = new StructId.Constant();
+
+      StructId.Addition addition = new StructId.Addition();
+      StructId.And and = new StructId.And();
+      StructId.Average average = new StructId.Average();
+      StructId.Cosinus cosinus = new StructId.Cosinus();
+      StructId.Division division = new StructId.Division();
+      StructId.Equal equal = new StructId.Equal();
+      StructId.Exponential exponential = new StructId.Exponential();
+      StructId.GreaterThan greaterThan = new StructId.GreaterThan();
+      StructId.IfThenElse ifThenElse = new StructId.IfThenElse();
+      StructId.LessThan lessThan = new StructId.LessThan();
+      StructId.Logarithm logarithm = new StructId.Logarithm();
+      StructId.Multiplication multiplication = new StructId.Multiplication();
+      StructId.Not not = new StructId.Not();
+      StructId.Or or = new StructId.Or();
+      StructId.Power power = new StructId.Power();
+      StructId.Signum signum = new StructId.Signum();
+      StructId.Sinus sinus = new StructId.Sinus();
+      StructId.Sqrt sqrt = new StructId.Sqrt();
+      StructId.Subtraction subtraction = new StructId.Subtraction();
+      StructId.Tangens tangens = new StructId.Tangens();
+      StructId.Xor xor = new StructId.Xor();
+
+      IFunction[] booleanFunctions = new IFunction[] {
+        and,
+        equal,
+        greaterThan,
+        lessThan,
+        not,
+        or,
+        xor 
+      };
+      IFunction[] doubleFunctions = new IFunction[] {
+        variable,
+        constant,
+        addition,
+        average,
+        cosinus,
+        division,
+        exponential,
+        ifThenElse,
+        logarithm,
+        multiplication,
+        power,
+        signum,
+        sinus,
+        sqrt,
+        subtraction,
+        tangens
+      };
+
+      SetAllowedSubOperators(and, booleanFunctions);
+      SetAllowedSubOperators(equal, doubleFunctions);
+      SetAllowedSubOperators(greaterThan, doubleFunctions);
+      SetAllowedSubOperators(lessThan, doubleFunctions);
+      SetAllowedSubOperators(not, booleanFunctions);
+      SetAllowedSubOperators(or, booleanFunctions);
+      SetAllowedSubOperators(xor, booleanFunctions);
+      SetAllowedSubOperators(addition, doubleFunctions);
+      SetAllowedSubOperators(average, doubleFunctions);
+      SetAllowedSubOperators(cosinus, doubleFunctions);
+      SetAllowedSubOperators(division, doubleFunctions);
+      SetAllowedSubOperators(exponential, doubleFunctions);
+      SetAllowedSubOperators(ifThenElse, 0, booleanFunctions);
+      SetAllowedSubOperators(ifThenElse, 1, doubleFunctions);
+      SetAllowedSubOperators(ifThenElse, 2, doubleFunctions);
+      SetAllowedSubOperators(logarithm, doubleFunctions);
+      SetAllowedSubOperators(multiplication, doubleFunctions);
+      SetAllowedSubOperators(power, doubleFunctions);
+      SetAllowedSubOperators(signum, doubleFunctions);
+      SetAllowedSubOperators(sinus, doubleFunctions);
+      SetAllowedSubOperators(sqrt, doubleFunctions);
+      SetAllowedSubOperators(subtraction, doubleFunctions);
+      SetAllowedSubOperators(tangens, doubleFunctions);
+
+      operatorLibrary = new GPOperatorLibrary();
+      operatorLibrary.GPOperatorGroup.AddOperator(variable);
+      operatorLibrary.GPOperatorGroup.AddOperator(constant);
+      operatorLibrary.GPOperatorGroup.AddOperator(addition);
+      operatorLibrary.GPOperatorGroup.AddOperator(average);
+      operatorLibrary.GPOperatorGroup.AddOperator(and);
+      operatorLibrary.GPOperatorGroup.AddOperator(cosinus);
+      operatorLibrary.GPOperatorGroup.AddOperator(division);
+      operatorLibrary.GPOperatorGroup.AddOperator(equal);
+      operatorLibrary.GPOperatorGroup.AddOperator(exponential);
+      operatorLibrary.GPOperatorGroup.AddOperator(greaterThan);
+      operatorLibrary.GPOperatorGroup.AddOperator(ifThenElse);
+      operatorLibrary.GPOperatorGroup.AddOperator(lessThan);
+      operatorLibrary.GPOperatorGroup.AddOperator(logarithm);
+      operatorLibrary.GPOperatorGroup.AddOperator(multiplication);
+      operatorLibrary.GPOperatorGroup.AddOperator(not);
+      operatorLibrary.GPOperatorGroup.AddOperator(power);
+      operatorLibrary.GPOperatorGroup.AddOperator(or);
+      operatorLibrary.GPOperatorGroup.AddOperator(signum);
+      operatorLibrary.GPOperatorGroup.AddOperator(sinus);
+      operatorLibrary.GPOperatorGroup.AddOperator(sqrt);
+      operatorLibrary.GPOperatorGroup.AddOperator(subtraction);
+      operatorLibrary.GPOperatorGroup.AddOperator(tangens);
+      operatorLibrary.GPOperatorGroup.AddOperator(xor);
+    }
+
+    private void SetAllowedSubOperators(IFunction f, IFunction[] gs) {
+      foreach(IConstraint c in f.Constraints) {
+        if(c is SubOperatorTypeConstraint) {
+          SubOperatorTypeConstraint typeConstraint = c as SubOperatorTypeConstraint;
+          typeConstraint.Clear();
+          foreach(IFunction g in gs) {
+            typeConstraint.AddOperator(g);
+          }
+        } else if(c is AllSubOperatorsTypeConstraint) {
+          AllSubOperatorsTypeConstraint typeConstraint = c as AllSubOperatorsTypeConstraint;
+          typeConstraint.Clear();
+          foreach(IFunction g in gs) {
+            typeConstraint.AddOperator(g);
+          }
+        }
+      }
+    }
+
+    private void SetAllowedSubOperators(IFunction f, int p, IFunction[] gs) {
+      foreach(IConstraint c in f.Constraints) {
+        if(c is SubOperatorTypeConstraint) {
+          SubOperatorTypeConstraint typeConstraint = c as SubOperatorTypeConstraint;
+          if(typeConstraint.SubOperatorIndex.Data == p) {
+            typeConstraint.Clear();
+            foreach(IFunction g in gs) {
+              typeConstraint.AddOperator(g);
+            }
+          }
+        }
+      }
+    }
+  }
+}
Index: /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.Classification/HeuristicLab.GP.Classification.csproj
===================================================================
--- /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.Classification/HeuristicLab.GP.Classification.csproj	(revision 646)
+++ /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.Classification/HeuristicLab.GP.Classification.csproj	(revision 646)
@@ -0,0 +1,59 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.21022</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>9c97d1b9-ce64-47c5-bac6-4e38d918fdba</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.GP.Classification</RootNamespace>
+    <AssemblyName>HeuristicLab.GP.Classification</AssemblyName>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Xml.Linq">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data.DataSetExtensions">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Class1.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
Index: /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.Classification/HeuristicLab.GP.StructureIdentification.Classification.csproj
===================================================================
--- /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.Classification/HeuristicLab.GP.StructureIdentification.Classification.csproj	(revision 646)
+++ /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.Classification/HeuristicLab.GP.StructureIdentification.Classification.csproj	(revision 646)
@@ -0,0 +1,120 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.21022</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{7C20D100-8BEB-433A-9499-F075E2CB9297}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.GP.Classification</RootNamespace>
+    <AssemblyName>HeuristicLab.GP.Classification</AssemblyName>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <SignAssembly>true</SignAssembly>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x86\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <OutputPath>bin\x86\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Xml.Linq">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data.DataSetExtensions">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="AccuracyEvaluator.cs" />
+    <Compile Include="ClassificationMatrixEvaluator.cs" />
+    <Compile Include="ClassificationMeanSquaredErrorEvaluator.cs" />
+    <Compile Include="CrossValidation.cs" />
+    <Compile Include="FunctionLibraryInjector.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="HeuristicLabGPClassificationPlugin.cs" />
+    <Compile Include="MCCEvaluator.cs" />
+    <Compile Include="MulticlassModeller.cs" />
+    <Compile Include="MulticlassOneVsOneAnalyzer.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\HeuristicLab.Constraints\HeuristicLab.Constraints.csproj">
+      <Project>{FCD62C6F-4793-4593-AE9A-0BDCA256EE99}</Project>
+      <Name>HeuristicLab.Constraints</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.Core\HeuristicLab.Core.csproj">
+      <Project>{F43B59AB-2B8C-4570-BC1E-15592086517C}</Project>
+      <Name>HeuristicLab.Core</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.DataAnalysis\HeuristicLab.DataAnalysis.csproj">
+      <Project>{7DD3A97A-56E9-462F-90E2-A351FE7AF5C2}</Project>
+      <Name>HeuristicLab.DataAnalysis</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.Data\HeuristicLab.Data.csproj">
+      <Project>{F473D9AF-3F09-4296-9F28-3C65118DAFFA}</Project>
+      <Name>HeuristicLab.Data</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.GP.StructureIdentification\HeuristicLab.GP.StructureIdentification.csproj">
+      <Project>{74223A32-C726-4978-BE78-37113A18373C}</Project>
+      <Name>HeuristicLab.GP.StructureIdentification</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.GP\HeuristicLab.GP.csproj">
+      <Project>{1F1CF3ED-374C-4288-995B-93F6B872F571}</Project>
+      <Name>HeuristicLab.GP</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.PluginInfrastructure\HeuristicLab.PluginInfrastructure.csproj">
+      <Project>{94186A6A-5176-4402-AE83-886557B53CCA}</Project>
+      <Name>HeuristicLab.PluginInfrastructure</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
Index: /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.Classification/HeuristicLabGPClassificationPlugin.cs
===================================================================
--- /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.Classification/HeuristicLabGPClassificationPlugin.cs	(revision 646)
+++ /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.Classification/HeuristicLabGPClassificationPlugin.cs	(revision 646)
@@ -0,0 +1,38 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 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.Text;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.GP.Classification {
+  [ClassInfo(Name = "HeuristicLab.GP.Classification-3.2")]
+  [PluginFile(Filename = "HeuristicLab.GP.Classification-3.2.dll", Filetype = PluginFileType.Assembly)]
+  [Dependency(Dependency = "HeuristicLab.Constraints-3.2")]
+  [Dependency(Dependency = "HeuristicLab.Core-3.2")]
+  [Dependency(Dependency = "HeuristicLab.Data-3.2")]
+  [Dependency(Dependency = "HeuristicLab.DataAnalysis-3.2")]
+  [Dependency(Dependency = "HeuristicLab.Operators-3.2")]
+  [Dependency(Dependency = "HeuristicLab.Random-3.2")]
+  public class HeuristicLabGPClassificationPlugin : PluginBase {
+  }
+}
Index: /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.Classification/MCCEvaluator.cs
===================================================================
--- /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.Classification/MCCEvaluator.cs	(revision 646)
+++ /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.Classification/MCCEvaluator.cs	(revision 646)
@@ -0,0 +1,95 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 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.Text;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.GP.StructureIdentification;
+
+namespace HeuristicLab.GP.Classification {
+  public class MCCEvaluator : GPEvaluatorBase {
+    private double limit;
+    private double[] original = new double[1];
+    private double[] estimated = new double[1];
+    private DoubleData mcc;
+    public override string Description {
+      get {
+        return @"Calculates the matthews correlation coefficient for a given model and class separation threshold";
+      }
+    }
+    public MCCEvaluator()
+      : base() {
+      AddVariableInfo(new VariableInfo("ClassSeparation", "The value of separation between negative and positive target classification values (for instance 0.5 if negative=0 and positive=1).", typeof(DoubleData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("MCC", "The matthews correlation coefficient of the model", typeof(DoubleData), VariableKind.New));
+    }
+
+    public override IOperation Apply(IScope scope) {
+      mcc = GetVariableValue<DoubleData>("MCC", scope, false, false);
+      if(mcc == null) {
+        mcc = new DoubleData();
+        scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("MCC"), mcc));
+      }
+      limit = GetVariableValue<DoubleData>("ClassSeparation", scope, true).Data;
+      return base.Apply(scope);
+    }
+
+    public override void Evaluate(int start, int end) {
+      int nSamples = end - start;
+      if(estimated.Length != nSamples) {
+        estimated = new double[nSamples];
+        original = new double[nSamples];
+      }
+
+      double positive = 0;
+      double negative = 0;
+      for(int sample = start; sample < end; sample++) {
+        double est = GetEstimatedValue(sample);
+        double orig = GetOriginalValue(sample);
+        SetOriginalValue(sample, est);
+        estimated[sample - start] = est;
+        original[sample - start] = orig;
+        if(orig >= limit) positive++;
+        else negative++;
+      }
+      Array.Sort(estimated, original);
+      double best_mcc = -1.0;
+      double tp = 0;
+      double fn = positive;
+      double tn = negative;
+      double fp = 0;
+      for(int i = original.Length - 1; i >= 0; i--) {
+        if(original[i] >= limit) {
+          tp++; fn--;
+        } else {
+          tn--; fp++;
+        }
+        double mcc = (tp * tn - fp * fn) / Math.Sqrt(positive * (tp + fn) * (tn + fp) * negative);
+        if(best_mcc < mcc) {
+          best_mcc = mcc;
+        }
+      }
+      this.mcc.Data = best_mcc;
+    }
+  }
+}
Index: /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.Classification/MulticlassModeller.cs
===================================================================
--- /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.Classification/MulticlassModeller.cs	(revision 646)
+++ /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.Classification/MulticlassModeller.cs	(revision 646)
@@ -0,0 +1,150 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 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.Text;
+using System.Xml;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.DataAnalysis;
+
+namespace HeuristicLab.GP.Classification {
+  public class MulticlassModeller : OperatorBase {
+
+    private const string DATASET = "Dataset";
+    private const string TARGETVARIABLE = "TargetVariable";
+    private const string TARGETCLASSVALUES = "TargetClassValues";
+    private const string TRAININGSAMPLESSTART = "TrainingSamplesStart";
+    private const string TRAININGSAMPLESEND = "TrainingSamplesEnd";
+    private const string VALIDATIONSAMPLESSTART = "ValidationSamplesStart";
+    private const string VALIDATIONSAMPLESEND = "ValidationSamplesEnd";
+    private const string CLASSAVALUE = "ClassAValue";
+    private const string CLASSBVALUE = "ClassBValue";
+    private const double EPSILON = 1E-6;
+    public override string Description {
+      get { return @"TASK"; }
+    }
+
+    public MulticlassModeller()
+      : base() {
+      AddVariableInfo(new VariableInfo(DATASET, "The original dataset and the new dataset parts in the newly created subscopes", typeof(Dataset), VariableKind.In));
+      AddVariableInfo(new VariableInfo(TARGETVARIABLE, "TargetVariable", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo(TARGETCLASSVALUES, "Class values of the target variable in the original dataset and in the new dataset parts", typeof(ItemList<DoubleData>), VariableKind.In | VariableKind.New));
+      AddVariableInfo(new VariableInfo(CLASSAVALUE, "The original class value of the new class A", typeof(DoubleData), VariableKind.New));
+      AddVariableInfo(new VariableInfo(CLASSBVALUE, "The original class value of the new class B", typeof(DoubleData), VariableKind.New));
+      AddVariableInfo(new VariableInfo(TRAININGSAMPLESSTART, "The start of training samples in the original dataset and starts of training samples in the new dataset parts", typeof(IntData), VariableKind.In | VariableKind.New));
+      AddVariableInfo(new VariableInfo(TRAININGSAMPLESEND, "The end of training samples in the original dataset and ends of training samples in the new dataset parts", typeof(IntData), VariableKind.In | VariableKind.New));
+      AddVariableInfo(new VariableInfo(VALIDATIONSAMPLESSTART, "The start of validation samples in the original dataset and starts of validation samples in the new dataset parts", typeof(IntData), VariableKind.In | VariableKind.New));
+      AddVariableInfo(new VariableInfo(VALIDATIONSAMPLESEND, "The end of validation samples in the original dataset and ends of validation samples in the new dataset parts", typeof(IntData), VariableKind.In | VariableKind.New));
+    }
+
+    public override IOperation Apply(IScope scope) {
+      Dataset origDataset = GetVariableValue<Dataset>(DATASET, scope, true);
+      int targetVariable = GetVariableValue<IntData>(TARGETVARIABLE, scope, true).Data;
+      ItemList<DoubleData> classValues = GetVariableValue<ItemList<DoubleData>>(TARGETCLASSVALUES, scope, true);
+      int origTrainingSamplesStart = GetVariableValue<IntData>(TRAININGSAMPLESSTART, scope, true).Data;
+      int origTrainingSamplesEnd = GetVariableValue<IntData>(TRAININGSAMPLESEND, scope, true).Data;
+      int origValidationSamplesStart = GetVariableValue<IntData>(VALIDATIONSAMPLESSTART, scope, true).Data;
+      int origValidationSamplesEnd = GetVariableValue<IntData>(VALIDATIONSAMPLESEND, scope, true).Data;
+      ItemList<DoubleData> binaryClassValues = new ItemList<DoubleData>();
+      binaryClassValues.Add(new DoubleData(0.0));
+      binaryClassValues.Add(new DoubleData(1.0));
+      for(int i = 0; i < classValues.Count-1; i++) {
+        for(int j = i+1; j < classValues.Count; j++) {
+          Dataset dataset = new Dataset();
+          dataset.Columns = origDataset.Columns;
+          double classAValue = classValues[i].Data;
+          double classBValue = classValues[j].Data;
+          int trainingSamplesStart;
+          int trainingSamplesEnd;
+          int validationSamplesStart;
+          int validationSamplesEnd;
+
+          trainingSamplesStart = 0;
+          List<double[]> rows = new List<double[]>();
+          for(int k = origTrainingSamplesStart; k < origTrainingSamplesEnd; k++) {
+            double[] row = new double[dataset.Columns];
+            double targetValue = origDataset.GetValue(k, targetVariable);
+            if(IsEqual(targetValue, classAValue)) {
+              for(int l = 0; l < row.Length; l++) {
+                row[l] = origDataset.GetValue(k, l);
+              }
+              row[targetVariable] = 0;
+              rows.Add(row);
+            } else if(IsEqual(targetValue, classBValue)) {
+              for(int l = 0; l < row.Length; l++) {
+                row[l] = origDataset.GetValue(k, l);
+              }
+              row[targetVariable] = 1.0;
+              rows.Add(row);
+            }
+          }
+          trainingSamplesEnd = rows.Count;
+          validationSamplesStart = rows.Count;
+          for(int k = origValidationSamplesStart; k < origValidationSamplesEnd; k++) {
+            double[] row = new double[dataset.Columns];
+            double targetValue = origDataset.GetValue(k, targetVariable);
+            if(IsEqual(targetValue, classAValue)) {
+              for(int l = 0; l < row.Length; l++) {
+                row[l] = origDataset.GetValue(k, l);
+              }
+              row[targetVariable] = 0;
+              rows.Add(row);
+            } else if(IsEqual(targetValue, classBValue)) {
+              for(int l = 0; l < row.Length; l++) {
+                row[l] = origDataset.GetValue(k, l);
+              }
+              row[targetVariable] = 1.0;
+              rows.Add(row);
+            }
+          }
+          validationSamplesEnd = rows.Count;
+
+          dataset.Rows = rows.Count;
+          dataset.Samples = new double[dataset.Rows * dataset.Columns];
+          for(int k = 0; k < dataset.Rows; k++) {
+            for(int l = 0; l < dataset.Columns; l++) {
+              dataset.SetValue(k, l, rows[k][l]);
+            }
+          }
+
+          Scope childScope = new Scope(classAValue+" vs. "+classBValue);
+
+          childScope.AddVariable(new Variable(scope.TranslateName(TARGETCLASSVALUES), binaryClassValues));
+          childScope.AddVariable(new Variable(scope.TranslateName(CLASSAVALUE), new DoubleData(classAValue)));
+          childScope.AddVariable(new Variable(scope.TranslateName(CLASSBVALUE), new DoubleData(classBValue)));
+          childScope.AddVariable(new Variable(scope.TranslateName(TRAININGSAMPLESSTART), new IntData(trainingSamplesStart)));
+          childScope.AddVariable(new Variable(scope.TranslateName(TRAININGSAMPLESEND), new IntData(trainingSamplesEnd)));
+          childScope.AddVariable(new Variable(scope.TranslateName(VALIDATIONSAMPLESSTART), new IntData(validationSamplesStart)));
+          childScope.AddVariable(new Variable(scope.TranslateName(VALIDATIONSAMPLESEND), new IntData(validationSamplesEnd)));
+          childScope.AddVariable(new Variable(scope.TranslateName(DATASET), dataset));
+          scope.AddSubScope(childScope);
+        }
+      }
+      return null;
+    }
+
+    private bool IsEqual(double x, double y) {
+      return Math.Abs(x - y) < EPSILON;
+    }
+  }
+}
Index: /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.Classification/MulticlassOneVsOneAnalyzer.cs
===================================================================
--- /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.Classification/MulticlassOneVsOneAnalyzer.cs	(revision 646)
+++ /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.Classification/MulticlassOneVsOneAnalyzer.cs	(revision 646)
@@ -0,0 +1,128 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 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.Text;
+using System.Xml;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.DataAnalysis;
+using HeuristicLab.GP.StructureIdentification;
+
+namespace HeuristicLab.GP.Classification {
+  public class MulticlassOneVsOneAnalyzer : OperatorBase {
+
+    private const string DATASET = "Dataset";
+    private const string TARGETVARIABLE = "TargetVariable";
+    private const string TARGETCLASSVALUES = "TargetClassValues";
+    private const string SAMPLESSTART = "SamplesStart";
+    private const string SAMPLESEND = "SamplesEnd";
+    private const string CLASSAVALUE = "ClassAValue";
+    private const string CLASSBVALUE = "ClassBValue";
+    private const string BESTMODELLSCOPE = "BestValidationSolution";
+    private const string BESTMODELL = "FunctionTree";
+    private const string VOTES = "Votes";
+    private const string ACCURACY = "Accuracy";
+
+    private const double EPSILON = 1E-6;
+    public override string Description {
+      get { return @"TASK"; }
+    }
+
+    public MulticlassOneVsOneAnalyzer()
+      : base() {
+      AddVariableInfo(new VariableInfo(DATASET, "The dataset to use", typeof(Dataset), VariableKind.In));
+      AddVariableInfo(new VariableInfo(TARGETVARIABLE, "Target variable", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo(TARGETCLASSVALUES, "Class values of the target variable in the original dataset", typeof(ItemList<DoubleData>), VariableKind.In));
+      AddVariableInfo(new VariableInfo(CLASSAVALUE, "The original class value of the class A in the subscope", typeof(DoubleData), VariableKind.In));
+      AddVariableInfo(new VariableInfo(CLASSBVALUE, "The original class value of the class B in the subscope", typeof(DoubleData), VariableKind.In));
+      AddVariableInfo(new VariableInfo(SAMPLESSTART, "The start of samples in the original dataset", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo(SAMPLESEND, "The end of samples in the original dataset", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo(BESTMODELLSCOPE, "The variable containing the scope of the model (incl. meta data)", typeof(IScope), VariableKind.In));
+      AddVariableInfo(new VariableInfo(BESTMODELL, "The variable in the scope of the model that contains the actual model", typeof(BakedFunctionTree), VariableKind.In));
+      AddVariableInfo(new VariableInfo(VOTES, "Array with the votes for each instance", typeof(IntMatrixData), VariableKind.New));
+      AddVariableInfo(new VariableInfo(ACCURACY, "Accuracy of the one-vs-one multi-cass classifier", typeof(DoubleData), VariableKind.New));
+    }
+
+    public override IOperation Apply(IScope scope) {
+      Dataset dataset = GetVariableValue<Dataset>(DATASET, scope, true);
+      int targetVariable = GetVariableValue<IntData>(TARGETVARIABLE, scope, true).Data;
+      int samplesStart = GetVariableValue<IntData>(SAMPLESSTART, scope, true).Data;
+      int samplesEnd = GetVariableValue<IntData>(SAMPLESEND, scope, true).Data;
+      ItemList<DoubleData> classValues = GetVariableValue<ItemList<DoubleData>>(TARGETCLASSVALUES, scope, true);
+      int[,] votes = new int[samplesEnd - samplesStart, classValues.Count];
+
+      foreach(IScope childScope in scope.SubScopes) {
+        double classAValue = GetVariableValue<DoubleData>(CLASSAVALUE, childScope, true).Data;
+        double classBValue = GetVariableValue<DoubleData>(CLASSBVALUE, childScope, true).Data;
+        IScope bestScope = GetVariableValue<IScope>(BESTMODELLSCOPE, childScope, true);
+        BakedFunctionTree functionTree = GetVariableValue<BakedFunctionTree>(BESTMODELL, bestScope, true);
+
+        BakedTreeEvaluator evaluator = new BakedTreeEvaluator();
+        evaluator.ResetEvaluator(functionTree, dataset);
+
+        for(int i = 0; i < (samplesEnd - samplesStart); i++) {
+          double est = evaluator.Evaluate(i + samplesStart);
+          if(est < 0.5) {
+            CastVote(votes, i, classAValue, classValues);
+          } else {
+            CastVote(votes, i, classBValue, classValues);
+          }
+        }
+      }
+
+      int correctlyClassified = 0;
+      for(int i = 0; i < (samplesEnd - samplesStart); i++) {
+        double originalClassValue = dataset.GetValue(i + samplesStart, targetVariable);
+        double estimatedClassValue = classValues[0].Data;
+        int maxVotes = votes[i, 0];
+        int sameVotes = 0;
+        for(int j = 1; j < classValues[j].Data; j++) {
+          if(votes[i, j] > maxVotes) {
+            maxVotes = votes[i, j];
+            estimatedClassValue = classValues[j].Data;
+            sameVotes = 0;
+          } else if(votes[i, j] == maxVotes) {
+            sameVotes++;
+          }
+        }
+        if(IsEqual(originalClassValue, estimatedClassValue) && sameVotes == 0) correctlyClassified++;
+      }
+
+      double accuracy = correctlyClassified / (double)(samplesEnd - samplesStart);
+
+      scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName(VOTES), new IntMatrixData(votes)));
+      scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName(ACCURACY), new DoubleData(accuracy)));
+      return null;
+    }
+
+    private void CastVote(int[,] votes, int sample, double votedClass, ItemList<DoubleData> classValues) {
+      for(int i = 0; i < classValues.Count; i++) {
+        if(IsEqual(classValues[i].Data, votedClass)) votes[sample, i]++;
+      }
+    }
+
+    private bool IsEqual(double x, double y) {
+      return Math.Abs(x - y) < EPSILON;
+    }
+  }
+}
Index: /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.Classification/Properties/AssemblyInfo.cs
===================================================================
--- /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.Classification/Properties/AssemblyInfo.cs	(revision 646)
+++ /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.Classification/Properties/AssemblyInfo.cs	(revision 646)
@@ -0,0 +1,36 @@
+﻿using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("HeuristicLab.GP.Classification")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("FH OÖ")]
+[assembly: AssemblyProduct("HeuristicLab.GP.Classification")]
+[assembly: AssemblyCopyright("Copyright © FH OÖ 2008")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("9c97d1b9-ce64-47c5-bac6-4e38d918fdba")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
Index: /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.TimeSeries/AveragePercentageChangeEvaluator.cs
===================================================================
--- /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.TimeSeries/AveragePercentageChangeEvaluator.cs	(revision 646)
+++ /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.TimeSeries/AveragePercentageChangeEvaluator.cs	(revision 646)
@@ -0,0 +1,91 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 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.Text;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.GP.StructureIdentification;
+
+namespace HeuristicLab.GP.TimeSeries {
+  public class AvergePercentageChangeEvaluator : GPEvaluatorBase {
+    protected DoubleData apc;
+    private bool differential;
+    public override string Description {
+      get {
+        return @"TASK";
+      }
+    }
+
+    public AvergePercentageChangeEvaluator()
+      : base() {
+      AddVariableInfo(new VariableInfo("Differential", "Wether to transform the target variable to percentage change first or not.", typeof(BoolData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("APC", "The average percentage change of the model", typeof(DoubleData), VariableKind.New));
+    }
+
+    public override IOperation Apply(IScope scope) {
+      differential = GetVariableValue<BoolData>("Differential", scope, true).Data;
+      apc = GetVariableValue<DoubleData>("APC", scope, false, false);
+      if(apc == null) {
+        apc = new DoubleData();
+        scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("APC"), apc));
+      }
+
+      return base.Apply(scope);
+    }
+
+    public override void Evaluate(int start, int end) {
+      double percentageSum = 0;
+      for(int sample = start; sample < end; sample++) {
+        double prevOriginal;
+        double originalPercentageChange;
+        double estimatedPercentageChange;
+        if(differential) {
+          prevOriginal = GetOriginalValue(sample - 1);
+          originalPercentageChange = (GetOriginalValue(sample) - prevOriginal) / prevOriginal;
+          estimatedPercentageChange = (GetEstimatedValue(sample) - prevOriginal) / prevOriginal;
+          SetOriginalValue(sample, estimatedPercentageChange*prevOriginal + prevOriginal);
+        } else {
+          originalPercentageChange = GetOriginalValue(sample);
+          estimatedPercentageChange = GetEstimatedValue(sample);
+          SetOriginalValue(sample, estimatedPercentageChange);
+        }
+        if(!double.IsNaN(originalPercentageChange) && !double.IsInfinity(originalPercentageChange)) {
+          if((estimatedPercentageChange > 0 && originalPercentageChange > 0) ||
+            (estimatedPercentageChange < 0 && originalPercentageChange < 0)) {
+            percentageSum += Math.Abs(originalPercentageChange);
+          } else if((estimatedPercentageChange > 0 && originalPercentageChange < 0) ||
+            (estimatedPercentageChange < 0 && originalPercentageChange > 0)) {
+            percentageSum -= Math.Abs(originalPercentageChange);
+          }
+        }
+      }
+
+      percentageSum /= (end - start);
+      if(double.IsNaN(percentageSum) || double.IsInfinity(percentageSum)) {
+        percentageSum = double.MinValue;
+      }
+      apc.Data = percentageSum;
+    }
+  }
+}
Index: /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.TimeSeries/FunctionLibraryInjector.cs
===================================================================
--- /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.TimeSeries/FunctionLibraryInjector.cs	(revision 646)
+++ /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.TimeSeries/FunctionLibraryInjector.cs	(revision 646)
@@ -0,0 +1,222 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 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.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Constraints;
+using StructId = HeuristicLab.GP.StructureIdentification;
+
+namespace HeuristicLab.GP.TimeSeries {
+  public class FunctionLibraryInjector : OperatorBase {
+    private const string TARGETVARIABLE = "TargetVariable";
+    private const string AUTOREGRESSIVE = "Autoregressive";
+    private const string ALLOWEDFEATURES = "AllowedFeatures";
+    private const string MINTIMEOFFSET = "MinTimeOffset";
+    private const string MAXTIMEOFFSET = "MaxTimeOffset";
+    private const string FUNCTIONLIBRARY = "FunctionLibrary";
+
+    private StructId.Variable variable;
+    private StructId.Differential differential;
+    private GPOperatorLibrary operatorLibrary;
+
+    public override string Description {
+      get { return @"Injects a default function library."; }
+    }
+
+    public FunctionLibraryInjector()
+      : base() {
+      AddVariableInfo(new VariableInfo(TARGETVARIABLE, "The target variable", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo(AUTOREGRESSIVE, "Switch to turn on/off autoregressive modeling (wether to allow the target variable as input)", typeof(BoolData), VariableKind.In));
+      AddVariableInfo(new VariableInfo(ALLOWEDFEATURES, "List of indexes of allowed features", typeof(ItemList<IntData>), VariableKind.In));
+      AddVariableInfo(new VariableInfo(MINTIMEOFFSET, "Minimal time offset for all features", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo(MAXTIMEOFFSET, "Maximal time offset for all feature", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo(FUNCTIONLIBRARY, "Preconfigured default operator library", typeof(GPOperatorLibrary), VariableKind.New));
+    }
+
+    public override IOperation Apply(IScope scope) {
+      IntData minTimeOffset = GetVariableValue<IntData>(MINTIMEOFFSET, scope, true);
+      IntData maxTimeOffset = GetVariableValue<IntData>(MAXTIMEOFFSET, scope, true);
+      ItemList<IntData> allowedFeatures = GetVariableValue<ItemList<IntData>>(ALLOWEDFEATURES, scope, true);
+      int targetVariable = GetVariableValue<IntData>(TARGETVARIABLE, scope, true).Data;
+      bool autoregressive = GetVariableValue<BoolData>(AUTOREGRESSIVE, scope, true).Data;
+
+      if(autoregressive) {
+        // make sure the target-variable occures in list of allowed features
+        if(!allowedFeatures.Exists(d => d.Data == targetVariable)) allowedFeatures.Add(new IntData(targetVariable));
+      } else {
+        // remove the target-variable in case it occures in allowed features
+        List<IntData> ts = allowedFeatures.FindAll(d => d.Data == targetVariable);
+        foreach(IntData t in ts) allowedFeatures.Remove(t);
+      }
+
+      InitDefaultOperatorLibrary();
+
+      int[] allowedIndexes = new int[allowedFeatures.Count];
+      for(int i = 0; i < allowedIndexes.Length; i++) {
+        allowedIndexes[i] = allowedFeatures[i].Data;
+      }
+
+      variable.SetConstraints(allowedIndexes, minTimeOffset.Data, maxTimeOffset.Data);
+      differential.SetConstraints(allowedIndexes, minTimeOffset.Data, maxTimeOffset.Data);
+
+      scope.AddVariable(new Variable(scope.TranslateName(FUNCTIONLIBRARY), operatorLibrary));
+      return null;
+    }
+
+    private void InitDefaultOperatorLibrary() {
+      variable = new StructId.Variable();
+      differential = new StructId.Differential();
+      StructId.Constant constant = new StructId.Constant();
+
+      StructId.Addition addition = new StructId.Addition();
+      StructId.And and = new StructId.And();
+      StructId.Average average = new StructId.Average();
+      StructId.Cosinus cosinus = new StructId.Cosinus();
+      StructId.Division division = new StructId.Division();
+      StructId.Equal equal = new StructId.Equal();
+      StructId.Exponential exponential = new StructId.Exponential();
+      StructId.GreaterThan greaterThan = new StructId.GreaterThan();
+      StructId.IfThenElse ifThenElse = new StructId.IfThenElse();
+      StructId.LessThan lessThan = new StructId.LessThan();
+      StructId.Logarithm logarithm = new StructId.Logarithm();
+      StructId.Multiplication multiplication = new StructId.Multiplication();
+      StructId.Not not = new StructId.Not();
+      StructId.Or or = new StructId.Or();
+      StructId.Power power = new StructId.Power();
+      StructId.Signum signum = new StructId.Signum();
+      StructId.Sinus sinus = new StructId.Sinus();
+      StructId.Sqrt sqrt = new StructId.Sqrt();
+      StructId.Subtraction subtraction = new StructId.Subtraction();
+      StructId.Tangens tangens = new StructId.Tangens();
+      StructId.Xor xor = new StructId.Xor();
+
+      IFunction[] booleanFunctions = new IFunction[] {
+        and,
+        equal,
+        greaterThan,
+        lessThan,
+        not,
+        or,
+        xor };
+      IFunction[] doubleFunctions = new IFunction[] {
+        variable,
+        differential,
+        constant,
+        addition,
+        average,
+        cosinus,
+        division,
+        exponential,
+        ifThenElse,
+        logarithm,
+        multiplication,
+        power,
+        signum,
+        sinus,
+        sqrt,
+        subtraction,
+        tangens};
+
+      SetAllowedSubOperators(and, booleanFunctions);
+      SetAllowedSubOperators(equal, doubleFunctions);
+      SetAllowedSubOperators(greaterThan, doubleFunctions);
+      SetAllowedSubOperators(lessThan, doubleFunctions);
+      SetAllowedSubOperators(not, booleanFunctions);
+      SetAllowedSubOperators(or, booleanFunctions);
+      SetAllowedSubOperators(xor, booleanFunctions);
+      SetAllowedSubOperators(addition, doubleFunctions);
+      SetAllowedSubOperators(average, doubleFunctions);
+      SetAllowedSubOperators(cosinus, doubleFunctions);
+      SetAllowedSubOperators(division, doubleFunctions);
+      SetAllowedSubOperators(exponential, doubleFunctions);
+      SetAllowedSubOperators(ifThenElse, 0, booleanFunctions);
+      SetAllowedSubOperators(ifThenElse, 1, doubleFunctions);
+      SetAllowedSubOperators(ifThenElse, 2, doubleFunctions);
+      SetAllowedSubOperators(logarithm, doubleFunctions);
+      SetAllowedSubOperators(multiplication, doubleFunctions);
+      SetAllowedSubOperators(power, doubleFunctions);
+      SetAllowedSubOperators(signum, doubleFunctions);
+      SetAllowedSubOperators(sinus, doubleFunctions);
+      SetAllowedSubOperators(sqrt, doubleFunctions);
+      SetAllowedSubOperators(subtraction, doubleFunctions);
+      SetAllowedSubOperators(tangens, doubleFunctions);
+
+      operatorLibrary = new GPOperatorLibrary();
+      operatorLibrary.GPOperatorGroup.AddOperator(variable);
+      operatorLibrary.GPOperatorGroup.AddOperator(differential);
+      operatorLibrary.GPOperatorGroup.AddOperator(constant);
+      operatorLibrary.GPOperatorGroup.AddOperator(addition);
+      operatorLibrary.GPOperatorGroup.AddOperator(average);
+      operatorLibrary.GPOperatorGroup.AddOperator(and);
+      operatorLibrary.GPOperatorGroup.AddOperator(cosinus);
+      operatorLibrary.GPOperatorGroup.AddOperator(division);
+      operatorLibrary.GPOperatorGroup.AddOperator(equal);
+      operatorLibrary.GPOperatorGroup.AddOperator(exponential);
+      operatorLibrary.GPOperatorGroup.AddOperator(greaterThan);
+      operatorLibrary.GPOperatorGroup.AddOperator(ifThenElse);
+      operatorLibrary.GPOperatorGroup.AddOperator(lessThan);
+      operatorLibrary.GPOperatorGroup.AddOperator(logarithm);
+      operatorLibrary.GPOperatorGroup.AddOperator(multiplication);
+      operatorLibrary.GPOperatorGroup.AddOperator(not);
+      operatorLibrary.GPOperatorGroup.AddOperator(power);
+      operatorLibrary.GPOperatorGroup.AddOperator(or);
+      operatorLibrary.GPOperatorGroup.AddOperator(signum);
+      operatorLibrary.GPOperatorGroup.AddOperator(sinus);
+      operatorLibrary.GPOperatorGroup.AddOperator(sqrt);
+      operatorLibrary.GPOperatorGroup.AddOperator(subtraction);
+      operatorLibrary.GPOperatorGroup.AddOperator(tangens);
+      operatorLibrary.GPOperatorGroup.AddOperator(xor);
+    }
+
+    private void SetAllowedSubOperators(IFunction f, IFunction[] gs) {
+      foreach(IConstraint c in f.Constraints) {
+        if(c is SubOperatorTypeConstraint) {
+          SubOperatorTypeConstraint typeConstraint = c as SubOperatorTypeConstraint;
+          typeConstraint.Clear();
+          foreach(IFunction g in gs) {
+            typeConstraint.AddOperator(g);
+          }
+        } else if(c is AllSubOperatorsTypeConstraint) {
+          AllSubOperatorsTypeConstraint typeConstraint = c as AllSubOperatorsTypeConstraint;
+          typeConstraint.Clear();
+          foreach(IFunction g in gs) {
+            typeConstraint.AddOperator(g);
+          }
+        }
+      }
+    }
+
+    private void SetAllowedSubOperators(IFunction f, int p, IFunction[] gs) {
+      foreach(IConstraint c in f.Constraints) {
+        if(c is SubOperatorTypeConstraint) {
+          SubOperatorTypeConstraint typeConstraint = c as SubOperatorTypeConstraint;
+          if(typeConstraint.SubOperatorIndex.Data == p) {
+            typeConstraint.Clear();
+            foreach(IFunction g in gs) {
+              typeConstraint.AddOperator(g);
+            }
+          }
+        }
+      }
+    }
+  }
+}
Index: /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.TimeSeries/HeuristicLab.GP.StructureIdentification.TimeSeries.csproj
===================================================================
--- /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.TimeSeries/HeuristicLab.GP.StructureIdentification.TimeSeries.csproj	(revision 646)
+++ /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.TimeSeries/HeuristicLab.GP.StructureIdentification.TimeSeries.csproj	(revision 646)
@@ -0,0 +1,116 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.21022</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{6084CFB5-733F-449D-9F92-2E40D13F0514}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.GP.TimeSeries</RootNamespace>
+    <AssemblyName>HeuristicLab.GP.TimeSeries</AssemblyName>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <SignAssembly>true</SignAssembly>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x86\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <OutputPath>bin\x86\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Xml.Linq">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data.DataSetExtensions">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="AveragePercentageChangeEvaluator.cs" />
+    <Compile Include="FunctionLibraryInjector.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="HeuristicLabGPTimeSeriesPlugin.cs" />
+    <Compile Include="ProfitEvaluator.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="TheilInequalityCoefficientEvaluator.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\HeuristicLab.Constraints\HeuristicLab.Constraints.csproj">
+      <Project>{FCD62C6F-4793-4593-AE9A-0BDCA256EE99}</Project>
+      <Name>HeuristicLab.Constraints</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.Core\HeuristicLab.Core.csproj">
+      <Project>{F43B59AB-2B8C-4570-BC1E-15592086517C}</Project>
+      <Name>HeuristicLab.Core</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.DataAnalysis\HeuristicLab.DataAnalysis.csproj">
+      <Project>{7DD3A97A-56E9-462F-90E2-A351FE7AF5C2}</Project>
+      <Name>HeuristicLab.DataAnalysis</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.Data\HeuristicLab.Data.csproj">
+      <Project>{F473D9AF-3F09-4296-9F28-3C65118DAFFA}</Project>
+      <Name>HeuristicLab.Data</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.GP.StructureIdentification\HeuristicLab.GP.StructureIdentification.csproj">
+      <Project>{74223A32-C726-4978-BE78-37113A18373C}</Project>
+      <Name>HeuristicLab.GP.StructureIdentification</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.GP\HeuristicLab.GP.csproj">
+      <Project>{1F1CF3ED-374C-4288-995B-93F6B872F571}</Project>
+      <Name>HeuristicLab.GP</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.PluginInfrastructure\HeuristicLab.PluginInfrastructure.csproj">
+      <Project>{94186A6A-5176-4402-AE83-886557B53CCA}</Project>
+      <Name>HeuristicLab.PluginInfrastructure</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
Index: /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.TimeSeries/HeuristicLabGPTimeSeriesPlugin.cs
===================================================================
--- /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.TimeSeries/HeuristicLabGPTimeSeriesPlugin.cs	(revision 646)
+++ /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.TimeSeries/HeuristicLabGPTimeSeriesPlugin.cs	(revision 646)
@@ -0,0 +1,37 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 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.Text;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.GP.TimeSeries {
+  [ClassInfo(Name = "HeuristicLab.GP.TimeSeries-3.2")]
+  [PluginFile(Filename = "HeuristicLab.GP.TimeSeries-3.2.dll", Filetype = PluginFileType.Assembly)]
+  [Dependency(Dependency = "HeuristicLab.Constraints-3.2")]
+  [Dependency(Dependency = "HeuristicLab.Core-3.2")]
+  [Dependency(Dependency = "HeuristicLab.Data-3.2")]
+  [Dependency(Dependency = "HeuristicLab.DataAnalysis-3.2")]
+  [Dependency(Dependency = "HeuristicLab.GP.StructureIdentification-3.2")]
+  public class HeuristicLabGPTimeSeriesPlugin : PluginBase {
+  }
+}
Index: /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.TimeSeries/ProfitEvaluator.cs
===================================================================
--- /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.TimeSeries/ProfitEvaluator.cs	(revision 646)
+++ /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.TimeSeries/ProfitEvaluator.cs	(revision 646)
@@ -0,0 +1,92 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 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.Text;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.GP.StructureIdentification;
+
+namespace HeuristicLab.GP.TimeSeries {
+  public class ProfitEvaluator : GPEvaluatorBase {
+    protected DoubleData profit;
+    private int exchangeRateVarIndex;
+    private double transactionCost;
+    public override string Description {
+      get {
+        return @"TASK";
+      }
+    }
+
+    public ProfitEvaluator()
+      : base() {
+      AddVariableInfo(new VariableInfo("ExchangeRate", "The index of the variable in the dataset for the exchange rate", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("Profit", "The estimated profit of the model", typeof(DoubleData), VariableKind.New));
+      AddVariableInfo(new VariableInfo("TransactionCost", "Cost of a trade in percent of the transaction volume (0..1)", typeof(DoubleData), VariableKind.In));
+    }
+
+    public override IOperation Apply(IScope scope) {
+      exchangeRateVarIndex = GetVariableValue<IntData>("ExchangeRate", scope, true).Data;
+      transactionCost = GetVariableValue<DoubleData>("TransactionCost", scope, true).Data;
+      profit = GetVariableValue<DoubleData>("Profit", scope, false, false);
+      if(profit == null) {
+        profit = new DoubleData();
+        scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("Profit"), profit));
+      }
+
+      return base.Apply(scope);
+    }
+
+    public override void Evaluate(int start, int end) {
+      double cA = 1.0; // start with a capital of one entity of A
+      double cB = 0;
+      double exchangeRate = double.MaxValue;
+      for(int sample = start; sample < end; sample++) {
+        exchangeRate = dataset.GetValue(sample, exchangeRateVarIndex);
+        double originalPercentageChange = GetOriginalValue(sample);
+        double estimatedPercentageChange = GetEstimatedValue(sample);
+        SetOriginalValue(sample, estimatedPercentageChange);
+        if(!double.IsNaN(originalPercentageChange) && !double.IsInfinity(originalPercentageChange)) {
+          if(estimatedPercentageChange > 0) {
+            // prediction is the rate of B/A will increase (= get more B for one A) => exchange all B to A
+            cA += (cB / exchangeRate) * (1-transactionCost);
+            cB = 0;
+          } else if(estimatedPercentageChange < 0) {
+            // prediction is the rate of B/A will drop (= get more A for one B) => exchange all A to B
+            cB += (cA * exchangeRate) * (1-transactionCost);
+            cA = 0;
+          }
+        }
+      }
+
+      if(double.IsNaN(cA) || double.IsInfinity(cA) || double.IsInfinity(cB) || double.IsNaN(cB)) {
+        cA = 0;
+        cB = 0;
+      }
+      // at the end we must exchange all B back to A 
+      // (because we want to buy the local beer not import one from B-country)
+      profit.Data = cA + ((cB / exchangeRate) * (1-transactionCost));
+      profit.Data -= 1.0; // substract the start capital to determine actual profit
+    }
+  }
+}
Index: /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.TimeSeries/Properties/AssemblyInfo.cs
===================================================================
--- /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.TimeSeries/Properties/AssemblyInfo.cs	(revision 646)
+++ /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.TimeSeries/Properties/AssemblyInfo.cs	(revision 646)
@@ -0,0 +1,36 @@
+﻿using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("HeuristicLab.GP.TimeSeries")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("FH OÖ")]
+[assembly: AssemblyProduct("HeuristicLab.GP.TimeSeries")]
+[assembly: AssemblyCopyright("Copyright © FH OÖ 2008")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("85e23c52-2d78-49df-9013-feba800cb04d")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
Index: /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.TimeSeries/TheilInequalityCoefficientEvaluator.cs
===================================================================
--- /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.TimeSeries/TheilInequalityCoefficientEvaluator.cs	(revision 646)
+++ /branches/GpPluginsRefactoringBranch/HeuristicLab.GP.StructureIdentification.TimeSeries/TheilInequalityCoefficientEvaluator.cs	(revision 646)
@@ -0,0 +1,83 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 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.Text;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.GP.StructureIdentification;
+
+namespace HeuristicLab.GP.TimeSeries {
+  public class TheilInequalityCoefficientEvaluator : GPEvaluatorBase {
+    private bool differential;
+    private DoubleData theilInequaliy;
+    public override string Description {
+      get {
+        return @"Evaluates 'FunctionTree' for all samples of 'Dataset' and calculates
+the 'Theil inequality coefficient (scale invariant)' of estimated values vs. real values of 'TargetVariable'.";
+      }
+    }
+
+    public TheilInequalityCoefficientEvaluator()
+      : base() {
+      AddVariableInfo(new VariableInfo("Differential", "Wether to calculate the coefficient for the predicted change vs. original change or for the absolute prediction vs. original value", typeof(BoolData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("TheilInequalityCoefficient", "Theil's inequality coefficient of the model", typeof(DoubleData), VariableKind.New));
+
+    }
+
+    public override IOperation Apply(IScope scope) {
+      differential = GetVariableValue<BoolData>("Differential", scope, true).Data;
+      theilInequaliy = GetVariableValue<DoubleData>("TheilInequalityCoefficient", scope, false, false);
+      if(theilInequaliy == null) {
+        theilInequaliy = new DoubleData();
+        scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("TheilInequalityCoefficient"), theilInequaliy));
+      }
+
+      return base.Apply(scope);
+    }
+
+    public override void Evaluate(int start, int end) {
+      double errorsSquaredSum = 0.0;
+      double estimatedSquaredSum = 0.0;
+      double originalSquaredSum = 0.0;
+      for(int sample = start; sample < end; sample++) {
+        double prevValue = 0.0;
+        if(differential) prevValue = GetOriginalValue(sample - 1);
+        double estimatedChange = GetEstimatedValue(sample) - prevValue;
+        double originalChange = GetOriginalValue(sample) - prevValue;
+        SetOriginalValue(sample, estimatedChange + prevValue);
+        if(!double.IsNaN(originalChange) && !double.IsInfinity(originalChange)) {
+          double error = estimatedChange - originalChange;
+          errorsSquaredSum += error * error;
+          estimatedSquaredSum += estimatedChange * estimatedChange;
+          originalSquaredSum += originalChange * originalChange;
+        }
+      }
+      int nSamples = end - start;
+      double quality = Math.Sqrt(errorsSquaredSum / nSamples) / (Math.Sqrt(estimatedSquaredSum / nSamples) + Math.Sqrt(originalSquaredSum / nSamples));
+      if(double.IsNaN(quality) || double.IsInfinity(quality))
+        quality = double.MaxValue;
+      theilInequaliy.Data = quality;
+    }
+  }
+}
