Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
07/30/13 13:58:45 (11 years ago)
Author:
bburlacu
Message:

#2021: Code enhancements: changed the SymbolicExpressionTreeLinearCompiler to use and return an array directly and not a list.ToArray(). Replaced GetPrefixSequence lambda with a standalone method and eliminated SetSkip lambda from the PrepareInstructions method. Updated description of SymbolicDataAnalysisExpressionTreeLinearInterpreter.

Location:
branches/HeuristicLab.DataAnalysis.Symbolic.LinearInterpreter
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/HeuristicLab.DataAnalysis.Symbolic.LinearInterpreter/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Compiler/SymbolicExpressionTreeLinearCompiler.cs

    r9758 r9815  
    2121
    2222using System;
    23 using System.Collections.Generic;
    24 using System.Linq;
    2523
    2624namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
     
    2826    public static LinearInstruction[] Compile(ISymbolicExpressionTree tree, Func<ISymbolicExpressionTreeNode, byte> opCodeMapper) {
    2927      var root = tree.Root.GetSubtree(0).GetSubtree(0);
    30       var code = new List<LinearInstruction> {
    31           new LinearInstruction { dynamicNode = root, nArguments = (byte)root.SubtreeCount, opCode = opCodeMapper(root) }
    32         };
    33       // iterate breadth-wise over tree nodes and produce an array of instructions
    34       var nodes = root.IterateNodesBreadth().ToArray();
    35       for (int i = 0; i != nodes.Length; ++i) {
    36         code[i].childIndex = (byte)code.Count;
    37         code.AddRange(nodes[i].Subtrees.Select(s => new LinearInstruction { dynamicNode = s, nArguments = (byte)s.SubtreeCount, opCode = opCodeMapper(s) }));
     28      var code = new LinearInstruction[root.GetLength()];
     29      code[0] = new LinearInstruction { dynamicNode = root, nArguments = (byte)root.SubtreeCount, opCode = opCodeMapper(root) };
     30      int c = 1, i = 0;
     31      foreach (var node in root.IterateNodesBreadth()) {
     32        for (int j = 0; j != node.SubtreeCount; ++j) {
     33          var s = node.GetSubtree(j);
     34          code[c + j] = new LinearInstruction { dynamicNode = s, nArguments = (byte)s.SubtreeCount, opCode = opCodeMapper(s) };
     35        }
     36        code[i].childIndex = (byte)c;
     37        c += node.SubtreeCount;
     38        ++i;
    3839      }
    39 
    40       return code.ToArray();
     40      return code;
    4141    }
    4242  }
  • branches/HeuristicLab.DataAnalysis.Symbolic.LinearInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeLinearInterpreter.cs

    r9793 r9815  
    3232namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
    3333  [StorableClass]
    34   [Item("SymbolicDataAnalysisExpressionTreeLinearInterpreter", "Linear (non-recursive) interpreter for symbolic expression trees. This interpreter is faster but does not support Integral, Derivative, TimeLag or ADF function nodes.")]
     34  [Item("SymbolicDataAnalysisExpressionTreeLinearInterpreter", "Fast linear (non-recursive) interpreter for symbolic expression trees. Does not support ADFs.")]
    3535  public sealed class SymbolicDataAnalysisExpressionTreeLinearInterpreter : ParameterizedNamedItem, ISymbolicDataAnalysisExpressionTreeInterpreter {
    3636    private const string CheckExpressionsWithIntervalArithmeticParameterName = "CheckExpressionsWithIntervalArithmetic";
     
    126126      PrepareInstructions(code, dataset);
    127127      return rows.Select(row => Evaluate(dataset, ref row, code));
    128     }
    129 
    130     private static LinearInstruction[] GetPrefixSequence(LinearInstruction[] code, int startIndex) {
    131       Action<LinearInstruction, List<LinearInstruction>> getPrefix = null;
    132       getPrefix = (instr, list) => {
    133         list.Add(instr);
    134         for (int i = 0; i != instr.nArguments; ++i) {
    135           getPrefix(code[instr.childIndex + i], list);
    136         }
    137       };
    138       var l = new List<LinearInstruction>();
    139       getPrefix(code[startIndex], l);
    140       return l.ToArray();
    141     }
    142 
    143     private static void PrepareInstructions(LinearInstruction[] code, Dataset dataset) {
    144       Action<LinearInstruction> setSkip = null;
    145       setSkip = instruction => {
    146         instruction.skip = true;
    147         for (int j = 0; j != instruction.nArguments; ++j) {
    148           setSkip(code[instruction.childIndex + j]);
    149         }
    150       };
    151 
    152       for (int i = 0; i != code.Length; ++i) {
    153         var instr = code[i];
    154         #region opcode switch
    155         switch (instr.opCode) {
    156           case OpCodes.Constant: {
    157               var constTreeNode = (ConstantTreeNode)instr.dynamicNode;
    158               instr.value = constTreeNode.Value;
    159               instr.skip = true; // the value is already set so this instruction should be skipped in the evaluation phase
    160             }
    161             break;
    162           case OpCodes.Variable: {
    163               var variableTreeNode = (VariableTreeNode)instr.dynamicNode;
    164               instr.iArg0 = dataset.GetReadOnlyDoubleValues(variableTreeNode.VariableName);
    165             }
    166             break;
    167           case OpCodes.LagVariable: {
    168               var laggedVariableTreeNode = (LaggedVariableTreeNode)instr.dynamicNode;
    169               instr.iArg0 = dataset.GetReadOnlyDoubleValues(laggedVariableTreeNode.VariableName);
    170             }
    171             break;
    172           case OpCodes.VariableCondition: {
    173               var variableConditionTreeNode = (VariableConditionTreeNode)instr.dynamicNode;
    174               instr.iArg0 = dataset.GetReadOnlyDoubleValues(variableConditionTreeNode.VariableName);
    175             }
    176             break;
    177           case OpCodes.TimeLag:
    178           case OpCodes.Integral:
    179           case OpCodes.Derivative: {
    180               Instruction[] seq = GetPrefixSequence(code, i);
    181               var interpreterState = new InterpreterState(seq, 0);
    182               instr.iArg0 = interpreterState;
    183               for (int j = 0; j != instr.nArguments; ++j) {
    184                 // the linear evaluator will skip these instructions and they will be evaluated using the default (recursive) evaluator
    185                 setSkip(code[instr.childIndex + j]);
    186               }
    187             }
    188             break;
    189         }
    190         #endregion
    191       }
    192128    }
    193129
     
    489425      return code[0].value;
    490426    }
     427
     428    private static LinearInstruction[] GetPrefixSequence(LinearInstruction[] code, int startIndex) {
     429      var list = new List<LinearInstruction>();
     430      int i = startIndex;
     431      while (i != code.Length) {
     432        var instr = code[i];
     433        list.Add(instr);
     434        i = instr.nArguments > 0 ? instr.childIndex : i + 1;
     435      }
     436      return list.ToArray();
     437    }
     438
     439    private static void PrepareInstructions(LinearInstruction[] code, Dataset dataset) {
     440      for (int i = 0; i != code.Length; ++i) {
     441        var instr = code[i];
     442        #region opcode switch
     443        switch (instr.opCode) {
     444          case OpCodes.Constant: {
     445              var constTreeNode = (ConstantTreeNode)instr.dynamicNode;
     446              instr.value = constTreeNode.Value;
     447              instr.skip = true; // the value is already set so this instruction should be skipped in the evaluation phase
     448            }
     449            break;
     450          case OpCodes.Variable: {
     451              var variableTreeNode = (VariableTreeNode)instr.dynamicNode;
     452              instr.iArg0 = dataset.GetReadOnlyDoubleValues(variableTreeNode.VariableName);
     453            }
     454            break;
     455          case OpCodes.LagVariable: {
     456              var laggedVariableTreeNode = (LaggedVariableTreeNode)instr.dynamicNode;
     457              instr.iArg0 = dataset.GetReadOnlyDoubleValues(laggedVariableTreeNode.VariableName);
     458            }
     459            break;
     460          case OpCodes.VariableCondition: {
     461              var variableConditionTreeNode = (VariableConditionTreeNode)instr.dynamicNode;
     462              instr.iArg0 = dataset.GetReadOnlyDoubleValues(variableConditionTreeNode.VariableName);
     463            }
     464            break;
     465          case OpCodes.TimeLag:
     466          case OpCodes.Integral:
     467          case OpCodes.Derivative: {
     468              var seq = GetPrefixSequence(code, i);
     469              var interpreterState = new InterpreterState(seq, 0);
     470              instr.iArg0 = interpreterState;
     471              for (int j = 1; j != seq.Length; ++j)
     472                seq[j].skip = true;
     473            }
     474            break;
     475        }
     476        #endregion
     477      }
     478    }
    491479  }
    492480}
Note: See TracChangeset for help on using the changeset viewer.