Changeset 5051 for branches/GP.Symbols (TimeLag, Diff, Integral)/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/SimpleArithmeticExpressionInterpreter.cs
- Timestamp:
- 12/07/10 10:23:58 (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/GP.Symbols (TimeLag, Diff, Integral)/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/SimpleArithmeticExpressionInterpreter.cs
r5026 r5051 22 22 using System; 23 23 using System.Collections.Generic; 24 using System.Linq; 24 25 using HeuristicLab.Common; 25 26 using HeuristicLab.Core; … … 35 36 // not thread safe! 36 37 public sealed class SimpleArithmeticExpressionInterpreter : NamedItem, ISymbolicExpressionTreeInterpreter { 38 private struct InstructionEvaluation { 39 int instructionIndex; 40 int row; 41 } 42 37 43 private class OpCodes { 38 44 public const byte Add = 1; … … 68 74 69 75 public const byte TimeLag = 22; 76 public const byte Integral = 23; 77 public const byte Derivative = 24; 70 78 } 71 79 … … 93 101 { typeof(Argument), OpCodes.Arg }, 94 102 { typeof(TimeLag), OpCodes.TimeLag}, 103 { typeof(Integral), OpCodes.Integral}, 104 { typeof(Derivative), OpCodes.Derivative} 95 105 }; 96 106 private const int ARGUMENT_STACK_SIZE = 1024; … … 102 112 private double[] argumentStack = new double[ARGUMENT_STACK_SIZE]; 103 113 private int argStackPointer; 114 private Dictionary<InstructionEvaluation, double> cachedEvaluations; 104 115 105 116 public override bool CanChangeName { … … 120 131 public SimpleArithmeticExpressionInterpreter() 121 132 : base() { 133 cachedEvaluations = new Dictionary<InstructionEvaluation, double>(); 122 134 } 123 135 124 136 public IEnumerable<double> GetSymbolicExpressionTreeValues(SymbolicExpressionTree tree, Dataset dataset, IEnumerable<int> rows) { 125 137 this.dataset = dataset; 138 cachedEvaluations.Clear(); 126 139 var compiler = new SymbolicExpressionTreeCompiler(); 127 140 compiler.AddInstructionPostProcessingHook(PostProcessInstruction); … … 133 146 yield return Evaluate(); 134 147 } 148 cachedEvaluations.Clear(); 135 149 } 136 150 … … 295 309 case OpCodes.TimeLag: { 296 310 var timeLagTreeNode = (LaggedTreeNode)currentInstr.dynamicNode; 311 if (row + timeLagTreeNode.Lag < 0 || row + timeLagTreeNode.Lag >= dataset.Rows) 312 return double.NaN; 313 297 314 row += timeLagTreeNode.Lag; 298 if (row < 0 || row >= dataset.Rows) {299 row -= timeLagTreeNode.Lag;300 return double.NaN;301 }302 315 double result = Evaluate(); 303 316 row -= timeLagTreeNode.Lag; 304 317 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 305 354 } 306 355 default: throw new NotSupportedException();
Note: See TracChangeset
for help on using the changeset viewer.