Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/LinearTimeSeriesPrognosis.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/LinearTimeSeriesPrognosis.cs	(revision 7099)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/LinearTimeSeriesPrognosis.cs	(revision 7100)
@@ -76,59 +76,71 @@
     #region linear regression
     protected override void Run() {
-      double rmsError, cvRmsError;
-      var solution = CreateLinearTimeSeriesPrognosisSolution(Problem.ProblemData, MaximalLag, out rmsError, out cvRmsError);
+      double[] rmsErrors, cvRmsErrors;
+      var solution = CreateLinearTimeSeriesPrognosisSolution(Problem.ProblemData, MaximalLag, out rmsErrors, out cvRmsErrors);
       Results.Add(new Result(LinearTimeSeriesPrognosisModelResultName, "The linear time-series prognosis solution.", solution));
-      Results.Add(new Result("Root mean square error", "The root of the mean of squared errors of the linear time-series prognosis solution on the training set.", new DoubleValue(rmsError)));
-      Results.Add(new Result("Estimated root mean square error (cross-validation)", "The estimated root of the mean of squared errors of the linear time-series prognosis solution via cross validation.", new DoubleValue(cvRmsError)));
+      Results.Add(new Result("Root mean square errors", "The root of the mean of squared errors of the linear time-series prognosis solution on the training set.", new DoubleArray(rmsErrors)));
+      Results.Add(new Result("Estimated root mean square errors (cross-validation)", "The estimated root of the mean of squared errors of the linear time-series prognosis solution via cross validation.", new DoubleArray(cvRmsErrors)));
     }
 
-    public static ISymbolicTimeSeriesPrognosisSolution CreateLinearTimeSeriesPrognosisSolution(ITimeSeriesPrognosisProblemData problemData, int maximalLag, out double rmsError, out double cvRmsError) {
+    public static ISymbolicTimeSeriesPrognosisSolution CreateLinearTimeSeriesPrognosisSolution(ITimeSeriesPrognosisProblemData problemData, int maximalLag, out double[] rmsError, out double[] cvRmsError) {
       Dataset dataset = problemData.Dataset;
-      string targetVariable = problemData.TargetVariable;
-      IEnumerable<string> allowedInputVariables = problemData.AllowedInputVariables;
-      IEnumerable<int> rows = problemData.TrainingIndizes;
-      IEnumerable<int> lags = Enumerable.Range(1, maximalLag);
-      double[,] inputMatrix = AlglibUtil.PrepareInputMatrix(dataset, allowedInputVariables.Concat(new string[] { targetVariable }), rows, lags);
-      if (inputMatrix.Cast<double>().Any(x => double.IsNaN(x) || double.IsInfinity(x)))
-        throw new NotSupportedException("Linear time-series prognosis does not support NaN or infinity values in the input dataset.");
+      string[] targetVariables = problemData.TargetVariables.ToArray();
 
-      alglib.linearmodel lm = new alglib.linearmodel();
-      alglib.lrreport ar = new alglib.lrreport();
-      int nRows = inputMatrix.GetLength(0);
-      int nFeatures = inputMatrix.GetLength(1) - 1;
-      double[] coefficients = new double[nFeatures + 1]; // last coefficient is for the constant
-
-      int retVal = 1;
-      alglib.lrbuild(inputMatrix, nRows, nFeatures, out retVal, out lm, out ar);
-      if (retVal != 1) throw new ArgumentException("Error in calculation of linear time series prognosis solution");
-      rmsError = ar.rmserror;
-      cvRmsError = ar.cvrmserror;
-
-      alglib.lrunpack(lm, out coefficients, out nFeatures);
-
+      // prepare symbolic expression tree to hold the models for each target variable
       ISymbolicExpressionTree tree = new SymbolicExpressionTree(new ProgramRootSymbol().CreateTreeNode());
       ISymbolicExpressionTreeNode startNode = new StartSymbol().CreateTreeNode();
       tree.Root.AddSubtree(startNode);
-      ISymbolicExpressionTreeNode addition = new Addition().CreateTreeNode();
-      startNode.AddSubtree(addition);
+      int i = 0;
+      rmsError = new double[targetVariables.Length];
+      cvRmsError = new double[targetVariables.Length];
+      foreach (var targetVariable in targetVariables) {
+        IEnumerable<string> allowedInputVariables = problemData.AllowedInputVariables;
+        IEnumerable<int> rows = problemData.TrainingIndizes;
+        IEnumerable<int> lags = Enumerable.Range(1, maximalLag);
+        double[,] inputMatrix = AlglibUtil.PrepareInputMatrix(dataset,
+                                                              allowedInputVariables.Concat(new string[] { targetVariable }),
+                                                              rows, lags);
+        if (inputMatrix.Cast<double>().Any(x => double.IsNaN(x) || double.IsInfinity(x)))
+          throw new NotSupportedException(
+            "Linear time-series prognosis does not support NaN or infinity values in the input dataset.");
 
-      int col = 0;
-      foreach (string column in allowedInputVariables) {
-        foreach (int lag in lags) {
-          LaggedVariableTreeNode vNode =
-            (LaggedVariableTreeNode)new HeuristicLab.Problems.DataAnalysis.Symbolic.LaggedVariable().CreateTreeNode();
-          vNode.VariableName = column;
-          vNode.Weight = coefficients[col];
-          vNode.Lag = -lag;
-          addition.AddSubtree(vNode);
-          col++;
+        alglib.linearmodel lm = new alglib.linearmodel();
+        alglib.lrreport ar = new alglib.lrreport();
+        int nRows = inputMatrix.GetLength(0);
+        int nFeatures = inputMatrix.GetLength(1) - 1;
+        double[] coefficients = new double[nFeatures + 1]; // last coefficient is for the constant
+
+        int retVal = 1;
+        alglib.lrbuild(inputMatrix, nRows, nFeatures, out retVal, out lm, out ar);
+        if (retVal != 1) throw new ArgumentException("Error in calculation of linear time series prognosis solution");
+        rmsError[i] = ar.rmserror;
+        cvRmsError[i] = ar.cvrmserror;
+
+        alglib.lrunpack(lm, out coefficients, out nFeatures);
+
+        ISymbolicExpressionTreeNode addition = new Addition().CreateTreeNode();
+
+        int col = 0;
+        foreach (string column in allowedInputVariables) {
+          foreach (int lag in lags) {
+            LaggedVariableTreeNode vNode =
+              (LaggedVariableTreeNode)new HeuristicLab.Problems.DataAnalysis.Symbolic.LaggedVariable().CreateTreeNode();
+            vNode.VariableName = column;
+            vNode.Weight = coefficients[col];
+            vNode.Lag = -lag;
+            addition.AddSubtree(vNode);
+            col++;
+          }
         }
+
+        ConstantTreeNode cNode = (ConstantTreeNode)new Constant().CreateTreeNode();
+        cNode.Value = coefficients[coefficients.Length - 1];
+        addition.AddSubtree(cNode);
+
+        startNode.AddSubtree(addition);
+        i++;
       }
 
-      ConstantTreeNode cNode = (ConstantTreeNode)new Constant().CreateTreeNode();
-      cNode.Value = coefficients[coefficients.Length - 1];
-      addition.AddSubtree(cNode);
-
-      SymbolicTimeSeriesPrognosisSolution solution = new SymbolicTimeSeriesPrognosisSolution(new SymbolicTimeSeriesPrognosisModel(tree, new SymbolicDataAnalysisExpressionTreeInterpreter()), (ITimeSeriesPrognosisProblemData)problemData.Clone());
+      SymbolicTimeSeriesPrognosisSolution solution = new SymbolicTimeSeriesPrognosisSolution(new SymbolicTimeSeriesPrognosisModel(tree, new SymbolicTimeSeriesPrognosisInterpreter(problemData.TargetVariables.ToArray())), (ITimeSeriesPrognosisProblemData)problemData.Clone());
       solution.Model.Name = "Linear Time-Series Prognosis Model";
       return solution;
