Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
05/14/08 19:23:46 (16 years ago)
Author:
gkronber
Message:

implemented #146

Location:
trunk/sources/HeuristicLab.Functions
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Functions/BakedFunctionTree.cs

    r239 r259  
    2828using HeuristicLab.Data;
    2929using System.Xml;
     30using System.Globalization;
    3031
    3132namespace HeuristicLab.Functions {
     
    3334    private List<int> code;
    3435    private List<double> data;
    35 
     36    private static BakedTreeEvaluator evaluator = new BakedTreeEvaluator();
    3637    public BakedFunctionTree() {
    3738      code = new List<int>();
     
    4243      : this() {
    4344      code.Add(0);
    44       code.Add(BakedTreeEvaluator.MapFunction(function));
     45      code.Add(evaluator.MapFunction(function));
    4546      code.Add(0);
    4647      treesExpanded = true;
     
    5859      : this() {
    5960      code.Add(0);
    60       code.Add(BakedTreeEvaluator.MapFunction(tree.Function));
     61      code.Add(evaluator.MapFunction(tree.Function));
    6162      code.Add(tree.LocalVariables.Count);
    6263      foreach(IVariable variable in tree.LocalVariables) {
     
    158159        if(!variablesExpanded) {
    159160          variables = new List<IVariable>();
    160           IFunction function = BakedTreeEvaluator.MapSymbol(code[1]);
     161          IFunction function = evaluator.MapSymbol(code[1]);
    161162          int localVariableIndex = 0;
    162163          foreach(IVariableInfo variableInfo in function.VariableInfos) {
     
    186187
    187188    public IFunction Function {
    188       get { return BakedTreeEvaluator.MapSymbol(code[1]); }
     189      get { return evaluator.MapSymbol(code[1]); }
    189190    }
    190191
     
    220221    }
    221222
    222     private BakedTreeEvaluator evaluator;
    223223    public double Evaluate(Dataset dataset, int sampleIndex) {
    224224      FlattenVariables();
    225225      FlattenTrees();
    226       if(evaluator == null) evaluator = new BakedTreeEvaluator(code, data);
     226      evaluator.SetCode(code, data);
    227227      return evaluator.Evaluate(dataset, sampleIndex);
    228228    }
     
    230230
    231231    public override XmlNode GetXmlNode(string name, XmlDocument document, IDictionary<Guid, IStorable> persistedObjects) {
     232      FlattenVariables();
     233      FlattenTrees();
    232234      XmlNode node = base.GetXmlNode(name, document, persistedObjects);
    233       node.AppendChild(PersistenceManager.Persist("Function", Function, document, persistedObjects));
    234       XmlNode subTreesNode = document.CreateNode(XmlNodeType.Element, "SubTrees", null);
    235       for(int i = 0; i < SubTrees.Count; i++)
    236         subTreesNode.AppendChild(PersistenceManager.Persist(SubTrees[i], document, persistedObjects));
    237       node.AppendChild(subTreesNode);
    238       XmlNode variablesNode = document.CreateNode(XmlNodeType.Element, "Variables", null);
    239       foreach(IVariable variable in LocalVariables)
    240         variablesNode.AppendChild(PersistenceManager.Persist(variable, document, persistedObjects));
    241       node.AppendChild(variablesNode);
     235      if(evaluator != null) {
     236        XmlNode evaluatorNode = PersistenceManager.Persist("Evaluator", evaluator, document, persistedObjects);
     237        node.AppendChild(evaluatorNode);
     238      }
     239      XmlAttribute codeAttribute = document.CreateAttribute("Code");
     240      codeAttribute.Value = GetString<int>(code);
     241      node.Attributes.Append(codeAttribute);
     242      XmlAttribute dataAttribute = document.CreateAttribute("Data");
     243      dataAttribute.Value = GetString<double>(data);
     244      node.Attributes.Append(dataAttribute);
    242245      return node;
    243246    }
     
    245248    public override void Populate(XmlNode node, IDictionary<Guid, IStorable> restoredObjects) {
    246249      base.Populate(node, restoredObjects);
    247       IFunction function = (IFunction)PersistenceManager.Restore(node.SelectSingleNode("Function"), restoredObjects);
    248       code.Add(0);
    249       code.Add(BakedTreeEvaluator.MapFunction(function));
    250       code.Add(0);
    251       treesExpanded = true;
    252       subTrees = new List<IFunctionTree>();
    253       variables = new List<IVariable>();
    254       variablesExpanded = true;
    255       XmlNode subTreesNode = node.SelectSingleNode("SubTrees");
    256       for(int i = 0; i < subTreesNode.ChildNodes.Count; i++)
    257         subTrees.Add((IFunctionTree)PersistenceManager.Restore(subTreesNode.ChildNodes[i], restoredObjects));
    258       XmlNode variablesNode = node.SelectSingleNode("Variables");
    259       foreach(XmlNode variableNode in variablesNode.ChildNodes)
    260         variables.Add((IVariable)PersistenceManager.Restore(variableNode, restoredObjects));
     250      XmlNode evaluatorNode = node.SelectSingleNode("Evaluator");
     251      if(evaluatorNode != null) {
     252        BakedTreeEvaluator evaluator = (BakedTreeEvaluator)PersistenceManager.Restore(evaluatorNode, restoredObjects);
     253        BakedFunctionTree.evaluator = evaluator;
     254      }
     255      code = GetList<int>(node.Attributes["Code"].Value, s => int.Parse(s, CultureInfo.InvariantCulture));
     256      data = GetList<double>(node.Attributes["Data"].Value, s => double.Parse(s, CultureInfo.InvariantCulture));
     257    }
     258
     259    private string GetString<T>(IEnumerable<T> xs) where T : IConvertible {
     260      StringBuilder builder = new StringBuilder();
     261      foreach(T x in xs) {
     262        builder.Append(x.ToString(CultureInfo.InvariantCulture) + "; ");
     263      }
     264      if(builder.Length > 0) builder.Remove(builder.Length - 2, 2);
     265      return builder.ToString();
     266    }
     267
     268    private List<T> GetList<T>(string s, Converter<string, T> converter) {
     269      List<T> result = new List<T>();
     270      string[] tokens = s.Split(new char[] {';',' '}, StringSplitOptions.RemoveEmptyEntries);
     271      foreach(string token in tokens) {
     272        T x = converter(token.Trim());
     273        result.Add(x);
     274      }
     275      return result;
    261276    }
    262277
     
    264279      BakedFunctionTree clone = new BakedFunctionTree();
    265280      // in case the user (de)serialized the tree between evaluation and selection we have to flatten the tree again.
    266       if(treesExpanded) FlattenTrees(); 
     281      if(treesExpanded) FlattenTrees();
    267282      if(variablesExpanded) FlattenVariables();
    268283      clone.code.AddRange(code);
  • trunk/sources/HeuristicLab.Functions/BakedTreeEvaluator.cs

    r239 r259  
    44using System.Text;
    55using HeuristicLab.DataAnalysis;
     6using HeuristicLab.Core;
     7using System.Xml;
    68
    79namespace HeuristicLab.Functions {
    8   internal class BakedTreeEvaluator {
     10  internal class BakedTreeEvaluator : StorableBase {
    911    private const int ADDITION = 10010;
    1012    private const int AND = 10020;
     
    3133    private const int XOR = 10230;
    3234
    33     private static int nextFunctionSymbol = 10240;
    34     private static Dictionary<int, IFunction> symbolTable;
    35     private static Dictionary<IFunction, int> reverseSymbolTable;
    36     private static Dictionary<Type, int> staticTypes;
    37     private static int MAX_CODE_LENGTH = 4096;
    38     private static int MAX_DATA_LENGTH = 4096;
    39     private static int[] codeArr = new int[MAX_CODE_LENGTH];
    40     private static double[] dataArr = new double[MAX_DATA_LENGTH];
    41 
    42     static BakedTreeEvaluator() {
     35    private int nextFunctionSymbol = 10240;
     36    private Dictionary<int, IFunction> symbolTable;
     37    private Dictionary<IFunction, int> reverseSymbolTable;
     38    private Dictionary<Type, int> staticTypes;
     39    private const int MAX_CODE_LENGTH = 4096;
     40    private const int MAX_DATA_LENGTH = 4096;
     41    private int[] codeArr = new int[MAX_CODE_LENGTH];
     42    private double[] dataArr = new double[MAX_DATA_LENGTH];
     43
     44    public BakedTreeEvaluator() {
    4345      symbolTable = new Dictionary<int, IFunction>();
    4446      reverseSymbolTable = new Dictionary<IFunction, int>();
     
    6971    }
    7072
    71     internal BakedTreeEvaluator(List<int> code, List<double> data) {
    72       code.CopyTo(codeArr);
    73       data.CopyTo(dataArr);
    74     }
    75 
    76     internal static int MapFunction(IFunction function) {
     73    internal int MapFunction(IFunction function) {
    7774      if(!reverseSymbolTable.ContainsKey(function)) {
    7875        int curFunctionSymbol;
     
    8885    }
    8986
    90     internal static IFunction MapSymbol(int symbol) {
     87    internal IFunction MapSymbol(int symbol) {
    9188      return symbolTable[symbol];
    9289    }
    9390
     91    internal void SetCode(List<int> code, List<double> data) {
     92      code.CopyTo(codeArr);
     93      data.CopyTo(dataArr);
     94    }
    9495
    9596    private int PC;
     
    108109    private double EvaluateBakedCode() {
    109110      int arity = codeArr[PC];
    110       int functionSymbol = codeArr[PC+1];
    111       int nLocalVariables = codeArr[PC+2];
     111      int functionSymbol = codeArr[PC + 1];
     112      int nLocalVariables = codeArr[PC + 2];
    112113      PC += 3;
    113114      switch(functionSymbol) {
    114115        case VARIABLE: {
    115116            int var = (int)dataArr[DP];
    116             double weight = dataArr[DP+1];
    117             int row = sampleIndex + (int)dataArr[DP+2];
     117            double weight = dataArr[DP + 1];
     118            int row = sampleIndex + (int)dataArr[DP + 2];
    118119            DP += 3;
    119120            if(row < 0 || row >= dataset.Rows) return double.NaN;
     
    202203            for(int i = 0; i < arity; i++) {
    203204              double x = Math.Round(EvaluateBakedCode());
    204               if(x == 0 || x==1.0) result *= x;
     205              if(x == 0 || x == 1.0) result *= x;
    205206              else result = double.NaN;
    206207            }
     
    269270      }
    270271    }
     272
     273    public override object Clone(IDictionary<Guid, object> clonedObjects) {
     274      throw new NotImplementedException();
     275    }
     276
     277    public override XmlNode GetXmlNode(string name, XmlDocument document, IDictionary<Guid, IStorable> persistedObjects) {
     278      XmlNode node = base.GetXmlNode(name, document, persistedObjects);
     279      XmlAttribute nextFunctionSymbolAttribute = document.CreateAttribute("NextFunctionSymbol");
     280      nextFunctionSymbolAttribute.Value = nextFunctionSymbol.ToString();
     281      node.Attributes.Append(nextFunctionSymbolAttribute);
     282      XmlNode symbolTableNode = document.CreateNode(XmlNodeType.Element, "SymbolTable", null);
     283      foreach(KeyValuePair<int, IFunction> entry in symbolTable) {
     284        XmlNode entryNode = PersistenceManager.Persist("Entry", entry.Value, document, persistedObjects);
     285        XmlAttribute symbolAttr = document.CreateAttribute("Symbol");
     286        symbolAttr.Value = entry.Key.ToString();
     287        entryNode.Attributes.Append(symbolAttr);
     288        symbolTableNode.AppendChild(entryNode);
     289      }
     290      node.AppendChild(symbolTableNode);
     291      return node;
     292    }
     293
     294    public override void Populate(XmlNode node, IDictionary<Guid, IStorable> restoredObjects) {
     295      base.Populate(node, restoredObjects);
     296      symbolTable.Clear();
     297      reverseSymbolTable.Clear();
     298      nextFunctionSymbol = int.Parse(node.Attributes["NextFunctionSymbol"].Value);
     299      XmlNode symbolTableNode = node.SelectSingleNode("SymbolTable");
     300      foreach(XmlNode entry in symbolTableNode.ChildNodes) {
     301        IFunction function = (IFunction)PersistenceManager.Restore(entry, restoredObjects);
     302        int symbol = int.Parse(entry.Attributes["Symbol"].Value);
     303        symbolTable[symbol] = function;
     304        reverseSymbolTable[function] = symbol;
     305      }
     306    }
    271307  }
    272308}
Note: See TracChangeset for help on using the changeset viewer.