Changeset 7120


Ignore:
Timestamp:
12/05/11 08:22:36 (9 years ago)
Author:
gkronber
Message:

#1081 implemented multi-variate symbolic expression tree interpreter for time series prognosis.

Location:
branches/HeuristicLab.TimeSeries
Files:
1 added
1 deleted
18 edited

Legend:

Unmodified
Added
Removed
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/LinearTimeSeriesPrognosis.cs

    r7100 r7120  
    142142      }
    143143
    144       SymbolicTimeSeriesPrognosisSolution solution = new SymbolicTimeSeriesPrognosisSolution(new SymbolicTimeSeriesPrognosisModel(tree, new SymbolicTimeSeriesPrognosisInterpreter(problemData.TargetVariables.ToArray())), (ITimeSeriesPrognosisProblemData)problemData.Clone());
     144      SymbolicTimeSeriesPrognosisSolution solution = new SymbolicTimeSeriesPrognosisSolution(new SymbolicTimeSeriesPrognosisModel(tree, new SymbolicDataAnalysisExpressionTreeInterpreter(), problemData.TargetVariables.ToArray()), (ITimeSeriesPrognosisProblemData)problemData.Clone());
    145145      solution.Model.Name = "Linear Time-Series Prognosis Model";
    146146      return solution;
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Symbols/StartSymbol.cs

    r6803 r7120  
    2626  [StorableClass]
    2727  [Item(StartSymbol.StartSymbolName, StartSymbol.StartSymbolDescription)]
    28   public sealed class StartSymbol : Symbol, IReadOnlySymbol {
     28  public sealed class StartSymbol : Symbol {
    2929    public const string StartSymbolName = "StartSymbol";
    3030    public const string StartSymbolDescription = "Special symbol that represents the starting node of the result producing branch of a symbolic expression tree.";
    3131    private const int minimumArity = 1;
    32     private const int maximumArity = 1;
     32    private const int maximumArity = 255;
    3333
    3434    public override int MinimumArity {
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views-3.4.csproj

    r7099 r7120  
    111111  <ItemGroup>
    112112    <Compile Include="Plugin.cs" />
    113     <Compile Include="SymbolicTimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.cs">
    114       <SubType>UserControl</SubType>
    115     </Compile>
    116     <Compile Include="SymbolicTimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.Designer.cs">
    117       <DependentUpon>SymbolicTimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.cs</DependentUpon>
    118     </Compile>
    119     <Compile Include="SymbolicTimeSeriesPrognosisSolutionView.cs">
    120       <SubType>UserControl</SubType>
    121     </Compile>
    122     <Compile Include="SymbolicTimeSeriesPrognosisSolutionView.Designer.cs">
    123       <DependentUpon>SymbolicTimeSeriesPrognosisSolutionView.cs</DependentUpon>
    124     </Compile>
    125113    <None Include="HeuristicLab.snk" />
    126114    <None Include="Plugin.cs.frame" />
    127     <Compile Include="InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView.cs">
    128       <SubType>UserControl</SubType>
    129     </Compile>
    130     <Compile Include="InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView.Designer.cs">
    131       <DependentUpon>InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView.cs</DependentUpon>
    132     </Compile>
    133115    <Compile Include="Properties\AssemblyInfo.cs" />
    134116    <None Include="Properties\AssemblyInfo.cs.frame" />
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis-3.4.csproj

    r7100 r7120  
    111111  <ItemGroup>
    112112    <Compile Include="Interfaces\ISymbolicTimeSeriesPrognosisInterpreterOperator.cs" />
    113     <Compile Include="Interfaces\ISymbolicTimeSeriesPrognogisInterpreter.cs" />
    114113    <Compile Include="Interfaces\ISymbolicTimeSeriesPrognosisEvaluator.cs" />
    115114    <Compile Include="Interfaces\ISymbolicTimeSeriesPrognosisModel.cs" />
     
    122121    <Compile Include="SingleObjective\SymbolicTimeSeriesPrognosisSingleObjectiveProblem.cs" />
    123122    <Compile Include="SingleObjective\SymbolicTimeSeriesPrognosisSingleObjectiveTrainingBestSolutionAnalyzer.cs" />
    124     <Compile Include="SymbolicTimeSeriesPrognosisInterpreter.cs" />
    125123    <Compile Include="SymbolicTimeSeriesPrognosisModel.cs" />
    126124    <Compile Include="SymbolicTimeSeriesPrognosisSolution.cs" />
     
    139137      <Name>HeuristicLab.Collections-3.3</Name>
    140138    </ProjectReference>
     139    <ProjectReference Include="..\..\HeuristicLab.Common.Resources\3.3\HeuristicLab.Common.Resources-3.3.csproj">
     140      <Project>{0E27A536-1C4A-4624-A65E-DC4F4F23E3E1}</Project>
     141      <Name>HeuristicLab.Common.Resources-3.3</Name>
     142    </ProjectReference>
    141143    <ProjectReference Include="..\..\HeuristicLab.Common\3.3\HeuristicLab.Common-3.3.csproj">
    142144      <Project>{A9AD58B9-3EF9-4CC1-97E5-8D909039FF5C}</Project>
     
    182184      <Project>{DF87C13E-A889-46FF-8153-66DCAA8C5674}</Project>
    183185      <Name>HeuristicLab.Problems.DataAnalysis-3.4</Name>
     186    </ProjectReference>
     187    <ProjectReference Include="..\..\HeuristicLab.Random\3.3\HeuristicLab.Random-3.3.csproj">
     188      <Project>{F4539FB6-4708-40C9-BE64-0A1390AEA197}</Project>
     189      <Name>HeuristicLab.Random-3.3</Name>
    184190    </ProjectReference>
    185191  </ItemGroup>
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Interfaces/ISymbolicTimeSeriesPrognosisEvaluator.cs

    r6802 r7120  
    2020#endregion
    2121
     22using HeuristicLab.Core;
     23using HeuristicLab.Data;
    2224
    2325namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis {
    2426  public interface ISymbolicTimeSeriesPrognosisEvaluator : ISymbolicDataAnalysisEvaluator<ITimeSeriesPrognosisProblemData> {
     27    IValueLookupParameter<IntValue> HorizonParameter { get; }
    2528  }
    2629}
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Interfaces/ISymbolicTimeSeriesPrognosisInterpreterOperator.cs

    r7100 r7120  
    2424namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis {
    2525  public interface ISymbolicTimeSeriesPrognosisInterpreterOperator : IOperator {
    26     ILookupParameter<ISymbolicTimeSeriesPrognosisInterpreter> SymbolicTimeSeriesPrognosisInterpreterParameter { get; }
     26    ILookupParameter<ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter> SymbolicTimeSeriesPrognosisInterpreterParameter { get; }
    2727  }
    2828}
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Interfaces/ISymbolicTimeSeriesPrognosisModel.cs

    r6802 r7120  
    2222using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
    2323namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis {
    24   public interface ISymbolicTimeSeriesPrognosisModel : ITimeSeriesPrognosisModel, ISymbolicDataAnalysisModel {
     24  public interface ISymbolicTimeSeriesPrognosisModel : ITimeSeriesPrognosisModel {
     25    ISymbolicExpressionTree SymbolicExpressionTree { get; }
     26    ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter Interpreter { get; }
    2527  }
    2628}
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveEvaluator.cs

    r6802 r7120  
    2222
    2323using HeuristicLab.Common;
     24using HeuristicLab.Core;
     25using HeuristicLab.Data;
     26using HeuristicLab.Parameters;
    2427using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
    2528namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis {
    2629  public abstract class SymbolicTimeSeriesPrognosisSingleObjectiveEvaluator : SymbolicDataAnalysisSingleObjectiveEvaluator<ITimeSeriesPrognosisProblemData>, ISymbolicTimeSeriesPrognosisSingleObjectiveEvaluator {
     30    private const string HorizonParameterName = "Horizon";
     31
     32    public IValueLookupParameter<IntValue> HorizonParameter {
     33      get { return (IValueLookupParameter<IntValue>)Parameters[HorizonParameterName]; }
     34    }
     35
    2736    [StorableConstructor]
    2837    protected SymbolicTimeSeriesPrognosisSingleObjectiveEvaluator(bool deserializing) : base(deserializing) { }
     
    3140    }
    3241
    33     protected SymbolicTimeSeriesPrognosisSingleObjectiveEvaluator() : base() { }
     42    protected SymbolicTimeSeriesPrognosisSingleObjectiveEvaluator()
     43      : base() {
     44      Parameters.Add(new ValueLookupParameter<IntValue>(HorizonParameterName, "The time interval for which the prognosis should be calculated.", new IntValue(1)));
     45    }
    3446  }
    3547}
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveMeanSquaredErrorEvaluator.cs

    r7100 r7120  
    2020#endregion
    2121
     22using System;
    2223using System.Collections.Generic;
     24using System.Linq;
    2325using HeuristicLab.Common;
    2426using HeuristicLab.Core;
     
    4850      IEnumerable<int> rows = GenerateRowsToEvaluate();
    4951
    50       double quality = Calculate(SymbolicTimeSeriesPrognosisInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows);
     52      double quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue,
     53        solution,
     54        EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper,
     55        ProblemDataParameter.ActualValue,
     56        rows, HorizonParameter.ActualValue.Value);
    5157      QualityParameter.ActualValue = new DoubleValue(quality);
    5258
     
    5460    }
    5561
    56     public static double Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, ITimeSeriesPrognosisProblemData problemData, IEnumerable<int> rows) {
    57       IEnumerable<double> estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, rows);
    58       OnlineMeanAndVarianceCalculator meanCalculator = new OnlineMeanAndVarianceCalculator();
     62    public static double Calculate(ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, ITimeSeriesPrognosisProblemData problemData, IEnumerable<int> rows, int horizon) {
     63      var allPredictedContinuations = interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, problemData.TargetVariables.ToArray(), rows, horizon);
     64      var meanCalculator = new OnlineMeanAndVarianceCalculator();
     65      var allPredictedContinuationsEnumerator = allPredictedContinuations.GetEnumerator();
    5966      foreach (var targetVariable in problemData.TargetVariables) {
    60         IEnumerable<double> originalValues = problemData.Dataset.GetDoubleValues(targetVariable, rows);
    61         IEnumerable<double> boundedEstimationValues = estimatedValues.LimitToRange(lowerEstimationLimit,
    62                                                                                    upperEstimationLimit);
    63         OnlineCalculatorError errorState;
    64         meanCalculator.Add(OnlineMeanSquaredErrorCalculator.Calculate(originalValues, boundedEstimationValues, out errorState));
    65         if (errorState != OnlineCalculatorError.None) return double.NaN;
     67        if (!allPredictedContinuationsEnumerator.MoveNext()) throw new InvalidOperationException();
     68        var actualContinuations = from r in rows
     69                                  select problemData.Dataset.GetDoubleValues(targetVariable, Enumerable.Range(r, horizon));
     70        var actualContinuationsEnumerator = actualContinuations.GetEnumerator();
     71        var predictedContinuationsEnumerator = allPredictedContinuationsEnumerator.Current.GetEnumerator();
     72        while (actualContinuationsEnumerator.MoveNext() & predictedContinuationsEnumerator.MoveNext()) {
     73          OnlineCalculatorError errorState;
     74          meanCalculator.Add(OnlineMeanSquaredErrorCalculator.Calculate(predictedContinuationsEnumerator.Current.LimitToRange(lowerEstimationLimit, upperEstimationLimit),
     75                                                                        actualContinuationsEnumerator.Current, out errorState));
     76          if (errorState != OnlineCalculatorError.None) return double.NaN;
     77        }
    6678      }
    6779      return meanCalculator.Mean;
     
    6981
    7082    public override double Evaluate(IExecutionContext context, ISymbolicExpressionTree tree, ITimeSeriesPrognosisProblemData problemData, IEnumerable<int> rows) {
    71       SymbolicTimeSeriesPrognosisInterpreterParameter.ExecutionContext = context;
     83      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = context;
    7284      EstimationLimitsParameter.ExecutionContext = context;
     85      HorizonParameter.ExecutionContext = context;
    7386
    74       double mse = Calculate(SymbolicTimeSeriesPrognosisInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows);
     87      double mse = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, HorizonParameter.ActualValue.Value);
    7588
    76 
    77       SymbolicTimeSeriesPrognosisInterpreterParameter.ExecutionContext = null;
     89      HorizonParameter.ExecutionContext = null;
     90      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
    7891      EstimationLimitsParameter.ExecutionContext = null;
    7992
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectivePearsonRSquaredEvaluator.cs

    r7100 r7120  
    2020#endregion
    2121
     22using System;
    2223using System.Collections.Generic;
     24using System.Linq;
    2325using HeuristicLab.Common;
    2426using HeuristicLab.Core;
     
    4850      IEnumerable<int> rows = GenerateRowsToEvaluate();
    4951
    50       double quality = Calculate(SymbolicTimeSeriesPrognosisInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows);
     52      double quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution,
     53        EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper,
     54        ProblemDataParameter.ActualValue,
     55        rows, HorizonParameter.ActualValue.Value);
    5156      QualityParameter.ActualValue = new DoubleValue(quality);
    5257
     
    5459    }
    5560
    56     public static double Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, ITimeSeriesPrognosisProblemData problemData, IEnumerable<int> rows) {
    57       IEnumerable<double> estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, rows);
     61    public static double Calculate(ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, ITimeSeriesPrognosisProblemData problemData, IEnumerable<int> rows, int horizon) {
     62      var allPredictedContinuations =
     63        interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, problemData.TargetVariables.ToArray(),
     64                                                    rows, horizon).ToArray();
     65
    5866      var meanCalculator = new OnlineMeanAndVarianceCalculator();
     67      int i = 0;
    5968      foreach (var targetVariable in problemData.TargetVariables) {
    60         IEnumerable<double> originalValues = problemData.Dataset.GetDoubleValues(targetVariable, rows);
     69        var actualContinuations = from r in rows
     70                                  select problemData.Dataset.GetDoubleValues(targetVariable, Enumerable.Range(r, horizon));
     71        var startValues = problemData.Dataset.GetDoubleValues(targetVariable, rows.Select(r => r - 1));
    6172        OnlineCalculatorError errorState;
    62         meanCalculator.Add(OnlinePearsonsRSquaredCalculator.Calculate(estimatedValues, originalValues, out errorState));
    63         if (errorState != OnlineCalculatorError.None) return 0.0;
     73        meanCalculator.Add(OnlineTheilsUStatisticCalculator.Calculate(
     74          startValues,
     75          allPredictedContinuations.Select(v => v.ElementAt(i)),
     76          actualContinuations, out errorState));
     77        if (errorState != OnlineCalculatorError.None) return double.NaN;
     78        i++;
    6479      }
    6580      return meanCalculator.Mean;
     
    6782
    6883    public override double Evaluate(IExecutionContext context, ISymbolicExpressionTree tree, ITimeSeriesPrognosisProblemData problemData, IEnumerable<int> rows) {
    69       SymbolicTimeSeriesPrognosisInterpreterParameter.ExecutionContext = context;
     84      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = context;
    7085      EstimationLimitsParameter.ExecutionContext = context;
     86      HorizonParameter.ExecutionContext = context;
    7187
    72       double r2 = Calculate(SymbolicTimeSeriesPrognosisInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows);
     88      double r2 = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, HorizonParameter.ActualValue.Value);
    7389
    74       SymbolicTimeSeriesPrognosisInterpreterParameter.ExecutionContext = null;
     90      HorizonParameter.ExecutionContext = null;
     91      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
    7592      EstimationLimitsParameter.ExecutionContext = null;
    7693
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveProblem.cs

    r7100 r7120  
    3131  [Creatable("Problems")]
    3232  public class SymbolicTimeSeriesPrognosisSingleObjectiveProblem : SymbolicDataAnalysisSingleObjectiveProblem<ITimeSeriesPrognosisProblemData, ISymbolicTimeSeriesPrognosisSingleObjectiveEvaluator, ISymbolicDataAnalysisSolutionCreator>, ITimeSeriesPrognosisProblem {
    33     private const double PunishmentFactor = 10;
    3433    private const int InitialMaximumTreeDepth = 8;
    3534    private const int InitialMaximumTreeLength = 25;
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveTrainingBestSolutionAnalyzer.cs

    r7100 r7120  
    2020#endregion
    2121
     22using System.Linq;
    2223using HeuristicLab.Common;
    2324using HeuristicLab.Core;
     
    3435  [StorableClass]
    3536  public sealed class SymbolicTimeSeriesPrognosisSingleObjectiveTrainingBestSolutionAnalyzer : SymbolicDataAnalysisSingleObjectiveTrainingBestSolutionAnalyzer<ISymbolicTimeSeriesPrognosisSolution>,
    36   ISymbolicTimeSeriesPrognosisInterpreterOperator, ISymbolicDataAnalysisBoundedOperator {
     37  ISymbolicDataAnalysisInterpreterOperator, ISymbolicDataAnalysisBoundedOperator {
    3738    private const string ProblemDataParameterName = "ProblemData";
    38     private const string SymbolicTimeSeriesPrognosisInterpreterParameterName = "SymbolicTimeSeriesPrognosisInterpreter";
     39    private const string SymbolicDataAnalysisTreeInterpreterParameterName = "SymbolicDataAnalysisTreeInterpreter";
    3940    private const string EstimationLimitsParameterName = "EstimationLimits";
    4041    private const string ApplyLinearScalingParameterName = "ApplyLinearScaling";
     
    4344      get { return (ILookupParameter<ITimeSeriesPrognosisProblemData>)Parameters[ProblemDataParameterName]; }
    4445    }
    45     public ILookupParameter<ISymbolicTimeSeriesPrognosisInterpreter> SymbolicTimeSeriesPrognosisInterpreterParameter {
    46       get { return (ILookupParameter<ISymbolicTimeSeriesPrognosisInterpreter>)Parameters[SymbolicTimeSeriesPrognosisInterpreterParameterName]; }
     46    public ILookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter> SymbolicDataAnalysisTreeInterpreterParameter {
     47      get { return (ILookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>)Parameters[SymbolicDataAnalysisTreeInterpreterParameterName]; }
    4748    }
    4849    public IValueLookupParameter<DoubleLimit> EstimationLimitsParameter {
     
    6667      : base() {
    6768      Parameters.Add(new LookupParameter<ITimeSeriesPrognosisProblemData>(ProblemDataParameterName, "The problem data for the symbolic regression solution."));
    68       Parameters.Add(new LookupParameter<ISymbolicTimeSeriesPrognosisInterpreter>(SymbolicTimeSeriesPrognosisInterpreterParameterName, "The symbolic time series prognosis interpreter for the symbolic expression tree."));
     69      Parameters.Add(new LookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>(SymbolicDataAnalysisTreeInterpreterParameterName, "The symbolic time series prognosis interpreter for the symbolic expression tree."));
    6970      Parameters.Add(new ValueLookupParameter<DoubleLimit>(EstimationLimitsParameterName, "The lower and upper limit for the estimated values produced by the symbolic regression model."));
    7071      Parameters.Add(new ValueParameter<BoolValue>(ApplyLinearScalingParameterName, "Flag that indicates if the produced symbolic regression solution should be linearly scaled.", new BoolValue(true)));
     
    7576
    7677    protected override ISymbolicTimeSeriesPrognosisSolution CreateSolution(ISymbolicExpressionTree bestTree, double bestQuality) {
    77       var model = new SymbolicTimeSeriesPrognosisModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicTimeSeriesPrognosisInterpreterParameter.ActualValue);
     78      var model = new SymbolicTimeSeriesPrognosisModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, ProblemDataParameter.ActualValue.TargetVariables.ToArray());
    7879      if (ApplyLinearScaling.Value)
    7980        SymbolicTimeSeriesPrognosisModel.Scale(model, ProblemDataParameter.ActualValue);
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SymbolicTimeSeriesPrognosisInterpreter.cs

    r7100 r7120  
    3333  [StorableClass]
    3434  [Item("SymbolicTimeSeriesPrognosisInterpreter", "Interpreter for symbolic expression trees including automatically defined functions.")]
    35   public sealed class SymbolicTimeSeriesPrognosisInterpreter : ParameterizedNamedItem, ISymbolicTimeSeriesPrognosisInterpreter {
     35  public sealed class SymbolicTimeSeriesPrognosisInterpreter : ParameterizedNamedItem, ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter {
    3636    private const string CheckExpressionsWithIntervalArithmeticParameterName = "CheckExpressionsWithIntervalArithmetic";
    3737    #region private classes
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SymbolicTimeSeriesPrognosisModel.cs

    r7100 r7120  
    2121
    2222using System.Collections.Generic;
     23using System.Drawing;
    2324using System.Linq;
    2425using HeuristicLab.Common;
     
    3334  [StorableClass]
    3435  [Item(Name = "Symbolic Time-Series Prognosis Model", Description = "Represents a symbolic time series prognosis model.")]
    35   public class SymbolicTimeSeriesPrognosisModel : SymbolicDataAnalysisModel, ISymbolicTimeSeriesPrognosisModel {
    36     public new ISymbolicTimeSeriesPrognosisInterpreter Interpreter {
    37       get { return (ISymbolicTimeSeriesPrognosisInterpreter)base.Interpreter; }
     36  public class SymbolicTimeSeriesPrognosisModel : NamedItem, ISymbolicTimeSeriesPrognosisModel {
     37    public override Image ItemImage {
     38      get { return HeuristicLab.Common.Resources.VSImageLibrary.Function; }
    3839    }
     40
     41    #region properties
     42
     43    [Storable]
     44    private ISymbolicExpressionTree symbolicExpressionTree;
     45    public ISymbolicExpressionTree SymbolicExpressionTree {
     46      get { return symbolicExpressionTree; }
     47    }
     48
     49    [Storable]
     50    private ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter interpreter;
     51    public ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter Interpreter {
     52      get { return interpreter; }
     53    }
     54
     55    #endregion
     56
     57    [Storable]
     58    private string[] targetVariables;
     59
    3960
    4061    [StorableConstructor]
     
    4263    protected SymbolicTimeSeriesPrognosisModel(SymbolicTimeSeriesPrognosisModel original, Cloner cloner)
    4364      : base(original, cloner) {
     65      this.symbolicExpressionTree = cloner.Clone(original.symbolicExpressionTree);
     66      this.interpreter = cloner.Clone(original.interpreter);
    4467    }
    45     public SymbolicTimeSeriesPrognosisModel(ISymbolicExpressionTree tree, ISymbolicTimeSeriesPrognosisInterpreter interpreter)
    46       : base(tree, interpreter) {
     68    public SymbolicTimeSeriesPrognosisModel(ISymbolicExpressionTree tree, ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter interpreter, IEnumerable<string> targetVariables)
     69      : base() {
     70      this.name = ItemName;
     71      this.description = ItemDescription;
     72      this.symbolicExpressionTree = tree;
     73      this.interpreter = interpreter; this.targetVariables = targetVariables.ToArray();
    4774    }
    4875
     
    5279
    5380    public IEnumerable<IEnumerable<IEnumerable<double>>> GetPrognosedValues(Dataset dataset, IEnumerable<int> rows, int horizon) {
    54       return Interpreter.GetSymbolicExpressionTreeValues(SymbolicExpressionTree, dataset, rows, horizon);
     81      return Interpreter.GetSymbolicExpressionTreeValues(SymbolicExpressionTree, dataset, targetVariables, rows, horizon);
    5582    }
    5683
     
    6895      int i = 0;
    6996      int horizon = 1;
    70       var estimatedValues = model.Interpreter.GetSymbolicExpressionTreeValues(model.SymbolicExpressionTree, dataset, rows, horizon)
     97      var estimatedValues = model.Interpreter.GetSymbolicExpressionTreeValues(model.SymbolicExpressionTree, dataset, problemData.TargetVariables.ToArray(), rows, horizon)
    7198        .ToArray();
    7299      foreach (var targetVariable in targetVariables) {
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj

    r7037 r7120  
    126126    <Compile Include="Creators\SymbolicDataAnalysisExpressionRampedHalfAndHalfTreeCreator.cs" />
    127127    <Compile Include="Creators\SymbolicDataAnalysisExpressionTreeCreator.cs" />
     128    <Compile Include="Interfaces\ISymbolicTimeSeriesPrognogisExpressionTreeInterpreter.cs" />
    128129    <Compile Include="Plugin.cs" />
    129130    <Compile Include="SymbolicDataAnalysisExpressionTreeILEmittingInterpreter.cs" />
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/ISymbolicDataAnalysisExpressionTreeInterpreter.cs

    r5809 r7120  
    2525
    2626namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
    27   public interface ISymbolicDataAnalysisExpressionTreeInterpreter : INamedItem {
     27  public interface ISymbolicDataAnalysisExpressionTreeInterpreter : ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter {
    2828    IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, IEnumerable<int> rows);
    2929  }
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeILEmittingInterpreter.cs

    r7077 r7120  
    222222      }
    223223    }
     224    public IEnumerable<IEnumerable<IEnumerable<double>>> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, string[] targetVariables, IEnumerable<int> rows, int horizon) {
     225      throw new NotImplementedException();
     226    }
    224227
    225228    private void CompileInstructions(ILGenerator il, InterpreterState state, Dataset ds) {
  • branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeInterpreter.cs

    r6860 r7120  
    2222using System;
    2323using System.Collections.Generic;
     24using System.Linq;
    2425using HeuristicLab.Common;
    2526using HeuristicLab.Core;
     
    3233  [StorableClass]
    3334  [Item("SymbolicDataAnalysisExpressionTreeInterpreter", "Interpreter for symbolic expression trees including automatically defined functions.")]
    34   public sealed class SymbolicDataAnalysisExpressionTreeInterpreter : ParameterizedNamedItem, ISymbolicDataAnalysisExpressionTreeInterpreter {
     35  public sealed class SymbolicDataAnalysisExpressionTreeInterpreter : ParameterizedNamedItem,
     36    ISymbolicDataAnalysisExpressionTreeInterpreter, ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter {
    3537    private const string CheckExpressionsWithIntervalArithmeticParameterName = "CheckExpressionsWithIntervalArithmetic";
    3638    #region private classes
     
    199201
    200202    public IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, IEnumerable<int> rows) {
     203      return from prog in GetSymbolicExpressionTreeValues(tree, dataset, new string[] { "#NOTHING#" }, rows, 1)
     204             select prog.First().First();
     205    }
     206
     207    // for each row for each target variable one prognosis (=enumerable of future values)
     208    public IEnumerable<IEnumerable<IEnumerable<double>>> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, string[] targetVariables, IEnumerable<int> rows, int horizon) {
    201209      if (CheckExpressionsWithIntervalArithmetic.Value)
    202210        throw new NotSupportedException("Interval arithmetic is not yet supported in the symbolic data analysis interpreter.");
     
    223231      var state = new InterpreterState(code, necessaryArgStackSize);
    224232
     233      int nComponents = tree.Root.GetSubtree(0).SubtreeCount;
     234      // produce a n-step forecast for each target variable for all rows
     235      var cachedPrognosedValues = new Dictionary<string, double[]>();
     236      foreach (var targetVariable in targetVariables)
     237        cachedPrognosedValues[targetVariable] = new double[horizon];
    225238      foreach (var rowEnum in rows) {
    226239        int row = rowEnum;
    227         state.Reset();
    228         yield return Evaluate(dataset, ref row, state);
    229       }
    230     }
    231 
    232     private double Evaluate(Dataset dataset, ref int row, InterpreterState state) {
     240        List<double[]> vProgs = new List<double[]>();
     241        foreach (var horizonRow in Enumerable.Range(row, horizon)) {
     242          int localRow = horizonRow; // create a local variable for the ref parameter
     243          var vPrognosis = from i in Enumerable.Range(0, nComponents)
     244                           select Evaluate(dataset, ref localRow, row - 1, state, cachedPrognosedValues);
     245
     246          var vPrognosisArr = vPrognosis.ToArray();
     247          vProgs.Add(vPrognosisArr);
     248          // set cachedValues for prognosis of future values
     249          for (int i = 0; i < vPrognosisArr.Length; i++)
     250            cachedPrognosedValues[targetVariables[i]][horizonRow - row] = vPrognosisArr[i];
     251
     252          state.Reset();
     253        }
     254
     255        yield return from component in Enumerable.Range(0, nComponents)
     256                     select from prognosisStep in Enumerable.Range(0, vProgs.Count)
     257                            select vProgs[prognosisStep][component];
     258      }
     259    }
     260
     261    private double Evaluate(Dataset dataset, ref int row, int lastObservedRow, InterpreterState state, Dictionary<string, double[]> cachedPrognosedValues) {
    233262      Instruction currentInstr = state.NextInstruction();
    234263      switch (currentInstr.opCode) {
    235264        case OpCodes.Add: {
    236             double s = Evaluate(dataset, ref row, state);
    237             for (int i = 1; i < currentInstr.nArguments; i++) {
    238               s += Evaluate(dataset, ref row, state);
     265            double s = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
     266            for (int i = 1; i < currentInstr.nArguments; i++) {
     267              s += Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
    239268            }
    240269            return s;
    241270          }
    242271        case OpCodes.Sub: {
    243             double s = Evaluate(dataset, ref row, state);
    244             for (int i = 1; i < currentInstr.nArguments; i++) {
    245               s -= Evaluate(dataset, ref row, state);
     272            double s = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
     273            for (int i = 1; i < currentInstr.nArguments; i++) {
     274              s -= Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
    246275            }
    247276            if (currentInstr.nArguments == 1) s = -s;
     
    249278          }
    250279        case OpCodes.Mul: {
    251             double p = Evaluate(dataset, ref row, state);
    252             for (int i = 1; i < currentInstr.nArguments; i++) {
    253               p *= Evaluate(dataset, ref row, state);
     280            double p = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
     281            for (int i = 1; i < currentInstr.nArguments; i++) {
     282              p *= Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
    254283            }
    255284            return p;
    256285          }
    257286        case OpCodes.Div: {
    258             double p = Evaluate(dataset, ref row, state);
    259             for (int i = 1; i < currentInstr.nArguments; i++) {
    260               p /= Evaluate(dataset, ref row, state);
     287            double p = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
     288            for (int i = 1; i < currentInstr.nArguments; i++) {
     289              p /= Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
    261290            }
    262291            if (currentInstr.nArguments == 1) p = 1.0 / p;
     
    264293          }
    265294        case OpCodes.Average: {
    266             double sum = Evaluate(dataset, ref row, state);
    267             for (int i = 1; i < currentInstr.nArguments; i++) {
    268               sum += Evaluate(dataset, ref row, state);
     295            double sum = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
     296            for (int i = 1; i < currentInstr.nArguments; i++) {
     297              sum += Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
    269298            }
    270299            return sum / currentInstr.nArguments;
    271300          }
    272301        case OpCodes.Cos: {
    273             return Math.Cos(Evaluate(dataset, ref row, state));
     302            return Math.Cos(Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues));
    274303          }
    275304        case OpCodes.Sin: {
    276             return Math.Sin(Evaluate(dataset, ref row, state));
     305            return Math.Sin(Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues));
    277306          }
    278307        case OpCodes.Tan: {
    279             return Math.Tan(Evaluate(dataset, ref row, state));
     308            return Math.Tan(Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues));
    280309          }
    281310        case OpCodes.Power: {
    282             double x = Evaluate(dataset, ref row, state);
    283             double y = Math.Round(Evaluate(dataset, ref row, state));
     311            double x = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
     312            double y = Math.Round(Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues));
    284313            return Math.Pow(x, y);
    285314          }
    286315        case OpCodes.Root: {
    287             double x = Evaluate(dataset, ref row, state);
    288             double y = Math.Round(Evaluate(dataset, ref row, state));
     316            double x = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
     317            double y = Math.Round(Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues));
    289318            return Math.Pow(x, 1 / y);
    290319          }
    291320        case OpCodes.Exp: {
    292             return Math.Exp(Evaluate(dataset, ref row, state));
     321            return Math.Exp(Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues));
    293322          }
    294323        case OpCodes.Log: {
    295             return Math.Log(Evaluate(dataset, ref row, state));
     324            return Math.Log(Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues));
    296325          }
    297326        case OpCodes.IfThenElse: {
    298             double condition = Evaluate(dataset, ref row, state);
     327            double condition = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
    299328            double result;
    300329            if (condition > 0.0) {
    301               result = Evaluate(dataset, ref row, state); SkipInstructions(state);
     330              result = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues); SkipInstructions(state);
    302331            } else {
    303               SkipInstructions(state); result = Evaluate(dataset, ref row, state);
     332              SkipInstructions(state); result = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
    304333            }
    305334            return result;
    306335          }
    307336        case OpCodes.AND: {
    308             double result = Evaluate(dataset, ref row, state);
    309             for (int i = 1; i < currentInstr.nArguments; i++) {
    310               if (result > 0.0) result = Evaluate(dataset, ref row, state);
     337            double result = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
     338            for (int i = 1; i < currentInstr.nArguments; i++) {
     339              if (result > 0.0) result = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
    311340              else {
    312341                SkipInstructions(state);
     
    316345          }
    317346        case OpCodes.OR: {
    318             double result = Evaluate(dataset, ref row, state);
    319             for (int i = 1; i < currentInstr.nArguments; i++) {
    320               if (result <= 0.0) result = Evaluate(dataset, ref row, state);
     347            double result = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
     348            for (int i = 1; i < currentInstr.nArguments; i++) {
     349              if (result <= 0.0) result = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
    321350              else {
    322351                SkipInstructions(state);
     
    326355          }
    327356        case OpCodes.NOT: {
    328             return Evaluate(dataset, ref row, state) > 0.0 ? -1.0 : 1.0;
     357            return Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues) > 0.0 ? -1.0 : 1.0;
    329358          }
    330359        case OpCodes.GT: {
    331             double x = Evaluate(dataset, ref row, state);
    332             double y = Evaluate(dataset, ref row, state);
     360            double x = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
     361            double y = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
    333362            if (x > y) return 1.0;
    334363            else return -1.0;
    335364          }
    336365        case OpCodes.LT: {
    337             double x = Evaluate(dataset, ref row, state);
    338             double y = Evaluate(dataset, ref row, state);
     366            double x = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
     367            double y = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
    339368            if (x < y) return 1.0;
    340369            else return -1.0;
     
    343372            var timeLagTreeNode = (LaggedTreeNode)currentInstr.dynamicNode;
    344373            row += timeLagTreeNode.Lag;
    345             double result = Evaluate(dataset, ref row, state);
     374            double result = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
    346375            row -= timeLagTreeNode.Lag;
    347376            return result;
     
    353382            for (int i = 0; i < Math.Abs(timeLagTreeNode.Lag); i++) {
    354383              row += Math.Sign(timeLagTreeNode.Lag);
    355               sum += Evaluate(dataset, ref row, state);
     384              sum += Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
    356385              state.ProgramCounter = savedPc;
    357386            }
    358387            row -= timeLagTreeNode.Lag;
    359             sum += Evaluate(dataset, ref row, state);
     388            sum += Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
    360389            return sum;
    361390          }
     
    367396        case OpCodes.Derivative: {
    368397            int savedPc = state.ProgramCounter;
    369             double f_0 = Evaluate(dataset, ref row, state); row--;
     398            double f_0 = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues); row--;
    370399            state.ProgramCounter = savedPc;
    371             double f_1 = Evaluate(dataset, ref row, state); row -= 2;
     400            double f_1 = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues); row -= 2;
    372401            state.ProgramCounter = savedPc;
    373             double f_3 = Evaluate(dataset, ref row, state); row--;
     402            double f_3 = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues); row--;
    374403            state.ProgramCounter = savedPc;
    375             double f_4 = Evaluate(dataset, ref row, state);
     404            double f_4 = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
    376405            row += 4;
    377406
     
    382411            double[] argValues = new double[currentInstr.nArguments];
    383412            for (int i = 0; i < currentInstr.nArguments; i++) {
    384               argValues[i] = Evaluate(dataset, ref row, state);
     413              argValues[i] = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
    385414            }
    386415            // push on argument values on stack
     
    392421            state.ProgramCounter = (ushort)currentInstr.iArg0;
    393422            // evaluate the function
    394             double v = Evaluate(dataset, ref row, state);
     423            double v = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
    395424
    396425            // delete the stack frame
     
    408437              return double.NaN;
    409438            var variableTreeNode = (VariableTreeNode)currentInstr.dynamicNode;
    410             return ((IList<double>)currentInstr.iArg0)[row] * variableTreeNode.Weight;
     439            if (row <= lastObservedRow || !cachedPrognosedValues.ContainsKey(variableTreeNode.VariableName)) return ((IList<double>)currentInstr.iArg0)[row] * variableTreeNode.Weight;
     440            else return cachedPrognosedValues[variableTreeNode.VariableName][row - lastObservedRow - 1] * variableTreeNode.Weight;
    411441          }
    412442        case OpCodes.LagVariable: {
     
    415445            if (actualRow < 0 || actualRow >= dataset.Rows)
    416446              return double.NaN;
    417             return ((IList<double>)currentInstr.iArg0)[actualRow] * laggedVariableTreeNode.Weight;
     447            if (actualRow <= lastObservedRow || !cachedPrognosedValues.ContainsKey(laggedVariableTreeNode.VariableName)) return ((IList<double>)currentInstr.iArg0)[actualRow] * laggedVariableTreeNode.Weight;
     448            else return cachedPrognosedValues[laggedVariableTreeNode.VariableName][actualRow - lastObservedRow - 1] * laggedVariableTreeNode.Weight;
    418449          }
    419450        case OpCodes.Constant: {
     
    428459              return double.NaN;
    429460            var variableConditionTreeNode = (VariableConditionTreeNode)currentInstr.dynamicNode;
    430             double variableValue = ((IList<double>)currentInstr.iArg0)[row];
     461            double variableValue;
     462            if (row <= lastObservedRow || !cachedPrognosedValues.ContainsKey(variableConditionTreeNode.VariableName))
     463              variableValue = ((IList<double>)currentInstr.iArg0)[row];
     464            else
     465              variableValue = cachedPrognosedValues[variableConditionTreeNode.VariableName][row - lastObservedRow - 1];
     466
    431467            double x = variableValue - variableConditionTreeNode.Threshold;
    432468            double p = 1 / (1 + Math.Exp(-variableConditionTreeNode.Slope * x));
    433469
    434             double trueBranch = Evaluate(dataset, ref row, state);
    435             double falseBranch = Evaluate(dataset, ref row, state);
     470            double trueBranch = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
     471            double falseBranch = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
    436472
    437473            return trueBranch * p + falseBranch * (1 - p);
Note: See TracChangeset for help on using the changeset viewer.