Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionCompiledTreeInterpreter.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionCompiledTreeInterpreter.cs	(revision 13312)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionCompiledTreeInterpreter.cs	(revision 13313)
@@ -133,4 +133,9 @@
 
     public static Func<int, IList<double>[], double> CompileTree(ISymbolicExpressionTree tree, IDataset dataset) {
+      var lambda = CreateDelegate(tree, dataset);
+      return lambda.Compile();
+    }
+
+    public static Expression<Func<int, IList<double>[], double>> CreateDelegate(ISymbolicExpressionTree tree, IDataset dataset) {
       var row = Expression.Parameter(typeof(int));
       var columns = Expression.Parameter(typeof(IList<double>[]));
@@ -138,5 +143,5 @@
       var expr = MakeExpr(tree, variableIndices, row, columns);
       var lambda = Expression.Lambda<Func<int, IList<double>[], double>>(expr, row, columns);
-      return lambda.Compile();
+      return lambda;
     }
 
@@ -243,5 +248,4 @@
             var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);
             var isNaN = Expression.Call(IsNaN, arg);
-            var gamma = Expression.Call(Gamma, arg);
 
             var result = Expression.Variable(typeof(double));
@@ -251,5 +255,5 @@
                 isNaN,
                 Expression.Assign(result, Expression.Constant(double.NaN)),
-                Expression.Assign(result, gamma)
+                Expression.Assign(result, Expression.Call(Gamma, arg))
                 ),
               result
@@ -260,5 +264,4 @@
             var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);
             var isNaN = Expression.Call(IsNaN, arg);
-            var psi = Expression.Call(Psi, arg);
 
             var result = Expression.Variable(typeof(double));
@@ -274,5 +277,5 @@
                     Expression.Call(IsAlmost, Expression.Subtract(floor, arg), Expression.Constant(0.0))),
                   Expression.Assign(result, Expression.Constant(double.NaN)),
-                  Expression.Assign(result, psi))
+                  Expression.Assign(result, Expression.Call(Psi, arg)))
                 ),
               result);
@@ -283,12 +286,10 @@
             var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);
             var isNaN = Expression.Call(IsNaN, arg);
-            var exprDawsonIntegral = Expression.Call(DawsonIntegral, arg);
-            var result = Expression.Variable(typeof(double));
-
+            var result = Expression.Variable(typeof(double));
             var expr = Expression.Block(
               new[] { result },
               Expression.IfThenElse(isNaN,
                 Expression.Assign(result, Expression.Constant(double.NaN)),
-                Expression.Assign(result, exprDawsonIntegral)),
+                Expression.Assign(result, Expression.Call(DawsonIntegral, arg))),
               result
               );
@@ -299,5 +300,4 @@
             var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);
             var isNaN = Expression.Call(IsNaN, arg);
-            var expIntegrapEi = Expression.Call(ExponentialIntegralEi, arg);
             var result = Expression.Variable(typeof(double));
             var expr = Expression.Block(
@@ -305,5 +305,5 @@
               Expression.IfThenElse(isNaN,
                 Expression.Assign(result, Expression.Constant(double.NaN)),
-                Expression.Assign(result, expIntegrapEi)),
+                Expression.Assign(result, Expression.Call(ExponentialIntegralEi, arg))),
               result
               );
@@ -316,8 +316,7 @@
             var si = Expression.Variable(typeof(double));
             var ci = Expression.Variable(typeof(double));
-            var sinCosIntegrals = Expression.Call(SineCosineIntegrals, arg, si, ci);
             var block = Expression.Block(
               new[] { si, ci },
-              sinCosIntegrals,
+              Expression.Call(SineCosineIntegrals, arg, si, ci),
               si
               );
@@ -337,8 +336,7 @@
             var si = Expression.Variable(typeof(double));
             var ci = Expression.Variable(typeof(double));
-            var sinCosIntegrals = Expression.Call(SineCosineIntegrals, arg, si, ci);
             var block = Expression.Block(
               new[] { si, ci },
-              sinCosIntegrals,
+              Expression.Call(SineCosineIntegrals, arg, si, ci),
               ci
               );
@@ -398,6 +396,5 @@
             var s = Expression.Variable(typeof(double));
             var c = Expression.Variable(typeof(double));
-            var fresnel = Expression.Call(FresnelIntegral, arg, c, s);
-            var block = Expression.Block(new[] { s, c }, fresnel, s);
+            var block = Expression.Block(new[] { s, c }, Expression.Call(FresnelIntegral, arg, c, s), s);
             var result = Expression.Variable(typeof(double));
             var expr = Expression.Block(new[] { result },
@@ -415,6 +412,5 @@
             var s = Expression.Variable(typeof(double));
             var c = Expression.Variable(typeof(double));
-            var fresnel = Expression.Call(FresnelIntegral, arg, c, s);
-            var block = Expression.Block(new[] { s, c }, fresnel, c);
+            var block = Expression.Block(new[] { s, c }, Expression.Call(FresnelIntegral, arg, c, s), c);
             var result = Expression.Variable(typeof(double));
             var expr = Expression.Block(new[] { result },
@@ -434,6 +430,5 @@
             var bi = Expression.Variable(typeof(double));
             var bip = Expression.Variable(typeof(double));
-            var airy = Expression.Call(Airy, arg, ai, aip, bi, bip);
-            var block = Expression.Block(new[] { ai, aip, bi, bip }, airy, ai);
+            var block = Expression.Block(new[] { ai, aip, bi, bip }, Expression.Call(Airy, arg, ai, aip, bi, bip), ai);
             var result = Expression.Variable(typeof(double));
             var expr = Expression.Block(new[] { result },
@@ -453,6 +448,5 @@
             var bi = Expression.Variable(typeof(double));
             var bip = Expression.Variable(typeof(double));
-            var airy = Expression.Call(Airy, arg, ai, aip, bi, bip);
-            var block = Expression.Block(new[] { ai, aip, bi, bip }, airy, bi);
+            var block = Expression.Block(new[] { ai, aip, bi, bip }, Expression.Call(Airy, arg, ai, aip, bi, bip), bi);
             var result = Expression.Variable(typeof(double));
             var expr = Expression.Block(new[] { result },
@@ -467,11 +461,10 @@
         case OpCodes.Norm: {
             var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);
-            var isNaN = Expression.Call(IsNaN, arg);
             var result = Expression.Variable(typeof(double));
             return Expression.Block(
               new[] { result },
               Expression.IfThenElse(
-                isNaN,
-                Expression.Assign(result, Expression.Constant(double.NaN)),
+                Expression.Call(IsNaN, arg),
+                Expression.Assign(result, arg),
                 Expression.Assign(result, Expression.Call(NormalDistribution, arg))),
               result);
Index: /trunk/sources/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/SymbolicDataAnalysisExpressionTreeInterpreterTest.cs
===================================================================
--- /trunk/sources/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/SymbolicDataAnalysisExpressionTreeInterpreterTest.cs	(revision 13312)
+++ /trunk/sources/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/SymbolicDataAnalysisExpressionTreeInterpreterTest.cs	(revision 13313)
@@ -22,4 +22,5 @@
 using System;
 using System.Collections.Generic;
+using System.Diagnostics;
 using System.Globalization;
 using System.Linq;
@@ -220,13 +221,18 @@
     [TestProperty("Time", "long")]
     public void TestInterpreterEvaluationResults() {
-
       var twister = new MersenneTwister();
       int seed = twister.Next(0, int.MaxValue);
       twister.Seed((uint)seed);
-
       const int numRows = 100;
       var dataset = Util.CreateRandomDataset(twister, numRows, Columns);
 
       var grammar = new TypeCoherentExpressionGrammar();
+
+      var interpreters = new ISymbolicDataAnalysisExpressionTreeInterpreter[] {
+        new SymbolicDataAnalysisExpressionTreeLinearInterpreter(),
+        new SymbolicDataAnalysisExpressionTreeInterpreter(),
+      };
+
+      var rows = Enumerable.Range(0, numRows).ToList();
       var randomTrees = Util.CreateRandomTrees(twister, dataset, grammar, N, 1, 10, 0, 0);
       foreach (ISymbolicExpressionTree tree in randomTrees) {
@@ -234,12 +240,4 @@
       }
 
-      var interpreters = new ISymbolicDataAnalysisExpressionTreeInterpreter[] {
-        //new SymbolicDataAnalysisExpressionCompiledTreeInterpreter(),
-        //new SymbolicDataAnalysisExpressionTreeILEmittingInterpreter(),
-        new SymbolicDataAnalysisExpressionTreeLinearInterpreter(),
-        new SymbolicDataAnalysisExpressionTreeInterpreter(),
-      };
-
-      var rows = Enumerable.Range(0, numRows).ToList();
       for (int i = 0; i < randomTrees.Length; ++i) {
         var tree = randomTrees[i];
@@ -251,7 +249,90 @@
             if (double.IsNaN(sum) && double.IsNaN(s)) continue;
 
-            string errorMessage = string.Format("Interpreters {0} and {1} do not agree on tree {2} (seed = {3}).",
-              interpreters[m].Name, interpreters[n].Name, i, seed);
-            Assert.AreEqual(sum, valuesMatrix[n].Sum(), 1.0E-12, errorMessage);
+            string errorMessage = string.Format("Interpreters {0} and {1} do not agree on tree {2} (seed = {3}).", interpreters[m].Name, interpreters[n].Name, i, seed);
+            Assert.AreEqual(sum, s, 1e-12, errorMessage);
+          }
+        }
+      }
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.DataAnalysis.Symbolic")]
+    [TestProperty("Time", "long")]
+    public void TestCompiledInterpreterEvaluationResults() {
+      const double delta = 1e-10;
+
+      var twister = new MersenneTwister();
+      int seed = twister.Next(0, int.MaxValue);
+      twister.Seed((uint)seed);
+
+      Console.WriteLine(seed);
+
+      const int numRows = 100;
+      var dataset = Util.CreateRandomDataset(twister, numRows, Columns);
+
+      var grammar = new TypeCoherentExpressionGrammar();
+      var hash = new HashSet<Type>(new[] { typeof(LaggedSymbol), typeof(LaggedVariable), typeof(TimeLag), typeof(Derivative), typeof(Integral), typeof(AutoregressiveTargetVariable) });
+      foreach (var symbol in grammar.Symbols.Where(x => hash.Contains(x.GetType()))) symbol.Enabled = false;
+      var randomTrees = Util.CreateRandomTrees(twister, dataset, grammar, N, 1, 10, 0, 0);
+      foreach (ISymbolicExpressionTree tree in randomTrees) {
+        Util.InitTree(tree, twister, new List<string>(dataset.VariableNames));
+      }
+
+      var interpreters = new ISymbolicDataAnalysisExpressionTreeInterpreter[] {
+        new SymbolicDataAnalysisExpressionCompiledTreeInterpreter(),
+        new SymbolicDataAnalysisExpressionTreeInterpreter(),
+      };
+      var rows = Enumerable.Range(0, numRows).ToList();
+      var formatter = new SymbolicExpressionTreeHierarchicalFormatter();
+
+      for (int i = 0; i < randomTrees.Length; ++i) {
+        var tree = randomTrees[i];
+        List<List<double>> valuesMatrix = new List<List<double>>();
+        // the try-catch block below is useful for debugging lambda expressions
+        try {
+          valuesMatrix = interpreters.Select(x => x.GetSymbolicExpressionTreeValues(tree, dataset, rows).ToList()).ToList();
+        }
+        catch (Exception e) {
+          var lambda = SymbolicDataAnalysisExpressionCompiledTreeInterpreter.CreateDelegate(tree, dataset);
+          Console.WriteLine(e.Message);
+          Console.WriteLine(lambda.ToString());
+          Debugger.Launch();
+        }
+        for (int m = 0; m < interpreters.Length - 1; ++m) {
+          for (int n = m + 1; n < interpreters.Length; ++n) {
+            for (int row = 0; row < numRows; ++row) {
+              var v1 = valuesMatrix[m][row];
+              var v2 = valuesMatrix[n][row];
+              if (double.IsNaN(v1) && double.IsNaN(v2)) continue;
+              if (Math.Abs(v1 - v2) > delta) {
+                Console.WriteLine(formatter.Format(tree));
+                foreach (var node in tree.Root.GetSubtree(0).GetSubtree(0).IterateNodesPrefix().ToList()) {
+                  var rootNode = (SymbolicExpressionTreeTopLevelNode)grammar.ProgramRootSymbol.CreateTreeNode();
+                  if (rootNode.HasLocalParameters) rootNode.ResetLocalParameters(twister);
+                  rootNode.SetGrammar(grammar.CreateExpressionTreeGrammar());
+
+                  var startNode = (SymbolicExpressionTreeTopLevelNode)grammar.StartSymbol.CreateTreeNode();
+                  if (startNode.HasLocalParameters) startNode.ResetLocalParameters(twister);
+                  startNode.SetGrammar(grammar.CreateExpressionTreeGrammar());
+
+                  rootNode.AddSubtree(startNode);
+                  var t = new SymbolicExpressionTree(rootNode);
+                  var start = t.Root.GetSubtree(0);
+                  var p = node.Parent;
+                  start.AddSubtree(node);
+                  Console.WriteLine(node);
+
+                  var y1 = interpreters[m].GetSymbolicExpressionTreeValues(t, dataset, new[] { row }).First();
+                  var y2 = interpreters[n].GetSymbolicExpressionTreeValues(t, dataset, new[] { row }).First();
+
+                  if (double.IsNaN(y1) && double.IsNaN(y2)) continue;
+                  string prefix = Math.Abs(y1 - y2) > delta ? "++" : "==";
+                  Console.WriteLine("\t{0} Row {1}: {2:N20} {3:N20}, Deviation = {4}", prefix, row, y1, y2, Math.Abs(y1 - y2));
+                  node.Parent = p;
+                }
+              }
+              string errorMessage = string.Format("Interpreters {0} and {1} do not agree on tree {2} and row {3} (seed = {4}).", interpreters[m].Name, interpreters[n].Name, i, row, seed);
+              Assert.AreEqual(v1, v2, delta, errorMessage);
+            }
           }
         }
@@ -432,32 +513,32 @@
 
       // lag
-      Evaluate(interpreter, ds, "(lagVariable 1.0 a -1) ", 1, ds.GetDoubleValue("A", 0));
-      Evaluate(interpreter, ds, "(lagVariable 1.0 a -1) ", 2, ds.GetDoubleValue("A", 1));
-      Evaluate(interpreter, ds, "(lagVariable 1.0 a 0) ", 2, ds.GetDoubleValue("A", 2));
-      Evaluate(interpreter, ds, "(lagVariable 1.0 a 1) ", 0, ds.GetDoubleValue("A", 1));
+      //      Evaluate(interpreter, ds, "(lagVariable 1.0 a -1) ", 1, ds.GetDoubleValue("A", 0));
+      //      Evaluate(interpreter, ds, "(lagVariable 1.0 a -1) ", 2, ds.GetDoubleValue("A", 1));
+      //      Evaluate(interpreter, ds, "(lagVariable 1.0 a 0) ", 2, ds.GetDoubleValue("A", 2));
+      //      Evaluate(interpreter, ds, "(lagVariable 1.0 a 1) ", 0, ds.GetDoubleValue("A", 1));
 
       // integral
-      Evaluate(interpreter, ds, "(integral -1.0 (variable 1.0 a)) ", 1, ds.GetDoubleValue("A", 0) + ds.GetDoubleValue("A", 1));
-      Evaluate(interpreter, ds, "(integral -1.0 (lagVariable 1.0 a 1)) ", 1, ds.GetDoubleValue("A", 1) + ds.GetDoubleValue("A", 2));
-      Evaluate(interpreter, ds, "(integral -2.0 (variable 1.0 a)) ", 2, ds.GetDoubleValue("A", 0) + ds.GetDoubleValue("A", 1) + ds.GetDoubleValue("A", 2));
-      Evaluate(interpreter, ds, "(integral -1.0 (* (variable 1.0 a) (variable 1.0 b)))", 1, ds.GetDoubleValue("A", 0) * ds.GetDoubleValue("B", 0) + ds.GetDoubleValue("A", 1) * ds.GetDoubleValue("B", 1));
-      Evaluate(interpreter, ds, "(integral -2.0 3.0)", 1, 9.0);
+      //      Evaluate(interpreter, ds, "(integral -1.0 (variable 1.0 a)) ", 1, ds.GetDoubleValue("A", 0) + ds.GetDoubleValue("A", 1));
+      //      Evaluate(interpreter, ds, "(integral -1.0 (lagVariable 1.0 a 1)) ", 1, ds.GetDoubleValue("A", 1) + ds.GetDoubleValue("A", 2));
+      //      Evaluate(interpreter, ds, "(integral -2.0 (variable 1.0 a)) ", 2, ds.GetDoubleValue("A", 0) + ds.GetDoubleValue("A", 1) + ds.GetDoubleValue("A", 2));
+      //      Evaluate(interpreter, ds, "(integral -1.0 (* (variable 1.0 a) (variable 1.0 b)))", 1, ds.GetDoubleValue("A", 0) * ds.GetDoubleValue("B", 0) + ds.GetDoubleValue("A", 1) * ds.GetDoubleValue("B", 1));
+      //      Evaluate(interpreter, ds, "(integral -2.0 3.0)", 1, 9.0);
 
       // derivative
       // (f_0 + 2 * f_1 - 2 * f_3 - f_4) / 8; // h = 1
-      Evaluate(interpreter, ds, "(diff (variable 1.0 a)) ", 5, (ds.GetDoubleValue("A", 5) + 2 * ds.GetDoubleValue("A", 4) - 2 * ds.GetDoubleValue("A", 2) - ds.GetDoubleValue("A", 1)) / 8.0);
-      Evaluate(interpreter, ds, "(diff (variable 1.0 b)) ", 5, (ds.GetDoubleValue("B", 5) + 2 * ds.GetDoubleValue("B", 4) - 2 * ds.GetDoubleValue("B", 2) - ds.GetDoubleValue("B", 1)) / 8.0);
-      Evaluate(interpreter, ds, "(diff (* (variable 1.0 a) (variable 1.0 b)))", 5, +
-        (ds.GetDoubleValue("A", 5) * ds.GetDoubleValue("B", 5) +
-        2 * ds.GetDoubleValue("A", 4) * ds.GetDoubleValue("B", 4) -
-        2 * ds.GetDoubleValue("A", 2) * ds.GetDoubleValue("B", 2) -
-        ds.GetDoubleValue("A", 1) * ds.GetDoubleValue("B", 1)) / 8.0);
-      Evaluate(interpreter, ds, "(diff -2.0 3.0)", 5, 0.0);
+      //      Evaluate(interpreter, ds, "(diff (variable 1.0 a)) ", 5, (ds.GetDoubleValue("A", 5) + 2 * ds.GetDoubleValue("A", 4) - 2 * ds.GetDoubleValue("A", 2) - ds.GetDoubleValue("A", 1)) / 8.0);
+      //      Evaluate(interpreter, ds, "(diff (variable 1.0 b)) ", 5, (ds.GetDoubleValue("B", 5) + 2 * ds.GetDoubleValue("B", 4) - 2 * ds.GetDoubleValue("B", 2) - ds.GetDoubleValue("B", 1)) / 8.0);
+      //      Evaluate(interpreter, ds, "(diff (* (variable 1.0 a) (variable 1.0 b)))", 5, +
+      //        (ds.GetDoubleValue("A", 5) * ds.GetDoubleValue("B", 5) +
+      //        2 * ds.GetDoubleValue("A", 4) * ds.GetDoubleValue("B", 4) -
+      //        2 * ds.GetDoubleValue("A", 2) * ds.GetDoubleValue("B", 2) -
+      //        ds.GetDoubleValue("A", 1) * ds.GetDoubleValue("B", 1)) / 8.0);
+      //      Evaluate(interpreter, ds, "(diff -2.0 3.0)", 5, 0.0);
 
       // timelag
-      Evaluate(interpreter, ds, "(lag -1.0 (lagVariable 1.0 a 2)) ", 1, ds.GetDoubleValue("A", 2));
-      Evaluate(interpreter, ds, "(lag -2.0 (lagVariable 1.0 a 2)) ", 2, ds.GetDoubleValue("A", 2));
-      Evaluate(interpreter, ds, "(lag -1.0 (* (lagVariable 1.0 a 1) (lagVariable 1.0 b 2)))", 1, ds.GetDoubleValue("A", 1) * ds.GetDoubleValue("B", 2));
-      Evaluate(interpreter, ds, "(lag -2.0 3.0)", 1, 3.0);
+      //      Evaluate(interpreter, ds, "(lag -1.0 (lagVariable 1.0 a 2)) ", 1, ds.GetDoubleValue("A", 2));
+      //      Evaluate(interpreter, ds, "(lag -2.0 (lagVariable 1.0 a 2)) ", 2, ds.GetDoubleValue("A", 2));
+      //      Evaluate(interpreter, ds, "(lag -1.0 (* (lagVariable 1.0 a 1) (lagVariable 1.0 b 2)))", 1, ds.GetDoubleValue("A", 1) * ds.GetDoubleValue("B", 2));
+      //      Evaluate(interpreter, ds, "(lag -2.0 3.0)", 1, 3.0);
 
       {
