Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
10/23/16 09:44:29 (8 years ago)
Author:
gkronber
Message:

#2650: merged r14332:14350 from trunk to branch

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

Legend:

Unmodified
Added
Removed
  • branches/symbreg-factors-2650

  • branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic

  • branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/InfixExpressionFormatter.cs

    r14251 r14351  
    8181          }
    8282          strBuilder.Append(")");
     83        } else {
     84          // function with multiple arguments
     85          strBuilder.Append(token).Append("(");
     86          FormatRecursively(node.Subtrees.First(), strBuilder);
     87          foreach (var subtree in node.Subtrees.Skip(1)) {
     88            strBuilder.Append(", ");
     89            FormatRecursively(subtree, strBuilder);
     90          }
     91          strBuilder.Append(")");
    8392        }
    8493      } else if (node.SubtreeCount == 1) {
     
    94103          FormatRecursively(node.GetSubtree(0), strBuilder);
    95104        } else {
    96           // function
     105          // function with only one argument
    97106          strBuilder.Append(token).Append("(");
    98107          FormatRecursively(node.GetSubtree(0), strBuilder);
     
    101110      } else {
    102111        // no subtrees
    103         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) {
    104129          var varNode = node as VariableTreeNode;
    105130          if (!varNode.Weight.IsAlmost(1.0)) {
     
    144169            strBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}", constNode.Value);
    145170          else
    146             strBuilder.AppendFormat(CultureInfo.InvariantCulture, "({0})", constNode.Value);     // (-1)
     171            strBuilder.AppendFormat(CultureInfo.InvariantCulture, "({0})", constNode.Value); // (-1
    147172        }
    148173      }
  • branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/InfixExpressionParser.cs

    r14330 r14351  
    2626using System.Text;
    2727using HeuristicLab.Collections;
     28using HeuristicLab.Common;
    2829using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
    2930
     
    4849  /// </summary>
    4950  public sealed class InfixExpressionParser {
    50     private enum TokenType { Operator, Identifier, Number, LeftPar, RightPar, Eq, End, NA };
     51    private enum TokenType { Operator, Identifier, Number, LeftPar, RightPar, Comma, Eq, End, NA };
    5152    private class Token {
    5253      internal double doubleVal;
     
    114115        { "MEAN", new Average()},
    115116        { "IF", new IfThenElse()},
    116         { ">", new GreaterThan()},
    117         { "<", new LessThan()},
     117        { "GT", new GreaterThan()},
     118        { "LT", new LessThan()},
    118119        { "AND", new And()},
    119120        { "OR", new Or()},
     
    121122        { "XOR", new Xor()},
    122123        { "DIFF", new Derivative()},
     124        { "LAG", new LaggedVariable() },
    123125      };
    124126
     
    150152        }
    151153        if (char.IsDigit(str[pos])) {
    152           // read number (=> read until white space or operator)
     154          // read number (=> read until white space or operator or comma)
    153155          var sb = new StringBuilder();
    154156          sb.Append(str[pos]);
     
    159161            && str[pos] != '*'
    160162            && str[pos] != '/'
    161             && str[pos] != ')') {
     163            && str[pos] != ')'
     164            && str[pos] != ',') {
    162165            sb.Append(str[pos]);
    163166            pos++;
     
    226229          pos++;
    227230          yield return new Token { TokenType = TokenType.Eq, strVal = "=" };
     231        } else if (str[pos] == ',') {
     232          pos++;
     233          yield return new Token { TokenType = TokenType.Comma, strVal = "," };
    228234        } else {
    229235          throw new ArgumentException("Invalid character: " + str[pos]);
     
    232238    }
    233239
     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 }
    234245    private ISymbolicExpressionTreeNode ParseS(Queue<Token> tokens) {
    235246      var expr = ParseExpr(tokens);
     
    339350    }
    340351
    341     // Fact = '(' Expr ')' | funcId '(' Expr ')' | varId [ = valId ] | number
     352    // Fact = '(' Expr ')' | 'LAG' '(' varId ',' ['+' | '-' ] number ')' | funcId '(' Expr ')' | varId [ = valId ] | number
    342353    private ISymbolicExpressionTreeNode ParseFact(Queue<Token> tokens) {
    343354      var next = tokens.Peek();
     
    359370          if (lPar.TokenType != TokenType.LeftPar)
    360371            throw new ArgumentException("expected (");
    361           var expr = ParseExpr(tokens);
     372
     373          // handle 'lag' specifically
     374          if (funcNode.Symbol is LaggedVariable) {
     375            var varId = tokens.Dequeue();
     376            if (varId.TokenType != TokenType.Identifier) throw new ArgumentException("Identifier expected. Format for lagged variables: \"lag(x, -1)\"");
     377            var comma = tokens.Dequeue();
     378            if (comma.TokenType != TokenType.Comma) throw new ArgumentException("',' expected, Format for lagged variables: \"lag(x, -1)\"");
     379            double sign = 1.0;
     380            if (tokens.Peek().strVal == "+" || tokens.Peek().strVal == "-") {
     381              // read sign
     382              var signTok = tokens.Dequeue();
     383              if (signTok.strVal == "-") sign = -1.0;
     384            }
     385            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)))
     388              throw new ArgumentException("Time lags must be integer values");
     389            var laggedVarNode = funcNode as LaggedVariableTreeNode;
     390            laggedVarNode.VariableName = varId.strVal;
     391            laggedVarNode.Lag = (int)Math.Round(sign * lagToken.doubleVal);
     392            laggedVarNode.Weight = 1.0;
     393          } else {
     394            // functions
     395            var args = ParseArgList(tokens);
     396            // check number of arguments
     397            if (funcNode.Symbol.MinimumArity > args.Length || funcNode.Symbol.MaximumArity < args.Length) {
     398              throw new ArgumentException(string.Format("Symbol {0} requires between {1} and  {2} arguments.", funcId,
     399                funcNode.Symbol.MinimumArity, funcNode.Symbol.MaximumArity));
     400            }
     401            foreach (var arg in args) funcNode.AddSubtree(arg);
     402          }
     403
    362404          var rPar = tokens.Dequeue();
    363405          if (rPar.TokenType != TokenType.RightPar)
    364406            throw new ArgumentException("expected )");
    365407
    366           funcNode.AddSubtree(expr);
    367408          return funcNode;
    368409        } else {
     
    396437    }
    397438
     439    // ArgList = Expr { ',' Expr }
     440    private ISymbolicExpressionTreeNode[] ParseArgList(Queue<Token> tokens) {
     441      var exprList = new List<ISymbolicExpressionTreeNode>();
     442      exprList.Add(ParseExpr(tokens));
     443      while (tokens.Peek().TokenType != TokenType.RightPar) {
     444        var comma = tokens.Dequeue();
     445        if (comma.TokenType != TokenType.Comma) throw new ArgumentException("expected ',' ");
     446        exprList.Add(ParseExpr(tokens));
     447      }
     448      return exprList.ToArray();
     449    }
    398450  }
    399451}
  • branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionCompiledTreeInterpreter.cs

    r14185 r14351  
    614614        case OpCodes.VariableCondition: {
    615615            var variableConditionTreeNode = (VariableConditionTreeNode)node;
     616            if (variableConditionTreeNode.Symbol.IgnoreSlope) throw new NotSupportedException("Strict variable conditionals are not supported");
    616617            var variableName = variableConditionTreeNode.VariableName;
    617618            var indexExpr = Expression.Constant(variableIndices[variableName]);
  • branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeInterpreter.cs

    r14251 r14351  
    488488            if (row < 0 || row >= dataset.Rows) return double.NaN;
    489489            var variableConditionTreeNode = (VariableConditionTreeNode)currentInstr.dynamicNode;
    490             double variableValue = ((IList<double>)currentInstr.data)[row];
    491             double x = variableValue - variableConditionTreeNode.Threshold;
    492             double p = 1 / (1 + Math.Exp(-variableConditionTreeNode.Slope * x));
    493 
    494             double trueBranch = Evaluate(dataset, ref row, state);
    495             double falseBranch = Evaluate(dataset, ref row, state);
    496 
    497             return trueBranch * p + falseBranch * (1 - p);
     490            if (!variableConditionTreeNode.Symbol.IgnoreSlope) {
     491              double variableValue = ((IList<double>)currentInstr.data)[row];
     492              double x = variableValue - variableConditionTreeNode.Threshold;
     493              double p = 1 / (1 + Math.Exp(-variableConditionTreeNode.Slope * x));
     494
     495              double trueBranch = Evaluate(dataset, ref row, state);
     496              double falseBranch = Evaluate(dataset, ref row, state);
     497
     498              return trueBranch * p + falseBranch * (1 - p);
     499            } else {
     500              // strict threshold
     501              double variableValue = ((IList<double>)currentInstr.data)[row];
     502              if (variableValue <= variableConditionTreeNode.Threshold) {
     503                var left = Evaluate(dataset, ref row, state);
     504                state.SkipInstructions();
     505                return left;
     506              } else {
     507                state.SkipInstructions();
     508                return Evaluate(dataset, ref row, state);
     509              }
     510            }
    498511          }
    499512        default:
  • branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeLinearInterpreter.cs

    r14330 r14351  
    126126    private readonly object syncRoot = new object();
    127127    public IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, IDataset dataset, IEnumerable<int> rows) {
     128      if (!rows.Any()) return Enumerable.Empty<double>();
    128129      if (CheckExpressionsWithIntervalArithmetic)
    129130        throw new NotSupportedException("Interval arithmetic is not yet supported in the symbolic data analysis interpreter.");
     
    171172          if (row < 0 || row >= dataset.Rows) instr.value = double.NaN;
    172173          var variableConditionTreeNode = (VariableConditionTreeNode)instr.dynamicNode;
    173           double variableValue = ((IList<double>)instr.data)[row];
    174           double x = variableValue - variableConditionTreeNode.Threshold;
    175           double p = 1 / (1 + Math.Exp(-variableConditionTreeNode.Slope * x));
    176 
    177           double trueBranch = code[instr.childIndex].value;
    178           double falseBranch = code[instr.childIndex + 1].value;
    179 
    180           instr.value = trueBranch * p + falseBranch * (1 - p);
     174          if (!variableConditionTreeNode.Symbol.IgnoreSlope) {
     175            double variableValue = ((IList<double>)instr.data)[row];
     176            double x = variableValue - variableConditionTreeNode.Threshold;
     177            double p = 1 / (1 + Math.Exp(-variableConditionTreeNode.Slope * x));
     178
     179            double trueBranch = code[instr.childIndex].value;
     180            double falseBranch = code[instr.childIndex + 1].value;
     181
     182            instr.value = trueBranch * p + falseBranch * (1 - p);
     183          } else {
     184            double variableValue = ((IList<double>)instr.data)[row];
     185            if (variableValue <= variableConditionTreeNode.Threshold) {
     186              instr.value = code[instr.childIndex].value;
     187            } else {
     188              instr.value = code[instr.childIndex + 1].value;
     189            }
     190          }
    181191        } else if (instr.opCode == OpCodes.Add) {
    182192          double s = code[instr.childIndex].value;
     
    433443              for (int j = 1; j != seq.Length; ++j)
    434444                seq[j].skip = true;
    435             }
    436             break;
     445              break;
     446            }
    437447        }
    438448        #endregion
  • branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/VariableCondition.cs

    r14238 r14351  
    149149        }
    150150      }
     151    }
     152
     153    /// <summary>
     154    /// Flag to indicate if the interpreter should ignore the slope parameter (introduced for representation of expression trees)
     155    /// </summary>
     156    [Storable]
     157    private bool ignoreSlope;
     158    public bool IgnoreSlope {
     159      get { return ignoreSlope; }
     160      set { ignoreSlope = value; }
    151161    }
    152162
  • branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/VariableConditionTreeNode.cs

    r14238 r14351  
    9696
    9797    public override string ToString() {
    98       if (slope.IsAlmost(0.0))
     98      if (slope.IsAlmost(0.0) || Symbol.IgnoreSlope) {
     99        return variableName + " < " + threshold.ToString("E4");
     100      } else {
    99101        return variableName + " > " + threshold.ToString("E4") + Environment.NewLine +
    100           "slope: " + slope.ToString("E4");
    101       else
    102         return variableName + " > " + threshold.ToString("E4");
     102               "slope: " + slope.ToString("E4");
     103      }
    103104    }
    104105  }
Note: See TracChangeset for help on using the changeset viewer.