Index: /branches/2966_interval_calculation/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj
===================================================================
--- /branches/2966_interval_calculation/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj	(revision 16322)
+++ /branches/2966_interval_calculation/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj	(revision 16323)
@@ -199,4 +199,5 @@
     <Compile Include="Interfaces\IVariableSymbol.cs" />
     <Compile Include="Interpreter\SymbolicDataAnalysisExpressionCompiledTreeInterpreter.cs" />
+    <Compile Include="Interpreter\Intervalnterpreter.cs" />
     <Compile Include="SymbolicDataAnalysisExpressionTreeSimplificationOperator.cs" />
     <Compile Include="SymbolicDataAnalysisModelComplexityCalculator.cs" />
Index: /branches/2966_interval_calculation/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/Intervalnterpreter.cs
===================================================================
--- /branches/2966_interval_calculation/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/Intervalnterpreter.cs	(revision 16323)
+++ /branches/2966_interval_calculation/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/Intervalnterpreter.cs	(revision 16323)
@@ -0,0 +1,216 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Algorithms.DataAnalysis.KnowledgeIntegration.IntervalArithmetic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+using HeuristicLab.Problems.DataAnalysis.Symbolic;
+
+namespace HeuristicLab.Algorithms.DataAnalysis.KnowledgeIntegration.Interpreter {
+  [StorableClass]
+  [Item("SymbolicDataAnalysisIntervalArithmeticInterpreter", "Interpreter for interval arithmetic within symbolic regression.")]
+  public class IntervalInterpreter : ParameterizedNamedItem{
+    private const string EvaluatedSolutionsParameterName = "EvaluatedSolutions";
+    public IFixedValueParameter<IntValue> EvaluatedSolutionsParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[EvaluatedSolutionsParameterName]; }
+    }
+
+    public int EvaluatedSolutions {
+      get { return EvaluatedSolutionsParameter.Value.Value; }
+      set { EvaluatedSolutionsParameter.Value.Value = value; }
+    }
+
+    public void ClearState() { }
+
+    protected IntervalInterpreter(bool deserializing) : base(deserializing) { }
+
+    protected IntervalInterpreter(IntervalInterpreter original,
+        Cloner cloner)
+        : base(original, cloner) { }
+
+    public IntervalInterpreter()
+        : base("SymbolicDataAnalysisIntervalArithmeticInterpreter", "Interpreter for interval arithmetic within symbolic regression.") { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new IntervalInterpreter(this, cloner);
+    }
+
+    private readonly object syncRoot = new object();
+
+    private static InterpreterState PrepareInterpreterState(ISymbolicExpressionTree tree, 
+      IEnumerable<int> rows, IDataset dataset = null, Dictionary<string, Interval> customIntervals = null) {
+      Instruction[] code = SymbolicExpressionTreeCompiler.Compile(tree, OpCodes.MapSymbolToOpCode);
+      int necessaryArgStackSize = 0;
+      
+      foreach(Instruction instr in code) {
+        if (instr.opCode == OpCodes.Variable) {
+          var variableTreeNode = (VariableTreeNode)instr.dynamicNode;
+          IList<double> values = new List<double>();
+
+          if (dataset != null && customIntervals != null) {
+            if (customIntervals.ContainsKey(variableTreeNode.VariableName)) {
+              instr.data = customIntervals[variableTreeNode.VariableName];
+            } else {
+              foreach (var rowEnum in rows) {
+                values.Add(dataset.GetReadOnlyDoubleValues(variableTreeNode.VariableName)[rowEnum]);
+              }
+              instr.data = new Interval(values.Min(), values.Max());
+            }
+          } else if (dataset != null) {
+             foreach (var rowEnum in rows) {
+              values.Add(dataset.GetReadOnlyDoubleValues(variableTreeNode.VariableName)[rowEnum]);
+            }
+            instr.data = new Interval(values.Min(), values.Max());
+          } else if (customIntervals != null) {
+            if (customIntervals.ContainsKey(variableTreeNode.VariableName)) { 
+              instr.data = customIntervals[variableTreeNode.VariableName];
+            }
+          } else {
+            throw new Exception("No valid input for variables!");
+          }
+        }
+      }
+
+      return new InterpreterState(code, necessaryArgStackSize);
+    }
+
+    private Interval Evaluate(InterpreterState state, Dictionary<ISymbolicExpressionTreeNode, Interval> intervals) {
+      Instruction currentInstr = state.NextInstruction();
+      switch (currentInstr.opCode) {
+        //Elementary arithmetic rules
+        case OpCodes.Add: {
+            var s = Evaluate(state, intervals);
+            for (int i = 1; i < currentInstr.nArguments; i++) {
+              s = Interval.Add(s, Evaluate(state, intervals));
+            }
+            intervals.Add(currentInstr.dynamicNode, s);
+            return s;
+          }
+        case OpCodes.Sub: {
+            var s = Evaluate(state, intervals);
+            for (int i = 1; i < currentInstr.nArguments; i++) {
+              s = Interval.Subtract(s, Evaluate(state, intervals));
+            }
+            intervals.Add(currentInstr.dynamicNode, s);
+            return s;
+          }
+        case OpCodes.Mul: {
+            var s = Evaluate(state, intervals);
+            for (int i = 1; i < currentInstr.nArguments; i++) {
+              s = Interval.Multiply(s, Evaluate(state, intervals));
+            }
+            intervals.Add(currentInstr.dynamicNode, s);
+            return s;
+          }
+        case OpCodes.Div: {
+            var s = Evaluate(state, intervals);
+            for (int i = 1; i < currentInstr.nArguments; i++) {
+              s = Interval.Divide(s, Evaluate(state, intervals));
+            }
+            intervals.Add(currentInstr.dynamicNode, s);
+            return s;
+          }
+        //Trigonometric functions
+        case OpCodes.Sin: {
+            var s = Interval.Sine(Evaluate(state, intervals));
+            intervals.Add(currentInstr.dynamicNode, s);
+            return s;
+          }
+        case OpCodes.Cos: {
+            var s = Interval.Cosine(Evaluate(state, intervals));
+            intervals.Add(currentInstr.dynamicNode, s);
+            return s;
+          }
+        case OpCodes.Tan: {
+            var s = Interval.Tangens(Evaluate(state, intervals));
+            intervals.Add(currentInstr.dynamicNode, s);
+            return s;
+          }
+        //Exponential functions
+        case OpCodes.Log: {
+            var s = Interval.Logarithm(Evaluate(state, intervals));
+            intervals.Add(currentInstr.dynamicNode, s);
+            return s;
+          }
+        case OpCodes.Exp: {
+            var s = Interval.Exponential(Evaluate(state, intervals));
+            intervals.Add(currentInstr.dynamicNode, s);
+            return s;
+          }
+        case OpCodes.Power: {
+            var s = Evaluate(state, intervals);
+            for (int i = 1; i < currentInstr.nArguments; i++) {
+              s = Interval.Power(s, Evaluate(state, intervals));
+            }
+            intervals.Add(currentInstr.dynamicNode, s);
+            return s;
+          }
+        case OpCodes.Square: {
+            var s = Interval.Square(Evaluate(state, intervals));
+            intervals.Add(currentInstr.dynamicNode, s);
+            return s;
+          }
+        case OpCodes.Root: {
+            var s = Evaluate(state, intervals);
+            for (int i = 1; i < currentInstr.nArguments; i++) {
+              s = Interval.Root(s, Evaluate(state, intervals));
+            }
+            intervals.Add(currentInstr.dynamicNode, s);
+            return s;
+          }
+        case OpCodes.SquareRoot: {
+            var s = Interval.SquareRoot(Evaluate(state, intervals));
+            intervals.Add(currentInstr.dynamicNode, s);
+            return s;
+          }
+        //Variables, Constants, ...
+        case OpCodes.Variable: {
+            intervals.Add(currentInstr.dynamicNode, (Interval)currentInstr.data);
+            return (Interval)currentInstr.data;
+          }
+        case OpCodes.Constant: {
+            var constTreeNode = (ConstantTreeNode)currentInstr.dynamicNode;
+            var inter = new Interval(constTreeNode.Value, constTreeNode.Value);
+            intervals.Add(currentInstr.dynamicNode, inter);
+            return inter;
+          }
+        default:
+          throw new NotSupportedException();
+      }
+    }
+
+    public void InitializeState() {
+      EvaluatedSolutions = 0;
+    }
+
+    public Interval GetSymbolicExressionTreeIntervals(ISymbolicExpressionTree tree, IEnumerable<int> rows, out Dictionary<ISymbolicExpressionTreeNode, Interval> intervals) {
+      intervals = new Dictionary<ISymbolicExpressionTreeNode, Interval>();
+      var state = PrepareInterpreterState(tree, rows);
+      var x = Evaluate(state, intervals);
+
+      return x;
+    }
+
+    public Interval GetSymbolicExressionTreeIntervals(ISymbolicExpressionTree tree, IDataset dataset, IEnumerable<int> rows,
+      Dictionary<string, Interval> customIntervals, out Dictionary<ISymbolicExpressionTreeNode, Interval> intervals) {
+      intervals = new Dictionary<ISymbolicExpressionTreeNode, Interval>();
+      var state = PrepareInterpreterState(tree, rows, dataset, customIntervals);
+      var x = Evaluate(state, intervals);
+
+      return x;
+    }
+
+    public Interval GetSymbolicExressionTreeIntervals(ISymbolicExpressionTree tree, IDataset dataset, IEnumerable<int> rows, 
+      out Dictionary<ISymbolicExpressionTreeNode, Interval> intervals) {
+      intervals = new Dictionary<ISymbolicExpressionTreeNode, Interval>();
+      var state = PrepareInterpreterState(tree, rows, dataset);
+      var x = Evaluate(state, intervals);
+      
+      return x;
+    }
+  }
+}
Index: /branches/2966_interval_calculation/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj
===================================================================
--- /branches/2966_interval_calculation/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj	(revision 16322)
+++ /branches/2966_interval_calculation/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj	(revision 16323)
@@ -191,4 +191,5 @@
     <Compile Include="Implementation\ConstantModel.cs" />
     <Compile Include="Implementation\DataAnalysisModel.cs" />
+    <Compile Include="Implementation\Interval.cs" />
     <Compile Include="Implementation\Regression\ConfidenceBoundRegressionSolution.cs" />
     <Compile Include="Implementation\Regression\ConstantRegressionModel.cs" />
Index: /branches/2966_interval_calculation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Interval.cs
===================================================================
--- /branches/2966_interval_calculation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Interval.cs	(revision 16323)
+++ /branches/2966_interval_calculation/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Interval.cs	(revision 16323)
@@ -0,0 +1,208 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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;
+
+namespace HeuristicLab.Algorithms.DataAnalysis.KnowledgeIntegration.IntervalArithmetic {
+  public class Interval : IEquatable<Interval> {
+    private double lowerBound;
+    public double LowerBound {
+      get { return lowerBound; }
+      private set { lowerBound = value; }
+    }
+    private double upperBound;
+    public double UpperBound {
+      get { return upperBound; }
+      private set { lowerBound = value; }
+    }
+
+    public Interval(double lowerBound, double upperBound) {
+      if (lowerBound > upperBound)
+        throw new ArgumentException("LowerBound must be smaller than UpperBound.");
+
+      this.lowerBound = lowerBound;
+      this.upperBound = upperBound;
+    }
+
+    public bool Contains(double value) {
+      return lowerBound <= value && value <= upperBound;
+    }
+
+    public override string ToString() {
+      return "Interval: [" + lowerBound + ", " + upperBound + "]";
+    }
+
+    public bool IsInfiniteOrUndefined {
+      get {
+        return double.IsInfinity(LowerBound) || double.IsInfinity(UpperBound) ||
+                double.IsNaN(LowerBound) || double.IsNaN(UpperBound);
+      }
+    }
+
+    #region Equals, GetHashCode, == , !=
+    public bool Equals(Interval other) {
+      if (other == null)
+        return false;
+
+      return this.upperBound.IsAlmost(other.upperBound) && this.lowerBound.IsAlmost(other.lowerBound);
+    }
+
+    public override bool Equals(object obj) {
+      return Equals(obj as Interval);
+    }
+
+    public override int GetHashCode() {
+      return lowerBound.GetHashCode() ^ upperBound.GetHashCode();
+    }
+
+    public static bool operator ==(Interval interval1, Interval interval2) {
+      if (ReferenceEquals(interval1, null)) return ReferenceEquals(interval2, null);
+      return interval1.Equals(interval2);
+    }
+    public static bool operator !=(Interval interval1, Interval interval2) {
+      return !(interval1 == interval2);
+    }
+    #endregion
+
+    #region operations
+
+    // [x1,x2] + [y1,y2] = [x1 + y1,x2 + y2]
+    public static Interval Add(Interval a, Interval b) {
+      return new Interval(a.lowerBound + b.lowerBound, a.upperBound + b.upperBound);
+    }
+
+    // [x1,x2] − [y1,y2] = [x1 − y2,x2 − y1]
+    public static Interval Subtract(Interval a, Interval b) {
+      return new Interval(a.lowerBound - b.upperBound, a.upperBound - b.lowerBound);
+    }
+
+    // [x1,x2] * [y1,y2] = [min(x1*y1,x1*y2,x2*y1,x2*y2),max(x1*y1,x1*y2,x2*y1,x2*y2)]
+    public static Interval Multiply(Interval a, Interval b) {
+      double v1 = a.lowerBound * b.lowerBound;
+      double v2 = a.lowerBound * b.upperBound;
+      double v3 = a.upperBound * b.lowerBound;
+      double v4 = a.upperBound * b.upperBound;
+
+      double min = Math.Min(Math.Min(v1, v2), Math.Min(v3, v4));
+      double max = Math.Max(Math.Min(v1, v2), Math.Max(v3, v4));
+      return new Interval(min, max);
+    }
+
+    //mkommend: Divisiont by intervals containing 0 is implemented as defined in
+    //http://en.wikipedia.org/wiki/Interval_arithmetic
+    public static Interval Divide(Interval a, Interval b) {
+      if (b.Contains(0.0)) {
+        if (b.lowerBound.IsAlmost(0.0)) return Interval.Multiply(a, new Interval(1.0 / b.upperBound, double.PositiveInfinity));
+        else if (b.upperBound.IsAlmost(0.0)) return Interval.Multiply(a, new Interval(double.NegativeInfinity, 1.0 / b.lowerBound));
+        else return new Interval(double.NegativeInfinity, double.PositiveInfinity);
+      }
+      return Interval.Multiply(a, new Interval(1.0 / b.upperBound, 1.0 / b.lowerBound));
+    }
+
+    public static Interval Sine(Interval a) {
+      if (Math.Abs(a.upperBound - a.lowerBound) >= Math.PI * 2) return new Interval(-1, 1);
+
+      //divide the interval by PI/2 so that the optima lie at x element of N (0,1,2,3,4,...)
+      double Pihalf = Math.PI / 2;
+      Interval scaled = Interval.Divide(a, new Interval(Pihalf, Pihalf));
+      //move to positive scale
+      if (scaled.lowerBound < 0) {
+        int periodsToMove = Math.Abs((int)scaled.lowerBound / 4) + 1;
+        scaled = Interval.Add(scaled, new Interval(periodsToMove * 4, periodsToMove * 4));
+      }
+
+      double scaledLowerBound = scaled.lowerBound % 4.0;
+      double scaledUpperBound = scaled.upperBound % 4.0;
+      if (scaledUpperBound < scaledLowerBound) scaledUpperBound += 4.0;
+      List<double> sinValues = new List<double>();
+      sinValues.Add(Math.Sin(scaledLowerBound * Pihalf));
+      sinValues.Add(Math.Sin(scaledUpperBound * Pihalf));
+
+      int startValue = (int)Math.Ceiling(scaledLowerBound);
+      while (startValue < scaledUpperBound) {
+        sinValues.Add(Math.Sin(startValue * Pihalf));
+        startValue += 1;
+      }
+
+      return new Interval(sinValues.Min(), sinValues.Max());
+    }
+    public static Interval Cosine(Interval a) {
+      return Interval.Sine(Interval.Subtract(a, new Interval(Math.PI / 2, Math.PI / 2)));
+    }
+    public static Interval Tangens(Interval a) {
+      return Interval.Divide(Interval.Sine(a), Interval.Cosine(a));
+    }
+
+    public static Interval Logarithm(Interval a) {
+      return new Interval(Math.Log(a.lowerBound), Math.Log(a.upperBound));
+    }
+    public static Interval Exponential(Interval a) {
+      return new Interval(Math.Exp(a.lowerBound), Math.Exp(a.upperBound));
+    }
+
+    public static Interval Power(Interval a, Interval b) {
+      if (a.Contains(0.0) && b.lowerBound < 0) return new Interval(double.NaN, double.NaN);
+
+      int bLower = (int)Math.Round(b.lowerBound);
+      int bUpper = (int)Math.Round(b.upperBound);
+
+      List<double> powerValues = new List<double>();
+      powerValues.Add(Math.Pow(a.upperBound, bUpper));
+      powerValues.Add(Math.Pow(a.upperBound, bUpper - 1));
+      powerValues.Add(Math.Pow(a.upperBound, bLower));
+      powerValues.Add(Math.Pow(a.upperBound, bLower + 1));
+
+      powerValues.Add(Math.Pow(a.lowerBound, bUpper));
+      powerValues.Add(Math.Pow(a.lowerBound, bUpper - 1));
+      powerValues.Add(Math.Pow(a.lowerBound, bLower));
+      powerValues.Add(Math.Pow(a.lowerBound, bLower + 1));
+
+      return new Interval(powerValues.Min(), powerValues.Max());
+    }
+
+    public static Interval Square(Interval a) {
+      return Power(a, new Interval(2, 2));
+    }
+
+    public static Interval Cubic(Interval a) {
+      return Power(a, new Interval(3, 3));
+    }
+
+    public static Interval Root(Interval a, Interval b) {
+      int lower = (int)Math.Round(b.lowerBound);
+      int higher = (int)Math.Round(b.upperBound);
+
+      return new Interval(Math.Pow(a.lowerBound, 1.0 / higher), Math.Pow(a.upperBound, 1.0 / lower));
+    }
+
+    public static Interval SquareRoot(Interval a) {
+      return Root(a, new Interval(2, 2));
+    }
+
+    public static Interval CubicRoot(Interval a) {
+      return Root(a, new Interval(3, 3));
+    }
+    #endregion
+  }
+}
