Index: /trunk/sources/HeuristicLab.Modeling/3.2/DefaultRegressionOperators.cs
===================================================================
--- /trunk/sources/HeuristicLab.Modeling/3.2/DefaultRegressionOperators.cs	(revision 2378)
+++ /trunk/sources/HeuristicLab.Modeling/3.2/DefaultRegressionOperators.cs	(revision 2379)
@@ -60,4 +60,18 @@
       testMseEvaluator.GetVariableInfo("MSE").ActualName = ModelingResult.TestMeanSquaredError.ToString();
       testMseEvaluator.GetVariableInfo("Values").ActualName = "TestValues";
+      #endregion
+      #region NMSE
+      SimpleNMSEEvaluator trainingNmseEvaluator = new SimpleNMSEEvaluator();
+      trainingNmseEvaluator.Name = "TrainingNmseEvaluator";
+      trainingNmseEvaluator.GetVariableInfo("NMSE").ActualName = ModelingResult.TrainingNormalizedMeanSquaredError.ToString();
+      trainingNmseEvaluator.GetVariableInfo("Values").ActualName = "TrainingValues";
+      SimpleNMSEEvaluator validationNmseEvaluator = new SimpleNMSEEvaluator();
+      validationNmseEvaluator.Name = "ValidationMseEvaluator";
+      validationNmseEvaluator.GetVariableInfo("NMSE").ActualName = ModelingResult.ValidationNormalizedMeanSquaredError.ToString();
+      validationNmseEvaluator.GetVariableInfo("Values").ActualName = "ValidationValues";
+      SimpleNMSEEvaluator testNmseEvaluator = new SimpleNMSEEvaluator();
+      testNmseEvaluator.Name = "TestNmseEvaluator";
+      testNmseEvaluator.GetVariableInfo("NMSE").ActualName = ModelingResult.TestNormalizedMeanSquaredError.ToString();
+      testNmseEvaluator.GetVariableInfo("Values").ActualName = "TestValues";
       #endregion
       #region MAPE
@@ -121,4 +135,7 @@
       seq.AddSubOperator(validationMseEvaluator);
       seq.AddSubOperator(testMseEvaluator);
+      seq.AddSubOperator(trainingNmseEvaluator);
+      seq.AddSubOperator(validationNmseEvaluator);
+      seq.AddSubOperator(testNmseEvaluator);
       seq.AddSubOperator(trainingMapeEvaluator);
       seq.AddSubOperator(validationMapeEvaluator);
@@ -167,4 +184,7 @@
       model.ExtractResult(modelScope, ModelingResult.ValidationMeanSquaredError);
       model.ExtractResult(modelScope, ModelingResult.TestMeanSquaredError);
+      model.ExtractResult(modelScope, ModelingResult.TrainingNormalizedMeanSquaredError);
+      model.ExtractResult(modelScope, ModelingResult.ValidationNormalizedMeanSquaredError);
+      model.ExtractResult(modelScope, ModelingResult.TestNormalizedMeanSquaredError);
       model.ExtractResult(modelScope, ModelingResult.TrainingMeanAbsolutePercentageError);
       model.ExtractResult(modelScope, ModelingResult.ValidationMeanAbsolutePercentageError);
Index: /trunk/sources/HeuristicLab.Modeling/3.2/DefaultTimeSeriesOperators.cs
===================================================================
--- /trunk/sources/HeuristicLab.Modeling/3.2/DefaultTimeSeriesOperators.cs	(revision 2378)
+++ /trunk/sources/HeuristicLab.Modeling/3.2/DefaultTimeSeriesOperators.cs	(revision 2379)
@@ -45,4 +45,5 @@
       seq.AddSubOperator(DefaultRegressionOperators.CreatePostProcessingOperator());
 
+      #region theil inequality
       SimpleTheilInequalityCoefficientEvaluator trainingTheil = new SimpleTheilInequalityCoefficientEvaluator();
       trainingTheil.Name = "TrainingTheilInequalityEvaluator";
@@ -61,4 +62,43 @@
       seq.AddSubOperator(validationTheil);
       seq.AddSubOperator(testTheil);
+      #endregion
+
+      #region directional symmetry
+      SimpleDirectionalSymmetryEvaluator trainingDS = new SimpleDirectionalSymmetryEvaluator();
+      trainingDS.Name = "TrainingDirectionalSymmetryEvaluator";
+      trainingDS.GetVariableInfo("Values").ActualName = "TrainingValues";
+      trainingDS.GetVariableInfo("DirectionalSymmetry").ActualName = ModelingResult.TrainingDirectionalSymmetry.ToString();
+      SimpleDirectionalSymmetryEvaluator validationDS = new SimpleDirectionalSymmetryEvaluator();
+      validationDS.Name = "ValidationDirectionalSymmetryEvaluator";
+      validationDS.GetVariableInfo("Values").ActualName = "ValidationValues";
+      validationDS.GetVariableInfo("DirectionalSymmetry").ActualName = ModelingResult.ValidationDirectionalSymmetry.ToString();
+      SimpleDirectionalSymmetryEvaluator testDS = new SimpleDirectionalSymmetryEvaluator();
+      testDS.Name = "TestDirectionalSymmetryEvaluator";
+      testDS.GetVariableInfo("Values").ActualName = "TestValues";
+      testDS.GetVariableInfo("DirectionalSymmetry").ActualName = ModelingResult.TestDirectionalSymmetry.ToString();
+
+      seq.AddSubOperator(trainingDS);
+      seq.AddSubOperator(validationDS);
+      seq.AddSubOperator(testDS);
+      #endregion
+
+      #region weighted directional symmetry
+      SimpleWeightedDirectionalSymmetryEvaluator trainingWDS = new SimpleWeightedDirectionalSymmetryEvaluator();
+      trainingWDS.Name = "TrainingWeightedDirectionalSymmetryEvaluator";
+      trainingWDS.GetVariableInfo("Values").ActualName = "TrainingValues";
+      trainingWDS.GetVariableInfo("WeightedDirectionalSymmetry").ActualName = ModelingResult.TrainingWeightedDirectionalSymmetry.ToString();
+      SimpleWeightedDirectionalSymmetryEvaluator validationWDS = new SimpleWeightedDirectionalSymmetryEvaluator();
+      validationWDS.Name = "ValidationWeightedDirectionalSymmetryEvaluator";
+      validationWDS.GetVariableInfo("Values").ActualName = "ValidationValues";
+      validationWDS.GetVariableInfo("WeightedDirectionalSymmetry").ActualName = ModelingResult.ValidationWeightedDirectionalSymmetry.ToString();
+      SimpleWeightedDirectionalSymmetryEvaluator testWDS = new SimpleWeightedDirectionalSymmetryEvaluator();
+      testWDS.Name = "TestWeightedDirectionalSymmetryEvaluator";
+      testWDS.GetVariableInfo("Values").ActualName = "TestValues";
+      testWDS.GetVariableInfo("WeightedDirectionalSymmetry").ActualName = ModelingResult.TestWeightedDirectionalSymmetry.ToString();
+
+      seq.AddSubOperator(trainingWDS);
+      seq.AddSubOperator(validationWDS);
+      seq.AddSubOperator(testWDS);
+      #endregion
 
       op.OperatorGraph.AddOperator(seq);
@@ -72,4 +112,10 @@
       model.ExtractResult(modelScope, ModelingResult.ValidationTheilInequality);
       model.ExtractResult(modelScope, ModelingResult.TestTheilInequality);
+      model.ExtractResult(modelScope, ModelingResult.TrainingDirectionalSymmetry);
+      model.ExtractResult(modelScope, ModelingResult.ValidationDirectionalSymmetry);
+      model.ExtractResult(modelScope, ModelingResult.TestDirectionalSymmetry);
+      model.ExtractResult(modelScope, ModelingResult.TrainingWeightedDirectionalSymmetry);
+      model.ExtractResult(modelScope, ModelingResult.ValidationWeightedDirectionalSymmetry);
+      model.ExtractResult(modelScope, ModelingResult.TestWeightedDirectionalSymmetry);
       model.Type = ModelType.TimeSeriesPrognosis;
       return model;
Index: /trunk/sources/HeuristicLab.Modeling/3.2/HeuristicLab.Modeling-3.2.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Modeling/3.2/HeuristicLab.Modeling-3.2.csproj	(revision 2378)
+++ /trunk/sources/HeuristicLab.Modeling/3.2/HeuristicLab.Modeling-3.2.csproj	(revision 2379)
@@ -84,4 +84,7 @@
     <Compile Include="AnalyzerModel.cs" />
     <Compile Include="BestSolutionStorer.cs" />
+    <Compile Include="SimpleWeightedDirectionalSymmetryEvaluator.cs" />
+    <Compile Include="SimpleDirectionalSymmetryEvaluator.cs" />
+    <Compile Include="SimpleNMSEEvaluator.cs" />
     <Compile Include="ModelingResult.cs" />
     <Compile Include="ModelType.cs" />
Index: /trunk/sources/HeuristicLab.Modeling/3.2/MatrixCreator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Modeling/3.2/MatrixCreator.cs	(revision 2378)
+++ /trunk/sources/HeuristicLab.Modeling/3.2/MatrixCreator.cs	(revision 2379)
@@ -25,9 +25,9 @@
 
 namespace HeuristicLab.Modeling {
-  public class MatrixCreator<T> {
-    public static T[,] CreateMatrix(T[] first, T[] second) {
+  public class Matrix<T> {
+    public static T[,] Create(T[] first, T[] second) {
       if (first.Length != second.Length)
         throw new ArgumentException("Both arrays must be of same length.");
-      T[,] array = new T[first.Length,2];
+      T[,] array = new T[first.Length, 2];
       for (int i = 0; i < first.Length; i++) {
         array[i, 0] = first[i];
@@ -36,4 +36,13 @@
       return array;
     }
+
+    public static T[] GetColumn(T[,] matrix, int column) {
+      if (column >= matrix.GetLength(1)) throw new ArgumentException("Invalid column index: " + column + ". Matrix has only " + matrix.GetLength(1) + " columns.");
+      T[] result = new T[matrix.GetLength(0)];
+      for (int i = 0; i < result.Length; i++) {
+        result[i] = matrix[i, column];
+      }
+      return result;
+    }
   }
 }
Index: /trunk/sources/HeuristicLab.Modeling/3.2/ModelingResult.cs
===================================================================
--- /trunk/sources/HeuristicLab.Modeling/3.2/ModelingResult.cs	(revision 2378)
+++ /trunk/sources/HeuristicLab.Modeling/3.2/ModelingResult.cs	(revision 2379)
@@ -27,4 +27,8 @@
     TestMeanSquaredError,
 
+    TrainingNormalizedMeanSquaredError,
+    ValidationNormalizedMeanSquaredError,
+    TestNormalizedMeanSquaredError,
+
     TrainingMeanAbsolutePercentageError,
     ValidationMeanAbsolutePercentageError,
@@ -51,4 +55,12 @@
     TestTheilInequality,
 
+    TrainingDirectionalSymmetry,
+    ValidationDirectionalSymmetry,
+    TestDirectionalSymmetry,
+
+    TrainingWeightedDirectionalSymmetry,
+    ValidationWeightedDirectionalSymmetry,
+    TestWeightedDirectionalSymmetry,
+
     VariableQualityImpact,
     VariableEvaluationImpact
Index: /trunk/sources/HeuristicLab.Modeling/3.2/SimpleDirectionalSymmetryEvaluator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Modeling/3.2/SimpleDirectionalSymmetryEvaluator.cs	(revision 2379)
+++ /trunk/sources/HeuristicLab.Modeling/3.2/SimpleDirectionalSymmetryEvaluator.cs	(revision 2379)
@@ -0,0 +1,41 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.DataAnalysis;
+
+namespace HeuristicLab.Modeling {
+  public class SimpleDirectionalSymmetryEvaluator : SimpleEvaluatorBase {
+
+    public override string OutputVariableName {
+      get {
+        return "DirectionalSymmetry";
+      }
+    }
+
+    public override double Evaluate(double[,] values) {
+      return Calculate(values);
+    }
+
+    public static double Calculate(double[,] values) {
+      int n = 0;
+      int nCorrect = 0;
+      for (int i = 1; i < values.GetLength(0); i++) {
+        double prevOriginal = values[i - 1, ORIGINAL_INDEX];
+        double original = values[i, ORIGINAL_INDEX];
+        double prevEstimated = values[i - 1, ESTIMATION_INDEX];
+        double estimated = values[i, ESTIMATION_INDEX];
+
+        if (!(double.IsNaN(original) || double.IsInfinity(original) || double.IsNaN(prevOriginal) || double.IsInfinity(prevOriginal))) {
+          n++;
+          if (!(double.IsNaN(estimated) || double.IsInfinity(estimated) || double.IsNaN(prevEstimated) || double.IsInfinity(prevEstimated))) {
+            if ((original - prevOriginal) * (estimated - prevEstimated) >= 0) nCorrect++;
+          }
+        }
+      }
+      return (double)nCorrect / (double)n * 100.0;
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Modeling/3.2/SimpleNMSEEvaluator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Modeling/3.2/SimpleNMSEEvaluator.cs	(revision 2379)
+++ /trunk/sources/HeuristicLab.Modeling/3.2/SimpleNMSEEvaluator.cs	(revision 2379)
@@ -0,0 +1,43 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.DataAnalysis;
+
+namespace HeuristicLab.Modeling {
+  public class SimpleNMSEEvaluator : SimpleEvaluatorBase {
+
+    public override string OutputVariableName {
+      get {
+        return "NMSE";
+      }
+    }
+    public override double Evaluate(double[,] values) {
+      try {
+        return Calculate(values);
+      }
+      catch (ArgumentException) {
+        return double.PositiveInfinity;
+      }
+    }
+
+    public static double Calculate(double[,] values) {
+      double mse = SimpleMSEEvaluator.Calculate(values);
+      double mean = Statistics.Mean(Matrix<double>.GetColumn(values, ORIGINAL_INDEX));
+      double ssd = 0;
+      int n = 0;
+      for (int i = 0; i < values.GetLength(0); i++) {
+        double original = values[i, ORIGINAL_INDEX];
+        if (!(double.IsNaN(original) || double.IsInfinity(original))) {
+          double dev = original - mean;
+          ssd += dev * dev;
+          n++;
+        }
+      }
+      double variance = ssd / (n - 1);
+      return mse / variance;
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Modeling/3.2/SimpleWeightedDirectionalSymmetryEvaluator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Modeling/3.2/SimpleWeightedDirectionalSymmetryEvaluator.cs	(revision 2379)
+++ /trunk/sources/HeuristicLab.Modeling/3.2/SimpleWeightedDirectionalSymmetryEvaluator.cs	(revision 2379)
@@ -0,0 +1,41 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.DataAnalysis;
+
+namespace HeuristicLab.Modeling {
+  public class SimpleWeightedDirectionalSymmetryEvaluator : SimpleEvaluatorBase {
+
+    public override string OutputVariableName {
+      get {
+        return "WeightedDirectionalSymmetry";
+      }
+    }
+
+    public override double Evaluate(double[,] values) {
+      return Calculate(values);
+    }
+
+    public static double Calculate(double[,] values) {
+      double correctSum = 0.0;
+      double incorrectSum = 0.0;
+      for (int i = 1; i < values.GetLength(0); i++) {
+        double prevOriginal = values[i - 1, ORIGINAL_INDEX];
+        double original = values[i, ORIGINAL_INDEX];
+        double prevEstimated = values[i - 1, ESTIMATION_INDEX];
+        double estimated = values[i, ESTIMATION_INDEX];
+        if (!(double.IsNaN(original) || double.IsInfinity(original) || double.IsNaN(prevOriginal) || double.IsInfinity(prevOriginal))) {
+          if (!(double.IsNaN(estimated) || double.IsInfinity(estimated) || double.IsNaN(prevEstimated) || double.IsInfinity(prevEstimated))) {
+            double error = Math.Abs(estimated - original);
+            if ((original - prevOriginal) * (estimated - prevEstimated) >= 0) correctSum += error;
+            else incorrectSum += error;
+          }
+        }
+      }
+      return incorrectSum / correctSum;
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Modeling/3.2/VariableEvaluationImpactCalculator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Modeling/3.2/VariableEvaluationImpactCalculator.cs	(revision 2378)
+++ /trunk/sources/HeuristicLab.Modeling/3.2/VariableEvaluationImpactCalculator.cs	(revision 2379)
@@ -114,5 +114,5 @@
     private static double CalculateVAF(double[] referenceValues, double[] newValues) {
       try {
-        return SimpleVarianceAccountedForEvaluator.Calculate(MatrixCreator<double>.CreateMatrix(referenceValues, newValues));
+        return SimpleVarianceAccountedForEvaluator.Calculate(Matrix<double>.Create(referenceValues, newValues));
       }
       catch (ArgumentException) {
Index: /trunk/sources/HeuristicLab.Modeling/3.2/VariableQualityImpactCalculator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Modeling/3.2/VariableQualityImpactCalculator.cs	(revision 2378)
+++ /trunk/sources/HeuristicLab.Modeling/3.2/VariableQualityImpactCalculator.cs	(revision 2379)
@@ -122,5 +122,5 @@
     private static double CalculateMSE(double[] referenceValues, double[] newValues) {
       try {
-        return SimpleMSEEvaluator.Calculate(MatrixCreator<double>.CreateMatrix(referenceValues, newValues));
+        return SimpleMSEEvaluator.Calculate(Matrix<double>.Create(referenceValues, newValues));
       }
       catch (ArgumentException) {
