Index: branches/HeuristicLab.DataAnalysis.Symbolic.LinearInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeLinearInterpreter.cs
===================================================================
--- branches/HeuristicLab.DataAnalysis.Symbolic.LinearInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeLinearInterpreter.cs	(revision 9290)
+++ branches/HeuristicLab.DataAnalysis.Symbolic.LinearInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeLinearInterpreter.cs	(revision 9292)
@@ -124,129 +124,127 @@
       }
 
-      double[] values = new double[code.Length];
-
       foreach (var rowEnum in rows) {
         int row = rowEnum;
-        yield return Evaluate(dataset, ref row, code, values);
+        yield return Evaluate(dataset, ref row, code);
       }
     }
 
-    protected virtual double Evaluate(Dataset dataset, ref int row, Instruction[] code, double[] values) {
+    protected virtual double Evaluate(Dataset dataset, ref int row, Instruction[] code) {
       int count = 0;
       for (int j = 0; j != code.Length; ++j) {
         Instruction currentInstr = code[j];
-
-        #region switch
+	int narg = currentInstr.nArguments;
+
         switch (currentInstr.opCode) {
           case OpCodes.Add: {
-              double s = values[j - currentInstr.nArguments];
-              for (int i = j - currentInstr.nArguments + 1; i < j; i++) {
-                s += values[i];
-              }
-              values[j] = s;
+              double s = code[j - narg].value;
+              for (int i = j - narg + 1; i < j; i++) {
+                s += code[i].value;
+              }
+              currentInstr.value = s;
             }
             break;
           case OpCodes.Sub: {
-              double s = values[j - currentInstr.nArguments];
-              for (int i = j - currentInstr.nArguments + 1; i < j; i++) {
-                s -= values[i];
-              }
-              if (currentInstr.nArguments == 1) s = -s;
-              values[j] = s;
+              double s = code[j - narg].value;
+              for (int i = j - narg + 1; i < j; i++) {
+                s -= code[i].value;
+              }
+              if (narg == 1) s = -s;
+              currentInstr.value = s;
             }
             break;
           case OpCodes.Mul: {
-              double p = values[j - currentInstr.nArguments];
-              for (int i = j - currentInstr.nArguments + 1; i < j; i++) {
-                p *= values[i];
-              }
-              values[j] = p;
+              double p = code[j - narg].value;
+              for (int i = j - narg + 1; i < j; i++) {
+                p *= code[i].value;
+              }
+              currentInstr.value = p;
             }
             break;
           case OpCodes.Div: {
-              double p = values[j - currentInstr.nArguments];
-              for (int i = j - currentInstr.nArguments + 1; i < j; i++) {
-                p /= values[i];
-              }
-              if (currentInstr.nArguments == 1) p = 1.0 / p;
-              values[j] = p;
+              double p = code[j - narg].value;
+              for (int i = j - narg + 1; i < j; i++) {
+                p /= code[i].value;
+              }
+              if (narg == 1) p = 1.0 / p;
+              currentInstr.value = p;
             }
             break;
           case OpCodes.Average: {
-              double sum = values[j - currentInstr.nArguments];
-              for (int i = j - currentInstr.nArguments + 1; i < j; i++) {
-                sum += values[i];
-              }
-              values[j] = sum / currentInstr.nArguments;
+              double sum = code[j - narg].value;
+              for (int i = j - narg + 1; i < j; i++) {
+                sum += code[i].value;
+              }
+              currentInstr.value = sum / narg;
             }
             break;
           case OpCodes.Cos: {
-              values[j] = Math.Cos(values[j - currentInstr.nArguments]);
+              currentInstr.value = Math.Cos(code[j - 1].value);
             }
             break;
           case OpCodes.Sin: {
-              values[j] = Math.Sin(values[j - currentInstr.nArguments]);
+              currentInstr.value = Math.Sin(code[j - 1].value);
               break;
             }
           case OpCodes.Tan: {
-              values[j] = Math.Tan(values[j - currentInstr.nArguments]);
+              currentInstr.value = Math.Tan(code[j - 1].value);
             }
             break;
           case OpCodes.Square: {
-              values[j] = Math.Pow(values[j - currentInstr.nArguments], 2);
+              currentInstr.value = Math.Pow(code[j - 1].value, 2);
             }
             break;
           case OpCodes.Power: {
-              double x = values[j - currentInstr.nArguments];
-              double y = Math.Round(values[j - currentInstr.nArguments + 1]);
-              values[j] = Math.Pow(x, y);
+              double x = code[j - 2].value;
+              double y = Math.Round(code[j - 1].value);
+              currentInstr.value = Math.Pow(x, y);
             }
             break;
           case OpCodes.SquareRoot: {
-              values[j] = Math.Sqrt(values[j - currentInstr.nArguments]);
+              currentInstr.value = Math.Sqrt(code[j - 1].value);
             }
             break;
           case OpCodes.Root: {
-              double x = values[j - currentInstr.nArguments];
-              double y = Math.Round(values[j - currentInstr.nArguments + 1]);
-              values[j] = Math.Pow(x, 1 / y);
+              double x = code[j - 2].value;
+              double y = Math.Round(code[j - 1].value);
+              currentInstr.value = Math.Pow(x, 1 / y);
             }
             break;
           case OpCodes.Exp: {
-              values[j] = Math.Exp(values[j - currentInstr.nArguments]);
+              currentInstr.value = Math.Exp(code[j - 1].value);
             }
             break;
           case OpCodes.Log: {
-              values[j] = Math.Log(values[j - currentInstr.nArguments]);
+              currentInstr.value = Math.Log(code[j - 1].value);
             }
             break;
           case OpCodes.Gamma: {
-              values[j] = double.IsNaN(values[j - currentInstr.nArguments]) ? double.NaN : alglib.gammafunction(values[j - currentInstr.nArguments]);
+              currentInstr.value = double.IsNaN(code[j - 1].value) ? double.NaN : alglib.gammafunction(code[j - 1].value);
             }
             break;
           case OpCodes.Psi: {
-              var x = values[j - currentInstr.nArguments];
-              if (double.IsNaN(x)) values[j] = double.NaN;
-              else if (x <= 0 && (Math.Floor(x) - x).IsAlmost(0)) values[j] = double.NaN;
-              else values[j] = alglib.psi(x);
+              var x = code[j - 1].value;
+              if (double.IsNaN(x)) currentInstr.value = double.NaN;
+              else if (x <= 0 && (Math.Floor(x) - x).IsAlmost(0)) currentInstr.value = double.NaN;
+              else currentInstr.value = alglib.psi(x);
             }
             break;
           case OpCodes.Dawson: {
-              var x = values[j - currentInstr.nArguments];
-              values[j] = double.IsNaN(x) ? double.NaN : alglib.dawsonintegral(x);
+              var x = code[j - 1].value;
+              currentInstr.value = double.IsNaN(x) ? double.NaN : alglib.dawsonintegral(x);
             }
             break;
           case OpCodes.ExponentialIntegralEi: {
-              var x = values[j - currentInstr.nArguments];
-              values[j] = double.IsNaN(x) ? double.NaN : alglib.exponentialintegralei(x);
+              var x = code[j - 1].value;
+              currentInstr.value = double.IsNaN(x) ? double.NaN : alglib.exponentialintegralei(x);
             }
             break;
           case OpCodes.SineIntegral: {
               double si, ci;
-              var x = values[j - currentInstr.nArguments];
-              if (double.IsNaN(x)) values[j] = double.NaN;
+              var x = code[j - 1].value;
+              if (double.IsNaN(x)) currentInstr.value = double.NaN;
               else {
                 alglib.sinecosineintegrals(x, out si, out ci);
-                values[j] = si;
+                currentInstr.value = si;
               }
             }
@@ -254,9 +252,9 @@
           case OpCodes.CosineIntegral: {
               double si, ci;
-              var x = values[j - currentInstr.nArguments];
-              if (double.IsNaN(x)) values[j] = double.NaN;
+              var x = code[j - 1].value;
+              if (double.IsNaN(x)) currentInstr.value = double.NaN;
               else {
                 alglib.sinecosineintegrals(x, out si, out ci);
-                values[j] = ci;
+                currentInstr.value = ci;
               }
             }
@@ -264,9 +262,9 @@
           case OpCodes.HyperbolicSineIntegral: {
               double shi, chi;
-              var x = values[j - currentInstr.nArguments];
-              if (double.IsNaN(x)) values[j] = double.NaN;
+              var x = code[j - 1].value;
+              if (double.IsNaN(x)) currentInstr.value = double.NaN;
               else {
                 alglib.hyperbolicsinecosineintegrals(x, out shi, out chi);
-                values[j] = shi;
+                currentInstr.value = shi;
               }
             }
@@ -274,9 +272,9 @@
           case OpCodes.HyperbolicCosineIntegral: {
               double shi, chi;
-              var x = values[j - currentInstr.nArguments];
-              if (double.IsNaN(x)) values[j] = double.NaN;
+              var x = code[j - 1].value;
+              if (double.IsNaN(x)) currentInstr.value = double.NaN;
               else {
                 alglib.hyperbolicsinecosineintegrals(x, out shi, out chi);
-                values[j] = chi;
+                currentInstr.value = chi;
               }
             }
@@ -284,9 +282,9 @@
           case OpCodes.FresnelCosineIntegral: {
               double c = 0, s = 0;
-              var x = values[j - currentInstr.nArguments];
-              if (double.IsNaN(x)) values[j] = double.NaN;
+              var x = code[j - 1].value;
+              if (double.IsNaN(x)) currentInstr.value = double.NaN;
               else {
                 alglib.fresnelintegral(x, ref c, ref s);
-                values[j] = c;
+                currentInstr.value = c;
               }
             }
@@ -294,9 +292,9 @@
           case OpCodes.FresnelSineIntegral: {
               double c = 0, s = 0;
-              var x = values[j - currentInstr.nArguments];
-              if (double.IsNaN(x)) values[j] = double.NaN;
+              var x = code[j - 1].value;
+              if (double.IsNaN(x)) currentInstr.value = double.NaN;
               else {
                 alglib.fresnelintegral(x, ref c, ref s);
-                values[j] = s;
+                currentInstr.value = s;
               }
             }
@@ -304,9 +302,9 @@
           case OpCodes.AiryA: {
               double ai, aip, bi, bip;
-              var x = values[j - currentInstr.nArguments];
-              if (double.IsNaN(x)) values[j] = double.NaN;
+              var x = code[j - 1].value;
+              if (double.IsNaN(x)) currentInstr.value = double.NaN;
               else {
                 alglib.airy(x, out ai, out aip, out bi, out bip);
-                values[j] = ai;
+                currentInstr.value = ai;
               }
             }
@@ -314,63 +312,63 @@
           case OpCodes.AiryB: {
               double ai, aip, bi, bip;
-              var x = values[j - currentInstr.nArguments];
-              if (double.IsNaN(x)) values[j] = double.NaN;
+              var x = code[j - 1].value;
+              if (double.IsNaN(x)) currentInstr.value = double.NaN;
               else {
                 alglib.airy(x, out ai, out aip, out bi, out bip);
-                values[j] = bi;
+                currentInstr.value = bi;
               }
             }
             break;
           case OpCodes.Norm: {
-              var x = values[j - currentInstr.nArguments];
-              values[j] = double.IsNaN(x) ? double.NaN : alglib.normaldistribution(x);
+              var x = code[j - 1].value;
+              currentInstr.value = double.IsNaN(x) ? double.NaN : alglib.normaldistribution(x);
             }
             break;
           case OpCodes.Erf: {
-              var x = values[j - currentInstr.nArguments];
-              values[j] = double.IsNaN(x) ? double.NaN : alglib.errorfunction(x);
+              var x = code[j - 1].value;
+              currentInstr.value = double.IsNaN(x) ? double.NaN : alglib.errorfunction(x);
             }
             break;
           case OpCodes.Bessel: {
-              var x = values[j - currentInstr.nArguments];
-              values[j] = double.IsNaN(x) ? double.NaN : alglib.besseli0(x);
+              var x = code[j - 1].value;
+              currentInstr.value = double.IsNaN(x) ? double.NaN : alglib.besseli0(x);
             }
             break;
           case OpCodes.IfThenElse: {
-              double condition = values[j - currentInstr.nArguments];
-              double result = condition > 0.0 ? values[j - currentInstr.nArguments] : values[j - currentInstr.nArguments + 1];
-              values[j] = result;
+              double condition = code[j - narg].value;
+              double result = condition > 0.0 ? code[j - 2].value : code[j - 1].value;
+              currentInstr.value = result;
             }
             break;
           case OpCodes.AND: {
-              double result = values[j - currentInstr.nArguments];
-              for (int i = j - currentInstr.nArguments + 1; i < j; i++) {
-                if (result > 0.0) result = values[i];
-              }
-              values[j] = result > 0.0 ? 1.0 : -1.0;
+              double result = code[j - narg].value;
+              for (int i = j - narg + 1; i < j; i++) {
+                if (result > 0.0) result = code[i].value;
+              }
+              currentInstr.value = result > 0.0 ? 1.0 : -1.0;
             }
             break;
           case OpCodes.OR: {
-              double result = values[j - currentInstr.nArguments];
-              for (int i = 1; i < currentInstr.nArguments; i++) {
-                if (result <= 0.0) result = values[i]; ;
-              }
-              values[j] = result > 0.0 ? 1.0 : -1.0;
+              double result = code[j - narg].value;
+              for (int i = j - narg + 1; i < j; i++) {
+                if (result <= 0.0) result = code[i].value; ;
+              }
+              currentInstr.value = result > 0.0 ? 1.0 : -1.0;
             }
             break;
           case OpCodes.NOT: {
-              values[j] = values[j - currentInstr.nArguments] > 0.0 ? -1.0 : 1.0;
+              currentInstr.value = code[j - 1].value > 0.0 ? -1.0 : 1.0;
             }
             break;
           case OpCodes.GT: {
-              double x = values[j - currentInstr.nArguments];
-              double y = values[j - currentInstr.nArguments + 1];
-              values[j] = x > y ? 1.0 : -1.0;
+              double x = code[j - 2].value;
+              double y = code[j - 1].value;
+              currentInstr.value = x > y ? 1.0 : -1.0;
             }
             break;
           case OpCodes.LT: {
-              double x = values[j - currentInstr.nArguments];
-              double y = values[j - currentInstr.nArguments + 1];
-              values[j] = x < y ? 1.0 : -1.0;
+              double x = code[j - 2].value;
+              double y = code[j - 1].value;
+              currentInstr.value = x < y ? 1.0 : -1.0;
             }
             break;
@@ -396,8 +394,8 @@
             }
           case OpCodes.Variable: {
-              if (row < 0 || row >= dataset.Rows) values[j] = double.NaN;
+              if (row < 0 || row >= dataset.Rows) currentInstr.value = double.NaN;
               else {
                 var variableTreeNode = (VariableTreeNode)currentInstr.dynamicNode;
-                values[j] = ((IList<double>)currentInstr.iArg0)[row] * variableTreeNode.Weight;
+                currentInstr.value = ((IList<double>)currentInstr.iArg0)[row] * variableTreeNode.Weight;
               }
             }
@@ -406,7 +404,7 @@
               var laggedVariableTreeNode = (LaggedVariableTreeNode)currentInstr.dynamicNode;
               int actualRow = row + laggedVariableTreeNode.Lag;
-              if (actualRow < 0 || actualRow >= dataset.Rows) values[j] = double.NaN;
-              else {
-                values[j] = ((IList<double>)currentInstr.iArg0)[actualRow] * laggedVariableTreeNode.Weight;
+              if (actualRow < 0 || actualRow >= dataset.Rows) currentInstr.value = double.NaN;
+              else {
+                currentInstr.value = ((IList<double>)currentInstr.iArg0)[actualRow] * laggedVariableTreeNode.Weight;
               }
             }
@@ -414,5 +412,5 @@
           case OpCodes.Constant: {
               var constTreeNode = (ConstantTreeNode)currentInstr.dynamicNode;
-              values[j] = constTreeNode.Value;
+              currentInstr.value = constTreeNode.Value;
             }
             break;
@@ -421,5 +419,5 @@
           //to determine the relative amounts of the true and false branch see http://en.wikipedia.org/wiki/Logistic_function
           case OpCodes.VariableCondition: {
-              if (row < 0 || row >= dataset.Rows) values[j] = double.NaN;
+              if (row < 0 || row >= dataset.Rows) currentInstr.value = double.NaN;
               else {
                 var variableConditionTreeNode = (VariableConditionTreeNode)currentInstr.dynamicNode;
@@ -428,8 +426,8 @@
                 double p = 1 / (1 + Math.Exp(-variableConditionTreeNode.Slope * x));
 
-                double trueBranch = values[j - currentInstr.nArguments];
-                double falseBranch = values[j - currentInstr.nArguments + 1];
-
-                values[j] = trueBranch * p + falseBranch * (1 - p);
+                double trueBranch = code[j - narg].value;
+                double falseBranch = code[j - narg + 1].value;
+
+                currentInstr.value = trueBranch * p + falseBranch * (1 - p);
               }
             }
@@ -438,8 +436,4 @@
             throw new NotSupportedException();
         }
-        #endregion
-
-        // book-keeping in order to keep all the values correct
-        int narg = currentInstr.nArguments;
 
         // we count the values before the next function is encountered
@@ -448,5 +442,5 @@
         if (count > narg) {
           for (int i = 1; i <= count - narg; ++i)
-            values[j - i] = values[j - i - narg];
+            code[j - i].value = code[j - i - narg].value;
         }
 
@@ -454,5 +448,5 @@
       }
 
-      return values[values.Length - 1];
+      return code[code.Length - 1].value;
     }
   }
