Changeset 259
- Timestamp:
- 05/14/08 19:23:46 (17 years ago)
- Location:
- trunk/sources/HeuristicLab.Functions
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.Functions/BakedFunctionTree.cs
r239 r259 28 28 using HeuristicLab.Data; 29 29 using System.Xml; 30 using System.Globalization; 30 31 31 32 namespace HeuristicLab.Functions { … … 33 34 private List<int> code; 34 35 private List<double> data; 35 36 private static BakedTreeEvaluator evaluator = new BakedTreeEvaluator(); 36 37 public BakedFunctionTree() { 37 38 code = new List<int>(); … … 42 43 : this() { 43 44 code.Add(0); 44 code.Add( BakedTreeEvaluator.MapFunction(function));45 code.Add(evaluator.MapFunction(function)); 45 46 code.Add(0); 46 47 treesExpanded = true; … … 58 59 : this() { 59 60 code.Add(0); 60 code.Add( BakedTreeEvaluator.MapFunction(tree.Function));61 code.Add(evaluator.MapFunction(tree.Function)); 61 62 code.Add(tree.LocalVariables.Count); 62 63 foreach(IVariable variable in tree.LocalVariables) { … … 158 159 if(!variablesExpanded) { 159 160 variables = new List<IVariable>(); 160 IFunction function = BakedTreeEvaluator.MapSymbol(code[1]);161 IFunction function = evaluator.MapSymbol(code[1]); 161 162 int localVariableIndex = 0; 162 163 foreach(IVariableInfo variableInfo in function.VariableInfos) { … … 186 187 187 188 public IFunction Function { 188 get { return BakedTreeEvaluator.MapSymbol(code[1]); }189 get { return evaluator.MapSymbol(code[1]); } 189 190 } 190 191 … … 220 221 } 221 222 222 private BakedTreeEvaluator evaluator;223 223 public double Evaluate(Dataset dataset, int sampleIndex) { 224 224 FlattenVariables(); 225 225 FlattenTrees(); 226 if(evaluator == null) evaluator = new BakedTreeEvaluator(code, data);226 evaluator.SetCode(code, data); 227 227 return evaluator.Evaluate(dataset, sampleIndex); 228 228 } … … 230 230 231 231 public override XmlNode GetXmlNode(string name, XmlDocument document, IDictionary<Guid, IStorable> persistedObjects) { 232 FlattenVariables(); 233 FlattenTrees(); 232 234 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); 242 245 return node; 243 246 } … … 245 248 public override void Populate(XmlNode node, IDictionary<Guid, IStorable> restoredObjects) { 246 249 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; 261 276 } 262 277 … … 264 279 BakedFunctionTree clone = new BakedFunctionTree(); 265 280 // 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(); 267 282 if(variablesExpanded) FlattenVariables(); 268 283 clone.code.AddRange(code); -
trunk/sources/HeuristicLab.Functions/BakedTreeEvaluator.cs
r239 r259 4 4 using System.Text; 5 5 using HeuristicLab.DataAnalysis; 6 using HeuristicLab.Core; 7 using System.Xml; 6 8 7 9 namespace HeuristicLab.Functions { 8 internal class BakedTreeEvaluator {10 internal class BakedTreeEvaluator : StorableBase { 9 11 private const int ADDITION = 10010; 10 12 private const int AND = 10020; … … 31 33 private const int XOR = 10230; 32 34 33 private staticint nextFunctionSymbol = 10240;34 private staticDictionary<int, IFunction> symbolTable;35 private staticDictionary<IFunction, int> reverseSymbolTable;36 private staticDictionary<Type, int> staticTypes;37 private staticint MAX_CODE_LENGTH = 4096;38 private staticint MAX_DATA_LENGTH = 4096;39 private staticint[] codeArr = new int[MAX_CODE_LENGTH];40 private staticdouble[] 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() { 43 45 symbolTable = new Dictionary<int, IFunction>(); 44 46 reverseSymbolTable = new Dictionary<IFunction, int>(); … … 69 71 } 70 72 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) { 77 74 if(!reverseSymbolTable.ContainsKey(function)) { 78 75 int curFunctionSymbol; … … 88 85 } 89 86 90 internal staticIFunction MapSymbol(int symbol) {87 internal IFunction MapSymbol(int symbol) { 91 88 return symbolTable[symbol]; 92 89 } 93 90 91 internal void SetCode(List<int> code, List<double> data) { 92 code.CopyTo(codeArr); 93 data.CopyTo(dataArr); 94 } 94 95 95 96 private int PC; … … 108 109 private double EvaluateBakedCode() { 109 110 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]; 112 113 PC += 3; 113 114 switch(functionSymbol) { 114 115 case VARIABLE: { 115 116 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]; 118 119 DP += 3; 119 120 if(row < 0 || row >= dataset.Rows) return double.NaN; … … 202 203 for(int i = 0; i < arity; i++) { 203 204 double x = Math.Round(EvaluateBakedCode()); 204 if(x == 0 || x ==1.0) result *= x;205 if(x == 0 || x == 1.0) result *= x; 205 206 else result = double.NaN; 206 207 } … … 269 270 } 270 271 } 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 } 271 307 } 272 308 }
Note: See TracChangeset
for help on using the changeset viewer.