Index: /trunk/sources/HeuristicLab 3.3.sln
===================================================================
--- /trunk/sources/HeuristicLab 3.3.sln	(revision 8797)
+++ /trunk/sources/HeuristicLab 3.3.sln	(revision 8798)
@@ -363,4 +363,8 @@
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Problems.Scheduling.Views-3.3", "HeuristicLab.Problems.Scheduling.Views\3.3\HeuristicLab.Problems.Scheduling.Views-3.3.csproj", "{78763A4E-E163-48C2-98EB-709760D06F25}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis-3.4", "HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis\3.4\HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis-3.4.csproj", "{07486E68-1517-4B9D-A58D-A38E99AE71AB}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views-3.4", "HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views\3.4\HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views-3.4.csproj", "{E6CB1FC5-78EC-4EB8-BF12-35303C36F962}"
 EndProject
 Global
@@ -1778,4 +1782,28 @@
 		{78763A4E-E163-48C2-98EB-709760D06F25}.Release|x86.ActiveCfg = Release|x86
 		{78763A4E-E163-48C2-98EB-709760D06F25}.Release|x86.Build.0 = Release|x86
+		{07486E68-1517-4B9D-A58D-A38E99AE71AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{07486E68-1517-4B9D-A58D-A38E99AE71AB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{07486E68-1517-4B9D-A58D-A38E99AE71AB}.Debug|x64.ActiveCfg = Debug|x64
+		{07486E68-1517-4B9D-A58D-A38E99AE71AB}.Debug|x64.Build.0 = Debug|x64
+		{07486E68-1517-4B9D-A58D-A38E99AE71AB}.Debug|x86.ActiveCfg = Debug|x86
+		{07486E68-1517-4B9D-A58D-A38E99AE71AB}.Debug|x86.Build.0 = Debug|x86
+		{07486E68-1517-4B9D-A58D-A38E99AE71AB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{07486E68-1517-4B9D-A58D-A38E99AE71AB}.Release|Any CPU.Build.0 = Release|Any CPU
+		{07486E68-1517-4B9D-A58D-A38E99AE71AB}.Release|x64.ActiveCfg = Release|x64
+		{07486E68-1517-4B9D-A58D-A38E99AE71AB}.Release|x64.Build.0 = Release|x64
+		{07486E68-1517-4B9D-A58D-A38E99AE71AB}.Release|x86.ActiveCfg = Release|x86
+		{07486E68-1517-4B9D-A58D-A38E99AE71AB}.Release|x86.Build.0 = Release|x86
+		{E6CB1FC5-78EC-4EB8-BF12-35303C36F962}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{E6CB1FC5-78EC-4EB8-BF12-35303C36F962}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{E6CB1FC5-78EC-4EB8-BF12-35303C36F962}.Debug|x64.ActiveCfg = Debug|x64
+		{E6CB1FC5-78EC-4EB8-BF12-35303C36F962}.Debug|x64.Build.0 = Debug|x64
+		{E6CB1FC5-78EC-4EB8-BF12-35303C36F962}.Debug|x86.ActiveCfg = Debug|x86
+		{E6CB1FC5-78EC-4EB8-BF12-35303C36F962}.Debug|x86.Build.0 = Debug|x86
+		{E6CB1FC5-78EC-4EB8-BF12-35303C36F962}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{E6CB1FC5-78EC-4EB8-BF12-35303C36F962}.Release|Any CPU.Build.0 = Release|Any CPU
+		{E6CB1FC5-78EC-4EB8-BF12-35303C36F962}.Release|x64.ActiveCfg = Release|x64
+		{E6CB1FC5-78EC-4EB8-BF12-35303C36F962}.Release|x64.Build.0 = Release|x64
+		{E6CB1FC5-78EC-4EB8-BF12-35303C36F962}.Release|x86.ActiveCfg = Release|x86
+		{E6CB1FC5-78EC-4EB8-BF12-35303C36F962}.Release|x86.Build.0 = Release|x86
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/HeuristicLab.Algorithms.DataAnalysis-3.4.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/HeuristicLab.Algorithms.DataAnalysis-3.4.csproj	(revision 8797)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/HeuristicLab.Algorithms.DataAnalysis-3.4.csproj	(revision 8798)
@@ -231,4 +231,5 @@
       <SubType>Code</SubType>
     </Compile>
+    <Compile Include="TimeSeries\AutoregressiveModeling.cs" />
   </ItemGroup>
   <ItemGroup>
@@ -312,4 +313,8 @@
       <Name>HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4</Name>
       <Private>False</Private>
+    </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\3.4\HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj">
Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/Plugin.cs.frame
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/Plugin.cs.frame	(revision 8797)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/Plugin.cs.frame	(revision 8798)
@@ -46,4 +46,5 @@
   [PluginDependency("HeuristicLab.Problems.DataAnalysis.Symbolic.Classification", "3.4")]
   [PluginDependency("HeuristicLab.Problems.DataAnalysis.Symbolic.Regression", "3.4")]
+  [PluginDependency("HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis", "3.4")]
   [PluginDependency("HeuristicLab.LibSVM", "3.12")]
   [PluginDependency("HeuristicLab.Random", "3.3")]
Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/TimeSeries/AutoregressiveModeling.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/TimeSeries/AutoregressiveModeling.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/TimeSeries/AutoregressiveModeling.cs	(revision 8798)
@@ -0,0 +1,141 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+using HeuristicLab.Problems.DataAnalysis.Symbolic;
+using HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis;
+
+namespace HeuristicLab.Algorithms.DataAnalysis.TimeSeries {
+  [Item("Autoregressive Modeling", "Timeseries modeling algorithm that creates AR-N models.")]
+  [Creatable("Data Analysis")]
+  [StorableClass]
+  public class AutoregressiveModeling : FixedDataAnalysisAlgorithm<ITimeSeriesPrognosisProblem> {
+    private const string TimeOffesetParameterName = "Maximum Time Offset";
+
+    public IFixedValueParameter<IntValue> TimeOffsetParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[TimeOffesetParameterName]; }
+    }
+
+
+    public int TimeOffset {
+      get { return TimeOffsetParameter.Value.Value; }
+      set { TimeOffsetParameter.Value.Value = value; }
+    }
+
+    [StorableConstructor]
+    protected AutoregressiveModeling(bool deserializing) : base(deserializing) { }
+    protected AutoregressiveModeling(AutoregressiveModeling original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new AutoregressiveModeling(this, cloner);
+    }
+
+    public AutoregressiveModeling()
+      : base() {
+      Parameters.Add(new FixedValueParameter<IntValue>(TimeOffesetParameterName, "The maximum time offset for the model ranging from 1 to infinity.", new IntValue(1)));
+      Problem = new TimeSeriesPrognosisProblem();
+    }
+
+    protected override void Run() {
+      double rmsError, cvRmsError;
+      var solution = CreateAutoRegressiveSolution(Problem.ProblemData, TimeOffset, out rmsError, out cvRmsError);
+      Results.Add(new Result("Autoregressive solution", "The autoregressive time series prognosis solution.", solution));
+      Results.Add(new Result("Root mean square error", "The root of the mean of squared errors of the autoregressive 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 autoregressive time series prognosis solution via cross validation.", new DoubleValue(cvRmsError)));
+    }
+
+    /// <summary>
+    /// Calculates an AR(p) model. For further information see http://en.wikipedia.org/wiki/Autoregressive_model
+    /// </summary>
+    /// <param name="problemData">The problem data which should be used for training</param>
+    /// <param name="timeOffset">The parameter p of the AR(p) specifying the maximum time offset [1,infinity] </param>
+    /// <returns>The times series autoregressive solution </returns>
+    public static ITimeSeriesPrognosisSolution CreateAutoRegressiveSolution(ITimeSeriesPrognosisProblemData problemData, int timeOffset) {
+      double rmsError, cvRmsError;
+      return CreateAutoRegressiveSolution(problemData, timeOffset, out rmsError, out cvRmsError);
+    }
+
+    private static ITimeSeriesPrognosisSolution CreateAutoRegressiveSolution(ITimeSeriesPrognosisProblemData problemData, int timeOffset, out double rmsError, out double cvRmsError) {
+      string targetVariable = problemData.TargetVariable;
+
+      double[,] inputMatrix = new double[problemData.TrainingPartition.Size, timeOffset + 1];
+      var targetValues = problemData.Dataset.GetDoubleValues(targetVariable).ToList();
+      for (int i = 0, row = problemData.TrainingPartition.Start; i < problemData.TrainingPartition.Size; i++, row++) {
+        for (int col = 0; col < timeOffset; col++) {
+          inputMatrix[i, col] = targetValues[row - col - 1];
+        }
+      }
+      // set target values in last column
+      for (int i = 0; i < inputMatrix.GetLength(0); i++)
+        inputMatrix[i, timeOffset] = targetValues[i + problemData.TrainingPartition.Start];
+
+      if (inputMatrix.Cast<double>().Any(x => double.IsNaN(x) || double.IsInfinity(x)))
+        throw new NotSupportedException("Linear regression does not support NaN or infinity values in the input dataset.");
+
+
+      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 regression solution");
+      rmsError = ar.rmserror;
+      cvRmsError = ar.cvrmserror;
+
+      alglib.lrunpack(lm, out coefficients, out nFeatures);
+
+
+      ISymbolicExpressionTree tree = new SymbolicExpressionTree(new ProgramRootSymbol().CreateTreeNode());
+      ISymbolicExpressionTreeNode startNode = new StartSymbol().CreateTreeNode();
+      tree.Root.AddSubtree(startNode);
+      ISymbolicExpressionTreeNode addition = new Addition().CreateTreeNode();
+      startNode.AddSubtree(addition);
+
+      for (int i = 0; i < timeOffset; i++) {
+        LaggedVariableTreeNode node = (LaggedVariableTreeNode)new LaggedVariable().CreateTreeNode();
+        node.VariableName = targetVariable;
+        node.Weight = coefficients[i];
+        node.Lag = (i + 1) * -1;
+        addition.AddSubtree(node);
+      }
+
+      ConstantTreeNode cNode = (ConstantTreeNode)new Constant().CreateTreeNode();
+      cNode.Value = coefficients[coefficients.Length - 1];
+      addition.AddSubtree(cNode);
+
+      var interpreter = new SymbolicTimeSeriesPrognosisExpressionTreeInterpreter(problemData.TargetVariable);
+      var model = new SymbolicTimeSeriesPrognosisModel(tree, interpreter);
+      var solution = model.CreateTimeSeriesPrognosisSolution((ITimeSeriesPrognosisProblemData)problemData.Clone());
+      return solution;
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Compiler/SymbolicExpressionTreeCompiler.cs
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Compiler/SymbolicExpressionTreeCompiler.cs	(revision 8797)
+++ /trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Compiler/SymbolicExpressionTreeCompiler.cs	(revision 8798)
@@ -25,14 +25,15 @@
 
 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
-  public class SymbolicExpressionTreeCompiler {
-    private Dictionary<string, ushort> entryPoint = new Dictionary<string, ushort>();
-    private List<Func<Instruction, Instruction>> postInstructionCompiledHooks = new List<Func<Instruction, Instruction>>();
+  public static class SymbolicExpressionTreeCompiler {
 
-    public Instruction[] Compile(ISymbolicExpressionTree tree, Func<ISymbolicExpressionTreeNode, byte> opCodeMapper) {
+    public static Instruction[] Compile(ISymbolicExpressionTree tree, Func<ISymbolicExpressionTreeNode, byte> opCodeMapper) {
+      return Compile(tree, opCodeMapper, Enumerable.Empty<Func<Instruction, Instruction>>());
+    }
+    public static Instruction[] Compile(ISymbolicExpressionTree tree, Func<ISymbolicExpressionTreeNode, byte> opCodeMapper, IEnumerable<Func<Instruction, Instruction>> postInstructionCompiledHooks) {
+      Dictionary<string, ushort> entryPoint = new Dictionary<string, ushort>();
       List<Instruction> code = new List<Instruction>();
-      entryPoint.Clear();
       // compile main body branches
       foreach (var branch in tree.Root.GetSubtree(0).Subtrees) {
-        code.AddRange(Compile(branch, opCodeMapper));
+        code.AddRange(Compile(branch, opCodeMapper, postInstructionCompiledHooks));
       }
       // compile function branches
@@ -43,5 +44,5 @@
         if (code.Count > ushort.MaxValue) throw new ArgumentException("Code for the tree is too long (> ushort.MaxValue).");
         entryPoint[branch.FunctionName] = (ushort)code.Count;
-        code.AddRange(Compile(branch.GetSubtree(0), opCodeMapper));
+        code.AddRange(Compile(branch.GetSubtree(0), opCodeMapper, postInstructionCompiledHooks));
       }
       // address of all functions is fixed now
@@ -52,5 +53,4 @@
           var invokeNode = (InvokeFunctionTreeNode)instr.dynamicNode;
           instr.iArg0 = entryPoint[invokeNode.Symbol.FunctionName];
-          code[i] = instr;
         }
       }
@@ -59,5 +59,5 @@
     }
 
-    private IEnumerable<Instruction> Compile(ISymbolicExpressionTreeNode branch, Func<ISymbolicExpressionTreeNode, byte> opCodeMapper) {
+    private static IEnumerable<Instruction> Compile(ISymbolicExpressionTreeNode branch, Func<ISymbolicExpressionTreeNode, byte> opCodeMapper, IEnumerable<Func<Instruction, Instruction>> postInstructionCompiledHooks) {
       foreach (var node in branch.IterateNodesPrefix()) {
         Instruction instr = new Instruction();
@@ -77,13 +77,4 @@
       }
     }
-
-    /// <summary>
-    /// Adds a function that will be called every time an instruction is compiled.
-    /// The compiled will insert the instruction returned by the hook into the code.
-    /// </summary>
-    /// <param name="hook">The hook that should be called for each compiled instruction.</param>
-    public void AddInstructionPostProcessingHook(Func<Instruction, Instruction> hook) {
-      postInstructionCompiledHooks.Add(hook);
-    }
   }
 }
Index: /trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionTreeTerminalNode.cs
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionTreeTerminalNode.cs	(revision 8797)
+++ /trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionTreeTerminalNode.cs	(revision 8798)
@@ -30,7 +30,5 @@
   public abstract class SymbolicExpressionTreeTerminalNode : SymbolicExpressionTreeNode {
     public override IEnumerable<ISymbolicExpressionTreeNode> Subtrees {
-      get {
-        return Enumerable.Empty<ISymbolicExpressionTreeNode>();
-      }
+      get { return Enumerable.Empty<ISymbolicExpressionTreeNode>(); }
     }
 
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views-3.4.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views-3.4.csproj	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views-3.4.csproj	(revision 8798)
@@ -0,0 +1,237 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{E6CB1FC5-78EC-4EB8-BF12-35303C36F962}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views</RootNamespace>
+    <AssemblyName>HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views-3.4</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
+    <FileAlignment>512</FileAlignment>
+    <SignAssembly>true</SignAssembly>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <OldToolsVersion>3.5</OldToolsVersion>
+    <UpgradeBackupLocation />
+    <PublishUrl>publish\</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Disk</InstallFrom>
+    <UpdateEnabled>false</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <IsWebBootstrapper>false</IsWebBootstrapper>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>../../bin/</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>../../bin/</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
+    <OutputPath>../../bin/</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>../../bin/</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <OutputPath>../../bin/</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Windows.Forms.DataVisualization" />
+    <Reference Include="System.Xml.Linq">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data.DataSetExtensions">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </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">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="SymbolicTimeSeriesPrognosisSolutionView.Designer.cs">
+      <DependentUpon>SymbolicTimeSeriesPrognosisSolutionView.cs</DependentUpon>
+    </Compile>
+    <None Include="HeuristicLab.snk" />
+    <None Include="Plugin.cs.frame" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <None Include="Properties\AssemblyInfo.cs.frame" />
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+      <Visible>False</Visible>
+      <ProductName>Windows Installer 3.1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\HeuristicLab.Collections\3.3\HeuristicLab.Collections-3.3.csproj">
+      <Project>{958B43BC-CC5C-4FA2-8628-2B3B01D890B6}</Project>
+      <Name>HeuristicLab.Collections-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Common\3.3\HeuristicLab.Common-3.3.csproj">
+      <Project>{A9AD58B9-3EF9-4CC1-97E5-8D909039FF5C}</Project>
+      <Name>HeuristicLab.Common-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Core.Views\3.3\HeuristicLab.Core.Views-3.3.csproj">
+      <Project>{E226881D-315F-423D-B419-A766FE0D8685}</Project>
+      <Name>HeuristicLab.Core.Views-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Core\3.3\HeuristicLab.Core-3.3.csproj">
+      <Project>{C36BD924-A541-4A00-AFA8-41701378DDC5}</Project>
+      <Name>HeuristicLab.Core-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Data\3.3\HeuristicLab.Data-3.3.csproj">
+      <Project>{BBAB9DF5-5EF3-4BA8-ADE9-B36E82114937}</Project>
+      <Name>HeuristicLab.Data-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Encodings.SymbolicExpressionTreeEncoding\3.4\HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.csproj">
+      <Project>{06D4A186-9319-48A0-BADE-A2058D462EEA}</Project>
+      <Name>HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.MainForm.WindowsForms\3.3\HeuristicLab.MainForm.WindowsForms-3.3.csproj">
+      <Project>{AB687BBE-1BFE-476B-906D-44237135431D}</Project>
+      <Name>HeuristicLab.MainForm.WindowsForms-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.MainForm\3.3\HeuristicLab.MainForm-3.3.csproj">
+      <Project>{3BD61258-31DA-4B09-89C0-4F71FEF5F05A}</Project>
+      <Name>HeuristicLab.MainForm-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Optimization\3.3\HeuristicLab.Optimization-3.3.csproj">
+      <Project>{14AB8D24-25BC-400C-A846-4627AA945192}</Project>
+      <Name>HeuristicLab.Optimization-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.PluginInfrastructure\3.3\HeuristicLab.PluginInfrastructure-3.3.csproj">
+      <Project>{94186A6A-5176-4402-AE83-886557B53CCA}</Project>
+      <Name>HeuristicLab.PluginInfrastructure-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Problems.DataAnalysis.Symbolic.Regression\3.4\HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.csproj">
+      <Project>{5AC82412-911B-4FA2-A013-EDC5E3F3FCC2}</Project>
+      <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>
+      <Name>HeuristicLab.Problems.DataAnalysis.Symbolic.Views-3.4</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Problems.DataAnalysis.Symbolic\3.4\HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj">
+      <Project>{3D28463F-EC96-4D82-AFEE-38BE91A0CA00}</Project>
+      <Name>HeuristicLab.Problems.DataAnalysis.Symbolic-3.4</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Problems.DataAnalysis.Views\3.4\HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj">
+      <Project>{3E9E8944-44FF-40BB-A622-3A4A7DD0F198}</Project>
+      <Name>HeuristicLab.Problems.DataAnalysis.Views-3.4</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Problems.DataAnalysis\3.4\HeuristicLab.Problems.DataAnalysis-3.4.csproj">
+      <Project>{DF87C13E-A889-46FF-8153-66DCAA8C5674}</Project>
+      <Name>HeuristicLab.Problems.DataAnalysis-3.4</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+  <PropertyGroup>
+    <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">
+      set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+      set ProjectDir=$(ProjectDir)
+      set SolutionDir=$(SolutionDir)
+      set Outdir=$(Outdir)
+
+      call PreBuildEvent.cmd
+    </PreBuildEvent>
+    <PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
+      export ProjectDir=$(ProjectDir)
+      export SolutionDir=$(SolutionDir)
+
+      $SolutionDir/PreBuildEvent.sh
+    </PreBuildEvent>
+  </PropertyGroup>
+</Project>
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView.Designer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView.Designer.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView.Designer.cs	(revision 8798)
@@ -0,0 +1,61 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 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
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views {
+  partial class InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.SuspendLayout();
+      // 
+      // InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Name = "InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView";
+      this.Size = new System.Drawing.Size(564, 348);
+      this.btnOptimizeConstants.Enabled = false;
+      this.ResumeLayout(false);
+    }
+
+    #endregion
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView.cs	(revision 8798)
@@ -0,0 +1,130 @@
+﻿#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 HeuristicLab.Common;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Problems.DataAnalysis.Symbolic.Views;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views {
+  public partial class InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView : InteractiveSymbolicDataAnalysisSolutionSimplifierView {
+    private readonly ConstantTreeNode constantNode;
+    private readonly SymbolicExpressionTree tempTree;
+
+    public new SymbolicTimeSeriesPrognosisSolution Content {
+      get { return (SymbolicTimeSeriesPrognosisSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView()
+      : base() {
+      InitializeComponent();
+      this.Caption = "Interactive Time-Series Prognosis Solution Simplifier";
+
+      constantNode = ((ConstantTreeNode)new Constant().CreateTreeNode());
+      ISymbolicExpressionTreeNode root = new ProgramRootSymbol().CreateTreeNode();
+      ISymbolicExpressionTreeNode start = new StartSymbol().CreateTreeNode();
+      root.AddSubtree(start);
+      tempTree = new SymbolicExpressionTree(root);
+    }
+
+    protected override void UpdateModel(ISymbolicExpressionTree tree) {
+      var model = new SymbolicTimeSeriesPrognosisModel(tree, Content.Model.Interpreter);
+      SymbolicTimeSeriesPrognosisModel.Scale(model, Content.ProblemData, Content.ProblemData.TargetVariable);
+      Content.Model = model;
+    }
+
+    protected override Dictionary<ISymbolicExpressionTreeNode, double> CalculateReplacementValues(ISymbolicExpressionTree tree) {
+      Dictionary<ISymbolicExpressionTreeNode, double> replacementValues = new Dictionary<ISymbolicExpressionTreeNode, double>();
+      foreach (var componentBranch in tree.Root.GetSubtree(0).Subtrees)
+        foreach (ISymbolicExpressionTreeNode node in componentBranch.IterateNodesPrefix()) {
+          replacementValues[node] = CalculateReplacementValue(node, tree);
+        }
+      return replacementValues;
+    }
+
+    protected override Dictionary<ISymbolicExpressionTreeNode, double> CalculateImpactValues(ISymbolicExpressionTree tree) {
+      var interpreter = Content.Model.Interpreter;
+      var rows = Content.ProblemData.TrainingIndices;
+      var dataset = Content.ProblemData.Dataset;
+      var targetVariable = Content.ProblemData.TargetVariable;
+      var targetValues = dataset.GetDoubleValues(targetVariable, rows);
+      var originalOutput = interpreter.GetSymbolicExpressionTreeValues(tree, dataset, rows).ToArray();
+
+      Dictionary<ISymbolicExpressionTreeNode, double> impactValues = new Dictionary<ISymbolicExpressionTreeNode, double>();
+      List<ISymbolicExpressionTreeNode> nodes = tree.Root.GetSubtree(0).GetSubtree(0).IterateNodesPostfix().ToList();
+      OnlineCalculatorError errorState;
+      double originalR2 = OnlinePearsonsRSquaredCalculator.Calculate(targetValues, originalOutput, out errorState);
+      if (errorState != OnlineCalculatorError.None) originalR2 = 0.0;
+
+      foreach (ISymbolicExpressionTreeNode node in nodes) {
+        var parent = node.Parent;
+        constantNode.Value = CalculateReplacementValue(node, tree);
+        ISymbolicExpressionTreeNode replacementNode = constantNode;
+        SwitchNode(parent, node, replacementNode);
+        var newOutput = interpreter.GetSymbolicExpressionTreeValues(tree, dataset, rows);
+        double newR2 = OnlinePearsonsRSquaredCalculator.Calculate(targetValues, newOutput, out errorState);
+        if (errorState != OnlineCalculatorError.None) newR2 = 0.0;
+
+        // impact = 0 if no change
+        // impact < 0 if new solution is better
+        // impact > 0 if new solution is worse
+        impactValues[node] = originalR2 - newR2;
+        SwitchNode(parent, replacementNode, node);
+      }
+      return impactValues;
+    }
+
+    private double CalculateReplacementValue(ISymbolicExpressionTreeNode node, ISymbolicExpressionTree sourceTree) {
+      // remove old ADFs
+      while (tempTree.Root.SubtreeCount > 1) tempTree.Root.RemoveSubtree(1);
+      // clone ADFs of source tree
+      for (int i = 1; i < sourceTree.Root.SubtreeCount; i++) {
+        tempTree.Root.AddSubtree((ISymbolicExpressionTreeNode)sourceTree.Root.GetSubtree(i).Clone());
+      }
+      var start = tempTree.Root.GetSubtree(0);
+      while (start.SubtreeCount > 0) start.RemoveSubtree(0);
+      start.AddSubtree((ISymbolicExpressionTreeNode)node.Clone());
+      var interpreter = Content.Model.Interpreter;
+      var rows = Content.ProblemData.TrainingIndices;
+      var allPrognosedValues = interpreter.GetSymbolicExpressionTreeValues(tempTree, Content.ProblemData.Dataset, rows);
+
+      return allPrognosedValues.Median();
+    }
+
+
+    private void SwitchNode(ISymbolicExpressionTreeNode root, ISymbolicExpressionTreeNode oldBranch, ISymbolicExpressionTreeNode newBranch) {
+      for (int i = 0; i < root.SubtreeCount; i++) {
+        if (root.GetSubtree(i) == oldBranch) {
+          root.RemoveSubtree(i);
+          root.InsertSubtree(i, newBranch);
+          return;
+        }
+      }
+    }
+
+    protected override void btnOptimizeConstants_Click(object sender, EventArgs e) {
+      throw new NotImplementedException();
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/Plugin.cs.frame
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/Plugin.cs.frame	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/Plugin.cs.frame	(revision 8798)
@@ -0,0 +1,44 @@
+#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.Text;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views {
+  [Plugin("HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views", "Provides views for symbolic time-series prognosis problem classes.", "3.4.1.$WCREV$")]
+  [PluginFile("HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views-3.4.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.Common", "3.3")]
+  [PluginDependency("HeuristicLab.Core", "3.3")]
+  [PluginDependency("HeuristicLab.Core.Views", "3.3")]
+  [PluginDependency("HeuristicLab.Encodings.SymbolicExpressionTreeEncoding", "3.4")]
+  [PluginDependency("HeuristicLab.MainForm", "3.3")]
+  [PluginDependency("HeuristicLab.MainForm.WindowsForms", "3.3")]
+  [PluginDependency("HeuristicLab.Optimization","3.3")]
+  [PluginDependency("HeuristicLab.Problems.DataAnalysis", "3.4")]
+  [PluginDependency("HeuristicLab.Problems.DataAnalysis.Symbolic", "3.4")]
+  [PluginDependency("HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis", "3.4")]
+  [PluginDependency("HeuristicLab.Problems.DataAnalysis.Symbolic.Views", "3.4")]
+  [PluginDependency("HeuristicLab.Problems.DataAnalysis.Views", "3.4")]
+  public class HeuristicLabProblemsDataAnalysisSymbolicTimeSeriesPrognosisViewsPlugin : PluginBase {
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/Properties/AssemblyInfo.cs.frame
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/Properties/AssemblyInfo.cs.frame	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/Properties/AssemblyInfo.cs.frame	(revision 8798)
@@ -0,0 +1,55 @@
+#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.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views")]
+[assembly: AssemblyDescription("Provides views for symbolic time-series prognosis problem classes.")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2011 HEAL")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("7B83FC56-8725-40A4-9F87-B16AD05B7070")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers 
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("3.4.0.0")]
+[assembly: AssemblyFileVersion("3.4.1.$WCREV$")]
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/SymbolicTimeSeriesPrognosisSolutionView.Designer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/SymbolicTimeSeriesPrognosisSolutionView.Designer.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/SymbolicTimeSeriesPrognosisSolutionView.Designer.cs	(revision 8798)
@@ -0,0 +1,96 @@
+﻿namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views {
+  partial class SymbolicTimeSeriesPrognosisSolutionView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.btnSimplify = new System.Windows.Forms.Button();
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
+      this.splitContainer.Panel1.SuspendLayout();
+      this.splitContainer.Panel2.SuspendLayout();
+      this.splitContainer.SuspendLayout();
+      this.itemsGroupBox.SuspendLayout();
+      this.detailsGroupBox.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // splitContainer
+      // 
+      // 
+      // splitContainer.Panel1
+      // 
+      this.splitContainer.Panel1.Controls.Add(this.btnSimplify);
+      this.splitContainer.Size = new System.Drawing.Size(480, 275);
+      this.splitContainer.SplitterDistance = 255;
+      // 
+      // itemsGroupBox
+      // 
+      this.itemsGroupBox.Size = new System.Drawing.Size(486, 294);
+      // 
+      // itemsListView
+      // 
+      this.itemsListView.Size = new System.Drawing.Size(249, 238);
+      // 
+      // detailsGroupBox
+      // 
+      this.detailsGroupBox.Size = new System.Drawing.Size(215, 246);
+      // 
+      // addButton
+      // 
+      this.toolTip.SetToolTip(this.addButton, "Add");
+      // 
+      // removeButton
+      // 
+      this.toolTip.SetToolTip(this.removeButton, "Remove");
+      // 
+      // viewHost
+      // 
+      this.viewHost.Size = new System.Drawing.Size(203, 221);
+      // 
+      // btnSimplify
+      // 
+      this.btnSimplify.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+      this.btnSimplify.Location = new System.Drawing.Point(177, 4);
+      this.btnSimplify.Name = "btnSimplify";
+      this.btnSimplify.Size = new System.Drawing.Size(75, 23);
+      this.btnSimplify.TabIndex = 6;
+      this.btnSimplify.Text = "Simplify";
+      this.btnSimplify.UseVisualStyleBackColor = true;
+      this.btnSimplify.Click += new System.EventHandler(this.btn_SimplifyModel_Click);
+      // 
+      // SymbolicTimeSeriesPrognosisSolutionView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.Name = "SymbolicTimeSeriesPrognosisSolutionView";
+      this.Size = new System.Drawing.Size(486, 294);
+      this.splitContainer.Panel1.ResumeLayout(false);
+      this.splitContainer.Panel2.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
+      this.splitContainer.ResumeLayout(false);
+      this.itemsGroupBox.ResumeLayout(false);
+      this.detailsGroupBox.ResumeLayout(false);
+      this.ResumeLayout(false);
+    }
+
+    #endregion
+    private System.Windows.Forms.Button btnSimplify;
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/SymbolicTimeSeriesPrognosisSolutionView.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/SymbolicTimeSeriesPrognosisSolutionView.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/SymbolicTimeSeriesPrognosisSolutionView.cs	(revision 8798)
@@ -0,0 +1,46 @@
+﻿#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.Windows.Forms;
+using HeuristicLab.MainForm;
+using HeuristicLab.Problems.DataAnalysis.Views;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views {
+  [Content(typeof(SymbolicTimeSeriesPrognosisSolution), false)]
+  [View("SymbolicTimeSeriesPrognosisSolution View")]
+  public partial class SymbolicTimeSeriesPrognosisSolutionView : TimeSeriesPrognosisSolutionView {
+    public SymbolicTimeSeriesPrognosisSolutionView() {
+      InitializeComponent();
+    }
+
+    protected new SymbolicTimeSeriesPrognosisSolution Content {
+      get { return (SymbolicTimeSeriesPrognosisSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    private void btn_SimplifyModel_Click(object sender, EventArgs e) {
+      InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView view = new InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView();
+      view.Content = (SymbolicTimeSeriesPrognosisSolution)this.Content.Clone();
+      view.Show();
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis-3.4.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis-3.4.csproj	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis-3.4.csproj	(revision 8798)
@@ -0,0 +1,238 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{07486E68-1517-4B9D-A58D-A38E99AE71AB}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis</RootNamespace>
+    <AssemblyName>HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis-3.4</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
+    <FileAlignment>512</FileAlignment>
+    <SignAssembly>true</SignAssembly>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <OldToolsVersion>3.5</OldToolsVersion>
+    <UpgradeBackupLocation />
+    <PublishUrl>publish\</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Disk</InstallFrom>
+    <UpdateEnabled>false</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <IsWebBootstrapper>false</IsWebBootstrapper>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>../../bin/</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>../../bin/</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
+    <OutputPath>../../bin/</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>../../bin/</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <OutputPath>../../bin/</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="ALGLIB-3.6.0, Version=3.6.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.ALGLIB-3.6.0, Version=3.6.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Xml.Linq">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data.DataSetExtensions">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Interfaces\ISymbolicTimeSeriesPrognogisExpressionTreeInterpreter.cs" />
+    <Compile Include="Interfaces\ISymbolicTimeSeriesPrognosisInterpreterOperator.cs" />
+    <Compile Include="Interfaces\ISymbolicTimeSeriesPrognosisEvaluator.cs" />
+    <Compile Include="Interfaces\ISymbolicTimeSeriesPrognosisModel.cs" />
+    <Compile Include="Interfaces\ISymbolicTimeSeriesPrognosisSingleObjectiveEvaluator.cs" />
+    <Compile Include="Interfaces\ISymbolicTimeSeriesPrognosisSolution.cs" />
+    <Compile Include="Plugin.cs" />
+    <Compile Include="SingleObjective\SymbolicTimeSeriesPrognosisSingleObjectiveEvaluator.cs" />
+    <Compile Include="SingleObjective\SymbolicTimeSeriesPrognosisSingleObjectiveMeanSquaredErrorEvaluator.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="SingleObjective\SymbolicTimeSeriesPrognosisSingleObjectiveOverfittingAnalyzer.cs" />
+    <Compile Include="SingleObjective\SymbolicTimeSeriesPrognosisSingleObjectiveProblem.cs" />
+    <Compile Include="SingleObjective\SymbolicTimeSeriesPrognosisSingleObjectiveTrainingBestSolutionAnalyzer.cs" />
+    <Compile Include="SingleObjective\SymbolicTimeSeriesPrognosisSingleObjectiveValidationBestSolutionAnalyzer.cs" />
+    <Compile Include="SymbolicTimeSeriesPrognosisExpressionTreeInterpreter.cs" />
+    <Compile Include="SymbolicTimeSeriesPrognosisModel.cs" />
+    <Compile Include="SymbolicTimeSeriesPrognosisSolution.cs" />
+    <None Include="HeuristicLab.snk" />
+    <None Include="Plugin.cs.frame" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <None Include="Properties\AssemblyInfo.cs.frame" />
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+      <Visible>False</Visible>
+      <ProductName>Windows Installer 3.1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\HeuristicLab.Analysis\3.3\HeuristicLab.Analysis-3.3.csproj">
+      <Project>{887425B4-4348-49ED-A457-B7D2C26DDBF9}</Project>
+      <Name>HeuristicLab.Analysis-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Collections\3.3\HeuristicLab.Collections-3.3.csproj">
+      <Project>{958B43BC-CC5C-4FA2-8628-2B3B01D890B6}</Project>
+      <Name>HeuristicLab.Collections-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Common\3.3\HeuristicLab.Common-3.3.csproj">
+      <Project>{A9AD58B9-3EF9-4CC1-97E5-8D909039FF5C}</Project>
+      <Name>HeuristicLab.Common-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Core\3.3\HeuristicLab.Core-3.3.csproj">
+      <Project>{C36BD924-A541-4A00-AFA8-41701378DDC5}</Project>
+      <Name>HeuristicLab.Core-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Data\3.3\HeuristicLab.Data-3.3.csproj">
+      <Project>{BBAB9DF5-5EF3-4BA8-ADE9-B36E82114937}</Project>
+      <Name>HeuristicLab.Data-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Encodings.SymbolicExpressionTreeEncoding\3.4\HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.csproj">
+      <Project>{06D4A186-9319-48A0-BADE-A2058D462EEA}</Project>
+      <Name>HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Operators\3.3\HeuristicLab.Operators-3.3.csproj">
+      <Project>{23DA7FF4-D5B8-41B6-AA96-F0561D24F3EE}</Project>
+      <Name>HeuristicLab.Operators-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Optimization\3.3\HeuristicLab.Optimization-3.3.csproj">
+      <Project>{14AB8D24-25BC-400C-A846-4627AA945192}</Project>
+      <Name>HeuristicLab.Optimization-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Parameters\3.3\HeuristicLab.Parameters-3.3.csproj">
+      <Project>{56F9106A-079F-4C61-92F6-86A84C2D84B7}</Project>
+      <Name>HeuristicLab.Parameters-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Persistence\3.3\HeuristicLab.Persistence-3.3.csproj">
+      <Project>{102BC7D3-0EF9-439C-8F6D-96FF0FDB8E1B}</Project>
+      <Name>HeuristicLab.Persistence-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.PluginInfrastructure\3.3\HeuristicLab.PluginInfrastructure-3.3.csproj">
+      <Project>{94186A6A-5176-4402-AE83-886557B53CCA}</Project>
+      <Name>HeuristicLab.PluginInfrastructure-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Problems.DataAnalysis.Symbolic.Regression\3.4\HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.csproj">
+      <Project>{5AC82412-911B-4FA2-A013-EDC5E3F3FCC2}</Project>
+      <Name>HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Problems.DataAnalysis.Symbolic\3.4\HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj">
+      <Project>{3D28463F-EC96-4D82-AFEE-38BE91A0CA00}</Project>
+      <Name>HeuristicLab.Problems.DataAnalysis.Symbolic-3.4</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Problems.DataAnalysis\3.4\HeuristicLab.Problems.DataAnalysis-3.4.csproj">
+      <Project>{DF87C13E-A889-46FF-8153-66DCAA8C5674}</Project>
+      <Name>HeuristicLab.Problems.DataAnalysis-3.4</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Problems.Instances\3.3\HeuristicLab.Problems.Instances-3.3.csproj">
+      <Project>{3540E29E-4793-49E7-8EE2-FEA7F61C3994}</Project>
+      <Name>HeuristicLab.Problems.Instances-3.3</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+  <PropertyGroup>
+    <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">
+      set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+      set ProjectDir=$(ProjectDir)
+      set SolutionDir=$(SolutionDir)
+      set Outdir=$(Outdir)
+
+      call PreBuildEvent.cmd
+    </PreBuildEvent>
+    <PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
+      export ProjectDir=$(ProjectDir)
+      export SolutionDir=$(SolutionDir)
+
+      $SolutionDir/PreBuildEvent.sh
+    </PreBuildEvent>
+  </PropertyGroup>
+</Project>
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Interfaces/ISymbolicTimeSeriesPrognogisExpressionTreeInterpreter.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Interfaces/ISymbolicTimeSeriesPrognogisExpressionTreeInterpreter.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Interfaces/ISymbolicTimeSeriesPrognogisExpressionTreeInterpreter.cs	(revision 8798)
@@ -0,0 +1,31 @@
+﻿#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.Collections.Generic;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+  public interface ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter : ISymbolicDataAnalysisExpressionTreeInterpreter {
+    string TargetVariable { get; set; }
+    IEnumerable<IEnumerable<double>> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, IEnumerable<int> rows, int horizon);
+    IEnumerable<IEnumerable<double>> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, IEnumerable<int> rows, IEnumerable<int> horizon);
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Interfaces/ISymbolicTimeSeriesPrognosisEvaluator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Interfaces/ISymbolicTimeSeriesPrognosisEvaluator.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Interfaces/ISymbolicTimeSeriesPrognosisEvaluator.cs	(revision 8798)
@@ -0,0 +1,29 @@
+﻿#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 HeuristicLab.Core;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis {
+  public interface ISymbolicTimeSeriesPrognosisEvaluator : ISymbolicDataAnalysisEvaluator<ITimeSeriesPrognosisProblemData> {
+    IValueLookupParameter<IntValue> HorizonParameter { get; }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Interfaces/ISymbolicTimeSeriesPrognosisInterpreterOperator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Interfaces/ISymbolicTimeSeriesPrognosisInterpreterOperator.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Interfaces/ISymbolicTimeSeriesPrognosisInterpreterOperator.cs	(revision 8798)
@@ -0,0 +1,28 @@
+﻿#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 HeuristicLab.Core;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis {
+  public interface ISymbolicTimeSeriesPrognosisInterpreterOperator : IOperator {
+    ILookupParameter<ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter> SymbolicTimeSeriesPrognosisInterpreterParameter { get; }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Interfaces/ISymbolicTimeSeriesPrognosisModel.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Interfaces/ISymbolicTimeSeriesPrognosisModel.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Interfaces/ISymbolicTimeSeriesPrognosisModel.cs	(revision 8798)
@@ -0,0 +1,26 @@
+﻿#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
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis {
+  public interface ISymbolicTimeSeriesPrognosisModel : ITimeSeriesPrognosisModel, ISymbolicDataAnalysisModel {
+    new ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter Interpreter { get; }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Interfaces/ISymbolicTimeSeriesPrognosisSingleObjectiveEvaluator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Interfaces/ISymbolicTimeSeriesPrognosisSingleObjectiveEvaluator.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Interfaces/ISymbolicTimeSeriesPrognosisSingleObjectiveEvaluator.cs	(revision 8798)
@@ -0,0 +1,25 @@
+﻿#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
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis {
+  public interface ISymbolicTimeSeriesPrognosisSingleObjectiveEvaluator : ISymbolicTimeSeriesPrognosisEvaluator, ISymbolicDataAnalysisSingleObjectiveEvaluator<ITimeSeriesPrognosisProblemData> {
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Interfaces/ISymbolicTimeSeriesPrognosisSolution.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Interfaces/ISymbolicTimeSeriesPrognosisSolution.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Interfaces/ISymbolicTimeSeriesPrognosisSolution.cs	(revision 8798)
@@ -0,0 +1,28 @@
+﻿#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 HeuristicLab.Problems.DataAnalysis.Symbolic;
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis {
+  public interface ISymbolicTimeSeriesPrognosisSolution : ITimeSeriesPrognosisSolution, ISymbolicDataAnalysisSolution {
+    new ISymbolicTimeSeriesPrognosisModel Model { get; }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Plugin.cs.frame
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Plugin.cs.frame	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Plugin.cs.frame	(revision 8798)
@@ -0,0 +1,46 @@
+#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.Text;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis {
+  [Plugin("HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis","Provides classes to perform symbolic time-series prognosis.", "3.4.1.$WCREV$")]
+  [PluginFile("HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis-3.4.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.ALGLIB", "3.6")]
+  [PluginDependency("HeuristicLab.Analysis", "3.3")]
+  [PluginDependency("HeuristicLab.Common", "3.3")]
+  [PluginDependency("HeuristicLab.Collections", "3.3")]
+  [PluginDependency("HeuristicLab.Core", "3.3")]
+  [PluginDependency("HeuristicLab.Data", "3.3")]
+  [PluginDependency("HeuristicLab.Encodings.SymbolicExpressionTreeEncoding", "3.4")]
+  [PluginDependency("HeuristicLab.Operators", "3.3")]
+  [PluginDependency("HeuristicLab.Optimization", "3.3")]
+  [PluginDependency("HeuristicLab.Parameters", "3.3")]
+  [PluginDependency("HeuristicLab.Persistence", "3.3")]
+  [PluginDependency("HeuristicLab.Problems.DataAnalysis", "3.4")]
+  [PluginDependency("HeuristicLab.Problems.DataAnalysis.Symbolic", "3.4")]
+    [PluginDependency("HeuristicLab.Problems.DataAnalysis.Symbolic.Regression", "3.4")]
+  public class HeuristicLabProblemsDataAnalysisSymbolicTimeSeriesPrognosisPlugin : PluginBase {
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Properties/AssemblyInfo.cs.frame
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Properties/AssemblyInfo.cs.frame	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Properties/AssemblyInfo.cs.frame	(revision 8798)
@@ -0,0 +1,55 @@
+#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.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis")]
+[assembly: AssemblyDescription("Provides classes to perform symbolic time-series prognosis.")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2011 HEAL")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("6C9D6E55-8D82-45AA-8440-8BBA5AFD7437")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers 
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("3.4.0.0")]
+[assembly: AssemblyFileVersion("3.4.1.$WCREV$")]
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveEvaluator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveEvaluator.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveEvaluator.cs	(revision 8798)
@@ -0,0 +1,48 @@
+﻿#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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis {
+  [StorableClass]
+  public abstract class SymbolicTimeSeriesPrognosisSingleObjectiveEvaluator : SymbolicDataAnalysisSingleObjectiveEvaluator<ITimeSeriesPrognosisProblemData>, ISymbolicTimeSeriesPrognosisSingleObjectiveEvaluator {
+    private const string HorizonParameterName = "Horizon";
+    public IValueLookupParameter<IntValue> HorizonParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters[HorizonParameterName]; }
+    }
+
+    [StorableConstructor]
+    protected SymbolicTimeSeriesPrognosisSingleObjectiveEvaluator(bool deserializing) : base(deserializing) { }
+    protected SymbolicTimeSeriesPrognosisSingleObjectiveEvaluator(SymbolicTimeSeriesPrognosisSingleObjectiveEvaluator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+
+    protected SymbolicTimeSeriesPrognosisSingleObjectiveEvaluator()
+      : base() {
+      Parameters.Add(new ValueLookupParameter<IntValue>(HorizonParameterName, "The time interval for which the prognosis should be calculated.", new IntValue(1)));
+      ApplyLinearScalingParameter.Hidden = true;
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveMeanSquaredErrorEvaluator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveMeanSquaredErrorEvaluator.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveMeanSquaredErrorEvaluator.cs	(revision 8798)
@@ -0,0 +1,106 @@
+﻿#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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis {
+  [Item("Mean squared error Evaluator", "Calculates the mean squared error of a symbolic time-series prognosis solution.")]
+  [StorableClass]
+  public class SymbolicTimeSeriesPrognosisSingleObjectiveMeanSquaredErrorEvaluator : SymbolicTimeSeriesPrognosisSingleObjectiveEvaluator {
+    [StorableConstructor]
+    protected SymbolicTimeSeriesPrognosisSingleObjectiveMeanSquaredErrorEvaluator(bool deserializing) : base(deserializing) { }
+    protected SymbolicTimeSeriesPrognosisSingleObjectiveMeanSquaredErrorEvaluator(SymbolicTimeSeriesPrognosisSingleObjectiveMeanSquaredErrorEvaluator original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SymbolicTimeSeriesPrognosisSingleObjectiveMeanSquaredErrorEvaluator(this, cloner);
+    }
+
+    public SymbolicTimeSeriesPrognosisSingleObjectiveMeanSquaredErrorEvaluator() : base() { }
+
+    public override bool Maximization { get { return false; } }
+
+    public override IOperation Apply() {
+      var solution = SymbolicExpressionTreeParameter.ActualValue;
+      IEnumerable<int> rows = GenerateRowsToEvaluate();
+
+      var interpreter = (ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter)SymbolicDataAnalysisTreeInterpreterParameter.ActualValue;
+
+      double quality = Calculate(interpreter, solution,
+        EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper,
+        ProblemDataParameter.ActualValue, rows, EvaluationPartitionParameter.ActualValue,
+        HorizonParameter.ActualValue.Value, ApplyLinearScalingParameter.ActualValue.Value);
+      QualityParameter.ActualValue = new DoubleValue(quality);
+
+      return base.Apply();
+    }
+
+    public static double Calculate(ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, ITimeSeriesPrognosisProblemData problemData, IEnumerable<int> rows, IntRange evaluationPartition, int horizon, bool applyLinearScaling) {
+      var horizions = rows.Select(r => Math.Min(horizon, evaluationPartition.End - r));
+      IEnumerable<double> targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows.Zip(horizions, Enumerable.Range).SelectMany(r => r));
+      IEnumerable<double> estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, rows, horizions).SelectMany(x => x);
+      OnlineCalculatorError errorState;
+
+      double mse;
+      if (applyLinearScaling && horizon == 1) { //perform normal evaluation and afterwards scale the solution and calculate the fitness value        
+        var mseCalculator = new OnlineMeanSquaredErrorCalculator();
+        CalculateWithScaling(targetValues, estimatedValues, lowerEstimationLimit, upperEstimationLimit, mseCalculator, problemData.Dataset.Rows * horizon);
+        errorState = mseCalculator.ErrorState;
+        mse = mseCalculator.MeanSquaredError;
+      } else if (applyLinearScaling) { //first create model to perform linear scaling and afterwards calculate fitness for the scaled model
+        var model = new SymbolicTimeSeriesPrognosisModel((ISymbolicExpressionTree)solution.Clone(), interpreter, lowerEstimationLimit, upperEstimationLimit);
+        SymbolicTimeSeriesPrognosisModel.Scale(model, problemData, problemData.TargetVariable);
+        var scaledSolution = model.SymbolicExpressionTree;
+        estimatedValues = interpreter.GetSymbolicExpressionTreeValues(scaledSolution, problemData.Dataset, rows, horizions).SelectMany(x => x);
+        var boundedEstimatedValues = estimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit);
+        mse = OnlineMeanSquaredErrorCalculator.Calculate(targetValues, boundedEstimatedValues, out errorState);
+      } else {
+        var boundedEstimatedValues = estimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit);
+        mse = OnlineMeanSquaredErrorCalculator.Calculate(targetValues, boundedEstimatedValues, out errorState);
+      }
+
+      if (errorState != OnlineCalculatorError.None) return Double.NaN;
+      else return mse;
+    }
+
+
+    public override double Evaluate(IExecutionContext context, ISymbolicExpressionTree tree, ITimeSeriesPrognosisProblemData problemData, IEnumerable<int> rows) {
+      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = context;
+      EstimationLimitsParameter.ExecutionContext = context;
+      HorizonParameter.ExecutionContext = context;
+      EvaluationPartitionParameter.ExecutionContext = context;
+
+      double mse = Calculate((ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter)SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, EvaluationPartitionParameter.ActualValue, HorizonParameter.ActualValue.Value, ApplyLinearScalingParameter.ActualValue.Value);
+
+      HorizonParameter.ExecutionContext = null;
+      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
+      EstimationLimitsParameter.ExecutionContext = null;
+      EvaluationPartitionParameter.ExecutionContext = null;
+
+      return mse;
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveOverfittingAnalyzer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveOverfittingAnalyzer.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveOverfittingAnalyzer.cs	(revision 8798)
@@ -0,0 +1,122 @@
+#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.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Analysis;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis {
+  [Item("SymbolicTimeSeriesPrognosisSingleObjectiveOverfittingAnalyzer", "Calculates and tracks correlation of training and validation fitness of symbolic time-series prognosis models.")]
+  [StorableClass]
+  public sealed class SymbolicTimeSeriesPrognosisSingleObjectiveOverfittingAnalyzer : SymbolicDataAnalysisSingleObjectiveValidationAnalyzer<ISymbolicTimeSeriesPrognosisSingleObjectiveEvaluator, ITimeSeriesPrognosisProblemData> {
+    private const string TrainingValidationCorrelationParameterName = "Training and validation fitness correlation";
+    private const string TrainingValidationCorrelationTableParameterName = "Training and validation fitness correlation table";
+    private const string LowerCorrelationThresholdParameterName = "LowerCorrelationThreshold";
+    private const string UpperCorrelationThresholdParameterName = "UpperCorrelationThreshold";
+    private const string OverfittingParameterName = "IsOverfitting";
+
+    #region parameter properties
+    public ILookupParameter<DoubleValue> TrainingValidationQualityCorrelationParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters[TrainingValidationCorrelationParameterName]; }
+    }
+    public ILookupParameter<DataTable> TrainingValidationQualityCorrelationTableParameter {
+      get { return (ILookupParameter<DataTable>)Parameters[TrainingValidationCorrelationTableParameterName]; }
+    }
+    public IValueLookupParameter<DoubleValue> LowerCorrelationThresholdParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters[LowerCorrelationThresholdParameterName]; }
+    }
+    public IValueLookupParameter<DoubleValue> UpperCorrelationThresholdParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters[UpperCorrelationThresholdParameterName]; }
+    }
+    public ILookupParameter<BoolValue> OverfittingParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters[OverfittingParameterName]; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    private SymbolicTimeSeriesPrognosisSingleObjectiveOverfittingAnalyzer(bool deserializing) : base(deserializing) { }
+    private SymbolicTimeSeriesPrognosisSingleObjectiveOverfittingAnalyzer(SymbolicTimeSeriesPrognosisSingleObjectiveOverfittingAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    public SymbolicTimeSeriesPrognosisSingleObjectiveOverfittingAnalyzer()
+      : base() {
+      Parameters.Add(new LookupParameter<DoubleValue>(TrainingValidationCorrelationParameterName, "Correlation of training and validation fitnesses"));
+      Parameters.Add(new LookupParameter<DataTable>(TrainingValidationCorrelationTableParameterName, "Data table of training and validation fitness correlation values over the whole run."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>(LowerCorrelationThresholdParameterName, "Lower threshold for correlation value that marks the boundary from non-overfitting to overfitting.", new DoubleValue(0.65)));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>(UpperCorrelationThresholdParameterName, "Upper threshold for correlation value that marks the boundary from overfitting to non-overfitting.", new DoubleValue(0.75)));
+      Parameters.Add(new LookupParameter<BoolValue>(OverfittingParameterName, "Boolean indicator for overfitting."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SymbolicTimeSeriesPrognosisSingleObjectiveOverfittingAnalyzer(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      IEnumerable<int> rows = GenerateRowsToEvaluate();
+      if (!rows.Any()) return base.Apply();
+
+      double[] trainingQuality = QualityParameter.ActualValue.Select(x => x.Value).ToArray();
+      var problemData = ProblemDataParameter.ActualValue;
+      var evaluator = EvaluatorParameter.ActualValue;
+      // evaluate on validation partition
+      IExecutionContext childContext = (IExecutionContext)ExecutionContext.CreateChildOperation(evaluator);
+      double[] validationQuality = SymbolicExpressionTree
+        .AsParallel()
+        .Select(t => evaluator.Evaluate(childContext, t, problemData, rows))
+        .ToArray();
+      double r = 0.0;
+      try {
+        r = alglib.spearmancorr2(trainingQuality, validationQuality);
+      }
+      catch (alglib.alglibexception) {
+        r = 0.0;
+      }
+
+      TrainingValidationQualityCorrelationParameter.ActualValue = new DoubleValue(r);
+
+      if (TrainingValidationQualityCorrelationTableParameter.ActualValue == null) {
+        var dataTable = new DataTable(TrainingValidationQualityCorrelationTableParameter.Name, TrainingValidationQualityCorrelationTableParameter.Description);
+        dataTable.Rows.Add(new DataRow(TrainingValidationQualityCorrelationParameter.Name, TrainingValidationQualityCorrelationParameter.Description));
+        dataTable.Rows[TrainingValidationQualityCorrelationParameter.Name].VisualProperties.StartIndexZero = true;
+        TrainingValidationQualityCorrelationTableParameter.ActualValue = dataTable;
+        ResultCollectionParameter.ActualValue.Add(new Result(TrainingValidationQualityCorrelationTableParameter.Name, dataTable));
+      }
+
+      TrainingValidationQualityCorrelationTableParameter.ActualValue.Rows[TrainingValidationQualityCorrelationParameter.Name].Values.Add(r);
+
+      if (OverfittingParameter.ActualValue != null && OverfittingParameter.ActualValue.Value) {
+        // overfitting == true
+        // => r must reach the upper threshold to switch back to non-overfitting state
+        OverfittingParameter.ActualValue = new BoolValue(r < UpperCorrelationThresholdParameter.ActualValue.Value);
+      } else {
+        // overfitting == false 
+        // => r must drop below lower threshold to switch to overfitting state
+        OverfittingParameter.ActualValue = new BoolValue(r < LowerCorrelationThresholdParameter.ActualValue.Value);
+      }
+
+      return base.Apply();
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectivePearsonRSquaredEvaluator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectivePearsonRSquaredEvaluator.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectivePearsonRSquaredEvaluator.cs	(revision 8798)
@@ -0,0 +1,97 @@
+﻿#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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis {
+  [Item("Pearson R² Evaluator", "Calculates the square of the pearson correlation coefficient (also known as coefficient of determination) of a symbolic time-series prognosis solution.")]
+  [StorableClass]
+  public class SymbolicTimeSeriesPrognosisSingleObjectivePearsonRSquaredEvaluator : SymbolicTimeSeriesPrognosisSingleObjectiveEvaluator {
+    [StorableConstructor]
+    protected SymbolicTimeSeriesPrognosisSingleObjectivePearsonRSquaredEvaluator(bool deserializing) : base(deserializing) { }
+    protected SymbolicTimeSeriesPrognosisSingleObjectivePearsonRSquaredEvaluator(SymbolicTimeSeriesPrognosisSingleObjectivePearsonRSquaredEvaluator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SymbolicTimeSeriesPrognosisSingleObjectivePearsonRSquaredEvaluator(this, cloner);
+    }
+
+    public SymbolicTimeSeriesPrognosisSingleObjectivePearsonRSquaredEvaluator() : base() { }
+
+    public override bool Maximization { get { return true; } }
+
+    public override IOperation Apply() {
+      var solution = SymbolicExpressionTreeParameter.ActualValue;
+      IEnumerable<int> rows = GenerateRowsToEvaluate();
+
+      double quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution,
+        EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper,
+        ProblemDataParameter.ActualValue,
+        rows, HorizonParameter.ActualValue.Value);
+      QualityParameter.ActualValue = new DoubleValue(quality);
+
+      return base.Apply();
+    }
+
+    public static double Calculate(ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, ITimeSeriesPrognosisProblemData problemData, IEnumerable<int> rows, int horizon) {
+      var allPredictedContinuations =
+        interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, problemData.TargetVariables.ToArray(),
+                                                    rows, horizon).ToArray();
+
+      var meanCalculator = new OnlineMeanAndVarianceCalculator();
+      int i = 0;
+      foreach (var targetVariable in problemData.TargetVariables) {
+        var actualContinuations = from r in rows
+                                  select problemData.Dataset.GetDoubleValues(targetVariable, Enumerable.Range(r, horizon));
+        var startValues = problemData.Dataset.GetDoubleValues(targetVariable, rows.Select(r => r - 1));
+        OnlineCalculatorError errorState;
+        meanCalculator.Add(OnlineTheilsUStatisticCalculator.Calculate(
+          startValues,
+          allPredictedContinuations.Select(v => v.ElementAt(i)),
+          actualContinuations, out errorState));
+        if (errorState != OnlineCalculatorError.None) return double.NaN;
+        i++;
+      }
+      return meanCalculator.Mean;
+    }
+
+    public override double Evaluate(IExecutionContext context, ISymbolicExpressionTree tree, ITimeSeriesPrognosisProblemData problemData, IEnumerable<int> rows) {
+      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = context;
+      EstimationLimitsParameter.ExecutionContext = context;
+      HorizonParameter.ExecutionContext = context;
+
+      double r2 = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, HorizonParameter.ActualValue.Value);
+
+      HorizonParameter.ExecutionContext = null;
+      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
+      EstimationLimitsParameter.ExecutionContext = null;
+
+      return r2;
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveProblem.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveProblem.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveProblem.cs	(revision 8798)
@@ -0,0 +1,133 @@
+﻿#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.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis {
+  [Item("Symbolic Time-Series Prognosis Problem (single objective)", "Represents a single objective symbolic time-series prognosis problem.")]
+  [StorableClass]
+  [Creatable("Problems")]
+  public class SymbolicTimeSeriesPrognosisSingleObjectiveProblem : SymbolicDataAnalysisSingleObjectiveProblem<ITimeSeriesPrognosisProblemData, ISymbolicTimeSeriesPrognosisSingleObjectiveEvaluator, ISymbolicDataAnalysisSolutionCreator>, ITimeSeriesPrognosisProblem {
+    private const double PunishmentFactor = 10;
+    private const int InitialMaximumTreeDepth = 8;
+    private const int InitialMaximumTreeLength = 25;
+    private const string EstimationLimitsParameterName = "EstimationLimits";
+    private const string EstimationLimitsParameterDescription = "The limits for the estimated value that can be returned by the symbolic regression model.";
+
+    #region parameter properties
+    public IFixedValueParameter<DoubleLimit> EstimationLimitsParameter {
+      get { return (IFixedValueParameter<DoubleLimit>)Parameters[EstimationLimitsParameterName]; }
+    }
+    #endregion
+    #region properties
+    public DoubleLimit EstimationLimits {
+      get { return EstimationLimitsParameter.Value; }
+    }
+    #endregion
+    [StorableConstructor]
+    protected SymbolicTimeSeriesPrognosisSingleObjectiveProblem(bool deserializing) : base(deserializing) { }
+    protected SymbolicTimeSeriesPrognosisSingleObjectiveProblem(SymbolicTimeSeriesPrognosisSingleObjectiveProblem original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) { return new SymbolicTimeSeriesPrognosisSingleObjectiveProblem(this, cloner); }
+
+    public SymbolicTimeSeriesPrognosisSingleObjectiveProblem()
+      : base(new TimeSeriesPrognosisProblemData(), new SymbolicTimeSeriesPrognosisSingleObjectiveMeanSquaredErrorEvaluator(), new SymbolicDataAnalysisExpressionTreeCreator()) {
+      Parameters.Add(new FixedValueParameter<DoubleLimit>(EstimationLimitsParameterName, EstimationLimitsParameterDescription));
+      EstimationLimitsParameter.Hidden = true;
+
+      Maximization.Value = false;
+      MaximumSymbolicExpressionTreeDepth.Value = InitialMaximumTreeDepth;
+      MaximumSymbolicExpressionTreeLength.Value = InitialMaximumTreeLength;
+
+      var interpeter = new SymbolicTimeSeriesPrognosisExpressionTreeInterpreter();
+      interpeter.TargetVariable = ProblemData.TargetVariable;
+      SymbolicExpressionTreeInterpreter = interpeter;
+
+      SymbolicExpressionTreeGrammarParameter.ValueChanged += (o, e) => ConfigureGrammarSymbols();
+      ConfigureGrammarSymbols();
+
+      InitializeOperators();
+      UpdateEstimationLimits();
+    }
+
+    private void ConfigureGrammarSymbols() {
+      var grammar = SymbolicExpressionTreeGrammar as TypeCoherentExpressionGrammar;
+      if (grammar != null) grammar.ConfigureAsDefaultTimeSeriesPrognosisGrammar();
+      UpdateGrammar();
+    }
+    protected override void UpdateGrammar() {
+      base.UpdateGrammar();
+      foreach (var autoregressiveSymbol in SymbolicExpressionTreeGrammar.Symbols.OfType<AutoregressiveTargetVariable>()) {
+        if (!autoregressiveSymbol.Fixed) autoregressiveSymbol.VariableNames = ProblemData.TargetVariable.ToEnumerable();
+      }
+    }
+
+    private void InitializeOperators() {
+      Operators.Add(new SymbolicTimeSeriesPrognosisSingleObjectiveTrainingBestSolutionAnalyzer());
+      Operators.Add(new SymbolicTimeSeriesPrognosisSingleObjectiveValidationBestSolutionAnalyzer());
+      Operators.Add(new SymbolicTimeSeriesPrognosisSingleObjectiveOverfittingAnalyzer());
+      ParameterizeOperators();
+    }
+
+    private void UpdateEstimationLimits() {
+      if (ProblemData.TrainingIndices.Any()) {
+        var targetValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices).ToList();
+        var mean = targetValues.Average();
+        var range = targetValues.Max() - targetValues.Min();
+        EstimationLimits.Upper = mean + PunishmentFactor * range;
+        EstimationLimits.Lower = mean - PunishmentFactor * range;
+      } else {
+        EstimationLimits.Upper = double.MaxValue;
+        EstimationLimits.Lower = double.MinValue;
+      }
+    }
+
+    protected override void OnProblemDataChanged() {
+      base.OnProblemDataChanged();
+      var interpreter = SymbolicExpressionTreeInterpreter as ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter;
+      if (interpreter != null) {
+        interpreter.TargetVariable = ProblemData.TargetVariable;
+      }
+      UpdateEstimationLimits();
+
+    }
+
+    protected override void ParameterizeOperators() {
+      base.ParameterizeOperators();
+      if (Parameters.ContainsKey(EstimationLimitsParameterName)) {
+        var operators = Parameters.OfType<IValueParameter>().Select(p => p.Value).OfType<IOperator>().Union(Operators);
+        foreach (var op in operators.OfType<ISymbolicDataAnalysisBoundedOperator>()) {
+          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: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveTrainingBestSolutionAnalyzer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveTrainingBestSolutionAnalyzer.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveTrainingBestSolutionAnalyzer.cs	(revision 8798)
@@ -0,0 +1,71 @@
+#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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis {
+  /// <summary>
+  /// An operator that analyzes the training best symbolic time-series prognosis solution for single objective symbolic time-series prognosis problems.
+  /// </summary>
+  [Item("SymbolicTimeSeriesPrognosisSingleObjectiveTrainingBestSolutionAnalyzer", "An operator that analyzes the training best symbolic time-series prognosis solution for single objective symbolic time-series prognosis problems.")]
+  [StorableClass]
+  public sealed class SymbolicTimeSeriesPrognosisSingleObjectiveTrainingBestSolutionAnalyzer : SymbolicDataAnalysisSingleObjectiveTrainingBestSolutionAnalyzer<ISymbolicTimeSeriesPrognosisSolution>,
+  ISymbolicDataAnalysisInterpreterOperator, ISymbolicDataAnalysisBoundedOperator {
+    private const string ProblemDataParameterName = "ProblemData";
+    private const string SymbolicDataAnalysisTreeInterpreterParameterName = "SymbolicDataAnalysisTreeInterpreter";
+    private const string EstimationLimitsParameterName = "EstimationLimits";
+    #region parameter properties
+    public ILookupParameter<ITimeSeriesPrognosisProblemData> ProblemDataParameter {
+      get { return (ILookupParameter<ITimeSeriesPrognosisProblemData>)Parameters[ProblemDataParameterName]; }
+    }
+    public ILookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter> SymbolicDataAnalysisTreeInterpreterParameter {
+      get { return (ILookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>)Parameters[SymbolicDataAnalysisTreeInterpreterParameterName]; }
+    }
+    public IValueLookupParameter<DoubleLimit> EstimationLimitsParameter {
+      get { return (IValueLookupParameter<DoubleLimit>)Parameters[EstimationLimitsParameterName]; }
+    }
+    #endregion
+
+
+    [StorableConstructor]
+    private SymbolicTimeSeriesPrognosisSingleObjectiveTrainingBestSolutionAnalyzer(bool deserializing) : base(deserializing) { }
+    private SymbolicTimeSeriesPrognosisSingleObjectiveTrainingBestSolutionAnalyzer(SymbolicTimeSeriesPrognosisSingleObjectiveTrainingBestSolutionAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    public SymbolicTimeSeriesPrognosisSingleObjectiveTrainingBestSolutionAnalyzer()
+      : base() {
+      Parameters.Add(new LookupParameter<ITimeSeriesPrognosisProblemData>(ProblemDataParameterName, "The problem data for the symbolic regression solution."));
+      Parameters.Add(new LookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>(SymbolicDataAnalysisTreeInterpreterParameterName, "The symbolic time series prognosis interpreter for the symbolic expression tree."));
+      Parameters.Add(new ValueLookupParameter<DoubleLimit>(EstimationLimitsParameterName, "The lower and upper limit for the estimated values produced by the symbolic regression model."));
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SymbolicTimeSeriesPrognosisSingleObjectiveTrainingBestSolutionAnalyzer(this, cloner);
+    }
+
+    protected override ISymbolicTimeSeriesPrognosisSolution CreateSolution(ISymbolicExpressionTree bestTree, double bestQuality) {
+      var model = new SymbolicTimeSeriesPrognosisModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue as ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
+      if (ApplyLinearScalingParameter.ActualValue.Value) SymbolicTimeSeriesPrognosisModel.Scale(model, ProblemDataParameter.ActualValue, ProblemDataParameter.ActualValue.TargetVariable);
+      return new SymbolicTimeSeriesPrognosisSolution(model, (ITimeSeriesPrognosisProblemData)ProblemDataParameter.ActualValue.Clone());
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveValidationBestSolutionAnalyzer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveValidationBestSolutionAnalyzer.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveValidationBestSolutionAnalyzer.cs	(revision 8798)
@@ -0,0 +1,60 @@
+#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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis {
+  /// <summary>
+  /// An operator that analyzes the validation best symbolic time-series prognosis solution for single objective symbolic time-series prognosis problems.
+  /// </summary>
+  [Item("SymbolicTimeSeriesPrognosisSingleObjectiveValidationBestSolutionAnalyzer", "An operator that analyzes the validation best symbolic time-series prognosis solution for single objective symbolic time-series prognosis problems.")]
+  [StorableClass]
+  public sealed class SymbolicTimeSeriesPrognosisSingleObjectiveValidationBestSolutionAnalyzer : SymbolicDataAnalysisSingleObjectiveValidationBestSolutionAnalyzer<ISymbolicTimeSeriesPrognosisSolution, ISymbolicTimeSeriesPrognosisSingleObjectiveEvaluator, ITimeSeriesPrognosisProblemData>, ISymbolicDataAnalysisBoundedOperator {
+    private const string EstimationLimitsParameterName = "EstimationLimits";
+    #region parameter properties
+    public IValueLookupParameter<DoubleLimit> EstimationLimitsParameter {
+      get { return (IValueLookupParameter<DoubleLimit>)Parameters[EstimationLimitsParameterName]; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    private SymbolicTimeSeriesPrognosisSingleObjectiveValidationBestSolutionAnalyzer(bool deserializing) : base(deserializing) { }
+    private SymbolicTimeSeriesPrognosisSingleObjectiveValidationBestSolutionAnalyzer(SymbolicTimeSeriesPrognosisSingleObjectiveValidationBestSolutionAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    public SymbolicTimeSeriesPrognosisSingleObjectiveValidationBestSolutionAnalyzer()
+      : base() {
+      Parameters.Add(new ValueLookupParameter<DoubleLimit>(EstimationLimitsParameterName, "The lower and upper limit for the estimated values produced by the symbolic regression model."));
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SymbolicTimeSeriesPrognosisSingleObjectiveValidationBestSolutionAnalyzer(this, cloner);
+    }
+
+    protected override ISymbolicTimeSeriesPrognosisSolution CreateSolution(ISymbolicExpressionTree bestTree, double bestQuality) {
+      var model = new SymbolicTimeSeriesPrognosisModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue as ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
+      if (ApplyLinearScalingParameter.ActualValue.Value) SymbolicTimeSeriesPrognosisModel.Scale(model, ProblemDataParameter.ActualValue, ProblemDataParameter.ActualValue.TargetVariable);
+
+      return new SymbolicTimeSeriesPrognosisSolution(model, (ITimeSeriesPrognosisProblemData)ProblemDataParameter.ActualValue.Clone());
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SymbolicTimeSeriesPrognosisExpressionTreeInterpreter.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SymbolicTimeSeriesPrognosisExpressionTreeInterpreter.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SymbolicTimeSeriesPrognosisExpressionTreeInterpreter.cs	(revision 8798)
@@ -0,0 +1,146 @@
+﻿#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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis {
+  [StorableClass]
+  [Item("SymbolicTimeSeriesPrognosisInterpreter", "Interpreter for symbolic expression trees including automatically defined functions.")]
+  public sealed class SymbolicTimeSeriesPrognosisExpressionTreeInterpreter : SymbolicDataAnalysisExpressionTreeInterpreter, ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter {
+    private const string TargetVariableParameterName = "TargetVariable";
+
+    public IFixedValueParameter<StringValue> TargetVariableParameter {
+      get { return (IFixedValueParameter<StringValue>)Parameters[TargetVariableParameterName]; }
+    }
+
+    public string TargetVariable {
+      get { return TargetVariableParameter.Value.Value; }
+      set { TargetVariableParameter.Value.Value = value; }
+    }
+
+    [ThreadStatic]
+    private static double[] targetVariableCache;
+    [ThreadStatic]
+    private static List<int> invalidateCacheIndexes;
+
+    [StorableConstructor]
+    private SymbolicTimeSeriesPrognosisExpressionTreeInterpreter(bool deserializing) : base(deserializing) { }
+    private SymbolicTimeSeriesPrognosisExpressionTreeInterpreter(SymbolicTimeSeriesPrognosisExpressionTreeInterpreter original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SymbolicTimeSeriesPrognosisExpressionTreeInterpreter(this, cloner);
+    }
+
+    internal SymbolicTimeSeriesPrognosisExpressionTreeInterpreter()
+      : base("SymbolicTimeSeriesPrognosisInterpreter", "Interpreter for symbolic expression trees including automatically defined functions.") {
+      Parameters.Add(new FixedValueParameter<StringValue>(TargetVariableParameterName));
+      TargetVariableParameter.Hidden = true;
+    }
+
+    public SymbolicTimeSeriesPrognosisExpressionTreeInterpreter(string targetVariable)
+      : this() {
+      TargetVariable = targetVariable;
+    }
+
+    // for each row several (=#horizon) future predictions
+    public IEnumerable<IEnumerable<double>> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, IEnumerable<int> rows, int horizon) {
+      return GetSymbolicExpressionTreeValues(tree, dataset, rows, rows.Select(row => horizon));
+    }
+
+    public IEnumerable<IEnumerable<double>> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, IEnumerable<int> rows, IEnumerable<int> horizons) {
+      if (CheckExpressionsWithIntervalArithmetic.Value)
+        throw new NotSupportedException("Interval arithmetic is not yet supported in the symbolic data analysis interpreter.");
+      if (targetVariableCache == null || targetVariableCache.GetLength(0) < dataset.Rows)
+        targetVariableCache = dataset.GetDoubleValues(TargetVariable).ToArray();
+      if (invalidateCacheIndexes == null)
+        invalidateCacheIndexes = new List<int>(10);
+
+      string targetVariable = TargetVariable;
+      EvaluatedSolutions.Value++; // increment the evaluated solutions counter
+      var state = PrepareInterpreterState(tree, dataset, targetVariableCache);
+      var rowsEnumerator = rows.GetEnumerator();
+      var horizonsEnumerator = horizons.GetEnumerator();
+
+      // produce a n-step forecast for all rows
+      while (rowsEnumerator.MoveNext() & horizonsEnumerator.MoveNext()) {
+        int row = rowsEnumerator.Current;
+        int horizon = horizonsEnumerator.Current;
+        double[] vProgs = new double[horizon];
+
+        for (int i = 0; i < horizon; i++) {
+          int localRow = i + row; // create a local variable for the ref parameter
+          vProgs[i] = Evaluate(dataset, ref localRow, state);
+          targetVariableCache[localRow] = vProgs[i];
+          invalidateCacheIndexes.Add(localRow);
+          state.Reset();
+        }
+        yield return vProgs;
+
+        int j = 0;
+        foreach (var targetValue in dataset.GetDoubleValues(targetVariable, invalidateCacheIndexes)) {
+          targetVariableCache[invalidateCacheIndexes[j]] = targetValue;
+          j++;
+        }
+        invalidateCacheIndexes.Clear();
+      }
+
+      if (rowsEnumerator.MoveNext() || horizonsEnumerator.MoveNext())
+        throw new ArgumentException("Number of elements in rows and horizon enumerations doesn't match.");
+    }
+
+    private InterpreterState PrepareInterpreterState(ISymbolicExpressionTree tree, Dataset dataset, double[] targetVariableCache) {
+      Instruction[] code = SymbolicExpressionTreeCompiler.Compile(tree, OpCodes.MapSymbolToOpCode);
+      int necessaryArgStackSize = 0;
+      foreach (Instruction instr in code) {
+        if (instr.opCode == OpCodes.Variable) {
+          var variableTreeNode = (VariableTreeNode)instr.dynamicNode;
+          if (variableTreeNode.VariableName == TargetVariable)
+            instr.iArg0 = targetVariableCache;
+          else
+            instr.iArg0 = dataset.GetReadOnlyDoubleValues(variableTreeNode.VariableName);
+        } else if (instr.opCode == OpCodes.LagVariable) {
+          var variableTreeNode = (LaggedVariableTreeNode)instr.dynamicNode;
+          if (variableTreeNode.VariableName == TargetVariable)
+            instr.iArg0 = targetVariableCache;
+          else
+            instr.iArg0 = dataset.GetReadOnlyDoubleValues(variableTreeNode.VariableName);
+        } else if (instr.opCode == OpCodes.VariableCondition) {
+          var variableTreeNode = (VariableConditionTreeNode)instr.dynamicNode;
+          if (variableTreeNode.VariableName == TargetVariable)
+            instr.iArg0 = targetVariableCache;
+          else
+            instr.iArg0 = dataset.GetReadOnlyDoubleValues(variableTreeNode.VariableName);
+        } else if (instr.opCode == OpCodes.Call) {
+          necessaryArgStackSize += instr.nArguments + 1;
+        }
+      }
+
+      return new InterpreterState(code, necessaryArgStackSize);
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SymbolicTimeSeriesPrognosisModel.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SymbolicTimeSeriesPrognosisModel.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SymbolicTimeSeriesPrognosisModel.cs	(revision 8798)
@@ -0,0 +1,63 @@
+#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.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis {
+  /// <summary>
+  /// Represents a symbolic time-series prognosis model
+  /// </summary>
+  [StorableClass]
+  [Item(Name = "Symbolic Time-Series Prognosis Model", Description = "Represents a symbolic time series prognosis model.")]
+  public class SymbolicTimeSeriesPrognosisModel : SymbolicRegressionModel, ISymbolicTimeSeriesPrognosisModel {
+
+    public new ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter Interpreter {
+      get { return (ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter)base.Interpreter; }
+    }
+
+    [StorableConstructor]
+    protected SymbolicTimeSeriesPrognosisModel(bool deserializing) : base(deserializing) { }
+    protected SymbolicTimeSeriesPrognosisModel(SymbolicTimeSeriesPrognosisModel original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SymbolicTimeSeriesPrognosisModel(this, cloner);
+    }
+
+    public SymbolicTimeSeriesPrognosisModel(ISymbolicExpressionTree tree, ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter interpreter, double lowerLimit = double.MinValue, double upperLimit = double.MaxValue) : base(tree, interpreter, lowerLimit, upperLimit) { }
+
+    public IEnumerable<IEnumerable<double>> GetPrognosedValues(Dataset dataset, IEnumerable<int> rows, IEnumerable<int> horizons) {
+      var estimatedValues = Interpreter.GetSymbolicExpressionTreeValues(SymbolicExpressionTree, dataset, rows, horizons);
+      return estimatedValues.Select(predictionPerRow => predictionPerRow.LimitToRange(LowerEstimationLimit, UpperEstimationLimit));
+    }
+
+    public ISymbolicTimeSeriesPrognosisSolution CreateTimeSeriesPrognosisSolution(ITimeSeriesPrognosisProblemData problemData) {
+      return new SymbolicTimeSeriesPrognosisSolution(this, problemData);
+    }
+    ITimeSeriesPrognosisSolution ITimeSeriesPrognosisModel.CreateTimeSeriesPrognosisSolution(ITimeSeriesPrognosisProblemData problemData) {
+      return CreateTimeSeriesPrognosisSolution(problemData);
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SymbolicTimeSeriesPrognosisSolution.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SymbolicTimeSeriesPrognosisSolution.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SymbolicTimeSeriesPrognosisSolution.cs	(revision 8798)
@@ -0,0 +1,80 @@
+#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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis {
+  /// <summary>
+  /// Represents a symbolic time-series prognosis solution (model + data) and attributes of the solution like accuracy and complexity
+  /// </summary>
+  [StorableClass]
+  [Item(Name = "SymbolicTimeSeriesPrognosisSolution", Description = "Represents a symbolic time-series prognosis solution (model + data) and attributes of the solution like accuracy and complexity.")]
+  public sealed class SymbolicTimeSeriesPrognosisSolution : TimeSeriesPrognosisSolution, ISymbolicTimeSeriesPrognosisSolution {
+    private const string ModelLengthResultName = "Model Length";
+    private const string ModelDepthResultName = "Model Depth";
+
+    public new ISymbolicTimeSeriesPrognosisModel Model {
+      get { return (ISymbolicTimeSeriesPrognosisModel)base.Model; }
+      set { base.Model = value; }
+    }
+    ISymbolicDataAnalysisModel ISymbolicDataAnalysisSolution.Model {
+      get { return (ISymbolicDataAnalysisModel)base.Model; }
+    }
+    public int ModelLength {
+      get { return ((IntValue)this[ModelLengthResultName].Value).Value; }
+      private set { ((IntValue)this[ModelLengthResultName].Value).Value = value; }
+    }
+
+    public int ModelDepth {
+      get { return ((IntValue)this[ModelDepthResultName].Value).Value; }
+      private set { ((IntValue)this[ModelDepthResultName].Value).Value = value; }
+    }
+
+    [StorableConstructor]
+    private SymbolicTimeSeriesPrognosisSolution(bool deserializing) : base(deserializing) { }
+    private SymbolicTimeSeriesPrognosisSolution(SymbolicTimeSeriesPrognosisSolution original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public SymbolicTimeSeriesPrognosisSolution(ISymbolicTimeSeriesPrognosisModel model, ITimeSeriesPrognosisProblemData problemData)
+      : base(model, problemData) {
+      Add(new Result(ModelLengthResultName, "Length of the symbolic regression model.", new IntValue()));
+      Add(new Result(ModelDepthResultName, "Depth of the symbolic regression model.", new IntValue()));
+      CalculateResults();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SymbolicTimeSeriesPrognosisSolution(this, cloner);
+    }
+
+    protected override void RecalculateResults() {
+      base.RecalculateResults();
+      CalculateResults();
+    }
+    private void CalculateResults() {
+      ModelLength = Model.SymbolicExpressionTree.Length;
+      ModelDepth = Model.SymbolicExpressionTree.Depth;
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectiveTrainingBestSolutionAnalyzer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectiveTrainingBestSolutionAnalyzer.cs	(revision 8797)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectiveTrainingBestSolutionAnalyzer.cs	(revision 8798)
@@ -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: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Evaluators/SymbolicDataAnalysisEvaluator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Evaluators/SymbolicDataAnalysisEvaluator.cs	(revision 8797)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Evaluators/SymbolicDataAnalysisEvaluator.cs	(revision 8798)
@@ -45,4 +45,5 @@
     private const string RelativeNumberOfEvaluatedSamplesParameterName = "RelativeNumberOfEvaluatedSamples";
     private const string ApplyLinearScalingParameterName = "ApplyLinearScaling";
+    private const string ValidRowIndicatorParameterName = "ValidRowIndicator";
 
     public override bool CanChangeName { get { return false; } }
@@ -74,4 +75,7 @@
       get { return (ILookupParameter<BoolValue>)Parameters[ApplyLinearScalingParameterName]; }
     }
+    public IValueLookupParameter<StringValue> ValidRowIndicatorParameter {
+      get { return (IValueLookupParameter<StringValue>)Parameters[ValidRowIndicatorParameterName]; }
+    }
     #endregion
 
@@ -92,4 +96,5 @@
       Parameters.Add(new ValueLookupParameter<PercentValue>(RelativeNumberOfEvaluatedSamplesParameterName, "The relative number of samples of the dataset partition, which should be randomly chosen for evaluation between the start and end index."));
       Parameters.Add(new LookupParameter<BoolValue>(ApplyLinearScalingParameterName, "Flag that indicates if the individual should be linearly scaled before evaluating."));
+      Parameters.Add(new ValueLookupParameter<StringValue>(ValidRowIndicatorParameterName, "An indicator variable in the data set that specifies which rows should be evaluated (those for which the indicator <> 0) (optional)."));
     }
 
@@ -100,4 +105,6 @@
       if (!Parameters.ContainsKey(ApplyLinearScalingParameterName))
         Parameters.Add(new LookupParameter<BoolValue>(ApplyLinearScalingParameterName, "Flag that indicates if the individual should be linearly scaled before evaluating."));
+      if (!Parameters.ContainsKey(ValidRowIndicatorParameterName))
+        Parameters.Add(new ValueLookupParameter<StringValue>(ValidRowIndicatorParameterName, "An indicator variable in the data set that specifies which rows should be evaluated (those for which the indicator <> 0) (optional)."));
     }
 
@@ -112,5 +119,4 @@
       int testPartitionStart = ProblemDataParameter.ActualValue.TestPartition.Start;
       int testPartitionEnd = ProblemDataParameter.ActualValue.TestPartition.End;
-
       if (samplesEnd < samplesStart) throw new ArgumentException("Start value is larger than end value.");
 
@@ -124,5 +130,12 @@
       }
 
-      return rows.Where(i => i < testPartitionStart || testPartitionEnd <= i);
+      rows = rows.Where(i => i < testPartitionStart || testPartitionEnd <= i);
+      if (ValidRowIndicatorParameter.ActualValue != null) {
+        string indicatorVar = ValidRowIndicatorParameter.ActualValue.Value;
+        var problemData = ProblemDataParameter.ActualValue;
+        var indicatorRow = problemData.Dataset.GetReadOnlyDoubleValues(indicatorVar);
+        rows = rows.Where(r => !indicatorRow[r].IsAlmost(0.0));
+      }
+      return rows;
     }
 
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionLatexFormatter.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionLatexFormatter.cs	(revision 8797)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionLatexFormatter.cs	(revision 8798)
@@ -33,5 +33,6 @@
   [StorableClass]
   public sealed class SymbolicDataAnalysisExpressionLatexFormatter : NamedItem, ISymbolicExpressionTreeStringFormatter {
-    private List<double> constants;
+    private readonly List<double> constants;
+    private int targetCount;
     private int currentLag;
 
@@ -98,5 +99,5 @@
       } else if (node.Symbol is Division) {
         if (node.SubtreeCount == 1) {
-          strBuilder.Append(@" \cfrac{1}{");
+          strBuilder.Append(@" \cfrac{1");
         } else {
           strBuilder.Append(@" \cfrac{ ");
@@ -196,5 +197,5 @@
         strBuilder.Append(invokeNode.Symbol.FunctionName + @" \left( ");
       } else if (node.Symbol is StartSymbol) {
-        strBuilder.Append("Result & = ");
+        strBuilder.Append("target_" + (targetCount++) + "(t) & = ");
       } else if (node.Symbol is Argument) {
         var argSym = node.Symbol as Argument;
@@ -301,5 +302,6 @@
         strBuilder.Append(" , ");
       } else if (node.Symbol is StartSymbol) {
-        strBuilder.Append(@"\\" + Environment.NewLine + " & ");
+        strBuilder.Append(@"\\" + Environment.NewLine);
+        strBuilder.Append("target_" + (targetCount++) + "(t) & = ");
       } else if (node.Symbol is Power) {
         strBuilder.Append(@"\right) ^ { \operatorname{round} \left(");
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Grammars/FullFunctionalExpressionGrammar.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Grammars/FullFunctionalExpressionGrammar.cs	(revision 8797)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Grammars/FullFunctionalExpressionGrammar.cs	(revision 8798)
@@ -116,8 +116,11 @@
       var laggedVariable = new LaggedVariable();
       laggedVariable.InitialFrequency = 0.0;
+      var autoregressiveVariable = new AutoregressiveTargetVariable();
+      autoregressiveVariable.InitialFrequency = 0.0;
+      autoregressiveVariable.Enabled = false;
 
       var allSymbols = new List<Symbol>() { add, sub, mul, div, mean, sin, cos, tan, log, square, pow, sqrt, root, exp,
         airyA, airyB, bessel, cosineIntegral, dawson, erf, expIntegralEi, fresnelCosineIntegral, fresnelSineIntegral, gamma, hypCosineIntegral, hypSineIntegral, norm, psi, sineIntegral,
-        @if, gt, lt, and, or, not, timeLag, integral, derivative, constant, variableSymbol, laggedVariable, variableCondition };
+        @if, gt, lt, and, or, not, timeLag, integral, derivative, constant, variableSymbol, laggedVariable,autoregressiveVariable, variableCondition };
       var unaryFunctionSymbols = new List<Symbol>() { square, sqrt, sin, cos, tan, log, exp, not, timeLag, integral, derivative,
         airyA, airyB, bessel, cosineIntegral, dawson, erf, expIntegralEi, fresnelCosineIntegral, fresnelSineIntegral, gamma, hypCosineIntegral, hypSineIntegral, norm, psi, sineIntegral
@@ -126,5 +129,5 @@
       var binaryFunctionSymbols = new List<Symbol>() { pow, root, gt, lt, variableCondition };
       var ternarySymbols = new List<Symbol>() { add, sub, mul, div, mean, and, or };
-      var terminalSymbols = new List<Symbol>() { variableSymbol, constant, laggedVariable };
+      var terminalSymbols = new List<Symbol>() { variableSymbol, constant, laggedVariable, autoregressiveVariable };
 
       foreach (var symb in allSymbols)
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Grammars/TypeCoherentExpressionGrammar.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Grammars/TypeCoherentExpressionGrammar.cs	(revision 8797)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Grammars/TypeCoherentExpressionGrammar.cs	(revision 8798)
@@ -104,4 +104,5 @@
       var variableSymbol = new Variable();
       var laggedVariable = new LaggedVariable();
+      var autoregressiveVariable = new AutoregressiveTargetVariable();
       #endregion
 
@@ -122,5 +123,5 @@
       var conditionalSymbols = new GroupSymbol(ConditionalSymbolsName, new List<ISymbol> { conditionSymbols, comparisonSymbols, booleanOperationSymbols });
 
-      var timeSeriesSymbols = new GroupSymbol(TimeSeriesSymbolsName, new List<ISymbol> { timeLag, integral, derivative, laggedVariable });
+      var timeSeriesSymbols = new GroupSymbol(TimeSeriesSymbolsName, new List<ISymbol> { timeLag, integral, derivative, laggedVariable, autoregressiveVariable });
       #endregion
 
@@ -152,4 +153,5 @@
       SetSubtreeCount(derivative, 1, 1);
       SetSubtreeCount(laggedVariable, 0, 0);
+      SetSubtreeCount(autoregressiveVariable, 0, 0);
       #endregion
 
@@ -225,4 +227,17 @@
       Symbols.First(s => s.Name == TimeSeriesSymbolsName).Enabled = false;
     }
+
+    public void ConfigureAsDefaultTimeSeriesPrognosisGrammar() {
+      Symbols.First(s => s is Average).Enabled = false;
+      Symbols.First(s => s.Name == TrigonometricFunctionsName).Enabled = false;
+      Symbols.First(s => s.Name == PowerFunctionsName).Enabled = false;
+      Symbols.First(s => s.Name == ConditionalSymbolsName).Enabled = false;
+      Symbols.First(s => s.Name == SpecialFunctionsName).Enabled = false;
+
+      Symbols.First(s => s.Name == TimeSeriesSymbolsName).Enabled = true;
+      Symbols.First(s => s is Derivative).Enabled = false;
+      Symbols.First(s => s is Integral).Enabled = false;
+      Symbols.First(s => s is TimeLag).Enabled = false;
+    }
   }
 }
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj	(revision 8797)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj	(revision 8798)
@@ -141,6 +141,9 @@
     <Compile Include="Crossovers\SymbolicDataAnalysisExpressionSemanticSimilarityCrossover.cs" />
     <Compile Include="Interfaces\ISymbolicDataAnalysisExpressionCrossover.cs" />
+    <Compile Include="Interpreter\InterpreterState.cs" />
+    <Compile Include="Interpreter\OpCodes.cs" />
+    <Compile Include="Interpreter\SymbolicDataAnalysisExpressionTreeILEmittingInterpreter.cs" />
+    <Compile Include="Interpreter\SymbolicDataAnalysisExpressionTreeInterpreter.cs" />
     <Compile Include="Plugin.cs" />
-    <Compile Include="SymbolicDataAnalysisExpressionTreeILEmittingInterpreter.cs" />
     <Compile Include="Formatters\SymbolicDataAnalysisExpressionLatexFormatter.cs" />
     <Compile Include="Formatters\SymbolicDataAnalysisExpressionMATLABFormatter.cs" />
@@ -160,9 +163,9 @@
     <Compile Include="Interfaces\ISymbolicDataAnalysisAnalyzer.cs" />
     <Compile Include="SymbolicDataAnalysisSingleObjectiveProblem.cs" />
-    <Compile Include="SymbolicDataAnalysisExpressionTreeInterpreter.cs" />
     <Compile Include="SymbolicDataAnalysisExpressionTreeSimplifier.cs" />
     <Compile Include="SymbolicDataAnalysisProblem.cs" />
     <Compile Include="Symbols\Addition.cs" />
     <Compile Include="Symbols\And.cs" />
+    <Compile Include="Symbols\AutoregressiveVariable.cs" />
     <Compile Include="Symbols\Average.cs" />
     <Compile Include="Symbols\Constant.cs" />
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/InterpreterState.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/InterpreterState.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/InterpreterState.cs	(revision 8798)
@@ -0,0 +1,93 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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 HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+  public class InterpreterState {
+    private readonly double[] argumentStack;
+    private int argumentStackPointer;
+    private readonly Instruction[] code;
+
+    public int ProgramCounter { get; set; }
+    public bool InLaggedContext { get; set; }
+
+    public InterpreterState(Instruction[] code, int argumentStackSize) {
+      this.code = code;
+      this.ProgramCounter = 0;
+      this.InLaggedContext = false;
+      if (argumentStackSize > 0) {
+        this.argumentStack = new double[argumentStackSize];
+      }
+      this.argumentStackPointer = 0;
+    }
+
+    public void Reset() {
+      this.ProgramCounter = 0;
+      this.argumentStackPointer = 0;
+      this.InLaggedContext = false;
+    }
+
+    public Instruction NextInstruction() {
+      return code[ProgramCounter++];
+    }
+    // skips a whole branch
+    public void SkipInstructions() {
+      int i = 1;
+      while (i > 0) {
+        i += NextInstruction().nArguments;
+        i--;
+      }
+    }
+
+    private void Push(double val) {
+      argumentStack[argumentStackPointer++] = val;
+    }
+    private double Pop() {
+      return argumentStack[--argumentStackPointer];
+    }
+
+    public void CreateStackFrame(double[] argValues) {
+      // push in reverse order to make indexing easier
+      for (int i = argValues.Length - 1; i >= 0; i--) {
+        argumentStack[argumentStackPointer++] = argValues[i];
+      }
+      Push(argValues.Length);
+    }
+
+    public void RemoveStackFrame() {
+      int size = (int)Pop();
+      argumentStackPointer -= size;
+    }
+
+    public double GetStackFrameValue(ushort index) {
+      // layout of stack:
+      // [0]   <- argumentStackPointer
+      // [StackFrameSize = N + 1]
+      // [Arg0] <- argumentStackPointer - 2 - 0
+      // [Arg1] <- argumentStackPointer - 2 - 1
+      // [...]
+      // [ArgN] <- argumentStackPointer - 2 - N
+      // <Begin of stack frame>
+      return argumentStack[argumentStackPointer - index - 2];
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/OpCodes.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/OpCodes.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/OpCodes.cs	(revision 8798)
@@ -0,0 +1,139 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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 HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+  public static class OpCodes {
+    public const byte Add = 1;
+    public const byte Sub = 2;
+    public const byte Mul = 3;
+    public const byte Div = 4;
+
+    public const byte Sin = 5;
+    public const byte Cos = 6;
+    public const byte Tan = 7;
+
+    public const byte Log = 8;
+    public const byte Exp = 9;
+
+    public const byte IfThenElse = 10;
+
+    public const byte GT = 11;
+    public const byte LT = 12;
+
+    public const byte AND = 13;
+    public const byte OR = 14;
+    public const byte NOT = 15;
+
+
+    public const byte Average = 16;
+
+    public const byte Call = 17;
+
+    public const byte Variable = 18;
+    public const byte LagVariable = 19;
+    public const byte Constant = 20;
+    public const byte Arg = 21;
+
+    public const byte Power = 22;
+    public const byte Root = 23;
+    public const byte TimeLag = 24;
+    public const byte Integral = 25;
+    public const byte Derivative = 26;
+
+    public const byte VariableCondition = 27;
+
+    public const byte Square = 28;
+    public const byte SquareRoot = 29;
+    public const byte Gamma = 30;
+    public const byte Psi = 31;
+    public const byte Dawson = 32;
+    public const byte ExponentialIntegralEi = 33;
+    public const byte CosineIntegral = 34;
+    public const byte SineIntegral = 35;
+    public const byte HyperbolicCosineIntegral = 36;
+    public const byte HyperbolicSineIntegral = 37;
+    public const byte FresnelCosineIntegral = 38;
+    public const byte FresnelSineIntegral = 39;
+    public const byte AiryA = 40;
+    public const byte AiryB = 41;
+    public const byte Norm = 42;
+    public const byte Erf = 43;
+    public const byte Bessel = 44;
+
+    private static Dictionary<Type, byte> symbolToOpcode = new Dictionary<Type, byte>() {
+       { typeof(Addition), OpCodes.Add },
+      { typeof(Subtraction), OpCodes.Sub },
+      { typeof(Multiplication), OpCodes.Mul },
+      { typeof(Division), OpCodes.Div },
+      { typeof(Sine), OpCodes.Sin },
+      { typeof(Cosine), OpCodes.Cos },
+      { typeof(Tangent), OpCodes.Tan },
+      { typeof(Logarithm), OpCodes.Log },
+      { typeof(Exponential), OpCodes.Exp },
+      { typeof(IfThenElse), OpCodes.IfThenElse },
+      { typeof(GreaterThan), OpCodes.GT },
+      { typeof(LessThan), OpCodes.LT },
+      { typeof(And), OpCodes.AND },
+      { typeof(Or), OpCodes.OR },
+      { typeof(Not), OpCodes.NOT},
+      { typeof(Average), OpCodes.Average},
+      { typeof(InvokeFunction), OpCodes.Call },
+      { typeof(Variable), OpCodes.Variable },
+      { typeof(LaggedVariable), OpCodes.LagVariable },
+      { typeof(AutoregressiveTargetVariable),OpCodes.LagVariable},
+      { typeof(Constant), OpCodes.Constant },
+      { typeof(Argument), OpCodes.Arg },
+      { typeof(Power),OpCodes.Power},
+      { typeof(Root),OpCodes.Root},
+      { typeof(TimeLag), OpCodes.TimeLag}, 
+      { typeof(Integral), OpCodes.Integral},
+      { typeof(Derivative), OpCodes.Derivative},
+      { typeof(VariableCondition),OpCodes.VariableCondition},
+      { typeof(Square),OpCodes.Square},
+      { typeof(SquareRoot),OpCodes.SquareRoot},
+      { typeof(Gamma), OpCodes.Gamma },
+      { typeof(Psi), OpCodes.Psi },
+      { typeof(Dawson), OpCodes.Dawson},
+      { typeof(ExponentialIntegralEi), OpCodes.ExponentialIntegralEi },
+      { typeof(CosineIntegral), OpCodes.CosineIntegral },
+      { typeof(SineIntegral), OpCodes.SineIntegral },
+      { typeof(HyperbolicCosineIntegral), OpCodes.HyperbolicCosineIntegral },
+      { typeof(HyperbolicSineIntegral), OpCodes.HyperbolicSineIntegral },
+      { typeof(FresnelCosineIntegral), OpCodes.FresnelCosineIntegral },
+      { typeof(FresnelSineIntegral), OpCodes.FresnelSineIntegral },
+      { typeof(AiryA), OpCodes.AiryA },
+      { typeof(AiryB), OpCodes.AiryB },
+      { typeof(Norm), OpCodes.Norm},
+      { typeof(Erf), OpCodes.Erf},
+      { typeof(Bessel), OpCodes.Bessel}   
+    };
+
+    public static byte MapSymbolToOpCode(ISymbolicExpressionTreeNode treeNode) {
+      byte opCode;
+      if (symbolToOpcode.TryGetValue(treeNode.Symbol.GetType(), out opCode)) return opCode;
+      else throw new NotSupportedException("Symbol: " + treeNode.Symbol);
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeILEmittingInterpreter.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeILEmittingInterpreter.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeILEmittingInterpreter.cs	(revision 8798)
@@ -0,0 +1,734 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Reflection;
+using System.Reflection.Emit;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+  [StorableClass]
+  [Item("SymbolicDataAnalysisExpressionTreeILEmittingInterpreter", "Interpreter for symbolic expression trees.")]
+  public sealed class SymbolicDataAnalysisExpressionTreeILEmittingInterpreter : ParameterizedNamedItem, ISymbolicDataAnalysisExpressionTreeInterpreter {
+    private static readonly Type thisType = typeof(SymbolicDataAnalysisExpressionTreeILEmittingInterpreter);
+    internal delegate double CompiledFunction(int sampleIndex, IList<double>[] columns);
+
+    #region method infos
+    private static MethodInfo listGetValue = typeof(IList<double>).GetProperty("Item", new Type[] { typeof(int) }).GetGetMethod();
+
+    private static MethodInfo cos = typeof(Math).GetMethod("Cos", new Type[] { typeof(double) });
+    private static MethodInfo sin = typeof(Math).GetMethod("Sin", new Type[] { typeof(double) });
+    private static MethodInfo tan = typeof(Math).GetMethod("Tan", new Type[] { typeof(double) });
+    private static MethodInfo exp = typeof(Math).GetMethod("Exp", new Type[] { typeof(double) });
+    private static MethodInfo log = typeof(Math).GetMethod("Log", new Type[] { typeof(double) });
+    private static MethodInfo power = typeof(Math).GetMethod("Pow", new Type[] { typeof(double), typeof(double) });
+    private static MethodInfo round = typeof(Math).GetMethod("Round", new Type[] { typeof(double) });
+    private static MethodInfo sqrt = typeof(Math).GetMethod("Sqrt", new Type[] { typeof(double) });
+
+    private static MethodInfo airyA = thisType.GetMethod("AiryA", new Type[] { typeof(double) });
+    private static MethodInfo airyB = thisType.GetMethod("AiryB", new Type[] { typeof(double) });
+    private static MethodInfo gamma = thisType.GetMethod("Gamma", new Type[] { typeof(double) });
+    private static MethodInfo psi = thisType.GetMethod("Psi", new Type[] { typeof(double) });
+    private static MethodInfo dawson = thisType.GetMethod("Dawson", new Type[] { typeof(double) });
+    private static MethodInfo expIntegralEi = thisType.GetMethod("ExpIntegralEi", new Type[] { typeof(double) });
+    private static MethodInfo sinIntegral = thisType.GetMethod("SinIntegral", new Type[] { typeof(double) });
+    private static MethodInfo cosIntegral = thisType.GetMethod("CosIntegral", new Type[] { typeof(double) });
+    private static MethodInfo hypSinIntegral = thisType.GetMethod("HypSinIntegral", new Type[] { typeof(double) });
+    private static MethodInfo hypCosIntegral = thisType.GetMethod("HypCosIntegral", new Type[] { typeof(double) });
+    private static MethodInfo fresnelCosIntegral = thisType.GetMethod("FresnelCosIntegral", new Type[] { typeof(double) });
+    private static MethodInfo fresnelSinIntegral = thisType.GetMethod("FresnelSinIntegral", new Type[] { typeof(double) });
+    private static MethodInfo norm = thisType.GetMethod("Norm", new Type[] { typeof(double) });
+    private static MethodInfo erf = thisType.GetMethod("Erf", new Type[] { typeof(double) });
+    private static MethodInfo bessel = thisType.GetMethod("Bessel", new Type[] { typeof(double) });
+    #endregion
+
+    private const string CheckExpressionsWithIntervalArithmeticParameterName = "CheckExpressionsWithIntervalArithmetic";
+    private const string EvaluatedSolutionsParameterName = "EvaluatedSolutions";
+
+    public override bool CanChangeName {
+      get { return false; }
+    }
+
+    public override bool CanChangeDescription {
+      get { return false; }
+    }
+
+    #region parameter properties
+
+    public IValueParameter<BoolValue> CheckExpressionsWithIntervalArithmeticParameter {
+      get { return (IValueParameter<BoolValue>)Parameters[CheckExpressionsWithIntervalArithmeticParameterName]; }
+    }
+
+    public IValueParameter<IntValue> EvaluatedSolutionsParameter {
+      get { return (IValueParameter<IntValue>)Parameters[EvaluatedSolutionsParameterName]; }
+    }
+
+    #endregion
+
+    #region properties
+
+    public BoolValue CheckExpressionsWithIntervalArithmetic {
+      get { return CheckExpressionsWithIntervalArithmeticParameter.Value; }
+      set { CheckExpressionsWithIntervalArithmeticParameter.Value = value; }
+    }
+
+    public IntValue EvaluatedSolutions {
+      get { return EvaluatedSolutionsParameter.Value; }
+      set { EvaluatedSolutionsParameter.Value = value; }
+    }
+
+    #endregion
+
+
+    [StorableConstructor]
+    private SymbolicDataAnalysisExpressionTreeILEmittingInterpreter(bool deserializing) : base(deserializing) { }
+
+    private SymbolicDataAnalysisExpressionTreeILEmittingInterpreter(SymbolicDataAnalysisExpressionTreeILEmittingInterpreter original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SymbolicDataAnalysisExpressionTreeILEmittingInterpreter(this, cloner);
+    }
+
+    public SymbolicDataAnalysisExpressionTreeILEmittingInterpreter()
+      : base("SymbolicDataAnalysisExpressionTreeILEmittingInterpreter", "Interpreter for symbolic expression trees.") {
+      Parameters.Add(new ValueParameter<BoolValue>(CheckExpressionsWithIntervalArithmeticParameterName, "Switch that determines if the interpreter checks the validity of expressions with interval arithmetic before evaluating the expression.", new BoolValue(false)));
+      Parameters.Add(new ValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0)));
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (!Parameters.ContainsKey(EvaluatedSolutionsParameterName))
+        Parameters.Add(new ValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0)));
+    }
+
+    #region IStatefulItem
+
+    public void InitializeState() {
+      EvaluatedSolutions.Value = 0;
+    }
+
+    public void ClearState() {
+      EvaluatedSolutions.Value = 0;
+    }
+
+    #endregion
+
+    public IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, IEnumerable<int> rows) {
+      if (CheckExpressionsWithIntervalArithmetic.Value)
+        throw new NotSupportedException("Interval arithmetic is not yet supported in the symbolic data analysis interpreter.");
+
+      EvaluatedSolutions.Value++; // increment the evaluated solutions counter
+      var state = PrepareInterpreterState(tree, dataset);
+
+      Type[] methodArgs = { typeof(int), typeof(IList<double>[]) };
+      DynamicMethod testFun = new DynamicMethod("TestFun", typeof(double), methodArgs, typeof(SymbolicDataAnalysisExpressionTreeILEmittingInterpreter).Module);
+
+      ILGenerator il = testFun.GetILGenerator();
+      CompileInstructions(il, state, dataset);
+      il.Emit(System.Reflection.Emit.OpCodes.Conv_R8);
+      il.Emit(System.Reflection.Emit.OpCodes.Ret);
+      var function = (CompiledFunction)testFun.CreateDelegate(typeof(CompiledFunction));
+
+      IList<double>[] columns = dataset.DoubleVariables.Select(v => dataset.GetReadOnlyDoubleValues(v)).ToArray();
+
+      foreach (var row in rows) {
+        yield return function(row, columns);
+      }
+    }
+
+    private InterpreterState PrepareInterpreterState(ISymbolicExpressionTree tree, Dataset dataset) {
+      Instruction[] code = SymbolicExpressionTreeCompiler.Compile(tree, OpCodes.MapSymbolToOpCode);
+      Dictionary<string, int> doubleVariableNames = dataset.DoubleVariables.Select((x, i) => new { x, i }).ToDictionary(e => e.x, e => e.i);
+      int necessaryArgStackSize = 0;
+      foreach (Instruction instr in code) {
+        if (instr.opCode == OpCodes.Variable) {
+          var variableTreeNode = (VariableTreeNode)instr.dynamicNode;
+          instr.iArg0 = doubleVariableNames[variableTreeNode.VariableName];
+        } else if (instr.opCode == OpCodes.LagVariable) {
+          var laggedVariableTreeNode = (LaggedVariableTreeNode)instr.dynamicNode;
+          instr.iArg0 = doubleVariableNames[laggedVariableTreeNode.VariableName];
+        } else if (instr.opCode == OpCodes.VariableCondition) {
+          var variableConditionTreeNode = (VariableConditionTreeNode)instr.dynamicNode;
+          instr.iArg0 = doubleVariableNames[variableConditionTreeNode.VariableName];
+        } else if (instr.opCode == OpCodes.Call) {
+          necessaryArgStackSize += instr.nArguments + 1;
+        }
+      }
+      return new InterpreterState(code, necessaryArgStackSize);
+    }
+
+    private void CompileInstructions(ILGenerator il, InterpreterState state, Dataset ds) {
+      Instruction currentInstr = state.NextInstruction();
+      int nArgs = currentInstr.nArguments;
+
+      switch (currentInstr.opCode) {
+        case OpCodes.Add: {
+            if (nArgs > 0) {
+              CompileInstructions(il, state, ds);
+            }
+            for (int i = 1; i < nArgs; i++) {
+              CompileInstructions(il, state, ds);
+              il.Emit(System.Reflection.Emit.OpCodes.Add);
+            }
+            return;
+          }
+        case OpCodes.Sub: {
+            if (nArgs == 1) {
+              CompileInstructions(il, state, ds);
+              il.Emit(System.Reflection.Emit.OpCodes.Neg);
+              return;
+            }
+            if (nArgs > 0) {
+              CompileInstructions(il, state, ds);
+            }
+            for (int i = 1; i < nArgs; i++) {
+              CompileInstructions(il, state, ds);
+              il.Emit(System.Reflection.Emit.OpCodes.Sub);
+            }
+            return;
+          }
+        case OpCodes.Mul: {
+            if (nArgs > 0) {
+              CompileInstructions(il, state, ds);
+            }
+            for (int i = 1; i < nArgs; i++) {
+              CompileInstructions(il, state, ds);
+              il.Emit(System.Reflection.Emit.OpCodes.Mul);
+            }
+            return;
+          }
+        case OpCodes.Div: {
+            if (nArgs == 1) {
+              il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 1.0);
+              CompileInstructions(il, state, ds);
+              il.Emit(System.Reflection.Emit.OpCodes.Div);
+              return;
+            }
+            if (nArgs > 0) {
+              CompileInstructions(il, state, ds);
+            }
+            for (int i = 1; i < nArgs; i++) {
+              CompileInstructions(il, state, ds);
+              il.Emit(System.Reflection.Emit.OpCodes.Div);
+            }
+            return;
+          }
+        case OpCodes.Average: {
+            CompileInstructions(il, state, ds);
+            for (int i = 1; i < nArgs; i++) {
+              CompileInstructions(il, state, ds);
+              il.Emit(System.Reflection.Emit.OpCodes.Add);
+            }
+            il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, nArgs);
+            il.Emit(System.Reflection.Emit.OpCodes.Div);
+            return;
+          }
+        case OpCodes.Cos: {
+            CompileInstructions(il, state, ds);
+            il.Emit(System.Reflection.Emit.OpCodes.Call, cos);
+            return;
+          }
+        case OpCodes.Sin: {
+            CompileInstructions(il, state, ds);
+            il.Emit(System.Reflection.Emit.OpCodes.Call, sin);
+            return;
+          }
+        case OpCodes.Tan: {
+            CompileInstructions(il, state, ds);
+            il.Emit(System.Reflection.Emit.OpCodes.Call, tan);
+            return;
+          }
+        case OpCodes.Power: {
+            CompileInstructions(il, state, ds);
+            CompileInstructions(il, state, ds);
+            il.Emit(System.Reflection.Emit.OpCodes.Call, round);
+            il.Emit(System.Reflection.Emit.OpCodes.Call, power);
+            return;
+          }
+        case OpCodes.Root: {
+            CompileInstructions(il, state, ds);
+            il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 1.0); // 1 / round(...)
+            CompileInstructions(il, state, ds);
+            il.Emit(System.Reflection.Emit.OpCodes.Call, round);
+            il.Emit(System.Reflection.Emit.OpCodes.Div);
+            il.Emit(System.Reflection.Emit.OpCodes.Call, power);
+            return;
+          }
+        case OpCodes.Exp: {
+            CompileInstructions(il, state, ds);
+            il.Emit(System.Reflection.Emit.OpCodes.Call, exp);
+            return;
+          }
+        case OpCodes.Log: {
+            CompileInstructions(il, state, ds);
+            il.Emit(System.Reflection.Emit.OpCodes.Call, log);
+            return;
+          }
+        case OpCodes.Square: {
+            CompileInstructions(il, state, ds);
+            il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 2.0);
+            il.Emit(System.Reflection.Emit.OpCodes.Call, power);
+            return;
+          }
+        case OpCodes.SquareRoot: {
+            CompileInstructions(il, state, ds);
+            il.Emit(System.Reflection.Emit.OpCodes.Call, sqrt);
+            return;
+          }
+        case OpCodes.AiryA: {
+            CompileInstructions(il, state, ds);
+            il.Emit(System.Reflection.Emit.OpCodes.Call, airyA);
+            return;
+          }
+        case OpCodes.AiryB: {
+            CompileInstructions(il, state, ds);
+            il.Emit(System.Reflection.Emit.OpCodes.Call, airyB);
+            return;
+          }
+        case OpCodes.Bessel: {
+            CompileInstructions(il, state, ds);
+            il.Emit(System.Reflection.Emit.OpCodes.Call, bessel);
+            return;
+          }
+        case OpCodes.CosineIntegral: {
+            CompileInstructions(il, state, ds);
+            il.Emit(System.Reflection.Emit.OpCodes.Call, cosIntegral);
+            return;
+          }
+        case OpCodes.Dawson: {
+            CompileInstructions(il, state, ds);
+            il.Emit(System.Reflection.Emit.OpCodes.Call, dawson);
+            return;
+          }
+        case OpCodes.Erf: {
+            CompileInstructions(il, state, ds);
+            il.Emit(System.Reflection.Emit.OpCodes.Call, erf);
+            return;
+          }
+        case OpCodes.ExponentialIntegralEi: {
+            CompileInstructions(il, state, ds);
+            il.Emit(System.Reflection.Emit.OpCodes.Call, expIntegralEi);
+            return;
+          }
+        case OpCodes.FresnelCosineIntegral: {
+            CompileInstructions(il, state, ds);
+            il.Emit(System.Reflection.Emit.OpCodes.Call, fresnelCosIntegral);
+            return;
+          }
+        case OpCodes.FresnelSineIntegral: {
+            CompileInstructions(il, state, ds);
+            il.Emit(System.Reflection.Emit.OpCodes.Call, fresnelSinIntegral);
+            return;
+          }
+        case OpCodes.Gamma: {
+            CompileInstructions(il, state, ds);
+            il.Emit(System.Reflection.Emit.OpCodes.Call, gamma);
+            return;
+          }
+        case OpCodes.HyperbolicCosineIntegral: {
+            CompileInstructions(il, state, ds);
+            il.Emit(System.Reflection.Emit.OpCodes.Call, hypCosIntegral);
+            return;
+          }
+        case OpCodes.HyperbolicSineIntegral: {
+            CompileInstructions(il, state, ds);
+            il.Emit(System.Reflection.Emit.OpCodes.Call, hypSinIntegral);
+            return;
+          }
+        case OpCodes.Norm: {
+            CompileInstructions(il, state, ds);
+            il.Emit(System.Reflection.Emit.OpCodes.Call, norm);
+            return;
+          }
+        case OpCodes.Psi: {
+            CompileInstructions(il, state, ds);
+            il.Emit(System.Reflection.Emit.OpCodes.Call, psi);
+            return;
+          }
+        case OpCodes.SineIntegral: {
+            CompileInstructions(il, state, ds);
+            il.Emit(System.Reflection.Emit.OpCodes.Call, sinIntegral);
+            return;
+          }
+        case OpCodes.IfThenElse: {
+            Label end = il.DefineLabel();
+            Label c1 = il.DefineLabel();
+            CompileInstructions(il, state, ds);
+            il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_0); // > 0
+            il.Emit(System.Reflection.Emit.OpCodes.Cgt);
+            il.Emit(System.Reflection.Emit.OpCodes.Brfalse, c1);
+            CompileInstructions(il, state, ds);
+            il.Emit(System.Reflection.Emit.OpCodes.Br, end);
+            il.MarkLabel(c1);
+            CompileInstructions(il, state, ds);
+            il.MarkLabel(end);
+            return;
+          }
+        case OpCodes.AND: {
+            Label falseBranch = il.DefineLabel();
+            Label end = il.DefineLabel();
+            CompileInstructions(il, state, ds);
+            for (int i = 1; i < nArgs; i++) {
+              il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_0); // > 0
+              il.Emit(System.Reflection.Emit.OpCodes.Cgt);
+              il.Emit(System.Reflection.Emit.OpCodes.Brfalse, falseBranch);
+              CompileInstructions(il, state, ds);
+            }
+            il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_0); // > 0
+            il.Emit(System.Reflection.Emit.OpCodes.Cgt);
+            il.Emit(System.Reflection.Emit.OpCodes.Brfalse, falseBranch);
+            il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 1.0); // 1
+            il.Emit(System.Reflection.Emit.OpCodes.Br, end);
+            il.MarkLabel(falseBranch);
+            il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 1.0); // -1
+            il.Emit(System.Reflection.Emit.OpCodes.Neg);
+            il.MarkLabel(end);
+            return;
+          }
+        case OpCodes.OR: {
+            Label trueBranch = il.DefineLabel();
+            Label end = il.DefineLabel();
+            Label resultBranch = il.DefineLabel();
+            CompileInstructions(il, state, ds);
+            for (int i = 1; i < nArgs; i++) {
+              Label nextArgBranch = il.DefineLabel();
+              // complex definition because of special properties of NaN  
+              il.Emit(System.Reflection.Emit.OpCodes.Dup);
+              il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_0); // <= 0        
+              il.Emit(System.Reflection.Emit.OpCodes.Ble, nextArgBranch);
+              il.Emit(System.Reflection.Emit.OpCodes.Br, resultBranch);
+              il.MarkLabel(nextArgBranch);
+              il.Emit(System.Reflection.Emit.OpCodes.Pop);
+              CompileInstructions(il, state, ds);
+            }
+            il.MarkLabel(resultBranch);
+            il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_0); // > 0
+            il.Emit(System.Reflection.Emit.OpCodes.Cgt);
+            il.Emit(System.Reflection.Emit.OpCodes.Brtrue, trueBranch);
+            il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 1.0); // -1
+            il.Emit(System.Reflection.Emit.OpCodes.Neg);
+            il.Emit(System.Reflection.Emit.OpCodes.Br, end);
+            il.MarkLabel(trueBranch);
+            il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 1.0); // 1
+            il.MarkLabel(end);
+            return;
+          }
+        case OpCodes.NOT: {
+            CompileInstructions(il, state, ds);
+            il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_0); // > 0
+            il.Emit(System.Reflection.Emit.OpCodes.Cgt);
+            il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 2.0); // * 2
+            il.Emit(System.Reflection.Emit.OpCodes.Mul);
+            il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 1.0); // - 1
+            il.Emit(System.Reflection.Emit.OpCodes.Sub);
+            il.Emit(System.Reflection.Emit.OpCodes.Neg); // * -1
+            return;
+          }
+        case OpCodes.GT: {
+            CompileInstructions(il, state, ds);
+            CompileInstructions(il, state, ds);
+
+            il.Emit(System.Reflection.Emit.OpCodes.Cgt); // 1 (>) / 0 (otherwise)
+            il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 2.0); // * 2
+            il.Emit(System.Reflection.Emit.OpCodes.Mul);
+            il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 1.0); // - 1
+            il.Emit(System.Reflection.Emit.OpCodes.Sub);
+            return;
+          }
+        case OpCodes.LT: {
+            CompileInstructions(il, state, ds);
+            CompileInstructions(il, state, ds);
+            il.Emit(System.Reflection.Emit.OpCodes.Clt);
+            il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 2.0); // * 2
+            il.Emit(System.Reflection.Emit.OpCodes.Mul);
+            il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 1.0); // - 1
+            il.Emit(System.Reflection.Emit.OpCodes.Sub);
+            return;
+          }
+        case OpCodes.TimeLag: {
+            LaggedTreeNode laggedTreeNode = (LaggedTreeNode)currentInstr.dynamicNode;
+            il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); // row -= lag
+            il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, laggedTreeNode.Lag);
+            il.Emit(System.Reflection.Emit.OpCodes.Add);
+            il.Emit(System.Reflection.Emit.OpCodes.Starg, 0);
+            var prevLaggedContext = state.InLaggedContext;
+            state.InLaggedContext = true;
+            CompileInstructions(il, state, ds);
+            il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); // row += lag
+            il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, laggedTreeNode.Lag);
+            il.Emit(System.Reflection.Emit.OpCodes.Sub);
+            il.Emit(System.Reflection.Emit.OpCodes.Starg, 0);
+            state.InLaggedContext = prevLaggedContext;
+            return;
+          }
+        case OpCodes.Integral: {
+            int savedPc = state.ProgramCounter;
+            LaggedTreeNode laggedTreeNode = (LaggedTreeNode)currentInstr.dynamicNode;
+            il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); // row -= lag
+            il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, laggedTreeNode.Lag);
+            il.Emit(System.Reflection.Emit.OpCodes.Add);
+            il.Emit(System.Reflection.Emit.OpCodes.Starg, 0);
+            var prevLaggedContext = state.InLaggedContext;
+            state.InLaggedContext = true;
+            CompileInstructions(il, state, ds);
+            for (int l = laggedTreeNode.Lag; l < 0; l++) {
+              il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); // row += lag
+              il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_1);
+              il.Emit(System.Reflection.Emit.OpCodes.Add);
+              il.Emit(System.Reflection.Emit.OpCodes.Starg, 0);
+              state.ProgramCounter = savedPc;
+              CompileInstructions(il, state, ds);
+              il.Emit(System.Reflection.Emit.OpCodes.Add);
+            }
+            state.InLaggedContext = prevLaggedContext;
+            return;
+          }
+
+        //mkommend: derivate calculation taken from: 
+        //http://www.holoborodko.com/pavel/numerical-methods/numerical-derivative/smooth-low-noise-differentiators/
+        //one sided smooth differentiatior, N = 4
+        // y' = 1/8h (f_i + 2f_i-1, -2 f_i-3 - f_i-4)
+        case OpCodes.Derivative: {
+            int savedPc = state.ProgramCounter;
+            CompileInstructions(il, state, ds);
+            il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); // row --
+            il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_M1);
+            il.Emit(System.Reflection.Emit.OpCodes.Add);
+            il.Emit(System.Reflection.Emit.OpCodes.Starg, 0);
+            state.ProgramCounter = savedPc;
+            var prevLaggedContext = state.InLaggedContext;
+            state.InLaggedContext = true;
+            CompileInstructions(il, state, ds);
+            il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 2.0); // f_0 + 2 * f_1
+            il.Emit(System.Reflection.Emit.OpCodes.Mul);
+            il.Emit(System.Reflection.Emit.OpCodes.Add);
+
+            il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); // row -=2
+            il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_2);
+            il.Emit(System.Reflection.Emit.OpCodes.Sub);
+            il.Emit(System.Reflection.Emit.OpCodes.Starg, 0);
+            state.ProgramCounter = savedPc;
+            CompileInstructions(il, state, ds);
+            il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 2.0); // f_0 + 2 * f_1 - 2 * f_3
+            il.Emit(System.Reflection.Emit.OpCodes.Mul);
+            il.Emit(System.Reflection.Emit.OpCodes.Sub);
+
+            il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); // row --
+            il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_M1);
+            il.Emit(System.Reflection.Emit.OpCodes.Add);
+            il.Emit(System.Reflection.Emit.OpCodes.Starg, 0);
+            state.ProgramCounter = savedPc;
+            CompileInstructions(il, state, ds);
+            il.Emit(System.Reflection.Emit.OpCodes.Sub); // f_0 + 2 * f_1 - 2 * f_3 - f_4
+            il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 8.0); // / 8
+            il.Emit(System.Reflection.Emit.OpCodes.Div);
+
+            il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); // row +=4
+            il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_4);
+            il.Emit(System.Reflection.Emit.OpCodes.Add);
+            il.Emit(System.Reflection.Emit.OpCodes.Starg, 0);
+            state.InLaggedContext = prevLaggedContext;
+            return;
+          }
+        case OpCodes.Call: {
+            throw new NotSupportedException(
+              "Automatically defined functions are not supported by the SymbolicDataAnalysisTreeILEmittingInterpreter. Either turn of ADFs or change the interpeter.");
+          }
+        case OpCodes.Arg: {
+            throw new NotSupportedException(
+              "Automatically defined functions are not supported by the SymbolicDataAnalysisTreeILEmittingInterpreter. Either turn of ADFs or change the interpeter.");
+          }
+        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.Call, listGetValue);
+              il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, varNode.Weight); // load weight
+              il.Emit(System.Reflection.Emit.OpCodes.Mul);
+            } else {
+              var nanResult = il.DefineLabel();
+              var normalResult = il.DefineLabel();
+              il.Emit(System.Reflection.Emit.OpCodes.Dup);
+              il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_0);
+              il.Emit(System.Reflection.Emit.OpCodes.Blt, nanResult);
+              il.Emit(System.Reflection.Emit.OpCodes.Dup);
+              il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, ds.Rows);
+              il.Emit(System.Reflection.Emit.OpCodes.Bge, nanResult);
+              il.Emit(System.Reflection.Emit.OpCodes.Call, listGetValue);
+              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); // rowIndex
+              il.Emit(System.Reflection.Emit.OpCodes.Pop); // column reference
+              il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, double.NaN);
+              il.MarkLabel(normalResult);
+            }
+            return;
+          }
+        case OpCodes.LagVariable: {
+            var nanResult = il.DefineLabel();
+            var normalResult = 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
+            il.Emit(System.Reflection.Emit.OpCodes.Add); // actualRowIndex = rowIndex + sampleOffset
+            il.Emit(System.Reflection.Emit.OpCodes.Dup);
+            il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_0);
+            il.Emit(System.Reflection.Emit.OpCodes.Blt, nanResult);
+            il.Emit(System.Reflection.Emit.OpCodes.Dup);
+            il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, ds.Rows);
+            il.Emit(System.Reflection.Emit.OpCodes.Bge, nanResult);
+            il.Emit(System.Reflection.Emit.OpCodes.Call, listGetValue);
+            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.Ldc_R8, double.NaN);
+            il.MarkLabel(normalResult);
+            return;
+          }
+        case OpCodes.Constant: {
+            ConstantTreeNode constNode = (ConstantTreeNode)currentInstr.dynamicNode;
+            il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, constNode.Value);
+            return;
+          }
+
+        //mkommend: this symbol uses the logistic function f(x) = 1 / (1 + e^(-alpha * x) ) 
+        //to determine the relative amounts of the true and false branch see http://en.wikipedia.org/wiki/Logistic_function
+        case OpCodes.VariableCondition: {
+            throw new NotSupportedException("Interpretation of symbol " + currentInstr.dynamicNode.Symbol.Name +
+                                            " is not supported by the SymbolicDataAnalysisTreeILEmittingInterpreter");
+          }
+        default:
+          throw new NotSupportedException("Interpretation of symbol " + currentInstr.dynamicNode.Symbol.Name +
+                                          " is not supported by the SymbolicDataAnalysisTreeILEmittingInterpreter");
+      }
+    }
+
+    public static double AiryA(double x) {
+      if (double.IsNaN(x)) return double.NaN;
+      double ai, aip, bi, bip;
+      alglib.airy(x, out ai, out aip, out bi, out bip);
+      return ai;
+    }
+
+    public static double AiryB(double x) {
+      if (double.IsNaN(x)) return double.NaN;
+      double ai, aip, bi, bip;
+      alglib.airy(x, out ai, out aip, out bi, out bip);
+      return bi;
+    }
+    public static double Dawson(double x) {
+      if (double.IsNaN(x)) return double.NaN;
+      return alglib.dawsonintegral(x);
+    }
+
+    public static double Gamma(double x) {
+      if (double.IsNaN(x)) return double.NaN;
+      return alglib.gammafunction(x);
+    }
+
+    public static double Psi(double x) {
+      if (double.IsNaN(x)) return double.NaN;
+      else if (x <= 0 && (Math.Floor(x) - x).IsAlmost(0)) return double.NaN;
+      return alglib.psi(x);
+    }
+
+    public static double ExpIntegralEi(double x) {
+      if (double.IsNaN(x)) return double.NaN;
+      return alglib.exponentialintegralei(x);
+    }
+
+    public static double SinIntegral(double x) {
+      if (double.IsNaN(x)) return double.NaN;
+      double si, ci;
+      alglib.sinecosineintegrals(x, out si, out ci);
+      return si;
+    }
+
+    public static double CosIntegral(double x) {
+      if (double.IsNaN(x)) return double.NaN;
+      double si, ci;
+      alglib.sinecosineintegrals(x, out si, out ci);
+      return ci;
+    }
+
+    public static double HypSinIntegral(double x) {
+      if (double.IsNaN(x)) return double.NaN;
+      double shi, chi;
+      alglib.hyperbolicsinecosineintegrals(x, out shi, out chi);
+      return shi;
+    }
+
+    public static double HypCosIntegral(double x) {
+      if (double.IsNaN(x)) return double.NaN;
+      double shi, chi;
+      alglib.hyperbolicsinecosineintegrals(x, out shi, out chi);
+      return chi;
+    }
+
+    public static double FresnelCosIntegral(double x) {
+      if (double.IsNaN(x)) return double.NaN;
+      double c = 0, s = 0;
+      alglib.fresnelintegral(x, ref c, ref s);
+      return c;
+    }
+
+    public static double FresnelSinIntegral(double x) {
+      if (double.IsNaN(x)) return double.NaN;
+      double c = 0, s = 0;
+      alglib.fresnelintegral(x, ref c, ref s);
+      return s;
+    }
+
+    public static double Norm(double x) {
+      if (double.IsNaN(x)) return double.NaN;
+      return alglib.normaldistribution(x);
+    }
+
+    public static double Erf(double x) {
+      if (double.IsNaN(x)) return double.NaN;
+      return alglib.errorfunction(x);
+    }
+
+    public static double Bessel(double x) {
+      if (double.IsNaN(x)) return double.NaN;
+      return alglib.besseli0(x);
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeInterpreter.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeInterpreter.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeInterpreter.cs	(revision 8798)
@@ -0,0 +1,454 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+  [StorableClass]
+  [Item("SymbolicDataAnalysisExpressionTreeInterpreter", "Interpreter for symbolic expression trees including automatically defined functions.")]
+  public class SymbolicDataAnalysisExpressionTreeInterpreter : ParameterizedNamedItem, ISymbolicDataAnalysisExpressionTreeInterpreter {
+    private const string CheckExpressionsWithIntervalArithmeticParameterName = "CheckExpressionsWithIntervalArithmetic";
+    private const string EvaluatedSolutionsParameterName = "EvaluatedSolutions";
+
+    public override bool CanChangeName { get { return false; } }
+    public override bool CanChangeDescription { get { return false; } }
+
+    #region parameter properties
+    public IValueParameter<BoolValue> CheckExpressionsWithIntervalArithmeticParameter {
+      get { return (IValueParameter<BoolValue>)Parameters[CheckExpressionsWithIntervalArithmeticParameterName]; }
+    }
+
+    public IValueParameter<IntValue> EvaluatedSolutionsParameter {
+      get { return (IValueParameter<IntValue>)Parameters[EvaluatedSolutionsParameterName]; }
+    }
+    #endregion
+
+    #region properties
+    public BoolValue CheckExpressionsWithIntervalArithmetic {
+      get { return CheckExpressionsWithIntervalArithmeticParameter.Value; }
+      set { CheckExpressionsWithIntervalArithmeticParameter.Value = value; }
+    }
+
+    public IntValue EvaluatedSolutions {
+      get { return EvaluatedSolutionsParameter.Value; }
+      set { EvaluatedSolutionsParameter.Value = value; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected SymbolicDataAnalysisExpressionTreeInterpreter(bool deserializing) : base(deserializing) { }
+    protected SymbolicDataAnalysisExpressionTreeInterpreter(SymbolicDataAnalysisExpressionTreeInterpreter original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SymbolicDataAnalysisExpressionTreeInterpreter(this, cloner);
+    }
+
+    public SymbolicDataAnalysisExpressionTreeInterpreter()
+      : base("SymbolicDataAnalysisExpressionTreeInterpreter", "Interpreter for symbolic expression trees including automatically defined functions.") {
+      Parameters.Add(new ValueParameter<BoolValue>(CheckExpressionsWithIntervalArithmeticParameterName, "Switch that determines if the interpreter checks the validity of expressions with interval arithmetic before evaluating the expression.", new BoolValue(false)));
+      Parameters.Add(new ValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0)));
+    }
+
+    protected SymbolicDataAnalysisExpressionTreeInterpreter(string name, string description)
+      : base(name, description) {
+      Parameters.Add(new ValueParameter<BoolValue>(CheckExpressionsWithIntervalArithmeticParameterName, "Switch that determines if the interpreter checks the validity of expressions with interval arithmetic before evaluating the expression.", new BoolValue(false)));
+      Parameters.Add(new ValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0)));
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (!Parameters.ContainsKey(EvaluatedSolutionsParameterName))
+        Parameters.Add(new ValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0)));
+    }
+
+    #region IStatefulItem
+    public void InitializeState() {
+      EvaluatedSolutions.Value = 0;
+    }
+
+    public void ClearState() {
+    }
+    #endregion
+
+    public IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, IEnumerable<int> rows) {
+      if (CheckExpressionsWithIntervalArithmetic.Value)
+        throw new NotSupportedException("Interval arithmetic is not yet supported in the symbolic data analysis interpreter.");
+
+      EvaluatedSolutions.Value++; // increment the evaluated solutions counter
+      var state = PrepareInterpreterState(tree, dataset);
+
+      foreach (var rowEnum in rows) {
+        int row = rowEnum;
+        yield return Evaluate(dataset, ref row, state);
+        state.Reset();
+      }
+    }
+
+    private InterpreterState PrepareInterpreterState(ISymbolicExpressionTree tree, Dataset dataset) {
+      Instruction[] code = SymbolicExpressionTreeCompiler.Compile(tree, OpCodes.MapSymbolToOpCode);
+      int necessaryArgStackSize = 0;
+      foreach (Instruction instr in code) {
+        if (instr.opCode == OpCodes.Variable) {
+          var variableTreeNode = (VariableTreeNode)instr.dynamicNode;
+          instr.iArg0 = dataset.GetReadOnlyDoubleValues(variableTreeNode.VariableName);
+        } else if (instr.opCode == OpCodes.LagVariable) {
+          var laggedVariableTreeNode = (LaggedVariableTreeNode)instr.dynamicNode;
+          instr.iArg0 = dataset.GetReadOnlyDoubleValues(laggedVariableTreeNode.VariableName);
+        } else if (instr.opCode == OpCodes.VariableCondition) {
+          var variableConditionTreeNode = (VariableConditionTreeNode)instr.dynamicNode;
+          instr.iArg0 = dataset.GetReadOnlyDoubleValues(variableConditionTreeNode.VariableName);
+        } else if (instr.opCode == OpCodes.Call) {
+          necessaryArgStackSize += instr.nArguments + 1;
+        }
+      }
+      return new InterpreterState(code, necessaryArgStackSize);
+    }
+
+
+    protected virtual double Evaluate(Dataset dataset, ref int row, InterpreterState state) {
+      Instruction currentInstr = state.NextInstruction();
+      switch (currentInstr.opCode) {
+        case OpCodes.Add: {
+            double s = Evaluate(dataset, ref row, state);
+            for (int i = 1; i < currentInstr.nArguments; i++) {
+              s += Evaluate(dataset, ref row, state);
+            }
+            return s;
+          }
+        case OpCodes.Sub: {
+            double s = Evaluate(dataset, ref row, state);
+            for (int i = 1; i < currentInstr.nArguments; i++) {
+              s -= Evaluate(dataset, ref row, state);
+            }
+            if (currentInstr.nArguments == 1) s = -s;
+            return s;
+          }
+        case OpCodes.Mul: {
+            double p = Evaluate(dataset, ref row, state);
+            for (int i = 1; i < currentInstr.nArguments; i++) {
+              p *= Evaluate(dataset, ref row, state);
+            }
+            return p;
+          }
+        case OpCodes.Div: {
+            double p = Evaluate(dataset, ref row, state);
+            for (int i = 1; i < currentInstr.nArguments; i++) {
+              p /= Evaluate(dataset, ref row, state);
+            }
+            if (currentInstr.nArguments == 1) p = 1.0 / p;
+            return p;
+          }
+        case OpCodes.Average: {
+            double sum = Evaluate(dataset, ref row, state);
+            for (int i = 1; i < currentInstr.nArguments; i++) {
+              sum += Evaluate(dataset, ref row, state);
+            }
+            return sum / currentInstr.nArguments;
+          }
+        case OpCodes.Cos: {
+            return Math.Cos(Evaluate(dataset, ref row, state));
+          }
+        case OpCodes.Sin: {
+            return Math.Sin(Evaluate(dataset, ref row, state));
+          }
+        case OpCodes.Tan: {
+            return Math.Tan(Evaluate(dataset, ref row, state));
+          }
+        case OpCodes.Square: {
+            return Math.Pow(Evaluate(dataset, ref row, state), 2);
+          }
+        case OpCodes.Power: {
+            double x = Evaluate(dataset, ref row, state);
+            double y = Math.Round(Evaluate(dataset, ref row, state));
+            return Math.Pow(x, y);
+          }
+        case OpCodes.SquareRoot: {
+            return Math.Sqrt(Evaluate(dataset, ref row, state));
+          }
+        case OpCodes.Root: {
+            double x = Evaluate(dataset, ref row, state);
+            double y = Math.Round(Evaluate(dataset, ref row, state));
+            return Math.Pow(x, 1 / y);
+          }
+        case OpCodes.Exp: {
+            return Math.Exp(Evaluate(dataset, ref row, state));
+          }
+        case OpCodes.Log: {
+            return Math.Log(Evaluate(dataset, ref row, state));
+          }
+        case OpCodes.Gamma: {
+            var x = Evaluate(dataset, ref row, state);
+            if (double.IsNaN(x)) return double.NaN;
+            else return alglib.gammafunction(x);
+          }
+        case OpCodes.Psi: {
+            var x = Evaluate(dataset, ref row, state);
+            if (double.IsNaN(x)) return double.NaN;
+            else if (x <= 0 && (Math.Floor(x) - x).IsAlmost(0)) return double.NaN;
+            return alglib.psi(x);
+          }
+        case OpCodes.Dawson: {
+            var x = Evaluate(dataset, ref row, state);
+            if (double.IsNaN(x)) return double.NaN;
+            return alglib.dawsonintegral(x);
+          }
+        case OpCodes.ExponentialIntegralEi: {
+            var x = Evaluate(dataset, ref row, state);
+            if (double.IsNaN(x)) return double.NaN;
+            return alglib.exponentialintegralei(x);
+          }
+        case OpCodes.SineIntegral: {
+            double si, ci;
+            var x = Evaluate(dataset, ref row, state);
+            if (double.IsNaN(x)) return double.NaN;
+            else {
+              alglib.sinecosineintegrals(x, out si, out ci);
+              return si;
+            }
+          }
+        case OpCodes.CosineIntegral: {
+            double si, ci;
+            var x = Evaluate(dataset, ref row, state);
+            if (double.IsNaN(x)) return double.NaN;
+            else {
+              alglib.sinecosineintegrals(x, out si, out ci);
+              return ci;
+            }
+          }
+        case OpCodes.HyperbolicSineIntegral: {
+            double shi, chi;
+            var x = Evaluate(dataset, ref row, state);
+            if (double.IsNaN(x)) return double.NaN;
+            else {
+              alglib.hyperbolicsinecosineintegrals(x, out shi, out chi);
+              return shi;
+            }
+          }
+        case OpCodes.HyperbolicCosineIntegral: {
+            double shi, chi;
+            var x = Evaluate(dataset, ref row, state);
+            if (double.IsNaN(x)) return double.NaN;
+            else {
+              alglib.hyperbolicsinecosineintegrals(x, out shi, out chi);
+              return chi;
+            }
+          }
+        case OpCodes.FresnelCosineIntegral: {
+            double c = 0, s = 0;
+            var x = Evaluate(dataset, ref row, state);
+            if (double.IsNaN(x)) return double.NaN;
+            else {
+              alglib.fresnelintegral(x, ref c, ref s);
+              return c;
+            }
+          }
+        case OpCodes.FresnelSineIntegral: {
+            double c = 0, s = 0;
+            var x = Evaluate(dataset, ref row, state);
+            if (double.IsNaN(x)) return double.NaN;
+            else {
+              alglib.fresnelintegral(x, ref c, ref s);
+              return s;
+            }
+          }
+        case OpCodes.AiryA: {
+            double ai, aip, bi, bip;
+            var x = Evaluate(dataset, ref row, state);
+            if (double.IsNaN(x)) return double.NaN;
+            else {
+              alglib.airy(x, out ai, out aip, out bi, out bip);
+              return ai;
+            }
+          }
+        case OpCodes.AiryB: {
+            double ai, aip, bi, bip;
+            var x = Evaluate(dataset, ref row, state);
+            if (double.IsNaN(x)) return double.NaN;
+            else {
+              alglib.airy(x, out ai, out aip, out bi, out bip);
+              return bi;
+            }
+          }
+        case OpCodes.Norm: {
+            var x = Evaluate(dataset, ref row, state);
+            if (double.IsNaN(x)) return double.NaN;
+            else return alglib.normaldistribution(x);
+          }
+        case OpCodes.Erf: {
+            var x = Evaluate(dataset, ref row, state);
+            if (double.IsNaN(x)) return double.NaN;
+            else return alglib.errorfunction(x);
+          }
+        case OpCodes.Bessel: {
+            var x = Evaluate(dataset, ref row, state);
+            if (double.IsNaN(x)) return double.NaN;
+            else return alglib.besseli0(x);
+          }
+        case OpCodes.IfThenElse: {
+            double condition = Evaluate(dataset, ref row, state);
+            double result;
+            if (condition > 0.0) {
+              result = Evaluate(dataset, ref row, state); state.SkipInstructions();
+            } else {
+              state.SkipInstructions(); result = Evaluate(dataset, ref row, state);
+            }
+            return result;
+          }
+        case OpCodes.AND: {
+            double result = Evaluate(dataset, ref row, state);
+            for (int i = 1; i < currentInstr.nArguments; i++) {
+              if (result > 0.0) result = Evaluate(dataset, ref row, state);
+              else {
+                state.SkipInstructions();
+              }
+            }
+            return result > 0.0 ? 1.0 : -1.0;
+          }
+        case OpCodes.OR: {
+            double result = Evaluate(dataset, ref row, state);
+            for (int i = 1; i < currentInstr.nArguments; i++) {
+              if (result <= 0.0) result = Evaluate(dataset, ref row, state);
+              else {
+                state.SkipInstructions();
+              }
+            }
+            return result > 0.0 ? 1.0 : -1.0;
+          }
+        case OpCodes.NOT: {
+            return Evaluate(dataset, ref row, state) > 0.0 ? -1.0 : 1.0;
+          }
+        case OpCodes.GT: {
+            double x = Evaluate(dataset, ref row, state);
+            double y = Evaluate(dataset, ref row, state);
+            if (x > y) return 1.0;
+            else return -1.0;
+          }
+        case OpCodes.LT: {
+            double x = Evaluate(dataset, ref row, state);
+            double y = Evaluate(dataset, ref row, state);
+            if (x < y) return 1.0;
+            else return -1.0;
+          }
+        case OpCodes.TimeLag: {
+            var timeLagTreeNode = (LaggedTreeNode)currentInstr.dynamicNode;
+            row += timeLagTreeNode.Lag;
+            double result = Evaluate(dataset, ref row, state);
+            row -= timeLagTreeNode.Lag;
+            return result;
+          }
+        case OpCodes.Integral: {
+            int savedPc = state.ProgramCounter;
+            var timeLagTreeNode = (LaggedTreeNode)currentInstr.dynamicNode;
+            double sum = 0.0;
+            for (int i = 0; i < Math.Abs(timeLagTreeNode.Lag); i++) {
+              row += Math.Sign(timeLagTreeNode.Lag);
+              sum += Evaluate(dataset, ref row, state);
+              state.ProgramCounter = savedPc;
+            }
+            row -= timeLagTreeNode.Lag;
+            sum += Evaluate(dataset, ref row, state);
+            return sum;
+          }
+
+        //mkommend: derivate calculation taken from: 
+        //http://www.holoborodko.com/pavel/numerical-methods/numerical-derivative/smooth-low-noise-differentiators/
+        //one sided smooth differentiatior, N = 4
+        // y' = 1/8h (f_i + 2f_i-1, -2 f_i-3 - f_i-4)
+        case OpCodes.Derivative: {
+            int savedPc = state.ProgramCounter;
+            double f_0 = Evaluate(dataset, ref row, state); row--;
+            state.ProgramCounter = savedPc;
+            double f_1 = Evaluate(dataset, ref row, state); row -= 2;
+            state.ProgramCounter = savedPc;
+            double f_3 = Evaluate(dataset, ref row, state); row--;
+            state.ProgramCounter = savedPc;
+            double f_4 = Evaluate(dataset, ref row, state);
+            row += 4;
+
+            return (f_0 + 2 * f_1 - 2 * f_3 - f_4) / 8; // h = 1
+          }
+        case OpCodes.Call: {
+            // evaluate sub-trees
+            double[] argValues = new double[currentInstr.nArguments];
+            for (int i = 0; i < currentInstr.nArguments; i++) {
+              argValues[i] = Evaluate(dataset, ref row, state);
+            }
+            // push on argument values on stack 
+            state.CreateStackFrame(argValues);
+
+            // save the pc
+            int savedPc = state.ProgramCounter;
+            // set pc to start of function  
+            state.ProgramCounter = (ushort)currentInstr.iArg0;
+            // evaluate the function
+            double v = Evaluate(dataset, ref row, state);
+
+            // delete the stack frame
+            state.RemoveStackFrame();
+
+            // restore the pc => evaluation will continue at point after my subtrees  
+            state.ProgramCounter = savedPc;
+            return v;
+          }
+        case OpCodes.Arg: {
+            return state.GetStackFrameValue((ushort)currentInstr.iArg0);
+          }
+        case OpCodes.Variable: {
+            if (row < 0 || row >= dataset.Rows) return double.NaN;
+            var variableTreeNode = (VariableTreeNode)currentInstr.dynamicNode;
+            return ((IList<double>)currentInstr.iArg0)[row] * variableTreeNode.Weight;
+          }
+        case OpCodes.LagVariable: {
+            var laggedVariableTreeNode = (LaggedVariableTreeNode)currentInstr.dynamicNode;
+            int actualRow = row + laggedVariableTreeNode.Lag;
+            if (actualRow < 0 || actualRow >= dataset.Rows) return double.NaN;
+            return ((IList<double>)currentInstr.iArg0)[actualRow] * laggedVariableTreeNode.Weight;
+          }
+        case OpCodes.Constant: {
+            var constTreeNode = (ConstantTreeNode)currentInstr.dynamicNode;
+            return constTreeNode.Value;
+          }
+
+        //mkommend: this symbol uses the logistic function f(x) = 1 / (1 + e^(-alpha * x) ) 
+        //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) return double.NaN;
+            var variableConditionTreeNode = (VariableConditionTreeNode)currentInstr.dynamicNode;
+            double variableValue = ((IList<double>)currentInstr.iArg0)[row];
+            double x = variableValue - variableConditionTreeNode.Threshold;
+            double p = 1 / (1 + Math.Exp(-variableConditionTreeNode.Slope * x));
+
+            double trueBranch = Evaluate(dataset, ref row, state);
+            double falseBranch = Evaluate(dataset, ref row, state);
+
+            return trueBranch * p + falseBranch * (1 - p);
+          }
+        default: throw new NotSupportedException();
+      }
+    }
+  }
+}
Index: unk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeILEmittingInterpreter.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeILEmittingInterpreter.cs	(revision 8797)
+++ 	(revision )
@@ -1,907 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2012 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.Reflection;
-using System.Reflection.Emit;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
-  [StorableClass]
-  [Item("SymbolicDataAnalysisExpressionTreeILEmittingInterpreter", "Interpreter for symbolic expression trees.")]
-  public sealed class SymbolicDataAnalysisExpressionTreeILEmittingInterpreter : ParameterizedNamedItem,
-                                                                                ISymbolicDataAnalysisExpressionTreeInterpreter {
-    private static MethodInfo listGetValue =
-      typeof(IList<double>).GetProperty("Item", new Type[] { typeof(int) }).GetGetMethod();
-
-    private static MethodInfo cos = typeof(Math).GetMethod("Cos", new Type[] { typeof(double) });
-    private static MethodInfo sin = typeof(Math).GetMethod("Sin", new Type[] { typeof(double) });
-    private static MethodInfo tan = typeof(Math).GetMethod("Tan", new Type[] { typeof(double) });
-    private static MethodInfo exp = typeof(Math).GetMethod("Exp", new Type[] { typeof(double) });
-    private static MethodInfo log = typeof(Math).GetMethod("Log", new Type[] { typeof(double) });
-    private static MethodInfo power = typeof(Math).GetMethod("Pow", new Type[] { typeof(double), typeof(double) });
-    private static MethodInfo round = typeof(Math).GetMethod("Round", new Type[] { typeof(double) });
-    private static MethodInfo sqrt = typeof(Math).GetMethod("Sqrt", new Type[] { typeof(double) });
-
-    private static Type thisType = typeof(SymbolicDataAnalysisExpressionTreeILEmittingInterpreter);
-    private static MethodInfo airyA = thisType.GetMethod("AiryA", new Type[] { typeof(double) });
-    private static MethodInfo airyB = thisType.GetMethod("AiryB", new Type[] { typeof(double) });
-    private static MethodInfo gamma = thisType.GetMethod("Gamma", new Type[] { typeof(double) });
-    private static MethodInfo psi = thisType.GetMethod("Psi", new Type[] { typeof(double) });
-    private static MethodInfo dawson = thisType.GetMethod("Dawson", new Type[] { typeof(double) });
-    private static MethodInfo expIntegralEi = thisType.GetMethod("ExpIntegralEi", new Type[] { typeof(double) });
-    private static MethodInfo sinIntegral = thisType.GetMethod("SinIntegral", new Type[] { typeof(double) });
-    private static MethodInfo cosIntegral = thisType.GetMethod("CosIntegral", new Type[] { typeof(double) });
-    private static MethodInfo hypSinIntegral = thisType.GetMethod("HypSinIntegral", new Type[] { typeof(double) });
-    private static MethodInfo hypCosIntegral = thisType.GetMethod("HypCosIntegral", new Type[] { typeof(double) });
-    private static MethodInfo fresnelCosIntegral = thisType.GetMethod("FresnelCosIntegral", new Type[] { typeof(double) });
-    private static MethodInfo fresnelSinIntegral = thisType.GetMethod("FresnelSinIntegral", new Type[] { typeof(double) });
-    private static MethodInfo norm = thisType.GetMethod("Norm", new Type[] { typeof(double) });
-    private static MethodInfo erf = thisType.GetMethod("Erf", new Type[] { typeof(double) });
-    private static MethodInfo bessel = thisType.GetMethod("Bessel", new Type[] { typeof(double) });
-
-    internal delegate double CompiledFunction(int sampleIndex, IList<double>[] columns);
-
-    private const string CheckExpressionsWithIntervalArithmeticParameterName = "CheckExpressionsWithIntervalArithmetic";
-    private const string EvaluatedSolutionsParameterName = "EvaluatedSolutions";
-
-    #region private classes
-
-    private class InterpreterState {
-      private Instruction[] code;
-      private int pc;
-
-      public int ProgramCounter {
-        get { return pc; }
-        set { pc = value; }
-      }
-
-      private bool inLaggedContext;
-
-      public bool InLaggedContext {
-        get { return inLaggedContext; }
-        set { inLaggedContext = value; }
-      }
-
-      internal InterpreterState(Instruction[] code) {
-        this.inLaggedContext = false;
-        this.code = code;
-        this.pc = 0;
-      }
-
-      internal Instruction NextInstruction() {
-        return code[pc++];
-      }
-    }
-
-    private class OpCodes {
-      public const byte Add = 1;
-      public const byte Sub = 2;
-      public const byte Mul = 3;
-      public const byte Div = 4;
-
-      public const byte Sin = 5;
-      public const byte Cos = 6;
-      public const byte Tan = 7;
-
-      public const byte Log = 8;
-      public const byte Exp = 9;
-
-      public const byte IfThenElse = 10;
-
-      public const byte GT = 11;
-      public const byte LT = 12;
-
-      public const byte AND = 13;
-      public const byte OR = 14;
-      public const byte NOT = 15;
-
-
-      public const byte Average = 16;
-
-      public const byte Call = 17;
-
-      public const byte Variable = 18;
-      public const byte LagVariable = 19;
-      public const byte Constant = 20;
-      public const byte Arg = 21;
-
-      public const byte Power = 22;
-      public const byte Root = 23;
-      public const byte TimeLag = 24;
-      public const byte Integral = 25;
-      public const byte Derivative = 26;
-
-      public const byte VariableCondition = 27;
-
-      public const byte Square = 28;
-      public const byte SquareRoot = 29;
-      public const byte Gamma = 30;
-      public const byte Psi = 31;
-      public const byte Dawson = 32;
-      public const byte ExponentialIntegralEi = 33;
-      public const byte CosineIntegral = 34;
-      public const byte SineIntegral = 35;
-      public const byte HyperbolicCosineIntegral = 36;
-      public const byte HyperbolicSineIntegral = 37;
-      public const byte FresnelCosineIntegral = 38;
-      public const byte FresnelSineIntegral = 39;
-      public const byte AiryA = 40;
-      public const byte AiryB = 41;
-      public const byte Norm = 42;
-      public const byte Erf = 43;
-      public const byte Bessel = 44;
-    }
-
-    #endregion
-
-    private Dictionary<Type, byte> symbolToOpcode = new Dictionary<Type, byte>()
-                                                      {
-                                                        {typeof (Addition), OpCodes.Add},
-                                                        {typeof (Subtraction), OpCodes.Sub},
-                                                        {typeof (Multiplication), OpCodes.Mul},
-                                                        {typeof (Division), OpCodes.Div},
-                                                        {typeof (Sine), OpCodes.Sin},
-                                                        {typeof (Cosine), OpCodes.Cos},
-                                                        {typeof (Tangent), OpCodes.Tan},
-                                                        {typeof (Logarithm), OpCodes.Log},
-                                                        {typeof (Exponential), OpCodes.Exp},
-                                                        {typeof (IfThenElse), OpCodes.IfThenElse},
-                                                        {typeof (GreaterThan), OpCodes.GT},
-                                                        {typeof (LessThan), OpCodes.LT},
-                                                        {typeof (And), OpCodes.AND},
-                                                        {typeof (Or), OpCodes.OR},
-                                                        {typeof (Not), OpCodes.NOT},
-                                                        {typeof (Average), OpCodes.Average},
-                                                        {typeof (InvokeFunction), OpCodes.Call},
-                                                        {
-                                                          typeof (HeuristicLab.Problems.DataAnalysis.Symbolic.Variable),
-                                                          OpCodes.Variable
-                                                          },
-                                                        {typeof (LaggedVariable), OpCodes.LagVariable},
-                                                        {typeof (Constant), OpCodes.Constant},
-                                                        {typeof (Argument), OpCodes.Arg},
-                                                        {typeof (Power), OpCodes.Power},
-                                                        {typeof (Root), OpCodes.Root},
-                                                        {typeof (TimeLag), OpCodes.TimeLag},
-                                                        {typeof (Integral), OpCodes.Integral},
-                                                        {typeof (Derivative), OpCodes.Derivative},
-                                                        {typeof (VariableCondition), OpCodes.VariableCondition},
-                                                        {typeof (Square), OpCodes.Square},
-                                                        {typeof (SquareRoot), OpCodes.SquareRoot},
-                                                        {typeof (Gamma), OpCodes.Gamma},
-                                                        {typeof (Psi), OpCodes.Psi},
-                                                        {typeof (Dawson), OpCodes.Dawson},
-                                                        {typeof (ExponentialIntegralEi), OpCodes.ExponentialIntegralEi},
-                                                        {typeof (CosineIntegral), OpCodes.CosineIntegral},
-                                                        {typeof (SineIntegral), OpCodes.SineIntegral},
-                                                        {
-                                                          typeof (HyperbolicCosineIntegral),
-                                                          OpCodes.HyperbolicCosineIntegral
-                                                          },
-                                                        {
-                                                          typeof (HyperbolicSineIntegral), OpCodes.HyperbolicSineIntegral
-                                                          },
-                                                        {typeof (FresnelCosineIntegral), OpCodes.FresnelCosineIntegral},
-                                                        {typeof (FresnelSineIntegral), OpCodes.FresnelSineIntegral},
-                                                        {typeof (AiryA), OpCodes.AiryA},
-                                                        {typeof (AiryB), OpCodes.AiryB},
-                                                        {typeof (Norm), OpCodes.Norm},
-                                                        {typeof (Erf), OpCodes.Erf},
-                                                        {typeof (Bessel), OpCodes.Bessel}
-                                                      };
-
-    public override bool CanChangeName {
-      get { return false; }
-    }
-
-    public override bool CanChangeDescription {
-      get { return false; }
-    }
-
-    #region parameter properties
-
-    public IValueParameter<BoolValue> CheckExpressionsWithIntervalArithmeticParameter {
-      get { return (IValueParameter<BoolValue>)Parameters[CheckExpressionsWithIntervalArithmeticParameterName]; }
-    }
-
-    public IValueParameter<IntValue> EvaluatedSolutionsParameter {
-      get { return (IValueParameter<IntValue>)Parameters[EvaluatedSolutionsParameterName]; }
-    }
-
-    #endregion
-
-    #region properties
-
-    public BoolValue CheckExpressionsWithIntervalArithmetic {
-      get { return CheckExpressionsWithIntervalArithmeticParameter.Value; }
-      set { CheckExpressionsWithIntervalArithmeticParameter.Value = value; }
-    }
-
-    public IntValue EvaluatedSolutions {
-      get { return EvaluatedSolutionsParameter.Value; }
-      set { EvaluatedSolutionsParameter.Value = value; }
-    }
-
-    #endregion
-
-
-    [StorableConstructor]
-    private SymbolicDataAnalysisExpressionTreeILEmittingInterpreter(bool deserializing)
-      : base(deserializing) {
-    }
-
-    private SymbolicDataAnalysisExpressionTreeILEmittingInterpreter(
-      SymbolicDataAnalysisExpressionTreeILEmittingInterpreter original, Cloner cloner)
-      : base(original, cloner) {
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new SymbolicDataAnalysisExpressionTreeILEmittingInterpreter(this, cloner);
-    }
-
-    public SymbolicDataAnalysisExpressionTreeILEmittingInterpreter()
-      : base("SymbolicDataAnalysisExpressionTreeILEmittingInterpreter", "Interpreter for symbolic expression trees.") {
-      Parameters.Add(new ValueParameter<BoolValue>(CheckExpressionsWithIntervalArithmeticParameterName,
-                                                   "Switch that determines if the interpreter checks the validity of expressions with interval arithmetic before evaluating the expression.",
-                                                   new BoolValue(false)));
-      Parameters.Add(new ValueParameter<IntValue>(EvaluatedSolutionsParameterName,
-                                                  "A counter for the total number of solutions the interpreter has evaluated",
-                                                  new IntValue(0)));
-    }
-
-    [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserialization() {
-      if (!Parameters.ContainsKey(EvaluatedSolutionsParameterName))
-        Parameters.Add(new ValueParameter<IntValue>(EvaluatedSolutionsParameterName,
-                                                    "A counter for the total number of solutions the interpreter has evaluated",
-                                                    new IntValue(0)));
-    }
-
-    #region IStatefulItem
-
-    public void InitializeState() {
-      EvaluatedSolutions.Value = 0;
-    }
-
-    public void ClearState() {
-      EvaluatedSolutions.Value = 0;
-    }
-
-    #endregion
-
-    public IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset,
-                                                               IEnumerable<int> rows) {
-      if (CheckExpressionsWithIntervalArithmetic.Value)
-        throw new NotSupportedException(
-          "Interval arithmetic is not yet supported in the symbolic data analysis interpreter.");
-      EvaluatedSolutions.Value++; // increment the evaluated solutions counter
-      var compiler = new SymbolicExpressionTreeCompiler();
-      Instruction[] code = compiler.Compile(tree, MapSymbolToOpCode);
-      int necessaryArgStackSize = 0;
-
-      Dictionary<string, int> doubleVariableNames =
-        dataset.DoubleVariables.Select((x, i) => new { x, i }).ToDictionary(e => e.x, e => e.i);
-      IList<double>[] columns = (from v in doubleVariableNames.Keys
-                                 select dataset.GetReadOnlyDoubleValues(v))
-        .ToArray();
-
-      for (int i = 0; i < code.Length; i++) {
-        Instruction instr = code[i];
-        if (instr.opCode == OpCodes.Variable) {
-          var variableTreeNode = instr.dynamicNode as VariableTreeNode;
-          instr.iArg0 = doubleVariableNames[variableTreeNode.VariableName];
-          code[i] = instr;
-        } else if (instr.opCode == OpCodes.LagVariable) {
-          var variableTreeNode = instr.dynamicNode as LaggedVariableTreeNode;
-          instr.iArg0 = doubleVariableNames[variableTreeNode.VariableName];
-          code[i] = instr;
-        } else if (instr.opCode == OpCodes.VariableCondition) {
-          var variableConditionTreeNode = instr.dynamicNode as VariableConditionTreeNode;
-          instr.iArg0 = doubleVariableNames[variableConditionTreeNode.VariableName];
-        } else if (instr.opCode == OpCodes.Call) {
-          necessaryArgStackSize += instr.nArguments + 1;
-        }
-      }
-      var state = new InterpreterState(code);
-
-      Type[] methodArgs = { typeof(int), typeof(IList<double>[]) };
-      DynamicMethod testFun = new DynamicMethod("TestFun", typeof(double), methodArgs,
-                                                typeof(SymbolicDataAnalysisExpressionTreeILEmittingInterpreter).Module);
-
-      ILGenerator il = testFun.GetILGenerator();
-      CompileInstructions(il, state, dataset);
-      il.Emit(System.Reflection.Emit.OpCodes.Conv_R8);
-      il.Emit(System.Reflection.Emit.OpCodes.Ret);
-      var function = (CompiledFunction)testFun.CreateDelegate(typeof(CompiledFunction));
-
-      foreach (var row in rows) {
-        yield return function(row, columns);
-      }
-    }
-
-    private void CompileInstructions(ILGenerator il, InterpreterState state, Dataset ds) {
-      Instruction currentInstr = state.NextInstruction();
-      int nArgs = currentInstr.nArguments;
-
-      switch (currentInstr.opCode) {
-        case OpCodes.Add: {
-            if (nArgs > 0) {
-              CompileInstructions(il, state, ds);
-            }
-            for (int i = 1; i < nArgs; i++) {
-              CompileInstructions(il, state, ds);
-              il.Emit(System.Reflection.Emit.OpCodes.Add);
-            }
-            return;
-          }
-        case OpCodes.Sub: {
-            if (nArgs == 1) {
-              CompileInstructions(il, state, ds);
-              il.Emit(System.Reflection.Emit.OpCodes.Neg);
-              return;
-            }
-            if (nArgs > 0) {
-              CompileInstructions(il, state, ds);
-            }
-            for (int i = 1; i < nArgs; i++) {
-              CompileInstructions(il, state, ds);
-              il.Emit(System.Reflection.Emit.OpCodes.Sub);
-            }
-            return;
-          }
-        case OpCodes.Mul: {
-            if (nArgs > 0) {
-              CompileInstructions(il, state, ds);
-            }
-            for (int i = 1; i < nArgs; i++) {
-              CompileInstructions(il, state, ds);
-              il.Emit(System.Reflection.Emit.OpCodes.Mul);
-            }
-            return;
-          }
-        case OpCodes.Div: {
-            if (nArgs == 1) {
-              il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 1.0);
-              CompileInstructions(il, state, ds);
-              il.Emit(System.Reflection.Emit.OpCodes.Div);
-              return;
-            }
-            if (nArgs > 0) {
-              CompileInstructions(il, state, ds);
-            }
-            for (int i = 1; i < nArgs; i++) {
-              CompileInstructions(il, state, ds);
-              il.Emit(System.Reflection.Emit.OpCodes.Div);
-            }
-            return;
-          }
-        case OpCodes.Average: {
-            CompileInstructions(il, state, ds);
-            for (int i = 1; i < nArgs; i++) {
-              CompileInstructions(il, state, ds);
-              il.Emit(System.Reflection.Emit.OpCodes.Add);
-            }
-            il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, nArgs);
-            il.Emit(System.Reflection.Emit.OpCodes.Div);
-            return;
-          }
-        case OpCodes.Cos: {
-            CompileInstructions(il, state, ds);
-            il.Emit(System.Reflection.Emit.OpCodes.Call, cos);
-            return;
-          }
-        case OpCodes.Sin: {
-            CompileInstructions(il, state, ds);
-            il.Emit(System.Reflection.Emit.OpCodes.Call, sin);
-            return;
-          }
-        case OpCodes.Tan: {
-            CompileInstructions(il, state, ds);
-            il.Emit(System.Reflection.Emit.OpCodes.Call, tan);
-            return;
-          }
-        case OpCodes.Power: {
-            CompileInstructions(il, state, ds);
-            CompileInstructions(il, state, ds);
-            il.Emit(System.Reflection.Emit.OpCodes.Call, round);
-            il.Emit(System.Reflection.Emit.OpCodes.Call, power);
-            return;
-          }
-        case OpCodes.Root: {
-            CompileInstructions(il, state, ds);
-            il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 1.0); // 1 / round(...)
-            CompileInstructions(il, state, ds);
-            il.Emit(System.Reflection.Emit.OpCodes.Call, round);
-            il.Emit(System.Reflection.Emit.OpCodes.Div);
-            il.Emit(System.Reflection.Emit.OpCodes.Call, power);
-            return;
-          }
-        case OpCodes.Exp: {
-            CompileInstructions(il, state, ds);
-            il.Emit(System.Reflection.Emit.OpCodes.Call, exp);
-            return;
-          }
-        case OpCodes.Log: {
-            CompileInstructions(il, state, ds);
-            il.Emit(System.Reflection.Emit.OpCodes.Call, log);
-            return;
-          }
-        case OpCodes.Square: {
-            CompileInstructions(il, state, ds);
-            il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 2.0);
-            il.Emit(System.Reflection.Emit.OpCodes.Call, power);
-            return;
-          }
-        case OpCodes.SquareRoot: {
-            CompileInstructions(il, state, ds);
-            il.Emit(System.Reflection.Emit.OpCodes.Call, sqrt);
-            return;
-          }
-        case OpCodes.AiryA: {
-            CompileInstructions(il, state, ds);
-            il.Emit(System.Reflection.Emit.OpCodes.Call, airyA);
-            return;
-          }
-        case OpCodes.AiryB: {
-            CompileInstructions(il, state, ds);
-            il.Emit(System.Reflection.Emit.OpCodes.Call, airyB);
-            return;
-          }
-        case OpCodes.Bessel: {
-            CompileInstructions(il, state, ds);
-            il.Emit(System.Reflection.Emit.OpCodes.Call, bessel);
-            return;
-          }
-        case OpCodes.CosineIntegral: {
-            CompileInstructions(il, state, ds);
-            il.Emit(System.Reflection.Emit.OpCodes.Call, cosIntegral);
-            return;
-          }
-        case OpCodes.Dawson: {
-            CompileInstructions(il, state, ds);
-            il.Emit(System.Reflection.Emit.OpCodes.Call, dawson);
-            return;
-          }
-        case OpCodes.Erf: {
-            CompileInstructions(il, state, ds);
-            il.Emit(System.Reflection.Emit.OpCodes.Call, erf);
-            return;
-          }
-        case OpCodes.ExponentialIntegralEi: {
-            CompileInstructions(il, state, ds);
-            il.Emit(System.Reflection.Emit.OpCodes.Call, expIntegralEi);
-            return;
-          }
-        case OpCodes.FresnelCosineIntegral: {
-            CompileInstructions(il, state, ds);
-            il.Emit(System.Reflection.Emit.OpCodes.Call, fresnelCosIntegral);
-            return;
-          }
-        case OpCodes.FresnelSineIntegral: {
-            CompileInstructions(il, state, ds);
-            il.Emit(System.Reflection.Emit.OpCodes.Call, fresnelSinIntegral);
-            return;
-          }
-        case OpCodes.Gamma: {
-            CompileInstructions(il, state, ds);
-            il.Emit(System.Reflection.Emit.OpCodes.Call, gamma);
-            return;
-          }
-        case OpCodes.HyperbolicCosineIntegral: {
-            CompileInstructions(il, state, ds);
-            il.Emit(System.Reflection.Emit.OpCodes.Call, hypCosIntegral);
-            return;
-          }
-        case OpCodes.HyperbolicSineIntegral: {
-            CompileInstructions(il, state, ds);
-            il.Emit(System.Reflection.Emit.OpCodes.Call, hypSinIntegral);
-            return;
-          }
-        case OpCodes.Norm: {
-            CompileInstructions(il, state, ds);
-            il.Emit(System.Reflection.Emit.OpCodes.Call, norm);
-            return;
-          }
-        case OpCodes.Psi: {
-            CompileInstructions(il, state, ds);
-            il.Emit(System.Reflection.Emit.OpCodes.Call, psi);
-            return;
-          }
-        case OpCodes.SineIntegral: {
-            CompileInstructions(il, state, ds);
-            il.Emit(System.Reflection.Emit.OpCodes.Call, sinIntegral);
-            return;
-          }
-        case OpCodes.IfThenElse: {
-            Label end = il.DefineLabel();
-            Label c1 = il.DefineLabel();
-            CompileInstructions(il, state, ds);
-            il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_0); // > 0
-            il.Emit(System.Reflection.Emit.OpCodes.Cgt);
-            il.Emit(System.Reflection.Emit.OpCodes.Brfalse, c1);
-            CompileInstructions(il, state, ds);
-            il.Emit(System.Reflection.Emit.OpCodes.Br, end);
-            il.MarkLabel(c1);
-            CompileInstructions(il, state, ds);
-            il.MarkLabel(end);
-            return;
-          }
-        case OpCodes.AND: {
-            Label falseBranch = il.DefineLabel();
-            Label end = il.DefineLabel();
-            CompileInstructions(il, state, ds);
-            for (int i = 1; i < nArgs; i++) {
-              il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_0); // > 0
-              il.Emit(System.Reflection.Emit.OpCodes.Cgt);
-              il.Emit(System.Reflection.Emit.OpCodes.Brfalse, falseBranch);
-              CompileInstructions(il, state, ds);
-            }
-            il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_0); // > 0
-            il.Emit(System.Reflection.Emit.OpCodes.Cgt);
-            il.Emit(System.Reflection.Emit.OpCodes.Brfalse, falseBranch);
-            il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 1.0); // 1
-            il.Emit(System.Reflection.Emit.OpCodes.Br, end);
-            il.MarkLabel(falseBranch);
-            il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 1.0); // -1
-            il.Emit(System.Reflection.Emit.OpCodes.Neg);
-            il.MarkLabel(end);
-            return;
-          }
-        case OpCodes.OR: {
-            Label trueBranch = il.DefineLabel();
-            Label end = il.DefineLabel();
-            Label resultBranch = il.DefineLabel();
-            CompileInstructions(il, state, ds);
-            for (int i = 1; i < nArgs; i++) {
-              Label nextArgBranch = il.DefineLabel();
-              // complex definition because of special properties of NaN  
-              il.Emit(System.Reflection.Emit.OpCodes.Dup);
-              il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_0); // <= 0        
-              il.Emit(System.Reflection.Emit.OpCodes.Ble, nextArgBranch);
-              il.Emit(System.Reflection.Emit.OpCodes.Br, resultBranch);
-              il.MarkLabel(nextArgBranch);
-              il.Emit(System.Reflection.Emit.OpCodes.Pop);
-              CompileInstructions(il, state, ds);
-            }
-            il.MarkLabel(resultBranch);
-            il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_0); // > 0
-            il.Emit(System.Reflection.Emit.OpCodes.Cgt);
-            il.Emit(System.Reflection.Emit.OpCodes.Brtrue, trueBranch);
-            il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 1.0); // -1
-            il.Emit(System.Reflection.Emit.OpCodes.Neg);
-            il.Emit(System.Reflection.Emit.OpCodes.Br, end);
-            il.MarkLabel(trueBranch);
-            il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 1.0); // 1
-            il.MarkLabel(end);
-            return;
-          }
-        case OpCodes.NOT: {
-            CompileInstructions(il, state, ds);
-            il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_0); // > 0
-            il.Emit(System.Reflection.Emit.OpCodes.Cgt);
-            il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 2.0); // * 2
-            il.Emit(System.Reflection.Emit.OpCodes.Mul);
-            il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 1.0); // - 1
-            il.Emit(System.Reflection.Emit.OpCodes.Sub);
-            il.Emit(System.Reflection.Emit.OpCodes.Neg); // * -1
-            return;
-          }
-        case OpCodes.GT: {
-            CompileInstructions(il, state, ds);
-            CompileInstructions(il, state, ds);
-
-            il.Emit(System.Reflection.Emit.OpCodes.Cgt); // 1 (>) / 0 (otherwise)
-            il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 2.0); // * 2
-            il.Emit(System.Reflection.Emit.OpCodes.Mul);
-            il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 1.0); // - 1
-            il.Emit(System.Reflection.Emit.OpCodes.Sub);
-            return;
-          }
-        case OpCodes.LT: {
-            CompileInstructions(il, state, ds);
-            CompileInstructions(il, state, ds);
-            il.Emit(System.Reflection.Emit.OpCodes.Clt);
-            il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 2.0); // * 2
-            il.Emit(System.Reflection.Emit.OpCodes.Mul);
-            il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 1.0); // - 1
-            il.Emit(System.Reflection.Emit.OpCodes.Sub);
-            return;
-          }
-        case OpCodes.TimeLag: {
-            LaggedTreeNode laggedTreeNode = (LaggedTreeNode)currentInstr.dynamicNode;
-            il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); // row -= lag
-            il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, laggedTreeNode.Lag);
-            il.Emit(System.Reflection.Emit.OpCodes.Add);
-            il.Emit(System.Reflection.Emit.OpCodes.Starg, 0);
-            var prevLaggedContext = state.InLaggedContext;
-            state.InLaggedContext = true;
-            CompileInstructions(il, state, ds);
-            il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); // row += lag
-            il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, laggedTreeNode.Lag);
-            il.Emit(System.Reflection.Emit.OpCodes.Sub);
-            il.Emit(System.Reflection.Emit.OpCodes.Starg, 0);
-            state.InLaggedContext = prevLaggedContext;
-            return;
-          }
-        case OpCodes.Integral: {
-            int savedPc = state.ProgramCounter;
-            LaggedTreeNode laggedTreeNode = (LaggedTreeNode)currentInstr.dynamicNode;
-            il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); // row -= lag
-            il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, laggedTreeNode.Lag);
-            il.Emit(System.Reflection.Emit.OpCodes.Add);
-            il.Emit(System.Reflection.Emit.OpCodes.Starg, 0);
-            var prevLaggedContext = state.InLaggedContext;
-            state.InLaggedContext = true;
-            CompileInstructions(il, state, ds);
-            for (int l = laggedTreeNode.Lag; l < 0; l++) {
-              il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); // row += lag
-              il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_1);
-              il.Emit(System.Reflection.Emit.OpCodes.Add);
-              il.Emit(System.Reflection.Emit.OpCodes.Starg, 0);
-              state.ProgramCounter = savedPc;
-              CompileInstructions(il, state, ds);
-              il.Emit(System.Reflection.Emit.OpCodes.Add);
-            }
-            state.InLaggedContext = prevLaggedContext;
-            return;
-          }
-
-        //mkommend: derivate calculation taken from: 
-        //http://www.holoborodko.com/pavel/numerical-methods/numerical-derivative/smooth-low-noise-differentiators/
-        //one sided smooth differentiatior, N = 4
-        // y' = 1/8h (f_i + 2f_i-1, -2 f_i-3 - f_i-4)
-        case OpCodes.Derivative: {
-            int savedPc = state.ProgramCounter;
-            CompileInstructions(il, state, ds);
-            il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); // row --
-            il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_M1);
-            il.Emit(System.Reflection.Emit.OpCodes.Add);
-            il.Emit(System.Reflection.Emit.OpCodes.Starg, 0);
-            state.ProgramCounter = savedPc;
-            var prevLaggedContext = state.InLaggedContext;
-            state.InLaggedContext = true;
-            CompileInstructions(il, state, ds);
-            il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 2.0); // f_0 + 2 * f_1
-            il.Emit(System.Reflection.Emit.OpCodes.Mul);
-            il.Emit(System.Reflection.Emit.OpCodes.Add);
-
-            il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); // row -=2
-            il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_2);
-            il.Emit(System.Reflection.Emit.OpCodes.Sub);
-            il.Emit(System.Reflection.Emit.OpCodes.Starg, 0);
-            state.ProgramCounter = savedPc;
-            CompileInstructions(il, state, ds);
-            il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 2.0); // f_0 + 2 * f_1 - 2 * f_3
-            il.Emit(System.Reflection.Emit.OpCodes.Mul);
-            il.Emit(System.Reflection.Emit.OpCodes.Sub);
-
-            il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); // row --
-            il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_M1);
-            il.Emit(System.Reflection.Emit.OpCodes.Add);
-            il.Emit(System.Reflection.Emit.OpCodes.Starg, 0);
-            state.ProgramCounter = savedPc;
-            CompileInstructions(il, state, ds);
-            il.Emit(System.Reflection.Emit.OpCodes.Sub); // f_0 + 2 * f_1 - 2 * f_3 - f_4
-            il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 8.0); // / 8
-            il.Emit(System.Reflection.Emit.OpCodes.Div);
-
-            il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); // row +=4
-            il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_4);
-            il.Emit(System.Reflection.Emit.OpCodes.Add);
-            il.Emit(System.Reflection.Emit.OpCodes.Starg, 0);
-            state.InLaggedContext = prevLaggedContext;
-            return;
-          }
-        case OpCodes.Call: {
-            throw new NotSupportedException(
-              "Automatically defined functions are not supported by the SymbolicDataAnalysisTreeILEmittingInterpreter. Either turn of ADFs or change the interpeter.");
-          }
-        case OpCodes.Arg: {
-            throw new NotSupportedException(
-              "Automatically defined functions are not supported by the SymbolicDataAnalysisTreeILEmittingInterpreter. Either turn of ADFs or change the interpeter.");
-          }
-        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.Call, listGetValue);
-              il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, varNode.Weight); // load weight
-              il.Emit(System.Reflection.Emit.OpCodes.Mul);
-            } else {
-              var nanResult = il.DefineLabel();
-              var normalResult = il.DefineLabel();
-              il.Emit(System.Reflection.Emit.OpCodes.Dup);
-              il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_0);
-              il.Emit(System.Reflection.Emit.OpCodes.Blt, nanResult);
-              il.Emit(System.Reflection.Emit.OpCodes.Dup);
-              il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, ds.Rows);
-              il.Emit(System.Reflection.Emit.OpCodes.Bge, nanResult);
-              il.Emit(System.Reflection.Emit.OpCodes.Call, listGetValue);
-              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); // rowIndex
-              il.Emit(System.Reflection.Emit.OpCodes.Pop); // column reference
-              il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, double.NaN);
-              il.MarkLabel(normalResult);
-            }
-            return;
-          }
-        case OpCodes.LagVariable: {
-            var nanResult = il.DefineLabel();
-            var normalResult = 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
-            il.Emit(System.Reflection.Emit.OpCodes.Add); // actualRowIndex = rowIndex + sampleOffset
-            il.Emit(System.Reflection.Emit.OpCodes.Dup);
-            il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_0);
-            il.Emit(System.Reflection.Emit.OpCodes.Blt, nanResult);
-            il.Emit(System.Reflection.Emit.OpCodes.Dup);
-            il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, ds.Rows);
-            il.Emit(System.Reflection.Emit.OpCodes.Bge, nanResult);
-            il.Emit(System.Reflection.Emit.OpCodes.Call, listGetValue);
-            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.Ldc_R8, double.NaN);
-            il.MarkLabel(normalResult);
-            return;
-          }
-        case OpCodes.Constant: {
-            ConstantTreeNode constNode = (ConstantTreeNode)currentInstr.dynamicNode;
-            il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, constNode.Value);
-            return;
-          }
-
-        //mkommend: this symbol uses the logistic function f(x) = 1 / (1 + e^(-alpha * x) ) 
-        //to determine the relative amounts of the true and false branch see http://en.wikipedia.org/wiki/Logistic_function
-        case OpCodes.VariableCondition: {
-            throw new NotSupportedException("Interpretation of symbol " + currentInstr.dynamicNode.Symbol.Name +
-                                            " is not supported by the SymbolicDataAnalysisTreeILEmittingInterpreter");
-          }
-        default:
-          throw new NotSupportedException("Interpretation of symbol " + currentInstr.dynamicNode.Symbol.Name +
-                                          " is not supported by the SymbolicDataAnalysisTreeILEmittingInterpreter");
-      }
-    }
-
-    private byte MapSymbolToOpCode(ISymbolicExpressionTreeNode treeNode) {
-      byte opCode;
-      if (!symbolToOpcode.TryGetValue(treeNode.Symbol.GetType(), out opCode))
-        throw new NotSupportedException("Symbol: " + treeNode.Symbol);
-      return opCode;
-    }
-
-
-    public static double AiryA(double x) {
-      if (double.IsNaN(x)) return double.NaN;
-      double ai, aip, bi, bip;
-      alglib.airy(x, out ai, out aip, out bi, out bip);
-      return ai;
-    }
-
-    public static double AiryB(double x) {
-      if (double.IsNaN(x)) return double.NaN;
-      double ai, aip, bi, bip;
-      alglib.airy(x, out ai, out aip, out bi, out bip);
-      return bi;
-    }
-    public static double Dawson(double x) {
-      if (double.IsNaN(x)) return double.NaN;
-      return alglib.dawsonintegral(x);
-    }
-
-    public static double Gamma(double x) {
-      if (double.IsNaN(x)) return double.NaN;
-      return alglib.gammafunction(x);
-    }
-
-    public static double Psi(double x) {
-      if (double.IsNaN(x)) return double.NaN;
-      else if (x <= 0 && (Math.Floor(x) - x).IsAlmost(0)) return double.NaN;
-      return alglib.psi(x);
-    }
-
-    public static double ExpIntegralEi(double x) {
-      if (double.IsNaN(x)) return double.NaN;
-      return alglib.exponentialintegralei(x);
-    }
-
-    public static double SinIntegral(double x) {
-      if (double.IsNaN(x)) return double.NaN;
-      double si, ci;
-      alglib.sinecosineintegrals(x, out si, out ci);
-      return si;
-    }
-
-    public static double CosIntegral(double x) {
-      if (double.IsNaN(x)) return double.NaN;
-      double si, ci;
-      alglib.sinecosineintegrals(x, out si, out ci);
-      return ci;
-    }
-
-    public static double HypSinIntegral(double x) {
-      if (double.IsNaN(x)) return double.NaN;
-      double shi, chi;
-      alglib.hyperbolicsinecosineintegrals(x, out shi, out chi);
-      return shi;
-    }
-
-    public static double HypCosIntegral(double x) {
-      if (double.IsNaN(x)) return double.NaN;
-      double shi, chi;
-      alglib.hyperbolicsinecosineintegrals(x, out shi, out chi);
-      return chi;
-    }
-
-    public static double FresnelCosIntegral(double x) {
-      if (double.IsNaN(x)) return double.NaN;
-      double c = 0, s = 0;
-      alglib.fresnelintegral(x, ref c, ref s);
-      return c;
-    }
-
-    public static double FresnelSinIntegral(double x) {
-      if (double.IsNaN(x)) return double.NaN;
-      double c = 0, s = 0;
-      alglib.fresnelintegral(x, ref c, ref s);
-      return s;
-    }
-
-    public static double Norm(double x) {
-      if (double.IsNaN(x)) return double.NaN;
-      return alglib.normaldistribution(x);
-    }
-
-    public static double Erf(double x) {
-      if (double.IsNaN(x)) return double.NaN;
-      return alglib.errorfunction(x);
-    }
-
-    public static double Bessel(double x) {
-      if (double.IsNaN(x)) return double.NaN;
-      return alglib.besseli0(x);
-    }
-
-  }
-}
Index: unk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeInterpreter.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeInterpreter.cs	(revision 8797)
+++ 	(revision )
@@ -1,634 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2012 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 HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
-  [StorableClass]
-  [Item("SymbolicDataAnalysisExpressionTreeInterpreter", "Interpreter for symbolic expression trees including automatically defined functions.")]
-  public sealed class SymbolicDataAnalysisExpressionTreeInterpreter : ParameterizedNamedItem, ISymbolicDataAnalysisExpressionTreeInterpreter {
-    private const string CheckExpressionsWithIntervalArithmeticParameterName = "CheckExpressionsWithIntervalArithmetic";
-    private const string EvaluatedSolutionsParameterName = "EvaluatedSolutions";
-    #region private classes
-    private class InterpreterState {
-      private double[] argumentStack;
-      private int argumentStackPointer;
-      private Instruction[] code;
-      private int pc;
-      public int ProgramCounter {
-        get { return pc; }
-        set { pc = value; }
-      }
-      internal InterpreterState(Instruction[] code, int argumentStackSize) {
-        this.code = code;
-        this.pc = 0;
-        if (argumentStackSize > 0) {
-          this.argumentStack = new double[argumentStackSize];
-        }
-        this.argumentStackPointer = 0;
-      }
-
-      internal void Reset() {
-        this.pc = 0;
-        this.argumentStackPointer = 0;
-      }
-
-      internal Instruction NextInstruction() {
-        return code[pc++];
-      }
-      private void Push(double val) {
-        argumentStack[argumentStackPointer++] = val;
-      }
-      private double Pop() {
-        return argumentStack[--argumentStackPointer];
-      }
-
-      internal void CreateStackFrame(double[] argValues) {
-        // push in reverse order to make indexing easier
-        for (int i = argValues.Length - 1; i >= 0; i--) {
-          argumentStack[argumentStackPointer++] = argValues[i];
-        }
-        Push(argValues.Length);
-      }
-
-      internal void RemoveStackFrame() {
-        int size = (int)Pop();
-        argumentStackPointer -= size;
-      }
-
-      internal double GetStackFrameValue(ushort index) {
-        // layout of stack:
-        // [0]   <- argumentStackPointer
-        // [StackFrameSize = N + 1]
-        // [Arg0] <- argumentStackPointer - 2 - 0
-        // [Arg1] <- argumentStackPointer - 2 - 1
-        // [...]
-        // [ArgN] <- argumentStackPointer - 2 - N
-        // <Begin of stack frame>
-        return argumentStack[argumentStackPointer - index - 2];
-      }
-    }
-    private class OpCodes {
-      public const byte Add = 1;
-      public const byte Sub = 2;
-      public const byte Mul = 3;
-      public const byte Div = 4;
-
-      public const byte Sin = 5;
-      public const byte Cos = 6;
-      public const byte Tan = 7;
-
-      public const byte Log = 8;
-      public const byte Exp = 9;
-
-      public const byte IfThenElse = 10;
-
-      public const byte GT = 11;
-      public const byte LT = 12;
-
-      public const byte AND = 13;
-      public const byte OR = 14;
-      public const byte NOT = 15;
-
-
-      public const byte Average = 16;
-
-      public const byte Call = 17;
-
-      public const byte Variable = 18;
-      public const byte LagVariable = 19;
-      public const byte Constant = 20;
-      public const byte Arg = 21;
-
-      public const byte Power = 22;
-      public const byte Root = 23;
-      public const byte TimeLag = 24;
-      public const byte Integral = 25;
-      public const byte Derivative = 26;
-
-      public const byte VariableCondition = 27;
-
-      public const byte Square = 28;
-      public const byte SquareRoot = 29;
-      public const byte Gamma = 30;
-      public const byte Psi = 31;
-      public const byte Dawson = 32;
-      public const byte ExponentialIntegralEi = 33;
-      public const byte CosineIntegral = 34;
-      public const byte SineIntegral = 35;
-      public const byte HyperbolicCosineIntegral = 36;
-      public const byte HyperbolicSineIntegral = 37;
-      public const byte FresnelCosineIntegral = 38;
-      public const byte FresnelSineIntegral = 39;
-      public const byte AiryA = 40;
-      public const byte AiryB = 41;
-      public const byte Norm = 42;
-      public const byte Erf = 43;
-      public const byte Bessel = 44;
-    }
-    #endregion
-
-    private Dictionary<Type, byte> symbolToOpcode = new Dictionary<Type, byte>() {
-      { typeof(Addition), OpCodes.Add },
-      { typeof(Subtraction), OpCodes.Sub },
-      { typeof(Multiplication), OpCodes.Mul },
-      { typeof(Division), OpCodes.Div },
-      { typeof(Sine), OpCodes.Sin },
-      { typeof(Cosine), OpCodes.Cos },
-      { typeof(Tangent), OpCodes.Tan },
-      { typeof(Logarithm), OpCodes.Log },
-      { typeof(Exponential), OpCodes.Exp },
-      { typeof(IfThenElse), OpCodes.IfThenElse },
-      { typeof(GreaterThan), OpCodes.GT },
-      { typeof(LessThan), OpCodes.LT },
-      { typeof(And), OpCodes.AND },
-      { typeof(Or), OpCodes.OR },
-      { typeof(Not), OpCodes.NOT},
-      { typeof(Average), OpCodes.Average},
-      { typeof(InvokeFunction), OpCodes.Call },
-      { typeof(Variable), OpCodes.Variable },
-      { typeof(LaggedVariable), OpCodes.LagVariable },
-      { typeof(Constant), OpCodes.Constant },
-      { typeof(Argument), OpCodes.Arg },
-      { typeof(Power),OpCodes.Power},
-      { typeof(Root),OpCodes.Root},
-      { typeof(TimeLag), OpCodes.TimeLag}, 
-      { typeof(Integral), OpCodes.Integral},
-      { typeof(Derivative), OpCodes.Derivative},
-      { typeof(VariableCondition),OpCodes.VariableCondition},
-      { typeof(Square),OpCodes.Square},
-      { typeof(SquareRoot),OpCodes.SquareRoot},
-      { typeof(Gamma), OpCodes.Gamma },
-      { typeof(Psi), OpCodes.Psi },
-      { typeof(Dawson), OpCodes.Dawson},
-      { typeof(ExponentialIntegralEi), OpCodes.ExponentialIntegralEi },
-      { typeof(CosineIntegral), OpCodes.CosineIntegral },
-      { typeof(SineIntegral), OpCodes.SineIntegral },
-      { typeof(HyperbolicCosineIntegral), OpCodes.HyperbolicCosineIntegral },
-      { typeof(HyperbolicSineIntegral), OpCodes.HyperbolicSineIntegral },
-      { typeof(FresnelCosineIntegral), OpCodes.FresnelCosineIntegral },
-      { typeof(FresnelSineIntegral), OpCodes.FresnelSineIntegral },
-      { typeof(AiryA), OpCodes.AiryA },
-      { typeof(AiryB), OpCodes.AiryB },
-      { typeof(Norm), OpCodes.Norm},
-      { typeof(Erf), OpCodes.Erf},
-      { typeof(Bessel), OpCodes.Bessel}
-    };
-
-    public override bool CanChangeName {
-      get { return false; }
-    }
-    public override bool CanChangeDescription {
-      get { return false; }
-    }
-
-    #region parameter properties
-    public IValueParameter<BoolValue> CheckExpressionsWithIntervalArithmeticParameter {
-      get { return (IValueParameter<BoolValue>)Parameters[CheckExpressionsWithIntervalArithmeticParameterName]; }
-    }
-
-    public IValueParameter<IntValue> EvaluatedSolutionsParameter {
-      get { return (IValueParameter<IntValue>)Parameters[EvaluatedSolutionsParameterName]; }
-    }
-    #endregion
-
-    #region properties
-    public BoolValue CheckExpressionsWithIntervalArithmetic {
-      get { return CheckExpressionsWithIntervalArithmeticParameter.Value; }
-      set { CheckExpressionsWithIntervalArithmeticParameter.Value = value; }
-    }
-
-    public IntValue EvaluatedSolutions {
-      get { return EvaluatedSolutionsParameter.Value; }
-      set { EvaluatedSolutionsParameter.Value = value; }
-    }
-    #endregion
-
-    [StorableConstructor]
-    private SymbolicDataAnalysisExpressionTreeInterpreter(bool deserializing) : base(deserializing) { }
-    private SymbolicDataAnalysisExpressionTreeInterpreter(SymbolicDataAnalysisExpressionTreeInterpreter original, Cloner cloner) : base(original, cloner) { }
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new SymbolicDataAnalysisExpressionTreeInterpreter(this, cloner);
-    }
-
-    public SymbolicDataAnalysisExpressionTreeInterpreter()
-      : base("SymbolicDataAnalysisExpressionTreeInterpreter", "Interpreter for symbolic expression trees including automatically defined functions.") {
-      Parameters.Add(new ValueParameter<BoolValue>(CheckExpressionsWithIntervalArithmeticParameterName, "Switch that determines if the interpreter checks the validity of expressions with interval arithmetic before evaluating the expression.", new BoolValue(false)));
-      Parameters.Add(new ValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0)));
-    }
-
-    [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserialization() {
-      if (!Parameters.ContainsKey(EvaluatedSolutionsParameterName))
-        Parameters.Add(new ValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0)));
-    }
-
-    #region IStatefulItem
-    public void InitializeState() {
-      EvaluatedSolutions.Value = 0;
-    }
-
-    public void ClearState() {
-    }
-    #endregion
-
-    public IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, IEnumerable<int> rows) {
-      if (CheckExpressionsWithIntervalArithmetic.Value)
-        throw new NotSupportedException("Interval arithmetic is not yet supported in the symbolic data analysis interpreter.");
-      EvaluatedSolutions.Value++; // increment the evaluated solutions counter
-      var compiler = new SymbolicExpressionTreeCompiler();
-      Instruction[] code = compiler.Compile(tree, MapSymbolToOpCode);
-      int necessaryArgStackSize = 0;
-      for (int i = 0; i < code.Length; i++) {
-        Instruction instr = code[i];
-        if (instr.opCode == OpCodes.Variable) {
-          var variableTreeNode = instr.dynamicNode as VariableTreeNode;
-          instr.iArg0 = dataset.GetReadOnlyDoubleValues(variableTreeNode.VariableName);
-          code[i] = instr;
-        } else if (instr.opCode == OpCodes.LagVariable) {
-          var laggedVariableTreeNode = instr.dynamicNode as LaggedVariableTreeNode;
-          instr.iArg0 = dataset.GetReadOnlyDoubleValues(laggedVariableTreeNode.VariableName);
-          code[i] = instr;
-        } else if (instr.opCode == OpCodes.VariableCondition) {
-          var variableConditionTreeNode = instr.dynamicNode as VariableConditionTreeNode;
-          instr.iArg0 = dataset.GetReadOnlyDoubleValues(variableConditionTreeNode.VariableName);
-        } else if (instr.opCode == OpCodes.Call) {
-          necessaryArgStackSize += instr.nArguments + 1;
-        }
-      }
-      var state = new InterpreterState(code, necessaryArgStackSize);
-
-      foreach (var rowEnum in rows) {
-        int row = rowEnum;
-        state.Reset();
-        yield return Evaluate(dataset, ref row, state);
-      }
-    }
-
-    private double Evaluate(Dataset dataset, ref int row, InterpreterState state) {
-      Instruction currentInstr = state.NextInstruction();
-      switch (currentInstr.opCode) {
-        case OpCodes.Add: {
-            double s = Evaluate(dataset, ref row, state);
-            for (int i = 1; i < currentInstr.nArguments; i++) {
-              s += Evaluate(dataset, ref row, state);
-            }
-            return s;
-          }
-        case OpCodes.Sub: {
-            double s = Evaluate(dataset, ref row, state);
-            for (int i = 1; i < currentInstr.nArguments; i++) {
-              s -= Evaluate(dataset, ref row, state);
-            }
-            if (currentInstr.nArguments == 1) s = -s;
-            return s;
-          }
-        case OpCodes.Mul: {
-            double p = Evaluate(dataset, ref row, state);
-            for (int i = 1; i < currentInstr.nArguments; i++) {
-              p *= Evaluate(dataset, ref row, state);
-            }
-            return p;
-          }
-        case OpCodes.Div: {
-            double p = Evaluate(dataset, ref row, state);
-            for (int i = 1; i < currentInstr.nArguments; i++) {
-              p /= Evaluate(dataset, ref row, state);
-            }
-            if (currentInstr.nArguments == 1) p = 1.0 / p;
-            return p;
-          }
-        case OpCodes.Average: {
-            double sum = Evaluate(dataset, ref row, state);
-            for (int i = 1; i < currentInstr.nArguments; i++) {
-              sum += Evaluate(dataset, ref row, state);
-            }
-            return sum / currentInstr.nArguments;
-          }
-        case OpCodes.Cos: {
-            return Math.Cos(Evaluate(dataset, ref row, state));
-          }
-        case OpCodes.Sin: {
-            return Math.Sin(Evaluate(dataset, ref row, state));
-          }
-        case OpCodes.Tan: {
-            return Math.Tan(Evaluate(dataset, ref row, state));
-          }
-        case OpCodes.Square: {
-            return Math.Pow(Evaluate(dataset, ref row, state), 2);
-          }
-        case OpCodes.Power: {
-            double x = Evaluate(dataset, ref row, state);
-            double y = Math.Round(Evaluate(dataset, ref row, state));
-            return Math.Pow(x, y);
-          }
-        case OpCodes.SquareRoot: {
-            return Math.Sqrt(Evaluate(dataset, ref row, state));
-          }
-        case OpCodes.Root: {
-            double x = Evaluate(dataset, ref row, state);
-            double y = Math.Round(Evaluate(dataset, ref row, state));
-            return Math.Pow(x, 1 / y);
-          }
-        case OpCodes.Exp: {
-            return Math.Exp(Evaluate(dataset, ref row, state));
-          }
-        case OpCodes.Log: {
-            return Math.Log(Evaluate(dataset, ref row, state));
-          }
-        case OpCodes.Gamma: {
-            var x = Evaluate(dataset, ref row, state);
-            if (double.IsNaN(x)) return double.NaN;
-            else return alglib.gammafunction(x);
-          }
-        case OpCodes.Psi: {
-            var x = Evaluate(dataset, ref row, state);
-            if (double.IsNaN(x)) return double.NaN;
-            else if (x <= 0 && (Math.Floor(x) - x).IsAlmost(0)) return double.NaN;
-            return alglib.psi(x);
-          }
-        case OpCodes.Dawson: {
-            var x = Evaluate(dataset, ref row, state);
-            if (double.IsNaN(x)) return double.NaN;
-            return alglib.dawsonintegral(x);
-          }
-        case OpCodes.ExponentialIntegralEi: {
-            var x = Evaluate(dataset, ref row, state);
-            if (double.IsNaN(x)) return double.NaN;
-            return alglib.exponentialintegralei(x);
-          }
-        case OpCodes.SineIntegral: {
-            double si, ci;
-            var x = Evaluate(dataset, ref row, state);
-            if (double.IsNaN(x)) return double.NaN;
-            else {
-              alglib.sinecosineintegrals(x, out si, out ci);
-              return si;
-            }
-          }
-        case OpCodes.CosineIntegral: {
-            double si, ci;
-            var x = Evaluate(dataset, ref row, state);
-            if (double.IsNaN(x)) return double.NaN;
-            else {
-              alglib.sinecosineintegrals(x, out si, out ci);
-              return ci;
-            }
-          }
-        case OpCodes.HyperbolicSineIntegral: {
-            double shi, chi;
-            var x = Evaluate(dataset, ref row, state);
-            if (double.IsNaN(x)) return double.NaN;
-            else {
-              alglib.hyperbolicsinecosineintegrals(x, out shi, out chi);
-              return shi;
-            }
-          }
-        case OpCodes.HyperbolicCosineIntegral: {
-            double shi, chi;
-            var x = Evaluate(dataset, ref row, state);
-            if (double.IsNaN(x)) return double.NaN;
-            else {
-              alglib.hyperbolicsinecosineintegrals(x, out shi, out chi);
-              return chi;
-            }
-          }
-        case OpCodes.FresnelCosineIntegral: {
-            double c = 0, s = 0;
-            var x = Evaluate(dataset, ref row, state);
-            if (double.IsNaN(x)) return double.NaN;
-            else {
-              alglib.fresnelintegral(x, ref c, ref s);
-              return c;
-            }
-          }
-        case OpCodes.FresnelSineIntegral: {
-            double c = 0, s = 0;
-            var x = Evaluate(dataset, ref row, state);
-            if (double.IsNaN(x)) return double.NaN;
-            else {
-              alglib.fresnelintegral(x, ref c, ref s);
-              return s;
-            }
-          }
-        case OpCodes.AiryA: {
-            double ai, aip, bi, bip;
-            var x = Evaluate(dataset, ref row, state);
-            if (double.IsNaN(x)) return double.NaN;
-            else {
-              alglib.airy(x, out ai, out aip, out bi, out bip);
-              return ai;
-            }
-          }
-        case OpCodes.AiryB: {
-            double ai, aip, bi, bip;
-            var x = Evaluate(dataset, ref row, state);
-            if (double.IsNaN(x)) return double.NaN;
-            else {
-              alglib.airy(x, out ai, out aip, out bi, out bip);
-              return bi;
-            }
-          }
-        case OpCodes.Norm: {
-            var x = Evaluate(dataset, ref row, state);
-            if (double.IsNaN(x)) return double.NaN;
-            else return alglib.normaldistribution(x);
-          }
-        case OpCodes.Erf: {
-            var x = Evaluate(dataset, ref row, state);
-            if (double.IsNaN(x)) return double.NaN;
-            else return alglib.errorfunction(x);
-          }
-        case OpCodes.Bessel: {
-            var x = Evaluate(dataset, ref row, state);
-            if (double.IsNaN(x)) return double.NaN;
-            else return alglib.besseli0(x);
-          }
-        case OpCodes.IfThenElse: {
-            double condition = Evaluate(dataset, ref row, state);
-            double result;
-            if (condition > 0.0) {
-              result = Evaluate(dataset, ref row, state); SkipInstructions(state);
-            } else {
-              SkipInstructions(state); result = Evaluate(dataset, ref row, state);
-            }
-            return result;
-          }
-        case OpCodes.AND: {
-            double result = Evaluate(dataset, ref row, state);
-            for (int i = 1; i < currentInstr.nArguments; i++) {
-              if (result > 0.0) result = Evaluate(dataset, ref row, state);
-              else {
-                SkipInstructions(state);
-              }
-            }
-            return result > 0.0 ? 1.0 : -1.0;
-          }
-        case OpCodes.OR: {
-            double result = Evaluate(dataset, ref row, state);
-            for (int i = 1; i < currentInstr.nArguments; i++) {
-              if (result <= 0.0) result = Evaluate(dataset, ref row, state);
-              else {
-                SkipInstructions(state);
-              }
-            }
-            return result > 0.0 ? 1.0 : -1.0;
-          }
-        case OpCodes.NOT: {
-            return Evaluate(dataset, ref row, state) > 0.0 ? -1.0 : 1.0;
-          }
-        case OpCodes.GT: {
-            double x = Evaluate(dataset, ref row, state);
-            double y = Evaluate(dataset, ref row, state);
-            if (x > y) return 1.0;
-            else return -1.0;
-          }
-        case OpCodes.LT: {
-            double x = Evaluate(dataset, ref row, state);
-            double y = Evaluate(dataset, ref row, state);
-            if (x < y) return 1.0;
-            else return -1.0;
-          }
-        case OpCodes.TimeLag: {
-            var timeLagTreeNode = (LaggedTreeNode)currentInstr.dynamicNode;
-            row += timeLagTreeNode.Lag;
-            double result = Evaluate(dataset, ref row, state);
-            row -= timeLagTreeNode.Lag;
-            return result;
-          }
-        case OpCodes.Integral: {
-            int savedPc = state.ProgramCounter;
-            var timeLagTreeNode = (LaggedTreeNode)currentInstr.dynamicNode;
-            double sum = 0.0;
-            for (int i = 0; i < Math.Abs(timeLagTreeNode.Lag); i++) {
-              row += Math.Sign(timeLagTreeNode.Lag);
-              sum += Evaluate(dataset, ref row, state);
-              state.ProgramCounter = savedPc;
-            }
-            row -= timeLagTreeNode.Lag;
-            sum += Evaluate(dataset, ref row, state);
-            return sum;
-          }
-
-        //mkommend: derivate calculation taken from: 
-        //http://www.holoborodko.com/pavel/numerical-methods/numerical-derivative/smooth-low-noise-differentiators/
-        //one sided smooth differentiatior, N = 4
-        // y' = 1/8h (f_i + 2f_i-1, -2 f_i-3 - f_i-4)
-        case OpCodes.Derivative: {
-            int savedPc = state.ProgramCounter;
-            double f_0 = Evaluate(dataset, ref row, state); row--;
-            state.ProgramCounter = savedPc;
-            double f_1 = Evaluate(dataset, ref row, state); row -= 2;
-            state.ProgramCounter = savedPc;
-            double f_3 = Evaluate(dataset, ref row, state); row--;
-            state.ProgramCounter = savedPc;
-            double f_4 = Evaluate(dataset, ref row, state);
-            row += 4;
-
-            return (f_0 + 2 * f_1 - 2 * f_3 - f_4) / 8; // h = 1
-          }
-        case OpCodes.Call: {
-            // evaluate sub-trees
-            double[] argValues = new double[currentInstr.nArguments];
-            for (int i = 0; i < currentInstr.nArguments; i++) {
-              argValues[i] = Evaluate(dataset, ref row, state);
-            }
-            // push on argument values on stack 
-            state.CreateStackFrame(argValues);
-
-            // save the pc
-            int savedPc = state.ProgramCounter;
-            // set pc to start of function  
-            state.ProgramCounter = (ushort)currentInstr.iArg0;
-            // evaluate the function
-            double v = Evaluate(dataset, ref row, state);
-
-            // delete the stack frame
-            state.RemoveStackFrame();
-
-            // restore the pc => evaluation will continue at point after my subtrees  
-            state.ProgramCounter = savedPc;
-            return v;
-          }
-        case OpCodes.Arg: {
-            return state.GetStackFrameValue((ushort)currentInstr.iArg0);
-          }
-        case OpCodes.Variable: {
-            if (row < 0 || row >= dataset.Rows)
-              return double.NaN;
-            var variableTreeNode = (VariableTreeNode)currentInstr.dynamicNode;
-            return ((IList<double>)currentInstr.iArg0)[row] * variableTreeNode.Weight;
-          }
-        case OpCodes.LagVariable: {
-            var laggedVariableTreeNode = (LaggedVariableTreeNode)currentInstr.dynamicNode;
-            int actualRow = row + laggedVariableTreeNode.Lag;
-            if (actualRow < 0 || actualRow >= dataset.Rows)
-              return double.NaN;
-            return ((IList<double>)currentInstr.iArg0)[actualRow] * laggedVariableTreeNode.Weight;
-          }
-        case OpCodes.Constant: {
-            var constTreeNode = currentInstr.dynamicNode as ConstantTreeNode;
-            return constTreeNode.Value;
-          }
-
-        //mkommend: this symbol uses the logistic function f(x) = 1 / (1 + e^(-alpha * x) ) 
-        //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)
-              return double.NaN;
-            var variableConditionTreeNode = (VariableConditionTreeNode)currentInstr.dynamicNode;
-            double variableValue = ((IList<double>)currentInstr.iArg0)[row];
-            double x = variableValue - variableConditionTreeNode.Threshold;
-            double p = 1 / (1 + Math.Exp(-variableConditionTreeNode.Slope * x));
-
-            double trueBranch = Evaluate(dataset, ref row, state);
-            double falseBranch = Evaluate(dataset, ref row, state);
-
-            return trueBranch * p + falseBranch * (1 - p);
-          }
-        default: throw new NotSupportedException();
-      }
-    }
-
-    private byte MapSymbolToOpCode(ISymbolicExpressionTreeNode treeNode) {
-      byte opCode;
-      if (!symbolToOpcode.TryGetValue(treeNode.Symbol.GetType(), out opCode))
-        throw new NotSupportedException("Symbol: " + treeNode.Symbol);
-      return opCode;
-    }
-
-    // skips a whole branch
-    private void SkipInstructions(InterpreterState state) {
-      int i = 1;
-      while (i > 0) {
-        i += state.NextInstruction().nArguments;
-        i--;
-      }
-    }
-  }
-}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeSimplifier.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeSimplifier.cs	(revision 8797)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeSimplifier.cs	(revision 8798)
@@ -52,4 +52,7 @@
     private GreaterThan gtSymbol = new GreaterThan();
     private LessThan ltSymbol = new LessThan();
+    private Integral integralSymbol = new Integral();
+    private LaggedVariable laggedVariableSymbol = new LaggedVariable();
+    private TimeLag timeLagSymbol = new TimeLag();
 
     public ISymbolicExpressionTree Simplify(ISymbolicExpressionTree originalTree) {
@@ -182,4 +185,12 @@
     private bool IsConstant(ISymbolicExpressionTreeNode node) {
       return node.Symbol is Constant;
+    }
+
+    // dynamic
+    private bool IsTimeLag(ISymbolicExpressionTreeNode node) {
+      return node.Symbol is TimeLag;
+    }
+    private bool IsIntegral(ISymbolicExpressionTreeNode node) {
+      return node.Symbol is Integral;
     }
 
@@ -234,4 +245,8 @@
       } else if (IsNot(original)) {
         return SimplifyNot(original);
+      } else if (IsTimeLag(original)) {
+        return SimplifyTimeLag(original);
+      } else if (IsIntegral(original)) {
+        return SimplifyIntegral(original);
       } else {
         return SimplifyAny(original);
@@ -376,7 +391,47 @@
       return MakePower(GetSimplifiedTree(original.GetSubtree(0)), GetSimplifiedTree(original.GetSubtree(1)));
     }
+    private ISymbolicExpressionTreeNode SimplifyTimeLag(ISymbolicExpressionTreeNode original) {
+      var laggedTreeNode = original as ILaggedTreeNode;
+      var simplifiedSubtree = GetSimplifiedTree(original.GetSubtree(0));
+      if (!ContainsVariableCondition(simplifiedSubtree)) {
+        return AddLagToDynamicNodes(simplifiedSubtree, laggedTreeNode.Lag);
+      } else {
+        return MakeTimeLag(simplifiedSubtree, laggedTreeNode.Lag);
+      }
+    }
+    private ISymbolicExpressionTreeNode SimplifyIntegral(ISymbolicExpressionTreeNode original) {
+      var laggedTreeNode = original as ILaggedTreeNode;
+      var simplifiedSubtree = GetSimplifiedTree(original.GetSubtree(0));
+      if (IsConstant(simplifiedSubtree)) {
+        return GetSimplifiedTree(MakeProduct(simplifiedSubtree, MakeConstant(-laggedTreeNode.Lag)));
+      } else {
+        return MakeIntegral(simplifiedSubtree, laggedTreeNode.Lag);
+      }
+    }
+
     #endregion
 
     #region low level tree restructuring
+    private ISymbolicExpressionTreeNode MakeTimeLag(ISymbolicExpressionTreeNode subtree, int lag) {
+      if (lag == 0) return subtree;
+      if (IsConstant(subtree)) return subtree;
+      var lagNode = (LaggedTreeNode)timeLagSymbol.CreateTreeNode();
+      lagNode.Lag = lag;
+      lagNode.AddSubtree(subtree);
+      return lagNode;
+    }
+
+    private ISymbolicExpressionTreeNode MakeIntegral(ISymbolicExpressionTreeNode subtree, int lag) {
+      if (lag == 0) return subtree;
+      else if (lag == -1 || lag == 1) {
+        return MakeSum(subtree, AddLagToDynamicNodes((ISymbolicExpressionTreeNode)subtree.Clone(), lag));
+      } else {
+        var node = (LaggedTreeNode)integralSymbol.CreateTreeNode();
+        node.Lag = lag;
+        node.AddSubtree(subtree);
+        return node;
+      }
+    }
+
     private ISymbolicExpressionTreeNode MakeNot(ISymbolicExpressionTreeNode t) {
       if (IsConstant(t)) {
@@ -847,4 +902,32 @@
 
     #region helper functions
+    private bool ContainsVariableCondition(ISymbolicExpressionTreeNode node) {
+      if (node.Symbol is VariableCondition) return true;
+      foreach (var subtree in node.Subtrees)
+        if (ContainsVariableCondition(subtree)) return true;
+      return false;
+    }
+
+    private ISymbolicExpressionTreeNode AddLagToDynamicNodes(ISymbolicExpressionTreeNode node, int lag) {
+      var laggedTreeNode = node as ILaggedTreeNode;
+      var variableNode = node as VariableTreeNode;
+      var variableConditionNode = node as VariableConditionTreeNode;
+      if (laggedTreeNode != null)
+        laggedTreeNode.Lag += lag;
+      else if (variableNode != null) {
+        var laggedVariableNode = (LaggedVariableTreeNode)laggedVariableSymbol.CreateTreeNode();
+        laggedVariableNode.Lag = lag;
+        laggedVariableNode.VariableName = variableNode.VariableName;
+        return laggedVariableNode;
+      } else if (variableConditionNode != null) {
+        throw new NotSupportedException("Removal of time lags around variable condition symbols is not allowed.");
+      }
+      var subtrees = new List<ISymbolicExpressionTreeNode>(node.Subtrees);
+      while (node.SubtreeCount > 0) node.RemoveSubtree(0);
+      foreach (var subtree in subtrees) {
+        node.AddSubtree(AddLagToDynamicNodes(subtree, lag));
+      }
+      return node;
+    }
 
     private bool AreSameVariable(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/AutoregressiveVariable.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/AutoregressiveVariable.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/AutoregressiveVariable.cs	(revision 8798)
@@ -0,0 +1,39 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+  [StorableClass]
+  [Item("AutoregressiveTargetVariable", "Represents a variable value with a time offset.")]
+  public sealed class AutoregressiveTargetVariable : LaggedVariable {
+    [StorableConstructor]
+    private AutoregressiveTargetVariable(bool deserializing) : base(deserializing) { }
+    private AutoregressiveTargetVariable(AutoregressiveTargetVariable original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public AutoregressiveTargetVariable() : base("Autoregressive Target Variable", "Represents the target variable with a time offset.") { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new AutoregressiveTargetVariable(this, cloner);
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/LaggedVariable.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/LaggedVariable.cs	(revision 8797)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/LaggedVariable.cs	(revision 8798)
@@ -27,5 +27,5 @@
   [StorableClass]
   [Item("LaggedVariable", "Represents a variable value with a time offset.")]
-  public sealed class LaggedVariable : Variable {
+  public class LaggedVariable : Variable {
     [Storable]
     private int minLag;
@@ -41,13 +41,15 @@
     }
     [StorableConstructor]
-    private LaggedVariable(bool deserializing) : base(deserializing) { }
-    private LaggedVariable(LaggedVariable original, Cloner cloner)
+    protected LaggedVariable(bool deserializing) : base(deserializing) { }
+    protected LaggedVariable(LaggedVariable original, Cloner cloner)
       : base(original, cloner) {
       minLag = original.minLag;
       maxLag = original.maxLag;
     }
-    public LaggedVariable()
-      : base("LaggedVariable", "Represents a variable value with a time offset.") {
-      minLag = -1; maxLag = -1;
+    public LaggedVariable() : this("LaggedVariable", "Represents a variable value with a time offset.") { }
+    protected LaggedVariable(string name, string description)
+      : base(name, description) {
+      MinLag = -1;
+      MaxLag = -1;
     }
 
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/LaggedVariableTreeNode.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/LaggedVariableTreeNode.cs	(revision 8797)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/LaggedVariableTreeNode.cs	(revision 8798)
@@ -37,4 +37,8 @@
     }
 
+    public override bool HasLocalParameters {
+      get { return true; }
+    }
+
     [StorableConstructor]
     private LaggedVariableTreeNode(bool deserializing) : base(deserializing) { }
@@ -43,13 +47,7 @@
       lag = original.lag;
     }
-    private LaggedVariableTreeNode() { }
 
     public LaggedVariableTreeNode(LaggedVariable variableSymbol) : base(variableSymbol) { }
 
-    public override bool HasLocalParameters {
-      get {
-        return true;
-      }
-    }
 
     public override void ResetLocalParameters(IRandom random) {
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/Variable.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/Variable.cs	(revision 8797)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/Variable.cs	(revision 8798)
@@ -101,4 +101,15 @@
     }
 
+    public override bool Enabled {
+      get {
+        if (variableNames.Count == 0) return false;
+        return base.Enabled;
+      }
+      set {
+        if (variableNames.Count == 0) base.Enabled = false;
+        else base.Enabled = value;
+      }
+    }
+
     private const int minimumArity = 0;
     private const int maximumArity = 0;
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj	(revision 8797)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj	(revision 8798)
@@ -330,4 +330,22 @@
     <Compile Include="FeatureCorrelation\TimeframeFeatureCorrelationView.Designer.cs">
       <DependentUpon>TimeframeFeatureCorrelationView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Solution Views\TimeSeriesPrognosisSolutionView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Solution Views\TimeSeriesPrognosisSolutionView.Designer.cs">
+      <DependentUpon>TimeSeriesPrognosisSolutionView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="TimeSeriesPrognosis\TimeSeriesPrognosisResultsView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="TimeSeriesPrognosis\TimeSeriesPrognosisResultsView.Designer.cs">
+      <DependentUpon>TimeSeriesPrognosisResultsView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="TimeSeriesPrognosis\TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="TimeSeriesPrognosis\TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.Designer.cs">
+      <DependentUpon>TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.cs</DependentUpon>
     </Compile>
     <None Include="HeuristicLab.snk" />
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/Plugin.cs.frame
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/Plugin.cs.frame	(revision 8797)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/Plugin.cs.frame	(revision 8798)
@@ -47,2 +47,3 @@
   }
 }
+
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/DataAnalysisSolutionView.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/DataAnalysisSolutionView.cs	(revision 8797)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/DataAnalysisSolutionView.cs	(revision 8798)
@@ -147,4 +147,18 @@
     }
 
+    protected override void RebuildImageList() {
+      itemsListView.SmallImageList.Images.Clear();
+      foreach (ListViewItem listViewItem in itemsListView.Items) {
+        IResult result = listViewItem.Tag as IResult;
+        Type viewType = listViewItem.Tag as Type;
+        if (result != null) itemsListView.SmallImageList.Images.Add(result.ItemImage);
+        else if (viewType != null && typeof(IDataAnalysisSolutionEvaluationView).IsAssignableFrom(viewType))
+          itemsListView.SmallImageList.Images.Add(((IDataAnalysisSolutionEvaluationView)Activator.CreateInstance(viewType)).ViewImage);
+        else itemsListView.SmallImageList.Images.Add(HeuristicLab.Common.Resources.VSImageLibrary.Nothing);
+
+        listViewItem.ImageIndex = itemsListView.SmallImageList.Images.Count - 1;
+      }
+    }
+
     #region drag and drop
     protected override void itemsListView_DragEnter(object sender, DragEventArgs e) {
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/NamedDataAnalysisSolutionView.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/NamedDataAnalysisSolutionView.cs	(revision 8797)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/NamedDataAnalysisSolutionView.cs	(revision 8798)
@@ -53,7 +53,9 @@
         contentType = Content.GetType();
         panel.Controls.Clear();
-        var viewType = MainFormManager.GetViewTypes(Content.GetType(), true).Where(t => typeof(DataAnalysisSolutionView).IsAssignableFrom(t)).FirstOrDefault();
+        var viewType = MainFormManager.GetViewTypes(Content.GetType(), true).FirstOrDefault(t => typeof(DataAnalysisSolutionView).IsAssignableFrom(t));
         if (viewType != null) {
-          view = (DataAnalysisSolutionView)Activator.CreateInstance(viewType);
+          view = (DataAnalysisSolutionView)MainFormManager.CreateView(viewType);
+          view.Locked = Locked;
+          view.ReadOnly = ReadOnly;
           view.Dock = DockStyle.Fill;
           view.Content = Content;
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/TimeSeriesPrognosisSolutionView.Designer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/TimeSeriesPrognosisSolutionView.Designer.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/TimeSeriesPrognosisSolutionView.Designer.cs	(revision 8798)
@@ -0,0 +1,73 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class TimeSeriesPrognosisSolutionView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
+      this.splitContainer.Panel1.SuspendLayout();
+      this.splitContainer.Panel2.SuspendLayout();
+      this.splitContainer.SuspendLayout();
+      this.itemsGroupBox.SuspendLayout();
+      this.detailsGroupBox.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // itemsGroupBox
+      // 
+      this.itemsGroupBox.Text = "Time-series Prognosis Solution";
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Name = "RegressionSolutionView";
+      this.splitContainer.Panel1.ResumeLayout(false);
+      this.splitContainer.Panel2.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
+      this.splitContainer.ResumeLayout(false);
+      this.itemsGroupBox.ResumeLayout(false);
+      this.detailsGroupBox.ResumeLayout(false);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/TimeSeriesPrognosisSolutionView.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/TimeSeriesPrognosisSolutionView.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/TimeSeriesPrognosisSolutionView.cs	(revision 8798)
@@ -0,0 +1,53 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Windows.Forms;
+using HeuristicLab.Core;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("TimeSeriesPrognosisSolution View")]
+  [Content(typeof(TimeSeriesPrognosisSolution), false)]
+  public partial class TimeSeriesPrognosisSolutionView : RegressionSolutionView {
+    public TimeSeriesPrognosisSolutionView() {
+      InitializeComponent();
+    }
+
+    public new TimeSeriesPrognosisSolution Content {
+      get { return (TimeSeriesPrognosisSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    #region drag and drop
+    protected override void itemsListView_DragEnter(object sender, DragEventArgs e) {
+      validDragOperation = false;
+      if (ReadOnly) return;
+
+      var dropData = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
+      if (dropData is ITimeSeriesPrognosisProblemData) validDragOperation = true;
+      else if (dropData is IValueParameter) {
+        var param = (IValueParameter)dropData;
+        if (param.Value is ITimeSeriesPrognosisProblemData) validDragOperation = true;
+      }
+    }
+    #endregion
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisResultsView.Designer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisResultsView.Designer.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisResultsView.Designer.cs	(revision 8798)
@@ -0,0 +1,169 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class TimeSeriesPrognosisResultsView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.components = new System.ComponentModel.Container();
+      this.TrainingHorizonLabel = new System.Windows.Forms.Label();
+      this.TestHorizonLabel = new System.Windows.Forms.Label();
+      this.TrainingHorizonTextBox = new System.Windows.Forms.TextBox();
+      this.TestHorizonTextBox = new System.Windows.Forms.TextBox();
+      this.TrainingHorizonErrorProvider = new System.Windows.Forms.ErrorProvider(this.components);
+      this.TestHorizonErrorProvider = new System.Windows.Forms.ErrorProvider(this.components);
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
+      this.splitContainer.Panel1.SuspendLayout();
+      this.splitContainer.Panel2.SuspendLayout();
+      this.splitContainer.SuspendLayout();
+      this.itemsGroupBox.SuspendLayout();
+      this.detailsGroupBox.SuspendLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.TrainingHorizonErrorProvider)).BeginInit();
+      ((System.ComponentModel.ISupportInitialize)(this.TestHorizonErrorProvider)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // splitContainer
+      // 
+      // 
+      // splitContainer.Panel1
+      // 
+      this.splitContainer.Panel1.Controls.Add(this.TestHorizonTextBox);
+      this.splitContainer.Panel1.Controls.Add(this.TrainingHorizonTextBox);
+      this.splitContainer.Panel1.Controls.Add(this.TrainingHorizonLabel);
+      this.splitContainer.Panel1.Controls.Add(this.TestHorizonLabel);
+      // 
+      // itemsListView
+      // 
+      this.itemsListView.Location = new System.Drawing.Point(3, 82);
+      this.itemsListView.Size = new System.Drawing.Size(244, 279);
+      // 
+      // addButton
+      // 
+      this.toolTip.SetToolTip(this.addButton, "Add");
+      // 
+      // removeButton
+      // 
+      this.toolTip.SetToolTip(this.removeButton, "Remove");
+      // 
+      // TrainingHorizonLabel
+      // 
+      this.TrainingHorizonLabel.AutoSize = true;
+      this.TrainingHorizonLabel.Location = new System.Drawing.Point(3, 34);
+      this.TrainingHorizonLabel.Name = "TrainingHorizonLabel";
+      this.TrainingHorizonLabel.Size = new System.Drawing.Size(87, 13);
+      this.TrainingHorizonLabel.TabIndex = 7;
+      this.TrainingHorizonLabel.Text = "Training Horizon:";
+      // 
+      // TestHorizonLabel
+      // 
+      this.TestHorizonLabel.AutoSize = true;
+      this.TestHorizonLabel.Location = new System.Drawing.Point(3, 60);
+      this.TestHorizonLabel.Name = "TestHorizonLabel";
+      this.TestHorizonLabel.Size = new System.Drawing.Size(73, 13);
+      this.TestHorizonLabel.TabIndex = 8;
+      this.TestHorizonLabel.Text = "Test Horizon: ";
+      // 
+      // TrainingHorizonTextBox
+      // 
+      this.TrainingHorizonTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.TrainingHorizonTextBox.Location = new System.Drawing.Point(96, 31);
+      this.TrainingHorizonTextBox.Name = "TrainingHorizonTextBox";
+      this.TrainingHorizonTextBox.Size = new System.Drawing.Size(151, 20);
+      this.TrainingHorizonTextBox.TabIndex = 1;
+      this.TrainingHorizonTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TrainingHorizonTextBox_KeyDown);
+      this.TrainingHorizonTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.TrainingHorizonTextBox_Validating);
+      this.TrainingHorizonTextBox.Validated += new System.EventHandler(this.TrainingHorizonTextBox_Validated);
+      // 
+      // TestHorizonTextBox
+      // 
+      this.TestHorizonTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.TestHorizonTextBox.Location = new System.Drawing.Point(96, 57);
+      this.TestHorizonTextBox.Name = "TestHorizonTextBox";
+      this.TestHorizonTextBox.Size = new System.Drawing.Size(151, 20);
+      this.TestHorizonTextBox.TabIndex = 1;
+      this.TestHorizonTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TestHorizonTextBox_KeyDown);
+      this.TestHorizonTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.TestHorizonTextBox_Validating);
+      this.TestHorizonTextBox.Validated += new System.EventHandler(this.TestHorizonTextBox_Validated);
+      // 
+      // TrainingHorizonErrorProvider
+      // 
+      this.TrainingHorizonErrorProvider.BlinkRate = 0;
+      this.TrainingHorizonErrorProvider.BlinkStyle = System.Windows.Forms.ErrorBlinkStyle.NeverBlink;
+      this.TrainingHorizonErrorProvider.ContainerControl = this;
+      // 
+      // TestHorizonErrorProvider
+      // 
+      this.TestHorizonErrorProvider.BlinkRate = 0;
+      this.TestHorizonErrorProvider.BlinkStyle = System.Windows.Forms.ErrorBlinkStyle.NeverBlink;
+      this.TestHorizonErrorProvider.ContainerControl = this;
+      // 
+      // TimeSeriesPrognosisResultsView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Name = "TimeSeriesPrognosisResultsView";
+      this.splitContainer.Panel1.ResumeLayout(false);
+      this.splitContainer.Panel1.PerformLayout();
+      this.splitContainer.Panel2.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
+      this.splitContainer.ResumeLayout(false);
+      this.itemsGroupBox.ResumeLayout(false);
+      this.detailsGroupBox.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.TrainingHorizonErrorProvider)).EndInit();
+      ((System.ComponentModel.ISupportInitialize)(this.TestHorizonErrorProvider)).EndInit();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.TextBox TestHorizonTextBox;
+    private System.Windows.Forms.TextBox TrainingHorizonTextBox;
+    private System.Windows.Forms.Label TrainingHorizonLabel;
+    private System.Windows.Forms.Label TestHorizonLabel;
+    private System.Windows.Forms.ErrorProvider TrainingHorizonErrorProvider;
+    private System.Windows.Forms.ErrorProvider TestHorizonErrorProvider;
+
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisResultsView.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisResultsView.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisResultsView.cs	(revision 8798)
@@ -0,0 +1,144 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Windows.Forms;
+using HeuristicLab.MainForm;
+using HeuristicLab.Optimization.Views;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("TimeSeriesPrognosisResultsView")]
+  [Content(typeof(TimeSeriesPrognosisResults), IsDefaultView = true)]
+  public partial class TimeSeriesPrognosisResultsView : ResultCollectionView {
+    public new TimeSeriesPrognosisResults Content {
+      get { return (TimeSeriesPrognosisResults)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public override bool Locked {
+      get {
+        return base.Locked;
+      }
+      set {
+        base.Locked = value;
+      }
+    }
+
+    public TimeSeriesPrognosisResultsView() {
+      InitializeComponent();
+      TrainingHorizonErrorProvider.SetIconAlignment(TrainingHorizonTextBox, ErrorIconAlignment.MiddleLeft);
+      TrainingHorizonErrorProvider.SetIconPadding(TrainingHorizonTextBox, 2);
+      TestHorizonErrorProvider.SetIconAlignment(TestHorizonTextBox, ErrorIconAlignment.MiddleLeft);
+      TestHorizonErrorProvider.SetIconPadding(TestHorizonTextBox, 2);
+    }
+
+    #region Content Events
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.TrainingHorizonChanged += new System.EventHandler(Content_TrainingHorizonChanged);
+      Content.TestHorizonChanged += new System.EventHandler(Content_TestHorizonChanged);
+    }
+    protected override void DeregisterContentEvents() {
+      Content.TrainingHorizonChanged -= new System.EventHandler(Content_TrainingHorizonChanged);
+      Content.TestHorizonChanged -= new System.EventHandler(Content_TestHorizonChanged);
+      base.DeregisterContentEvents();
+    }
+
+    private void Content_TrainingHorizonChanged(object sender, System.EventArgs e) {
+      TrainingHorizonTextBox.Text = Content.TrainingHorizon.ToString();
+    }
+
+    private void Content_TestHorizonChanged(object sender, System.EventArgs e) {
+      TestHorizonTextBox.Text = Content.TestHorizon.ToString();
+    }
+    #endregion
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        TrainingHorizonTextBox.Text = string.Empty;
+        TestHorizonTextBox.Text = string.Empty;
+      } else {
+        TrainingHorizonTextBox.Text = Content.TrainingHorizon.ToString();
+        TestHorizonTextBox.Text = Content.TestHorizon.ToString();
+      }
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      //necessary cause this could be triggered by the base ctor when the controls are not created yet
+      if (TrainingHorizonTextBox == null || TestHorizonTextBox == null) return;
+      TrainingHorizonTextBox.Enabled = Content != null && !Locked;
+      TestHorizonTextBox.Enabled = Content != null && !Locked;
+    }
+
+    #region Control events
+    private void TrainingHorizonTextBox_Validating(object sender, System.ComponentModel.CancelEventArgs e) {
+      int trainingHorizon;
+      if (!int.TryParse(TrainingHorizonTextBox.Text, out trainingHorizon)) {
+        e.Cancel = true;
+        TrainingHorizonErrorProvider.SetError(TrainingHorizonTextBox, "Please enter a numeric value.");
+        TrainingHorizonTextBox.SelectAll();
+      }
+    }
+
+    private void TrainingHorizonTextBox_Validated(object sender, System.EventArgs e) {
+      Content.TrainingHorizon = int.Parse(TrainingHorizonTextBox.Text);
+      TrainingHorizonErrorProvider.SetError(TrainingHorizonTextBox, string.Empty);
+      TrainingHorizonTextBox.Text = Content.TrainingHorizon.ToString();
+    }
+
+    private void TrainingHorizonTextBox_KeyDown(object sender, KeyEventArgs e) {
+      if ((e.KeyCode == Keys.Enter) || (e.KeyCode == Keys.Return))
+        TrainingHorizonLabel.Select();  // select label to validate data
+
+      if (e.KeyCode == Keys.Escape) {
+        TrainingHorizonTextBox.Text = Content.TrainingHorizon.ToString();
+        TrainingHorizonLabel.Select();  // select label to validate data
+      }
+    }
+
+    private void TestHorizonTextBox_Validating(object sender, System.ComponentModel.CancelEventArgs e) {
+      int testHorizon;
+      if (!int.TryParse(TestHorizonTextBox.Text, out testHorizon)) {
+        e.Cancel = true;
+        TestHorizonErrorProvider.SetError(TestHorizonTextBox, "Please enter a numeric value.");
+        TestHorizonTextBox.SelectAll();
+      }
+    }
+
+    private void TestHorizonTextBox_Validated(object sender, System.EventArgs e) {
+      Content.TestHorizon = int.Parse(TestHorizonTextBox.Text);
+      TestHorizonErrorProvider.SetError(TestHorizonTextBox, string.Empty);
+      TestHorizonTextBox.Text = Content.TestHorizon.ToString();
+    }
+
+    private void TestHorizonTextBox_KeyDown(object sender, KeyEventArgs e) {
+      if ((e.KeyCode == Keys.Enter) || (e.KeyCode == Keys.Return))
+        TestHorizonLabel.Select();  // select label to validate data
+
+      if (e.KeyCode == Keys.Escape) {
+        TestHorizonTextBox.Text = Content.TestHorizon.ToString();
+        TestHorizonLabel.Select();  // select label to validate data
+      }
+    }
+    #endregion
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.Designer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.Designer.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.Designer.cs	(revision 8798)
@@ -0,0 +1,43 @@
+﻿namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.components = new System.ComponentModel.Container();
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Name = "TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView";
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.cs	(revision 8798)
@@ -0,0 +1,63 @@
+﻿#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.Collections.Generic;
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Error Characteristics Curve")]
+  [Content(typeof(ITimeSeriesPrognosisSolution))]
+  public partial class TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView : RegressionSolutionErrorCharacteristicsCurveView {
+
+
+    public TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView()
+      : base() {
+      InitializeComponent();
+    }
+
+    public new ITimeSeriesPrognosisSolution Content {
+      get { return (ITimeSeriesPrognosisSolution)base.Content; }
+      set { base.Content = value; }
+    }
+    public new ITimeSeriesPrognosisProblemData ProblemData {
+      get {
+        if (Content == null) return null;
+        return Content.ProblemData;
+      }
+    }
+
+    protected override void UpdateChart() {
+      base.UpdateChart();
+      if (Content == null) return;
+
+      //AR1 model
+      double alpha, beta;
+      OnlineCalculatorError errorState;
+      IEnumerable<double> trainingStartValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices.Select(r => r - 1).Where(r => r > 0)).ToList();
+      OnlineLinearScalingParameterCalculator.Calculate(ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices.Where(x => x > 0)), trainingStartValues, out alpha, out beta, out errorState);
+      var AR1model = new TimeSeriesPrognosisAutoRegressiveModel(ProblemData.TargetVariable, new double[] { beta }, alpha).CreateTimeSeriesPrognosisSolution(ProblemData);
+      AR1model.Name = "AR(1) Model";
+      AddRegressionSolution(AR1model);
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Dataset.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Dataset.cs	(revision 8797)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Dataset.cs	(revision 8798)
@@ -193,6 +193,5 @@
       if (values == null) throw new ArgumentException("The varialbe " + variableName + " is not a double variable.");
 
-      foreach (int index in rows)
-        yield return values[index];
+      return rows.Select(index => values[index]);
     }
 
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/DatasetExtensions.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/DatasetExtensions.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/DatasetExtensions.cs	(revision 8798)
@@ -0,0 +1,34 @@
+#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.Collections.Generic;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public static class DatasetExtensions {
+    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: /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj	(revision 8797)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj	(revision 8798)
@@ -116,4 +116,5 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="DatasetExtensions.cs" />
     <Compile Include="DoubleLimit.cs" />
     <Compile Include="Implementation\Classification\ClassificationEnsembleModel.cs">
@@ -137,4 +138,11 @@
     </Compile>
     <Compile Include="Implementation\Regression\RegressionEnsembleSolution.cs" />
+    <Compile Include="Implementation\TimeSeriesPrognosis\Models\ConstantTimeSeriesPrognosisModel.cs" />
+    <Compile Include="Implementation\TimeSeriesPrognosis\Models\TimeSeriesPrognosisAutoRegressiveModel.cs" />
+    <Compile Include="Implementation\TimeSeriesPrognosis\TimeSeriesPrognosisProblem.cs" />
+    <Compile Include="Implementation\TimeSeriesPrognosis\TimeSeriesPrognosisProblemData.cs" />
+    <Compile Include="Implementation\TimeSeriesPrognosis\TimeSeriesPrognosisResults.cs" />
+    <Compile Include="Implementation\TimeSeriesPrognosis\TimeSeriesPrognosisSolution.cs" />
+    <Compile Include="Implementation\TimeSeriesPrognosis\TimeSeriesPrognosisSolutionBase.cs" />
     <Compile Include="Interfaces\Classification\IClassificationEnsembleModel.cs">
       <SubType>Code</SubType>
@@ -149,6 +157,13 @@
     <Compile Include="Interfaces\Regression\IRegressionEnsembleSolution.cs" />
     <Compile Include="Implementation\Regression\RegressionSolutionBase.cs" />
+    <Compile Include="Interfaces\TimeSeriesPrognosis\IOnlineTimeSeriesCalculator.cs" />
+    <Compile Include="Interfaces\TimeSeriesPrognosis\ITimeSeriesPrognosisModel.cs" />
+    <Compile Include="Interfaces\TimeSeriesPrognosis\ITimeSeriesPrognosisProblem.cs" />
+    <Compile Include="Interfaces\TimeSeriesPrognosis\ITimeSeriesPrognosisProblemData.cs" />
+    <Compile Include="Interfaces\TimeSeriesPrognosis\ITimeSeriesPrognosisSolution.cs" />
+    <Compile Include="OnlineCalculators\AutoCorrelationCalculator.cs" />
     <Compile Include="OnlineCalculators\OnlineBoundedMeanSquaredErrorCalculator.cs" />
     <Compile Include="OnlineCalculators\HoeffdingsDependenceCalculator.cs" />
+    <Compile Include="OnlineCalculators\OnlineDirectionalSymmetryCalculator.cs" />
     <Compile Include="OnlineCalculators\OnlineMaxAbsoluteErrorCalculator.cs" />
     <Compile Include="OnlineCalculators\OnlineMeanErrorCalculator.cs" />
@@ -189,4 +204,6 @@
     <Compile Include="OnlineCalculators\OnlinePearsonsRSquaredCalculator.cs" />
     <Compile Include="Implementation\Regression\RegressionSolution.cs" />
+    <Compile Include="OnlineCalculators\OnlineTheilsUStatisticCalculator.cs" />
+    <Compile Include="OnlineCalculators\OnlineWeightedDirectionalSymmetryCalculator.cs" />
     <Compile Include="OnlineCalculators\SpearmansRankCorrelationCoefficientCalculator.cs" />
     <Compile Include="Plugin.cs" />
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisProblem.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisProblem.cs	(revision 8797)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisProblem.cs	(revision 8798)
@@ -66,4 +66,9 @@
     }
 
+    protected DataAnalysisProblem(T problemData)
+      : this() {
+      ProblemData = problemData;
+    }
+
     [StorableHook(HookType.AfterDeserialization)]
     private void AfterDeserialization() {
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ConstantRegressionModel.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ConstantRegressionModel.cs	(revision 8797)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ConstantRegressionModel.cs	(revision 8798)
@@ -30,5 +30,5 @@
   public class ConstantRegressionModel : NamedItem, IRegressionModel {
     [Storable]
-    private double constant;
+    protected double constant;
     public double Constant {
       get { return constant; }
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionProblem.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionProblem.cs	(revision 8797)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionProblem.cs	(revision 8798)
@@ -36,8 +36,6 @@
     public override IDeepCloneable Clone(Cloner cloner) { return new RegressionProblem(this, cloner); }
 
-    public RegressionProblem()
-      : base() {
-      ProblemData = new RegressionProblemData();
-    }
+    public RegressionProblem() : base(new RegressionProblemData()) { }
+
   }
 }
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolutionBase.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolutionBase.cs	(revision 8797)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolutionBase.cs	(revision 8798)
@@ -29,16 +29,29 @@
   [StorableClass]
   public abstract class RegressionSolutionBase : DataAnalysisSolution, IRegressionSolution {
-    private const string TrainingMeanSquaredErrorResultName = "Mean squared error (training)";
-    private const string TestMeanSquaredErrorResultName = "Mean squared error (test)";
-    private const string TrainingMeanAbsoluteErrorResultName = "Mean absolute error (training)";
-    private const string TestMeanAbsoluteErrorResultName = "Mean absolute error (test)";
-    private const string TrainingSquaredCorrelationResultName = "Pearson's R² (training)";
-    private const string TestSquaredCorrelationResultName = "Pearson's R² (test)";
-    private const string TrainingRelativeErrorResultName = "Average relative error (training)";
-    private const string TestRelativeErrorResultName = "Average relative error (test)";
-    private const string TrainingNormalizedMeanSquaredErrorResultName = "Normalized mean squared error (training)";
-    private const string TestNormalizedMeanSquaredErrorResultName = "Normalized mean squared error (test)";
-    private const string TrainingMeanErrorResultName = "Mean error (training)";
-    private const string TestMeanErrorResultName = "Mean error (test)";
+    protected const string TrainingMeanSquaredErrorResultName = "Mean squared error (training)";
+    protected const string TestMeanSquaredErrorResultName = "Mean squared error (test)";
+    protected const string TrainingMeanAbsoluteErrorResultName = "Mean absolute error (training)";
+    protected const string TestMeanAbsoluteErrorResultName = "Mean absolute error (test)";
+    protected const string TrainingSquaredCorrelationResultName = "Pearson's R² (training)";
+    protected const string TestSquaredCorrelationResultName = "Pearson's R² (test)";
+    protected const string TrainingRelativeErrorResultName = "Average relative error (training)";
+    protected const string TestRelativeErrorResultName = "Average relative error (test)";
+    protected const string TrainingNormalizedMeanSquaredErrorResultName = "Normalized mean squared error (training)";
+    protected const string TestNormalizedMeanSquaredErrorResultName = "Normalized mean squared error (test)";
+    protected const string TrainingMeanErrorResultName = "Mean error (training)";
+    protected const string TestMeanErrorResultName = "Mean error (test)";
+
+    protected const string TrainingMeanSquaredErrorResultDescription = "Mean of squared errors of the model on the training partition";
+    protected const string TestMeanSquaredErrorResultDescription = "Mean of squared errors of the model on the test partition";
+    protected const string TrainingMeanAbsoluteErrorResultDescription = "Mean of absolute errors of the model on the training partition";
+    protected const string TestMeanAbsoluteErrorResultDescription = "Mean of absolute errors of the model on the test partition";
+    protected const string TrainingSquaredCorrelationResultDescription = "Squared Pearson's correlation coefficient of the model output and the actual values on the training partition";
+    protected const string TestSquaredCorrelationResultDescription = "Squared Pearson's correlation coefficient of the model output and the actual values on the test partition";
+    protected const string TrainingRelativeErrorResultDescription = "Average of the relative errors of the model output and the actual values on the training partition";
+    protected const string TestRelativeErrorResultDescription = "Average of the relative errors of the model output and the actual values on the test partition";
+    protected const string TrainingNormalizedMeanSquaredErrorResultDescription = "Normalized mean of squared errors of the model on the training partition";
+    protected const string TestNormalizedMeanSquaredErrorResultDescription = "Normalized mean of squared errors of the model on the test partition";
+    protected const string TrainingMeanErrorResultDescription = "Mean of errors of the model on the training partition";
+    protected const string TestMeanErrorResultDescription = "Mean of errors of the model on the test partition";
 
     public new IRegressionModel Model {
@@ -115,16 +128,16 @@
     protected RegressionSolutionBase(IRegressionModel model, IRegressionProblemData problemData)
       : base(model, problemData) {
-      Add(new Result(TrainingMeanSquaredErrorResultName, "Mean of squared errors of the model on the training partition", new DoubleValue()));
-      Add(new Result(TestMeanSquaredErrorResultName, "Mean of squared errors of the model on the test partition", new DoubleValue()));
-      Add(new Result(TrainingMeanAbsoluteErrorResultName, "Mean of absolute errors of the model on the training partition", new DoubleValue()));
-      Add(new Result(TestMeanAbsoluteErrorResultName, "Mean of absolute errors of the model on the test partition", new DoubleValue()));
-      Add(new Result(TrainingSquaredCorrelationResultName, "Squared Pearson's correlation coefficient of the model output and the actual values on the training partition", new DoubleValue()));
-      Add(new Result(TestSquaredCorrelationResultName, "Squared Pearson's correlation coefficient of the model output and the actual values on the test partition", new DoubleValue()));
-      Add(new Result(TrainingRelativeErrorResultName, "Average of the relative errors of the model output and the actual values on the training partition", new PercentValue()));
-      Add(new Result(TestRelativeErrorResultName, "Average of the relative errors of the model output and the actual values on the test partition", new PercentValue()));
-      Add(new Result(TrainingNormalizedMeanSquaredErrorResultName, "Normalized mean of squared errors of the model on the training partition", new DoubleValue()));
-      Add(new Result(TestNormalizedMeanSquaredErrorResultName, "Normalized mean of squared errors of the model on the test partition", new DoubleValue()));
-      Add(new Result(TrainingMeanErrorResultName, "Mean of errors of the model on the training partition", new DoubleValue()));
-      Add(new Result(TestMeanErrorResultName, "Mean of errors of the model on the test partition", new DoubleValue()));
+      Add(new Result(TrainingMeanSquaredErrorResultName, TrainingMeanSquaredErrorResultDescription, new DoubleValue()));
+      Add(new Result(TestMeanSquaredErrorResultName, TestMeanSquaredErrorResultDescription, new DoubleValue()));
+      Add(new Result(TrainingMeanAbsoluteErrorResultName, TrainingMeanAbsoluteErrorResultDescription, new DoubleValue()));
+      Add(new Result(TestMeanAbsoluteErrorResultName, TestMeanAbsoluteErrorResultDescription, new DoubleValue()));
+      Add(new Result(TrainingSquaredCorrelationResultName, TrainingSquaredCorrelationResultDescription, new DoubleValue()));
+      Add(new Result(TestSquaredCorrelationResultName, TestSquaredCorrelationResultDescription, new DoubleValue()));
+      Add(new Result(TrainingRelativeErrorResultName, TrainingRelativeErrorResultDescription, new PercentValue()));
+      Add(new Result(TestRelativeErrorResultName, TestRelativeErrorResultDescription, new PercentValue()));
+      Add(new Result(TrainingNormalizedMeanSquaredErrorResultName, TrainingNormalizedMeanSquaredErrorResultDescription, new DoubleValue()));
+      Add(new Result(TestNormalizedMeanSquaredErrorResultName, TestNormalizedMeanSquaredErrorResultDescription, new DoubleValue()));
+      Add(new Result(TrainingMeanErrorResultName, TrainingMeanErrorResultDescription, new DoubleValue()));
+      Add(new Result(TestMeanErrorResultName, TestMeanErrorResultDescription, new DoubleValue()));
     }
 
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/Models/ConstantTimeSeriesPrognosisModel.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/Models/ConstantTimeSeriesPrognosisModel.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/Models/ConstantTimeSeriesPrognosisModel.cs	(revision 8798)
@@ -0,0 +1,49 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("Constant TimeSeries Model", "A time series model that returns for all prediciton the same constant value.")]
+  public class ConstantTimeSeriesPrognosisModel : ConstantRegressionModel, ITimeSeriesPrognosisModel {
+    [StorableConstructor]
+    protected ConstantTimeSeriesPrognosisModel(bool deserializing) : base(deserializing) { }
+    protected ConstantTimeSeriesPrognosisModel(ConstantTimeSeriesPrognosisModel original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ConstantTimeSeriesPrognosisModel(this, cloner);
+    }
+
+    public ConstantTimeSeriesPrognosisModel(double constant) : base(constant) { }
+
+    public IEnumerable<IEnumerable<double>> GetPrognosedValues(Dataset dataset, IEnumerable<int> rows, IEnumerable<int> horizons) {
+      return horizons.Select(horizon => Enumerable.Repeat(Constant, horizon));
+    }
+
+    public ITimeSeriesPrognosisSolution CreateTimeSeriesPrognosisSolution(ITimeSeriesPrognosisProblemData problemData) {
+      return new TimeSeriesPrognosisSolution(this, problemData);
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/Models/TimeSeriesPrognosisAutoRegressiveModel.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/Models/TimeSeriesPrognosisAutoRegressiveModel.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/Models/TimeSeriesPrognosisAutoRegressiveModel.cs	(revision 8798)
@@ -0,0 +1,118 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("Autoregressive TimeSeries Model", "A linear autoregressive time series model used to predict future values.")]
+  public class TimeSeriesPrognosisAutoRegressiveModel : NamedItem, ITimeSeriesPrognosisModel {
+    [Storable]
+    public double[] Phi { get; private set; }
+    [Storable]
+    public double Constant { get; private set; }
+    [Storable]
+    public string TargetVariable { get; private set; }
+
+    public int TimeOffset { get { return Phi.Length; } }
+
+    [StorableConstructor]
+    protected TimeSeriesPrognosisAutoRegressiveModel(bool deserializing) : base(deserializing) { }
+    protected TimeSeriesPrognosisAutoRegressiveModel(TimeSeriesPrognosisAutoRegressiveModel original, Cloner cloner)
+      : base(original, cloner) {
+      this.Phi = (double[])original.Phi.Clone();
+      this.Constant = original.Constant;
+      this.TargetVariable = original.TargetVariable;
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TimeSeriesPrognosisAutoRegressiveModel(this, cloner);
+    }
+    public TimeSeriesPrognosisAutoRegressiveModel(string targetVariable, double[] phi, double constant)
+      : base("AR(1) Model") {
+      Phi = (double[])phi.Clone();
+      Constant = constant;
+      TargetVariable = targetVariable;
+    }
+
+    public IEnumerable<IEnumerable<double>> GetPrognosedValues(Dataset dataset, IEnumerable<int> rows, IEnumerable<int> horizons) {
+      var rowsEnumerator = rows.GetEnumerator();
+      var horizonsEnumerator = horizons.GetEnumerator();
+      var targetValues = dataset.GetReadOnlyDoubleValues(TargetVariable);
+      // produce a n-step forecast for all rows
+      while (rowsEnumerator.MoveNext() & horizonsEnumerator.MoveNext()) {
+        int row = rowsEnumerator.Current;
+        int horizon = horizonsEnumerator.Current;
+        if (row - TimeOffset < 0) {
+          yield return Enumerable.Repeat(double.NaN, horizon);
+          continue;
+        }
+
+        double[] prognosis = new double[horizon];
+        for (int h = 0; h < horizon; h++) {
+          double estimatedValue = 0.0;
+          for (int i = 1; i <= TimeOffset; i++) {
+            int offset = h - i;
+            if (offset >= 0) estimatedValue += prognosis[offset] * Phi[i - 1];
+            else estimatedValue += targetValues[row + offset] * Phi[i - 1];
+
+          }
+          estimatedValue += Constant;
+          prognosis[h] = estimatedValue;
+        }
+
+        yield return prognosis;
+      }
+
+      if (rowsEnumerator.MoveNext() || horizonsEnumerator.MoveNext())
+        throw new ArgumentException("Number of elements in rows and horizon enumerations doesn't match.");
+    }
+
+    public IEnumerable<double> GetEstimatedValues(Dataset dataset, IEnumerable<int> rows) {
+      var targetVariables = dataset.GetReadOnlyDoubleValues(TargetVariable);
+      foreach (int row in rows) {
+        double estimatedValue = 0.0;
+        if (row - TimeOffset < 0) {
+          yield return double.NaN;
+          continue;
+        }
+
+        for (int i = 1; i <= TimeOffset; i++) {
+          estimatedValue += targetVariables[row - i] * Phi[i - 1];
+        }
+        estimatedValue += Constant;
+        yield return estimatedValue;
+      }
+    }
+
+    public ITimeSeriesPrognosisSolution CreateTimeSeriesPrognosisSolution(ITimeSeriesPrognosisProblemData problemData) {
+      return new TimeSeriesPrognosisSolution(this, problemData);
+    }
+    public IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
+      throw new NotSupportedException();
+    }
+
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisProblem.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisProblem.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisProblem.cs	(revision 8798)
@@ -0,0 +1,38 @@
+#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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("Time-series Prognosis Problem", "A general time-series prognosis problem.")]
+  [Creatable("Problems")]
+  public class TimeSeriesPrognosisProblem : DataAnalysisProblem<ITimeSeriesPrognosisProblemData>, ITimeSeriesPrognosisProblem {
+    [StorableConstructor]
+    protected TimeSeriesPrognosisProblem(bool deserializing) : base(deserializing) { }
+    protected TimeSeriesPrognosisProblem(TimeSeriesPrognosisProblem original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) { return new TimeSeriesPrognosisProblem(this, cloner); }
+
+    public TimeSeriesPrognosisProblem() : base(new TimeSeriesPrognosisProblemData()) { }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisProblemData.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisProblemData.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisProblemData.cs	(revision 8798)
@@ -0,0 +1,1612 @@
+#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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("TimeSeriesPrognosisProblemData", "Represents an item containing all data defining a time series prognosis problem.")]
+  public class TimeSeriesPrognosisProblemData : RegressionProblemData, ITimeSeriesPrognosisProblemData {
+    #region default data
+    private static double[,] mackey_glass_17 = new double[,] {
+{9.0000000e-01},
+{9.0000000e-01},
+{9.0000000e-01},
+{9.4136145e-01},
+{1.1188041e+00},
+{1.2161867e+00},
+{1.2476827e+00},
+{1.0067861e+00},
+{7.1297054e-01},
+{5.0349420e-01},
+{5.8392542e-01},
+{9.4327347e-01},
+{1.0178784e+00},
+{1.0346794e+00},
+{1.1640420e+00},
+{1.0670009e+00},
+{1.0026658e+00},
+{7.7000347e-01},
+{7.0782984e-01},
+{7.9370192e-01},
+{1.0558440e+00},
+{1.2000510e+00},
+{1.2998549e+00},
+{1.1857500e+00},
+{8.4250325e-01},
+{5.5885374e-01},
+{4.2572016e-01},
+{7.5043060e-01},
+{9.7291951e-01},
+{9.3785503e-01},
+{1.0653587e+00},
+{1.1355961e+00},
+{1.1533842e+00},
+{1.0678134e+00},
+{8.1349649e-01},
+{6.6246660e-01},
+{6.2210481e-01},
+{9.3890430e-01},
+{1.1287058e+00},
+{1.1699535e+00},
+{1.2412759e+00},
+{9.8090748e-01},
+{7.3311051e-01},
+{5.2596003e-01},
+{6.3134850e-01},
+{9.7849655e-01},
+{1.0578901e+00},
+{1.0888001e+00},
+{1.1681297e+00},
+{9.9896471e-01},
+{8.7928027e-01},
+{6.6864116e-01},
+{7.3694626e-01},
+{9.7850487e-01},
+{1.1571565e+00},
+{1.2440406e+00},
+{1.2532851e+00},
+{9.3967388e-01},
+{6.5403177e-01},
+{4.5549437e-01},
+{6.4110939e-01},
+{9.6727507e-01},
+{9.8419122e-01},
+{1.0332443e+00},
+{1.1440570e+00},
+{1.0922307e+00},
+{1.0485820e+00},
+{8.0447560e-01},
+{7.1465526e-01},
+{7.1296010e-01},
+{9.9300973e-01},
+{1.1766813e+00},
+{1.2618288e+00},
+{1.2517022e+00},
+{9.2078170e-01},
+{6.2369710e-01},
+{4.3562308e-01},
+{6.4988558e-01},
+{9.5895791e-01},
+{9.5866122e-01},
+{1.0183775e+00},
+{1.1415533e+00},
+{1.1289579e+00},
+{1.1022163e+00},
+{8.4414928e-01},
+{6.9891813e-01},
+{6.2493643e-01},
+{9.0049230e-01},
+{1.1246569e+00},
+{1.1850486e+00},
+{1.2646400e+00},
+{1.0193893e+00},
+{7.3830722e-01},
+{5.1921750e-01},
+{5.6836076e-01},
+{9.3609361e-01},
+{1.0324202e+00},
+{1.0360676e+00},
+{1.1675966e+00},
+{1.0504944e+00},
+{9.8129158e-01},
+{7.5798016e-01},
+{7.1660079e-01},
+{8.3950658e-01},
+{1.0870027e+00},
+{1.2170776e+00},
+{1.3123779e+00},
+{1.1361782e+00},
+{7.9337369e-01},
+{5.2230472e-01},
+{4.3857925e-01},
+{8.0873950e-01},
+{9.7422631e-01},
+{9.3291515e-01},
+{1.0947530e+00},
+{1.1335086e+00},
+{1.1645714e+00},
+{1.0315895e+00},
+{7.9058261e-01},
+{6.3878936e-01},
+{6.4385427e-01},
+{9.7290237e-01},
+{1.1330941e+00},
+{1.1738960e+00},
+{1.2210669e+00},
+{9.4813374e-01},
+{7.1548595e-01},
+{5.2046031e-01},
+{6.8100333e-01},
+{1.0072944e+00},
+{1.0641199e+00},
+{1.1194312e+00},
+{1.1522817e+00},
+{9.7118023e-01},
+{8.2966445e-01},
+{6.3876024e-01},
+{7.6770138e-01},
+{1.0325752e+00},
+{1.1660632e+00},
+{1.2543878e+00},
+{1.1956003e+00},
+{8.7571542e-01},
+{6.1252082e-01},
+{4.5699619e-01},
+{7.4030148e-01},
+{1.0017485e+00},
+{9.8958385e-01},
+{1.0949833e+00},
+{1.1249612e+00},
+{1.0658962e+00},
+{9.5636335e-01},
+{7.4498806e-01},
+{7.2563393e-01},
+{8.3530455e-01},
+{1.0977307e+00},
+{1.2314926e+00},
+{1.3167422e+00},
+{1.1172604e+00},
+{7.6900341e-01},
+{5.0549771e-01},
+{4.4450990e-01},
+{8.2808038e-01},
+{9.6930396e-01},
+{9.2772189e-01},
+{1.1010458e+00},
+{1.1366939e+00},
+{1.1770457e+00},
+{1.0282839e+00},
+{7.8657093e-01},
+{6.2340354e-01},
+{6.3476140e-01},
+{9.6941037e-01},
+{1.1224823e+00},
+{1.1576217e+00},
+{1.2147442e+00},
+{9.5631199e-01},
+{7.3947874e-01},
+{5.4187646e-01},
+{6.8681641e-01},
+{1.0131445e+00},
+{1.0865854e+00},
+{1.1414849e+00},
+{1.1594630e+00},
+{9.4411600e-01},
+{7.7794034e-01},
+{5.9741518e-01},
+{7.7225037e-01},
+{1.0587360e+00},
+{1.1485933e+00},
+{1.2344562e+00},
+{1.1458853e+00},
+{8.5415118e-01},
+{6.2127481e-01},
+{4.9756097e-01},
+{8.0931406e-01},
+{1.0430891e+00},
+{1.0367506e+00},
+{1.1608048e+00},
+{1.0902522e+00},
+{9.6945804e-01},
+{7.9607346e-01},
+{6.7035674e-01},
+{8.2493000e-01},
+{1.0685565e+00},
+{1.1912458e+00},
+{1.2916937e+00},
+{1.1585237e+00},
+{8.2653804e-01},
+{5.5624667e-01},
+{4.4364773e-01},
+{7.8679896e-01},
+{9.8947432e-01},
+{9.5587476e-01},
+{1.0976735e+00},
+{1.1247419e+00},
+{1.1220470e+00},
+{9.9754667e-01},
+{7.7406653e-01},
+{6.7630712e-01},
+{7.2445263e-01},
+{1.0303591e+00},
+{1.1801427e+00},
+{1.2506686e+00},
+{1.1989987e+00},
+{8.7114663e-01},
+{6.0602798e-01},
+{4.5163741e-01},
+{7.3553573e-01},
+{9.9456302e-01},
+{9.8098646e-01},
+{1.0857031e+00},
+{1.1289641e+00},
+{1.0828069e+00},
+{9.8224963e-01},
+{7.5966277e-01},
+{7.1111527e-01},
+{7.8645769e-01},
+{1.0673541e+00},
+{1.2116816e+00},
+{1.2990734e+00},
+{1.1657704e+00},
+{8.1779454e-01},
+{5.4428063e-01},
+{4.3047549e-01},
+{7.7832590e-01},
+{9.7551443e-01},
+{9.3705618e-01},
+{1.0807206e+00},
+{1.1339189e+00},
+{1.1551319e+00},
+{1.0473610e+00},
+{8.0021464e-01},
+{6.5377513e-01},
+{6.3810292e-01},
+{9.6140773e-01},
+{1.1354401e+00},
+{1.1782311e+00},
+{1.2323246e+00},
+{9.5811452e-01},
+{7.1400985e-01},
+{5.1434848e-01},
+{6.5876782e-01},
+{9.9374878e-01},
+{1.0532057e+00},
+{1.0987291e+00},
+{1.1569941e+00},
+{9.9327584e-01},
+{8.7055783e-01},
+{6.6607204e-01},
+{7.5154249e-01},
+{9.9147904e-01},
+{1.1618652e+00},
+{1.2531013e+00},
+{1.2445235e+00},
+{9.2459418e-01},
+{6.3924685e-01},
+{4.4899067e-01},
+{6.5946924e-01},
+{9.7165260e-01},
+{9.7791817e-01},
+{1.0391898e+00},
+{1.1412631e+00},
+{1.0983393e+00},
+{1.0493420e+00},
+{8.0399406e-01},
+{7.0992449e-01},
+{7.0350356e-01},
+{9.8952236e-01},
+{1.1734521e+00},
+{1.2538876e+00},
+{1.2508500e+00},
+{9.2423636e-01},
+{6.3070030e-01},
+{4.4136962e-01},
+{6.4946966e-01},
+{9.6197955e-01},
+{9.6606332e-01},
+{1.0237953e+00},
+{1.1421522e+00},
+{1.1183774e+00},
+{1.0857179e+00},
+{8.3157725e-01},
+{7.0250588e-01},
+{6.4917325e-01},
+{9.2959329e-01},
+{1.1407976e+00},
+{1.2080261e+00},
+{1.2684960e+00},
+{9.9122930e-01},
+{7.0220017e-01},
+{4.8816416e-01},
+{5.8586111e-01},
+{9.4668329e-01},
+{1.0087590e+00},
+{1.0232927e+00},
+{1.1559444e+00},
+{1.0720927e+00},
+{1.0286336e+00},
+{7.9460252e-01},
+{7.2093651e-01},
+{7.6292167e-01},
+{1.0248985e+00},
+{1.1929944e+00},
+{1.2920208e+00},
+{1.2293181e+00},
+{8.8290244e-01},
+{5.8527613e-01},
+{4.1855360e-01},
+{6.9074767e-01},
+{9.5977708e-01},
+{9.3601019e-01},
+{1.0268467e+00},
+{1.1397909e+00},
+{1.1581327e+00},
+{1.1205956e+00},
+{8.5280669e-01},
+{6.7763483e-01},
+{5.7983286e-01},
+{8.6429914e-01},
+{1.0976939e+00},
+{1.1367408e+00},
+{1.2374931e+00},
+{1.0493382e+00},
+{8.0588138e-01},
+{5.9127581e-01},
+{5.7929225e-01},
+{9.2472931e-01},
+{1.0849831e+00},
+{1.0943246e+00},
+{1.2041235e+00},
+{1.0091917e+00},
+{8.4987188e-01},
+{6.3876182e-01},
+{6.7747918e-01},
+{9.7202288e-01},
+{1.1405471e+00},
+{1.1943368e+00},
+{1.2338428e+00},
+{9.4462558e-01},
+{6.9738430e-01},
+{4.9856007e-01},
+{6.6823589e-01},
+{9.9611375e-01},
+{1.0393748e+00},
+{1.0920087e+00},
+{1.1489492e+00},
+{1.0066576e+00},
+{8.9589007e-01},
+{6.8845995e-01},
+{7.5294149e-01},
+{9.6184563e-01},
+{1.1555071e+00},
+{1.2567316e+00},
+{1.2751778e+00},
+{9.6335246e-01},
+{6.5830948e-01},
+{4.4799275e-01},
+{5.9888825e-01},
+{9.4430988e-01},
+{9.6837958e-01},
+{9.9677549e-01},
+{1.1434629e+00},
+{1.1210684e+00},
+{1.1148356e+00},
+{8.6401556e-01},
+{7.1420118e-01},
+{6.2999725e-01},
+{8.7537864e-01},
+{1.1167941e+00},
+{1.1896694e+00},
+{1.2722030e+00},
+{1.0454715e+00},
+{7.4997564e-01},
+{5.2383173e-01},
+{5.3664145e-01},
+{9.1117041e-01},
+{1.0244044e+00},
+{1.0151287e+00},
+{1.1633675e+00},
+{1.0695966e+00},
+{1.0183575e+00},
+{8.0087884e-01},
+{7.1535296e-01},
+{7.8553095e-01},
+{1.0319822e+00},
+{1.1937155e+00},
+{1.2977947e+00},
+{1.2217806e+00},
+{8.7524512e-01},
+{5.7851885e-01},
+{4.1763620e-01},
+{7.0155638e-01},
+{9.6135267e-01},
+{9.3393602e-01},
+{1.0323424e+00},
+{1.1394608e+00},
+{1.1605598e+00},
+{1.1161968e+00},
+{8.4854339e-01},
+{6.7338626e-01},
+{5.7982826e-01},
+{8.7043086e-01},
+{1.0990834e+00},
+{1.1357404e+00},
+{1.2369383e+00},
+{1.0441753e+00},
+{8.0417958e-01},
+{5.9002711e-01},
+{5.8533894e-01},
+{9.3051649e-01},
+{1.0871279e+00},
+{1.0984983e+00},
+{1.2044155e+00},
+{1.0039892e+00},
+{8.4210523e-01},
+{6.3124655e-01},
+{6.8055115e-01},
+{9.7935183e-01},
+{1.1399170e+00},
+{1.1935307e+00},
+{1.2269029e+00},
+{9.3758049e-01},
+{6.9527243e-01},
+{5.0033084e-01},
+{6.8171448e-01},
+{1.0034848e+00},
+{1.0435853e+00},
+{1.1027381e+00},
+{1.1454200e+00},
+{9.9636446e-01},
+{8.7575610e-01},
+{6.7572455e-01},
+{7.6161436e-01},
+{9.8751885e-01},
+{1.1634852e+00},
+{1.2613366e+00},
+{1.2527158e+00},
+{9.3041078e-01},
+{6.3648886e-01},
+{4.4289908e-01},
+{6.4543043e-01},
+{9.6271252e-01},
+{9.6856037e-01},
+{1.0237816e+00},
+{1.1419384e+00},
+{1.1143808e+00},
+{1.0817980e+00},
+{8.2952128e-01},
+{7.0565231e-01},
+{6.5745758e-01},
+{9.3688510e-01},
+{1.1457239e+00},
+{1.2160319e+00},
+{1.2696485e+00},
+{9.8373294e-01},
+{6.9141844e-01},
+{4.7910268e-01},
+{5.8995166e-01},
+{9.4754885e-01},
+{1.0004197e+00},
+{1.0182334e+00},
+{1.1527974e+00},
+{1.0815601e+00},
+{1.0462772e+00},
+{8.0856012e-01},
+{7.2009150e-01},
+{7.3360533e-01},
+{9.9726771e-01},
+{1.1799228e+00},
+{1.2752553e+00},
+{1.2545993e+00},
+{9.1834232e-01},
+{6.1478702e-01},
+{4.2718988e-01},
+{6.4709630e-01},
+{9.5321724e-01},
+{9.4745071e-01},
+{1.0082615e+00},
+{1.1408283e+00},
+{1.1449070e+00},
+{1.1287695e+00},
+{8.6506953e-01},
+{6.9506068e-01},
+{5.9077914e-01},
+{8.5235412e-01},
+{1.0981812e+00},
+{1.1502068e+00},
+{1.2457878e+00},
+{1.0606248e+00},
+{7.9743949e-01},
+{5.7871635e-01},
+{5.5597309e-01},
+{9.0976389e-01},
+{1.0678545e+00},
+{1.0678466e+00},
+{1.1926843e+00},
+{1.0306506e+00},
+{9.0068600e-01},
+{6.8968565e-01},
+{6.8293693e-01},
+{9.2938386e-01},
+{1.1389931e+00},
+{1.2107723e+00},
+{1.2742112e+00},
+{9.9571305e-01},
+{7.0900966e-01},
+{4.8711002e-01},
+{5.7843327e-01},
+{9.4262722e-01},
+{1.0068885e+00},
+{1.0174671e+00},
+{1.1549847e+00},
+{1.0752383e+00},
+{1.0382561e+00},
+{8.0493588e-01},
+{7.2297438e-01},
+{7.5109199e-01},
+{1.0099650e+00},
+{1.1869526e+00},
+{1.2859723e+00},
+{1.2455314e+00},
+{9.0247113e-01},
+{5.9968946e-01},
+{4.2056794e-01},
+{6.6467784e-01},
+{9.5461231e-01},
+{9.3926954e-01},
+{1.0128964e+00},
+{1.1403075e+00},
+{1.1549599e+00},
+{1.1335031e+00},
+{8.6584651e-01},
+{6.8689154e-01},
+{5.7663890e-01},
+{8.4338430e-01},
+{1.0904343e+00},
+{1.1347127e+00},
+{1.2344704e+00},
+{1.0665197e+00},
+{8.1831436e-01},
+{6.0374950e-01},
+{5.6609914e-01},
+{9.0609488e-01},
+{1.0837698e+00},
+{1.0903349e+00},
+{1.2068005e+00},
+{1.0215332e+00},
+{8.5834739e-01},
+{6.4797779e-01},
+{6.6278967e-01},
+{9.5567807e-01},
+{1.1370612e+00},
+{1.1868501e+00},
+{1.2426235e+00},
+{9.6133342e-01},
+{7.1189926e-01},
+{5.0582127e-01},
+{6.4642134e-01},
+{9.8585814e-01},
+{1.0428580e+00},
+{1.0831242e+00},
+{1.1568123e+00},
+{1.0097872e+00},
+{9.0412446e-01},
+{6.9144384e-01},
+{7.4452934e-01},
+{9.5158341e-01},
+{1.1512270e+00},
+{1.2509608e+00},
+{1.2807229e+00},
+{9.7601316e-01},
+{6.6959369e-01},
+{4.5362019e-01},
+{5.8397806e-01},
+{9.3866865e-01},
+{9.7211974e-01},
+{9.9154526e-01},
+{1.1440232e+00},
+{1.1182310e+00},
+{1.1159711e+00},
+{8.6902975e-01},
+{7.1839537e-01},
+{6.3437176e-01},
+{8.7058758e-01},
+{1.1155207e+00},
+{1.1929730e+00},
+{1.2750340e+00},
+{1.0511137e+00},
+{7.5075715e-01},
+{5.2249794e-01},
+{5.2857771e-01},
+{9.0479637e-01},
+{1.0201490e+00},
+{1.0078239e+00},
+{1.1602784e+00},
+{1.0762699e+00},
+{1.0328279e+00},
+{8.1754050e-01},
+{7.1739458e-01},
+{7.6521302e-01},
+{1.0063562e+00},
+{1.1829441e+00},
+{1.2880301e+00},
+{1.2505618e+00},
+{9.0963666e-01},
+{6.0373594e-01},
+{4.2059572e-01},
+{6.5552332e-01},
+{9.5216646e-01},
+{9.3915492e-01},
+{1.0073402e+00},
+{1.1402595e+00},
+{1.1555473e+00},
+{1.1400569e+00},
+{8.7240707e-01},
+{6.8972093e-01},
+{5.7304964e-01},
+{8.3155186e-01},
+{1.0852244e+00},
+{1.1309096e+00},
+{1.2300408e+00},
+{1.0756716e+00},
+{8.2836037e-01},
+{6.1503305e-01},
+{5.6289537e-01},
+{8.9596963e-01},
+{1.0857176e+00},
+{1.0933045e+00},
+{1.2103223e+00},
+{1.0266092e+00},
+{8.5466111e-01},
+{6.4485312e-01},
+{6.5137619e-01},
+{9.5039035e-01},
+{1.1326982e+00},
+{1.1771304e+00},
+{1.2406618e+00},
+{9.6686921e-01},
+{7.2402007e-01},
+{5.1657512e-01},
+{6.4610863e-01},
+{9.8716024e-01},
+{1.0536774e+00},
+{1.0920775e+00},
+{1.1611436e+00},
+{9.9694608e-01},
+{8.7913715e-01},
+{6.7096137e-01},
+{7.4646346e-01},
+{9.8211586e-01},
+{1.1596887e+00},
+{1.2506463e+00},
+{1.2528610e+00},
+{9.3574881e-01},
+{6.4708026e-01},
+{4.5058777e-01},
+{6.4326949e-01},
+{9.6585146e-01},
+{9.7825812e-01},
+{1.0299115e+00},
+{1.1430802e+00},
+{1.1005190e+00},
+{1.0609387e+00},
+{8.1379890e-01},
+{7.1122428e-01},
+{6.9156533e-01},
+{9.7259709e-01},
+{1.1655186e+00},
+{1.2452699e+00},
+{1.2619116e+00},
+{9.4482161e-01},
+{6.4801701e-01},
+{4.4907240e-01},
+{6.2485209e-01},
+{9.5564190e-01},
+{9.7288683e-01},
+{1.0147847e+00},
+{1.1443809e+00},
+{1.1120870e+00},
+{1.0877802e+00},
+{8.3639407e-01},
+{7.0935594e-01},
+{6.5684224e-01},
+{9.2695542e-01},
+{1.1418485e+00},
+{1.2155793e+00},
+{1.2744439e+00},
+{9.9526406e-01},
+{6.9858658e-01},
+{4.8225678e-01},
+{5.7551868e-01},
+{9.3953863e-01},
+{1.0000682e+00},
+{1.0105854e+00},
+{1.1531271e+00},
+{1.0852683e+00},
+{1.0562598e+00},
+{8.2024340e-01},
+{7.2070006e-01},
+{7.2200828e-01},
+{9.7907123e-01},
+{1.1713283e+00},
+{1.2668075e+00},
+{1.2685662e+00},
+{9.4120299e-01},
+{6.3302397e-01},
+{4.3403723e-01},
+{6.1877701e-01},
+{9.4622798e-01},
+{9.5365292e-01},
+{9.9618857e-01},
+{1.1414351e+00},
+{1.1389950e+00},
+{1.1349258e+00},
+{8.7553815e-01},
+{7.0489527e-01},
+{5.9575516e-01},
+{8.3938416e-01},
+{1.0946321e+00},
+{1.1549299e+00},
+{1.2478627e+00},
+{1.0727433e+00},
+{8.0007945e-01},
+{5.7879852e-01},
+{5.4142544e-01},
+{8.9584895e-01},
+{1.0605852e+00},
+{1.0558398e+00},
+{1.1875826e+00},
+{1.0434789e+00},
+{9.2439267e-01},
+{7.1612758e-01},
+{6.8218882e-01},
+{9.0102182e-01},
+{1.1275375e+00},
+{1.2109971e+00},
+{1.2892493e+00},
+{1.0360675e+00},
+{7.3214326e-01},
+{4.9603224e-01},
+{5.2859768e-01},
+{9.0839931e-01},
+{9.9967438e-01},
+{9.8761933e-01},
+{1.1495807e+00},
+{1.0955451e+00},
+{1.0837190e+00},
+{8.6306190e-01},
+{7.2864571e-01},
+{6.9570443e-01},
+{9.1466309e-01},
+{1.1416079e+00},
+{1.2423455e+00},
+{1.2979661e+00},
+{1.0158501e+00},
+{6.9306586e-01},
+{4.6540187e-01},
+{5.3429520e-01},
+{9.1176535e-01},
+{9.7214664e-01},
+{9.6587930e-01},
+{1.1395672e+00},
+{1.1254350e+00},
+{1.1438751e+00},
+{9.1306791e-01},
+{7.3239337e-01},
+{6.1798523e-01},
+{7.9591503e-01},
+{1.0777494e+00},
+{1.1677842e+00},
+{1.2502967e+00},
+{1.1151699e+00},
+{8.1642087e-01},
+{5.8442000e-01},
+{5.0055038e-01},
+{8.4650946e-01},
+{1.0385843e+00},
+{1.0234916e+00},
+{1.1635033e+00},
+{1.0803258e+00},
+{9.9050756e-01},
+{8.0394987e-01},
+{6.9093478e-01},
+{8.1258118e-01},
+{1.0510811e+00},
+{1.1928214e+00},
+{1.2964341e+00},
+{1.1903709e+00},
+{8.5006682e-01},
+{5.6609363e-01},
+{4.2789827e-01},
+{7.4508986e-01},
+{9.7546850e-01},
+{9.4304490e-01},
+{1.0657257e+00},
+{1.1344752e+00},
+{1.1448680e+00},
+{1.0604924e+00},
+{8.0946851e-01},
+{6.6897242e-01},
+{6.3751840e-01},
+{9.5203759e-01},
+{1.1383222e+00},
+{1.1857882e+00},
+{1.2429358e+00},
+{9.6640521e-01},
+{7.0943525e-01},
+{5.0606242e-01},
+{6.3814517e-01},
+{9.8050653e-01},
+{1.0400252e+00},
+{1.0768445e+00},
+{1.1586073e+00},
+{1.0171349e+00},
+{9.1652446e-01},
+{7.0015343e-01},
+{7.3826470e-01},
+{9.3314098e-01},
+{1.1436325e+00},
+{1.2463125e+00},
+{1.2921798e+00},
+{1.0004180e+00},
+{6.8706555e-01},
+{4.6091370e-01},
+{5.5360860e-01},
+{9.2333217e-01},
+{9.7324082e-01},
+{9.7644851e-01},
+{1.1422917e+00},
+{1.1211038e+00},
+{1.1312591e+00},
+{8.9312684e-01},
+{7.2669146e-01},
+{6.2634170e-01},
+{8.3089176e-01},
+{1.0962164e+00},
+{1.1808500e+00},
+{1.2661262e+00},
+{1.0871224e+00},
+{7.8484345e-01},
+{5.5241172e-01},
+{5.0720010e-01},
+{8.7433135e-01},
+{1.0293171e+00},
+{1.0110677e+00},
+{1.1612664e+00},
+{1.0781429e+00},
+{1.0169296e+00},
+{8.1818733e-01},
+{7.0825239e-01},
+{7.8555548e-01},
+{1.0202406e+00},
+{1.1861871e+00},
+{1.2927766e+00},
+{1.2345608e+00},
+{8.9196638e-01},
+{5.9165129e-01},
+{4.1993302e-01},
+{6.8133251e-01},
+{9.5902336e-01},
+{9.3840491e-01},
+{1.0229760e+00},
+{1.1397483e+00},
+{1.1549910e+00},
+{1.1221729e+00},
+{8.5521466e-01},
+{6.8171599e-01},
+{5.8253142e-01},
+{8.6249156e-01},
+{1.0984374e+00},
+{1.1402897e+00},
+{1.2397438e+00},
+{1.0509675e+00},
+{8.0267914e-01},
+{5.8719202e-01},
+{5.7423177e-01},
+{9.2225657e-01},
+{1.0807070e+00},
+{1.0878295e+00},
+{1.2011335e+00},
+{1.0137713e+00},
+{8.6200406e-01},
+{6.5063788e-01},
+{6.7962388e-01},
+{9.6415425e-01},
+{1.1427244e+00},
+{1.2001432e+00},
+{1.2435862e+00},
+{9.5255718e-01},
+{6.9548843e-01},
+{4.9228114e-01},
+{6.4975070e-01},
+{9.8475452e-01},
+{1.0290189e+00},
+{1.0735305e+00},
+{1.1514964e+00},
+{1.0265685e+00},
+{9.3450570e-01},
+{7.1609613e-01},
+{7.4066401e-01},
+{9.0672547e-01},
+{1.1323663e+00},
+{1.2457251e+00},
+{1.3080265e+00},
+{1.0368462e+00},
+{7.0922252e-01},
+{4.6922499e-01},
+{5.0971665e-01},
+{8.9530783e-01},
+{9.6897032e-01},
+{9.5144881e-01},
+{1.1327578e+00},
+{1.1313397e+00},
+{1.1615669e+00},
+{9.4490349e-01},
+{7.4435097e-01},
+{6.0879030e-01},
+{7.4201167e-01},
+{1.0475442e+00},
+{1.1489683e+00},
+{1.2189341e+00},
+{1.1527726e+00},
+{8.6373864e-01},
+{6.3765290e-01},
+{5.0482479e-01},
+{7.9976041e-01},
+{1.0463811e+00},
+{1.0486243e+00},
+{1.1650654e+00},
+{1.0937932e+00},
+{9.5242412e-01},
+{7.7776887e-01},
+{6.5337298e-01},
+{8.3412675e-01},
+{1.0842165e+00},
+{1.1876958e+00},
+{1.2860798e+00},
+{1.1277640e+00},
+{8.0705117e-01},
+{5.4933954e-01},
+{4.6409423e-01},
+{8.2407983e-01},
+{1.0029510e+00},
+{9.7182671e-01},
+{1.1248927e+00},
+{1.1108497e+00},
+{1.0927585e+00},
+{9.3345740e-01},
+{7.4563087e-01},
+{6.9815644e-01},
+{8.2911579e-01},
+{1.0975320e+00},
+{1.2225208e+00},
+{1.3041931e+00},
+{1.1107874e+00},
+{7.6954799e-01},
+{5.1381033e-01},
+{4.5656108e-01},
+{8.3803614e-01},
+{9.8059578e-01},
+{9.4343837e-01},
+{1.1139527e+00},
+{1.1272959e+00},
+{1.1505047e+00},
+{9.8802150e-01},
+{7.6846480e-01},
+{6.4059710e-01},
+{7.0404249e-01},
+{1.0213995e+00},
+{1.1571646e+00},
+{1.2167098e+00},
+{1.1922700e+00},
+{8.8891917e-01},
+{6.4610240e-01},
+{4.8423413e-01},
+{7.4237703e-01},
+{1.0194305e+00},
+{1.0263817e+00},
+{1.1223002e+00},
+{1.1218476e+00},
+{1.0047937e+00},
+{8.6916869e-01},
+{6.8761628e-01},
+{7.7272726e-01},
+{9.8680374e-01},
+{1.1662112e+00},
+{1.2718586e+00},
+{1.2599891e+00},
+{9.3374084e-01},
+{6.3070745e-01},
+{4.3512068e-01},
+{6.3400337e-01},
+{9.5387123e-01},
+{9.5725486e-01},
+{1.0083783e+00},
+{1.1414776e+00},
+{1.1320033e+00},
+{1.1156485e+00},
+{8.5730304e-01},
+{7.0257566e-01},
+{6.1385070e-01},
+{8.7645096e-01},
+{1.1135407e+00},
+{1.1743915e+00},
+{1.2617479e+00},
+{1.0416530e+00},
+{7.6141001e-01},
+{5.3947941e-01},
+{5.5263397e-01},
+{9.2079176e-01},
+{1.0423877e+00},
+{1.0391593e+00},
+{1.1741828e+00},
+{1.0475738e+00},
+{9.6528247e-01},
+{7.4824631e-01},
+{7.0765109e-01},
+{8.6076413e-01},
+{1.1015853e+00},
+{1.2180296e+00},
+{1.3087379e+00},
+{1.1050105e+00},
+{7.7144492e-01},
+{5.1073157e-01},
+{4.5959721e-01},
+{8.4138746e-01},
+{9.8058403e-01},
+{9.4385625e-01},
+{1.1155190e+00},
+{1.1265194e+00},
+{1.1505430e+00},
+{9.8480260e-01},
+{7.6753361e-01},
+{6.3998096e-01},
+{7.0790430e-01},
+{1.0242649e+00},
+{1.1582776e+00},
+{1.2187970e+00},
+{1.1895283e+00},
+{8.8519343e-01},
+{6.4254017e-01},
+{4.8336487e-01},
+{7.4700679e-01},
+{1.0202300e+00},
+{1.0250636e+00},
+{1.1237335e+00},
+{1.1201468e+00},
+{1.0057497e+00},
+{8.6867488e-01},
+{6.8876595e-01},
+{7.7314271e-01},
+{9.8646241e-01},
+{1.1663720e+00},
+{1.2725046e+00},
+{1.2607985e+00},
+{9.3432428e-01},
+{6.3055002e-01},
+{4.3462242e-01},
+{6.3267663e-01},
+{9.5306639e-01},
+{9.5647018e-01},
+{1.0069834e+00},
+{1.1414283e+00},
+{1.1332454e+00},
+{1.1183329e+00},
+{8.5964718e-01},
+{7.0259273e-01},
+{6.1086847e-01},
+{8.7145976e-01},
+{1.1109278e+00},
+{1.1713319e+00},
+{1.2600859e+00},
+{1.0459933e+00},
+{7.6697548e-01},
+{5.4492361e-01},
+{5.5082792e-01},
+{9.1787603e-01},
+{1.0454451e+00},
+{1.0416026e+00},
+{1.1762039e+00},
+{1.0460129e+00},
+{9.5856257e-01},
+{7.4291843e-01},
+{7.0478730e-01},
+{8.6904294e-01},
+{1.1074327e+00},
+{1.2185136e+00},
+{1.3067057e+00},
+{1.0916662e+00},
+{7.6226341e-01},
+{5.0599582e-01},
+{4.7004755e-01},
+{8.5459323e-01},
+{9.8292600e-01},
+{9.4923741e-01},
+{1.1230180e+00},
+{1.1230727e+00},
+{1.1436380e+00},
+{9.6517685e-01},
+{7.5906667e-01},
+{6.4229098e-01},
+{7.3739829e-01},
+{1.0441989e+00},
+{1.1689429e+00},
+{1.2377221e+00},
+{1.1702644e+00},
+{8.5776744e-01},
+{6.1283507e-01},
+{4.7508171e-01},
+{7.7650778e-01},
+{1.0199875e+00},
+{1.0098181e+00},
+{1.1277738e+00},
+{1.1115547e+00},
+{1.0256012e+00},
+{8.8156161e-01},
+{7.0600708e-01},
+{7.6171841e-01},
+{9.5613909e-01},
+{1.1569502e+00},
+{1.2691300e+00},
+{1.2887802e+00},
+{9.7384680e-01},
+{6.5493328e-01},
+{4.3953117e-01},
+{5.7648851e-01},
+{9.2999054e-01},
+{9.5436230e-01},
+{9.7297008e-01},
+{1.1391325e+00},
+{1.1416064e+00},
+{1.1590944e+00},
+{9.0850247e-01},
+{7.1895834e-01},
+{5.8564424e-01},
+{7.8301903e-01},
+{1.0675300e+00},
+{1.1390766e+00},
+{1.2237314e+00},
+{1.1158432e+00},
+{8.4615038e-01},
+{6.2929929e-01},
+{5.3024321e-01},
+{8.4771779e-01},
+{1.0679772e+00},
+{1.0707805e+00},
+{1.1942615e+00},
+{1.0628072e+00},
+{9.0277875e-01},
+{7.0464579e-01},
+{6.4124982e-01},
+{8.9445063e-01},
+{1.1236998e+00},
+{1.1838208e+00},
+{1.2721938e+00},
+{1.0302053e+00},
+{7.4928918e-01},
+{5.2054789e-01},
+{5.5300914e-01},
+{9.2450978e-01},
+{1.0290172e+00},
+{1.0254177e+00},
+{1.1658431e+00},
+{1.0585030e+00},
+{9.9937151e-01},
+{7.7845423e-01},
+{7.1727834e-01},
+{8.1473462e-01},
+{1.0635825e+00},
+{1.2081434e+00},
+{1.3087387e+00},
+{1.1774543e+00},
+{8.2930325e-01},
+{5.4568406e-01},
+{4.2252006e-01},
+{7.6155262e-01},
+{9.6902023e-01},
+{9.2946430e-01},
+{1.0663917e+00},
+{1.1373062e+00},
+{1.1667915e+00},
+{1.0769457e+00},
+{8.1823128e-01},
+{6.5190054e-01},
+{6.0082155e-01},
+{9.2122516e-01},
+{1.1147361e+00},
+{1.1467530e+00},
+{1.2352757e+00},
+{9.9993521e-01},
+{7.6890308e-01},
+{5.5857496e-01},
+{6.2725763e-01},
+{9.7318317e-01},
+{1.0840117e+00},
+{1.1108847e+00},
+{1.1857549e+00},
+{9.7757101e-01},
+{8.2394503e-01},
+{6.1941336e-01},
+{7.2410931e-01},
+{1.0158088e+00},
+{1.1491174e+00},
+{1.2188178e+00},
+{1.2007209e+00},
+{8.9859946e-01},
+{6.5456633e-01},
+{4.8391373e-01},
+{7.3135136e-01},
+{1.0176181e+00},
+{1.0277501e+00},
+{1.1176213e+00},
+{1.1248859e+00},
+{1.0041498e+00},
+{8.7364691e-01},
+{6.8812425e-01},
+{7.7228478e-01},
+{9.8423833e-01},
+{1.1655135e+00},
+{1.2710944e+00},
+{1.2619166e+00},
+{9.3651452e-01},
+{6.3284215e-01},
+{4.3578889e-01},
+{6.3021849e-01},
+{9.5269846e-01},
+{9.5770175e-01},
+{1.0064613e+00},
+{1.1416014e+00},
+{1.1318041e+00},
+{1.1173687e+00},
+{8.5933718e-01},
+{7.0364317e-01},
+{6.1326177e-01},
+{8.7318554e-01},
+{1.1121947e+00},
+{1.1737687e+00},
+{1.2616019e+00},
+{1.0447114e+00},
+{7.6386287e-01},
+{5.4149208e-01},
+{5.5006680e-01},
+{9.1816862e-01},
+{1.0427545e+00},
+{1.0385725e+00},
+{1.1744959e+00},
+{1.0484442e+00},
+{9.6566520e-01},
+{7.4941645e-01},
+{7.0654030e-01},
+{8.5978495e-01},
+{1.1007328e+00},
+{1.2172148e+00},
+{1.3084224e+00},
+{1.1066295e+00},
+{7.7306455e-01},
+{5.1195750e-01},
+{4.5881820e-01},
+{8.3991753e-01},
+{9.8090418e-01},
+{9.4402667e-01},
+{1.1150495e+00},
+{1.1263864e+00},
+{1.1498512e+00},
+{9.8537193e-01},
+{7.6788821e-01},
+{6.4101222e-01},
+{7.0798171e-01},
+{1.0241973e+00},
+{1.1588402e+00},
+{1.2194902e+00},
+{1.1900225e+00},
+{8.8503290e-01},
+{6.4170616e-01},
+{4.8247262e-01},
+{7.4633801e-01},
+{1.0194608e+00},
+{1.0238758e+00},
+{1.1225142e+00},
+{1.1204876e+00},
+{1.0078894e+00},
+{8.7195748e-01},
+{6.9071922e-01},
+{7.7128559e-01},
+{9.8171063e-01},
+{1.1648359e+00},
+{1.2716060e+00},
+{1.2653194e+00},
+{9.4044785e-01},
+{6.3462126e-01},
+{4.3541986e-01},
+{6.2397592e-01},
+{9.4996429e-01},
+{9.5654324e-01},
+{1.0018949e+00},
+{1.1415375e+00},
+{1.1340702e+00},
+{1.1242483e+00},
+{8.6601272e-01},
+{7.0479002e-01},
+{6.0700568e-01},
+{8.6003770e-01},
+{1.1056434e+00},
+{1.1671804e+00},
+{1.2575999e+00},
+{1.0561104e+00},
+{7.7723774e-01},
+{5.5451638e-01},
+{5.4470017e-01},
+{9.0953268e-01},
+{1.0489983e+00},
+{1.0432715e+00},
+{1.1787522e+00},
+{1.0466535e+00},
+{9.5253913e-01},
+{7.3976965e-01},
+{6.9910727e-01},
+{8.7457184e-01},
+{1.1111747e+00},
+{1.2168058e+00},
+{1.3037145e+00},
+{1.0820947e+00},
+{7.5710433e-01},
+{5.0441461e-01},
+{4.7923251e-01},
+{8.6434525e-01},
+{9.8624111e-01},
+{9.5555561e-01},
+{1.1291297e+00},
+{1.1187232e+00},
+{1.1339455e+00},
+{9.4624297e-01},
+{7.5185473e-01},
+{6.4886735e-01},
+{7.6947931e-01},
+{1.0640658e+00},
+{1.1819490e+00},
+{1.2581006e+00},
+{1.1479357e+00},
+{8.2795383e-01},
+{5.8084914e-01},
+{4.6968322e-01},
+{8.0540679e-01},
+{1.0147037e+00},
+{9.9267552e-01},
+{1.1297166e+00},
+{1.1074520e+00},
+{1.0535732e+00},
+{8.9989357e-01},
+{7.2414622e-01},
+{7.3710872e-01},
+{9.0842211e-01},
+{1.1372436e+00},
+{1.2550645e+00},
+{1.3118017e+00},
+{1.0309191e+00},
+{6.9715233e-01},
+{4.6014528e-01},
+{5.1093338e-01},
+{8.9602085e-01},
+{9.6063866e-01},
+{9.4454964e-01},
+{1.1299822e+00},
+{1.1400660e+00},
+{1.1784050e+00},
+{9.5942169e-01},
+{7.4592605e-01},
+{5.9179210e-01},
+{7.0833096e-01},
+{1.0269127e+00},
+{1.1280089e+00},
+{1.1874924e+00},
+{1.1668412e+00},
+{8.9924653e-01},
+{6.8916581e-01},
+{5.3047422e-01},
+{7.7534076e-01},
+{1.0549099e+00},
+{1.0847312e+00},
+{1.1818109e+00},
+{1.1071479e+00},
+{9.0609669e-01},
+{7.2016981e-01},
+{5.9922569e-01},
+{8.4631545e-01},
+{1.1007330e+00},
+{1.1539455e+00},
+{1.2548057e+00},
+{1.0707369e+00},
+{7.9955359e-01},
+{5.7211183e-01},
+{5.3729384e-01},
+{8.9511329e-01},
+{1.0559775e+00},
+{1.0482488e+00},
+{1.1833103e+00},
+{1.0467011e+00},
+{9.3892077e-01},
+{7.3109756e-01},
+{6.8881096e-01},
+{8.8724202e-01},
+{1.1196405e+00},
+{1.2137632e+00},
+{1.2969341e+00},
+{1.0598913e+00},
+{7.4476987e-01},
+{5.0025043e-01},
+{5.0175473e-01},
+{8.8612613e-01},
+{9.9295902e-01},
+{9.7027740e-01},
+{1.1406663e+00},
+{1.1082236e+00},
+{1.1111857e+00},
+{9.0519862e-01},
+{7.3853971e-01},
+{6.6752554e-01},
+{8.4076984e-01},
+{1.1041197e+00},
+{1.2107499e+00},
+{1.2910787e+00},
+{1.0889124e+00},
+{7.6218879e-01},
+{5.1854183e-01},
+{4.8212027e-01},
+{8.6343438e-01},
+{9.9664176e-01},
+{9.6786348e-01},
+{1.1354766e+00},
+{1.1100558e+00},
+{1.1078273e+00},
+{9.1950063e-01},
+{7.4186814e-01},
+{6.7554741e-01},
+{8.2771704e-01},
+{1.0970261e+00},
+{1.2115055e+00},
+{1.2926801e+00},
+{1.1044430e+00},
+{7.7268354e-01},
+{5.2367729e-01},
+{4.6962326e-01},
+{8.4775775e-01},
+{9.9325612e-01},
+{9.6094332e-01},
+{1.1271528e+00},
+{1.1156670e+00},
+{1.1183008e+00},
+{9.4351589e-01},
+{7.5035067e-01},
+{6.6773972e-01},
+{7.8886291e-01},
+{1.0750322e+00},
+{1.1971741e+00},
+{1.2770426e+00},
+{1.1387571e+00},
+{8.0837143e-01},
+{5.5509702e-01},
+{4.5955065e-01},
+{8.1398530e-01},
+{1.0008314e+00},
+{9.7057086e-01},
+{1.1195985e+00},
+{1.1149111e+00},
+{1.0957539e+00},
+{9.4451157e-01},
+{7.4819097e-01},
+{6.9474604e-01},
+{8.1250200e-01},
+{1.0876804e+00},
+{1.2158509e+00},
+{1.2988266e+00},
+{1.1270851e+00},
+{7.8595861e-01},
+{5.2690470e-01},
+{4.5032342e-01},
+{8.2266007e-01},
+{9.8371303e-01},
+{9.4630598e-01},
+{1.1090276e+00}};
+
+    private static readonly Dataset defaultDataset;
+    private static readonly IEnumerable<string> defaultAllowedInputVariables;
+    private static readonly string defaultTargetVariable;
+
+    static TimeSeriesPrognosisProblemData() {
+      defaultDataset = new Dataset(new string[] { "x" }, mackey_glass_17);
+      defaultDataset.Name = "Mackey-Glass (t=17) Time Series Benchmark Dataset";
+      defaultAllowedInputVariables = Enumerable.Empty<string>();
+      defaultTargetVariable = "x";
+    }
+    #endregion
+
+    private const string TrainingHorizonParameterName = "Training Horizon";
+    private const string TestHorizonParameterName = "Test Horizon";
+
+    public IFixedValueParameter<IntValue> TrainingHorizonParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[TrainingHorizonParameterName]; }
+    }
+    public IFixedValueParameter<IntValue> TestHorizonParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[TestHorizonParameterName]; }
+    }
+
+    #region Properties
+    public int TrainingHorizon {
+      get { return TrainingHorizonParameter.Value.Value; }
+      set { TrainingHorizonParameter.Value.Value = value; }
+    }
+
+    public int TestHorizon {
+      get { return TestHorizonParameter.Value.Value; }
+      set { TestHorizonParameter.Value.Value = value; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected TimeSeriesPrognosisProblemData(bool deserializing) : base(deserializing) { }
+
+    protected TimeSeriesPrognosisProblemData(TimeSeriesPrognosisProblemData original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TimeSeriesPrognosisProblemData(this, cloner);
+    }
+
+    public TimeSeriesPrognosisProblemData()
+      : this(defaultDataset, defaultAllowedInputVariables, defaultTargetVariable) {
+      TrainingPartition.Start = 50;
+    }
+    public TimeSeriesPrognosisProblemData(Dataset dataset, IEnumerable<string> allowedInputVariables, string targetVariable)
+      : base(dataset, allowedInputVariables, targetVariable) {
+      Parameters.Add(new FixedValueParameter<IntValue>(TrainingHorizonParameterName, "Specifies the horizon (how far the prognosis reaches in the future) for each training sample.", new IntValue(1)));
+      Parameters.Add(new FixedValueParameter<IntValue>(TestHorizonParameterName, "Specifies the horizon (how far the prognosis reaches in the future) for each test sample.", new IntValue(1)));
+
+      TrainingHorizonParameter.Hidden = true;
+      TestHorizonParameter.Hidden = true;
+
+      TrainingPartition.Start = Math.Min((int)(TrainingPartition.Size * 0.2), 50);
+
+      RegisterParameterEventHandlers();
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterParameterEventHandlers();
+    }
+
+    private void RegisterParameterEventHandlers() {
+      TrainingHorizonParameter.Value.ValueChanged += new System.EventHandler(Parameter_ValueChanged);
+      TestHorizonParameter.Value.ValueChanged += new System.EventHandler(Parameter_ValueChanged);
+    }
+
+    private void Parameter_ValueChanged(object sender, EventArgs e) {
+      OnChanged();
+    }
+
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisResults.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisResults.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisResults.cs	(revision 8798)
@@ -0,0 +1,456 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("Prognosis Results", "Represents a collection of time series prognosis results.")]
+  public class TimeSeriesPrognosisResults : ResultCollection {
+    #region result names
+    protected const string PrognosisTrainingMeanSquaredErrorResultName = "Mean squared error (training)";
+    protected const string PrognosisTestMeanSquaredErrorResultName = "Mean squared error (test)";
+    protected const string PrognosisTrainingMeanAbsoluteErrorResultName = "Mean absolute error (training)";
+    protected const string PrognosisTestMeanAbsoluteErrorResultName = "Mean absolute error (test)";
+    protected const string PrognosisTrainingSquaredCorrelationResultName = "Pearson's R² (training)";
+    protected const string PrognosisTestSquaredCorrelationResultName = "Pearson's R² (test)";
+    protected const string PrognosisTrainingRelativeErrorResultName = "Average relative error (training)";
+    protected const string PrognosisTestRelativeErrorResultName = "Average relative error (test)";
+    protected const string PrognosisTrainingNormalizedMeanSquaredErrorResultName = "Normalized mean squared error (training)";
+    protected const string PrognosisTestNormalizedMeanSquaredErrorResultName = "Normalized mean squared error (test)";
+    protected const string PrognosisTrainingMeanErrorResultName = "Mean error (training)";
+    protected const string PrognosisTestMeanErrorResultName = "Mean error (test)";
+
+    protected const string PrognosisTrainingDirectionalSymmetryResultName = "Average directional symmetry (training)";
+    protected const string PrognosisTestDirectionalSymmetryResultName = "Average directional symmetry (test)";
+    protected const string PrognosisTrainingWeightedDirectionalSymmetryResultName = "Average weighted directional symmetry (training)";
+    protected const string PrognosisTestWeightedDirectionalSymmetryResultName = "Average weighted directional symmetry (test)";
+    protected const string PrognosisTrainingTheilsUStatisticAR1ResultName = "Theil's U2 (AR1) (training)";
+    protected const string PrognosisTestTheilsUStatisticAR1ResultName = "Theil's U2 (AR1) (test)";
+    protected const string PrognosisTrainingTheilsUStatisticMeanResultName = "Theil's U2 (mean) (training)";
+    protected const string PrognosisTestTheilsUStatisticMeanResultName = "Theil's U2 (mean) (test)";
+    #endregion
+
+    #region result descriptions
+    protected const string PrognosisTrainingMeanSquaredErrorResultDescription = "Mean of squared errors of the model on the training partition";
+    protected const string PrognosisTestMeanSquaredErrorResultDescription = "Mean of squared errors of the model on the test partition";
+    protected const string PrognosisTrainingMeanAbsoluteErrorResultDescription = "Mean of absolute errors of the model on the training partition";
+    protected const string PrognosisTestMeanAbsoluteErrorResultDescription = "Mean of absolute errors of the model on the test partition";
+    protected const string PrognosisTrainingSquaredCorrelationResultDescription = "Squared Pearson's correlation coefficient of the model output and the actual values on the training partition";
+    protected const string PrognosisTestSquaredCorrelationResultDescription = "Squared Pearson's correlation coefficient of the model output and the actual values on the test partition";
+    protected const string PrognosisTrainingRelativeErrorResultDescription = "Average of the relative errors of the model output and the actual values on the training partition";
+    protected const string PrognosisTestRelativeErrorResultDescription = "Average of the relative errors of the model output and the actual values on the test partition";
+    protected const string PrognosisTrainingNormalizedMeanSquaredErrorResultDescription = "Normalized mean of squared errors of the model on the training partition";
+    protected const string PrognosisTestNormalizedMeanSquaredErrorResultDescription = "Normalized mean of squared errors of the model on the test partition";
+    protected const string PrognosisTrainingMeanErrorResultDescription = "Mean of errors of the model on the training partition";
+    protected const string PrognosisTestMeanErrorResultDescription = "Mean of errors of the model on the test partition";
+
+    protected const string PrognosisTrainingDirectionalSymmetryResultDescription = "The average directional symmetry of the forecasts of the model on the training partition";
+    protected const string PrognosisTestDirectionalSymmetryResultDescription = "The average directional symmetry of the forecasts of the model on the test partition";
+    protected const string PrognosisTrainingWeightedDirectionalSymmetryResultDescription = "The average weighted directional symmetry of the forecasts of the model on the training partition";
+    protected const string PrognosisTestWeightedDirectionalSymmetryResultDescription = "The average weighted directional symmetry of the forecasts of the model on the test partition";
+    protected const string PrognosisTrainingTheilsUStatisticAR1ResultDescription = "The Theil's U statistic (reference: AR1 model) of the forecasts of the model on the training partition";
+    protected const string PrognosisTestTheilsUStatisticAR1ResultDescription = "The Theil's U statistic (reference: AR1 model) of the forecasts of the model on the test partition";
+    protected const string PrognosisTrainingTheilsUStatisticMeanResultDescription = "The Theil's U statistic (reference: mean model) of the forecasts of the model on the training partition";
+    protected const string PrognosisTestTheilsUStatisticMeanResultDescription = "The Theil's U statistic (reference: mean value) of the forecasts of the model on the test partition";
+    #endregion
+
+    #region result properties
+    //prognosis results for different horizons
+    public double PrognosisTrainingMeanSquaredError {
+      get {
+        if (!ContainsKey(PrognosisTrainingMeanSquaredErrorResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTrainingMeanSquaredErrorResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTrainingMeanSquaredErrorResultName)) Add(new Result(PrognosisTrainingMeanSquaredErrorResultName, PrognosisTrainingMeanSquaredErrorResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTrainingMeanSquaredErrorResultName].Value).Value = value;
+      }
+    }
+
+    public double PrognosisTestMeanSquaredError {
+      get {
+        if (!ContainsKey(PrognosisTestMeanSquaredErrorResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTestMeanSquaredErrorResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTestMeanSquaredErrorResultName)) Add(new Result(PrognosisTestMeanSquaredErrorResultName, PrognosisTestMeanSquaredErrorResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTestMeanSquaredErrorResultName].Value).Value = value;
+      }
+    }
+
+    public double PrognosisTrainingMeanAbsoluteError {
+      get {
+        if (!ContainsKey(PrognosisTrainingMeanAbsoluteErrorResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTrainingMeanAbsoluteErrorResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTrainingMeanAbsoluteErrorResultName)) Add(new Result(PrognosisTrainingMeanAbsoluteErrorResultName, PrognosisTrainingMeanAbsoluteErrorResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTrainingMeanAbsoluteErrorResultName].Value).Value = value;
+      }
+    }
+
+    public double PrognosisTestMeanAbsoluteError {
+      get {
+        if (!ContainsKey(PrognosisTestMeanAbsoluteErrorResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTestMeanAbsoluteErrorResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTestMeanAbsoluteErrorResultName)) Add(new Result(PrognosisTestMeanAbsoluteErrorResultName, PrognosisTestMeanAbsoluteErrorResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTestMeanAbsoluteErrorResultName].Value).Value = value;
+      }
+    }
+
+    public double PrognosisTrainingRSquared {
+      get {
+        if (!ContainsKey(PrognosisTrainingSquaredCorrelationResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTrainingSquaredCorrelationResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTrainingSquaredCorrelationResultName)) Add(new Result(PrognosisTrainingSquaredCorrelationResultName, PrognosisTrainingSquaredCorrelationResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTrainingSquaredCorrelationResultName].Value).Value = value;
+      }
+    }
+
+    public double PrognosisTestRSquared {
+      get {
+        if (!ContainsKey(PrognosisTestSquaredCorrelationResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTestSquaredCorrelationResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTestSquaredCorrelationResultName)) Add(new Result(PrognosisTestSquaredCorrelationResultName, PrognosisTestSquaredCorrelationResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTestSquaredCorrelationResultName].Value).Value = value;
+      }
+    }
+
+    public double PrognosisTrainingRelativeError {
+      get {
+        if (!ContainsKey(PrognosisTrainingRelativeErrorResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTrainingRelativeErrorResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTrainingRelativeErrorResultName)) Add(new Result(PrognosisTrainingRelativeErrorResultName, PrognosisTrainingRelativeErrorResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTrainingRelativeErrorResultName].Value).Value = value;
+      }
+    }
+
+    public double PrognosisTestRelativeError {
+      get {
+        if (!ContainsKey(PrognosisTestRelativeErrorResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTestRelativeErrorResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTestRelativeErrorResultName)) Add(new Result(PrognosisTestRelativeErrorResultName, PrognosisTestRelativeErrorResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTestRelativeErrorResultName].Value).Value = value;
+      }
+    }
+
+    public double PrognosisTrainingNormalizedMeanSquaredError {
+      get {
+        if (!ContainsKey(PrognosisTrainingNormalizedMeanSquaredErrorResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTrainingNormalizedMeanSquaredErrorResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTrainingNormalizedMeanSquaredErrorResultName)) Add(new Result(PrognosisTrainingNormalizedMeanSquaredErrorResultName, PrognosisTrainingNormalizedMeanSquaredErrorResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTrainingNormalizedMeanSquaredErrorResultName].Value).Value = value;
+      }
+    }
+
+    public double PrognosisTestNormalizedMeanSquaredError {
+      get {
+        if (!ContainsKey(PrognosisTestNormalizedMeanSquaredErrorResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTestNormalizedMeanSquaredErrorResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTestNormalizedMeanSquaredErrorResultName)) Add(new Result(PrognosisTestNormalizedMeanSquaredErrorResultName, PrognosisTestNormalizedMeanSquaredErrorResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTestNormalizedMeanSquaredErrorResultName].Value).Value = value;
+      }
+    }
+
+    public double PrognosisTrainingMeanError {
+      get {
+        if (!ContainsKey(PrognosisTrainingMeanErrorResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTrainingMeanErrorResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTrainingMeanErrorResultName)) Add(new Result(PrognosisTrainingMeanErrorResultName, PrognosisTrainingMeanErrorResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTrainingMeanErrorResultName].Value).Value = value;
+      }
+    }
+
+    public double PrognosisTestMeanError {
+      get {
+        if (!ContainsKey(PrognosisTestMeanErrorResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTestMeanErrorResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTestMeanErrorResultName)) Add(new Result(PrognosisTestMeanErrorResultName, PrognosisTestMeanErrorResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTestMeanErrorResultName].Value).Value = value;
+      }
+    }
+
+
+    public double PrognosisTrainingDirectionalSymmetry {
+      get {
+        if (!ContainsKey(PrognosisTrainingDirectionalSymmetryResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTrainingDirectionalSymmetryResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTrainingDirectionalSymmetryResultName)) Add(new Result(PrognosisTrainingDirectionalSymmetryResultName, PrognosisTrainingDirectionalSymmetryResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTrainingDirectionalSymmetryResultName].Value).Value = value;
+      }
+    }
+    public double PrognosisTestDirectionalSymmetry {
+      get {
+        if (!ContainsKey(PrognosisTestDirectionalSymmetryResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTestDirectionalSymmetryResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTestDirectionalSymmetryResultName)) Add(new Result(PrognosisTestDirectionalSymmetryResultName, PrognosisTestDirectionalSymmetryResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTestDirectionalSymmetryResultName].Value).Value = value;
+      }
+    }
+    public double PrognosisTrainingWeightedDirectionalSymmetry {
+      get {
+        if (!ContainsKey(PrognosisTrainingWeightedDirectionalSymmetryResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTrainingWeightedDirectionalSymmetryResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTrainingWeightedDirectionalSymmetryResultName)) Add(new Result(PrognosisTrainingWeightedDirectionalSymmetryResultName, PrognosisTrainingWeightedDirectionalSymmetryResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTrainingWeightedDirectionalSymmetryResultName].Value).Value = value;
+      }
+    }
+    public double PrognosisTestWeightedDirectionalSymmetry {
+      get {
+        if (!ContainsKey(PrognosisTestWeightedDirectionalSymmetryResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTestWeightedDirectionalSymmetryResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTestWeightedDirectionalSymmetryResultName)) Add(new Result(PrognosisTestWeightedDirectionalSymmetryResultName, PrognosisTestWeightedDirectionalSymmetryResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTestWeightedDirectionalSymmetryResultName].Value).Value = value;
+      }
+    }
+    public double PrognosisTrainingTheilsUStatisticAR1 {
+      get {
+        if (!ContainsKey(PrognosisTrainingTheilsUStatisticAR1ResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTrainingTheilsUStatisticAR1ResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTrainingTheilsUStatisticAR1ResultName)) Add(new Result(PrognosisTrainingTheilsUStatisticAR1ResultName, PrognosisTrainingTheilsUStatisticAR1ResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTrainingTheilsUStatisticAR1ResultName].Value).Value = value;
+      }
+    }
+    public double PrognosisTestTheilsUStatisticAR1 {
+      get {
+        if (!ContainsKey(PrognosisTestTheilsUStatisticAR1ResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTestTheilsUStatisticAR1ResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTestTheilsUStatisticAR1ResultName)) Add(new Result(PrognosisTestTheilsUStatisticAR1ResultName, PrognosisTestTheilsUStatisticAR1ResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTestTheilsUStatisticAR1ResultName].Value).Value = value;
+      }
+    }
+    public double PrognosisTrainingTheilsUStatisticMean {
+      get {
+        if (!ContainsKey(PrognosisTrainingTheilsUStatisticMeanResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTrainingTheilsUStatisticMeanResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTrainingTheilsUStatisticMeanResultName)) Add(new Result(PrognosisTrainingTheilsUStatisticMeanResultName, PrognosisTrainingTheilsUStatisticMeanResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTrainingTheilsUStatisticMeanResultName].Value).Value = value;
+      }
+    }
+    public double PrognosisTestTheilsUStatisticMean {
+      get {
+        if (!ContainsKey(PrognosisTestTheilsUStatisticMeanResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTestTheilsUStatisticMeanResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTestTheilsUStatisticMeanResultName)) Add(new Result(PrognosisTestTheilsUStatisticMeanResultName, PrognosisTestTheilsUStatisticMeanResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTestTheilsUStatisticMeanResultName].Value).Value = value;
+      }
+    }
+    #endregion
+
+    [Storable]
+    private int trainingHorizon;
+    public int TrainingHorizon {
+      get { return trainingHorizon; }
+      set {
+        if (trainingHorizon != value) {
+          trainingHorizon = value;
+          OnTrainingHorizonChanged();
+        }
+      }
+    }
+
+    [Storable]
+    private int testHorizon;
+    public int TestHorizon {
+      get { return testHorizon; }
+      set {
+        if (testHorizon != value) {
+          testHorizon = value;
+          OnTestHorizonChanged();
+        }
+      }
+    }
+
+    private ITimeSeriesPrognosisSolution solution;
+    [Storable]
+    public ITimeSeriesPrognosisSolution Solution {
+      get { return solution; }
+      private set { solution = value; } //necessary for persistence
+    }
+
+    [StorableConstructor]
+    public TimeSeriesPrognosisResults(bool deserializing) : base(deserializing) { }
+    protected TimeSeriesPrognosisResults(TimeSeriesPrognosisResults original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TimeSeriesPrognosisResults(this, cloner);
+    }
+
+    public TimeSeriesPrognosisResults(int trainingHorizon, int testHorizon, ITimeSeriesPrognosisSolution solution)
+      : base() {
+      this.trainingHorizon = trainingHorizon;
+      this.testHorizon = testHorizon;
+      this.solution = solution;
+      CalculateTrainingPrognosisResults();
+      CalculateTestPrognosisResults();
+    }
+
+    #region events
+    public event EventHandler TrainingHorizonChanged;
+    protected virtual void OnTrainingHorizonChanged() {
+      CalculateTrainingPrognosisResults();
+      var handler = TrainingHorizonChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    public event EventHandler TestHorizonChanged;
+    protected virtual void OnTestHorizonChanged() {
+      CalculateTestPrognosisResults();
+      var handler = TestHorizonChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    #endregion
+
+    private void CalculateTrainingPrognosisResults() {
+      OnlineCalculatorError errorState;
+      var problemData = Solution.ProblemData;
+      var model = Solution.Model;
+      //mean model
+      double trainingMean = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TrainingIndices).Average();
+      var meanModel = new ConstantTimeSeriesPrognosisModel(trainingMean);
+
+      //AR1 model
+      double alpha, beta;
+      IEnumerable<double> trainingStartValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TrainingIndices.Select(r => r - 1).Where(r => r > 0)).ToList();
+      OnlineLinearScalingParameterCalculator.Calculate(problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TrainingIndices.Where(x => x > 0)), trainingStartValues, out alpha, out beta, out errorState);
+      var AR1model = new TimeSeriesPrognosisAutoRegressiveModel(problemData.TargetVariable, new double[] { beta }, alpha);
+
+      var trainingHorizions = problemData.TrainingIndices.Select(r => Math.Min(trainingHorizon, problemData.TrainingPartition.End - r)).ToList();
+      IEnumerable<IEnumerable<double>> trainingTargetValues = problemData.TrainingIndices.Zip(trainingHorizions, Enumerable.Range).Select(r => problemData.Dataset.GetDoubleValues(problemData.TargetVariable, r)).ToList();
+      IEnumerable<IEnumerable<double>> trainingEstimatedValues = model.GetPrognosedValues(problemData.Dataset, problemData.TrainingIndices, trainingHorizions).ToList();
+      IEnumerable<IEnumerable<double>> trainingMeanModelPredictions = meanModel.GetPrognosedValues(problemData.Dataset, problemData.TrainingIndices, trainingHorizions).ToList();
+      IEnumerable<IEnumerable<double>> trainingAR1ModelPredictions = AR1model.GetPrognosedValues(problemData.Dataset, problemData.TrainingIndices, trainingHorizions).ToList();
+
+      IEnumerable<double> originalTrainingValues = trainingTargetValues.SelectMany(x => x).ToList();
+      IEnumerable<double> estimatedTrainingValues = trainingEstimatedValues.SelectMany(x => x).ToList();
+
+      double trainingMSE = OnlineMeanSquaredErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
+      PrognosisTrainingMeanSquaredError = errorState == OnlineCalculatorError.None ? trainingMSE : double.NaN;
+      double trainingMAE = OnlineMeanAbsoluteErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
+      PrognosisTrainingMeanAbsoluteError = errorState == OnlineCalculatorError.None ? trainingMAE : double.NaN;
+      double trainingR2 = OnlinePearsonsRSquaredCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
+      PrognosisTrainingRSquared = errorState == OnlineCalculatorError.None ? trainingR2 : double.NaN;
+      double trainingRelError = OnlineMeanAbsolutePercentageErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
+      PrognosisTrainingRelativeError = errorState == OnlineCalculatorError.None ? trainingRelError : double.NaN;
+      double trainingNMSE = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
+      PrognosisTrainingNormalizedMeanSquaredError = errorState == OnlineCalculatorError.None ? trainingNMSE : double.NaN;
+      double trainingME = OnlineMeanErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
+      PrognosisTrainingMeanError = errorState == OnlineCalculatorError.None ? trainingME : double.NaN;
+
+      PrognosisTrainingDirectionalSymmetry = OnlineDirectionalSymmetryCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingEstimatedValues, out errorState);
+      PrognosisTrainingDirectionalSymmetry = errorState == OnlineCalculatorError.None ? PrognosisTrainingDirectionalSymmetry : 0.0;
+      PrognosisTrainingWeightedDirectionalSymmetry = OnlineWeightedDirectionalSymmetryCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingEstimatedValues, out errorState);
+      PrognosisTrainingWeightedDirectionalSymmetry = errorState == OnlineCalculatorError.None ? PrognosisTrainingWeightedDirectionalSymmetry : 0.0;
+      PrognosisTrainingTheilsUStatisticAR1 = OnlineTheilsUStatisticCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingAR1ModelPredictions, trainingEstimatedValues, out errorState);
+      PrognosisTrainingTheilsUStatisticAR1 = errorState == OnlineCalculatorError.None ? PrognosisTrainingTheilsUStatisticAR1 : double.PositiveInfinity;
+      PrognosisTrainingTheilsUStatisticMean = OnlineTheilsUStatisticCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingMeanModelPredictions, trainingEstimatedValues, out errorState);
+      PrognosisTrainingTheilsUStatisticMean = errorState == OnlineCalculatorError.None ? PrognosisTrainingTheilsUStatisticMean : double.PositiveInfinity;
+    }
+
+    private void CalculateTestPrognosisResults() {
+      OnlineCalculatorError errorState;
+      var problemData = Solution.ProblemData;
+      var model = Solution.Model;
+      //mean model
+      double trainingMean = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TrainingIndices).Average();
+      var meanModel = new ConstantTimeSeriesPrognosisModel(trainingMean);
+
+      //AR1 model
+      double alpha, beta;
+      IEnumerable<double> trainingStartValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TrainingIndices.Select(r => r - 1).Where(r => r > 0)).ToList();
+      OnlineLinearScalingParameterCalculator.Calculate(problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TrainingIndices.Where(x => x > 0)), trainingStartValues, out alpha, out beta, out errorState);
+      var AR1model = new TimeSeriesPrognosisAutoRegressiveModel(problemData.TargetVariable, new double[] { beta }, alpha);
+
+      var testHorizions = problemData.TestIndices.Select(r => Math.Min(testHorizon, problemData.TestPartition.End - r)).ToList();
+      IEnumerable<IEnumerable<double>> testTargetValues = problemData.TestIndices.Zip(testHorizions, Enumerable.Range).Select(r => problemData.Dataset.GetDoubleValues(problemData.TargetVariable, r)).ToList();
+      IEnumerable<IEnumerable<double>> testEstimatedValues = model.GetPrognosedValues(problemData.Dataset, problemData.TestIndices, testHorizions).ToList();
+      IEnumerable<double> testStartValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TestIndices.Select(r => r - 1).Where(r => r > 0)).ToList();
+      IEnumerable<IEnumerable<double>> testMeanModelPredictions = meanModel.GetPrognosedValues(problemData.Dataset, problemData.TestIndices, testHorizions).ToList();
+      IEnumerable<IEnumerable<double>> testAR1ModelPredictions = AR1model.GetPrognosedValues(problemData.Dataset, problemData.TestIndices, testHorizions).ToList();
+
+      IEnumerable<double> originalTestValues = testTargetValues.SelectMany(x => x).ToList();
+      IEnumerable<double> estimatedTestValues = testEstimatedValues.SelectMany(x => x).ToList();
+
+      double testMSE = OnlineMeanSquaredErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
+      PrognosisTestMeanSquaredError = errorState == OnlineCalculatorError.None ? testMSE : double.NaN;
+      double testMAE = OnlineMeanAbsoluteErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
+      PrognosisTestMeanAbsoluteError = errorState == OnlineCalculatorError.None ? testMAE : double.NaN;
+      double testR2 = OnlinePearsonsRSquaredCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
+      PrognosisTestRSquared = errorState == OnlineCalculatorError.None ? testR2 : double.NaN;
+      double testRelError = OnlineMeanAbsolutePercentageErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
+      PrognosisTestRelativeError = errorState == OnlineCalculatorError.None ? testRelError : double.NaN;
+      double testNMSE = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
+      PrognosisTestNormalizedMeanSquaredError = errorState == OnlineCalculatorError.None ? testNMSE : double.NaN;
+      double testME = OnlineMeanErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
+      PrognosisTestMeanError = errorState == OnlineCalculatorError.None ? testME : double.NaN;
+
+      PrognosisTestDirectionalSymmetry = OnlineDirectionalSymmetryCalculator.Calculate(testStartValues, testTargetValues, testEstimatedValues, out errorState);
+      PrognosisTestDirectionalSymmetry = errorState == OnlineCalculatorError.None ? PrognosisTestDirectionalSymmetry : 0.0;
+      PrognosisTestWeightedDirectionalSymmetry = OnlineWeightedDirectionalSymmetryCalculator.Calculate(testStartValues, testTargetValues, testEstimatedValues, out errorState);
+      PrognosisTestWeightedDirectionalSymmetry = errorState == OnlineCalculatorError.None ? PrognosisTestWeightedDirectionalSymmetry : 0.0;
+      PrognosisTestTheilsUStatisticAR1 = OnlineTheilsUStatisticCalculator.Calculate(testStartValues, testTargetValues, testAR1ModelPredictions, testEstimatedValues, out errorState);
+      PrognosisTestTheilsUStatisticAR1 = errorState == OnlineCalculatorError.None ? PrognosisTestTheilsUStatisticAR1 : double.PositiveInfinity;
+      PrognosisTestTheilsUStatisticMean = OnlineTheilsUStatisticCalculator.Calculate(testStartValues, testTargetValues, testMeanModelPredictions, testEstimatedValues, out errorState);
+      PrognosisTestTheilsUStatisticMean = errorState == OnlineCalculatorError.None ? PrognosisTestTheilsUStatisticMean : double.PositiveInfinity;
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolution.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolution.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolution.cs	(revision 8798)
@@ -0,0 +1,46 @@
+#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.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  /// <summary>
+  /// Represents a time series prognosis data analysis solution
+  /// </summary>
+  [StorableClass]
+  public class TimeSeriesPrognosisSolution : TimeSeriesPrognosisSolutionBase {
+    [StorableConstructor]
+    protected TimeSeriesPrognosisSolution(bool deserializing) : base(deserializing) { }
+    protected TimeSeriesPrognosisSolution(TimeSeriesPrognosisSolution original, Cloner cloner) : base(original, cloner) { }
+    protected internal TimeSeriesPrognosisSolution(ITimeSeriesPrognosisModel model, ITimeSeriesPrognosisProblemData problemData)
+      : base(model, problemData) {
+      CalculateRegressionResults();
+      CalculateTimeSeriesResults();
+      CalculateTimeSeriesResults(ProblemData.TrainingHorizon, ProblemData.TestHorizon);
+    }
+
+    public override IEnumerable<IEnumerable<double>> GetPrognosedValues(IEnumerable<int> rows, IEnumerable<int> horizons) {
+      return Model.GetPrognosedValues(ProblemData.Dataset, rows, horizons);
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionBase.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionBase.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionBase.cs	(revision 8798)
@@ -0,0 +1,197 @@
+﻿#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.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  public abstract class TimeSeriesPrognosisSolutionBase : RegressionSolutionBase, ITimeSeriesPrognosisSolution {
+    #region result names
+    protected const string TrainingDirectionalSymmetryResultName = "Average directional symmetry (training)";
+    protected const string TestDirectionalSymmetryResultName = "Average directional symmetry (test)";
+    protected const string TrainingWeightedDirectionalSymmetryResultName = "Average weighted directional symmetry (training)";
+    protected const string TestWeightedDirectionalSymmetryResultName = "Average weighted directional symmetry (test)";
+    protected const string TrainingTheilsUStatisticAR1ResultName = "Theil's U2 (AR1) (training)";
+    protected const string TestTheilsUStatisticLastResultName = "Theil's U2 (AR1) (test)";
+    protected const string TrainingTheilsUStatisticMeanResultName = "Theil's U2 (mean) (training)";
+    protected const string TestTheilsUStatisticMeanResultName = "Theil's U2 (mean) (test)";
+    protected const string TimeSeriesPrognosisResultName = "Prognosis Results";
+    #endregion
+
+    #region result descriptions
+    protected const string TrainingDirectionalSymmetryResultDescription = "The average directional symmetry of the forecasts of the model on the training partition";
+    protected const string TestDirectionalSymmetryResultDescription = "The average directional symmetry of the forecasts of the model on the test partition";
+    protected const string TrainingWeightedDirectionalSymmetryResultDescription = "The average weighted directional symmetry of the forecasts of the model on the training partition";
+    protected const string TestWeightedDirectionalSymmetryResultDescription = "The average weighted directional symmetry of the forecasts of the model on the test partition";
+    protected const string TrainingTheilsUStatisticAR1ResultDescription = "The Theil's U statistic (reference: AR1 model) of the forecasts of the model on the training partition";
+    protected const string TestTheilsUStatisticAR1ResultDescription = "The Theil's U statistic (reference: AR1 model) of the forecasts of the model on the test partition";
+    protected const string TrainingTheilsUStatisticMeanResultDescription = "The Theil's U statistic (reference: mean model) of the forecasts of the model on the training partition";
+    protected const string TestTheilsUStatisticMeanResultDescription = "The Theil's U statistic (reference: mean value) of the forecasts of the model on the test partition";
+    protected const string TimeSeriesPrognosisResultDescription = "The calculated results of predictions in the future.";
+    #endregion
+
+    public new ITimeSeriesPrognosisModel Model {
+      get { return (ITimeSeriesPrognosisModel)base.Model; }
+      protected set { base.Model = value; }
+    }
+
+    public new ITimeSeriesPrognosisProblemData ProblemData {
+      get { return (ITimeSeriesPrognosisProblemData)base.ProblemData; }
+      set { base.ProblemData = value; }
+    }
+
+    public abstract IEnumerable<IEnumerable<double>> GetPrognosedValues(IEnumerable<int> rows, IEnumerable<int> horizon);
+
+    #region Results
+    public double TrainingDirectionalSymmetry {
+      get { return ((DoubleValue)this[TrainingDirectionalSymmetryResultName].Value).Value; }
+      private set { ((DoubleValue)this[TrainingDirectionalSymmetryResultName].Value).Value = value; }
+    }
+    public double TestDirectionalSymmetry {
+      get { return ((DoubleValue)this[TestDirectionalSymmetryResultName].Value).Value; }
+      private set { ((DoubleValue)this[TestDirectionalSymmetryResultName].Value).Value = value; }
+    }
+    public double TrainingWeightedDirectionalSymmetry {
+      get { return ((DoubleValue)this[TrainingWeightedDirectionalSymmetryResultName].Value).Value; }
+      private set { ((DoubleValue)this[TrainingWeightedDirectionalSymmetryResultName].Value).Value = value; }
+    }
+    public double TestWeightedDirectionalSymmetry {
+      get { return ((DoubleValue)this[TestWeightedDirectionalSymmetryResultName].Value).Value; }
+      private set { ((DoubleValue)this[TestWeightedDirectionalSymmetryResultName].Value).Value = value; }
+    }
+    public double TrainingTheilsUStatisticAR1 {
+      get { return ((DoubleValue)this[TrainingTheilsUStatisticAR1ResultName].Value).Value; }
+      private set { ((DoubleValue)this[TrainingTheilsUStatisticAR1ResultName].Value).Value = value; }
+    }
+    public double TestTheilsUStatisticAR1 {
+      get { return ((DoubleValue)this[TestTheilsUStatisticLastResultName].Value).Value; }
+      private set { ((DoubleValue)this[TestTheilsUStatisticLastResultName].Value).Value = value; }
+    }
+    public double TrainingTheilsUStatisticMean {
+      get { return ((DoubleValue)this[TrainingTheilsUStatisticMeanResultName].Value).Value; }
+      private set { ((DoubleValue)this[TrainingTheilsUStatisticMeanResultName].Value).Value = value; }
+    }
+    public double TestTheilsUStatisticMean {
+      get { return ((DoubleValue)this[TestTheilsUStatisticMeanResultName].Value).Value; }
+      private set { ((DoubleValue)this[TestTheilsUStatisticMeanResultName].Value).Value = value; }
+    }
+
+    public TimeSeriesPrognosisResults TimeSeriesPrognosisResults {
+      get {
+        if (!ContainsKey(TimeSeriesPrognosisResultName)) return null;
+        return (TimeSeriesPrognosisResults)this[TimeSeriesPrognosisResultName];
+      }
+      set {
+        if (ContainsKey(TimeSeriesPrognosisResultName)) Remove(TimeSeriesPrognosisResultName);
+        Add(new Result(TimeSeriesPrognosisResultName, TimeSeriesPrognosisResultDescription, value));
+      }
+    }
+    #endregion
+
+
+    public override IEnumerable<double> EstimatedValues {
+      get { return GetEstimatedValues(Enumerable.Range(0, ProblemData.Dataset.Rows)); }
+    }
+    public override IEnumerable<double> EstimatedTrainingValues {
+      get { return GetEstimatedValues(ProblemData.TrainingIndices); }
+    }
+    public override IEnumerable<double> EstimatedTestValues {
+      get { return GetEstimatedValues(ProblemData.TestIndices); }
+    }
+    public override IEnumerable<double> GetEstimatedValues(IEnumerable<int> rows) {
+      return Model.GetEstimatedValues(ProblemData.Dataset, rows);
+    }
+
+    [StorableConstructor]
+    protected TimeSeriesPrognosisSolutionBase(bool deserializing) : base(deserializing) { }
+    protected TimeSeriesPrognosisSolutionBase(TimeSeriesPrognosisSolutionBase original, Cloner cloner) : base(original, cloner) { }
+    protected TimeSeriesPrognosisSolutionBase(ITimeSeriesPrognosisModel model, ITimeSeriesPrognosisProblemData problemData)
+      : base(model, problemData) {
+      Add(new Result(TrainingDirectionalSymmetryResultName, TrainingDirectionalSymmetryResultDescription, new DoubleValue()));
+      Add(new Result(TestDirectionalSymmetryResultName, TestDirectionalSymmetryResultDescription, new DoubleValue()));
+      Add(new Result(TrainingWeightedDirectionalSymmetryResultName, TrainingWeightedDirectionalSymmetryResultDescription, new DoubleValue()));
+      Add(new Result(TestWeightedDirectionalSymmetryResultName, TestWeightedDirectionalSymmetryResultDescription, new DoubleValue()));
+      Add(new Result(TrainingTheilsUStatisticAR1ResultName, TrainingTheilsUStatisticAR1ResultDescription, new DoubleValue()));
+      Add(new Result(TestTheilsUStatisticLastResultName, TestTheilsUStatisticAR1ResultDescription, new DoubleValue()));
+      Add(new Result(TrainingTheilsUStatisticMeanResultName, TrainingTheilsUStatisticMeanResultDescription, new DoubleValue()));
+      Add(new Result(TestTheilsUStatisticMeanResultName, TestTheilsUStatisticMeanResultDescription, new DoubleValue()));
+    }
+
+    protected override void RecalculateResults() {
+      base.RecalculateResults();
+      CalculateTimeSeriesResults();
+      CalculateTimeSeriesResults(ProblemData.TrainingHorizon, ProblemData.TestHorizon);
+    }
+
+    protected void CalculateTimeSeriesResults() {
+      OnlineCalculatorError errorState;
+      double trainingMean = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices).Average();
+      var meanModel = new ConstantTimeSeriesPrognosisModel(trainingMean);
+
+      double alpha, beta;
+      IEnumerable<double> trainingStartValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices.Select(r => r - 1).Where(r => r > 0)).ToList();
+      OnlineLinearScalingParameterCalculator.Calculate(ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices.Where(x => x > 0)), trainingStartValues, out alpha, out beta, out errorState);
+      var AR1model = new TimeSeriesPrognosisAutoRegressiveModel(ProblemData.TargetVariable, new double[] { beta }, alpha);
+
+
+      #region Calculate training quality measures
+      IEnumerable<double> trainingTargetValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices).ToList();
+      IEnumerable<double> trainingEstimatedValues = EstimatedTrainingValues.ToList();
+      IEnumerable<double> trainingMeanModelPredictions = meanModel.GetEstimatedValues(ProblemData.Dataset, ProblemData.TrainingIndices).ToList();
+      IEnumerable<double> trainingAR1ModelPredictions = AR1model.GetEstimatedValues(ProblemData.Dataset, ProblemData.TrainingIndices).ToList();
+
+      TrainingDirectionalSymmetry = OnlineDirectionalSymmetryCalculator.Calculate(trainingTargetValues.First(), trainingTargetValues, trainingEstimatedValues, out errorState);
+      TrainingDirectionalSymmetry = errorState == OnlineCalculatorError.None ? TrainingDirectionalSymmetry : 0.0;
+      TrainingWeightedDirectionalSymmetry = OnlineWeightedDirectionalSymmetryCalculator.Calculate(trainingTargetValues.First(), trainingTargetValues, trainingEstimatedValues, out errorState);
+      TrainingWeightedDirectionalSymmetry = errorState == OnlineCalculatorError.None ? TrainingWeightedDirectionalSymmetry : 0.0;
+      TrainingTheilsUStatisticAR1 = OnlineTheilsUStatisticCalculator.Calculate(trainingTargetValues.First(), trainingTargetValues, trainingAR1ModelPredictions, trainingEstimatedValues, out errorState);
+      TrainingTheilsUStatisticAR1 = errorState == OnlineCalculatorError.None ? TrainingTheilsUStatisticAR1 : double.PositiveInfinity;
+      TrainingTheilsUStatisticMean = OnlineTheilsUStatisticCalculator.Calculate(trainingTargetValues.First(), trainingTargetValues, trainingMeanModelPredictions, trainingEstimatedValues, out errorState);
+      TrainingTheilsUStatisticMean = errorState == OnlineCalculatorError.None ? TrainingTheilsUStatisticMean : double.PositiveInfinity;
+      #endregion
+
+      #region Calculate test quality measures
+      IEnumerable<double> testTargetValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TestIndices).ToList();
+      IEnumerable<double> testEstimatedValues = EstimatedTestValues.ToList();
+      IEnumerable<double> testMeanModelPredictions = meanModel.GetEstimatedValues(ProblemData.Dataset, ProblemData.TestIndices).ToList();
+      IEnumerable<double> testAR1ModelPredictions = AR1model.GetEstimatedValues(ProblemData.Dataset, ProblemData.TestIndices).ToList();
+
+      TestDirectionalSymmetry = OnlineDirectionalSymmetryCalculator.Calculate(testTargetValues.First(), testTargetValues, testEstimatedValues, out errorState);
+      TestDirectionalSymmetry = errorState == OnlineCalculatorError.None ? TestDirectionalSymmetry : 0.0;
+      TestWeightedDirectionalSymmetry = OnlineWeightedDirectionalSymmetryCalculator.Calculate(testTargetValues.First(), testTargetValues, testEstimatedValues, out errorState);
+      TestWeightedDirectionalSymmetry = errorState == OnlineCalculatorError.None ? TestWeightedDirectionalSymmetry : 0.0;
+      TestTheilsUStatisticAR1 = OnlineTheilsUStatisticCalculator.Calculate(testTargetValues.First(), testTargetValues, testAR1ModelPredictions, testEstimatedValues, out errorState);
+      TestTheilsUStatisticAR1 = errorState == OnlineCalculatorError.None ? TestTheilsUStatisticAR1 : double.PositiveInfinity;
+      TestTheilsUStatisticMean = OnlineTheilsUStatisticCalculator.Calculate(testTargetValues.First(), testTargetValues, testMeanModelPredictions, testEstimatedValues, out errorState);
+      TestTheilsUStatisticMean = errorState == OnlineCalculatorError.None ? TestTheilsUStatisticMean : double.PositiveInfinity;
+      #endregion
+    }
+
+    protected void CalculateTimeSeriesResults(int trainingHorizon, int testHorizon) {
+      TimeSeriesPrognosisResults = new TimeSeriesPrognosisResults(trainingHorizon, testHorizon, this);
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/IOnlineTimeSeriesCalculator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/IOnlineTimeSeriesCalculator.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/IOnlineTimeSeriesCalculator.cs	(revision 8798)
@@ -0,0 +1,33 @@
+#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;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface IOnlineTimeSeriesCalculator {
+    OnlineCalculatorError ErrorState { get; }
+    double Value { get; }
+    void Reset();
+    void Add(double startValue, IEnumerable<double> actualContinuation, IEnumerable<double> predictedContinuation);
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisModel.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisModel.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisModel.cs	(revision 8798)
@@ -0,0 +1,28 @@
+﻿#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.Collections.Generic;
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface ITimeSeriesPrognosisModel : IRegressionModel {
+    IEnumerable<IEnumerable<double>> GetPrognosedValues(Dataset dataset, IEnumerable<int> rows, IEnumerable<int> horizons);
+    ITimeSeriesPrognosisSolution CreateTimeSeriesPrognosisSolution(ITimeSeriesPrognosisProblemData problemData);
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisProblem.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisProblem.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisProblem.cs	(revision 8798)
@@ -0,0 +1,25 @@
+﻿#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
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface ITimeSeriesPrognosisProblem : IDataAnalysisProblem<ITimeSeriesPrognosisProblemData> {
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisProblemData.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisProblemData.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisProblemData.cs	(revision 8798)
@@ -0,0 +1,27 @@
+﻿#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
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface ITimeSeriesPrognosisProblemData : IRegressionProblemData {
+    int TrainingHorizon { get; set; }
+    int TestHorizon { get; set; }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisSolution.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisSolution.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisSolution.cs	(revision 8798)
@@ -0,0 +1,39 @@
+﻿#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.Collections.Generic;
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface ITimeSeriesPrognosisSolution : IRegressionSolution {
+    new ITimeSeriesPrognosisModel Model { get; }
+    new ITimeSeriesPrognosisProblemData ProblemData { get; set; }
+
+    IEnumerable<IEnumerable<double>> GetPrognosedValues(IEnumerable<int> rows, IEnumerable<int> horizon);
+
+    double TrainingTheilsUStatisticAR1 { get; }
+    double TestTheilsUStatisticAR1 { get; }
+    double TrainingTheilsUStatisticMean { get; }
+    double TestTheilsUStatisticMean { get; }
+    double TrainingDirectionalSymmetry { get; }
+    double TestDirectionalSymmetry { get; }
+    double TrainingWeightedDirectionalSymmetry { get; }
+    double TestWeightedDirectionalSymmetry { get; }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/AutoCorrelationCalculator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/AutoCorrelationCalculator.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/AutoCorrelationCalculator.cs	(revision 8798)
@@ -0,0 +1,38 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Linq;
+
+namespace HeuristicLab.Problems.DataAnalysis.OnlineCalculators {
+  public class AutoCorrelationCalculator {
+    public static double[] Calculate(double[] values, out OnlineCalculatorError error) {
+      error = OnlineCalculatorError.None;
+      if (values.Any(x => double.IsNaN(x) || double.IsInfinity(x))) {
+        error = OnlineCalculatorError.InvalidValueAdded;
+        return new double[0];
+      }
+
+      double[] correlations = new double[values.Length];
+      alglib.corr.corrr1dcircular(values, values.Length, values, values.Length, ref correlations);
+      return correlations;
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineDirectionalSymmetryCalculator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineDirectionalSymmetryCalculator.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineDirectionalSymmetryCalculator.cs	(revision 8798)
@@ -0,0 +1,119 @@
+﻿#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 HeuristicLab.Common;
+
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public class OnlineDirectionalSymmetryCalculator : IOnlineTimeSeriesCalculator {
+    private int n;
+    private int nCorrect;
+
+    public double DirectionalSymmetry {
+      get {
+        if (n < 1) return 0.0;
+        return (double)nCorrect / n;
+      }
+    }
+
+    public OnlineDirectionalSymmetryCalculator() {
+      Reset();
+    }
+
+    public double Value {
+      get { return DirectionalSymmetry; }
+    }
+
+    private OnlineCalculatorError errorState;
+    public OnlineCalculatorError ErrorState {
+      get { return errorState; }
+    }
+
+    public void Add(double startValue, IEnumerable<double> actualContinuation, IEnumerable<double> predictedContinuation) {
+      if (double.IsNaN(startValue) || (errorState & OnlineCalculatorError.InvalidValueAdded) > 0) {
+        errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
+      } else {
+        var actualEnumerator = actualContinuation.GetEnumerator();
+        var predictedEnumerator = predictedContinuation.GetEnumerator();
+        double prevActual = startValue;
+        double prevPredicted = startValue;
+        while (actualEnumerator.MoveNext() & predictedEnumerator.MoveNext() & errorState != OnlineCalculatorError.InvalidValueAdded) {
+          double actual = actualEnumerator.Current;
+          double predicted = predictedEnumerator.Current;
+          if (double.IsNaN(actual) || double.IsNaN(predicted)) {
+            errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
+          } else {
+            // count a prediction correct if the trend (positive/negative/no change) is predicted correctly
+            if ((actual - prevActual) * (predicted - prevPredicted) > 0.0 ||
+                (actual - prevActual).IsAlmost(predicted - prevPredicted)
+              ) {
+              nCorrect++;
+            }
+            n++;
+          }
+        }
+        // check if both enumerators are at the end to make sure both enumerations have the same length
+        if (actualEnumerator.MoveNext() || predictedEnumerator.MoveNext()) {
+          errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
+        } else {
+          errorState = errorState & (~OnlineCalculatorError.InsufficientElementsAdded); // n >= 1
+        }
+      }
+    }
+
+    public void Reset() {
+      n = 0;
+      nCorrect = 0;
+      errorState = OnlineCalculatorError.InsufficientElementsAdded;
+    }
+
+    public static double Calculate(double startValue, IEnumerable<double> actualContinuation, IEnumerable<double> predictedContinuation, out OnlineCalculatorError errorState) {
+      OnlineDirectionalSymmetryCalculator dsCalculator = new OnlineDirectionalSymmetryCalculator();
+      dsCalculator.Add(startValue, actualContinuation, predictedContinuation);
+      errorState = dsCalculator.ErrorState;
+      return dsCalculator.DirectionalSymmetry;
+    }
+    
+    public static double Calculate(IEnumerable<double> startValues, IEnumerable<IEnumerable<double>> actualContinuations, IEnumerable<IEnumerable<double>> predictedContinuations, out OnlineCalculatorError errorState) {
+      IEnumerator<double> startValueEnumerator = startValues.GetEnumerator();
+      IEnumerator<IEnumerable<double>> actualContinuationsEnumerator = actualContinuations.GetEnumerator();
+      IEnumerator<IEnumerable<double>> predictedContinuationsEnumerator = predictedContinuations.GetEnumerator();
+      OnlineDirectionalSymmetryCalculator dsCalculator = new OnlineDirectionalSymmetryCalculator();
+
+      // always move forward all enumerators (do not use short-circuit evaluation!)
+      while (startValueEnumerator.MoveNext() & actualContinuationsEnumerator.MoveNext() & predictedContinuationsEnumerator.MoveNext()) {
+        dsCalculator.Add(startValueEnumerator.Current, actualContinuationsEnumerator.Current, predictedContinuationsEnumerator.Current);
+        if (dsCalculator.ErrorState != OnlineCalculatorError.None) break;
+      }
+
+      // check if all enumerators are at the end to make sure both enumerations have the same length
+      if (dsCalculator.ErrorState == OnlineCalculatorError.None &&
+          (startValueEnumerator.MoveNext() || actualContinuationsEnumerator.MoveNext() || predictedContinuationsEnumerator.MoveNext())) {
+        throw new ArgumentException("Number of elements in startValues, actualContinuations and estimatedValues predictedContinuations doesn't match.");
+      } else {
+        errorState = dsCalculator.ErrorState;
+        return dsCalculator.DirectionalSymmetry;
+      }
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineTheilsUStatisticCalculator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineTheilsUStatisticCalculator.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineTheilsUStatisticCalculator.cs	(revision 8798)
@@ -0,0 +1,128 @@
+﻿#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;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public class OnlineTheilsUStatisticCalculator : IOnlineTimeSeriesCalculator {
+    private OnlineMeanAndVarianceCalculator squaredErrorMeanCalculator;
+    private OnlineMeanAndVarianceCalculator unbiasedEstimatorMeanCalculator;
+
+    public double TheilsUStatistic {
+      get {
+        return Math.Sqrt(squaredErrorMeanCalculator.Mean) / Math.Sqrt(unbiasedEstimatorMeanCalculator.Mean);
+      }
+    }
+
+    private OnlineCalculatorError errorState;
+    public OnlineCalculatorError ErrorState {
+      get { return errorState | squaredErrorMeanCalculator.MeanErrorState | unbiasedEstimatorMeanCalculator.MeanErrorState; }
+    }
+
+    public OnlineTheilsUStatisticCalculator() {
+      squaredErrorMeanCalculator = new OnlineMeanAndVarianceCalculator();
+      unbiasedEstimatorMeanCalculator = new OnlineMeanAndVarianceCalculator();
+      Reset();
+    }
+
+    #region IOnlineEvaluator Members
+    public double Value {
+      get { return TheilsUStatistic; }
+    }
+
+    public void Add(double startValue, IEnumerable<double> actualContinuation, IEnumerable<double> predictedContinuation) {
+      throw new NotSupportedException();
+    }
+
+    public void Add(double startValue, IEnumerable<double> actualContinuation, IEnumerable<double> referenceContinuation, IEnumerable<double> predictedContinuation) {
+      if (double.IsNaN(startValue) || (errorState & OnlineCalculatorError.InvalidValueAdded) > 0) {
+        errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
+      } else {
+        var actualEnumerator = actualContinuation.GetEnumerator();
+        var predictedEnumerator = predictedContinuation.GetEnumerator();
+        var referenceEnumerator = referenceContinuation.GetEnumerator();
+        while (actualEnumerator.MoveNext() & predictedEnumerator.MoveNext() & referenceEnumerator.MoveNext()
+          & ErrorState != OnlineCalculatorError.InvalidValueAdded) {
+          double actual = actualEnumerator.Current;
+          double predicted = predictedEnumerator.Current;
+          double reference = referenceEnumerator.Current;
+          if (double.IsNaN(actual) || double.IsNaN(predicted) || double.IsNaN(reference)) {
+            errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
+          } else {
+            // error of predicted change
+            double errorPredictedChange = (predicted - startValue) - (actual - startValue);
+            squaredErrorMeanCalculator.Add(errorPredictedChange * errorPredictedChange);
+
+            double errorReference = (reference - startValue) - (actual - startValue);
+            unbiasedEstimatorMeanCalculator.Add(errorReference * errorReference);
+          }
+        }
+        // check if both enumerators are at the end to make sure both enumerations have the same length
+        if (actualEnumerator.MoveNext() || predictedEnumerator.MoveNext() || referenceEnumerator.MoveNext()) {
+          errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
+        } else {
+          errorState = errorState & (~OnlineCalculatorError.InsufficientElementsAdded); // n >= 1
+        }
+      }
+    }
+
+
+    public void Reset() {
+      squaredErrorMeanCalculator.Reset();
+      unbiasedEstimatorMeanCalculator.Reset();
+      errorState = OnlineCalculatorError.InsufficientElementsAdded;
+    }
+
+    #endregion
+
+    public static double Calculate(double startValue, IEnumerable<double> actualContinuation, IEnumerable<double> referenceContinuation, IEnumerable<double> predictedContinuation, out OnlineCalculatorError errorState) {
+      OnlineTheilsUStatisticCalculator calculator = new OnlineTheilsUStatisticCalculator();
+      calculator.Add(startValue, actualContinuation, referenceContinuation, predictedContinuation);
+      errorState = calculator.ErrorState;
+      return calculator.TheilsUStatistic;
+    }
+
+    public static double Calculate(IEnumerable<double> startValues, IEnumerable<IEnumerable<double>> actualContinuations, IEnumerable<IEnumerable<double>> referenceContinuations, IEnumerable<IEnumerable<double>> predictedContinuations, out OnlineCalculatorError errorState) {
+      IEnumerator<double> startValueEnumerator = startValues.GetEnumerator();
+      IEnumerator<IEnumerable<double>> actualContinuationsEnumerator = actualContinuations.GetEnumerator();
+      IEnumerator<IEnumerable<double>> referenceContinuationsEnumerator = referenceContinuations.GetEnumerator();
+      IEnumerator<IEnumerable<double>> predictedContinuationsEnumerator = predictedContinuations.GetEnumerator();
+
+      OnlineTheilsUStatisticCalculator calculator = new OnlineTheilsUStatisticCalculator();
+
+      // always move forward all enumerators (do not use short-circuit evaluation!)
+      while (startValueEnumerator.MoveNext() & actualContinuationsEnumerator.MoveNext() & referenceContinuationsEnumerator.MoveNext() & predictedContinuationsEnumerator.MoveNext()) {
+        calculator.Add(startValueEnumerator.Current, actualContinuationsEnumerator.Current, referenceContinuationsEnumerator.Current, predictedContinuationsEnumerator.Current);
+        if (calculator.ErrorState != OnlineCalculatorError.None) break;
+      }
+
+      // check if all enumerators are at the end to make sure both enumerations have the same length
+      if (calculator.ErrorState == OnlineCalculatorError.None &&
+          (startValueEnumerator.MoveNext() || actualContinuationsEnumerator.MoveNext() || referenceContinuationsEnumerator.MoveNext() || predictedContinuationsEnumerator.MoveNext())) {
+        throw new ArgumentException("Number of elements in startValues, actualContinuations, referenceContinuation and estimatedValues predictedContinuations doesn't match.");
+      } else {
+        errorState = calculator.ErrorState;
+        return calculator.TheilsUStatistic;
+      }
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineWeightedDirectionalSymmetryCalculator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineWeightedDirectionalSymmetryCalculator.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineWeightedDirectionalSymmetryCalculator.cs	(revision 8798)
@@ -0,0 +1,121 @@
+﻿#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 HeuristicLab.Common;
+
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public class OnlineWeightedDirectionalSymmetryCalculator : IOnlineTimeSeriesCalculator {
+    private int n;
+    private double correctSum;
+    private double incorrectSum;
+
+    public double WeightedDirectionalSymmetry {
+      get {
+        if (n <= 1) return 0.0;
+        return incorrectSum / correctSum;
+      }
+    }
+
+    public OnlineWeightedDirectionalSymmetryCalculator() {
+      Reset();
+    }
+
+    public double Value {
+      get { return WeightedDirectionalSymmetry; }
+    }
+
+    private OnlineCalculatorError errorState;
+    public OnlineCalculatorError ErrorState {
+      get { return errorState; }
+    }
+
+    public void Add(double startValue, IEnumerable<double> actualContinuation, IEnumerable<double> predictedContinuation) {
+      if (double.IsNaN(startValue) || (errorState & OnlineCalculatorError.InvalidValueAdded) > 0) {
+        errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
+      } else {
+        var actualEnumerator = actualContinuation.GetEnumerator();
+        var predictedEnumerator = predictedContinuation.GetEnumerator();
+        while (actualEnumerator.MoveNext() & predictedEnumerator.MoveNext() & errorState != OnlineCalculatorError.InvalidValueAdded) {
+          double actual = actualEnumerator.Current;
+          double predicted = predictedEnumerator.Current;
+          if (double.IsNaN(actual) || double.IsNaN(predicted)) {
+            errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
+          } else {
+            double err = Math.Abs(actual - predicted);
+            // count as correct only if the trend (positive/negative/no change) is predicted correctly
+            if ((actual - startValue) * (predicted - startValue) > 0.0 ||
+              (actual - startValue).IsAlmost(predicted - startValue)) {
+              correctSum += err;
+            } else {
+              incorrectSum += err;
+            }
+            n++;
+          }
+        }
+        // check if both enumerators are at the end to make sure both enumerations have the same length
+        if (actualEnumerator.MoveNext() || predictedEnumerator.MoveNext()) {
+          errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
+        } else {
+          errorState = errorState & (~OnlineCalculatorError.InsufficientElementsAdded); // n >= 1
+        }
+      }
+    }
+
+    public void Reset() {
+      n = 0;
+      correctSum = 0;
+      incorrectSum = 0;
+      errorState = OnlineCalculatorError.InsufficientElementsAdded;
+    }
+
+    public static double Calculate(double startValue, IEnumerable<double> actualContinuation, IEnumerable<double> predictedContinuation, out OnlineCalculatorError errorState) {
+      OnlineWeightedDirectionalSymmetryCalculator calculator = new OnlineWeightedDirectionalSymmetryCalculator();
+      calculator.Add(startValue, actualContinuation, predictedContinuation);
+      errorState = calculator.ErrorState;
+      return calculator.WeightedDirectionalSymmetry;
+    }
+
+    public static double Calculate(IEnumerable<double> startValues, IEnumerable<IEnumerable<double>> actualContinuations, IEnumerable<IEnumerable<double>> predictedContinuations, out OnlineCalculatorError errorState) {
+      IEnumerator<double> startValueEnumerator = startValues.GetEnumerator();
+      IEnumerator<IEnumerable<double>> actualContinuationsEnumerator = actualContinuations.GetEnumerator();
+      IEnumerator<IEnumerable<double>> predictedContinuationsEnumerator = predictedContinuations.GetEnumerator();
+      OnlineWeightedDirectionalSymmetryCalculator calculator = new OnlineWeightedDirectionalSymmetryCalculator();
+
+      // always move forward all enumerators (do not use short-circuit evaluation!)
+      while (startValueEnumerator.MoveNext() & actualContinuationsEnumerator.MoveNext() & predictedContinuationsEnumerator.MoveNext()) {
+        calculator.Add(startValueEnumerator.Current, actualContinuationsEnumerator.Current, predictedContinuationsEnumerator.Current);
+        if (calculator.ErrorState != OnlineCalculatorError.None) break;
+      }
+
+      // check if all enumerators are at the end to make sure both enumerations have the same length
+      if (calculator.ErrorState == OnlineCalculatorError.None &&
+          (startValueEnumerator.MoveNext() || actualContinuationsEnumerator.MoveNext() || predictedContinuationsEnumerator.MoveNext())) {
+        throw new ArgumentException("Number of elements in startValues, actualContinuations and estimatedValues predictedContinuations doesn't match.");
+      } else {
+        errorState = calculator.ErrorState;
+        return calculator.WeightedDirectionalSymmetry;
+      }
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.Instances.DataAnalysis/3.3/HeuristicLab.Problems.Instances.DataAnalysis-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Problems.Instances.DataAnalysis/3.3/HeuristicLab.Problems.Instances.DataAnalysis-3.3.csproj	(revision 8797)
+++ /trunk/sources/HeuristicLab.Problems.Instances.DataAnalysis/3.3/HeuristicLab.Problems.Instances.DataAnalysis-3.3.csproj	(revision 8798)
@@ -197,4 +197,6 @@
     <Compile Include="Regression\Vladislavleva\VladislavlevaInstanceProvider.cs" />
     <Compile Include="TableFileParser.cs" />
+    <Compile Include="TimeSeries\CSV\TimeSeriesPrognosisCSVInstanceProvider.cs" />
+    <Compile Include="TimeSeries\TimeSeriesPrognosisInstanceProvider.cs" />
   </ItemGroup>
   <ItemGroup>
Index: /trunk/sources/HeuristicLab.Problems.Instances.DataAnalysis/3.3/TimeSeries/CSV/TimeSeriesPrognosisCSVInstanceProvider.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.Instances.DataAnalysis/3.3/TimeSeries/CSV/TimeSeriesPrognosisCSVInstanceProvider.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.Instances.DataAnalysis/3.3/TimeSeries/CSV/TimeSeriesPrognosisCSVInstanceProvider.cs	(revision 8798)
@@ -0,0 +1,51 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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 HeuristicLab.Problems.DataAnalysis;
+namespace HeuristicLab.Problems.Instances.DataAnalysis {
+  public class TimeSeriesPrognosisCSVInstanceProvider : TimeSeriesPrognosisInstanceProvider {
+    public override string Name {
+      get { return "CSV Problem Provider"; }
+    }
+    public override string Description {
+      get {
+        return "";
+      }
+    }
+    public override Uri WebLink {
+      get { return new Uri("http://dev.heuristiclab.com/trac/hl/core/wiki/UsersFAQ#DataAnalysisImportFileFormat"); }
+    }
+    public override string ReferencePublication {
+      get { return ""; }
+    }
+
+    public override IEnumerable<IDataDescriptor> GetDataDescriptors() {
+      return new List<IDataDescriptor>();
+    }
+
+    public override ITimeSeriesPrognosisProblemData LoadData(IDataDescriptor descriptor) {
+      throw new NotImplementedException();
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.Instances.DataAnalysis/3.3/TimeSeries/TimeSeriesPrognosisInstanceProvider.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.Instances.DataAnalysis/3.3/TimeSeries/TimeSeriesPrognosisInstanceProvider.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Problems.Instances.DataAnalysis/3.3/TimeSeries/TimeSeriesPrognosisInstanceProvider.cs	(revision 8798)
@@ -0,0 +1,94 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.IO;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Problems.Instances.DataAnalysis {
+  public abstract class TimeSeriesPrognosisInstanceProvider : IProblemInstanceProvider<ITimeSeriesPrognosisProblemData> {
+    public bool CanImportData { get { return true; } }
+    public bool CanExportData { get { return true; } }
+
+
+    public ITimeSeriesPrognosisProblemData ImportData(string path) {
+      TableFileParser csvFileParser = new TableFileParser();
+      csvFileParser.Parse(path);
+
+      Dataset dataset = new Dataset(csvFileParser.VariableNames, csvFileParser.Values);
+      string targetVar = csvFileParser.VariableNames.Last();
+
+      IEnumerable<string> allowedInputVars = dataset.DoubleVariables.Where(x => !x.Equals(targetVar));
+
+      ITimeSeriesPrognosisProblemData regData = new TimeSeriesPrognosisProblemData(dataset, allowedInputVars, targetVar);
+
+      int trainingPartEnd = csvFileParser.Rows * 2 / 3;
+      regData.TrainingPartition.Start = 0;
+      regData.TrainingPartition.End = trainingPartEnd;
+      regData.TestPartition.Start = trainingPartEnd;
+      regData.TestPartition.End = csvFileParser.Rows;
+
+      int pos = path.LastIndexOf('\\');
+      if (pos < 0)
+        regData.Name = path;
+      else {
+        pos++;
+        regData.Name = path.Substring(pos, path.Length - pos);
+      }
+      return regData;
+    }
+
+    public void ExportData(ITimeSeriesPrognosisProblemData instance, string path) {
+      StringBuilder strBuilder = new StringBuilder();
+
+      foreach (var variable in instance.InputVariables) {
+        strBuilder.Append(variable + ";");
+      }
+      strBuilder.Remove(strBuilder.Length - 1, 1);
+      strBuilder.AppendLine();
+
+      Dataset dataset = instance.Dataset;
+
+      for (int i = 0; i < dataset.Rows; i++) {
+        for (int j = 0; j < dataset.Columns; j++) {
+          strBuilder.Append(dataset.GetValue(i, j) + ";");
+        }
+        strBuilder.Remove(strBuilder.Length - 1, 1);
+        strBuilder.AppendLine();
+      }
+
+      using (StreamWriter writer = new StreamWriter(path)) {
+        writer.Write(strBuilder);
+      }
+    }
+
+    public abstract IEnumerable<IDataDescriptor> GetDataDescriptors();
+    public abstract ITimeSeriesPrognosisProblemData LoadData(IDataDescriptor descriptor);
+
+    public abstract string Name { get; }
+    public abstract string Description { get; }
+    public abstract Uri WebLink { get; }
+    public abstract string ReferencePublication { get; }
+  }
+}
Index: /trunk/sources/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis-3.4/SymbolicDataAnalysisExpressionTreeInterpreterTest.cs
===================================================================
--- /trunk/sources/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis-3.4/SymbolicDataAnalysisExpressionTreeInterpreterTest.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis-3.4/SymbolicDataAnalysisExpressionTreeInterpreterTest.cs	(revision 8798)
@@ -0,0 +1,367 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Globalization;
+using System.Linq;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis;
+using HeuristicLab.Problems.DataAnalysis.Symbolic_34.Tests;
+using HeuristicLab.Random;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis_34.Tests {
+
+  [TestClass()]
+  public class SymbolicTimeSeriesPrognosisInterpreterTest {
+    private const int N = 1000;
+    private const int Rows = 100;
+    private const int Columns = 50;
+    private TestContext testContextInstance;
+
+    /// <summary>
+    ///Gets or sets the test context which provides
+    ///information about and functionality for the current test run.
+    ///</summary>
+    public TestContext TestContext {
+      get {
+        return testContextInstance;
+      }
+      set {
+        testContextInstance = value;
+      }
+    }
+
+    [TestMethod]
+    public void SymbolicTimeSeriesPrognosisTreeInterpreterTypeCoherentGrammarPerformanceTest() {
+      TypeCoherentGrammarPerformanceTest(new SymbolicTimeSeriesPrognosisExpressionTreeInterpreter("y"), 12.5e6);
+    }
+    [TestMethod]
+    public void SymbolicTimeSeriesPrognosisTreeInterpreterFullGrammarPerformanceTest() {
+      FullGrammarPerformanceTest(new SymbolicTimeSeriesPrognosisExpressionTreeInterpreter("y"), 12.5e6);
+    }
+    [TestMethod]
+    public void SymbolicTimeSeriesPrognosisTreeInterpreterArithmeticGrammarPerformanceTest() {
+      ArithmeticGrammarPerformanceTest(new SymbolicTimeSeriesPrognosisExpressionTreeInterpreter("y"), 12.5e6);
+    }
+
+    private void TypeCoherentGrammarPerformanceTest(ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter interpreter, double nodesPerSecThreshold) {
+      var twister = new MersenneTwister(31415);
+      var dataset = Util.CreateRandomDataset(twister, Rows, Columns);
+      var grammar = new TypeCoherentExpressionGrammar();
+      grammar.ConfigureAsDefaultRegressionGrammar();
+      grammar.MaximumFunctionArguments = 0;
+      grammar.MaximumFunctionDefinitions = 0;
+      grammar.MinimumFunctionArguments = 0;
+      grammar.MinimumFunctionDefinitions = 0;
+      var randomTrees = Util.CreateRandomTrees(twister, dataset, grammar, N, 1, 100, 0, 0);
+      foreach (ISymbolicExpressionTree tree in randomTrees) {
+        Util.InitTree(tree, twister, new List<string>(dataset.VariableNames));
+      }
+      double nodesPerSec = Util.CalculateEvaluatedNodesPerSec(randomTrees, interpreter, dataset, 3);
+      Assert.IsTrue(nodesPerSec > nodesPerSecThreshold); // evaluated nodes per seconds must be larger than 15mNodes/sec
+    }
+
+    private void FullGrammarPerformanceTest(ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter interpreter, double nodesPerSecThreshold) {
+      var twister = new MersenneTwister(31415);
+      var dataset = Util.CreateRandomDataset(twister, Rows, Columns);
+      var grammar = new FullFunctionalExpressionGrammar();
+      grammar.MaximumFunctionArguments = 0;
+      grammar.MaximumFunctionDefinitions = 0;
+      grammar.MinimumFunctionArguments = 0;
+      grammar.MinimumFunctionDefinitions = 0;
+      var randomTrees = Util.CreateRandomTrees(twister, dataset, grammar, N, 1, 100, 0, 0);
+      foreach (ISymbolicExpressionTree tree in randomTrees) {
+        Util.InitTree(tree, twister, new List<string>(dataset.VariableNames));
+      }
+      double nodesPerSec = Util.CalculateEvaluatedNodesPerSec(randomTrees, interpreter, dataset, 3);
+      Assert.IsTrue(nodesPerSec > nodesPerSecThreshold); // evaluated nodes per seconds must be larger than 15mNodes/sec
+    }
+
+    private void ArithmeticGrammarPerformanceTest(ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter interpreter, double nodesPerSecThreshold) {
+      var twister = new MersenneTwister(31415);
+      var dataset = Util.CreateRandomDataset(twister, Rows, Columns);
+      var grammar = new ArithmeticExpressionGrammar();
+      grammar.MaximumFunctionArguments = 0;
+      grammar.MaximumFunctionDefinitions = 0;
+      grammar.MinimumFunctionArguments = 0;
+      grammar.MinimumFunctionDefinitions = 0;
+      var randomTrees = Util.CreateRandomTrees(twister, dataset, grammar, N, 1, 100, 0, 0);
+      foreach (SymbolicExpressionTree tree in randomTrees) {
+        Util.InitTree(tree, twister, new List<string>(dataset.VariableNames));
+      }
+
+      double nodesPerSec = Util.CalculateEvaluatedNodesPerSec(randomTrees, interpreter, dataset, 3);
+      Assert.IsTrue(nodesPerSec > nodesPerSecThreshold); // evaluated nodes per seconds must be larger than 15mNodes/sec
+    }
+
+
+    /// <summary>
+    ///A test for Evaluate
+    ///</summary>
+    [TestMethod]
+    public void SymbolicDataAnalysisExpressionTreeInterpreterEvaluateTest() {
+      Dataset ds = new Dataset(new string[] { "Y", "A", "B" }, new double[,] {
+        { 1.0, 1.0, 1.0 },
+        { 2.0, 2.0, 2.0 },
+        { 3.0, 1.0, 2.0 },
+        { 4.0, 1.0, 1.0 },
+        { 5.0, 2.0, 2.0 },
+        { 6.0, 1.0, 2.0 },
+        { 7.0, 1.0, 1.0 },
+        { 8.0, 2.0, 2.0 },
+        { 9.0, 1.0, 2.0 },
+        { 10.0, 1.0, 1.0 },
+        { 11.0, 2.0, 2.0 },
+        { 12.0, 1.0, 2.0 }
+      });
+
+      var interpreter = new SymbolicDataAnalysisExpressionTreeInterpreter();
+      EvaluateTerminals(interpreter, ds);
+      EvaluateOperations(interpreter, ds);
+      EvaluateAdf(interpreter, ds);
+    }
+
+    //[TestMethod]
+    //public void SymbolicDataAnalysisExpressionILEmittingTreeInterpreterEvaluateTest() {
+    //  Dataset ds = new Dataset(new string[] { "Y", "A", "B" }, new double[,] {
+    //    { 1.0, 1.0, 1.0 },
+    //    { 2.0, 2.0, 2.0 },
+    //    { 3.0, 1.0, 2.0 },
+    //    { 4.0, 1.0, 1.0 },
+    //    { 5.0, 2.0, 2.0 },
+    //    { 6.0, 1.0, 2.0 },
+    //    { 7.0, 1.0, 1.0 },
+    //    { 8.0, 2.0, 2.0 },
+    //    { 9.0, 1.0, 2.0 },
+    //    { 10.0, 1.0, 1.0 },
+    //    { 11.0, 2.0, 2.0 },
+    //    { 12.0, 1.0, 2.0 }
+    //  });
+
+    //  var interpreter = new SymbolicDataAnalysisExpressionTreeILEmittingInterpreter();
+    //  EvaluateTerminals(interpreter, ds);
+    //  EvaluateOperations(interpreter, ds);
+    //}
+
+    private void EvaluateTerminals(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, Dataset ds) {
+      // constants
+      Evaluate(interpreter, ds, "(+ 1.5 3.5)", 0, 5.0);
+
+      // variables
+      Evaluate(interpreter, ds, "(variable 2.0 a)", 0, 2.0);
+      Evaluate(interpreter, ds, "(variable 2.0 a)", 1, 4.0);
+    }
+
+    private void EvaluateAdf(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, Dataset ds) {
+
+      // ADF      
+      Evaluate(interpreter, ds, @"(PROG 
+                                    (MAIN 
+                                      (CALL ADF0)) 
+                                    (defun ADF0 1.0))", 1, 1.0);
+      Evaluate(interpreter, ds, @"(PROG 
+                                    (MAIN 
+                                      (* (CALL ADF0) (CALL ADF0)))
+                                    (defun ADF0 2.0))", 1, 4.0);
+      Evaluate(interpreter, ds, @"(PROG 
+                                    (MAIN 
+                                      (CALL ADF0 2.0 3.0))
+                                    (defun ADF0 
+                                      (+ (ARG 0) (ARG 1))))", 1, 5.0);
+      Evaluate(interpreter, ds, @"(PROG 
+                                    (MAIN (CALL ADF1 2.0 3.0))
+                                    (defun ADF0 
+                                      (- (ARG 1) (ARG 0)))
+                                    (defun ADF1
+                                      (+ (CALL ADF0 (ARG 1) (ARG 0))
+                                         (CALL ADF0 (ARG 0) (ARG 1)))))", 1, 0.0);
+      Evaluate(interpreter, ds, @"(PROG 
+                                    (MAIN (CALL ADF1 (variable 2.0 a) 3.0))
+                                    (defun ADF0 
+                                      (- (ARG 1) (ARG 0)))
+                                    (defun ADF1                                                                              
+                                      (CALL ADF0 (ARG 1) (ARG 0))))", 1, 1.0);
+      Evaluate(interpreter, ds,
+               @"(PROG 
+                                    (MAIN (CALL ADF1 (variable 2.0 a) 3.0))
+                                    (defun ADF0 
+                                      (- (ARG 1) (ARG 0)))
+                                    (defun ADF1                                                                              
+                                      (+ (CALL ADF0 (ARG 1) (ARG 0))
+                                         (CALL ADF0 (ARG 0) (ARG 1)))))", 1, 0.0);
+    }
+
+    private void EvaluateOperations(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, Dataset ds) {
+      // addition
+      Evaluate(interpreter, ds, "(+ (variable 2.0 a ))", 1, 4.0);
+      Evaluate(interpreter, ds, "(+ (variable 2.0 a ) (variable 3.0 b ))", 0, 5.0);
+      Evaluate(interpreter, ds, "(+ (variable 2.0 a ) (variable 3.0 b ))", 1, 10.0);
+      Evaluate(interpreter, ds, "(+ (variable 2.0 a) (variable 3.0 b ))", 2, 8.0);
+      Evaluate(interpreter, ds, "(+ 8.0 2.0 2.0)", 0, 12.0);
+
+      // subtraction
+      Evaluate(interpreter, ds, "(- (variable 2.0 a ))", 1, -4.0);
+      Evaluate(interpreter, ds, "(- (variable 2.0 a ) (variable 3.0 b))", 0, -1.0);
+      Evaluate(interpreter, ds, "(- (variable 2.0 a ) (variable 3.0 b ))", 1, -2.0);
+      Evaluate(interpreter, ds, "(- (variable 2.0 a ) (variable 3.0 b ))", 2, -4.0);
+      Evaluate(interpreter, ds, "(- 8.0 2.0 2.0)", 0, 4.0);
+
+      // multiplication
+      Evaluate(interpreter, ds, "(* (variable 2.0 a ))", 0, 2.0);
+      Evaluate(interpreter, ds, "(* (variable 2.0 a ) (variable 3.0 b ))", 0, 6.0);
+      Evaluate(interpreter, ds, "(* (variable 2.0 a ) (variable 3.0 b ))", 1, 24.0);
+      Evaluate(interpreter, ds, "(* (variable 2.0 a ) (variable 3.0 b ))", 2, 12.0);
+      Evaluate(interpreter, ds, "(* 8.0 2.0 2.0)", 0, 32.0);
+
+      // division
+      Evaluate(interpreter, ds, "(/ (variable 2.0 a ))", 1, 1.0 / 4.0);
+      Evaluate(interpreter, ds, "(/ (variable 2.0 a ) 2.0)", 0, 1.0);
+      Evaluate(interpreter, ds, "(/ (variable 2.0 a ) 2.0)", 1, 2.0);
+      Evaluate(interpreter, ds, "(/ (variable 3.0 b ) 2.0)", 2, 3.0);
+      Evaluate(interpreter, ds, "(/ 8.0 2.0 2.0)", 0, 2.0);
+
+      // gt
+      Evaluate(interpreter, ds, "(> (variable 2.0 a) 2.0)", 0, -1.0);
+      Evaluate(interpreter, ds, "(> 2.0 (variable 2.0 a))", 0, -1.0);
+      Evaluate(interpreter, ds, "(> (variable 2.0 a) 1.9)", 0, 1.0);
+      Evaluate(interpreter, ds, "(> 1.9 (variable 2.0 a))", 0, -1.0);
+      Evaluate(interpreter, ds, "(> (log -1.0) (log -1.0))", 0, -1.0); // (> nan nan) should be false
+
+      // lt
+      Evaluate(interpreter, ds, "(< (variable 2.0 a) 2.0)", 0, -1.0);
+      Evaluate(interpreter, ds, "(< 2.0 (variable 2.0 a))", 0, -1.0);
+      Evaluate(interpreter, ds, "(< (variable 2.0 a) 1.9)", 0, -1.0);
+      Evaluate(interpreter, ds, "(< 1.9 (variable 2.0 a))", 0, 1.0);
+      Evaluate(interpreter, ds, "(< (log -1.0) (log -1.0))", 0, -1.0); // (< nan nan) should be false
+
+      // If
+      Evaluate(interpreter, ds, "(if -10.0 2.0 3.0)", 0, 3.0);
+      Evaluate(interpreter, ds, "(if -1.0 2.0 3.0)", 0, 3.0);
+      Evaluate(interpreter, ds, "(if 0.0 2.0 3.0)", 0, 3.0);
+      Evaluate(interpreter, ds, "(if 1.0 2.0 3.0)", 0, 2.0);
+      Evaluate(interpreter, ds, "(if 10.0 2.0 3.0)", 0, 2.0);
+      Evaluate(interpreter, ds, "(if (log -1.0) 2.0 3.0)", 0, 3.0); // if(nan) should return the else branch
+
+      // NOT
+      Evaluate(interpreter, ds, "(not -1.0)", 0, 1.0);
+      Evaluate(interpreter, ds, "(not -2.0)", 0, 1.0);
+      Evaluate(interpreter, ds, "(not 1.0)", 0, -1.0);
+      Evaluate(interpreter, ds, "(not 2.0)", 0, -1.0);
+      Evaluate(interpreter, ds, "(not 0.0)", 0, 1.0);
+      Evaluate(interpreter, ds, "(not (log -1.0))", 0, 1.0);
+
+      // AND
+      Evaluate(interpreter, ds, "(and -1.0 -2.0)", 0, -1.0);
+      Evaluate(interpreter, ds, "(and -1.0 2.0)", 0, -1.0);
+      Evaluate(interpreter, ds, "(and 1.0 -2.0)", 0, -1.0);
+      Evaluate(interpreter, ds, "(and 1.0 0.0)", 0, -1.0);
+      Evaluate(interpreter, ds, "(and 0.0 0.0)", 0, -1.0);
+      Evaluate(interpreter, ds, "(and 1.0 2.0)", 0, 1.0);
+      Evaluate(interpreter, ds, "(and 1.0 2.0 3.0)", 0, 1.0);
+      Evaluate(interpreter, ds, "(and 1.0 -2.0 3.0)", 0, -1.0);
+      Evaluate(interpreter, ds, "(and (log -1.0))", 0, -1.0); // (and NaN)
+      Evaluate(interpreter, ds, "(and (log -1.0)  1.0)", 0, -1.0); // (and NaN 1.0)
+
+
+      // OR
+      Evaluate(interpreter, ds, "(or -1.0 -2.0)", 0, -1.0);
+      Evaluate(interpreter, ds, "(or -1.0 2.0)", 0, 1.0);
+      Evaluate(interpreter, ds, "(or 1.0 -2.0)", 0, 1.0);
+      Evaluate(interpreter, ds, "(or 1.0 2.0)", 0, 1.0);
+      Evaluate(interpreter, ds, "(or 0.0 0.0)", 0, -1.0);
+      Evaluate(interpreter, ds, "(or -1.0 -2.0 -3.0)", 0, -1.0);
+      Evaluate(interpreter, ds, "(or -1.0 -2.0 3.0)", 0, 1.0);
+      Evaluate(interpreter, ds, "(or (log -1.0))", 0, -1.0); // (or NaN)
+      Evaluate(interpreter, ds, "(or (log -1.0)  1.0)", 0, -1.0); // (or NaN 1.0)
+
+      // sin, cos, tan
+      Evaluate(interpreter, ds, "(sin " + Math.PI.ToString(NumberFormatInfo.InvariantInfo) + ")", 0, 0.0);
+      Evaluate(interpreter, ds, "(sin 0.0)", 0, 0.0);
+      Evaluate(interpreter, ds, "(cos " + Math.PI.ToString(NumberFormatInfo.InvariantInfo) + ")", 0, -1.0);
+      Evaluate(interpreter, ds, "(cos 0.0)", 0, 1.0);
+      Evaluate(interpreter, ds, "(tan " + Math.PI.ToString(NumberFormatInfo.InvariantInfo) + ")", 0, Math.Tan(Math.PI));
+      Evaluate(interpreter, ds, "(tan 0.0)", 0, Math.Tan(Math.PI));
+
+      // exp, log
+      Evaluate(interpreter, ds, "(log (exp 7.0))", 0, Math.Log(Math.Exp(7)));
+      Evaluate(interpreter, ds, "(exp (log 7.0))", 0, Math.Exp(Math.Log(7)));
+      Evaluate(interpreter, ds, "(log -3.0)", 0, Math.Log(-3));
+
+      // power
+      Evaluate(interpreter, ds, "(pow 2.0 3.0)", 0, 8.0);
+      Evaluate(interpreter, ds, "(pow 4.0 0.5)", 0, 1.0); // interpreter should round to the nearest integer value value (.5 is rounded to the even number)
+      Evaluate(interpreter, ds, "(pow 4.0 2.5)", 0, 16.0); // interpreter should round to the nearest integer value value (.5 is rounded to the even number)
+      Evaluate(interpreter, ds, "(pow -2.0 3.0)", 0, -8.0);
+      Evaluate(interpreter, ds, "(pow 2.0 -3.0)", 0, 1.0 / 8.0);
+      Evaluate(interpreter, ds, "(pow -2.0 -3.0)", 0, -1.0 / 8.0);
+
+      // root
+      Evaluate(interpreter, ds, "(root 9.0 2.0)", 0, 3.0);
+      Evaluate(interpreter, ds, "(root 27.0 3.0)", 0, 3.0);
+      Evaluate(interpreter, ds, "(root 2.0 -3.0)", 0, Math.Pow(2.0, -1.0 / 3.0));
+
+      // mean
+      Evaluate(interpreter, ds, "(mean -1.0 1.0 -1.0)", 0, -1.0 / 3.0);
+
+      // 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));
+
+      // 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);
+
+      // 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);
+
+      // 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);
+    }
+
+    private void Evaluate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, Dataset ds, string expr, int index, double expected) {
+      var importer = new SymbolicExpressionImporter();
+      ISymbolicExpressionTree tree = importer.Import(expr);
+
+      double actual = interpreter.GetSymbolicExpressionTreeValues(tree, ds, Enumerable.Range(index, 1)).First();
+
+      Assert.IsFalse(double.IsNaN(actual) && !double.IsNaN(expected));
+      Assert.IsFalse(!double.IsNaN(actual) && double.IsNaN(expected));
+      Assert.AreEqual(expected, actual, 1.0E-12, expr);
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis-3.4/Util.cs
===================================================================
--- /trunk/sources/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis-3.4/Util.cs	(revision 8798)
+++ /trunk/sources/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis-3.4/Util.cs	(revision 8798)
@@ -0,0 +1,102 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Diagnostics;
+using System.Linq;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Random;
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis_34.Tests {
+  internal class Util {
+    public static void InitTree(ISymbolicExpressionTree tree, MersenneTwister twister, List<string> varNames) {
+      foreach (var node in tree.IterateNodesPostfix()) {
+        if (node is VariableTreeNode) {
+          var varNode = node as VariableTreeNode;
+          varNode.Weight = twister.NextDouble() * 20.0 - 10.0;
+          varNode.VariableName = varNames[twister.Next(varNames.Count)];
+        } else if (node is ConstantTreeNode) {
+          var constantNode = node as ConstantTreeNode;
+          constantNode.Value = twister.NextDouble() * 20.0 - 10.0;
+        }
+      }
+    }
+
+
+    public static ISymbolicExpressionTree[] CreateRandomTrees(MersenneTwister twister, Dataset dataset, ISymbolicExpressionGrammar grammar, int popSize) {
+      return CreateRandomTrees(twister, dataset, grammar, popSize, 1, 200, 3, 3);
+    }
+
+    public static ISymbolicExpressionTree[] CreateRandomTrees(MersenneTwister twister, Dataset dataset, ISymbolicExpressionGrammar grammar,
+      int popSize, int minSize, int maxSize,
+      int maxFunctionDefinitions, int maxFunctionArguments) {
+      foreach (Variable variableSymbol in grammar.Symbols.OfType<Variable>()) {
+        variableSymbol.VariableNames = dataset.VariableNames.Skip(1);
+      }
+      ISymbolicExpressionTree[] randomTrees = new ISymbolicExpressionTree[popSize];
+      for (int i = 0; i < randomTrees.Length; i++) {
+        randomTrees[i] = ProbabilisticTreeCreator.Create(twister, grammar, maxSize, 10);
+      }
+      return randomTrees;
+    }
+
+    public static Dataset CreateRandomDataset(MersenneTwister twister, int rows, int columns) {
+      double[,] data = new double[rows, columns];
+      for (int i = 0; i < rows; i++) {
+        for (int j = 0; j < columns; j++) {
+          data[i, j] = twister.NextDouble() * 2.0 - 1.0;
+        }
+      }
+      IEnumerable<string> variableNames = new string[] { "y" }.Concat(Enumerable.Range(0, columns - 1).Select(x => "x" + x.ToString()));
+      Dataset ds = new Dataset(variableNames, data);
+      return ds;
+    }
+
+    public static double NodesPerSecond(long nNodes, Stopwatch watch) {
+      return nNodes / (watch.ElapsedMilliseconds / 1000.0);
+    }
+
+    private const int horizon = 10;
+    public static double CalculateEvaluatedNodesPerSec(ISymbolicExpressionTree[] trees, ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter interpreter, Dataset dataset, int repetitions) {
+      interpreter.TargetVariable = dataset.VariableNames.First();
+      // warm up
+      IEnumerable<int> rows = Enumerable.Range(0, dataset.Rows - horizon);
+      long nNodes = 0;
+      for (int i = 0; i < trees.Length; i++) {
+        nNodes += trees[i].Length * (dataset.Rows - horizon) * horizon;
+        interpreter.GetSymbolicExpressionTreeValues(trees[i], dataset, rows, horizon).Count(); // count needs to evaluate all rows
+      }
+
+      Stopwatch watch = new Stopwatch();
+      for (int rep = 0; rep < repetitions; rep++) {
+        watch.Start();
+        for (int i = 0; i < trees.Length; i++) {
+          interpreter.GetSymbolicExpressionTreeValues(trees[i], dataset, rows, horizon).Count(); // count needs to evaluate all rows
+        }
+        watch.Stop();
+      }
+      Console.WriteLine("Random tree evaluation performance of " + interpreter.GetType() + ": " +
+        watch.ElapsedMilliseconds + "ms " +
+        Util.NodesPerSecond(nNodes * repetitions, watch) + " nodes/sec");
+      return Util.NodesPerSecond(nNodes * repetitions, watch);
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Tests/HeuristicLab.Tests.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Tests/HeuristicLab.Tests.csproj	(revision 8797)
+++ /trunk/sources/HeuristicLab.Tests/HeuristicLab.Tests.csproj	(revision 8798)
@@ -212,4 +212,7 @@
     <Reference Include="HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4, Version=3.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <HintPath>..\bin\HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis-3.4, Version=3.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <HintPath>..\bin\HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis-3.4.dll</HintPath>
     </Reference>
     <Reference Include="HeuristicLab.Problems.Instances-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
@@ -386,4 +389,6 @@
     <Compile Include="HeuristicLab.Problems.DataAnalysis-3.4\OnlineCalculatorPerformanceTest.cs" />
     <Compile Include="HeuristicLab.Problems.DataAnalysis-3.4\StatisticCalculatorsTest.cs" />
+    <Compile Include="HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis-3.4\SymbolicDataAnalysisExpressionTreeInterpreterTest.cs" />
+    <Compile Include="HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis-3.4\Util.cs" />
     <Compile Include="HeuristicLab.Problems.Instances.DataAnalysis-3.3\RegressionInstanceProviderTest.cs" />
     <Compile Include="HeuristicLab.Problems.Instances.DataAnalysis-3.3\TableFileParserTest.cs" />
