Ignore:
Timestamp:
12/07/10 10:23:58 (11 years ago)
Author:
mkommend
Message:

Added new symbols for GP (ticket #1256).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/GP.Symbols (TimeLag, Diff, Integral)/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/SimpleArithmeticExpressionInterpreter.cs

    r5026 r5051  
    2222using System;
    2323using System.Collections.Generic;
     24using System.Linq;
    2425using HeuristicLab.Common;
    2526using HeuristicLab.Core;
     
    3536  // not thread safe!
    3637  public sealed class SimpleArithmeticExpressionInterpreter : NamedItem, ISymbolicExpressionTreeInterpreter {
     38    private struct InstructionEvaluation {
     39      int instructionIndex;
     40      int row;
     41    }
     42
    3743    private class OpCodes {
    3844      public const byte Add = 1;
     
    6874
    6975      public const byte TimeLag = 22;
     76      public const byte Integral = 23;
     77      public const byte Derivative = 24;
    7078    }
    7179
     
    93101      { typeof(Argument), OpCodes.Arg },
    94102      { typeof(TimeLag), OpCodes.TimeLag},
     103      { typeof(Integral), OpCodes.Integral},
     104      { typeof(Derivative), OpCodes.Derivative}
    95105    };
    96106    private const int ARGUMENT_STACK_SIZE = 1024;
     
    102112    private double[] argumentStack = new double[ARGUMENT_STACK_SIZE];
    103113    private int argStackPointer;
     114    private Dictionary<InstructionEvaluation, double> cachedEvaluations;
    104115
    105116    public override bool CanChangeName {
     
    120131    public SimpleArithmeticExpressionInterpreter()
    121132      : base() {
     133      cachedEvaluations = new Dictionary<InstructionEvaluation, double>();
    122134    }
    123135
    124136    public IEnumerable<double> GetSymbolicExpressionTreeValues(SymbolicExpressionTree tree, Dataset dataset, IEnumerable<int> rows) {
    125137      this.dataset = dataset;
     138      cachedEvaluations.Clear();
    126139      var compiler = new SymbolicExpressionTreeCompiler();
    127140      compiler.AddInstructionPostProcessingHook(PostProcessInstruction);
     
    133146        yield return Evaluate();
    134147      }
     148      cachedEvaluations.Clear();
    135149    }
    136150
     
    295309        case OpCodes.TimeLag: {
    296310            var timeLagTreeNode = (LaggedTreeNode)currentInstr.dynamicNode;
     311            if (row + timeLagTreeNode.Lag < 0 || row + timeLagTreeNode.Lag >= dataset.Rows)
     312              return double.NaN;
     313
    297314            row += timeLagTreeNode.Lag;
    298             if (row < 0 || row >= dataset.Rows) {
    299               row -= timeLagTreeNode.Lag;
    300               return double.NaN;
    301             }
    302315            double result = Evaluate();
    303316            row -= timeLagTreeNode.Lag;
    304317            return result;
     318          }
     319        case OpCodes.Integral: {
     320            int nextPc = pc;
     321            var timeLagTreeNode = (LaggedTreeNode)currentInstr.dynamicNode;
     322            if (row + timeLagTreeNode.Lag < 0 || row + timeLagTreeNode.Lag >= dataset.Rows)
     323              return double.NaN;
     324            double sum = 0.0;
     325            if (timeLagTreeNode.IterateNodesPrefix().OfType<VariableTreeNode>().Any()) {
     326              for (int i = 0; i < Math.Abs(timeLagTreeNode.Lag); i++) {
     327                row += Math.Sign(timeLagTreeNode.Lag);
     328                sum += Evaluate();
     329                pc = nextPc;
     330              }
     331              row -= timeLagTreeNode.Lag;
     332              sum += Evaluate();
     333            } else sum = Math.Abs(timeLagTreeNode.Lag) * Evaluate();
     334            return sum;
     335          }
     336
     337        //mkommend: derivate calculation taken from:
     338        //http://www.holoborodko.com/pavel/numerical-methods/numerical-derivative/smooth-low-noise-differentiators/
     339        //one sided smooth differentiatior, N = 4
     340        // y' = 1/8h (f_i + 2f_i-1, -2 f_i-3 - f_i-4)
     341        case OpCodes.Derivative: {
     342            if (row - 4 < 0) return double.NaN;
     343            int nextPc = pc;
     344            double f_0 = Evaluate(); row--;
     345            pc = nextPc;
     346            double f_1 = Evaluate(); row -= 2;
     347            pc = nextPc;
     348            double f_3 = Evaluate(); row--;
     349            pc = nextPc;
     350            double f_4 = Evaluate();
     351            row += 4;
     352
     353            return (f_0 + 2 * f_1 - 2 * f_3 - f_4) / 8; // h = 1
    305354          }
    306355        default: throw new NotSupportedException();
Note: See TracChangeset for help on using the changeset viewer.