- Timestamp:
- 10/23/16 09:44:29 (8 years ago)
- Location:
- branches/symbreg-factors-2650
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/symbreg-factors-2650
- Property svn:mergeinfo changed
/trunk/sources merged: 14332,14340-14350
- Property svn:mergeinfo changed
-
branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic
- Property svn:mergeinfo changed
/trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic merged: 14345,14347,14350
- Property svn:mergeinfo changed
-
branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/InfixExpressionFormatter.cs
r14251 r14351 81 81 } 82 82 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(")"); 83 92 } 84 93 } else if (node.SubtreeCount == 1) { … … 94 103 FormatRecursively(node.GetSubtree(0), strBuilder); 95 104 } else { 96 // function 105 // function with only one argument 97 106 strBuilder.Append(token).Append("("); 98 107 FormatRecursively(node.GetSubtree(0), strBuilder); … … 101 110 } else { 102 111 // 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) { 104 129 var varNode = node as VariableTreeNode; 105 130 if (!varNode.Weight.IsAlmost(1.0)) { … … 144 169 strBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}", constNode.Value); 145 170 else 146 strBuilder.AppendFormat(CultureInfo.InvariantCulture, "({0})", constNode.Value); // (-1)171 strBuilder.AppendFormat(CultureInfo.InvariantCulture, "({0})", constNode.Value); // (-1 147 172 } 148 173 } -
branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/InfixExpressionParser.cs
r14330 r14351 26 26 using System.Text; 27 27 using HeuristicLab.Collections; 28 using HeuristicLab.Common; 28 29 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; 29 30 … … 48 49 /// </summary> 49 50 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 }; 51 52 private class Token { 52 53 internal double doubleVal; … … 114 115 { "MEAN", new Average()}, 115 116 { "IF", new IfThenElse()}, 116 { " >", new GreaterThan()},117 { " <", new LessThan()},117 { "GT", new GreaterThan()}, 118 { "LT", new LessThan()}, 118 119 { "AND", new And()}, 119 120 { "OR", new Or()}, … … 121 122 { "XOR", new Xor()}, 122 123 { "DIFF", new Derivative()}, 124 { "LAG", new LaggedVariable() }, 123 125 }; 124 126 … … 150 152 } 151 153 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) 153 155 var sb = new StringBuilder(); 154 156 sb.Append(str[pos]); … … 159 161 && str[pos] != '*' 160 162 && str[pos] != '/' 161 && str[pos] != ')') { 163 && str[pos] != ')' 164 && str[pos] != ',') { 162 165 sb.Append(str[pos]); 163 166 pos++; … … 226 229 pos++; 227 230 yield return new Token { TokenType = TokenType.Eq, strVal = "=" }; 231 } else if (str[pos] == ',') { 232 pos++; 233 yield return new Token { TokenType = TokenType.Comma, strVal = "," }; 228 234 } else { 229 235 throw new ArgumentException("Invalid character: " + str[pos]); … … 232 238 } 233 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 } 234 245 private ISymbolicExpressionTreeNode ParseS(Queue<Token> tokens) { 235 246 var expr = ParseExpr(tokens); … … 339 350 } 340 351 341 // Fact = '(' Expr ')' | funcId '(' Expr ')' | varId [ = valId ] | number352 // Fact = '(' Expr ')' | 'LAG' '(' varId ',' ['+' | '-' ] number ')' | funcId '(' Expr ')' | varId [ = valId ] | number 342 353 private ISymbolicExpressionTreeNode ParseFact(Queue<Token> tokens) { 343 354 var next = tokens.Peek(); … … 359 370 if (lPar.TokenType != TokenType.LeftPar) 360 371 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 362 404 var rPar = tokens.Dequeue(); 363 405 if (rPar.TokenType != TokenType.RightPar) 364 406 throw new ArgumentException("expected )"); 365 407 366 funcNode.AddSubtree(expr);367 408 return funcNode; 368 409 } else { … … 396 437 } 397 438 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 } 398 450 } 399 451 } -
branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionCompiledTreeInterpreter.cs
r14185 r14351 614 614 case OpCodes.VariableCondition: { 615 615 var variableConditionTreeNode = (VariableConditionTreeNode)node; 616 if (variableConditionTreeNode.Symbol.IgnoreSlope) throw new NotSupportedException("Strict variable conditionals are not supported"); 616 617 var variableName = variableConditionTreeNode.VariableName; 617 618 var indexExpr = Expression.Constant(variableIndices[variableName]); -
branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeInterpreter.cs
r14251 r14351 488 488 if (row < 0 || row >= dataset.Rows) return double.NaN; 489 489 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 } 498 511 } 499 512 default: -
branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeLinearInterpreter.cs
r14330 r14351 126 126 private readonly object syncRoot = new object(); 127 127 public IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, IDataset dataset, IEnumerable<int> rows) { 128 if (!rows.Any()) return Enumerable.Empty<double>(); 128 129 if (CheckExpressionsWithIntervalArithmetic) 129 130 throw new NotSupportedException("Interval arithmetic is not yet supported in the symbolic data analysis interpreter."); … … 171 172 if (row < 0 || row >= dataset.Rows) instr.value = double.NaN; 172 173 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 } 181 191 } else if (instr.opCode == OpCodes.Add) { 182 192 double s = code[instr.childIndex].value; … … 433 443 for (int j = 1; j != seq.Length; ++j) 434 444 seq[j].skip = true; 435 }436 break;445 break; 446 } 437 447 } 438 448 #endregion -
branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/VariableCondition.cs
r14238 r14351 149 149 } 150 150 } 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; } 151 161 } 152 162 -
branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/VariableConditionTreeNode.cs
r14238 r14351 96 96 97 97 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 { 99 101 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 } 103 104 } 104 105 }
Note: See TracChangeset
for help on using the changeset viewer.