Ignore:
Timestamp:
02/13/18 17:56:49 (19 months ago)
Author:
lkammere
Message:

#2886: Extend grammar enumeration algorithm's grammar to exp, log and sine.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/GrammarEnumeration/Grammar.cs

    r15746 r15772  
    2020    public NonterminalSymbol Term;
    2121    public NonterminalSymbol Factor;
     22    public NonterminalSymbol LogFactor;
     23    public NonterminalSymbol ExpFactor;
     24    public NonterminalSymbol SinFactor;
     25
     26    public NonterminalSymbol SimpleExpr;
     27    public NonterminalSymbol SimpleTerm;
    2228
    2329    public TerminalSymbol Addition;
    2430    public TerminalSymbol Multiplication;
     31    public TerminalSymbol Log;
     32    public TerminalSymbol Exp;
     33    public TerminalSymbol Sin;
     34
     35    // For infix notation
     36    public TerminalSymbol OpeningBracket;
     37    public TerminalSymbol ClosingBracket;
    2538
    2639    #endregion
     
    3952    private ISymbol expSy;
    4053    private ISymbol divSy;
     54    private ISymbol sinSy;
    4155
    4256    private ISymbol rootSy;
     
    5266      Term = new NonterminalSymbol("Term");
    5367      Factor = new NonterminalSymbol("Factor");
     68      LogFactor = new NonterminalSymbol("LogFactor");
     69      ExpFactor = new NonterminalSymbol("ExpFactor");
     70      SinFactor = new NonterminalSymbol("SinFactor");
     71
     72      SimpleExpr = new NonterminalSymbol("SimpleExpr");
     73      SimpleTerm = new NonterminalSymbol("SimpleTerm");
    5474
    5575      Addition = new TerminalSymbol("+");
    5676      Multiplication = new TerminalSymbol("*");
     77      Log = new TerminalSymbol("log");
     78      Exp = new TerminalSymbol("exp");
     79      Sin = new TerminalSymbol("sin");
     80
     81      OpeningBracket = new TerminalSymbol("(");
     82      ClosingBracket = new TerminalSymbol(")");
    5783      #endregion
    5884
     
    7096
    7197      Factor.AddProduction(Var);
     98      Factor.AddProduction(LogFactor);
     99      Factor.AddProduction(ExpFactor);
     100      Factor.AddProduction(SinFactor);
     101
     102      LogFactor.AddProduction(SimpleExpr, Log);
     103      ExpFactor.AddProduction(SimpleTerm, Exp);
     104      SinFactor.AddProduction(SimpleExpr, Sin);
     105
     106      SimpleExpr.AddProduction(SimpleTerm, SimpleExpr, Addition);
     107      SimpleExpr.AddProduction(SimpleTerm);
     108
     109      SimpleTerm.AddProduction(Var, SimpleTerm, Multiplication);
     110      SimpleTerm.AddProduction(Var);
    72111      #endregion
    73112
     
    78117      constSy = symbolicExpressionGrammar.Symbols.OfType<Constant>().First();
    79118      varSy = symbolicExpressionGrammar.Symbols.OfType<Variable>().First();
    80       addSy = symbolicExpressionGrammar.AllowedSymbols.OfType<Addition>().First();
    81       mulSy = symbolicExpressionGrammar.AllowedSymbols.OfType<Multiplication>().First();
    82       logSy = symbolicExpressionGrammar.AllowedSymbols.OfType<Logarithm>().First();
    83       expSy = symbolicExpressionGrammar.AllowedSymbols.OfType<Exponential>().First();
    84       divSy = symbolicExpressionGrammar.AllowedSymbols.OfType<Division>().First();
    85 
    86       rootSy = symbolicExpressionGrammar.AllowedSymbols.OfType<ProgramRootSymbol>().First();
    87       startSy = symbolicExpressionGrammar.AllowedSymbols.OfType<StartSymbol>().First();
     119      addSy = symbolicExpressionGrammar.Symbols.OfType<Addition>().First();
     120      mulSy = symbolicExpressionGrammar.Symbols.OfType<Multiplication>().First();
     121      logSy = symbolicExpressionGrammar.Symbols.OfType<Logarithm>().First();
     122      expSy = symbolicExpressionGrammar.Symbols.OfType<Exponential>().First();
     123      divSy = symbolicExpressionGrammar.Symbols.OfType<Division>().First();
     124      sinSy = symbolicExpressionGrammar.Symbols.OfType<Sine>().First();
     125
     126      rootSy = symbolicExpressionGrammar.Symbols.OfType<ProgramRootSymbol>().First();
     127      startSy = symbolicExpressionGrammar.Symbols.OfType<StartSymbol>().First();
    88128
    89129      #endregion
     
    104144    private int[] GetSubtreeHashes(Stack<Symbol> parseStack) {
    105145      Symbol currentSymbol = parseStack.Pop();
    106 
    107       // VARIABLE
    108       // if (Var.VariableTerminalSymbols.Contains(currentSymbol)) {
    109       //   return currentSymbol.StringRepresentation.GetHashCode().ToEnumerable().ToArray();
    110       // }
    111146
    112147      // MULTIPLICATION
     
    156191      }
    157192
     193      // LOG, EXP, SIN
     194      if (ReferenceEquals(currentSymbol, Log) || ReferenceEquals(currentSymbol, Exp) ||
     195          ReferenceEquals(currentSymbol, Sin)) {
     196        return AggregateHashes(parseStack.Peek(), GetSubtreeHashes(parseStack)).ToEnumerable().ToArray();
     197      }
     198
    158199      // var or nonterminal symbol
    159200      return currentSymbol.StringRepresentation.GetHashCode().ToEnumerable().ToArray();
     
    161202
    162203    private int AggregateHashes(Symbol operatorSym, IEnumerable<int> hashes) {
    163       // If multiple subtrees are "merged" (e.g. added, multiplied, etc.), consider the executed operation
    164204      var hashesArray = hashes.ToArray();
    165       int start = hashesArray.Length > 1 ? operatorSym.StringRepresentation.GetHashCode() : 0;
     205
     206      int start;
     207      if (ReferenceEquals(operatorSym, Addition) && hashesArray.Count() <= 1) {
     208        start = 0;
     209      } else {
     210        start = operatorSym.StringRepresentation.GetHashCode();
     211      }
     212
    166213      return hashesArray.Aggregate(start, (result, ti) => ((result << 5) + result) ^ ti.GetHashCode());
    167214    }
     
    199246        parsedSubTree.AddSubtree(ParseSymbolicExpressionTree(parseStack)); // left part
    200247        parsedSubTree.AddSubtree(ParseSymbolicExpressionTree(parseStack)); // right part
     248
     249      } else if (ReferenceEquals(currentSymbol, Log)) {
     250        parsedSubTree = logSy.CreateTreeNode();
     251        parsedSubTree.AddSubtree(ParseSymbolicExpressionTree(parseStack));
     252
     253      } else if (ReferenceEquals(currentSymbol, Exp)) {
     254        parsedSubTree = expSy.CreateTreeNode();
     255        parsedSubTree.AddSubtree(ParseSymbolicExpressionTree(parseStack));
     256
     257      } else if (ReferenceEquals(currentSymbol, Sin)) {
     258        parsedSubTree = sinSy.CreateTreeNode();
     259        parsedSubTree.AddSubtree(ParseSymbolicExpressionTree(parseStack));
    201260
    202261      } else if (Var.VariableTerminalSymbols.Contains(currentSymbol)) {
     
    233292        result.Add(head);
    234293        result.AddRange(rightPart);
     294
     295      } else if (ReferenceEquals(head, Log) || ReferenceEquals(head, Exp) || ReferenceEquals(head, Sin)) {
     296        result.Add(head);
     297        result.Add(OpeningBracket);
     298        result.AddRange(PostfixToInfixSubtreeParser(parseStack));
     299        result.Add(ClosingBracket);
     300
    235301      } else {
    236302        result.Add(head);
Note: See TracChangeset for help on using the changeset viewer.