Index: trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj	(revision 13040)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj	(revision 13100)
@@ -130,8 +130,10 @@
     <Compile Include="Implementation\Classification\ClassificationEnsembleProblemData.cs" />
     <Compile Include="Implementation\Classification\ClassificationSolutionBase.cs" />
+    <Compile Include="Implementation\Classification\ConstantClassificationSolution.cs" />
     <Compile Include="Implementation\Classification\DiscriminantFunctionClassificationSolutionBase.cs" />
     <Compile Include="Implementation\Clustering\ClusteringProblem.cs" />
     <Compile Include="Implementation\Clustering\ClusteringProblemData.cs" />
     <Compile Include="Implementation\Clustering\ClusteringSolution.cs" />
+    <Compile Include="Implementation\Regression\ConstantModel.cs" />
     <Compile Include="Implementation\Regression\ConstantRegressionModel.cs" />
     <Compile Include="Implementation\Regression\ConstantRegressionSolution.cs" />
@@ -182,8 +184,11 @@
     <Compile Include="OnlineCalculators\AutoCorrelationCalculator.cs" />
     <Compile Include="OnlineCalculators\ClassificationPerformanceMeasuresCalculator.cs" />
+    <Compile Include="OnlineCalculators\ConfusionMatrixCalculator.cs" />
     <Compile Include="OnlineCalculators\DependencyCalculator\HoeffdingsDependenceCalculator.cs" />
     <Compile Include="OnlineCalculators\DependencyCalculator\PearsonsRDependenceCalculator.cs" />
     <Compile Include="OnlineCalculators\DependencyCalculator\PearsonsRSquaredDependenceCalculator.cs" />
     <Compile Include="OnlineCalculators\DependencyCalculator\SpearmansRankCorrelationCoefficientCalculator.cs" />
+    <Compile Include="OnlineCalculators\FOneScoreCalculator.cs" />
+    <Compile Include="OnlineCalculators\MatthewsCorrelationCoefficientCalculator.cs" />
     <Compile Include="OnlineCalculators\OnlineBoundedMeanSquaredErrorCalculator.cs" />
     <Compile Include="OnlineCalculators\OnlineCovarianceCalculator.cs" />
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationPerformanceMeasures.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationPerformanceMeasures.cs	(revision 13040)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationPerformanceMeasures.cs	(revision 13100)
@@ -37,4 +37,6 @@
     protected const string TrainingFalsePositiveRateResultName = "False positive rate (training)";
     protected const string TrainingFalseDiscoveryRateResultName = "False discovery rate (training)";
+    protected const string TrainingF1ScoreResultName = "F1 score (training)";
+    protected const string TrainingMatthewsCorrelationResultName = "Matthews Correlation (training)";
     protected const string TestTruePositiveRateResultName = "True positive rate (test)";
     protected const string TestTrueNegativeRateResultName = "True negative rate (test)";
@@ -43,4 +45,6 @@
     protected const string TestFalsePositiveRateResultName = "False positive rate (test)";
     protected const string TestFalseDiscoveryRateResultName = "False discovery rate (test)";
+    protected const string TestF1ScoreResultName = "F1 score (test)";
+    protected const string TestMatthewsCorrelationResultName = "Matthews Correlation (test)";
     #endregion
 
@@ -89,4 +93,12 @@
       set { ((DoubleValue)this[TrainingFalseDiscoveryRateResultName].Value).Value = value; }
     }
+    public double TrainingF1Score {
+      get { return ((DoubleValue)this[TrainingF1ScoreResultName].Value).Value; }
+      set { ((DoubleValue)this[TrainingF1ScoreResultName].Value).Value = value; }
+    }
+    public double TrainingMatthewsCorrelation {
+      get { return ((DoubleValue)this[TrainingMatthewsCorrelationResultName].Value).Value; }
+      set { ((DoubleValue)this[TrainingMatthewsCorrelationResultName].Value).Value = value; }
+    }
     public double TestTruePositiveRate {
       get { return ((DoubleValue)this[TestTruePositiveRateResultName].Value).Value; }
@@ -113,4 +125,12 @@
       set { ((DoubleValue)this[TestFalseDiscoveryRateResultName].Value).Value = value; }
     }
+    public double TestF1Score {
+      get { return ((DoubleValue)this[TestF1ScoreResultName].Value).Value; }
+      set { ((DoubleValue)this[TestF1ScoreResultName].Value).Value = value; }
+    }
+    public double TestMatthewsCorrelation {
+      get { return ((DoubleValue)this[TestMatthewsCorrelationResultName].Value).Value; }
+      set { ((DoubleValue)this[TestMatthewsCorrelationResultName].Value).Value = value; }
+    }
     #endregion
 
@@ -123,4 +143,6 @@
       Add(new Result(TrainingFalsePositiveRateResultName, "The false positive rate is the complement of the true negative rate of the model on the training partition.", new PercentValue()));
       Add(new Result(TrainingFalseDiscoveryRateResultName, "The false discovery rate is the complement of the positive predictive value of the model on the training partition.", new PercentValue()));
+      Add(new Result(TrainingF1ScoreResultName, "The F1 score of the model on the training partition.", new DoubleValue()));
+      Add(new Result(TrainingMatthewsCorrelationResultName, "The Matthews correlation value of the model on the training partition.", new DoubleValue()));
       Add(new Result(TestTruePositiveRateResultName, "Sensitivity/True positive rate of the model on the test partition\n(TP/(TP+FN)).", new PercentValue()));
       Add(new Result(TestTrueNegativeRateResultName, "Specificity/True negative rate of the model on the test partition\n(TN/(FP+TN)).", new PercentValue()));
@@ -129,4 +151,6 @@
       Add(new Result(TestFalsePositiveRateResultName, "The false positive rate is the complement of the true negative rate of the model on the test partition.", new PercentValue()));
       Add(new Result(TestFalseDiscoveryRateResultName, "The false discovery rate is the complement of the positive predictive value of the model on the test partition.", new PercentValue()));
+      Add(new Result(TestF1ScoreResultName, "The F1 score of the model on the test partition.", new DoubleValue()));
+      Add(new Result(TrainingMatthewsCorrelationResultName, "The Matthews correlation value of the model on the test partition.", new DoubleValue()));
       TrainingTruePositiveRate = double.NaN;
       TrainingTrueNegativeRate = double.NaN;
@@ -135,4 +159,6 @@
       TrainingFalsePositiveRate = double.NaN;
       TrainingFalseDiscoveryRate = double.NaN;
+      TrainingF1Score = double.NaN;
+      TrainingMatthewsCorrelation = double.NaN;
       TestTruePositiveRate = double.NaN;
       TestTrueNegativeRate = double.NaN;
@@ -141,4 +167,6 @@
       TestFalsePositiveRate = double.NaN;
       TestFalseDiscoveryRate = double.NaN;
+      TestF1Score = double.NaN;
+      TestMatthewsCorrelation = double.NaN;
     }
 
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolutionBase.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolutionBase.cs	(revision 13040)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolutionBase.cs	(revision 13100)
@@ -26,4 +26,5 @@
 using HeuristicLab.Optimization;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis.OnlineCalculators;
 
 namespace HeuristicLab.Problems.DataAnalysis {
@@ -135,4 +136,15 @@
       if (testPerformanceCalculator.ErrorState == OnlineCalculatorError.None)
         ClassificationPerformanceMeasures.SetTestResults(testPerformanceCalculator);
+
+      var f1Training = FOneScoreCalculator.Calculate(originalTrainingClassValues, estimatedTrainingClassValues, out errorState);
+      if (errorState == OnlineCalculatorError.None) ClassificationPerformanceMeasures.TrainingF1Score = f1Training;
+      var f1Test = FOneScoreCalculator.Calculate(originalTestClassValues, estimatedTestClassValues, out errorState);
+      if (errorState == OnlineCalculatorError.None) ClassificationPerformanceMeasures.TestF1Score = f1Test;
+
+
+      var mccTraining = MatthewsCorrelationCoefficientCalculator.Calculate(originalTrainingClassValues, estimatedTrainingClassValues, out errorState);
+      if (errorState == OnlineCalculatorError.None) ClassificationPerformanceMeasures.TrainingMatthewsCorrelation = mccTraining;
+      var mccTest = MatthewsCorrelationCoefficientCalculator.Calculate(originalTestClassValues, estimatedTestClassValues, out errorState);
+      if (errorState == OnlineCalculatorError.None) ClassificationPerformanceMeasures.TestMatthewsCorrelation = mccTest;
     }
 
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ConstantClassificationSolution.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ConstantClassificationSolution.cs	(revision 13100)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ConstantClassificationSolution.cs	(revision 13100)
@@ -0,0 +1,47 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item(Name = "Constant Classification Solution", Description = "Represents a constant classification solution (model + data).")]
+  public class ConstantClassificationSolution : ClassificationSolution {
+    public new ConstantModel Model {
+      get { return (ConstantModel)base.Model; }
+      set { base.Model = value; }
+    }
+
+    [StorableConstructor]
+    protected ConstantClassificationSolution(bool deserializing) : base(deserializing) { }
+    protected ConstantClassificationSolution(ConstantClassificationSolution original, Cloner cloner) : base(original, cloner) { }
+    public ConstantClassificationSolution(ConstantModel model, IClassificationProblemData problemData)
+      : base(model, problemData) {
+      RecalculateResults();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ConstantClassificationSolution(this, cloner);
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ConstantModel.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ConstantModel.cs	(revision 13100)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ConstantModel.cs	(revision 13100)
@@ -0,0 +1,99 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("Constant Model", "A model that always returns the same constant value regardless of the presented input data.")]
+  public class ConstantModel : NamedItem, IRegressionModel, IClassificationModel, ITimeSeriesPrognosisModel, IStringConvertibleValue {
+    [Storable]
+    private double constant;
+    public double Constant {
+      get { return constant; }
+      // setter not implemented because manipulation of the constant is not allowed
+    }
+
+    [StorableConstructor]
+    protected ConstantModel(bool deserializing) : base(deserializing) { }
+    protected ConstantModel(ConstantModel original, Cloner cloner)
+      : base(original, cloner) {
+      this.constant = original.constant;
+    }
+    public override IDeepCloneable Clone(Cloner cloner) { return new ConstantModel(this, cloner); }
+
+    public ConstantModel(double constant)
+      : base() {
+      this.name = ItemName;
+      this.description = ItemDescription;
+      this.constant = constant;
+      this.ReadOnly = true; // changing a constant regression model is not supported
+    }
+
+    public IEnumerable<double> GetEstimatedValues(IDataset dataset, IEnumerable<int> rows) {
+      return rows.Select(row => Constant);
+    }
+    public IEnumerable<double> GetEstimatedClassValues(IDataset dataset, IEnumerable<int> rows) {
+      return GetEstimatedValues(dataset, rows);
+    }
+    public IEnumerable<IEnumerable<double>> GetPrognosedValues(IDataset dataset, IEnumerable<int> rows, IEnumerable<int> horizons) {
+      return rows.Select(_ => horizons.Select(__ => Constant));
+    }
+
+    public IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
+      return new ConstantRegressionSolution(this, new RegressionProblemData(problemData));
+    }
+    public IClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData) {
+      return new ConstantClassificationSolution(this, new ClassificationProblemData(problemData));
+    }
+    public ITimeSeriesPrognosisSolution CreateTimeSeriesPrognosisSolution(ITimeSeriesPrognosisProblemData problemData) {
+      return new TimeSeriesPrognosisSolution(this, new TimeSeriesPrognosisProblemData(problemData));
+    }
+
+    public override string ToString() {
+      return string.Format("Constant: {0}", GetValue());
+    }
+
+    #region IStringConvertibleValue
+    public bool ReadOnly { get; private set; }
+    public bool Validate(string value, out string errorMessage) {
+      throw new NotSupportedException(); // changing a constant regression model is not supported
+    }
+
+    public string GetValue() {
+      return string.Format("{0:E4}", constant);
+    }
+
+    public bool SetValue(string value) {
+      throw new NotSupportedException(); // changing a constant regression model is not supported
+    }
+
+    public event EventHandler ValueChanged;
+    #endregion
+
+  }
+}
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ConstantRegressionModel.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ConstantRegressionModel.cs	(revision 13040)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ConstantRegressionModel.cs	(revision 13100)
@@ -31,4 +31,5 @@
   [StorableClass]
   [Item("Constant Regression Model", "A model that always returns the same constant value regardless of the presented input data.")]
+  [Obsolete]
   public class ConstantRegressionModel : NamedItem, IRegressionModel, IStringConvertibleValue {
     [Storable]
@@ -60,5 +61,5 @@
 
     public IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
-      return new ConstantRegressionSolution(this, new RegressionProblemData(problemData));
+      return new ConstantRegressionSolution(new ConstantModel(constant), new RegressionProblemData(problemData));
     }
 
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ConstantRegressionSolution.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ConstantRegressionSolution.cs	(revision 13040)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ConstantRegressionSolution.cs	(revision 13100)
@@ -28,6 +28,6 @@
   [Item(Name = "Constant Regression Solution", Description = "Represents a constant regression solution (model + data).")]
   public class ConstantRegressionSolution : RegressionSolution {
-    public new ConstantRegressionModel Model {
-      get { return (ConstantRegressionModel)base.Model; }
+    public new ConstantModel Model {
+      get { return (ConstantModel)base.Model; }
       set { base.Model = value; }
     }
@@ -36,5 +36,5 @@
     protected ConstantRegressionSolution(bool deserializing) : base(deserializing) { }
     protected ConstantRegressionSolution(ConstantRegressionSolution original, Cloner cloner) : base(original, cloner) { }
-    public ConstantRegressionSolution(ConstantRegressionModel model, IRegressionProblemData problemData)
+    public ConstantRegressionSolution(ConstantModel model, IRegressionProblemData problemData)
       : base(model, problemData) {
       RecalculateResults();
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/Models/ConstantTimeSeriesPrognosisModel.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/Models/ConstantTimeSeriesPrognosisModel.cs	(revision 13040)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/Models/ConstantTimeSeriesPrognosisModel.cs	(revision 13100)
@@ -20,4 +20,5 @@
 #endregion
 
+using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -29,4 +30,5 @@
   [StorableClass]
   [Item("Constant TimeSeries Model", "A time series model that returns for all prediciton the same constant value.")]
+  [Obsolete]
   public class ConstantTimeSeriesPrognosisModel : ConstantRegressionModel, ITimeSeriesPrognosisModel {
     [StorableConstructor]
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisResults.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisResults.cs	(revision 13040)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisResults.cs	(revision 13100)
@@ -373,5 +373,5 @@
       //mean model
       double trainingMean = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TrainingIndices).Average();
-      var meanModel = new ConstantTimeSeriesPrognosisModel(trainingMean);
+      var meanModel = new ConstantModel(trainingMean);
 
       //AR1 model
@@ -448,5 +448,5 @@
         //mean model
         double trainingMean = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TrainingIndices).Average();
-        var meanModel = new ConstantTimeSeriesPrognosisModel(trainingMean);
+        var meanModel = new ConstantModel(trainingMean);
 
         //AR1 model
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionBase.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionBase.cs	(revision 13040)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionBase.cs	(revision 13100)
@@ -150,5 +150,5 @@
       OnlineCalculatorError errorState;
       double trainingMean = ProblemData.TrainingIndices.Any() ? ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices).Average() : double.NaN;
-      var meanModel = new ConstantTimeSeriesPrognosisModel(trainingMean);
+      var meanModel = new ConstantModel(trainingMean);
 
       double alpha, beta;
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/ConfusionMatrixCalculator.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/ConfusionMatrixCalculator.cs	(revision 13100)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/ConfusionMatrixCalculator.cs	(revision 13100)
@@ -0,0 +1,72 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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;
+
+namespace HeuristicLab.Problems.DataAnalysis.OnlineCalculators {
+  public class ConfusionMatrixCalculator {
+    public static double[,] Calculate(IEnumerable<double> originalValues, IEnumerable<double> estimatedValues, out OnlineCalculatorError errorState) {
+      if (originalValues.Count() != estimatedValues.Count()) {
+        throw new ArgumentException("Number of elements in originalValues and estimatedValues enumerations doesn't match.");
+      }
+
+      var  classValues = originalValues.Distinct().ToList();
+      var estimatedClassValues = estimatedValues.Distinct().ToList();
+
+      if (!estimatedClassValues.All(x => classValues.Contains(x))) {
+        errorState = OnlineCalculatorError.InvalidValueAdded;
+        return null;
+      }
+
+      int classes = classValues.Count;
+      double[,] confusionMatrix = new double[classes, classes];
+
+      Dictionary<double, int> classValueIndexMapping = new Dictionary<double, int>();
+      int index = 0;
+      foreach (double classValue in classValues.OrderBy(x => x)) {
+        classValueIndexMapping.Add(classValue, index);
+        index++;
+      }
+
+      IEnumerator<double> originalEnumerator = originalValues.GetEnumerator();
+      IEnumerator<double> estimatedEnumerator = estimatedValues.GetEnumerator();
+      int originalIndex;
+      int estimatedIndex;
+      while (originalEnumerator.MoveNext() & estimatedEnumerator.MoveNext()) {
+        if (!classValueIndexMapping.TryGetValue(originalEnumerator.Current, out originalIndex)) {
+          errorState = OnlineCalculatorError.InvalidValueAdded;
+          return null;
+        }
+        if (!classValueIndexMapping.TryGetValue(estimatedEnumerator.Current, out estimatedIndex)) {
+          errorState = OnlineCalculatorError.InvalidValueAdded;
+          return null;
+        }
+
+        confusionMatrix[estimatedIndex, originalIndex] += 1;
+      }
+
+      errorState = OnlineCalculatorError.None;
+      return confusionMatrix;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/FOneScoreCalculator.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/FOneScoreCalculator.cs	(revision 13100)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/FOneScoreCalculator.cs	(revision 13100)
@@ -0,0 +1,47 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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;
+
+namespace HeuristicLab.Problems.DataAnalysis.OnlineCalculators {
+  public class FOneScoreCalculator {
+    public static double Calculate(IEnumerable<double> originalValues, IEnumerable<double> estimatedValues, out OnlineCalculatorError errorState) {
+      if (originalValues.Distinct().Skip(2).Any()) {
+        throw new ArgumentException("F1 score can only be calculated for binary classification.");
+      }
+
+      var confusionMatrix = ConfusionMatrixCalculator.Calculate(originalValues, estimatedValues, out errorState);
+      if (!errorState.Equals(OnlineCalculatorError.None)) {
+        return double.NaN;
+      }
+      return CalculateFOne(confusionMatrix);
+    }
+
+    private static double CalculateFOne(double[,] confusionMatrix) {
+      double precision = confusionMatrix[0, 0] / (confusionMatrix[0, 0] + confusionMatrix[0, 1]);
+      double recall = confusionMatrix[0, 0] / (confusionMatrix[0, 0] + confusionMatrix[1, 0]);
+
+      return 2 * ((precision * recall) / (precision + recall));
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/MatthewsCorrelationCoefficientCalculator.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/MatthewsCorrelationCoefficientCalculator.cs	(revision 13100)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/MatthewsCorrelationCoefficientCalculator.cs	(revision 13100)
@@ -0,0 +1,79 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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;
+
+namespace HeuristicLab.Problems.DataAnalysis.OnlineCalculators {
+  public class MatthewsCorrelationCoefficientCalculator {
+    public static double Calculate(IEnumerable<double> originalValues, IEnumerable<double> estimatedValues, out OnlineCalculatorError errorState) {
+      var confusionMatrix = ConfusionMatrixCalculator.Calculate(originalValues, estimatedValues, out errorState);
+      if (!errorState.Equals(OnlineCalculatorError.None)) {
+        return double.NaN;
+      }
+      return CalculateMCC(confusionMatrix);
+    }
+
+    private static double CalculateMCC(double[,] confusionMatrix) {
+      if (confusionMatrix.GetLength(0) != confusionMatrix.GetLength(1)) {
+        throw new ArgumentException("Confusion matrix is not a square matrix.");
+      }
+
+      int classes = confusionMatrix.GetLength(0);
+      double numerator = 0;
+      for (int k = 0; k < classes; k++) {
+        for (int l = 0; l < classes; l++) {
+          for (int m = 0; m < classes; m++) {
+            numerator += confusionMatrix[k, k] * confusionMatrix[m, l] - confusionMatrix[l, k] * confusionMatrix[k, m];
+          }
+        }
+      }
+
+      double denominator1 = 0;
+      double denominator2 = 0;
+      for (int k = 0; k < classes; k++) {
+        double clk = 0;
+        double cgf = 0;
+        double ckl = 0;
+        double cfg = 0;
+        for (int l = 0; l < classes; l++) {
+          clk += confusionMatrix[l, k];
+          ckl += confusionMatrix[k, l];
+        }
+        for (int f = 0; f < classes; f++) {
+          if (f == k) {
+            continue;
+          }
+          for (int g = 0; g < classes; g++) {
+            cgf += confusionMatrix[g, f];
+            cfg += confusionMatrix[f, g];
+          }
+        }
+        denominator1 += clk * cgf;
+        denominator2 += ckl * cfg;
+      }
+      denominator1 = Math.Sqrt(denominator1);
+      denominator2 = Math.Sqrt(denominator2);
+
+      return numerator / (denominator1 * denominator2);
+    }
+  }
+}
