Changeset 18123


Ignore:
Timestamp:
12/15/21 10:34:24 (7 months ago)
Author:
gkronber
Message:

#3140: fixed parsing of Numbers in SymbolicExpressionImporter

Location:
branches/3140_NumberSymbol
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/3140_NumberSymbol/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/SymbolicExpressionImporter.cs

    r18114 r18123  
    9797
    9898    public ISymbolicExpressionTree Import(string str) {
    99       str = str.Replace("(", " ( ").Replace(")", " ) ");
     99      str = str.Replace("(", " ( ").Replace(")", " ) ")
     100        .Replace("<", " < ").Replace(">", " > ")
     101        .Replace("=", " = ");
    100102      ISymbolicExpressionTreeNode root = programRootSymbol.CreateTreeNode();
    101103      ISymbolicExpressionTreeNode start = startSymbol.CreateTreeNode();
     
    159161        Expect(Token.RPAR, tokens);
    160162        return tree;
    161       } else if (tokens.Peek().Symbol == TokenSymbol.NUMBER) {
     163      } else if (tokens.Peek().Symbol == TokenSymbol.CONSTANT) {
    162164        var t = (INumericTreeNode)number.CreateTreeNode();
    163165        t.Value = tokens.Dequeue().DoubleValue;
     166        return t;
     167      } else if (tokens.Peek().Symbol == TokenSymbol.LBRACKET) {
     168        Expect(Token.LBRACKET, tokens);
     169        Expect(Token.NUM, tokens);
     170        var t = (INumericTreeNode)number.CreateTreeNode();
     171        if (tokens.Peek().Symbol == TokenSymbol.EQ) {
     172          Expect(Token.EQ, tokens);
     173          var initValToken = tokens.Dequeue();
     174          if(initValToken.Symbol == TokenSymbol.CONSTANT) {
     175            t.Value = initValToken.DoubleValue;
     176          } else {
     177            throw new FormatException("Expected a real value");
     178          }
     179        }
     180        Expect(Token.RBRACKET, tokens);
    164181        return t;
    165182      } else throw new FormatException("Expected function or number symbol");
     
    224241
    225242      var weights = new List<double>();
    226       while (tokens.Peek().Symbol == TokenSymbol.NUMBER) {
     243      while (tokens.Peek().Symbol == TokenSymbol.CONSTANT) {
    227244        weights.Add(tokens.Dequeue().DoubleValue);
    228245      }
     
    252269
    253270      var weightTok = tokens.Dequeue();
    254       Debug.Assert(weightTok.Symbol == TokenSymbol.NUMBER);
     271      Debug.Assert(weightTok.Symbol == TokenSymbol.CONSTANT);
    255272      t.Weight = weightTok.DoubleValue;
    256273
     
    270287
    271288    private ISymbolicExpressionTreeNode CreateTree(Token token) {
    272       if (token.Symbol != TokenSymbol.SYMB) throw new FormatException("Expected function symbol, but got: " + token.StringValue);
     289      if (token.Symbol != TokenSymbol.SYMB &&
     290          token.Symbol != TokenSymbol.LBRACKET &&  // LBRACKET and RBRACKET are used for <num=..> and as LT, GT operators
     291          token.Symbol != TokenSymbol.RBRACKET 
     292          ) throw new FormatException("Expected function symbol, but got: " + token.StringValue);
    273293      return knownSymbols[token.StringValue].CreateTreeNode();
    274294    }
  • branches/3140_NumberSymbol/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/Token.cs

    r17180 r18123  
    2323
    2424namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
    25   internal enum TokenSymbol { LPAR, RPAR, SYMB, NUMBER };
     25  internal enum TokenSymbol {
     26    LPAR, RPAR, SYMB, CONSTANT,
     27    NUM, // num
     28    EQ,  // =
     29    LBRACKET, // <
     30    RBRACKET  // >
     31  };
    2632  internal class Token {
    2733    public static readonly Token LPAR = Token.Parse("(");
    2834    public static readonly Token RPAR = Token.Parse(")");
     35    public static readonly Token LBRACKET = Token.Parse("<");
     36    public static readonly Token RBRACKET = Token.Parse(">");
     37    public static readonly Token EQ = Token.Parse("=");
     38    public static readonly Token NUM = Token.Parse("num");
    2939
    3040    public TokenSymbol Symbol { get; set; }
     
    4656    public static Token Parse(string strToken) {
    4757      strToken = strToken.Trim();
    48       Token t = new Token();
     58      var t = new Token();
    4959      t.StringValue = strToken.Trim();
    50       double temp;
    5160      if (strToken == "") {
    5261        t = null;
     
    5564      } else if (strToken == ")") {
    5665        t.Symbol = TokenSymbol.RPAR;
    57       } else if (double.TryParse(strToken, NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat, out temp)) {
    58         t.Symbol = TokenSymbol.NUMBER;
    59         t.DoubleValue = double.Parse(strToken, CultureInfo.InvariantCulture.NumberFormat);
     66      } else if (strToken == "<") {
     67        t.Symbol = TokenSymbol.LBRACKET;
     68      } else if (strToken == ">") {
     69        t.Symbol = TokenSymbol.RBRACKET;
     70      } else if (strToken == "=") {
     71        t.Symbol = TokenSymbol.EQ;
     72      } else if (strToken.ToLower() == "num") {
     73        t.Symbol = TokenSymbol.NUM;
     74      } else if (double.TryParse(strToken, NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat, out var val)) {
     75        t.Symbol = TokenSymbol.CONSTANT;
     76        t.DoubleValue = val;
    6077      } else {
    6178        t.Symbol = TokenSymbol.SYMB;
  • branches/3140_NumberSymbol/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/SymbolicDataAnalysisExpressionTreeSimplifierTest.cs

    r17820 r18123  
    230230
    231231      #region abs
    232       AssertEqualAfterSimplification("(abs 2.0)", "2.0");
    233       AssertEqualAfterSimplification("(abs -2.0)", "2.0"); // constant folding
     232      AssertEqualAfterSimplification("(abs <num=2.0>)", "2.0");
     233      AssertEqualAfterSimplification("(abs <num=-2.0>)", "2.0"); // constant folding
    234234      AssertEqualAfterSimplification("(abs (exp (variable 2.0 x)))", "(exp (variable 2.0 x)))"); // exp is always positive
    235235      AssertEqualAfterSimplification("(abs (exp (variable 2.0 x)))", "(exp (variable 2.0 x)))"); // exp is always positive
     
    238238      AssertEqualAfterSimplification("(abs (cuberoot (variable 2.0 a)))", "(cuberoot (variable 2.0 a))"); // cuberoot is always positive (for our cases)
    239239
    240       AssertEqualAfterSimplification("(* (abs (variable 2.0 x)) 2.0)", "(abs (variable 4.0 x))");  // can multiply positive constants into abs
    241       AssertEqualAfterSimplification("(* (abs (variable 2.0 x)) -2.0)", "(* (abs (variable 4.0 x)) -1.0)"); // for negative constants keep the sign
     240      AssertEqualAfterSimplification("(* (abs (variable 2.0 x)) <num=2.0>)", "(abs (variable 4.0 x))");  // can multiply positive constants into abs
     241      AssertEqualAfterSimplification("(* (abs (variable 2.0 x)) <num=-2.0>)", "(* (abs (variable 4.0 x)) -1.0)"); // for negative constants keep the sign
    242242
    243243      AssertEqualAfterSimplification("(abs (* (variable 1.0 a) (variable 2.0 b)))", "(* (abs (variable 1.0 a)) (abs (variable 1.0 b)) 2.0))");
     
    265265
    266266      #region AQ
    267       AssertEqualAfterSimplification("(* (aq (variable 1.0 x) (variable 1.0 y)) 2.0)", "(aq (variable 2.0 x) (variable 1.0 y))");
    268       AssertEqualAfterSimplification("(/ (aq (variable 1.0 x) (variable 1.0 y)) 2.0)", "(aq (variable 0.5 x) (variable 1.0 y))");
     267      AssertEqualAfterSimplification("(* (aq (variable 1.0 x) (variable 1.0 y)) <num=2.0>)", "(aq (variable 2.0 x) (variable 1.0 y))");
     268      AssertEqualAfterSimplification("(/ (aq (variable 1.0 x) (variable 1.0 y)) <num=2.0>)", "(aq (variable 0.5 x) (variable 1.0 y))");
    269269
    270270      #endregion
    271271
    272272      #region do not drop subtrees with small weights
    273       AssertEqualAfterSimplification("(* 1e-14 (variable 1.0 a))", "(variable 1e-14 a)");
    274       AssertEqualAfterSimplification("(+ (variable 1.0 a) 1e-14)",
    275                                      "(+ (variable 1.0 a) 1e-14)");
     273      AssertEqualAfterSimplification("(* <num=1e-14> (variable 1.0 a))", "(variable 1e-14 a)");
     274      AssertEqualAfterSimplification("(+ (variable 1.0 a) <num=1e-14>)",
     275                                     "(+ (variable 1.0 a) <num=1e-14>)");
    276276      // a scenario where a term with small weight can have large effect
    277       AssertEqualAfterSimplification("(+ (* (pow (variable 1.0 a) 10) 1e-14) 1.0)",
    278                                      "(+ (* (pow (variable 1.0 a) 10) 1e-14) 1.0)");
     277      AssertEqualAfterSimplification("(+ (* (pow (variable 1.0 a) <num=10>) <num=1e-14>) 1.0)",
     278                                     "(+ (* (pow (variable 1.0 a) <num=10>) <num=1e-14>) 1.0)");
    279279      // a test case (from ticket #2985)
    280       AssertEqualAfterSimplification("(+ (* (exp (variable 3.5861E+001 a)) 5.5606E-016) 5.9323E-002)",
    281                                      "(+ (* (exp (variable 3.5861E+001 a)) 5.5606E-016) 5.9323E-002)");
     280      AssertEqualAfterSimplification("(+ (* (exp (variable 3.5861E+001 a)) <num=5.5606E-016>) <num=5.9323E-002>)",
     281                                     "(+ (* (exp (variable 3.5861E+001 a)) <num=5.5606E-016>) <num=5.9323E-002>)");
    282282      #endregion
    283283    }
Note: See TracChangeset for help on using the changeset viewer.