Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views-3.4.csproj
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views-3.4.csproj	(revision 7153)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views-3.4.csproj	(revision 7154)
@@ -110,10 +110,4 @@
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView.cs">
-      <SubType>UserControl</SubType>
-    </Compile>
-    <Compile Include="InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView.Designer.cs">
-      <DependentUpon>InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView.cs</DependentUpon>
-    </Compile>
     <Compile Include="Plugin.cs" />
     <Compile Include="SymbolicTimeSeriesPrognosisSolutionView.cs">
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView.cs	(revision 7153)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView.cs	(revision 7154)
@@ -69,5 +69,5 @@
       Dictionary<ISymbolicExpressionTreeNode, double> impactValues =
         new Dictionary<ISymbolicExpressionTreeNode, double>();
-      var originalOutput = interpreter.GetSymbolicExpressionTreeValues(tree, dataset, Content.ProblemData.TargetVariables.ToArray(), rows, 1)
+      var originalOutput = interpreter.GetSymbolicExpressionTreeValues(tree, dataset, Content.ProblemData.TargetVariables.ToArray(), rows)
         .ToArray();
       int i = 0;
@@ -76,5 +76,5 @@
         var targetValues = dataset.GetDoubleValues(targetVariable, rows);
         OnlineCalculatorError errorState;
-        double originalR2 = OnlinePearsonsRSquaredCalculator.Calculate(targetValues, originalOutput.Select(v => v.ElementAt(i).First()), out errorState);
+        double originalR2 = OnlinePearsonsRSquaredCalculator.Calculate(targetValues, originalOutput.Select(v => v.ElementAt(i)), out errorState);
         if (errorState != OnlineCalculatorError.None) originalR2 = 0.0;
 
@@ -85,5 +85,5 @@
           SwitchNode(parent, node, replacementNode);
           var newOutput = interpreter.GetSymbolicExpressionTreeValues(tree, dataset, Content.ProblemData.TargetVariables.ToArray(), rows, 1);
-          double newR2 = OnlinePearsonsRSquaredCalculator.Calculate(targetValues, newOutput.Select(v => v.ElementAt(i).First()), out errorState);
+          double newR2 = OnlinePearsonsRSquaredCalculator.Calculate(targetValues, newOutput.Select(v => v.First().ElementAt(i)), out errorState);
           if (errorState != OnlineCalculatorError.None) newR2 = 0.0;
 
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/SymbolicTimeSeriesPrognosisSolutionView.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/SymbolicTimeSeriesPrognosisSolutionView.cs	(revision 7153)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/SymbolicTimeSeriesPrognosisSolutionView.cs	(revision 7154)
@@ -39,7 +39,7 @@
 
     private void btn_SimplifyModel_Click(object sender, EventArgs e) {
-      InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView view = new InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView();
-      view.Content = (SymbolicTimeSeriesPrognosisSolution)this.Content.Clone();
-      view.Show();
+      //InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView view = new InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView();
+      //view.Content = (SymbolicTimeSeriesPrognosisSolution)this.Content.Clone();
+      //view.Show();
     }
   }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveMeanSquaredErrorEvaluator.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveMeanSquaredErrorEvaluator.cs	(revision 7153)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveMeanSquaredErrorEvaluator.cs	(revision 7154)
@@ -22,4 +22,5 @@
 using System;
 using System.Collections.Generic;
+using System.Drawing.Printing;
 using System.Linq;
 using HeuristicLab.Common;
@@ -65,26 +66,23 @@
       DetermineScalingFactors(solution, problemData, interpreter, rows, out alpha, out beta);
       var scaledSolution = Scale(solution, alpha, beta);
-
+      string[] targetVariables = problemData.TargetVariables.ToArray();
       var meanSquaredErrorCalculators = Enumerable.Range(0, problemData.TargetVariables.Count())
         .Select(i => new OnlineMeanSquaredErrorCalculator()).ToArray();
 
-      var allPredictedContinuations = interpreter.GetSymbolicExpressionTreeValues(scaledSolution, problemData.Dataset,
-                                                                                  problemData.TargetVariables.ToArray(),
-                                                                                  rows, horizon);
-      var allContinuationsEnumerator = allPredictedContinuations.GetEnumerator();
-      var rowsEnumerator = rows.GetEnumerator();
-      while (allContinuationsEnumerator.MoveNext() & rowsEnumerator.MoveNext()) {
-        var componentEnumerator = allContinuationsEnumerator.Current.GetEnumerator();
-        var mseCalculatorsEnumerator = meanSquaredErrorCalculators.AsEnumerable().GetEnumerator();
-        var targetVarEnumerator = problemData.TargetVariables.GetEnumerator();
-        while (componentEnumerator.MoveNext() & mseCalculatorsEnumerator.MoveNext() & targetVarEnumerator.MoveNext()) {
-          var stepEnumerator = componentEnumerator.Current.GetEnumerator();
-          var actualContinuationEnumerator = problemData.Dataset.GetDoubleValues(targetVarEnumerator.Current,
-                                                                       Enumerable.Range(rowsEnumerator.Current, horizon)).GetEnumerator();
-          while (stepEnumerator.MoveNext() & actualContinuationEnumerator.MoveNext()) {
-            double e = Math.Min(upperEstimationLimit, Math.Max(lowerEstimationLimit, stepEnumerator.Current));
-            mseCalculatorsEnumerator.Current.Add(actualContinuationEnumerator.Current, e);
-            if (mseCalculatorsEnumerator.Current.ErrorState == OnlineCalculatorError.InvalidValueAdded)
-              return double.NaN;
+      var allContinuationsEnumerator = interpreter.GetSymbolicExpressionTreeValues(scaledSolution, problemData.Dataset,
+                                                                                  targetVariables,
+                                                                                  rows, horizon).GetEnumerator();
+      allContinuationsEnumerator.MoveNext();
+      // foreach row
+      foreach (var row in rows) {
+        // foreach horizon
+        for (int h = 0; h < horizon; h++) {
+          // foreach component
+          for (int i = 0; i < meanSquaredErrorCalculators.Length; i++) {
+            double e = Math.Min(upperEstimationLimit, Math.Max(lowerEstimationLimit, allContinuationsEnumerator.Current));
+            meanSquaredErrorCalculators[i].Add(problemData.Dataset.GetDoubleValue(targetVariables[i], row + h), e);
+            if (meanSquaredErrorCalculators[i].ErrorState == OnlineCalculatorError.InvalidValueAdded)
+              return double.MaxValue;
+            allContinuationsEnumerator.MoveNext();
           }
         }
@@ -92,5 +90,5 @@
       var meanCalculator = new OnlineMeanAndVarianceCalculator();
       foreach (var calc in meanSquaredErrorCalculators) {
-        if (calc.ErrorState != OnlineCalculatorError.None) return double.NaN;
+        if (calc.ErrorState != OnlineCalculatorError.None) return double.MaxValue;
         meanCalculator.Add(calc.MeanSquaredError);
       }
@@ -109,5 +107,5 @@
       //  }
       //}
-      return meanCalculator.MeanErrorState == OnlineCalculatorError.None ? meanCalculator.Mean : double.NaN;
+      return meanCalculator.MeanErrorState == OnlineCalculatorError.None ? meanCalculator.Mean : double.MaxValue;
     }
 
@@ -153,15 +151,25 @@
       alpha = new double[nComponents];
       beta = new double[nComponents];
-      var oneStepPredictions = interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset,
-                                                                     targetVariables, rows,
-                                                                     1);
+      var oneStepPredictionsEnumerator = interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, targetVariables, rows).GetEnumerator();
+      var scalingParameterCalculators =
+        Enumerable.Repeat(0, nComponents).Select(x => new OnlineLinearScalingParameterCalculator()).ToArray();
+      var targetValues = problemData.Dataset.GetVectorEnumerable(targetVariables, rows);
+      var targetValueEnumerator = targetValues.GetEnumerator();
+
+      var more = oneStepPredictionsEnumerator.MoveNext() & targetValueEnumerator.MoveNext();
+      while (more) {
+        for (int i = 0; i < nComponents; i++) {
+          scalingParameterCalculators[i].Add(oneStepPredictionsEnumerator.Current, targetValueEnumerator.Current);
+          more = oneStepPredictionsEnumerator.MoveNext() & targetValueEnumerator.MoveNext();
+        }
+      }
+
       for (int i = 0; i < nComponents; i++) {
-        var target = problemData.Dataset.GetDoubleValues(targetVariables[i], rows);
-        var prediction = oneStepPredictions.Select(v => v.ElementAt(i).First());
-        OnlineCalculatorError errorState;
-        OnlineLinearScalingParameterCalculator.Calculate(prediction, target, out alpha[i], out beta[i], out errorState);
-        if (errorState != OnlineCalculatorError.None) {
-          alpha[i] = 0;
-          beta[i] = 1;
+        if (scalingParameterCalculators[i].ErrorState == OnlineCalculatorError.None) {
+          alpha[i] = scalingParameterCalculators[i].Alpha;
+          beta[i] = scalingParameterCalculators[i].Beta;
+        } else {
+          alpha[i] = 0.0;
+          beta[i] = 1.0;
         }
       }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveProblem.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveProblem.cs	(revision 7153)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveProblem.cs	(revision 7154)
@@ -57,5 +57,5 @@
       EstimationLimitsParameter.Hidden = true;
 
-      Maximization.Value = true;
+      Maximization.Value = false;
       MaximumSymbolicExpressionTreeDepth.Value = InitialMaximumTreeDepth;
       MaximumSymbolicExpressionTreeLength.Value = InitialMaximumTreeLength;
@@ -106,4 +106,12 @@
           op.EstimationLimitsParameter.ActualName = EstimationLimitsParameter.Name;
         }
+        foreach (var op in operators.OfType<SymbolicTimeSeriesPrognosisSingleObjectiveTrainingBestSolutionAnalyzer>())
+        {
+          op.MaximizationParameter.ActualName = MaximizationParameter.Name;
+          op.ProblemDataParameter.ActualName = ProblemDataParameter.Name;
+          op.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
+          op.SymbolicDataAnalysisTreeInterpreterParameter.ActualName = SymbolicExpressionTreeInterpreterParameter.Name;
+          op.SymbolicExpressionTreeParameter.ActualName = SolutionCreator.SymbolicExpressionTreeParameter.ActualName;
+        }
       }
     }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SymbolicTimeSeriesPrognosisModel.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SymbolicTimeSeriesPrognosisModel.cs	(revision 7153)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SymbolicTimeSeriesPrognosisModel.cs	(revision 7154)
@@ -20,4 +20,5 @@
 #endregion
 
+using System;
 using System.Collections.Generic;
 using System.Drawing;
@@ -69,4 +70,6 @@
       this.symbolicExpressionTree = cloner.Clone(original.symbolicExpressionTree);
       this.interpreter = cloner.Clone(original.interpreter);
+      this.targetVariables = new string[original.targetVariables.Length];
+      Array.Copy(original.targetVariables, this.targetVariables, this.targetVariables.Length);
     }
     public SymbolicTimeSeriesPrognosisModel(ISymbolicExpressionTree tree, ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter interpreter, IEnumerable<string> targetVariables)
@@ -83,5 +86,19 @@
 
     public IEnumerable<IEnumerable<IEnumerable<double>>> GetPrognosedValues(Dataset dataset, IEnumerable<int> rows, int horizon) {
-      return Interpreter.GetSymbolicExpressionTreeValues(SymbolicExpressionTree, dataset, targetVariables, rows, horizon);
+      var enumerator =
+        Interpreter.GetSymbolicExpressionTreeValues(SymbolicExpressionTree, dataset, targetVariables, rows, horizon).
+          GetEnumerator();
+      foreach (var r in rows) {
+        var l = new List<double[]>();
+        for (int h = 0; h < horizon; h++) {
+          double[] components = new double[targetVariables.Length];
+          for (int c = 0; c < components.Length; c++) {
+            enumerator.MoveNext();
+            components[c] = enumerator.Current;
+          }
+          l.Add(components);
+        }
+        yield return l;
+      }
     }
 
@@ -95,19 +112,27 @@
     public static void Scale(SymbolicTimeSeriesPrognosisModel model, ITimeSeriesPrognosisProblemData problemData) {
       var dataset = problemData.Dataset;
-      var targetVariables = problemData.TargetVariables;
+      var targetVariables = problemData.TargetVariables.ToArray();
       var rows = problemData.TrainingIndizes;
-      int i = 0;
-      int horizon = 1;
-      var estimatedValues = model.Interpreter.GetSymbolicExpressionTreeValues(model.SymbolicExpressionTree, dataset, problemData.TargetVariables.ToArray(), rows, horizon)
-        .ToArray();
-      foreach (var targetVariable in targetVariables) {
-        var targetValues = dataset.GetDoubleValues(targetVariable, rows);
-        double alpha;
-        double beta;
-        OnlineCalculatorError errorState;
-        OnlineLinearScalingParameterCalculator.Calculate(estimatedValues.Select(x => x.ElementAt(i).First()), targetValues,
-          out alpha, out beta, out errorState);
-        if (errorState != OnlineCalculatorError.None) continue;
+      var estimatedValuesEnumerator = model.Interpreter.GetSymbolicExpressionTreeValues(model.SymbolicExpressionTree, dataset,
+                                                                              targetVariables,
+                                                                              rows).GetEnumerator();
+      var scalingParameterCalculators =
+        problemData.TargetVariables.Select(v => new OnlineLinearScalingParameterCalculator()).ToArray();
+      var targetValuesEnumerator = problemData.Dataset.GetVectorEnumerable(targetVariables, rows).GetEnumerator();
 
+      var more = targetValuesEnumerator.MoveNext() & estimatedValuesEnumerator.MoveNext();
+      // foreach row
+      while (more) {
+        // foreach component
+        for (int i = 0; i < targetVariables.Length; i++) {
+          scalingParameterCalculators[i].Add(estimatedValuesEnumerator.Current, targetValuesEnumerator.Current);
+          more = estimatedValuesEnumerator.MoveNext() & targetValuesEnumerator.MoveNext();
+        }
+      }
+
+      for (int i = 0; i < targetVariables.Count(); i++) {
+        if (scalingParameterCalculators[i].ErrorState != OnlineCalculatorError.None) continue;
+        double alpha = scalingParameterCalculators[i].Alpha;
+        double beta = scalingParameterCalculators[i].Beta;
         ConstantTreeNode alphaTreeNode = null;
         ConstantTreeNode betaTreeNode = null;
@@ -136,5 +161,4 @@
           startNode.InsertSubtree(i, scaledMainBranch);
         }
-        i++;
       } // foreach
     }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectiveTrainingBestSolutionAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectiveTrainingBestSolutionAnalyzer.cs	(revision 7153)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectiveTrainingBestSolutionAnalyzer.cs	(revision 7154)
@@ -85,6 +85,6 @@
 
       var results = ResultCollection;
-      if (TrainingBestSolutionQuality == null ||
-        IsBetter(bestQuality, TrainingBestSolutionQuality.Value, Maximization.Value)) {
+      if (bestTree != null && (TrainingBestSolutionQuality == null ||
+        IsBetter(bestQuality, TrainingBestSolutionQuality.Value, Maximization.Value))) {
         TrainingBestSolution = CreateSolution(bestTree, bestQuality);
         TrainingBestSolutionQuality = new DoubleValue(bestQuality);
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/ISymbolicTimeSeriesPrognogisExpressionTreeInterpreter.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/ISymbolicTimeSeriesPrognogisExpressionTreeInterpreter.cs	(revision 7153)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/ISymbolicTimeSeriesPrognogisExpressionTreeInterpreter.cs	(revision 7154)
@@ -25,6 +25,8 @@
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
-  public interface ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter : INamedItem  {
-    IEnumerable<IEnumerable<IEnumerable<double>>> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, string[] targetVariables, IEnumerable<int> rows, int horizon);
+  public interface ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter : INamedItem {
+    IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset,
+                                                        string[] targetVariables, IEnumerable<int> rows);
+    IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, string[] targetVariables, IEnumerable<int> rows, int horizon);
   }
 }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeILEmittingInterpreter.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeILEmittingInterpreter.cs	(revision 7153)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeILEmittingInterpreter.cs	(revision 7154)
@@ -46,5 +46,5 @@
     private static MethodInfo round = typeof(Math).GetMethod("Round", new Type[] { typeof(double) });
 
-    internal delegate double CompiledFunction(int sampleIndex, IList<double>[] columns);
+    internal delegate double CompiledFunction(int sampleIndex, IList<double>[] columns, IList<double>[] cachedValues, int cacheStartIndex);
     private const string CheckExpressionsWithIntervalArithmeticParameterName = "CheckExpressionsWithIntervalArithmetic";
     #region private classes
@@ -179,10 +179,11 @@
 
     public IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, IEnumerable<int> rows) {
-      return from prog in GetSymbolicExpressionTreeValues(tree, dataset, new string[] { "#NOTHING#" }, rows, 1)
-             select prog.First().First();
-    }
-
-    // for each row for each target variable one prognosis (=enumerable of future values)
-    public IEnumerable<IEnumerable<IEnumerable<double>>> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, string[] targetVariables, IEnumerable<int> rows, int horizon) {
+      return GetSymbolicExpressionTreeValues(tree, dataset, new string[] { "#NOTHING#" }, rows);
+    }
+    public IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, string[] targetVariables, IEnumerable<int> rows) {
+      return GetSymbolicExpressionTreeValues(tree, dataset, targetVariables, rows, 1);
+    }
+    // for each row for each horizon for each target variable one value
+    public IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, string[] targetVariables, IEnumerable<int> rows, int horizon) {
       if (CheckExpressionsWithIntervalArithmetic.Value)
         throw new NotSupportedException("Interval arithmetic is not yet supported in the symbolic data analysis interpreter.");
@@ -211,5 +212,5 @@
       }
       var state = new InterpreterState(code);
-      Type[] methodArgs = { typeof(int), typeof(IList<double>[]) };
+      Type[] methodArgs = { typeof(int), typeof(IList<double>[]), typeof(IList<double>[]), typeof(int) };
 
       CompiledFunction[] function = new CompiledFunction[targetVariables.Length];
@@ -222,30 +223,22 @@
         function[i] = (CompiledFunction)testFun.CreateDelegate(typeof(CompiledFunction));
       }
-      int nComponents = tree.Root.GetSubtree(0).SubtreeCount;
-      // produce a n-step forecast for each target variable for all rows
       var values = doubleVariableNames.Keys
-        .Select(v => targetVariables.Contains(v) ?
-          (IList<double>)dataset.GetDoubleValues(v).ToList() :
-          dataset.GetReadOnlyDoubleValues(v))
-        .Concat(new List<double>[] { Enumerable.Repeat(0.0, dataset.Rows).ToList() }) // append list for calculated target variable
+        .Select(v => dataset.GetReadOnlyDoubleValues(v))
         .ToArray();
-      doubleVariableNames.Add("#NOTHING#", values.Count() - 1);
-      foreach (var rowEnum in rows) {
-        int row = rowEnum;
-        foreach (var horizonRow in Enumerable.Range(row, horizon)) {
-          for (int i = 0; i < nComponents; i++) {
-            var componentProg = function[i](horizonRow, values);
+      var cachedValues = (from var in doubleVariableNames.Keys
+                          select new double[horizon]).ToArray();
+      foreach (var row in rows) {
+        // init first line of cache 
+        int c = 0;
+        foreach (var var in doubleVariableNames.Keys)
+          cachedValues[c++][0] = dataset.GetDoubleValue(var, row);
+        for (int horizonRow = row; horizonRow < row + horizon; horizonRow++) {
+          for (int i = 0; i < function.Length; i++) {
+            var componentProg = function[i](horizonRow, values, cachedValues, row);
             // set cachedValues for prognosis of future values
-            values[doubleVariableNames[targetVariables[i]]][horizonRow] = componentProg;
-          }
-        }
-
-        yield return from component in Enumerable.Range(0, nComponents)
-                     select from horizonRow in Enumerable.Range(row, horizon)
-                            select values[doubleVariableNames[targetVariables[component]]][horizonRow];
-        // reset start value
-        foreach (var v in targetVariables) {
-          if (v != "#NOTHING#")
-            values[doubleVariableNames[v]][row] = dataset.GetDoubleValue(v, row);
+            if (horizon > 1)
+              cachedValues[doubleVariableNames[targetVariables[i]]][horizonRow - row] = componentProg;
+            yield return componentProg;
+          }
         }
       }
@@ -547,10 +540,10 @@
         case OpCodes.Variable: {
             VariableTreeNode varNode = (VariableTreeNode)currentInstr.dynamicNode;
-            il.Emit(System.Reflection.Emit.OpCodes.Ldarg_1); // load columns array
-            il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, (int)currentInstr.iArg0);
-            // load correct column of the current variable
-            il.Emit(System.Reflection.Emit.OpCodes.Ldelem_Ref);
-            il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); // rowIndex
             if (!state.InLaggedContext) {
+              il.Emit(System.Reflection.Emit.OpCodes.Ldarg_1); // load columns array
+              il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, (int)currentInstr.iArg0);
+              // load correct column of the current variable
+              il.Emit(System.Reflection.Emit.OpCodes.Ldelem_Ref);
+              il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); // rowIndex
               il.Emit(System.Reflection.Emit.OpCodes.Call, listGetValue);
               il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, varNode.Weight); // load weight
@@ -559,4 +552,7 @@
               var nanResult = il.DefineLabel();
               var normalResult = il.DefineLabel();
+              var cachedValue = il.DefineLabel();
+              var multiplyValue = il.DefineLabel();
+              il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); // rowIndex
               il.Emit(System.Reflection.Emit.OpCodes.Dup);
               il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_0);
@@ -565,5 +561,21 @@
               il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, ds.Rows);
               il.Emit(System.Reflection.Emit.OpCodes.Bge, nanResult);
+              il.Emit(System.Reflection.Emit.OpCodes.Ldarg_3);
+              il.Emit(System.Reflection.Emit.OpCodes.Bge, cachedValue);
+              il.Emit(System.Reflection.Emit.OpCodes.Ldarg_1); // load columns array
+              il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, (int)currentInstr.iArg0);
+              il.Emit(System.Reflection.Emit.OpCodes.Ldelem_Ref);
+              il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); // rowIndex
               il.Emit(System.Reflection.Emit.OpCodes.Call, listGetValue);
+              il.Emit(System.Reflection.Emit.OpCodes.Br, multiplyValue);
+              il.MarkLabel(cachedValue);
+              il.Emit(System.Reflection.Emit.OpCodes.Ldarg_2); // load cached values array
+              il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, (int)currentInstr.iArg0);
+              il.Emit(System.Reflection.Emit.OpCodes.Ldelem_Ref);
+              il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); // rowIndex
+              il.Emit(System.Reflection.Emit.OpCodes.Ldarg_3); // startRow
+              il.Emit(System.Reflection.Emit.OpCodes.Sub); // startRow
+              il.Emit(System.Reflection.Emit.OpCodes.Call, listGetValue);
+              il.MarkLabel(multiplyValue);
               il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, varNode.Weight); // load weight
               il.Emit(System.Reflection.Emit.OpCodes.Mul);
@@ -571,5 +583,4 @@
               il.MarkLabel(nanResult);
               il.Emit(System.Reflection.Emit.OpCodes.Pop); // rowIndex
-              il.Emit(System.Reflection.Emit.OpCodes.Pop); // column reference
               il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, double.NaN);
               il.MarkLabel(normalResult);
@@ -580,8 +591,7 @@
             var nanResult = il.DefineLabel();
             var normalResult = il.DefineLabel();
+            var cachedValue = il.DefineLabel();
+            var multiplyValue = il.DefineLabel();
             LaggedVariableTreeNode varNode = (LaggedVariableTreeNode)currentInstr.dynamicNode;
-            il.Emit(System.Reflection.Emit.OpCodes.Ldarg_1); // load columns array
-            il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, (int)currentInstr.iArg0); // load correct column of the current variable
-            il.Emit(System.Reflection.Emit.OpCodes.Ldelem_Ref);
             il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, varNode.Lag); // lag
             il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); // rowIndex
@@ -593,11 +603,33 @@
             il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, ds.Rows);
             il.Emit(System.Reflection.Emit.OpCodes.Bge, nanResult);
+            il.Emit(System.Reflection.Emit.OpCodes.Ldarg_3); // startindex
+            il.Emit(System.Reflection.Emit.OpCodes.Bge, cachedValue);
+            // normal value
+            il.Emit(System.Reflection.Emit.OpCodes.Ldarg_1); // load columns array
+            il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, (int)currentInstr.iArg0); // load correct column of the current variable
+            il.Emit(System.Reflection.Emit.OpCodes.Ldelem_Ref);
+            il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, varNode.Lag); // lag
+            il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); // rowIndex
+            il.Emit(System.Reflection.Emit.OpCodes.Add); // actualRowIndex = rowIndex + sampleOffset
             il.Emit(System.Reflection.Emit.OpCodes.Call, listGetValue);
+            il.Emit(System.Reflection.Emit.OpCodes.Br, multiplyValue);
+            il.MarkLabel(cachedValue);
+            // cached value
+            il.Emit(System.Reflection.Emit.OpCodes.Ldarg_2); // load cached values
+            il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, (int)currentInstr.iArg0); // load correct column of the current variable
+            il.Emit(System.Reflection.Emit.OpCodes.Ldelem_Ref);
+            il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, varNode.Lag); // lag
+            il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); // rowIndex
+            il.Emit(System.Reflection.Emit.OpCodes.Add); // actualRowIndex = rowIndex + sampleOffset
+            il.Emit(System.Reflection.Emit.OpCodes.Ldarg_3); // startRow
+            il.Emit(System.Reflection.Emit.OpCodes.Sub); // startRow            
+            il.Emit(System.Reflection.Emit.OpCodes.Call, listGetValue);
+
+            il.MarkLabel(multiplyValue);
             il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, varNode.Weight); // load weight
             il.Emit(System.Reflection.Emit.OpCodes.Mul);
             il.Emit(System.Reflection.Emit.OpCodes.Br, normalResult);
             il.MarkLabel(nanResult);
-            il.Emit(System.Reflection.Emit.OpCodes.Pop); // sample index
-            il.Emit(System.Reflection.Emit.OpCodes.Pop); // column reference
+            il.Emit(System.Reflection.Emit.OpCodes.Pop); // pop the row index
             il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, double.NaN);
             il.MarkLabel(normalResult);
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeInterpreter.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeInterpreter.cs	(revision 7153)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeInterpreter.cs	(revision 7154)
@@ -201,10 +201,14 @@
 
     public IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, IEnumerable<int> rows) {
-      return from prog in GetSymbolicExpressionTreeValues(tree, dataset, new string[] { "#NOTHING#" }, rows, 1)
-             select prog.First().First();
-    }
-
-    // for each row for each target variable one prognosis (=enumerable of future values)
-    public IEnumerable<IEnumerable<IEnumerable<double>>> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, string[] targetVariables, IEnumerable<int> rows, int horizon) {
+      return GetSymbolicExpressionTreeValues(tree, dataset, new string[] { "#NOTHING#" }, rows);
+    }
+
+    public IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, string[] targetVariables, IEnumerable<int> rows) {
+      return GetSymbolicExpressionTreeValues(tree, dataset, targetVariables, rows, 1);
+    }
+
+
+    // for each row for each horizon for each target variable one value 
+    public IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, string[] targetVariables, IEnumerable<int> rows, int horizon) {
       if (CheckExpressionsWithIntervalArithmetic.Value)
         throw new NotSupportedException("Interval arithmetic is not yet supported in the symbolic data analysis interpreter.");
@@ -238,22 +242,14 @@
       foreach (var rowEnum in rows) {
         int row = rowEnum;
-        List<double[]> vProgs = new List<double[]>();
         foreach (var horizonRow in Enumerable.Range(row, horizon)) {
           int localRow = horizonRow; // create a local variable for the ref parameter
-          var vPrognosis = from i in Enumerable.Range(0, nComponents)
-                           select Evaluate(dataset, ref localRow, row - 1, state, cachedPrognosedValues);
-
-          var vPrognosisArr = vPrognosis.ToArray();
-          vProgs.Add(vPrognosisArr);
-          // set cachedValues for prognosis of future values
-          for (int i = 0; i < vPrognosisArr.Length; i++)
-            cachedPrognosedValues[targetVariables[i]][horizonRow - row] = vPrognosisArr[i];
+          for (int c = 0; c < nComponents; c++) {
+            var prog = Evaluate(dataset, ref localRow, row - 1, state, cachedPrognosedValues);
+            yield return prog;
+            cachedPrognosedValues[targetVariables[c]][horizonRow - row] = prog;
+          }
 
           state.Reset();
         }
-
-        yield return from component in Enumerable.Range(0, nComponents)
-                     select from prognosisStep in Enumerable.Range(0, vProgs.Count)
-                            select vProgs[prognosisStep][component];
       }
     }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionLineChartView.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionLineChartView.cs	(revision 7153)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionLineChartView.cs	(revision 7154)
@@ -91,9 +91,9 @@
           this.chart.Series[PROGNOSEDVALUES_TRAINING_SERIES_NAME].Points
             .DataBindXY(Content.ProblemData.TrainingIndizes.ToArray(),
-                        Content.PrognosedTrainingValues.ElementAt(varIndex).ToArray());
+                        Content.PrognosedTrainingValues.SelectMany(x => x).Skip(varIndex).TakeEvery(Content.ProblemData.TargetVariables.Count()).ToArray());
         } else {
           this.chart.Series[PROGNOSEDVALUES_TRAINING_SERIES_NAME].Points
             .DataBindXY(Content.ProblemData.TrainingIndizes.ToArray(),
-                        Content.GetPrognosedValues(Content.ProblemData.TrainingIndizes, 1).Select(v => v.ElementAt(varIndex).First()).ToArray());
+                        Content.GetPrognosedValues(Content.ProblemData.TrainingIndizes, 1).SelectMany(x => x.Single()).Skip(varIndex).TakeEvery(Content.ProblemData.TargetVariables.Count()).ToArray());
         }
         this.chart.Series[PROGNOSEDVALUES_TRAINING_SERIES_NAME].Tag = Content;
@@ -109,10 +109,9 @@
           this.chart.Series[PROGNOSEDVALUES_TEST_SERIES_NAME].Points
             .DataBindXY(Content.ProblemData.TestIndizes.ToArray(),
-                        Content.PrognosedTestValues.ElementAt(varIndex).ToArray());
+                        Content.PrognosedTestValues.SelectMany(x => x).Skip(varIndex).TakeEvery(Content.ProblemData.TargetVariables.Count()).ToArray());
         } else {
           this.chart.Series[PROGNOSEDVALUES_TEST_SERIES_NAME].Points
             .DataBindXY(Content.ProblemData.TestIndizes.ToArray(),
-                        Content.GetPrognosedValues(Content.ProblemData.TestIndizes, 1).Select(
-                          v => v.ElementAt(varIndex).First()).ToArray());
+                        Content.GetPrognosedValues(Content.ProblemData.TestIndizes, 1).SelectMany(x => x.Single()).Skip(varIndex).TakeEvery(Content.ProblemData.TargetVariables.Count()).ToArray());
         }
         this.chart.Series[PROGNOSEDVALUES_TEST_SERIES_NAME].Tag = Content;
@@ -242,9 +241,12 @@
           case PROGNOSEDVALUES_TRAINING_SERIES_NAME:
             indizes = Content.ProblemData.TrainingIndizes.ToArray();
-            predictedValues = Content.PrognosedTrainingValues.ElementAt(varIndex).ToArray();
+            predictedValues =
+              Content.PrognosedTrainingValues.SelectMany(x => x).Skip(varIndex).TakeEvery(
+                Content.ProblemData.TargetVariables.Count()).ToArray();
             break;
           case PROGNOSEDVALUES_TEST_SERIES_NAME:
             indizes = Content.ProblemData.TestIndizes.ToArray();
-            predictedValues = Content.PrognosedTestValues.ElementAt(varIndex).ToArray();
+            Content.PrognosedTestValues.SelectMany(x => x).Skip(varIndex).TakeEvery(
+              Content.ProblemData.TargetVariables.Count()).ToArray();
             break;
         }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionPrognosedValuesView.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionPrognosedValuesView.cs	(revision 7153)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionPrognosedValuesView.cs	(revision 7154)
@@ -93,13 +93,18 @@
             values[row, 0] = row.ToString();
 
-          var prognosedTraining = Content.PrognosedTrainingValues.ToArray();
-          var prognosedTest = Content.PrognosedTestValues.ToArray();
+          var allPrognosedTraining = Content.PrognosedTrainingValues.SelectMany(x=>x).ToArray();
+          var allPrognosedTest = Content.PrognosedTestValues.SelectMany(x => x).ToArray();
 
           int i = 0;
           int targetVariableIndex = 0;
           foreach (var targetVariable in Content.ProblemData.TargetVariables) {
+            var prognosedTraining =
+              allPrognosedTraining.Skip(targetVariableIndex).TakeEvery(Content.ProblemData.TargetVariables.Count());
+            var prognosedTest =
+              allPrognosedTest.Skip(targetVariableIndex).TakeEvery(Content.ProblemData.TargetVariables.Count());
+
             double[] target = Content.ProblemData.Dataset.GetDoubleValues(targetVariable).ToArray();
 
-            var prognosedTrainingEnumerator = prognosedTraining[targetVariableIndex].GetEnumerator();
+            var prognosedTrainingEnumerator = prognosedTraining.GetEnumerator();
             foreach (var row in Content.ProblemData.TrainingIndizes) {
               prognosedTrainingEnumerator.MoveNext();
@@ -107,5 +112,5 @@
             }
 
-            var prognosedTestEnumerator = prognosedTest[targetVariableIndex].GetEnumerator();
+            var prognosedTestEnumerator = prognosedTest.GetEnumerator();
             foreach (var row in Content.ProblemData.TestIndizes) {
               prognosedTestEnumerator.MoveNext();
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/DatasetExtensions.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/DatasetExtensions.cs	(revision 7154)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/DatasetExtensions.cs	(revision 7154)
@@ -0,0 +1,50 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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 System.Text;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public static class DatasetExtensions {
+    public static IEnumerable<double> GetVectorEnumerable(this Dataset ds, IEnumerable<string> targetVariables, IEnumerable<int> rows) {
+      var vars = targetVariables.ToArray();
+      var values = (from var in vars
+                    select ds.GetReadOnlyDoubleValues(var))
+        .ToArray();
+
+      foreach (var r in rows) {
+        for (int i = 0; i < values.Length; i++)
+          yield return values[i][r];
+      }
+    }
+
+    public static IEnumerable<T> TakeEvery<T>(this IEnumerable<T> xs, int nth) {
+      int i = 0;
+      foreach (var x in xs) {
+        if (i % nth == 0) yield return x;
+        i++;
+      }
+    }
+  }
+}
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj	(revision 7153)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj	(revision 7154)
@@ -108,4 +108,5 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="DatasetExtensions.cs" />
     <Compile Include="DoubleLimit.cs" />
     <Compile Include="Implementation\Classification\ClassificationEnsembleModel.cs">
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionBase.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionBase.cs	(revision 7153)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionBase.cs	(revision 7154)
@@ -161,4 +161,5 @@
     protected void CalculateResults() {
       OnlineCalculatorError errorState;
+      string[] targetVariables = ProblemData.TargetVariables.ToArray();
       /*
       double[] estimatedTrainingValues = PrognosedTrainingValues.ToArray(); // cache values
@@ -193,67 +194,60 @@
               */
 
-      double[] trainingDs = new double[ProblemData.TargetVariables.Count()];
-      double[] testDs = new double[ProblemData.TargetVariables.Count()];
-
-      double[] trainingWds = new double[ProblemData.TargetVariables.Count()];
-      double[] testWds = new double[ProblemData.TargetVariables.Count()];
-
-      double[] trainingTheilsU = new double[ProblemData.TargetVariables.Count()];
-      double[] testTheilsU = new double[ProblemData.TargetVariables.Count()];
-      int i = 0;
-      var predictedContinuationTraining = PrognosedTrainingValues.ToArray();
-      var predictedContinuationTest = PrognosedTestValues.ToArray();
-
-      foreach (var targetVariable in ProblemData.TargetVariables) {
-        var actualTrainingValues = ProblemData.Dataset.GetDoubleValues(targetVariable, ProblemData.TrainingIndizes).ToArray();
-        var startTrainingValues = actualTrainingValues.Take(1);
-        // only one continuation (but the full training set)
-        var actualContinuationTraining = actualTrainingValues.Skip(1);
-
-        var actualTestValues = ProblemData.Dataset.GetDoubleValues(targetVariable, ProblemData.TestIndizes).ToArray();
-        var startTestValues = actualTestValues.Take(1);
-        // only one continuation (but the full training set)
-        var actualContinuationTest = actualTestValues.Skip(1);
-
-
-        trainingDs[i] = OnlineDirectionalSymmetryCalculator.Calculate(startTrainingValues,
-          Enumerable.Repeat(actualContinuationTraining, 1),
-          Enumerable.Repeat(predictedContinuationTraining[i], 1), out errorState);
-        if (errorState != OnlineCalculatorError.None) trainingDs[i] = double.NaN;
-
-        testDs[i] = OnlineDirectionalSymmetryCalculator.Calculate(startTestValues,
-          Enumerable.Repeat(actualContinuationTest, 1),
-          Enumerable.Repeat(predictedContinuationTest[i], 1), out errorState);
-        if (errorState != OnlineCalculatorError.None) testDs[i] = double.NaN;
-
-        trainingWds[i] =
-          OnlineWeightedDirectionalSymmetryCalculator.Calculate(startTrainingValues,
-          Enumerable.Repeat(actualContinuationTraining, 1),
-          Enumerable.Repeat(predictedContinuationTraining[i], 1), out errorState);
-        if (errorState != OnlineCalculatorError.None) trainingWds[i] = double.NaN;
-
-        testWds[i] = OnlineWeightedDirectionalSymmetryCalculator.Calculate(startTestValues,
-          Enumerable.Repeat(actualContinuationTest, 1),
-          Enumerable.Repeat(predictedContinuationTest[i], 1), out errorState);
-        if (errorState != OnlineCalculatorError.None) testWds[i] = double.NaN;
-
-        trainingTheilsU[i] = OnlineTheilsUStatisticCalculator.Calculate(startTrainingValues,
-          Enumerable.Repeat(actualContinuationTraining, 1),
-          Enumerable.Repeat(predictedContinuationTraining[i], 1), out errorState);
-        if (errorState != OnlineCalculatorError.None) trainingTheilsU[i] = double.NaN;
-
-        testTheilsU[i] = OnlineTheilsUStatisticCalculator.Calculate(startTestValues,
-          Enumerable.Repeat(actualContinuationTest, 1),
-          Enumerable.Repeat(predictedContinuationTest[i], 1), out errorState);
-        if (errorState != OnlineCalculatorError.None) testTheilsU[i] = double.NaN;
-        i++;
+      //double[] trainingDs = new double[targetVariables.Length];
+      //double[] testDs = new double[targetVariables.Length];
+
+      //double[] trainingWds = new double[targetVariables.Length];
+      //double[] testWds = new double[targetVariables.Length];
+
+      //double[] trainingTheilsU = new double[targetVariables.Length];
+      //double[] testTheilsU = new double[targetVariables.Length];
+
+      var trainingDsCalculators = new OnlineDirectionalSymmetryCalculator[targetVariables.Length];
+      var testDsCalculators = new OnlineDirectionalSymmetryCalculator[targetVariables.Length];
+      var trainingWdsCalculators = new OnlineWeightedDirectionalSymmetryCalculator[targetVariables.Length];
+      var testWdsCalculators = new OnlineWeightedDirectionalSymmetryCalculator[targetVariables.Length];
+      var trainingTheilsUCalculators = new OnlineTheilsUStatisticCalculator[targetVariables.Length];
+      var testTheilsUCalculators = new OnlineTheilsUStatisticCalculator[targetVariables.Length];
+      for (int i = 0; i < targetVariables.Length; i++) {
+        trainingDsCalculators[i] = new OnlineDirectionalSymmetryCalculator();
+        testDsCalculators[i] = new OnlineDirectionalSymmetryCalculator();
+        trainingWdsCalculators[i] = new OnlineWeightedDirectionalSymmetryCalculator();
+        testWdsCalculators[i] = new OnlineWeightedDirectionalSymmetryCalculator();
+        trainingTheilsUCalculators[i] = new OnlineTheilsUStatisticCalculator();
+        testTheilsUCalculators[i] = new OnlineTheilsUStatisticCalculator();
       }
 
-      TrainingDirectionalSymmetry = trainingDs;
-      TestDirectionalSymmetry = testDs;
-      TrainingWeightedDirectionalSymmetry = trainingWds;
-      TestWeightedDirectionalSymmetry = testWds;
-      TrainingTheilsUStatistic = trainingTheilsU;
-      TestTheilsUStatistic = testTheilsU;
+      var allPrognosedTrainingValues = PrognosedTrainingValues.SelectMany(x => x).ToArray();
+      var allPrognosedTestValues = PrognosedTestValues.SelectMany(x => x).ToArray();
+      for (int t = 0; t < targetVariables.Length; t++) {
+        var actualTrainingValues = ProblemData.Dataset.GetDoubleValues(targetVariables[t], ProblemData.TrainingIndizes);
+        double startTrainingValue = ProblemData.Dataset.GetDoubleValue(targetVariables[t], ProblemData.TrainingIndizes.First() - 1);
+        var prognosedTrainingValues = allPrognosedTrainingValues.Skip(t).TakeEvery(targetVariables.Length);
+        trainingDsCalculators[t].Add(startTrainingValue, actualTrainingValues, prognosedTrainingValues);
+        trainingWdsCalculators[t].Add(startTrainingValue, actualTrainingValues, prognosedTrainingValues);
+        trainingTheilsUCalculators[t].Add(startTrainingValue, actualTrainingValues, prognosedTrainingValues);
+
+        var actualTestValues = ProblemData.Dataset.GetDoubleValues(targetVariables[t], ProblemData.TestIndizes);
+        double startTestValue = ProblemData.Dataset.GetDoubleValue(targetVariables[t], ProblemData.TestIndizes.First() - 1);
+        var prognosedTestValues = allPrognosedTestValues.Skip(t).TakeEvery(targetVariables.Length);
+        testDsCalculators[t].Add(startTestValue, actualTestValues, prognosedTestValues);
+        testWdsCalculators[t].Add(startTestValue, actualTestValues, prognosedTestValues);
+        testTheilsUCalculators[t].Add(startTestValue, actualTestValues, prognosedTestValues);
+      }
+
+      TrainingDirectionalSymmetry = trainingDsCalculators.Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : 0.0)
+        .ToArray();
+      TestDirectionalSymmetry = testDsCalculators.Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : 0.0)
+        .ToArray();
+      TrainingWeightedDirectionalSymmetry = trainingWdsCalculators.Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : double.PositiveInfinity)
+        .ToArray();
+      TestWeightedDirectionalSymmetry = testWdsCalculators.Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : double.PositiveInfinity)
+        .ToArray();
+      TrainingTheilsUStatistic = trainingDsCalculators
+        .Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : double.PositiveInfinity)
+        .ToArray();
+      TestTheilsUStatistic = testTheilsUCalculators
+        .Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : double.PositiveInfinity)
+        .ToArray();
     }
   }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Tests/HeuristicLab-3.3/SamplesTest.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Tests/HeuristicLab-3.3/SamplesTest.cs	(revision 7153)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Tests/HeuristicLab-3.3/SamplesTest.cs	(revision 7154)
@@ -44,4 +44,5 @@
 using HeuristicLab.Problems.DataAnalysis.Symbolic.Classification;
 using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
+using HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis;
 using HeuristicLab.Problems.Knapsack;
 using HeuristicLab.Problems.TestFunctions;
@@ -434,4 +435,55 @@
     }
     #endregion
+    #region Symbolic Time-Series Prognosis
+    [TestMethod]
+    public void CreateGpSymbolicTimeSeriesPrognosisSampleTest() {
+      var ga = CreateGpSymbolicTimeSeriesPrognosisSample();
+      XmlGenerator.Serialize(ga, "../../SGP_SymbTimeSeries.hl");
+    }
+
+    [TestMethod]
+    public void RunGpSymbolicTimeSeriesPrognosisSample() {
+      var ga = CreateGpSymbolicTimeSeriesPrognosisSample();
+      ga.SetSeedRandomly.Value = false;
+      RunAlgorithm(ga);
+      Assert.Inconclusive("Asserts not implemented!");
+    }
+
+    private GeneticAlgorithm CreateGpSymbolicTimeSeriesPrognosisSample() {
+      GeneticAlgorithm ga = new GeneticAlgorithm();
+      #region Problem Configuration
+      SymbolicTimeSeriesPrognosisSingleObjectiveProblem symbTimeProblem = new SymbolicTimeSeriesPrognosisSingleObjectiveProblem();
+      symbTimeProblem.ProblemData.TrainingPartition.Start = 20;
+
+
+      // configure remaining problem parameters
+      symbTimeProblem.RelativeNumberOfEvaluatedSamples.Value = 1;
+      symbTimeProblem.MaximumSymbolicExpressionTreeLength.Value = 100;
+      symbTimeProblem.MaximumSymbolicExpressionTreeDepth.Value = 10;
+      symbTimeProblem.MaximumFunctionDefinitions.Value = 0;
+      symbTimeProblem.MaximumFunctionArguments.Value = 0;
+      symbTimeProblem.SymbolicExpressionTreeInterpreter = new SymbolicDataAnalysisExpressionTreeILEmittingInterpreter();
+      
+      #endregion
+      #region Algorithm Configuration
+      ga.Problem = symbTimeProblem;
+      ga.Name = "Genetic Programming - Symbolic Time-Series Prognosis";
+      ga.Description = "A standard genetic programming algorithm to solve a time-series prognosis problem (Mackey-Glass 17)";
+      ConfigureGeneticAlgorithmParameters<TournamentSelector, SubtreeCrossover, MultiSymbolicExpressionTreeManipulator>(
+        ga, 1000, 1, 100, 0.15, 5
+        );
+
+      var mutator = (MultiSymbolicExpressionTreeManipulator)ga.Mutator;
+      mutator.Operators.OfType<FullTreeShaker>().Single().ShakingFactor = 0.1;
+      mutator.Operators.OfType<OnePointShaker>().Single().ShakingFactor = 1.0;
+
+      ga.Analyzer.Operators.SetItemCheckedState(
+        ga.Analyzer.Operators
+        .OfType<SymbolicDataAnalysisAlleleFrequencyAnalyzer>()
+        .First(), false);
+      #endregion
+      return ga;
+    }
+    #endregion
     #endregion
 
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/SymbolicDataAnalysisExpressionTreeInterpreterTest.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/SymbolicDataAnalysisExpressionTreeInterpreterTest.cs	(revision 7153)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/SymbolicDataAnalysisExpressionTreeInterpreterTest.cs	(revision 7154)
@@ -315,9 +315,9 @@
       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) ", 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 -1.0 (lagVariable 1.0 a -1)) ", 3, 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));
@@ -336,7 +336,7 @@
 
       // 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 -1.0 (lagVariable 1.0 a -2)) ", 5, ds.GetDoubleValue("A", 2));
+      Evaluate(interpreter, ds, "(lag -2.0 (lagVariable 1.0 a -2)) ", 5, ds.GetDoubleValue("A", 1));
+      Evaluate(interpreter, ds, "(lag -1.0 (* (lagVariable 1.0 a -1) (lagVariable 1.0 b -2)))", 3, ds.GetDoubleValue("A", 1) * ds.GetDoubleValue("B", 0));
       Evaluate(interpreter, ds, "(lag -2.0 3.0)", 1, 3.0);
 
@@ -349,6 +349,10 @@
       Evaluate(interpreter, ds, @"(PROG 
                                     (MAIN (lagVariable 1.0 a -1) (lagVariable 1.0 b -1)))", new string[] { "A", "B" }, Enumerable.Range(1, 2), 3,
-      new[] { new[] { 1.0, 1.0, 1.0 }, new[] { 1.0, 1.0, 1.0 } },
-      new[] { new[] { 2.0, 2.0, 2.0 }, new[] { 2.0, 2.0, 2.0 } }
+      new[] { new[] { 1.0, 1.0},
+              new[] { 1.0, 1.0},
+              new[] { 1.0, 1.0}},
+      new[] { new[] { 2.0, 2.0},
+              new[] { 2.0, 2.0},
+              new[] { 2.0, 2.0} }
         );
 
@@ -364,7 +368,16 @@
       Evaluate(interpreter, ds, @"(PROG 
                                      (MAIN (lagVariable 2.0 a -2) (lagVariable 1.0 a -1)))", new string[] { "A", "B" }, Enumerable.Range(2, 3), 4,
-      new[] { new[] { 2.0, 4.0, 4.0, 8.0 }, new[] { 2.0, 2.0, 4.0, 4.0 } },
-      new[] { new[] { 4.0, 2.0, 8.0, 4.0 }, new[] { 1.0, 4.0, 2.0, 8.0 } },
-      new[] { new[] { 2.0, 2.0, 4.0, 4.0 }, new[] { 1.0, 2.0, 2.0, 4.0 } }
+      new[] { new[] { 2.0, 2.0},
+              new[] { 4.0, 2.0},
+              new[] { 4.0, 4.0},
+              new[] { 8.0, 4.0}},
+      new[] { new[] { 4.0, 1.0},
+              new[] { 2.0, 4.0},
+              new[] { 8.0, 2.0},
+              new[] { 4.0, 8.0}},
+      new[] { new[] { 2.0, 1.0},
+              new[] { 2.0, 2.0},
+              new[] { 4.0, 2.0},
+              new[] { 4.0, 4.0}}
         );
     }
@@ -384,16 +397,15 @@
       ISymbolicExpressionTree tree = importer.Import(expr);
 
-      var allPrognosis = interpreter.GetSymbolicExpressionTreeValues(tree, ds, targetVariables, rows, horizon);
+      var allPrognosis = interpreter.GetSymbolicExpressionTreeValues(tree, ds, targetVariables, rows, horizon).GetEnumerator();
       int i = 0;
-      foreach (var actual in allPrognosis) {
-        var actualEnumerator = actual.GetEnumerator();
-        var expectedEnumerator = expected[i].GetEnumerator();
-        while (actualEnumerator.MoveNext() & expectedEnumerator.MoveNext()) {
-          var aEnumerator = actualEnumerator.Current.GetEnumerator();
+      var expectedEnumerator = expected[i].GetEnumerator();
+      while (allPrognosis.MoveNext()) {
+        while (expectedEnumerator.MoveNext()) {
           var eEnumerator = expectedEnumerator.Current.GetEnumerator();
-          while (aEnumerator.MoveNext() & eEnumerator.MoveNext()) {
-            Assert.IsFalse(double.IsNaN(aEnumerator.Current) && !double.IsNaN(eEnumerator.Current));
-            Assert.IsFalse(!double.IsNaN(aEnumerator.Current) && double.IsNaN(eEnumerator.Current));
-            Assert.AreEqual(eEnumerator.Current, aEnumerator.Current, 1.0E-12, expr);
+          while (eEnumerator.MoveNext()) {
+            Assert.IsFalse(double.IsNaN(allPrognosis.Current) && !double.IsNaN(eEnumerator.Current));
+            Assert.IsFalse(!double.IsNaN(allPrognosis.Current) && double.IsNaN(eEnumerator.Current));
+            Assert.AreEqual(eEnumerator.Current, allPrognosis.Current, 1.0E-12, expr);
+            allPrognosis.MoveNext();
           }
         }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Tests/HeuristicLab.Tests.csproj
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Tests/HeuristicLab.Tests.csproj	(revision 7153)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Tests/HeuristicLab.Tests.csproj	(revision 7154)
@@ -830,4 +830,8 @@
       <Name>HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4</Name>
     </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis\3.4\HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis-3.4.csproj">
+      <Project>{07486E68-1517-4B9D-A58D-A38E99AE71AB}</Project>
+      <Name>HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis-3.4</Name>
+    </ProjectReference>
     <ProjectReference Include="..\HeuristicLab.Problems.DataAnalysis.Symbolic.Views\3.4\HeuristicLab.Problems.DataAnalysis.Symbolic.Views-3.4.csproj">
       <Project>{7A2531CE-3F7C-4F13-BCCA-ED6DC27A7086}</Project>
