Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
04/21/10 15:21:34 (14 years ago)
Author:
gkronber
Message:

Refactored symbolic expression tree encoding and problem classes for symbolic regression. #937 , #938

Location:
trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Compiler
Files:
1 added
2 moved

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Compiler/Instruction.cs

    r3456 r3462  
    2626using System.Collections.Generic;
    2727using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
    28 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.GeneralSymbols;
     28using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Symbols;
    2929
    30 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
    31   public enum CodeSymbol : byte {
    32     Add,
    33     Sub,
    34     Mul,
    35     Div,
    36     Call,
    37     Arg,
    38     Values,
    39     Dynamic
    40   };
     30namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Compiler {
     31  // total size of this struct should be small to improve cache access while executing the code
     32  // should be aligned to 8/16/32 byte
     33  // size = 4(8) + 1 + 1 + 2 = 8 (12)
    4134  public struct Instruction {
     35    // the tree node can hold additional data that is necessary for the execution of this instruction
     36    public SymbolicExpressionTreeNode dynamicNode;
     37    // op code of the function that determines what operation should be executed
     38    public byte opCode;
     39    // number of arguments of the current instruction
    4240    public byte nArguments;
    43     public CodeSymbol symbol;
    44     public short iArg0;
    45     public SymbolicExpressionTreeNode dynamicNode;
     41    // an optional short value (addresses for calls, argument index for arguments)
     42    public ushort iArg0;
    4643  }
    4744}
  • trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Compiler/SymbolicExpressionTreeCompiler.cs

    r3456 r3462  
    2727using System.Collections.Generic;
    2828using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
    29 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.GeneralSymbols;
     29using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Symbols;
    3030
    31 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
     31namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Compiler {
    3232  public class SymbolicExpressionTreeCompiler {
    33     private Dictionary<Type, CodeSymbol> codeSymbol = new Dictionary<Type, CodeSymbol>() {
    34       {typeof(Addition), CodeSymbol.Add},
    35       {typeof(Subtraction), CodeSymbol.Sub},
    36       {typeof(Multiplication), CodeSymbol.Mul},
    37       {typeof(Division), CodeSymbol.Div},
    38       {typeof(InvokeFunction), CodeSymbol.Call},
    39       {typeof(Argument), CodeSymbol.Arg},
    40       //{typeof(Values), CodeSymbol.Values}
    41     };
    42     private Dictionary<string, short> entryPoint = new Dictionary<string, short>();
     33    private Dictionary<string, ushort> entryPoint = new Dictionary<string, ushort>();
     34    private List<Func<Instruction, Instruction>> postInstructionCompiledHooks = new List<Func<Instruction, Instruction>>();
    4335
    44     public Instruction[] Compile(SymbolicExpressionTree tree) {
     36    public Instruction[] Compile(SymbolicExpressionTree tree, Func<SymbolicExpressionTreeNode, byte> opCodeMapper) {
    4537      List<Instruction> code = new List<Instruction>();
    4638      entryPoint.Clear();
    4739      // compile main body
    48       code.AddRange(Compile(tree.Root.SubTrees[0].SubTrees[0]));
     40      code.AddRange(Compile(tree.Root.SubTrees[0].SubTrees[0], opCodeMapper));
    4941      // compile branches
    5042      var functionBranches = from node in tree.IterateNodesPrefix()
     
    5244                             select node;
    5345      foreach (DefunTreeNode branch in functionBranches) {
    54         entryPoint[branch.FunctionName] = (short)code.Count;
    55         code.AddRange(Compile(branch.SubTrees[0]));
     46        if (code.Count > ushort.MaxValue) throw new ArgumentException("Code for the tree is too long (> ushort.MaxValue).");
     47        entryPoint[branch.FunctionName] = (ushort)code.Count;
     48        code.AddRange(Compile(branch.SubTrees[0], opCodeMapper));
    5649      }
    5750      // address of all functions is fixed now
     
    5952      for (int i = 0; i < code.Count; i++) {
    6053        Instruction instr = code[i];
    61         if (instr.symbol == CodeSymbol.Call) {
     54        if (instr.dynamicNode.Symbol is InvokeFunction) {
    6255          var invokeNode = (InvokeFunctionTreeNode)instr.dynamicNode;
    6356          instr.iArg0 = entryPoint[invokeNode.Symbol.FunctionName];
    64           instr.dynamicNode = null;
    6557          code[i] = instr;
    6658        }
     
    7062    }
    7163
    72     private IEnumerable<Instruction> Compile(SymbolicExpressionTreeNode branch) {
    73       foreach (var node in IteratePrefix(branch)) {
     64    private IEnumerable<Instruction> Compile(SymbolicExpressionTreeNode branch, Func<SymbolicExpressionTreeNode, byte> opCodeMapper) {
     65      foreach (var node in branch.IterateNodesPrefix()) {
    7466        Instruction instr = new Instruction();
    75         if (node.SubTrees.Count > 255) throw new ArgumentException();
     67        if (node.SubTrees.Count > 255) throw new ArgumentException("Number of subtrees is too big (>255)");
    7668        instr.nArguments = (byte)node.SubTrees.Count;
    77         if (codeSymbol.ContainsKey(node.Symbol.GetType())) {
    78           instr.symbol = codeSymbol[node.Symbol.GetType()];
    79           if (instr.symbol == CodeSymbol.Arg) {
    80             var argNode = (ArgumentTreeNode)node;
    81             instr.iArg0 = (short)argNode.Symbol.ArgumentIndex;
    82           } else if (instr.symbol == CodeSymbol.Call) {
    83             instr.dynamicNode = node; // save node for fixup of jump addresses in second iteration
    84           }
    85         } else {
    86           instr.symbol = CodeSymbol.Dynamic;
    87           instr.dynamicNode = node;
     69        instr.opCode = opCodeMapper(node);
     70        if (branch.Symbol is Argument) {
     71          var argNode = (ArgumentTreeNode)node;
     72          instr.iArg0 = (ushort)argNode.Symbol.ArgumentIndex;
     73        }
     74        instr.dynamicNode = node;
     75        foreach (var hook in postInstructionCompiledHooks) {
     76          instr = hook(instr);
    8877        }
    8978        yield return instr;
     
    9180    }
    9281
    93     private IEnumerable<SymbolicExpressionTreeNode> IteratePrefix(SymbolicExpressionTreeNode branch) {
    94       yield return branch;
    95       foreach (var subtree in branch.SubTrees) {
    96         foreach (var node in IteratePrefix(subtree))
    97           yield return node;
    98       }
     82    /// <summary>
     83    /// Adds a function that will be called every time an instruction is compiled.
     84    /// The compiled will insert the instruction returned by the hook into the code.
     85    /// </summary>
     86    /// <param name="hook">The hook that should be called for each compiled instruction.</param>
     87    public void AddInstructionPostProcessingHook(Func<Instruction, Instruction> hook) {
     88      postInstructionCompiledHooks.Add(hook);
    9989    }
    10090  }
Note: See TracChangeset for help on using the changeset viewer.