Changeset 14761


Ignore:
Timestamp:
03/18/17 12:17:13 (7 months ago)
Author:
gkronber
Message:

#2650 infix formatter also produces factor variable weights, infix parser supports reading of factor variable weights

Location:
branches/symbreg-factors-2650
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • branches/symbreg-factors-2650/HeuristicLab.Algorithms.DataAnalysis/3.4/NonlinearRegression/NonlinearRegression.cs

    r14719 r14761  
    224224      foreach(var parent in tree.IterateNodesPrefix().ToArray()) {
    225225        for(int i = 0; i < parent.SubtreeCount; i++) {
    226           var child = parent.GetSubtree(i) as VariableTreeNode;
    227           if(child != null && factorSymbol.VariableNames.Contains(child.VariableName)) {
     226          var varChild = parent.GetSubtree(i) as VariableTreeNode;
     227          var factorVarChild = parent.GetSubtree(i) as FactorVariableTreeNode;
     228          if(varChild != null && factorSymbol.VariableNames.Contains(varChild.VariableName)) {
    228229            parent.RemoveSubtree(i);
    229230            var factorTreeNode = (FactorVariableTreeNode)factorSymbol.CreateTreeNode();
    230             factorTreeNode.VariableName = child.VariableName;
     231            factorTreeNode.VariableName = varChild.VariableName;
    231232            factorTreeNode.Weights =
    232               factorTreeNode.Symbol.GetVariableValues(factorTreeNode.VariableName).Select(_ => 1.0).ToArray(); // weight = 1.0 for each value
     233              factorTreeNode.Symbol.GetVariableValues(factorTreeNode.VariableName).Select(_ => 1.0).ToArray();
     234            // weight = 1.0 for each value
     235            parent.InsertSubtree(i, factorTreeNode);
     236          } else if(factorVarChild != null && factorSymbol.VariableNames.Contains(factorVarChild.VariableName)) {
     237            if(factorSymbol.GetVariableValues(factorVarChild.VariableName).Count() != factorVarChild.Weights.Length)
     238              throw new ArgumentException(
     239                string.Format("Factor variable {0} needs exactly {1} weights",
     240                factorVarChild.VariableName,
     241                factorSymbol.GetVariableValues(factorVarChild.VariableName).Count()));
     242            parent.RemoveSubtree(i);
     243            var factorTreeNode = (FactorVariableTreeNode)factorSymbol.CreateTreeNode();
     244            factorTreeNode.VariableName = factorVarChild.VariableName;
     245            factorTreeNode.Weights = factorVarChild.Weights;
    233246            parent.InsertSubtree(i, factorTreeNode);
    234247          }
  • branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/InfixExpressionFormatter.cs

    r14351 r14761  
    6060
    6161    private void FormatRecursively(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) {
    62       if (node.SubtreeCount > 1) {
     62      if(node.SubtreeCount > 1) {
    6363        var token = GetToken(node.Symbol);
    64         if (token == "+" || token == "-" || token == "OR" || token == "XOR") {
     64        if(token == "+" || token == "-" || token == "OR" || token == "XOR") {
    6565          strBuilder.Append("(");
    6666          FormatRecursively(node.Subtrees.First(), strBuilder);
    6767
    68           foreach (var subtree in node.Subtrees.Skip(1)) {
     68          foreach(var subtree in node.Subtrees.Skip(1)) {
    6969            strBuilder.Append(" ").Append(token).Append(" ");
    7070            FormatRecursively(subtree, strBuilder);
     
    7272          strBuilder.Append(")");
    7373
    74         } else if (token == "*" || token == "/" || token == "AND") {
     74        } else if(token == "*" || token == "/" || token == "AND") {
    7575          strBuilder.Append("(");
    7676          FormatRecursively(node.Subtrees.First(), strBuilder);
    7777
    78           foreach (var subtree in node.Subtrees.Skip(1)) {
     78          foreach(var subtree in node.Subtrees.Skip(1)) {
    7979            strBuilder.Append(" ").Append(token).Append(" ");
    8080            FormatRecursively(subtree, strBuilder);
     
    8585          strBuilder.Append(token).Append("(");
    8686          FormatRecursively(node.Subtrees.First(), strBuilder);
    87           foreach (var subtree in node.Subtrees.Skip(1)) {
     87          foreach(var subtree in node.Subtrees.Skip(1)) {
    8888            strBuilder.Append(", ");
    8989            FormatRecursively(subtree, strBuilder);
     
    9191          strBuilder.Append(")");
    9292        }
    93       } else if (node.SubtreeCount == 1) {
     93      } else if(node.SubtreeCount == 1) {
    9494        var token = GetToken(node.Symbol);
    95         if (token == "-" || token == "NOT") {
     95        if(token == "-" || token == "NOT") {
    9696          strBuilder.Append("(").Append(token).Append("(");
    9797          FormatRecursively(node.GetSubtree(0), strBuilder);
    9898          strBuilder.Append("))");
    99         } else if (token == "/") {
     99        } else if(token == "/") {
    100100          strBuilder.Append("1/");
    101101          FormatRecursively(node.GetSubtree(0), strBuilder);
    102         } else if (token == "+" || token == "*") {
     102        } else if(token == "+" || token == "*") {
    103103          FormatRecursively(node.GetSubtree(0), strBuilder);
    104104        } else {
     
    110110      } else {
    111111        // no subtrees
    112         if (node.Symbol is LaggedVariable) {
     112        if(node.Symbol is LaggedVariable) {
    113113          var varNode = node as LaggedVariableTreeNode;
    114           if (!varNode.Weight.IsAlmost(1.0)) {
     114          if(!varNode.Weight.IsAlmost(1.0)) {
    115115            strBuilder.Append("(");
    116116            strBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}", varNode.Weight);
     
    118118          }
    119119          strBuilder.Append("LAG(");
    120           if (varNode.VariableName.Contains("'")) {
     120          if(varNode.VariableName.Contains("'")) {
    121121            strBuilder.AppendFormat("\"{0}\"", varNode.VariableName);
    122122          } else {
     
    126126            .AppendFormat(CultureInfo.InvariantCulture, "{0}", varNode.Lag)
    127127            .Append(")");
    128         } else if (node.Symbol is Variable) {
     128        } else if(node.Symbol is Variable) {
    129129          var varNode = node as VariableTreeNode;
    130           if (!varNode.Weight.IsAlmost(1.0)) {
     130          if(!varNode.Weight.IsAlmost(1.0)) {
    131131            strBuilder.Append("(");
    132132            strBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}", varNode.Weight);
    133133            strBuilder.Append("*");
    134134          }
    135           if (varNode.VariableName.Contains("'")) {
     135          if(varNode.VariableName.Contains("'")) {
    136136            strBuilder.AppendFormat("\"{0}\"", varNode.VariableName);
    137137          } else {
    138138            strBuilder.AppendFormat("'{0}'", varNode.VariableName);
    139139          }
    140           if (!varNode.Weight.IsAlmost(1.0)) {
     140          if(!varNode.Weight.IsAlmost(1.0)) {
    141141            strBuilder.Append(")");
    142142          }
    143         } else if (node.Symbol is FactorVariable) {
     143        } else if(node.Symbol is FactorVariable) {
    144144          var factorNode = node as FactorVariableTreeNode;
    145           if (factorNode.VariableName.Contains("'")) {
     145          if(factorNode.VariableName.Contains("'")) {
    146146            strBuilder.AppendFormat("\"{0}\"", factorNode.VariableName);
    147147          } else {
    148148            strBuilder.AppendFormat("'{0}'", factorNode.VariableName);
    149149          }
    150         } else if (node.Symbol is BinaryFactorVariable) {
     150          strBuilder.AppendFormat("[{0}]",
     151            string.Join(", ", factorNode.Weights.Select(w => w.ToString(CultureInfo.InvariantCulture))));
     152        } else if(node.Symbol is BinaryFactorVariable) {
    151153          var factorNode = node as BinaryFactorVariableTreeNode;
    152           if (!factorNode.Weight.IsAlmost(1.0)) {
     154          if(!factorNode.Weight.IsAlmost(1.0)) {
    153155            strBuilder.Append("(");
    154156            strBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}", factorNode.Weight);
    155157            strBuilder.Append("*");
    156158          }
    157           if (factorNode.VariableName.Contains("'")) {
     159          if(factorNode.VariableName.Contains("'")) {
    158160            strBuilder.AppendFormat("\"{0}={1}\"", factorNode.VariableName, factorNode.VariableValue);
    159161          } else {
    160162            strBuilder.AppendFormat("'{0}={1}'", factorNode.VariableName, factorNode.VariableValue);
    161163          }
    162           if (!factorNode.Weight.IsAlmost(1.0)) {
     164          if(!factorNode.Weight.IsAlmost(1.0)) {
    163165            strBuilder.Append(")");
    164166          }
    165167
    166         } else if (node.Symbol is Constant) {
     168        } else if(node.Symbol is Constant) {
    167169          var constNode = node as ConstantTreeNode;
    168           if (constNode.Value >= 0.0)
     170          if(constNode.Value >= 0.0)
    169171            strBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}", constNode.Value);
    170172          else
     
    176178    private string GetToken(ISymbol symbol) {
    177179      var tok = InfixExpressionParser.knownSymbols.GetBySecond(symbol).SingleOrDefault();
    178       if (tok == null)
     180      if(tok == null)
    179181        throw new ArgumentException(string.Format("Unknown symbol {0} found.", symbol.Name));
    180182      return tok;
  • branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/InfixExpressionParser.cs

    r14351 r14761  
    3939  ///
    4040  ///
    41   /// S       = Expr EOF
    42   /// Expr    = ['-' | '+'] Term { '+' Term | '-' Term }
    43   /// Term    = Fact { '*' Fact | '/' Fact }
    44   /// Fact    = '(' Expr ')' | funcId '(' Expr ')' | VarExpr | number
    45   /// VarExpr = varId [ '=' varVal]
    46   /// varId   =  ident | ' ident ' | " ident "
    47   /// varVal  =  ident | ' ident ' | " ident "
    48   /// ident   =  '_' | letter { '_' | letter | digit }
     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 }
    4954  /// </summary>
    5055  public sealed class InfixExpressionParser {
    51     private enum TokenType { Operator, Identifier, Number, LeftPar, RightPar, Comma, Eq, End, NA };
     56    private enum TokenType { Operator, Identifier, Number, LeftPar, RightPar, LeftBracket, RightBracket, Comma, Eq, End, NA };
    5257    private class Token {
    5358      internal double doubleVal;
     
    7782    private Variable variable = new Variable();
    7883    private BinaryFactorVariable binaryFactorVar = new BinaryFactorVariable();
     84    private FactorVariable factorVar = new FactorVariable();
    7985
    8086    private ProgramRootSymbol programRootSymbol = new ProgramRootSymbol();
     
    126132
    127133
    128       foreach (var kvp in dict) {
     134      foreach(var kvp in dict) {
    129135        knownSymbols.Add(kvp.Key, kvp.Value);
    130136      }
     
    145151    private IEnumerable<Token> GetAllTokens(string str) {
    146152      int pos = 0;
    147       while (true) {
    148         while (pos < str.Length && Char.IsWhiteSpace(str[pos])) pos++;
    149         if (pos >= str.Length) {
     153      while(true) {
     154        while(pos < str.Length && Char.IsWhiteSpace(str[pos])) pos++;
     155        if(pos >= str.Length) {
    150156          yield return new Token { TokenType = TokenType.End, strVal = "" };
    151157          yield break;
    152158        }
    153         if (char.IsDigit(str[pos])) {
     159        if(char.IsDigit(str[pos])) {
    154160          // read number (=> read until white space or operator or comma)
    155161          var sb = new StringBuilder();
    156162          sb.Append(str[pos]);
    157163          pos++;
    158           while (pos < str.Length && !char.IsWhiteSpace(str[pos])
     164          while(pos < str.Length && !char.IsWhiteSpace(str[pos])
    159165            && (str[pos] != '+' || str[pos - 1] == 'e' || str[pos - 1] == 'E')     // continue reading exponents
    160166            && (str[pos] != '-' || str[pos - 1] == 'e' || str[pos - 1] == 'E')
     
    162168            && str[pos] != '/'
    163169            && str[pos] != ')'
     170            && str[pos] != ']'
    164171            && str[pos] != ',') {
    165172            sb.Append(str[pos]);
     
    167174          }
    168175          double dblVal;
    169           if (double.TryParse(sb.ToString(), NumberStyles.Float, CultureInfo.InvariantCulture, out dblVal))
     176          if(double.TryParse(sb.ToString(), NumberStyles.Float, CultureInfo.InvariantCulture, out dblVal))
    170177            yield return new Token { TokenType = TokenType.Number, strVal = sb.ToString(), doubleVal = dblVal };
    171178          else yield return new Token { TokenType = TokenType.NA, strVal = sb.ToString() };
    172         } else if (char.IsLetter(str[pos]) || str[pos] == '_') {
     179        } else if(char.IsLetter(str[pos]) || str[pos] == '_') {
    173180          // read ident
    174181          var sb = new StringBuilder();
    175182          sb.Append(str[pos]);
    176183          pos++;
    177           while (pos < str.Length &&
     184          while(pos < str.Length &&
    178185            (char.IsLetter(str[pos]) || str[pos] == '_' || char.IsDigit(str[pos]))) {
    179186            sb.Append(str[pos]);
     
    181188          }
    182189          yield return new Token { TokenType = TokenType.Identifier, strVal = sb.ToString() };
    183         } else if (str[pos] == '"') {
     190        } else if(str[pos] == '"') {
    184191          // read to next "
    185192          pos++;
    186193          var sb = new StringBuilder();
    187           while (pos < str.Length && str[pos] != '"') {
     194          while(pos < str.Length && str[pos] != '"') {
    188195            sb.Append(str[pos]);
    189196            pos++;
    190197          }
    191           if (pos < str.Length && str[pos] == '"') {
     198          if(pos < str.Length && str[pos] == '"') {
    192199            pos++; // skip "
    193200            yield return new Token { TokenType = TokenType.Identifier, strVal = sb.ToString() };
     
    195202            yield return new Token { TokenType = TokenType.NA };
    196203
    197         } else if (str[pos] == '\'') {
     204        } else if(str[pos] == '\'') {
    198205          // read to next '
    199206          pos++;
    200207          var sb = new StringBuilder();
    201           while (pos < str.Length && str[pos] != '\'') {
     208          while(pos < str.Length && str[pos] != '\'') {
    202209            sb.Append(str[pos]);
    203210            pos++;
    204211          }
    205           if (pos < str.Length && str[pos] == '\'') {
     212          if(pos < str.Length && str[pos] == '\'') {
    206213            pos++; // skip '
    207214            yield return new Token { TokenType = TokenType.Identifier, strVal = sb.ToString() };
    208215          } else
    209216            yield return new Token { TokenType = TokenType.NA };
    210         } else if (str[pos] == '+') {
     217        } else if(str[pos] == '+') {
    211218          pos++;
    212219          yield return new Token { TokenType = TokenType.Operator, strVal = "+" };
    213         } else if (str[pos] == '-') {
     220        } else if(str[pos] == '-') {
    214221          pos++;
    215222          yield return new Token { TokenType = TokenType.Operator, strVal = "-" };
    216         } else if (str[pos] == '/') {
     223        } else if(str[pos] == '/') {
    217224          pos++;
    218225          yield return new Token { TokenType = TokenType.Operator, strVal = "/" };
    219         } else if (str[pos] == '*') {
     226        } else if(str[pos] == '*') {
    220227          pos++;
    221228          yield return new Token { TokenType = TokenType.Operator, strVal = "*" };
    222         } else if (str[pos] == '(') {
     229        } else if(str[pos] == '(') {
    223230          pos++;
    224231          yield return new Token { TokenType = TokenType.LeftPar, strVal = "(" };
    225         } else if (str[pos] == ')') {
     232        } else if(str[pos] == ')') {
    226233          pos++;
    227234          yield return new Token { TokenType = TokenType.RightPar, strVal = ")" };
    228         } else if (str[pos] == '=') {
     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] == '=') {
    229242          pos++;
    230243          yield return new Token { TokenType = TokenType.Eq, strVal = "=" };
    231         } else if (str[pos] == ',') {
     244        } else if(str[pos] == ',') {
    232245          pos++;
    233246          yield return new Token { TokenType = TokenType.Comma, strVal = "," };
     
    237250      }
    238251    }
    239 
    240     // S       = Expr EOF
    241     // Expr    = ['-' | '+'] Term { '+' Term | '-' Term }
    242     // Term    = Fact { '*' Fact | '/' Fact }
    243     // Fact    = '(' Expr ')' | funcId '(' ArgList ')' | varId | number
    244     // ArgList = Expr { ',' Expr }
     252    /// S             = Expr EOF
    245253    private ISymbolicExpressionTreeNode ParseS(Queue<Token> tokens) {
    246254      var expr = ParseExpr(tokens);
    247255
    248256      var endTok = tokens.Dequeue();
    249       if (endTok.TokenType != TokenType.End)
     257      if(endTok.TokenType != TokenType.End)
    250258        throw new ArgumentException(string.Format("Expected end of expression (got {0})", endTok.strVal));
    251259
    252260      return expr;
    253261    }
     262
     263    /// Expr          = ['-' | '+'] Term { '+' Term | '-' Term }
    254264    private ISymbolicExpressionTreeNode ParseExpr(Queue<Token> tokens) {
    255265      var next = tokens.Peek();
     
    257267      var negTerms = new List<ISymbolicExpressionTreeNode>();
    258268      bool negateFirstTerm = false;
    259       if (next.TokenType == TokenType.Operator && (next.strVal == "+" || next.strVal == "-")) {
     269      if(next.TokenType == TokenType.Operator && (next.strVal == "+" || next.strVal == "-")) {
    260270        tokens.Dequeue();
    261         if (next.strVal == "-")
     271        if(next.strVal == "-")
    262272          negateFirstTerm = true;
    263273      }
    264274      var t = ParseTerm(tokens);
    265       if (negateFirstTerm) negTerms.Add(t);
     275      if(negateFirstTerm) negTerms.Add(t);
    266276      else posTerms.Add(t);
    267277
    268278      next = tokens.Peek();
    269       while (next.strVal == "+" || next.strVal == "-") {
    270         switch (next.strVal) {
     279      while(next.strVal == "+" || next.strVal == "-") {
     280        switch(next.strVal) {
    271281          case "+": {
    272282              tokens.Dequeue();
     
    286296
    287297      var sum = GetSymbol("+").CreateTreeNode();
    288       foreach (var posTerm in posTerms) sum.AddSubtree(posTerm);
    289       if (negTerms.Any()) {
    290         if (negTerms.Count == 1) {
     298      foreach(var posTerm in posTerms) sum.AddSubtree(posTerm);
     299      if(negTerms.Any()) {
     300        if(negTerms.Count == 1) {
    291301          var sub = GetSymbol("-").CreateTreeNode();
    292302          sub.AddSubtree(negTerms.Single());
     
    294304        } else {
    295305          var sumNeg = GetSymbol("+").CreateTreeNode();
    296           foreach (var negTerm in negTerms) sumNeg.AddSubtree(negTerm);
     306          foreach(var negTerm in negTerms) sumNeg.AddSubtree(negTerm);
    297307
    298308          var constNode = (ConstantTreeNode)constant.CreateTreeNode();
     
    305315        }
    306316      }
    307       if (sum.SubtreeCount == 1) return sum.Subtrees.First();
     317      if(sum.SubtreeCount == 1) return sum.Subtrees.First();
    308318      else return sum;
    309319    }
     
    311321    private ISymbol GetSymbol(string tok) {
    312322      var symb = knownSymbols.GetByFirst(tok).FirstOrDefault();
    313       if (symb == null) throw new ArgumentException(string.Format("Unknown token {0} found.", tok));
     323      if(symb == null) throw new ArgumentException(string.Format("Unknown token {0} found.", tok));
    314324      return symb;
    315325    }
    316326
    317     // Term = Fact { '*' Fact | '/' Fact }
     327    /// Term          = Fact { '*' Fact | '/' Fact }
    318328    private ISymbolicExpressionTreeNode ParseTerm(Queue<Token> tokens) {
    319329      var factors = new List<ISymbolicExpressionTreeNode>();
     
    322332
    323333      var next = tokens.Peek();
    324       while (next.strVal == "*" || next.strVal == "/") {
    325         switch (next.strVal) {
     334      while(next.strVal == "*" || next.strVal == "/") {
     335        switch(next.strVal) {
    326336          case "*": {
    327337              tokens.Dequeue();
     
    342352        next = tokens.Peek();
    343353      }
    344       if (factors.Count == 1) return factors.First();
     354      if(factors.Count == 1) return factors.First();
    345355      else {
    346356        var prod = GetSymbol("*").CreateTreeNode();
    347         foreach (var f in factors) prod.AddSubtree(f);
     357        foreach(var f in factors) prod.AddSubtree(f);
    348358        return prod;
    349359      }
    350360    }
    351361
    352     // Fact = '(' Expr ')' | 'LAG' '(' varId ',' ['+' | '-' ] number ')' | funcId '(' Expr ')' | varId [ = valId ] | 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 }
    353372    private ISymbolicExpressionTreeNode ParseFact(Queue<Token> tokens) {
    354373      var next = tokens.Peek();
    355       if (next.TokenType == TokenType.LeftPar) {
     374      if(next.TokenType == TokenType.LeftPar) {
    356375        tokens.Dequeue();
    357376        var expr = ParseExpr(tokens);
    358377        var rPar = tokens.Dequeue();
    359         if (rPar.TokenType != TokenType.RightPar)
     378        if(rPar.TokenType != TokenType.RightPar)
    360379          throw new ArgumentException("expected )");
    361380        return expr;
    362       } else if (next.TokenType == TokenType.Identifier) {
     381      } else if(next.TokenType == TokenType.Identifier) {
    363382        var idTok = tokens.Dequeue();
    364         if (tokens.Peek().TokenType == TokenType.LeftPar) {
    365           // function identifier
     383        if(tokens.Peek().TokenType == TokenType.LeftPar) {
     384          // function identifier or LAG
    366385          var funcId = idTok.strVal.ToUpperInvariant();
    367386
    368387          var funcNode = GetSymbol(funcId).CreateTreeNode();
    369388          var lPar = tokens.Dequeue();
    370           if (lPar.TokenType != TokenType.LeftPar)
     389          if(lPar.TokenType != TokenType.LeftPar)
    371390            throw new ArgumentException("expected (");
    372391
    373392          // handle 'lag' specifically
    374           if (funcNode.Symbol is LaggedVariable) {
     393          if(funcNode.Symbol is LaggedVariable) {
    375394            var varId = tokens.Dequeue();
    376             if (varId.TokenType != TokenType.Identifier) throw new ArgumentException("Identifier expected. Format for lagged variables: \"lag(x, -1)\"");
     395            if(varId.TokenType != TokenType.Identifier) throw new ArgumentException("Identifier expected. Format for lagged variables: \"lag(x, -1)\"");
    377396            var comma = tokens.Dequeue();
    378             if (comma.TokenType != TokenType.Comma) throw new ArgumentException("',' expected, Format for lagged variables: \"lag(x, -1)\"");
     397            if(comma.TokenType != TokenType.Comma) throw new ArgumentException("',' expected, Format for lagged variables: \"lag(x, -1)\"");
    379398            double sign = 1.0;
    380             if (tokens.Peek().strVal == "+" || tokens.Peek().strVal == "-") {
     399            if(tokens.Peek().strVal == "+" || tokens.Peek().strVal == "-") {
    381400              // read sign
    382401              var signTok = tokens.Dequeue();
    383               if (signTok.strVal == "-") sign = -1.0;
     402              if(signTok.strVal == "-") sign = -1.0;
    384403            }
    385404            var lagToken = tokens.Dequeue();
    386             if (lagToken.TokenType != TokenType.Number) throw new ArgumentException("Number expected, Format for lagged variables: \"lag(x, -1)\"");
    387             if (!lagToken.doubleVal.IsAlmost(Math.Round(lagToken.doubleVal)))
     405            if(lagToken.TokenType != TokenType.Number) throw new ArgumentException("Number expected, Format for lagged variables: \"lag(x, -1)\"");
     406            if(!lagToken.doubleVal.IsAlmost(Math.Round(lagToken.doubleVal)))
    388407              throw new ArgumentException("Time lags must be integer values");
    389408            var laggedVarNode = funcNode as LaggedVariableTreeNode;
     
    395414            var args = ParseArgList(tokens);
    396415            // check number of arguments
    397             if (funcNode.Symbol.MinimumArity > args.Length || funcNode.Symbol.MaximumArity < args.Length) {
     416            if(funcNode.Symbol.MinimumArity > args.Length || funcNode.Symbol.MaximumArity < args.Length) {
    398417              throw new ArgumentException(string.Format("Symbol {0} requires between {1} and  {2} arguments.", funcId,
    399418                funcNode.Symbol.MinimumArity, funcNode.Symbol.MaximumArity));
    400419            }
    401             foreach (var arg in args) funcNode.AddSubtree(arg);
     420            foreach(var arg in args) funcNode.AddSubtree(arg);
    402421          }
    403422
    404423          var rPar = tokens.Dequeue();
    405           if (rPar.TokenType != TokenType.RightPar)
     424          if(rPar.TokenType != TokenType.RightPar)
    406425            throw new ArgumentException("expected )");
    407426
     
    409428        } else {
    410429          // variable
    411           if (tokens.Peek().TokenType == TokenType.Eq) {
     430          if(tokens.Peek().TokenType == TokenType.Eq) {
    412431            // binary factor
    413432            tokens.Dequeue(); // skip Eq
    414433            var valTok = tokens.Dequeue();
    415             if (valTok.TokenType != TokenType.Identifier) throw new ArgumentException("expected identifier");
     434            if(valTok.TokenType != TokenType.Identifier) throw new ArgumentException("expected identifier");
    416435            var binFactorNode = (BinaryFactorVariableTreeNode)binaryFactorVar.CreateTreeNode();
    417436            binFactorNode.Weight = 1.0;
     
    419438            binFactorNode.VariableValue = valTok.strVal;
    420439            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            if(tokens.Peek().TokenType != TokenType.Number) throw new ArgumentException("number expected");
     449            var weightTok = tokens.Dequeue();
     450            weights.Add(weightTok.doubleVal);
     451            while(tokens.Peek().TokenType == TokenType.Comma) {
     452              // skip comma
     453              tokens.Dequeue();
     454              weightTok = tokens.Dequeue();
     455              if(weightTok.TokenType != TokenType.Number) throw new ArgumentException("number expected");
     456              weights.Add(weightTok.doubleVal);
     457            }
     458            var rightBracketToken = tokens.Dequeue();
     459            if(rightBracketToken.TokenType != TokenType.RightBracket) throw new ArgumentException("closing bracket ] expected");
     460            factorVariableNode.Weights = weights.ToArray();
     461            return factorVariableNode;
    421462          } else {
    422463            // variable
     
    427468          }
    428469        }
    429       } else if (next.TokenType == TokenType.Number) {
     470      } else if(next.TokenType == TokenType.Number) {
    430471        var numTok = tokens.Dequeue();
    431472        var constNode = (ConstantTreeNode)constant.CreateTreeNode();
     
    441482      var exprList = new List<ISymbolicExpressionTreeNode>();
    442483      exprList.Add(ParseExpr(tokens));
    443       while (tokens.Peek().TokenType != TokenType.RightPar) {
     484      while(tokens.Peek().TokenType != TokenType.RightPar) {
    444485        var comma = tokens.Dequeue();
    445         if (comma.TokenType != TokenType.Comma) throw new ArgumentException("expected ',' ");
     486        if(comma.TokenType != TokenType.Comma) throw new ArgumentException("expected ',' ");
    446487        exprList.Add(ParseExpr(tokens));
    447488      }
  • branches/symbreg-factors-2650/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/InfixExpressionParserTest.cs

    r14351 r14761  
    3737      Console.WriteLine(formatter.Format(parser.Parse("3*3")));
    3838      Console.WriteLine(formatter.Format(parser.Parse("3 * 4")));
    39       Console.WriteLine(formatter.Format(parser.Parse("123E-03")  ));
     39      Console.WriteLine(formatter.Format(parser.Parse("123E-03")));
    4040      Console.WriteLine(formatter.Format(parser.Parse("123e-03")));
    4141      Console.WriteLine(formatter.Format(parser.Parse("123e+03")));
     
    106106      Console.WriteLine(formatter.Format(parser.Parse("x * LAG('x', +1)")));
    107107
     108      Console.WriteLine(formatter.Format(parser.Parse("x [1.0] * y")));
     109      Console.WriteLine(formatter.Format(parser.Parse("x [1.0, 2.0] * y [1.0, 2.0]")));
     110      Console.WriteLine(formatter.Format(parser.Parse("x[1] * y")));
     111      Console.WriteLine(formatter.Format(parser.Parse("x[1, 2] * y [1, 2]")));
     112
     113      Console.WriteLine(formatter.Format(parser.Parse("x='bla' * y")));
     114      Console.WriteLine(formatter.Format(parser.Parse("x = 'bla'")));
     115      Console.WriteLine(formatter.Format(parser.Parse("x = \"bla\"")));
     116      Console.WriteLine(formatter.Format(parser.Parse("1.0 * x = bla")));
     117      Console.WriteLine(formatter.Format(parser.Parse("1.0 * \"x\" = bla + y = \"bla2\"")));
    108118    }
    109119  }
Note: See TracChangeset for help on using the changeset viewer.