Index: branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.csproj
===================================================================
--- branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.csproj	(revision 17228)
+++ branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.csproj	(revision 17928)
@@ -119,4 +119,5 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="MultiObjective\NMSEConstraintsEvaluator.cs" />
     <Compile Include="MultiObjective\PearsonRSquaredNestedTreeSizeEvaluator.cs" />
     <Compile Include="MultiObjective\PearsonRSquaredNumberOfVariablesEvaluator.cs" />
@@ -125,5 +126,7 @@
     <Compile Include="MultiObjective\SymbolicRegressionMultiObjectiveValidationBestSolutionAnalyzer.cs" />
     <Compile Include="Plugin.cs" />
+    <Compile Include="ShapeConstraintsAnalyzer.cs" />
     <Compile Include="SingleObjective\ConstantOptimizationAnalyzer.cs" />
+    <Compile Include="SingleObjective\Evaluators\NMSEConstraintsEvaluator.cs" />
     <Compile Include="SingleObjective\Evaluators\SymbolicRegressionMeanRelativeErrorEvaluator.cs" />
     <Compile Include="SingleObjective\SymbolicRegressionSolutionsAnalyzer.cs" />
Index: branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/Interfaces/ISymbolicRegressionEvaluator.cs
===================================================================
--- branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/Interfaces/ISymbolicRegressionEvaluator.cs	(revision 17228)
+++ branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/Interfaces/ISymbolicRegressionEvaluator.cs	(revision 17928)
@@ -1,4 +1,3 @@
-﻿using HEAL.Attic;
-#region License Information
+﻿#region License Information
 /* HeuristicLab
  * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
@@ -20,5 +19,5 @@
  */
 #endregion
-
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
Index: branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/Interfaces/ISymbolicRegressionModel.cs
===================================================================
--- branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/Interfaces/ISymbolicRegressionModel.cs	(revision 17228)
+++ branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/Interfaces/ISymbolicRegressionModel.cs	(revision 17928)
@@ -1,4 +1,3 @@
-﻿using HEAL.Attic;
-#region License Information
+﻿#region License Information
 /* HeuristicLab
  * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
@@ -21,4 +20,6 @@
 #endregion
 
+using HEAL.Attic;
+
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
   [StorableType("a411e2b5-f926-41a6-b55b-1aef862db2fb")]
Index: branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/Interfaces/ISymbolicRegressionSolution.cs
===================================================================
--- branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/Interfaces/ISymbolicRegressionSolution.cs	(revision 17228)
+++ branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/Interfaces/ISymbolicRegressionSolution.cs	(revision 17928)
@@ -22,4 +22,5 @@
 
 
+
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
   [StorableType("dff1a450-e958-454f-bf8e-6b763fdcaff3")]
Index: branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/NMSEConstraintsEvaluator.cs
===================================================================
--- branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/NMSEConstraintsEvaluator.cs	(revision 17928)
+++ branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/NMSEConstraintsEvaluator.cs	(revision 17928)
@@ -0,0 +1,204 @@
+﻿#region License Information
+
+/* HeuristicLab
+ * Copyright (C) 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 HEAL.Attic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Parameters;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.MultiObjective {
+  [Item("NMSE Evaluator with shape-constraints",
+    "Calculates the NMSE and the constraints violations of a symbolic regression solution as objectives.")]
+  [StorableType("8E9D76B7-ED9C-43E7-9898-01FBD3633880")]
+  public class NMSEConstraintsEvaluator : SymbolicRegressionMultiObjectiveEvaluator {
+    public const string NumObjectivesParameterName = "NumObjectives";
+    private const string BoundsEstimatorParameterName = "BoundsEstimator";
+
+    public IFixedValueParameter<IntValue> NumObjectivesParameter =>
+      (IFixedValueParameter<IntValue>)Parameters[NumObjectivesParameterName];
+
+    public IValueParameter<IBoundsEstimator> BoundsEstimatorParameter =>
+      (IValueParameter<IBoundsEstimator>)Parameters[BoundsEstimatorParameterName];
+
+    [Storable]
+    private bool[] maximization;
+
+    public int NumObjectives {
+      get => NumObjectivesParameter.Value.Value;
+      set {
+        NumObjectivesParameter.Value.Value = value;
+
+        /*
+         * First objective is to minimize the NMSE
+         * All following objectives have to be minimized ==> Constraints
+         */
+        this.maximization = new bool[value];
+      }
+    }
+
+    public IBoundsEstimator BoundsEstimator {
+      get => BoundsEstimatorParameter.Value;
+      set => BoundsEstimatorParameter.Value = value;
+    }
+
+    #region Constructors
+
+    public NMSEConstraintsEvaluator() {
+      Parameters.Add(new FixedValueParameter<IntValue>(NumObjectivesParameterName, new IntValue(2)));
+      Parameters.Add(new ValueParameter<IBoundsEstimator>(BoundsEstimatorParameterName, new IntervalArithBoundsEstimator()));
+      maximization = new bool[2];
+    }
+
+    [StorableConstructor]
+    protected NMSEConstraintsEvaluator(StorableConstructorFlag _) : base(_) { }
+
+    protected NMSEConstraintsEvaluator(NMSEConstraintsEvaluator original, Cloner cloner) : base(original, cloner) {
+      this.maximization = (bool[])original.maximization.Clone();
+    }
+
+    #endregion
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new NMSEConstraintsEvaluator(this, cloner);
+    }
+
+
+    public override IOperation InstrumentedApply() {
+      var rows = GenerateRowsToEvaluate();
+      var tree = SymbolicExpressionTreeParameter.ActualValue;
+      var problemData = ProblemDataParameter.ActualValue;
+      var interpreter = SymbolicDataAnalysisTreeInterpreterParameter.ActualValue;
+      var estimationLimits = EstimationLimitsParameter.ActualValue;
+      var applyLinearScaling = ApplyLinearScalingParameter.ActualValue.Value;
+
+      if (UseConstantOptimization) {
+        SymbolicRegressionConstantOptimizationEvaluator.OptimizeConstants(interpreter, tree, problemData, rows,
+          false,
+          ConstantOptimizationIterations,
+          ConstantOptimizationUpdateVariableWeights,
+          estimationLimits.Lower,
+          estimationLimits.Upper);
+      } else {
+        if (applyLinearScaling) {
+          var rootNode = new ProgramRootSymbol().CreateTreeNode();
+          var startNode = new StartSymbol().CreateTreeNode();
+          var offset = tree.Root.GetSubtree(0) //Start
+                                .GetSubtree(0); //Offset
+          var scaling = offset.GetSubtree(0);
+
+          //Check if tree contains offset and scaling nodes
+          if (!(offset.Symbol is Addition) || !(scaling.Symbol is Multiplication))
+            throw new ArgumentException($"{ItemName} can only be used with IntervalArithmeticGrammar.");
+
+
+          var t = (ISymbolicExpressionTreeNode)scaling.GetSubtree(0).Clone();
+          rootNode.AddSubtree(startNode);
+          startNode.AddSubtree(t);
+          var newTree = new SymbolicExpressionTree(rootNode);
+
+          //calculate alpha and beta for scaling
+          var estimatedValues = interpreter.GetSymbolicExpressionTreeValues(newTree, problemData.Dataset, rows);
+
+          var targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
+          OnlineLinearScalingParameterCalculator.Calculate(estimatedValues, targetValues, out var alpha, out var beta,
+            out var errorState);
+          if (errorState == OnlineCalculatorError.None) {
+            //Set alpha and beta to the scaling nodes from ia grammar
+            var offsetParameter = offset.GetSubtree(1) as ConstantTreeNode;
+            offsetParameter.Value = alpha;
+            var scalingParameter = scaling.GetSubtree(1) as ConstantTreeNode;
+            scalingParameter.Value = beta;
+          }
+        }
+      }
+
+      var qualities = Calculate(interpreter, tree, estimationLimits.Lower, estimationLimits.Upper, problemData,
+        rows, BoundsEstimator);
+      QualitiesParameter.ActualValue = new DoubleArray(qualities);
+      return base.InstrumentedApply();
+    }
+
+    public override double[] Evaluate(
+      IExecutionContext context, ISymbolicExpressionTree tree,
+      IRegressionProblemData problemData,
+      IEnumerable<int> rows) {
+      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = context;
+      EstimationLimitsParameter.ExecutionContext = context;
+      ApplyLinearScalingParameter.ExecutionContext = context;
+
+      var quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree,
+        EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper,
+        problemData, rows, BoundsEstimator);
+
+      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
+      EstimationLimitsParameter.ExecutionContext = null;
+      ApplyLinearScalingParameter.ExecutionContext = null;
+
+      return quality;
+    }
+
+
+    public static double[] Calculate(
+      ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
+      ISymbolicExpressionTree solution, double lowerEstimationLimit,
+      double upperEstimationLimit,
+      IRegressionProblemData problemData, IEnumerable<int> rows, IBoundsEstimator estimator) {
+      OnlineCalculatorError errorState;
+      var estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, rows);
+      var targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
+      var constraints = problemData.ShapeConstraints.EnabledConstraints;
+      var intervalCollection = problemData.VariableRanges;
+
+      double nmse;
+
+      var boundedEstimatedValues = estimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit);
+      nmse = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(targetValues, boundedEstimatedValues, out errorState);
+      if (errorState != OnlineCalculatorError.None) nmse = 1.0;
+
+      if (nmse > 1)
+        nmse = 1.0;
+
+      var objectives = new List<double> { nmse };
+      var violations = IntervalUtil.GetConstraintViolations(constraints, estimator, intervalCollection, solution);
+      foreach (var violation in violations) {
+        if (double.IsNaN(violation) || double.IsInfinity(violation)) {
+          objectives.Add(double.MaxValue);
+        } else {
+          objectives.Add(violation);
+        }
+      }
+
+      return objectives.ToArray();
+    }
+
+    public override IEnumerable<bool> Maximization => maximization;
+  }
+}
Index: branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/ShapeConstraintsAnalyzer.cs
===================================================================
--- branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/ShapeConstraintsAnalyzer.cs	(revision 17928)
+++ branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/ShapeConstraintsAnalyzer.cs	(revision 17928)
@@ -0,0 +1,128 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Linq;
+using HEAL.Attic;
+using HeuristicLab.Analysis;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
+  [StorableType("4318C6BD-E0A1-45FE-AC30-96E7F73B51FB")]
+  [Item("ShapeConstraintsAnalyzer", "Analyzes the number of shape-constraint violations of symbolic regression models.")]
+  public class ShapeConstraintsAnalyzer : SymbolicDataAnalysisAnalyzer, ISymbolicExpressionTreeAnalyzer {
+    private const string ProblemDataParameterName = "ProblemData";
+    private const string ConstraintViolationsParameterName = "ConstraintViolations";
+    private const string InfeasibleSolutionsParameterName = "InfeasibleSolutions";
+
+    #region parameter properties
+
+    public ILookupParameter<IRegressionProblemData> RegressionProblemDataParameter =>
+      (ILookupParameter<IRegressionProblemData>) Parameters[ProblemDataParameterName];
+
+    public IResultParameter<DataTable> ConstraintViolationsParameter =>
+      (IResultParameter<DataTable>) Parameters[ConstraintViolationsParameterName];
+
+    public IResultParameter<DataTable> InfeasibleSolutionsParameter =>
+      (IResultParameter<DataTable>)Parameters[InfeasibleSolutionsParameterName];
+
+    #endregion
+
+    #region properties
+    public IRegressionProblemData RegressionProblemData => RegressionProblemDataParameter.ActualValue;
+    public DataTable ConstraintViolations => ConstraintViolationsParameter.ActualValue;
+    public DataTable InfeasibleSolutions => InfeasibleSolutionsParameter.ActualValue;
+    #endregion
+
+    public override bool EnabledByDefault => false;
+
+    [StorableConstructor]
+    protected ShapeConstraintsAnalyzer(StorableConstructorFlag _) : base(_) { }
+
+    protected ShapeConstraintsAnalyzer(ShapeConstraintsAnalyzer original, Cloner cloner) :
+      base(original, cloner) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ShapeConstraintsAnalyzer(this, cloner);
+    }
+
+    public ShapeConstraintsAnalyzer() {
+      Parameters.Add(new LookupParameter<IRegressionProblemData>(ProblemDataParameterName,
+        "The problem data of the symbolic data analysis problem."));
+      Parameters.Add(new ResultParameter<DataTable>(ConstraintViolationsParameterName,
+        "The number of constraint violations."));
+      Parameters.Add(new ResultParameter<DataTable>(InfeasibleSolutionsParameterName,
+        "The number of infeasible solutions."));
+
+
+      ConstraintViolationsParameter.DefaultValue = new DataTable(ConstraintViolationsParameterName) {
+        VisualProperties = {
+          XAxisTitle = "Generations",
+          YAxisTitle = "Constraint violations"
+        }
+      };
+
+      InfeasibleSolutionsParameter.DefaultValue = new DataTable(InfeasibleSolutionsParameterName) {
+        VisualProperties = {
+          XAxisTitle = "Generations",
+          YAxisTitle = "Infeasible solutions"
+        }
+      };
+    }
+
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() { }
+
+    public override IOperation Apply() {
+      var problemData = RegressionProblemData;
+      var trees = SymbolicExpressionTree.ToArray();
+
+      var results = ResultCollection;
+      var constraints = problemData.ShapeConstraints.EnabledConstraints;
+      var variableRanges = problemData.VariableRanges;
+      var constraintViolationsTable = ConstraintViolations;
+      var estimator = new IntervalArithBoundsEstimator();
+
+      if (!constraintViolationsTable.Rows.Any())
+        foreach (var constraint in constraints)
+          constraintViolationsTable.Rows.Add(new DataRow(constraint.ToString()));
+
+      foreach (var constraint in constraints) {
+        var numViolations = trees.Count(tree => IntervalUtil.GetConstraintViolation(constraint, estimator, variableRanges, tree) > 0.0);
+        constraintViolationsTable.Rows[constraint.ToString()].Values.Add(numViolations);
+      }
+
+      var constraintUnsatisfiedSolutionsDataTable = InfeasibleSolutions;
+      if (constraintUnsatisfiedSolutionsDataTable.Rows.Count == 0)
+        constraintUnsatisfiedSolutionsDataTable.Rows.Add(new DataRow(InfeasibleSolutionsParameterName));
+
+      constraintUnsatisfiedSolutionsDataTable.Rows[InfeasibleSolutionsParameterName]
+        .Values
+        .Add(trees.Count(t => IntervalUtil.GetConstraintViolations(constraints, estimator, variableRanges, t).Any(x => x > 0.0)));
+
+      return base.Apply();
+    }
+  }
+}
Index: branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/NMSEConstraintsEvaluator.cs
===================================================================
--- branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/NMSEConstraintsEvaluator.cs	(revision 17928)
+++ branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/NMSEConstraintsEvaluator.cs	(revision 17928)
@@ -0,0 +1,234 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 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 HEAL.Attic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Parameters;
+using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+  [Item("NMSE Evaluator with shape-constraints", "Calculates NMSE of a symbolic regression solution and checks constraints the fitness is a combination of NMSE and constraint violations.")]
+  [StorableType("27473973-DD8D-4375-997D-942E2280AE8E")]
+  public class NMSEConstraintsEvaluator : SymbolicRegressionSingleObjectiveEvaluator {
+    #region Parameter/Properties
+
+    private const string OptimizeParametersParameterName = "OptimizeParameters";
+    private const string ParameterOptimizationIterationsParameterName = "ParameterOptimizationIterations";
+    private const string UseSoftConstraintsParameterName = "UseSoftConstraintsEvaluation";
+    private const string BoundsEstimatorParameterName = "BoundsEstimator";
+    private const string PenaltyFactorParameterName = "PenaltyFactor";
+
+
+    public IFixedValueParameter<BoolValue> OptimizerParametersParameter =>
+      (IFixedValueParameter<BoolValue>)Parameters[OptimizeParametersParameterName];
+
+    public IFixedValueParameter<IntValue> ConstantOptimizationIterationsParameter =>
+      (IFixedValueParameter<IntValue>)Parameters[ParameterOptimizationIterationsParameterName];
+
+    public IFixedValueParameter<BoolValue> UseSoftConstraintsParameter =>
+      (IFixedValueParameter<BoolValue>)Parameters[UseSoftConstraintsParameterName];
+
+    public IValueParameter<IBoundsEstimator> BoundsEstimatorParameter =>
+      (IValueParameter<IBoundsEstimator>)Parameters[BoundsEstimatorParameterName];
+    public IFixedValueParameter<DoubleValue> PenaltyFactorParameter =>
+      (IFixedValueParameter<DoubleValue>)Parameters[PenaltyFactorParameterName];
+
+    public bool OptimizeParameters {
+      get => OptimizerParametersParameter.Value.Value;
+      set => OptimizerParametersParameter.Value.Value = value;
+    }
+
+    public int ConstantOptimizationIterations {
+      get => ConstantOptimizationIterationsParameter.Value.Value;
+      set => ConstantOptimizationIterationsParameter.Value.Value = value;
+    }
+
+    public bool UseSoftConstraints {
+      get => UseSoftConstraintsParameter.Value.Value;
+      set => UseSoftConstraintsParameter.Value.Value = value;
+    }
+
+    public IBoundsEstimator BoundsEstimator {
+      get => BoundsEstimatorParameter.Value;
+      set => BoundsEstimatorParameter.Value = value;
+    }
+
+    public double PenalityFactor {
+      get => PenaltyFactorParameter.Value.Value;
+      set => PenaltyFactorParameter.Value.Value = value;
+    }
+
+
+    public override bool Maximization => false; // NMSE is minimized
+
+    #endregion
+
+    #region Constructors/Cloning
+
+    [StorableConstructor]
+    protected NMSEConstraintsEvaluator(StorableConstructorFlag _) : base(_) { }
+
+    protected NMSEConstraintsEvaluator(
+      NMSEConstraintsEvaluator original, Cloner cloner) : base(original, cloner) { }
+
+    public NMSEConstraintsEvaluator() {
+      Parameters.Add(new FixedValueParameter<BoolValue>(OptimizeParametersParameterName,
+        "Define whether optimization of numeric parameters is active or not (default: false).", new BoolValue(false)));
+      Parameters.Add(new FixedValueParameter<IntValue>(ParameterOptimizationIterationsParameterName,
+        "Define how many parameter optimization steps should be performed (default: 10).", new IntValue(10)));
+      Parameters.Add(new FixedValueParameter<BoolValue>(UseSoftConstraintsParameterName,
+        "Define whether the constraints are penalized by soft or hard constraints (default: false).", new BoolValue(false)));
+      Parameters.Add(new ValueParameter<IBoundsEstimator>(BoundsEstimatorParameterName,
+        "The estimator which is used to estimate output ranges of models (default: interval arithmetic).", new IntervalArithBoundsEstimator()));
+      Parameters.Add(new FixedValueParameter<DoubleValue>(PenaltyFactorParameterName,
+        "Punishment factor for constraint violations for soft constraint handling (fitness = NMSE + penaltyFactor * avg(violations)) (default: 1.0)", new DoubleValue(1.0)));
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new NMSEConstraintsEvaluator(this, cloner);
+    }
+
+    #endregion
+
+    public override IOperation InstrumentedApply() {
+      var rows = GenerateRowsToEvaluate();
+      var tree = SymbolicExpressionTreeParameter.ActualValue;
+      var problemData = ProblemDataParameter.ActualValue;
+      var interpreter = SymbolicDataAnalysisTreeInterpreterParameter.ActualValue;
+      var estimationLimits = EstimationLimitsParameter.ActualValue;
+      var applyLinearScaling = ApplyLinearScalingParameter.ActualValue.Value;
+
+      if (OptimizeParameters) {
+        SymbolicRegressionConstantOptimizationEvaluator.OptimizeConstants(interpreter, tree, problemData, rows,
+          false, ConstantOptimizationIterations, true,
+          estimationLimits.Lower, estimationLimits.Upper);
+      } else {
+        if (applyLinearScaling) {
+          var rootNode = new ProgramRootSymbol().CreateTreeNode();
+          var startNode = new StartSymbol().CreateTreeNode();
+          var offset = tree.Root.GetSubtree(0) //Start
+                                .GetSubtree(0); //Offset
+          var scaling = offset.GetSubtree(0);
+
+          //Check if tree contains offset and scaling nodes
+          if (!(offset.Symbol is Addition) || !(scaling.Symbol is Multiplication))
+            throw new ArgumentException($"{ItemName} can only be used with IntervalArithmeticGrammar.");
+
+          var t = (ISymbolicExpressionTreeNode)scaling.GetSubtree(0).Clone();
+          rootNode.AddSubtree(startNode);
+          startNode.AddSubtree(t);
+          var newTree = new SymbolicExpressionTree(rootNode);
+
+          //calculate alpha and beta for scaling
+          var estimatedValues = interpreter.GetSymbolicExpressionTreeValues(newTree, problemData.Dataset, rows);
+
+          var targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
+          OnlineLinearScalingParameterCalculator.Calculate(estimatedValues, targetValues, out var alpha, out var beta,
+            out var errorState);
+
+          if (errorState == OnlineCalculatorError.None) {
+            //Set alpha and beta to the scaling nodes from ia grammar
+            var offsetParameter = offset.GetSubtree(1) as ConstantTreeNode;
+            offsetParameter.Value = alpha;
+            var scalingParameter = scaling.GetSubtree(1) as ConstantTreeNode;
+            scalingParameter.Value = beta;
+          }
+        } // else: alpha and beta are evolved
+      }
+
+      var quality = Calculate(interpreter, tree, estimationLimits.Lower, estimationLimits.Upper, problemData, rows,
+        BoundsEstimator, UseSoftConstraints, PenalityFactor);
+      QualityParameter.ActualValue = new DoubleValue(quality);
+
+      return base.InstrumentedApply();
+    }
+
+    public static double Calculate(
+      ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
+      ISymbolicExpressionTree tree,
+      double lowerEstimationLimit, double upperEstimationLimit,
+      IRegressionProblemData problemData, IEnumerable<int> rows,
+      IBoundsEstimator estimator,
+      bool useSoftConstraints = false, double penaltyFactor = 1.0) {
+
+      var estimatedValues = interpreter.GetSymbolicExpressionTreeValues(tree, problemData.Dataset, rows);
+      var targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
+      var constraints = problemData.ShapeConstraints.EnabledConstraints;
+      var intervalCollection = problemData.VariableRanges;
+
+      var boundedEstimatedValues = estimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit);
+      var nmse = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(targetValues, boundedEstimatedValues,
+        out var errorState);
+
+      if (errorState != OnlineCalculatorError.None) {
+        return 1.0;
+      }
+
+      var constraintViolations = IntervalUtil.GetConstraintViolations(constraints, estimator, intervalCollection, tree);
+
+      if (constraintViolations.Any(x => double.IsNaN(x) || double.IsInfinity(x))) {
+        return 1.0;
+      }
+
+      if (useSoftConstraints) {
+        if (penaltyFactor < 0.0)
+          throw new ArgumentException("The parameter has to be greater or equal 0.0!", nameof(penaltyFactor));
+
+        var weightedViolationSum = constraints
+          .Zip(constraintViolations, (c, v) => c.Weight * v)
+          .Average();
+
+        return Math.Min(nmse, 1.0) + penaltyFactor * weightedViolationSum;
+      } else if (constraintViolations.Any(x => x > 0.0)) {
+        return 1.0;
+      }
+
+      return nmse;
+    }
+
+    public override double Evaluate(
+      IExecutionContext context, ISymbolicExpressionTree tree, IRegressionProblemData problemData,
+      IEnumerable<int> rows) {
+      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = context;
+      EstimationLimitsParameter.ExecutionContext = context;
+      ApplyLinearScalingParameter.ExecutionContext = context;
+
+      var nmse = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree,
+        EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper,
+        problemData, rows, BoundsEstimator, UseSoftConstraints, PenalityFactor);
+
+      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
+      EstimationLimitsParameter.ExecutionContext = null;
+      ApplyLinearScalingParameter.ExecutionContext = null;
+
+      return nmse;
+    }
+  }
+}
Index: branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionConstantOptimizationEvaluator.cs
===================================================================
--- branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionConstantOptimizationEvaluator.cs	(revision 17228)
+++ branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionConstantOptimizationEvaluator.cs	(revision 17928)
@@ -209,7 +209,7 @@
       bool updateConstantsInTree = true, Action<double[], double, object> iterationCallback = null, EvaluationsCounter counter = null) {
 
-      // numeric constants in the tree become variables for constant opt
-      // variables in the tree become parameters (fixed values) for constant opt
-      // for each parameter (variable in the original tree) we store the 
+      // Numeric constants in the tree become variables for parameter optimization.
+      // Variables in the tree become parameters (fixed values) for parameter optimization.
+      // For each parameter (variable in the original tree) we store the 
       // variable name, variable value (for factor vars) and lag as a DataForVariable object.
       // A dictionary is used to find parameters
@@ -221,8 +221,8 @@
       if (!TreeToAutoDiffTermConverter.TryConvertToAutoDiff(tree, updateVariableWeights, applyLinearScaling, out parameters, out initialConstants, out func, out func_grad))
         throw new NotSupportedException("Could not optimize constants of symbolic expression tree due to not supported symbols used in the tree.");
-      if (parameters.Count == 0) return 0.0; // gkronber: constant expressions always have a R² of 0.0 
+      if (parameters.Count == 0) return 0.0; // constant expressions always have a R² of 0.0 
       var parameterEntries = parameters.ToArray(); // order of entries must be the same for x
 
-      //extract inital constants
+      // extract inital constants
       double[] c;
       if (applyLinearScaling) {
@@ -309,7 +309,9 @@
         VariableTreeNodeBase variableTreeNodeBase = node as VariableTreeNodeBase;
         FactorVariableTreeNode factorVarTreeNode = node as FactorVariableTreeNode;
-        if (constantTreeNode != null)
+        if (constantTreeNode != null) {
+          if (constantTreeNode.Parent.Symbol is Power 
+              && constantTreeNode.Parent.GetSubtree(1) == constantTreeNode) continue; // exponents in powers are not optimizated (see TreeToAutoDiffTermConverter)
           constantTreeNode.Value = constants[i++];
-        else if (updateVariableWeights && variableTreeNodeBase != null)
+        } else if (updateVariableWeights && variableTreeNodeBase != null)
           variableTreeNodeBase.Weight = constants[i++];
         else if (factorVarTreeNode != null) {
Index: branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveProblem.cs
===================================================================
--- branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveProblem.cs	(revision 17228)
+++ branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveProblem.cs	(revision 17928)
@@ -91,4 +91,9 @@
         changed = true;
       }
+
+      if (!Operators.OfType<ShapeConstraintsAnalyzer>().Any()) {
+        Operators.Add(new ShapeConstraintsAnalyzer());
+        changed = true;
+      }
       if (changed) {
         ParameterizeOperators();
@@ -113,4 +118,5 @@
       Operators.Add(new SymbolicRegressionSolutionsAnalyzer());
       Operators.Add(new SymbolicExpressionTreePhenotypicSimilarityCalculator());
+      Operators.Add(new ShapeConstraintsAnalyzer());
       Operators.Add(new SymbolicRegressionPhenotypicDiversityAnalyzer(Operators.OfType<SymbolicExpressionTreePhenotypicSimilarityCalculator>()) { DiversityResultName = "Phenotypic Diversity" });
       ParameterizeOperators();
Index: branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionSolution.cs
===================================================================
--- branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionSolution.cs	(revision 17228)
+++ branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionSolution.cs	(revision 17928)
@@ -1,3 +1,3 @@
-#region License Information
+﻿#region License Information
 /* HeuristicLab
  * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
@@ -21,4 +21,5 @@
 
 using System.Linq;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -26,5 +27,4 @@
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 using HeuristicLab.Optimization;
-using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
@@ -47,4 +47,6 @@
     private const string TestNaNEvaluationsResultName = "Test NaN Evaluations";
 
+    private const string ModelBoundsResultName = "Model Bounds";
+
     public new ISymbolicRegressionModel Model {
       get { return (ISymbolicRegressionModel)base.Model; }
@@ -95,4 +97,20 @@
       private set { ((IntValue)EstimationLimitsResultCollection[TestNaNEvaluationsResultName].Value).Value = value; }
     }
+
+    public IntervalCollection ModelBoundsCollection {
+      get {
+        if (!ContainsKey(ModelBoundsResultName)) return null;
+        return (IntervalCollection)this[ModelBoundsResultName].Value;
+      }
+      private set {
+        if (ContainsKey(ModelBoundsResultName)) {
+          this[ModelBoundsResultName].Value = value;
+        } else {
+          Add(new Result(ModelBoundsResultName, "Results concerning the derivation of symbolic regression solution", value));
+        }
+      }
+    }
+
+
 
     [StorableConstructor]
@@ -118,4 +136,8 @@
       estimationLimitResults.Add(new Result(TestNaNEvaluationsResultName, "", new IntValue()));
       Add(new Result(EstimationLimitsResultsResultName, "Results concerning the estimation limits of symbolic regression solution", estimationLimitResults));
+
+      if (IntervalInterpreter.IsCompatible(Model.SymbolicExpressionTree))
+        Add(new Result(ModelBoundsResultName, "Results concerning the derivation of symbolic regression solution", new IntervalCollection()));
+
       RecalculateResults();
     }
@@ -139,4 +161,11 @@
         CalculateResults();
       }
+
+      if (!ContainsKey(ModelBoundsResultName)) {
+        if (IntervalInterpreter.IsCompatible(Model.SymbolicExpressionTree)) {
+          Add(new Result(ModelBoundsResultName, "Results concerning the derivation of symbolic regression solution", new IntervalCollection()));
+          CalculateResults();
+        }
+      }
     }
 
@@ -159,4 +188,30 @@
       TrainingNaNEvaluations = Model.Interpreter.GetSymbolicExpressionTreeValues(Model.SymbolicExpressionTree, ProblemData.Dataset, ProblemData.TrainingIndices).Count(double.IsNaN);
       TestNaNEvaluations = Model.Interpreter.GetSymbolicExpressionTreeValues(Model.SymbolicExpressionTree, ProblemData.Dataset, ProblemData.TestIndices).Count(double.IsNaN);
+
+      //Check if the tree contains unknown symbols for the interval calculation
+      if (IntervalInterpreter.IsCompatible(Model.SymbolicExpressionTree))
+        ModelBoundsCollection = CalculateModelIntervals(this);
+    }
+
+    private static IntervalCollection CalculateModelIntervals(ISymbolicRegressionSolution solution) {
+      var intervalEvaluation = new IntervalCollection();
+      var interpreter = new IntervalInterpreter();
+      var problemData = solution.ProblemData;
+      var model = solution.Model;
+      var variableRanges = problemData.VariableRanges.GetReadonlyDictionary();
+
+      intervalEvaluation.AddInterval($"Target {problemData.TargetVariable}", new Interval(variableRanges[problemData.TargetVariable].LowerBound, variableRanges[problemData.TargetVariable].UpperBound));
+      intervalEvaluation.AddInterval("Model", interpreter.GetSymbolicExpressionTreeInterval(model.SymbolicExpressionTree, variableRanges));
+
+      if (DerivativeCalculator.IsCompatible(model.SymbolicExpressionTree)) {
+        foreach (var inputVariable in model.VariablesUsedForPrediction.OrderBy(v => v, new NaturalStringComparer())) {
+          var derivedModel = DerivativeCalculator.Derive(model.SymbolicExpressionTree, inputVariable);
+          var derivedResultInterval = interpreter.GetSymbolicExpressionTreeInterval(derivedModel, variableRanges);
+
+          intervalEvaluation.AddInterval(" ∂f/∂" + inputVariable, new Interval(derivedResultInterval.LowerBound, derivedResultInterval.UpperBound));
+        }
+      }
+
+      return intervalEvaluation;
     }
   }
