Changeset 14350


Ignore:
Timestamp:
10/23/16 09:22:49 (3 years ago)
Author:
gkronber
Message:

#2686: added support for lagged variables to infix parser and formatter

Location:
trunk/sources
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/InfixExpressionFormatter.cs

    r14347 r14350  
    110110      } else {
    111111        // no subtrees
    112         if (node.Symbol is Variable) {
     112        if (node.Symbol is LaggedVariable) {
     113          var varNode = node as LaggedVariableTreeNode;
     114          if (!varNode.Weight.IsAlmost(1.0)) {
     115            strBuilder.Append("(");
     116            strBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}", varNode.Weight);
     117            strBuilder.Append("*");
     118          }
     119          strBuilder.Append("LAG(");
     120          if (varNode.VariableName.Contains("'")) {
     121            strBuilder.AppendFormat("\"{0}\"", varNode.VariableName);
     122          } else {
     123            strBuilder.AppendFormat("'{0}'", varNode.VariableName);
     124          }
     125          strBuilder.Append(", ")
     126            .AppendFormat(CultureInfo.InvariantCulture, "{0}", varNode.Lag)
     127            .Append(")");
     128        } else if (node.Symbol is Variable) {
    113129          var varNode = node as VariableTreeNode;
    114130          if (!varNode.Weight.IsAlmost(1.0)) {
     
    130146            strBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}", constNode.Value);
    131147          else
    132             strBuilder.AppendFormat(CultureInfo.InvariantCulture, "({0})", constNode.Value);     // (-1)
     148            strBuilder.AppendFormat(CultureInfo.InvariantCulture, "({0})", constNode.Value); // (-1
    133149        }
    134150      }
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/InfixExpressionParser.cs

    r14347 r14350  
    2626using System.Text;
    2727using HeuristicLab.Collections;
     28using HeuristicLab.Common;
    2829using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
    2930
     
    109110        { "XOR", new Xor()},
    110111        { "DIFF", new Derivative()},
     112        { "LAG", new LaggedVariable() },
    111113      };
    112114
     
    333335    }
    334336
    335     // Fact = '(' Expr ')' | funcId '(' ArgList ')' | varId | number
     337    // Fact = '(' Expr ')' | 'LAG' '(' varId ',' ['+' | '-'] number ')' | funcId '(' ArgList ')' | varId | number
    336338    private ISymbolicExpressionTreeNode ParseFact(Queue<Token> tokens) {
    337339      var next = tokens.Peek();
     
    353355          if (lPar.TokenType != TokenType.LeftPar)
    354356            throw new ArgumentException("expected (");
    355           var args = ParseArgList(tokens);
    356 
    357           // check semantic constraints
    358           if (funcNode.Symbol.MinimumArity > args.Length || funcNode.Symbol.MaximumArity < args.Length)
    359             throw new ArgumentException(string.Format("Symbol {0} requires between {1} and  {2} arguments.", funcId,
    360               funcNode.Symbol.MinimumArity, funcNode.Symbol.MaximumArity));
    361           foreach (var arg in args) funcNode.AddSubtree(arg);
     357
     358          // handle 'lag' specifically
     359          if (funcNode.Symbol is LaggedVariable) {
     360            var varId = tokens.Dequeue();
     361            if (varId.TokenType != TokenType.Identifier) throw new ArgumentException("Identifier expected. Format for lagged variables: \"lag(x, -1)\"");
     362            var comma = tokens.Dequeue();
     363            if (comma.TokenType != TokenType.Comma) throw new ArgumentException("',' expected, Format for lagged variables: \"lag(x, -1)\"");
     364            double sign = 1.0;
     365            if (tokens.Peek().strVal == "+" || tokens.Peek().strVal == "-") {
     366              // read sign
     367              var signTok = tokens.Dequeue();
     368              if (signTok.strVal == "-") sign = -1.0;
     369            }
     370            var lagToken = tokens.Dequeue();
     371            if (lagToken.TokenType != TokenType.Number) throw new ArgumentException("Number expected, Format for lagged variables: \"lag(x, -1)\"");
     372            if (!lagToken.doubleVal.IsAlmost(Math.Round(lagToken.doubleVal)))
     373              throw new ArgumentException("Time lags must be integer values");
     374            var laggedVarNode = funcNode as LaggedVariableTreeNode;
     375            laggedVarNode.VariableName = varId.strVal;
     376            laggedVarNode.Lag = (int)Math.Round(sign * lagToken.doubleVal);
     377            laggedVarNode.Weight = 1.0;
     378          } else {
     379            // functions
     380            var args = ParseArgList(tokens);
     381            // check number of arguments
     382            if (funcNode.Symbol.MinimumArity > args.Length || funcNode.Symbol.MaximumArity < args.Length) {
     383              throw new ArgumentException(string.Format("Symbol {0} requires between {1} and  {2} arguments.", funcId,
     384                funcNode.Symbol.MinimumArity, funcNode.Symbol.MaximumArity));
     385            }
     386            foreach (var arg in args) funcNode.AddSubtree(arg);
     387          }
    362388
    363389          var rPar = tokens.Dequeue();
  • trunk/sources/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/InfixExpressionParserTest.cs

    r14347 r14350  
    101101      Console.WriteLine(formatter.Format(parser.Parse("IF(LT(0,1), 1 , 0)")));
    102102
     103      Console.WriteLine(formatter.Format(parser.Parse("LAG(x, 1)")));
     104      Console.WriteLine(formatter.Format(parser.Parse("LAG(x, -1)")));
     105      Console.WriteLine(formatter.Format(parser.Parse("LAG(x, +1)")));
     106      Console.WriteLine(formatter.Format(parser.Parse("x * LAG('x', +1)")));
     107
    103108    }
    104109  }
Note: See TracChangeset for help on using the changeset viewer.