Changeset 14576 for branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic
- Timestamp:
- 01/15/17 14:17:06 (8 years ago)
- Location:
- branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic
- Files:
-
- 8 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic
- Property svn:mergeinfo changed
/trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic merged: 14319,14345,14347,14350,14353-14354,14367,14378,14390-14391,14400
- Property svn:mergeinfo changed
-
branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/InfixExpressionFormatter.cs
r14307 r14576 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)) { … … 121 146 strBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}", constNode.Value); 122 147 else 123 strBuilder.AppendFormat(CultureInfo.InvariantCulture, "({0})", constNode.Value); // (-1)148 strBuilder.AppendFormat(CultureInfo.InvariantCulture, "({0})", constNode.Value); // (-1 124 149 } 125 150 } -
branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionLatexFormatter.cs
r14312 r14576 67 67 strBuilder.AppendLine(FormatRecursively(symbolicExpressionTree.Root)); 68 68 return strBuilder.ToString(); 69 } 70 catch (NotImplementedException ex) { 69 } catch (NotImplementedException ex) { 71 70 return ex.Message + Environment.NewLine + ex.StackTrace; 72 71 } … … 109 108 } else if (node.Symbol is Division) { 110 109 if (node.SubtreeCount == 1) { 111 strBuilder.Append(@" \cfrac{1 ");110 strBuilder.Append(@" \cfrac{1}{"); 112 111 } else { 113 112 strBuilder.Append(@" \cfrac{ "); … … 176 175 strBuilder.Append(@" \operatorname{if} \left( "); 177 176 } else if (node.Symbol is Constant) { 178 strBuilder.Append("c_{" + constants.Count + "} ");179 177 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 } 181 184 } else if (node.Symbol is LaggedVariable) { 182 185 var laggedVarNode = node as LaggedVariableTreeNode; -
branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/InfixExpressionParser.cs
r14307 r14576 26 26 using System.Text; 27 27 using HeuristicLab.Collections; 28 using HeuristicLab.Common; 28 29 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; 29 30 … … 37 38 /// </summary> 38 39 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 }; 40 41 private class Token { 41 42 internal double doubleVal; … … 102 103 { "MEAN", new Average()}, 103 104 { "IF", new IfThenElse()}, 104 { " >", new GreaterThan()},105 { " <", new LessThan()},105 { "GT", new GreaterThan()}, 106 { "LT", new LessThan()}, 106 107 { "AND", new And()}, 107 108 { "OR", new Or()}, … … 109 110 { "XOR", new Xor()}, 110 111 { "DIFF", new Derivative()}, 112 { "LAG", new LaggedVariable() }, 111 113 }; 112 114 … … 138 140 } 139 141 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) 141 143 var sb = new StringBuilder(); 142 144 sb.Append(str[pos]); 143 145 pos++; 144 146 while (pos < str.Length && !char.IsWhiteSpace(str[pos]) 145 && (str[pos] != '+' || str[pos -1] == 'e' || str[pos-1] == 'E') // continue reading exponents147 && (str[pos] != '+' || str[pos - 1] == 'e' || str[pos - 1] == 'E') // continue reading exponents 146 148 && (str[pos] != '-' || str[pos - 1] == 'e' || str[pos - 1] == 'E') 147 && str[pos] != '*' 149 && str[pos] != '*' 148 150 && str[pos] != '/' 149 && str[pos] != ')') { 151 && str[pos] != ')' 152 && str[pos] != ',') { 150 153 sb.Append(str[pos]); 151 154 pos++; … … 211 214 pos++; 212 215 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 } 221 230 private ISymbolicExpressionTreeNode ParseS(Queue<Token> tokens) { 222 231 var expr = ParseExpr(tokens); … … 326 335 } 327 336 328 // Fact = '(' Expr ')' | funcId '(' Expr')' | varId | number337 // Fact = '(' Expr ')' | 'LAG' '(' varId ',' ['+' | '-'] number ')' | funcId '(' ArgList ')' | varId | number 329 338 private ISymbolicExpressionTreeNode ParseFact(Queue<Token> tokens) { 330 339 var next = tokens.Peek(); … … 346 355 if (lPar.TokenType != TokenType.LeftPar) 347 356 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 349 389 var rPar = tokens.Dequeue(); 350 390 if (rPar.TokenType != TokenType.RightPar) 351 391 throw new ArgumentException("expected )"); 352 392 353 funcNode.AddSubtree(expr);354 393 return funcNode; 355 394 } else { … … 369 408 } 370 409 } 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 } 371 422 } 372 423 } -
branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/SymbolicExpressionImporter.cs
r14312 r14576 35 35 private const string INVOKESTART = "CALL"; 36 36 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>() 38 38 { 39 39 {"+", new Addition()}, -
branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionCompiledTreeInterpreter.cs
r14312 r14576 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/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeInterpreter.cs
r14312 r14576 471 471 if (row < 0 || row >= dataset.Rows) return double.NaN; 472 472 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 } 481 494 } 482 495 default: -
branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeLinearInterpreter.cs
r14312 r14576 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."); … … 166 167 if (row < 0 || row >= dataset.Rows) instr.value = double.NaN; 167 168 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 } 176 186 } else if (instr.opCode == OpCodes.Add) { 177 187 double s = code[instr.childIndex].value; … … 420 430 for (int j = 1; j != seq.Length; ++j) 421 431 seq[j].skip = true; 422 }423 break;432 break; 433 } 424 434 } 425 435 #endregion -
branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/VariableCondition.cs
r14312 r14576 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/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/VariableConditionTreeNode.cs
r14312 r14576 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.