Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
05/14/08 20:14:07 (17 years ago)
Author:
gkronber
Message:

fixed #146 (serialization of function-trees in linear form)

Location:
trunk/sources/HeuristicLab.Functions
Files:
1 added
3 edited

Legend:

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

    r259 r260  
    3434    private List<int> code;
    3535    private List<double> data;
    36     private static BakedTreeEvaluator evaluator = new BakedTreeEvaluator();
     36    private static EvaluatorSymbolTable symbolTable = EvaluatorSymbolTable.SymbolTable;
    3737    public BakedFunctionTree() {
    3838      code = new List<int>();
     
    4343      : this() {
    4444      code.Add(0);
    45       code.Add(evaluator.MapFunction(function));
     45      code.Add(symbolTable.MapFunction(function));
    4646      code.Add(0);
    4747      treesExpanded = true;
     
    5959      : this() {
    6060      code.Add(0);
    61       code.Add(evaluator.MapFunction(tree.Function));
     61      code.Add(symbolTable.MapFunction(tree.Function));
    6262      code.Add(tree.LocalVariables.Count);
    6363      foreach(IVariable variable in tree.LocalVariables) {
     
    159159        if(!variablesExpanded) {
    160160          variables = new List<IVariable>();
    161           IFunction function = evaluator.MapSymbol(code[1]);
     161          IFunction function = symbolTable.MapSymbol(code[1]);
    162162          int localVariableIndex = 0;
    163163          foreach(IVariableInfo variableInfo in function.VariableInfos) {
     
    187187
    188188    public IFunction Function {
    189       get { return evaluator.MapSymbol(code[1]); }
     189      get { return symbolTable.MapSymbol(code[1]); }
    190190    }
    191191
     
    221221    }
    222222
     223    private BakedTreeEvaluator evaluator = null;
    223224    public double Evaluate(Dataset dataset, int sampleIndex) {
    224225      FlattenVariables();
    225226      FlattenTrees();
    226       evaluator.SetCode(code, data);
     227      if(evaluator == null) evaluator = new BakedTreeEvaluator(code, data);
    227228      return evaluator.Evaluate(dataset, sampleIndex);
    228229    }
     
    250251      XmlNode evaluatorNode = node.SelectSingleNode("Evaluator");
    251252      if(evaluatorNode != null) {
    252         BakedTreeEvaluator evaluator = (BakedTreeEvaluator)PersistenceManager.Restore(evaluatorNode, restoredObjects);
    253         BakedFunctionTree.evaluator = evaluator;
     253        this.evaluator = (BakedTreeEvaluator)PersistenceManager.Restore(evaluatorNode, restoredObjects);
    254254      }
    255255      code = GetList<int>(node.Attributes["Code"].Value, s => int.Parse(s, CultureInfo.InvariantCulture));
    256256      data = GetList<double>(node.Attributes["Data"].Value, s => double.Parse(s, CultureInfo.InvariantCulture));
     257      treesExpanded = false;
     258      variablesExpanded = false;
    257259    }
    258260
  • trunk/sources/HeuristicLab.Functions/BakedTreeEvaluator.cs

    r259 r260  
    99namespace HeuristicLab.Functions {
    1010  internal class BakedTreeEvaluator : StorableBase {
    11     private const int ADDITION = 10010;
    12     private const int AND = 10020;
    13     private const int AVERAGE = 10030;
    14     private const int CONSTANT = 10040;
    15     private const int COSINUS = 10050;
    16     private const int DIVISION = 10060;
    17     private const int EQU = 10070;
    18     private const int EXP = 10080;
    19     private const int GT = 10090;
    20     private const int IFTE = 10100;
    21     private const int LT = 10110;
    22     private const int LOG = 10120;
    23     private const int MULTIPLICATION = 10130;
    24     private const int NOT = 10140;
    25     private const int OR = 10150;
    26     private const int POWER = 10160;
    27     private const int SIGNUM = 10170;
    28     private const int SINUS = 10180;
    29     private const int SQRT = 10190;
    30     private const int SUBSTRACTION = 10200;
    31     private const int TANGENS = 10210;
    32     private const int VARIABLE = 10220;
    33     private const int XOR = 10230;
    34 
    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 
     11    private int[] codeArr;
     12    private double[] dataArr;
     13    private static EvaluatorSymbolTable symbolTable = EvaluatorSymbolTable.SymbolTable;
     14
     15    // for persistence mechanism only
    4416    public BakedTreeEvaluator() {
    45       symbolTable = new Dictionary<int, IFunction>();
    46       reverseSymbolTable = new Dictionary<IFunction, int>();
    47       staticTypes = new Dictionary<Type, int>();
    48       staticTypes[typeof(Addition)] = ADDITION;
    49       staticTypes[typeof(And)] = AND;
    50       staticTypes[typeof(Average)] = AVERAGE;
    51       staticTypes[typeof(Constant)] = CONSTANT;
    52       staticTypes[typeof(Cosinus)] = COSINUS;
    53       staticTypes[typeof(Division)] = DIVISION;
    54       staticTypes[typeof(Equal)] = EQU;
    55       staticTypes[typeof(Exponential)] = EXP;
    56       staticTypes[typeof(GreaterThan)] = GT;
    57       staticTypes[typeof(IfThenElse)] = IFTE;
    58       staticTypes[typeof(LessThan)] = LT;
    59       staticTypes[typeof(Logarithm)] = LOG;
    60       staticTypes[typeof(Multiplication)] = MULTIPLICATION;
    61       staticTypes[typeof(Not)] = NOT;
    62       staticTypes[typeof(Or)] = OR;
    63       staticTypes[typeof(Power)] = POWER;
    64       staticTypes[typeof(Signum)] = SIGNUM;
    65       staticTypes[typeof(Sinus)] = SINUS;
    66       staticTypes[typeof(Sqrt)] = SQRT;
    67       staticTypes[typeof(Substraction)] = SUBSTRACTION;
    68       staticTypes[typeof(Tangens)] = TANGENS;
    69       staticTypes[typeof(Variable)] = VARIABLE;
    70       staticTypes[typeof(Xor)] = XOR;
    71     }
    72 
    73     internal int MapFunction(IFunction function) {
    74       if(!reverseSymbolTable.ContainsKey(function)) {
    75         int curFunctionSymbol;
    76         if(staticTypes.ContainsKey(function.GetType())) curFunctionSymbol = staticTypes[function.GetType()];
    77         else {
    78           curFunctionSymbol = nextFunctionSymbol;
    79           nextFunctionSymbol++;
    80         }
    81         reverseSymbolTable[function] = curFunctionSymbol;
    82         symbolTable[curFunctionSymbol] = function;
    83       }
    84       return reverseSymbolTable[function];
    85     }
    86 
    87     internal IFunction MapSymbol(int symbol) {
    88       return symbolTable[symbol];
    89     }
    90 
    91     internal void SetCode(List<int> code, List<double> data) {
    92       code.CopyTo(codeArr);
    93       data.CopyTo(dataArr);
     17    }
     18
     19    public BakedTreeEvaluator(List<int> code, List<double> data) {
     20      codeArr = code.ToArray();
     21      dataArr = data.ToArray();
    9422    }
    9523
     
    11341      PC += 3;
    11442      switch(functionSymbol) {
    115         case VARIABLE: {
     43        case EvaluatorSymbolTable.VARIABLE: {
    11644            int var = (int)dataArr[DP];
    11745            double weight = dataArr[DP + 1];
     
    12149            else return weight * dataset.GetValue(row, var);
    12250          }
    123         case CONSTANT: {
     51        case EvaluatorSymbolTable.CONSTANT: {
    12452            return dataArr[DP++];
    12553          }
    126         case MULTIPLICATION: {
     54        case EvaluatorSymbolTable.MULTIPLICATION: {
    12755            double result = EvaluateBakedCode();
    12856            for(int i = 1; i < arity; i++) {
     
    13159            return result;
    13260          }
    133         case ADDITION: {
     61        case EvaluatorSymbolTable.ADDITION: {
    13462            double sum = EvaluateBakedCode();
    13563            for(int i = 1; i < arity; i++) {
     
    13866            return sum;
    13967          }
    140         case SUBSTRACTION: {
     68        case EvaluatorSymbolTable.SUBSTRACTION: {
    14169            if(arity == 1) {
    14270              return -EvaluateBakedCode();
     
    14977            }
    15078          }
    151         case DIVISION: {
     79        case EvaluatorSymbolTable.DIVISION: {
    15280            double result;
    15381            if(arity == 1) {
     
    16290            else return result;
    16391          }
    164         case AVERAGE: {
     92        case EvaluatorSymbolTable.AVERAGE: {
    16593            double sum = EvaluateBakedCode();
    16694            for(int i = 1; i < arity; i++) {
     
    16997            return sum / arity;
    17098          }
    171         case COSINUS: {
     99        case EvaluatorSymbolTable.COSINUS: {
    172100            return Math.Cos(EvaluateBakedCode());
    173101          }
    174         case SINUS: {
     102        case EvaluatorSymbolTable.SINUS: {
    175103            return Math.Sin(EvaluateBakedCode());
    176104          }
    177         case EXP: {
     105        case EvaluatorSymbolTable.EXP: {
    178106            return Math.Exp(EvaluateBakedCode());
    179107          }
    180         case LOG: {
     108        case EvaluatorSymbolTable.LOG: {
    181109            return Math.Log(EvaluateBakedCode());
    182110          }
    183         case POWER: {
     111        case EvaluatorSymbolTable.POWER: {
    184112            double x = EvaluateBakedCode();
    185113            double p = EvaluateBakedCode();
    186114            return Math.Pow(x, p);
    187115          }
    188         case SIGNUM: {
     116        case EvaluatorSymbolTable.SIGNUM: {
    189117            double value = EvaluateBakedCode();
    190118            if(double.IsNaN(value)) return double.NaN;
    191119            else return Math.Sign(value);
    192120          }
    193         case SQRT: {
     121        case EvaluatorSymbolTable.SQRT: {
    194122            return Math.Sqrt(EvaluateBakedCode());
    195123          }
    196         case TANGENS: {
     124        case EvaluatorSymbolTable.TANGENS: {
    197125            return Math.Tan(EvaluateBakedCode());
    198126          }
    199         case AND: {
     127        case EvaluatorSymbolTable.AND: {
    200128            double result = 1.0;
    201129            // have to evaluate all sub-trees, skipping would probably not lead to a big gain because
     
    208136            return result;
    209137          }
    210         case EQU: {
     138        case EvaluatorSymbolTable.EQU: {
    211139            double x = EvaluateBakedCode();
    212140            double y = EvaluateBakedCode();
    213141            if(x == y) return 1.0; else return 0.0;
    214142          }
    215         case GT: {
     143        case EvaluatorSymbolTable.GT: {
    216144            double x = EvaluateBakedCode();
    217145            double y = EvaluateBakedCode();
     
    219147            else return 0.0;
    220148          }
    221         case IFTE: {
     149        case EvaluatorSymbolTable.IFTE: {
    222150            double condition = Math.Round(EvaluateBakedCode());
    223151            double x = EvaluateBakedCode();
     
    227155            else return double.NaN;
    228156          }
    229         case LT: {
     157        case EvaluatorSymbolTable.LT: {
    230158            double x = EvaluateBakedCode();
    231159            double y = EvaluateBakedCode();
     
    233161            else return 0.0;
    234162          }
    235         case NOT: {
     163        case EvaluatorSymbolTable.NOT: {
    236164            double result = Math.Round(EvaluateBakedCode());
    237165            if(result == 0.0) return 1.0;
     
    239167            else return double.NaN;
    240168          }
    241         case OR: {
     169        case EvaluatorSymbolTable.OR: {
    242170            double result = 0.0; // default is false
    243171            for(int i = 0; i < arity; i++) {
     
    248176            return result;
    249177          }
    250         case XOR: {
     178        case EvaluatorSymbolTable.XOR: {
    251179            double x = Math.Round(EvaluateBakedCode());
    252180            double y = Math.Round(EvaluateBakedCode());
     
    258186          }
    259187        default: {
    260             IFunction function = symbolTable[functionSymbol];
     188            IFunction function = symbolTable.MapSymbol(functionSymbol);
    261189            double[] args = new double[nLocalVariables + arity];
    262190            for(int i = 0; i < nLocalVariables; i++) {
     
    277205    public override XmlNode GetXmlNode(string name, XmlDocument document, IDictionary<Guid, IStorable> persistedObjects) {
    278206      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);
     207      node.AppendChild(PersistenceManager.Persist("SymbolTable", symbolTable, document, persistedObjects));
    291208      return node;
    292209    }
     
    294211    public override void Populate(XmlNode node, IDictionary<Guid, IStorable> restoredObjects) {
    295212      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       }
     213      PersistenceManager.Restore(node.SelectSingleNode("SymbolTable"), restoredObjects);
    306214    }
    307215  }
  • trunk/sources/HeuristicLab.Functions/HeuristicLab.Functions.csproj

    r229 r260  
    8383    <Compile Include="Power.cs" />
    8484    <Compile Include="Division.cs" />
     85    <Compile Include="SymbolTable.cs" />
    8586    <Compile Include="Tangens.cs" />
    8687    <Compile Include="Cosinus.cs" />
Note: See TracChangeset for help on using the changeset viewer.