using System; using System.Collections.Generic; using System.Linq; using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Data; using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; using HeuristicLab.Problems.DataAnalysis; using HeuristicLab.Problems.DataAnalysis.Symbolic; using HEAL.Attic; namespace HeuristicLab.Problems.DynamicalSystemsModelling { [StorableType("70AA254D-706E-474A-8129-E9A8A7067FE1")] public class Solution : Item { [Storable] private ISymbolicExpressionTree[] trees; public ISymbolicExpressionTree[] Trees { get { return trees; } } [Storable] private IRegressionProblemData problemData; public IRegressionProblemData ProblemData { get { return problemData; } } [Storable] private string[] targetVars; public string[] TargetVariables { get { return targetVars; } } [Storable] private string[] latentVariables; public string[] LatentVariables { get { return latentVariables; } } [Storable] private IEnumerable trainingEpisodes; public IEnumerable TrainingEpisodes { get { return trainingEpisodes; } } [Storable] private string odeSolver; [Storable] private int numericIntegrationSteps; [StorableConstructor] private Solution(StorableConstructorFlag _) : base(_) { } [StorableHook(HookType.AfterDeserialization)] private void AfterDeserialization() { } // cloning private Solution(Solution original, Cloner cloner) : base(original, cloner) { this.trees = new ISymbolicExpressionTree[original.trees.Length]; for (int i = 0; i < trees.Length; i++) this.trees[i] = cloner.Clone(original.trees[i]); this.problemData = cloner.Clone(original.problemData); this.targetVars = original.TargetVariables.ToArray(); this.latentVariables = original.LatentVariables.ToArray(); this.trainingEpisodes = original.TrainingEpisodes.Select(te => cloner.Clone(te)).ToArray(); this.odeSolver = original.odeSolver; this.numericIntegrationSteps = original.numericIntegrationSteps; } public Solution(ISymbolicExpressionTree[] trees, IRegressionProblemData problemData, string[] targetVars, string[] latentVariables, IEnumerable trainingEpisodes, string odeSolver, int numericIntegrationSteps) : base() { this.trees = trees; this.problemData = problemData; this.targetVars = targetVars; this.latentVariables = latentVariables; this.trainingEpisodes = trainingEpisodes; this.odeSolver = odeSolver; this.numericIntegrationSteps = numericIntegrationSteps; } public override IDeepCloneable Clone(Cloner cloner) { return new Solution(this, cloner); } public IEnumerable Predict(IntRange episode, int forecastHorizon) { var forecastEpisode = new IntRange(episode.Start, episode.End + forecastHorizon); var inputVariables = trees.SelectMany(t => t.IterateNodesPrefix().OfType().Select(n => n.VariableName)) .Except(targetVars) .Except(latentVariables) .Distinct(); var optimizationData = new Problem.OptimizationData(trees, targetVars, inputVariables.ToArray(), problemData, null, new[] { forecastEpisode }, numericIntegrationSteps, latentVariables, odeSolver); var fi = new double[forecastEpisode.Size * targetVars.Length]; var jac = new double[forecastEpisode.Size * targetVars.Length, optimizationData.nodeValueLookup.ParameterCount]; var latentValues = new double[forecastEpisode.Size, LatentVariables.Length]; Problem.Integrate(optimizationData, fi, jac, latentValues); for (int i = 0; i < forecastEpisode.Size; i++) { var res = new double[targetVars.Length + latentVariables.Length]; for (int j = 0; j < targetVars.Length; j++) { res[j] = fi[i * targetVars.Length + j]; } for (int j = 0; j < latentVariables.Length; j++) { res[targetVars.Length + j] = latentValues[i, j]; } yield return res; } } } }