Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
01/15/17 14:17:06 (8 years ago)
Author:
bburlacu
Message:

#1772: Merge trunk changes.

Location:
branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic
Files:
8 edited
2 copied

Legend:

Unmodified
Added
Removed
  • branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic

  • branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/InfixExpressionFormatter.cs

    r14307 r14576  
    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)) {
     
    121146            strBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}", constNode.Value);
    122147          else
    123             strBuilder.AppendFormat(CultureInfo.InvariantCulture, "({0})", constNode.Value);     // (-1)
     148            strBuilder.AppendFormat(CultureInfo.InvariantCulture, "({0})", constNode.Value); // (-1
    124149        }
    125150      }
  • branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionLatexFormatter.cs

    r14312 r14576  
    6767        strBuilder.AppendLine(FormatRecursively(symbolicExpressionTree.Root));
    6868        return strBuilder.ToString();
    69       }
    70       catch (NotImplementedException ex) {
     69      } catch (NotImplementedException ex) {
    7170        return ex.Message + Environment.NewLine + ex.StackTrace;
    7271      }
     
    109108      } else if (node.Symbol is Division) {
    110109        if (node.SubtreeCount == 1) {
    111           strBuilder.Append(@" \cfrac{1");
     110          strBuilder.Append(@" \cfrac{1}{");
    112111        } else {
    113112          strBuilder.Append(@" \cfrac{ ");
     
    176175        strBuilder.Append(@" \operatorname{if}  \left( ");
    177176      } else if (node.Symbol is Constant) {
    178         strBuilder.Append("c_{" + constants.Count + "} ");
    179177        var constNode = node as ConstantTreeNode;
    180         constants.Add(constNode.Value);
     178        if (constNode.Value.IsAlmost(1.0)) {
     179          strBuilder.Append("1 ");
     180        } else {
     181          strBuilder.Append("c_{" + constants.Count + "} ");
     182          constants.Add(constNode.Value);
     183        }
    181184      } else if (node.Symbol is LaggedVariable) {
    182185        var laggedVarNode = node as LaggedVariableTreeNode;
  • branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/InfixExpressionParser.cs

    r14307 r14576  
    2626using System.Text;
    2727using HeuristicLab.Collections;
     28using HeuristicLab.Common;
    2829using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
    2930
     
    3738  /// </summary>
    3839  public sealed class InfixExpressionParser {
    39     private enum TokenType { Operator, Identifier, Number, LeftPar, RightPar, End, NA };
     40    private enum TokenType { Operator, Identifier, Number, LeftPar, RightPar, Comma, End, NA };
    4041    private class Token {
    4142      internal double doubleVal;
     
    102103        { "MEAN", new Average()},
    103104        { "IF", new IfThenElse()},
    104         { ">", new GreaterThan()},
    105         { "<", new LessThan()},
     105        { "GT", new GreaterThan()},
     106        { "LT", new LessThan()},
    106107        { "AND", new And()},
    107108        { "OR", new Or()},
     
    109110        { "XOR", new Xor()},
    110111        { "DIFF", new Derivative()},
     112        { "LAG", new LaggedVariable() },
    111113      };
    112114
     
    138140        }
    139141        if (char.IsDigit(str[pos])) {
    140           // read number (=> read until white space or operator)
     142          // read number (=> read until white space or operator or comma)
    141143          var sb = new StringBuilder();
    142144          sb.Append(str[pos]);
    143145          pos++;
    144146          while (pos < str.Length && !char.IsWhiteSpace(str[pos])
    145             && (str[pos] != '+' || str[pos-1] == 'e' || str[pos-1] == 'E')     // continue reading exponents
     147            && (str[pos] != '+' || str[pos - 1] == 'e' || str[pos - 1] == 'E')     // continue reading exponents
    146148            && (str[pos] != '-' || str[pos - 1] == 'e' || str[pos - 1] == 'E')
    147             && str[pos] != '*'           
     149            && str[pos] != '*'
    148150            && str[pos] != '/'
    149             && str[pos] != ')') {
     151            && str[pos] != ')'
     152            && str[pos] != ',') {
    150153            sb.Append(str[pos]);
    151154            pos++;
     
    211214          pos++;
    212215          yield return new Token { TokenType = TokenType.RightPar, strVal = ")" };
    213         }
    214       }
    215     }
    216 
    217     // S = Expr EOF
    218     // Expr = ['-' | '+'] Term { '+' Term | '-' Term }
    219     // Term = Fact { '*' Fact | '/' Fact }
    220     // Fact = '(' Expr ')' | funcId '(' Expr ')' | varId | number
     216        } else if (str[pos] == ',') {
     217          pos++;
     218          yield return new Token { TokenType = TokenType.Comma, strVal = "," };
     219        } else {
     220          throw new ArgumentException("Invalid character: " + str[pos]);
     221        }
     222      }
     223    }
     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 }
    221230    private ISymbolicExpressionTreeNode ParseS(Queue<Token> tokens) {
    222231      var expr = ParseExpr(tokens);
     
    326335    }
    327336
    328     // Fact = '(' Expr ')' | funcId '(' Expr ')' | varId | number
     337    // Fact = '(' Expr ')' | 'LAG' '(' varId ',' ['+' | '-'] number ')' | funcId '(' ArgList ')' | varId | number
    329338    private ISymbolicExpressionTreeNode ParseFact(Queue<Token> tokens) {
    330339      var next = tokens.Peek();
     
    346355          if (lPar.TokenType != TokenType.LeftPar)
    347356            throw new ArgumentException("expected (");
    348           var expr = ParseExpr(tokens);
     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          }
     388
    349389          var rPar = tokens.Dequeue();
    350390          if (rPar.TokenType != TokenType.RightPar)
    351391            throw new ArgumentException("expected )");
    352392
    353           funcNode.AddSubtree(expr);
    354393          return funcNode;
    355394        } else {
     
    369408      }
    370409    }
     410
     411    // ArgList = Expr { ',' Expr }
     412    private ISymbolicExpressionTreeNode[] ParseArgList(Queue<Token> tokens) {
     413      var exprList = new List<ISymbolicExpressionTreeNode>();
     414      exprList.Add(ParseExpr(tokens));
     415      while (tokens.Peek().TokenType != TokenType.RightPar) {
     416        var comma = tokens.Dequeue();
     417        if (comma.TokenType != TokenType.Comma) throw new ArgumentException("expected ',' ");
     418        exprList.Add(ParseExpr(tokens));
     419      }
     420      return exprList.ToArray();
     421    }
    371422  }
    372423}
  • branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/SymbolicExpressionImporter.cs

    r14312 r14576  
    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()},
  • branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionCompiledTreeInterpreter.cs

    r14312 r14576  
    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/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeInterpreter.cs

    r14312 r14576  
    471471            if (row < 0 || row >= dataset.Rows) return double.NaN;
    472472            var variableConditionTreeNode = (VariableConditionTreeNode)currentInstr.dynamicNode;
    473             double variableValue = ((IList<double>)currentInstr.data)[row];
    474             double x = variableValue - variableConditionTreeNode.Threshold;
    475             double p = 1 / (1 + Math.Exp(-variableConditionTreeNode.Slope * x));
    476 
    477             double trueBranch = Evaluate(dataset, ref row, state);
    478             double falseBranch = Evaluate(dataset, ref row, state);
    479 
    480             return trueBranch * p + falseBranch * (1 - p);
     473            if (!variableConditionTreeNode.Symbol.IgnoreSlope) {
     474              double variableValue = ((IList<double>)currentInstr.data)[row];
     475              double x = variableValue - variableConditionTreeNode.Threshold;
     476              double p = 1 / (1 + Math.Exp(-variableConditionTreeNode.Slope * x));
     477
     478              double trueBranch = Evaluate(dataset, ref row, state);
     479              double falseBranch = Evaluate(dataset, ref row, state);
     480
     481              return trueBranch * p + falseBranch * (1 - p);
     482            } else {
     483              // strict threshold
     484              double variableValue = ((IList<double>)currentInstr.data)[row];
     485              if (variableValue <= variableConditionTreeNode.Threshold) {
     486                var left = Evaluate(dataset, ref row, state);
     487                state.SkipInstructions();
     488                return left;
     489              } else {
     490                state.SkipInstructions();
     491                return Evaluate(dataset, ref row, state);
     492              }
     493            }
    481494          }
    482495        default:
  • branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeLinearInterpreter.cs

    r14312 r14576  
    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.");
     
    166167          if (row < 0 || row >= dataset.Rows) instr.value = double.NaN;
    167168          var variableConditionTreeNode = (VariableConditionTreeNode)instr.dynamicNode;
    168           double variableValue = ((IList<double>)instr.data)[row];
    169           double x = variableValue - variableConditionTreeNode.Threshold;
    170           double p = 1 / (1 + Math.Exp(-variableConditionTreeNode.Slope * x));
    171 
    172           double trueBranch = code[instr.childIndex].value;
    173           double falseBranch = code[instr.childIndex + 1].value;
    174 
    175           instr.value = trueBranch * p + falseBranch * (1 - p);
     169          if (!variableConditionTreeNode.Symbol.IgnoreSlope) {
     170            double variableValue = ((IList<double>)instr.data)[row];
     171            double x = variableValue - variableConditionTreeNode.Threshold;
     172            double p = 1 / (1 + Math.Exp(-variableConditionTreeNode.Slope * x));
     173
     174            double trueBranch = code[instr.childIndex].value;
     175            double falseBranch = code[instr.childIndex + 1].value;
     176
     177            instr.value = trueBranch * p + falseBranch * (1 - p);
     178          } else {
     179            double variableValue = ((IList<double>)instr.data)[row];
     180            if (variableValue <= variableConditionTreeNode.Threshold) {
     181              instr.value = code[instr.childIndex].value;
     182            } else {
     183              instr.value = code[instr.childIndex + 1].value;
     184            }
     185          }
    176186        } else if (instr.opCode == OpCodes.Add) {
    177187          double s = code[instr.childIndex].value;
     
    420430              for (int j = 1; j != seq.Length; ++j)
    421431                seq[j].skip = true;
    422             }
    423             break;
     432              break;
     433            }
    424434        }
    425435        #endregion
  • branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/VariableCondition.cs

    r14312 r14576  
    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/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/VariableConditionTreeNode.cs

    r14312 r14576  
    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.