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 @@
Code
+
@@ -312,4 +313,8 @@
HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4
False
+
+
+ {07486E68-1517-4B9D-A58D-A38E99AE71AB}
+ HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis-3.4
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 .
+ */
+#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 {
+ private const string TimeOffesetParameterName = "Maximum Time Offset";
+
+ public IFixedValueParameter TimeOffsetParameter {
+ get { return (IFixedValueParameter)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(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)));
+ }
+
+ ///
+ /// Calculates an AR(p) model. For further information see http://en.wikipedia.org/wiki/Autoregressive_model
+ ///
+ /// The problem data which should be used for training
+ /// The parameter p of the AR(p) specifying the maximum time offset [1,infinity]
+ /// The times series autoregressive solution
+ 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().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 entryPoint = new Dictionary();
- private List> postInstructionCompiledHooks = new List>();
+ public static class SymbolicExpressionTreeCompiler {
- public Instruction[] Compile(ISymbolicExpressionTree tree, Func opCodeMapper) {
+ public static Instruction[] Compile(ISymbolicExpressionTree tree, Func opCodeMapper) {
+ return Compile(tree, opCodeMapper, Enumerable.Empty>());
+ }
+ public static Instruction[] Compile(ISymbolicExpressionTree tree, Func opCodeMapper, IEnumerable> postInstructionCompiledHooks) {
+ Dictionary entryPoint = new Dictionary();
List code = new List();
- 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 Compile(ISymbolicExpressionTreeNode branch, Func opCodeMapper) {
+ private static IEnumerable Compile(ISymbolicExpressionTreeNode branch, Func opCodeMapper, IEnumerable> postInstructionCompiledHooks) {
foreach (var node in branch.IterateNodesPrefix()) {
Instruction instr = new Instruction();
@@ -77,13 +77,4 @@
}
}
-
- ///
- /// 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.
- ///
- /// The hook that should be called for each compiled instruction.
- public void AddInstructionPostProcessingHook(Func 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 Subtrees {
- get {
- return Enumerable.Empty();
- }
+ get { return Enumerable.Empty(); }
}
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 @@
+
+
+
+ Debug
+ AnyCPU
+ 9.0.30729
+ 2.0
+ {E6CB1FC5-78EC-4EB8-BF12-35303C36F962}
+ Library
+ Properties
+ HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views
+ HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views-3.4
+ v4.0
+
+
+ 512
+ true
+ HeuristicLab.snk
+
+
+ 3.5
+
+ publish\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 0
+ 1.0.0.%2a
+ false
+ false
+ true
+
+
+ true
+ full
+ false
+ ../../bin/
+ DEBUG;TRACE
+ prompt
+ 4
+ AllRules.ruleset
+
+
+ pdbonly
+ true
+ ..\..\..\..\trunk\sources\bin\
+ TRACE
+ prompt
+ 4
+ AllRules.ruleset
+
+
+ true
+ ../../bin/
+ DEBUG;TRACE
+ full
+ x64
+ prompt
+ AllRules.ruleset
+
+
+ ../../bin/
+ TRACE
+ true
+ pdbonly
+ x64
+ prompt
+ AllRules.ruleset
+
+
+ true
+ ../../bin/
+ DEBUG;TRACE
+ full
+ x86
+ prompt
+ AllRules.ruleset
+
+
+ ../../bin/
+ TRACE
+ true
+ pdbonly
+ x86
+ prompt
+ AllRules.ruleset
+
+
+
+
+ 3.5
+
+
+
+
+
+ 3.5
+
+
+ 3.5
+
+
+
+
+
+
+ UserControl
+
+
+ InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView.cs
+
+
+
+ UserControl
+
+
+ SymbolicTimeSeriesPrognosisSolutionView.cs
+
+
+
+
+
+
+
+
+ False
+ .NET Framework 3.5 SP1 Client Profile
+ false
+
+
+ False
+ .NET Framework 3.5 SP1
+ true
+
+
+ False
+ Windows Installer 3.1
+ true
+
+
+
+
+ {958B43BC-CC5C-4FA2-8628-2B3B01D890B6}
+ HeuristicLab.Collections-3.3
+
+
+ {A9AD58B9-3EF9-4CC1-97E5-8D909039FF5C}
+ HeuristicLab.Common-3.3
+
+
+ {E226881D-315F-423D-B419-A766FE0D8685}
+ HeuristicLab.Core.Views-3.3
+
+
+ {C36BD924-A541-4A00-AFA8-41701378DDC5}
+ HeuristicLab.Core-3.3
+
+
+ {BBAB9DF5-5EF3-4BA8-ADE9-B36E82114937}
+ HeuristicLab.Data-3.3
+
+
+ {06D4A186-9319-48A0-BADE-A2058D462EEA}
+ HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4
+
+
+ {AB687BBE-1BFE-476B-906D-44237135431D}
+ HeuristicLab.MainForm.WindowsForms-3.3
+
+
+ {3BD61258-31DA-4B09-89C0-4F71FEF5F05A}
+ HeuristicLab.MainForm-3.3
+
+
+ {14AB8D24-25BC-400C-A846-4627AA945192}
+ HeuristicLab.Optimization-3.3
+
+
+ {94186A6A-5176-4402-AE83-886557B53CCA}
+ HeuristicLab.PluginInfrastructure-3.3
+
+
+ {5AC82412-911B-4FA2-A013-EDC5E3F3FCC2}
+ HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4
+
+
+ {07486E68-1517-4B9D-A58D-A38E99AE71AB}
+ HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis-3.4
+
+
+ {7A2531CE-3F7C-4F13-BCCA-ED6DC27A7086}
+ HeuristicLab.Problems.DataAnalysis.Symbolic.Views-3.4
+
+
+ {3D28463F-EC96-4D82-AFEE-38BE91A0CA00}
+ HeuristicLab.Problems.DataAnalysis.Symbolic-3.4
+
+
+ {3E9E8944-44FF-40BB-A622-3A4A7DD0F198}
+ HeuristicLab.Problems.DataAnalysis.Views-3.4
+
+
+ {DF87C13E-A889-46FF-8153-66DCAA8C5674}
+ HeuristicLab.Problems.DataAnalysis-3.4
+
+
+
+
+
+
+ set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+ set ProjectDir=$(ProjectDir)
+ set SolutionDir=$(SolutionDir)
+ set Outdir=$(Outdir)
+
+ call PreBuildEvent.cmd
+
+
+ export ProjectDir=$(ProjectDir)
+ export SolutionDir=$(SolutionDir)
+
+ $SolutionDir/PreBuildEvent.sh
+
+
+
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 .
+ */
+#endregion
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views {
+ partial class InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing) {
+ if (disposing && (components != null)) {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ 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 .
+ */
+#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 CalculateReplacementValues(ISymbolicExpressionTree tree) {
+ Dictionary replacementValues = new Dictionary();
+ 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 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 impactValues = new Dictionary();
+ List 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 .
+ */
+#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 .
+ */
+#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 {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing) {
+ if (disposing && (components != null)) {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ 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 .
+ */
+#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 @@
+
+
+
+ Debug
+ AnyCPU
+ 9.0.30729
+ 2.0
+ {07486E68-1517-4B9D-A58D-A38E99AE71AB}
+ Library
+ Properties
+ HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis
+ HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis-3.4
+ v4.0
+
+
+ 512
+ true
+ HeuristicLab.snk
+
+
+ 3.5
+
+ publish\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 0
+ 1.0.0.%2a
+ false
+ false
+ true
+
+
+ true
+ full
+ false
+ ../../bin/
+ DEBUG;TRACE
+ prompt
+ 4
+ AllRules.ruleset
+
+
+ pdbonly
+ true
+ ..\..\..\..\trunk\sources\bin\
+ TRACE
+ prompt
+ 4
+ AllRules.ruleset
+
+
+ true
+ ../../bin/
+ DEBUG;TRACE
+ full
+ x64
+ prompt
+ AllRules.ruleset
+
+
+ ../../bin/
+ TRACE
+ true
+ pdbonly
+ x64
+ prompt
+ AllRules.ruleset
+
+
+ true
+ ../../bin/
+ DEBUG;TRACE
+ full
+ x86
+ prompt
+ AllRules.ruleset
+
+
+ ../../bin/
+ TRACE
+ true
+ pdbonly
+ x86
+ prompt
+ AllRules.ruleset
+
+
+
+
+
+
+ 3.5
+
+
+
+ 3.5
+
+
+ 3.5
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Code
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ False
+ .NET Framework 3.5 SP1 Client Profile
+ false
+
+
+ False
+ .NET Framework 3.5 SP1
+ true
+
+
+ False
+ Windows Installer 3.1
+ true
+
+
+
+
+ {887425B4-4348-49ED-A457-B7D2C26DDBF9}
+ HeuristicLab.Analysis-3.3
+
+
+ {958B43BC-CC5C-4FA2-8628-2B3B01D890B6}
+ HeuristicLab.Collections-3.3
+
+
+ {A9AD58B9-3EF9-4CC1-97E5-8D909039FF5C}
+ HeuristicLab.Common-3.3
+
+
+ {C36BD924-A541-4A00-AFA8-41701378DDC5}
+ HeuristicLab.Core-3.3
+
+
+ {BBAB9DF5-5EF3-4BA8-ADE9-B36E82114937}
+ HeuristicLab.Data-3.3
+
+
+ {06D4A186-9319-48A0-BADE-A2058D462EEA}
+ HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4
+
+
+ {23DA7FF4-D5B8-41B6-AA96-F0561D24F3EE}
+ HeuristicLab.Operators-3.3
+
+
+ {14AB8D24-25BC-400C-A846-4627AA945192}
+ HeuristicLab.Optimization-3.3
+
+
+ {56F9106A-079F-4C61-92F6-86A84C2D84B7}
+ HeuristicLab.Parameters-3.3
+
+
+ {102BC7D3-0EF9-439C-8F6D-96FF0FDB8E1B}
+ HeuristicLab.Persistence-3.3
+
+
+ {94186A6A-5176-4402-AE83-886557B53CCA}
+ HeuristicLab.PluginInfrastructure-3.3
+
+
+ {5AC82412-911B-4FA2-A013-EDC5E3F3FCC2}
+ HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4
+
+
+ {3D28463F-EC96-4D82-AFEE-38BE91A0CA00}
+ HeuristicLab.Problems.DataAnalysis.Symbolic-3.4
+
+
+ {DF87C13E-A889-46FF-8153-66DCAA8C5674}
+ HeuristicLab.Problems.DataAnalysis-3.4
+
+
+ {3540E29E-4793-49E7-8EE2-FEA7F61C3994}
+ HeuristicLab.Problems.Instances-3.3
+
+
+
+
+
+
+ set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+ set ProjectDir=$(ProjectDir)
+ set SolutionDir=$(SolutionDir)
+ set Outdir=$(Outdir)
+
+ call PreBuildEvent.cmd
+
+
+ export ProjectDir=$(ProjectDir)
+ export SolutionDir=$(SolutionDir)
+
+ $SolutionDir/PreBuildEvent.sh
+
+
+
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 .
+ */
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+ public interface ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter : ISymbolicDataAnalysisExpressionTreeInterpreter {
+ string TargetVariable { get; set; }
+ IEnumerable> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, IEnumerable rows, int horizon);
+ IEnumerable> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, IEnumerable rows, IEnumerable 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 .
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis {
+ public interface ISymbolicTimeSeriesPrognosisEvaluator : ISymbolicDataAnalysisEvaluator {
+ IValueLookupParameter 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 .
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis {
+ public interface ISymbolicTimeSeriesPrognosisInterpreterOperator : IOperator {
+ ILookupParameter 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 .
+ */
+#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 .
+ */
+#endregion
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis {
+ public interface ISymbolicTimeSeriesPrognosisSingleObjectiveEvaluator : ISymbolicTimeSeriesPrognosisEvaluator, ISymbolicDataAnalysisSingleObjectiveEvaluator {
+ }
+}
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 .
+ */
+#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 .
+ */
+#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 .
+ */
+#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 .
+ */
+#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, ISymbolicTimeSeriesPrognosisSingleObjectiveEvaluator {
+ private const string HorizonParameterName = "Horizon";
+ public IValueLookupParameter HorizonParameter {
+ get { return (IValueLookupParameter)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(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 .
+ */
+#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 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 rows, IntRange evaluationPartition, int horizon, bool applyLinearScaling) {
+ var horizions = rows.Select(r => Math.Min(horizon, evaluationPartition.End - r));
+ IEnumerable targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows.Zip(horizions, Enumerable.Range).SelectMany(r => r));
+ IEnumerable 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 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 .
+ */
+#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 {
+ 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 TrainingValidationQualityCorrelationParameter {
+ get { return (ILookupParameter)Parameters[TrainingValidationCorrelationParameterName]; }
+ }
+ public ILookupParameter TrainingValidationQualityCorrelationTableParameter {
+ get { return (ILookupParameter)Parameters[TrainingValidationCorrelationTableParameterName]; }
+ }
+ public IValueLookupParameter LowerCorrelationThresholdParameter {
+ get { return (IValueLookupParameter)Parameters[LowerCorrelationThresholdParameterName]; }
+ }
+ public IValueLookupParameter UpperCorrelationThresholdParameter {
+ get { return (IValueLookupParameter)Parameters[UpperCorrelationThresholdParameterName]; }
+ }
+ public ILookupParameter OverfittingParameter {
+ get { return (ILookupParameter)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(TrainingValidationCorrelationParameterName, "Correlation of training and validation fitnesses"));
+ Parameters.Add(new LookupParameter(TrainingValidationCorrelationTableParameterName, "Data table of training and validation fitness correlation values over the whole run."));
+ Parameters.Add(new ValueLookupParameter(LowerCorrelationThresholdParameterName, "Lower threshold for correlation value that marks the boundary from non-overfitting to overfitting.", new DoubleValue(0.65)));
+ Parameters.Add(new ValueLookupParameter(UpperCorrelationThresholdParameterName, "Upper threshold for correlation value that marks the boundary from overfitting to non-overfitting.", new DoubleValue(0.75)));
+ Parameters.Add(new LookupParameter(OverfittingParameterName, "Boolean indicator for overfitting."));
+ }
+
+ public override IDeepCloneable Clone(Cloner cloner) {
+ return new SymbolicTimeSeriesPrognosisSingleObjectiveOverfittingAnalyzer(this, cloner);
+ }
+
+ public override IOperation Apply() {
+ IEnumerable 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 .
+ */
+#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 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 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 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 .
+ */
+#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, 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 EstimationLimitsParameter {
+ get { return (IFixedValueParameter)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(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()) {
+ 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().Select(p => p.Value).OfType().Union(Operators);
+ foreach (var op in operators.OfType()) {
+ op.EstimationLimitsParameter.ActualName = EstimationLimitsParameter.Name;
+ }
+ foreach (var op in operators.OfType()) {
+ 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 .
+ */
+#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 {
+ ///
+ /// An operator that analyzes the training best symbolic time-series prognosis solution for single objective symbolic time-series prognosis problems.
+ ///
+ [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,
+ ISymbolicDataAnalysisInterpreterOperator, ISymbolicDataAnalysisBoundedOperator {
+ private const string ProblemDataParameterName = "ProblemData";
+ private const string SymbolicDataAnalysisTreeInterpreterParameterName = "SymbolicDataAnalysisTreeInterpreter";
+ private const string EstimationLimitsParameterName = "EstimationLimits";
+ #region parameter properties
+ public ILookupParameter ProblemDataParameter {
+ get { return (ILookupParameter)Parameters[ProblemDataParameterName]; }
+ }
+ public ILookupParameter SymbolicDataAnalysisTreeInterpreterParameter {
+ get { return (ILookupParameter)Parameters[SymbolicDataAnalysisTreeInterpreterParameterName]; }
+ }
+ public IValueLookupParameter EstimationLimitsParameter {
+ get { return (IValueLookupParameter)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(ProblemDataParameterName, "The problem data for the symbolic regression solution."));
+ Parameters.Add(new LookupParameter(SymbolicDataAnalysisTreeInterpreterParameterName, "The symbolic time series prognosis interpreter for the symbolic expression tree."));
+ Parameters.Add(new ValueLookupParameter(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 .
+ */
+#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 {
+ ///
+ /// An operator that analyzes the validation best symbolic time-series prognosis solution for single objective symbolic time-series prognosis problems.
+ ///
+ [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, ISymbolicDataAnalysisBoundedOperator {
+ private const string EstimationLimitsParameterName = "EstimationLimits";
+ #region parameter properties
+ public IValueLookupParameter EstimationLimitsParameter {
+ get { return (IValueLookupParameter)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(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 .
+ */
+#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 TargetVariableParameter {
+ get { return (IFixedValueParameter)Parameters[TargetVariableParameterName]; }
+ }
+
+ public string TargetVariable {
+ get { return TargetVariableParameter.Value.Value; }
+ set { TargetVariableParameter.Value.Value = value; }
+ }
+
+ [ThreadStatic]
+ private static double[] targetVariableCache;
+ [ThreadStatic]
+ private static List 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(TargetVariableParameterName));
+ TargetVariableParameter.Hidden = true;
+ }
+
+ public SymbolicTimeSeriesPrognosisExpressionTreeInterpreter(string targetVariable)
+ : this() {
+ TargetVariable = targetVariable;
+ }
+
+ // for each row several (=#horizon) future predictions
+ public IEnumerable> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, IEnumerable rows, int horizon) {
+ return GetSymbolicExpressionTreeValues(tree, dataset, rows, rows.Select(row => horizon));
+ }
+
+ public IEnumerable> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, IEnumerable rows, IEnumerable 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(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 .
+ */
+#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 {
+ ///
+ /// Represents a symbolic time-series prognosis model
+ ///
+ [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> GetPrognosedValues(Dataset dataset, IEnumerable rows, IEnumerable 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 .
+ */
+#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 {
+ ///
+ /// Represents a symbolic time-series prognosis solution (model + data) and attributes of the solution like accuracy and complexity
+ ///
+ [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)Parameters[ApplyLinearScalingParameterName]; }
}
+ public IValueLookupParameter ValidRowIndicatorParameter {
+ get { return (IValueLookupParameter)Parameters[ValidRowIndicatorParameterName]; }
+ }
#endregion
@@ -92,4 +96,5 @@
Parameters.Add(new ValueLookupParameter(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(ApplyLinearScalingParameterName, "Flag that indicates if the individual should be linearly scaled before evaluating."));
+ Parameters.Add(new ValueLookupParameter(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(ApplyLinearScalingParameterName, "Flag that indicates if the individual should be linearly scaled before evaluating."));
+ if (!Parameters.ContainsKey(ValidRowIndicatorParameterName))
+ Parameters.Add(new ValueLookupParameter(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 constants;
+ private readonly List 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() { 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() { 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() { pow, root, gt, lt, variableCondition };
var ternarySymbols = new List() { add, sub, mul, div, mean, and, or };
- var terminalSymbols = new List() { variableSymbol, constant, laggedVariable };
+ var terminalSymbols = new List() { 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 { conditionSymbols, comparisonSymbols, booleanOperationSymbols });
- var timeSeriesSymbols = new GroupSymbol(TimeSeriesSymbolsName, new List { timeLag, integral, derivative, laggedVariable });
+ var timeSeriesSymbols = new GroupSymbol(TimeSeriesSymbolsName, new List { 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 @@
+
+
+
+
-
@@ -160,9 +163,9 @@
-
+
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 .
+ */
+#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
+ //
+ 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 .
+ */
+#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 symbolToOpcode = new Dictionary() {
+ { 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 .
+ */
+#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[] columns);
+
+ #region method infos
+ private static MethodInfo listGetValue = typeof(IList).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 CheckExpressionsWithIntervalArithmeticParameter {
+ get { return (IValueParameter)Parameters[CheckExpressionsWithIntervalArithmeticParameterName]; }
+ }
+
+ public IValueParameter EvaluatedSolutionsParameter {
+ get { return (IValueParameter)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(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(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(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 GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, IEnumerable 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[]) };
+ 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[] 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 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 .
+ */
+#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 CheckExpressionsWithIntervalArithmeticParameter {
+ get { return (IValueParameter)Parameters[CheckExpressionsWithIntervalArithmeticParameterName]; }
+ }
+
+ public IValueParameter EvaluatedSolutionsParameter {
+ get { return (IValueParameter)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(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(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(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(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(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 GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, IEnumerable 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)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)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)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 .
- */
-#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).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[] 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 symbolToOpcode = new Dictionary()
- {
- {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 CheckExpressionsWithIntervalArithmeticParameter {
- get { return (IValueParameter)Parameters[CheckExpressionsWithIntervalArithmeticParameterName]; }
- }
-
- public IValueParameter EvaluatedSolutionsParameter {
- get { return (IValueParameter)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(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(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(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 GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset,
- IEnumerable 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 doubleVariableNames =
- dataset.DoubleVariables.Select((x, i) => new { x, i }).ToDictionary(e => e.x, e => e.i);
- IList[] 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[]) };
- 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 .
- */
-#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
- //
- 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 symbolToOpcode = new Dictionary() {
- { 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 CheckExpressionsWithIntervalArithmeticParameter {
- get { return (IValueParameter)Parameters[CheckExpressionsWithIntervalArithmeticParameterName]; }
- }
-
- public IValueParameter EvaluatedSolutionsParameter {
- get { return (IValueParameter)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(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(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(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 GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, IEnumerable 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)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)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)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(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 .
+ */
+#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 @@
TimeframeFeatureCorrelationView.cs
+
+
+ UserControl
+
+
+ TimeSeriesPrognosisSolutionView.cs
+
+
+ UserControl
+
+
+ TimeSeriesPrognosisResultsView.cs
+
+
+ UserControl
+
+
+ TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.cs
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 .
+ */
+#endregion
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+ partial class TimeSeriesPrognosisSolutionView {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing) {
+ if (disposing && (components != null)) {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ 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 .
+ */
+#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 .
+ */
+#endregion
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+ partial class TimeSeriesPrognosisResultsView {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing) {
+ if (disposing) {
+ if (components != null) components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ 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 .
+ */
+#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 {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing) {
+ if (disposing && (components != null)) {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ 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 .
+ */
+#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 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 .
+ */
+#endregion
+
+using System.Collections.Generic;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+ public static class DatasetExtensions {
+ public static IEnumerable TakeEvery(this IEnumerable 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 @@
+
@@ -137,4 +138,11 @@
+
+
+
+
+
+
+
Code
@@ -149,6 +157,13 @@
+
+
+
+
+
+
+
@@ -189,4 +204,6 @@
+
+
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 .
+ */
+#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> GetPrognosedValues(Dataset dataset, IEnumerable rows, IEnumerable 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 .
+ */
+#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> GetPrognosedValues(Dataset dataset, IEnumerable rows, IEnumerable 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 GetEstimatedValues(Dataset dataset, IEnumerable 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 .
+ */
+#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, 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 .
+ */
+#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 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();
+ defaultTargetVariable = "x";
+ }
+ #endregion
+
+ private const string TrainingHorizonParameterName = "Training Horizon";
+ private const string TestHorizonParameterName = "Test Horizon";
+
+ public IFixedValueParameter TrainingHorizonParameter {
+ get { return (IFixedValueParameter)Parameters[TrainingHorizonParameterName]; }
+ }
+ public IFixedValueParameter TestHorizonParameter {
+ get { return (IFixedValueParameter)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 allowedInputVariables, string targetVariable)
+ : base(dataset, allowedInputVariables, targetVariable) {
+ Parameters.Add(new FixedValueParameter(TrainingHorizonParameterName, "Specifies the horizon (how far the prognosis reaches in the future) for each training sample.", new IntValue(1)));
+ Parameters.Add(new FixedValueParameter(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 .
+ */
+#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 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> trainingTargetValues = problemData.TrainingIndices.Zip(trainingHorizions, Enumerable.Range).Select(r => problemData.Dataset.GetDoubleValues(problemData.TargetVariable, r)).ToList();
+ IEnumerable> trainingEstimatedValues = model.GetPrognosedValues(problemData.Dataset, problemData.TrainingIndices, trainingHorizions).ToList();
+ IEnumerable> trainingMeanModelPredictions = meanModel.GetPrognosedValues(problemData.Dataset, problemData.TrainingIndices, trainingHorizions).ToList();
+ IEnumerable> trainingAR1ModelPredictions = AR1model.GetPrognosedValues(problemData.Dataset, problemData.TrainingIndices, trainingHorizions).ToList();
+
+ IEnumerable originalTrainingValues = trainingTargetValues.SelectMany(x => x).ToList();
+ IEnumerable 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 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> testTargetValues = problemData.TestIndices.Zip(testHorizions, Enumerable.Range).Select(r => problemData.Dataset.GetDoubleValues(problemData.TargetVariable, r)).ToList();
+ IEnumerable> testEstimatedValues = model.GetPrognosedValues(problemData.Dataset, problemData.TestIndices, testHorizions).ToList();
+ IEnumerable testStartValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TestIndices.Select(r => r - 1).Where(r => r > 0)).ToList();
+ IEnumerable> testMeanModelPredictions = meanModel.GetPrognosedValues(problemData.Dataset, problemData.TestIndices, testHorizions).ToList();
+ IEnumerable> testAR1ModelPredictions = AR1model.GetPrognosedValues(problemData.Dataset, problemData.TestIndices, testHorizions).ToList();
+
+ IEnumerable originalTestValues = testTargetValues.SelectMany(x => x).ToList();
+ IEnumerable 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 .
+ */
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+ ///
+ /// Represents a time series prognosis data analysis solution
+ ///
+ [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> GetPrognosedValues(IEnumerable rows, IEnumerable 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 .
+ */
+#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> GetPrognosedValues(IEnumerable rows, IEnumerable 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 EstimatedValues {
+ get { return GetEstimatedValues(Enumerable.Range(0, ProblemData.Dataset.Rows)); }
+ }
+ public override IEnumerable EstimatedTrainingValues {
+ get { return GetEstimatedValues(ProblemData.TrainingIndices); }
+ }
+ public override IEnumerable EstimatedTestValues {
+ get { return GetEstimatedValues(ProblemData.TestIndices); }
+ }
+ public override IEnumerable GetEstimatedValues(IEnumerable 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 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 trainingTargetValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices).ToList();
+ IEnumerable trainingEstimatedValues = EstimatedTrainingValues.ToList();
+ IEnumerable trainingMeanModelPredictions = meanModel.GetEstimatedValues(ProblemData.Dataset, ProblemData.TrainingIndices).ToList();
+ IEnumerable 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 testTargetValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TestIndices).ToList();
+ IEnumerable testEstimatedValues = EstimatedTestValues.ToList();
+ IEnumerable testMeanModelPredictions = meanModel.GetEstimatedValues(ProblemData.Dataset, ProblemData.TestIndices).ToList();
+ IEnumerable 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 .
+ */
+#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 actualContinuation, IEnumerable 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 .
+ */
+#endregion
+
+using System.Collections.Generic;
+namespace HeuristicLab.Problems.DataAnalysis {
+ public interface ITimeSeriesPrognosisModel : IRegressionModel {
+ IEnumerable> GetPrognosedValues(Dataset dataset, IEnumerable rows, IEnumerable 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 .
+ */
+#endregion
+
+namespace HeuristicLab.Problems.DataAnalysis {
+ public interface ITimeSeriesPrognosisProblem : IDataAnalysisProblem {
+ }
+}
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 .
+ */
+#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 .
+ */
+#endregion
+
+using System.Collections.Generic;
+namespace HeuristicLab.Problems.DataAnalysis {
+ public interface ITimeSeriesPrognosisSolution : IRegressionSolution {
+ new ITimeSeriesPrognosisModel Model { get; }
+ new ITimeSeriesPrognosisProblemData ProblemData { get; set; }
+
+ IEnumerable> GetPrognosedValues(IEnumerable rows, IEnumerable 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 .
+ */
+#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 .
+ */
+#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 actualContinuation, IEnumerable 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 actualContinuation, IEnumerable predictedContinuation, out OnlineCalculatorError errorState) {
+ OnlineDirectionalSymmetryCalculator dsCalculator = new OnlineDirectionalSymmetryCalculator();
+ dsCalculator.Add(startValue, actualContinuation, predictedContinuation);
+ errorState = dsCalculator.ErrorState;
+ return dsCalculator.DirectionalSymmetry;
+ }
+
+ public static double Calculate(IEnumerable startValues, IEnumerable> actualContinuations, IEnumerable> predictedContinuations, out OnlineCalculatorError errorState) {
+ IEnumerator startValueEnumerator = startValues.GetEnumerator();
+ IEnumerator> actualContinuationsEnumerator = actualContinuations.GetEnumerator();
+ IEnumerator> 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 .
+ */
+#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 actualContinuation, IEnumerable predictedContinuation) {
+ throw new NotSupportedException();
+ }
+
+ public void Add(double startValue, IEnumerable actualContinuation, IEnumerable referenceContinuation, IEnumerable 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 actualContinuation, IEnumerable referenceContinuation, IEnumerable 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 startValues, IEnumerable> actualContinuations, IEnumerable> referenceContinuations, IEnumerable> predictedContinuations, out OnlineCalculatorError errorState) {
+ IEnumerator startValueEnumerator = startValues.GetEnumerator();
+ IEnumerator> actualContinuationsEnumerator = actualContinuations.GetEnumerator();
+ IEnumerator> referenceContinuationsEnumerator = referenceContinuations.GetEnumerator();
+ IEnumerator> 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 .
+ */
+#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 actualContinuation, IEnumerable 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 actualContinuation, IEnumerable predictedContinuation, out OnlineCalculatorError errorState) {
+ OnlineWeightedDirectionalSymmetryCalculator calculator = new OnlineWeightedDirectionalSymmetryCalculator();
+ calculator.Add(startValue, actualContinuation, predictedContinuation);
+ errorState = calculator.ErrorState;
+ return calculator.WeightedDirectionalSymmetry;
+ }
+
+ public static double Calculate(IEnumerable startValues, IEnumerable> actualContinuations, IEnumerable> predictedContinuations, out OnlineCalculatorError errorState) {
+ IEnumerator startValueEnumerator = startValues.GetEnumerator();
+ IEnumerator> actualContinuationsEnumerator = actualContinuations.GetEnumerator();
+ IEnumerator> 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 @@
+
+
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 .
+ */
+#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 GetDataDescriptors() {
+ return new List();
+ }
+
+ 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 .
+ */
+#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 {
+ 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 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 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 .
+ */
+#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;
+
+ ///
+ ///Gets or sets the test context which provides
+ ///information about and functionality for the current test run.
+ ///
+ 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(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(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(dataset.VariableNames));
+ }
+
+ double nodesPerSec = Util.CalculateEvaluatedNodesPerSec(randomTrees, interpreter, dataset, 3);
+ Assert.IsTrue(nodesPerSec > nodesPerSecThreshold); // evaluated nodes per seconds must be larger than 15mNodes/sec
+ }
+
+
+ ///
+ ///A test for Evaluate
+ ///
+ [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 .
+ */
+#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 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()) {
+ 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 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 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 @@
..\bin\HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.dll
+
+
+ ..\bin\HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis-3.4.dll
@@ -386,4 +389,6 @@
+
+