Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
04/04/17 17:52:44 (8 years ago)
Author:
gkronber
Message:

#2650: merged the factors branch into trunk

Location:
trunk/sources
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources

  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic

  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/InfixExpressionParser.cs

    r14350 r14826  
    3333  /// Parses mathematical expressions in infix form. E.g. x1 * (3.0 * x2 + x3)
    3434  /// Identifier format (functions or variables): '_' | letter { '_' | letter | digit }
    35   /// Variables names can be set under quotes "" or '' because variable names might contain spaces.
     35  /// Variables names and variable values can be set under quotes "" or '' because variable names might contain spaces.
     36  ///   Variable = ident | " ident " | ' ident '
    3637  /// It is also possible to use functions e.g. log("x1") or real-valued constants e.g. 3.1415 .
    3738  /// Variable names are case sensitive. Function names are not case sensitive.
     39  ///
     40  ///
     41  /// S             = Expr EOF
     42  /// Expr          = ['-' | '+'] Term { '+' Term | '-' Term }
     43  /// Term          = Fact { '*' Fact | '/' Fact }
     44  /// Fact          = '(' Expr ')'
     45  ///                 | 'LAG' '(' varId ',' ['+' | '-' ] number ')'
     46  ///                 | funcId '(' ArgList ')'
     47  ///                 | VarExpr | number
     48  /// ArgList       = Expr { ',' Expr }
     49  /// VarExpr       = varId OptFactorPart
     50  /// OptFactorPart = [ ('=' varVal | '[' ['+' | '-' ] number {',' ['+' | '-' ] number } ']' ) ]
     51  /// varId         =  ident | ' ident ' | " ident "
     52  /// varVal        =  ident | ' ident ' | " ident "
     53  /// ident         =  '_' | letter { '_' | letter | digit }
    3854  /// </summary>
    3955  public sealed class InfixExpressionParser {
    40     private enum TokenType { Operator, Identifier, Number, LeftPar, RightPar, Comma, End, NA };
     56    private enum TokenType { Operator, Identifier, Number, LeftPar, RightPar, LeftBracket, RightBracket, Comma, Eq, End, NA };
    4157    private class Token {
    4258      internal double doubleVal;
     
    6581    private Constant constant = new Constant();
    6682    private Variable variable = new Variable();
     83    private BinaryFactorVariable binaryFactorVar = new BinaryFactorVariable();
     84    private FactorVariable factorVar = new FactorVariable();
    6785
    6886    private ProgramRootSymbol programRootSymbol = new ProgramRootSymbol();
     
    150168            && str[pos] != '/'
    151169            && str[pos] != ')'
     170            && str[pos] != ']'
    152171            && str[pos] != ',') {
    153172            sb.Append(str[pos]);
     
    214233          pos++;
    215234          yield return new Token { TokenType = TokenType.RightPar, strVal = ")" };
     235        } else if (str[pos] == '[') {
     236          pos++;
     237          yield return new Token { TokenType = TokenType.LeftBracket, strVal = "[" };
     238        } else if (str[pos] == ']') {
     239          pos++;
     240          yield return new Token { TokenType = TokenType.RightBracket, strVal = "]" };
     241        } else if (str[pos] == '=') {
     242          pos++;
     243          yield return new Token { TokenType = TokenType.Eq, strVal = "=" };
    216244        } else if (str[pos] == ',') {
    217245          pos++;
     
    222250      }
    223251    }
    224 
    225     // S       = Expr EOF
    226     // Expr    = ['-' | '+'] Term { '+' Term | '-' Term }
    227     // Term    = Fact { '*' Fact | '/' Fact }
    228     // Fact    = '(' Expr ')' | funcId '(' ArgList ')' | varId | number
    229     // ArgList = Expr { ',' Expr }
     252    /// S             = Expr EOF
    230253    private ISymbolicExpressionTreeNode ParseS(Queue<Token> tokens) {
    231254      var expr = ParseExpr(tokens);
     
    237260      return expr;
    238261    }
     262
     263    /// Expr          = ['-' | '+'] Term { '+' Term | '-' Term }
    239264    private ISymbolicExpressionTreeNode ParseExpr(Queue<Token> tokens) {
    240265      var next = tokens.Peek();
     
    300325    }
    301326
    302     // Term = Fact { '*' Fact | '/' Fact }
     327    /// Term          = Fact { '*' Fact | '/' Fact }
    303328    private ISymbolicExpressionTreeNode ParseTerm(Queue<Token> tokens) {
    304329      var factors = new List<ISymbolicExpressionTreeNode>();
     
    335360    }
    336361
    337     // Fact = '(' Expr ')' | 'LAG' '(' varId ',' ['+' | '-'] number ')' | funcId '(' ArgList ')' | varId | number
     362    /// Fact          = '(' Expr ')'
     363    ///                 | 'LAG' '(' varId ',' ['+' | '-' ] number ')'
     364    ///                 | funcId '(' ArgList ')'
     365    ///                 | VarExpr | number
     366    /// ArgList       = Expr { ',' Expr }
     367    /// VarExpr       = varId OptFactorPart
     368    /// OptFactorPart = [ ('=' varVal | '[' ['+' | '-' ] number {',' ['+' | '-' ] number } ']' ) ]
     369    /// varId         =  ident | ' ident ' | " ident "
     370    /// varVal        =  ident | ' ident ' | " ident "
     371    /// ident         =  '_' | letter { '_' | letter | digit }
    338372    private ISymbolicExpressionTreeNode ParseFact(Queue<Token> tokens) {
    339373      var next = tokens.Peek();
     
    348382        var idTok = tokens.Dequeue();
    349383        if (tokens.Peek().TokenType == TokenType.LeftPar) {
    350           // function identifier
     384          // function identifier or LAG
    351385          var funcId = idTok.strVal.ToUpperInvariant();
    352386
     
    394428        } else {
    395429          // variable
    396           var varNode = (VariableTreeNode)variable.CreateTreeNode();
    397           varNode.Weight = 1.0;
    398           varNode.VariableName = idTok.strVal;
    399           return varNode;
     430          if (tokens.Peek().TokenType == TokenType.Eq) {
     431            // binary factor
     432            tokens.Dequeue(); // skip Eq
     433            var valTok = tokens.Dequeue();
     434            if (valTok.TokenType != TokenType.Identifier) throw new ArgumentException("expected identifier");
     435            var binFactorNode = (BinaryFactorVariableTreeNode)binaryFactorVar.CreateTreeNode();
     436            binFactorNode.Weight = 1.0;
     437            binFactorNode.VariableName = idTok.strVal;
     438            binFactorNode.VariableValue = valTok.strVal;
     439            return binFactorNode;
     440          } else if (tokens.Peek().TokenType == TokenType.LeftBracket) {
     441            // factor variable
     442            var factorVariableNode = (FactorVariableTreeNode)factorVar.CreateTreeNode();
     443            factorVariableNode.VariableName = idTok.strVal;
     444
     445            tokens.Dequeue(); // skip [
     446            var weights = new List<double>();
     447            // at least one weight is necessary
     448            var sign = 1.0;
     449            if (tokens.Peek().TokenType == TokenType.Operator) {
     450              var opToken = tokens.Dequeue();
     451              if (opToken.strVal == "+") sign = 1.0;
     452              else if (opToken.strVal == "-") sign = -1.0;
     453              else throw new ArgumentException();
     454            }
     455            if (tokens.Peek().TokenType != TokenType.Number) throw new ArgumentException("number expected");
     456            var weightTok = tokens.Dequeue();
     457            weights.Add(sign * weightTok.doubleVal);
     458            while (tokens.Peek().TokenType == TokenType.Comma) {
     459              // skip comma
     460              tokens.Dequeue();
     461              if (tokens.Peek().TokenType == TokenType.Operator) {
     462                var opToken = tokens.Dequeue();
     463                if (opToken.strVal == "+") sign = 1.0;
     464                else if (opToken.strVal == "-") sign = -1.0;
     465                else throw new ArgumentException();
     466              }
     467              weightTok = tokens.Dequeue();
     468              if (weightTok.TokenType != TokenType.Number) throw new ArgumentException("number expected");
     469              weights.Add(sign * weightTok.doubleVal);
     470            }
     471            var rightBracketToken = tokens.Dequeue();
     472            if (rightBracketToken.TokenType != TokenType.RightBracket) throw new ArgumentException("closing bracket ] expected");
     473            factorVariableNode.Weights = weights.ToArray();
     474            return factorVariableNode;
     475          } else {
     476            // variable
     477            var varNode = (VariableTreeNode)variable.CreateTreeNode();
     478            varNode.Weight = 1.0;
     479            varNode.VariableName = idTok.strVal;
     480            return varNode;
     481          }
    400482        }
    401483      } else if (next.TokenType == TokenType.Number) {
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/SymbolicExpressionImporter.cs

    r14185 r14826  
    3535    private const string INVOKESTART = "CALL";
    3636    private const string TIMELAGSTART = "LAG";
    37     private Dictionary<string, Symbol> knownSymbols = new Dictionary<string, Symbol>() 
     37    private Dictionary<string, Symbol> knownSymbols = new Dictionary<string, Symbol>()
    3838      {
    3939        {"+", new Addition()},
     
    4545        {"POW", new Power()},
    4646        {"ROOT", new Root()},
     47        {"SQR", new Square()},
     48        {"SQRT", new SquareRoot()},
    4749        {"SIN",new Sine()},
    4850        {"COS", new Cosine()},
     
    7476        {"PROG", new ProgramRootSymbol()},
    7577        {"MAIN", new StartSymbol()},
     78        {"FACTOR", new FactorVariable() },
     79        {"BINFACTOR", new BinaryFactorVariable()}
    7680      };
    7781
     
    8286    TimeLag timeLag = new TimeLag();
    8387    Integral integral = new Integral();
     88    FactorVariable factorVar = new FactorVariable();
     89    BinaryFactorVariable binFactorVar = new BinaryFactorVariable();
    8490
    8591    ProgramRootSymbol programRootSymbol = new ProgramRootSymbol();
     
    136142            tree.AddSubtree(ParseSexp(tokens));
    137143          }
     144        } else if (tokens.Peek().StringValue.StartsWith("FACTOR")) {
     145          tree = ParseFactor(tokens);
     146        } else if (tokens.Peek().StringValue.StartsWith("BINFACTOR")) {
     147          tree = ParseBinaryFactor(tokens);
    138148        } else {
    139149          Token curToken = tokens.Dequeue();
     
    201211    }
    202212
     213    private ISymbolicExpressionTreeNode ParseFactor(Queue<Token> tokens) {
     214      Token tok = tokens.Dequeue();
     215      Debug.Assert(tok.StringValue == "FACTOR");
     216      FactorVariableTreeNode t = (FactorVariableTreeNode)(new FactorVariable()).CreateTreeNode(); // create a new symbol each time on purpose
     217      var varNameTok = tokens.Dequeue();
     218      Debug.Assert(tok.Symbol == TokenSymbol.SYMB);
     219      t.VariableName = varNameTok.StringValue;
     220
     221      var weights = new List<double>();
     222      while (tokens.Peek().Symbol == TokenSymbol.NUMBER) {
     223        weights.Add(tokens.Dequeue().DoubleValue);
     224      }
     225
     226      t.Weights = weights.ToArray();
     227
     228      // create a set of (virtual) values to match the number of weights
     229      t.Symbol.VariableNames = new string[] { t.VariableName };
     230      t.Symbol.VariableValues = new[]
     231      { new KeyValuePair<string, Dictionary<string,int>>(
     232        t.VariableName,
     233        weights.Select((_, i) => Tuple.Create(_,i)).ToDictionary(tup=>"X" + tup.Item2, tup=>tup.Item2)) };
     234      return t;
     235    }
     236
     237    private ISymbolicExpressionTreeNode ParseBinaryFactor(Queue<Token> tokens) {
     238      Token tok = tokens.Dequeue();
     239      Debug.Assert(tok.StringValue == "BINFACTOR");
     240      var t = (BinaryFactorVariableTreeNode)binFactorVar.CreateTreeNode();
     241      var varNameTok = tokens.Dequeue();
     242      Debug.Assert(varNameTok.Symbol == TokenSymbol.SYMB);
     243      t.VariableName = varNameTok.StringValue;
     244
     245      var varValTok = tokens.Dequeue();
     246      Debug.Assert(varValTok.Symbol == TokenSymbol.SYMB);
     247      t.VariableValue = varValTok.StringValue;
     248
     249      var weightTok = tokens.Dequeue();
     250      Debug.Assert(weightTok.Symbol == TokenSymbol.NUMBER);
     251      t.Weight = weightTok.DoubleValue;
     252
     253      return t;
     254    }
     255
     256
    203257    private ISymbolicExpressionTreeNode ParseLaggedVariable(Queue<Token> tokens) {
    204258      Token varTok = tokens.Dequeue();
Note: See TracChangeset for help on using the changeset viewer.