- Timestamp:
- 07/06/17 11:19:24 (7 years ago)
- Location:
- stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeSimplifier.cs
r14843 r15145 33 33 /// </summary> 34 34 public class TreeSimplifier { 35 private Addition addSymbol = new Addition(); 36 private Multiplication mulSymbol = new Multiplication(); 37 private Division divSymbol = new Division(); 38 private Constant constSymbol = new Constant(); 39 private Variable varSymbol = new Variable(); 40 private Logarithm logSymbol = new Logarithm(); 41 private Exponential expSymbol = new Exponential(); 42 private Root rootSymbol = new Root(); 43 private Square sqrSymbol = new Square(); 44 private SquareRoot sqrtSymbol = new SquareRoot(); 45 private Power powSymbol = new Power(); 46 private Sine sineSymbol = new Sine(); 47 private Cosine cosineSymbol = new Cosine(); 48 private Tangent tanSymbol = new Tangent(); 49 private IfThenElse ifThenElseSymbol = new IfThenElse(); 50 private And andSymbol = new And(); 51 private Or orSymbol = new Or(); 52 private Not notSymbol = new Not(); 53 private GreaterThan gtSymbol = new GreaterThan(); 54 private LessThan ltSymbol = new LessThan(); 55 private Integral integralSymbol = new Integral(); 56 private LaggedVariable laggedVariableSymbol = new LaggedVariable(); 57 private TimeLag timeLagSymbol = new TimeLag(); 58 59 public ISymbolicExpressionTree Simplify(ISymbolicExpressionTree originalTree) { 35 private static readonly Addition addSymbol = new Addition(); 36 private static readonly Multiplication mulSymbol = new Multiplication(); 37 private static readonly Division divSymbol = new Division(); 38 private static readonly Constant constSymbol = new Constant(); 39 private static readonly Logarithm logSymbol = new Logarithm(); 40 private static readonly Exponential expSymbol = new Exponential(); 41 private static readonly Root rootSymbol = new Root(); 42 private static readonly Square sqrSymbol = new Square(); 43 private static readonly SquareRoot sqrtSymbol = new SquareRoot(); 44 private static readonly Power powSymbol = new Power(); 45 private static readonly Sine sineSymbol = new Sine(); 46 private static readonly Cosine cosineSymbol = new Cosine(); 47 private static readonly Tangent tanSymbol = new Tangent(); 48 private static readonly IfThenElse ifThenElseSymbol = new IfThenElse(); 49 private static readonly And andSymbol = new And(); 50 private static readonly Or orSymbol = new Or(); 51 private static readonly Not notSymbol = new Not(); 52 private static readonly GreaterThan gtSymbol = new GreaterThan(); 53 private static readonly LessThan ltSymbol = new LessThan(); 54 private static readonly Integral integralSymbol = new Integral(); 55 private static readonly LaggedVariable laggedVariableSymbol = new LaggedVariable(); 56 private static readonly TimeLag timeLagSymbol = new TimeLag(); 57 58 [Obsolete("Use static method TreeSimplifier.Simplify instead")] 59 public TreeSimplifier() { } 60 61 public static ISymbolicExpressionTree Simplify(ISymbolicExpressionTree originalTree) { 60 62 var clone = (ISymbolicExpressionTreeNode)originalTree.Root.Clone(); 61 63 // macro expand (initially no argument trees) … … 67 69 // check that each node is only referenced once 68 70 var nodes = rootNode.IterateNodesPrefix().ToArray(); 69 foreach (var n in nodes) if(nodes.Count(ni => ni == n) > 1) throw new InvalidOperationException();71 foreach (var n in nodes) if (nodes.Count(ni => ni == n) > 1) throw new InvalidOperationException(); 70 72 #endif 71 73 return new SymbolicExpressionTree(rootNode); … … 73 75 74 76 // the argumentTrees list contains already expanded trees used as arguments for invocations 75 private ISymbolicExpressionTreeNode MacroExpand(ISymbolicExpressionTreeNode root, ISymbolicExpressionTreeNode node,77 private static ISymbolicExpressionTreeNode MacroExpand(ISymbolicExpressionTreeNode root, ISymbolicExpressionTreeNode node, 76 78 IList<ISymbolicExpressionTreeNode> argumentTrees) { 77 79 List<ISymbolicExpressionTreeNode> subtrees = new List<ISymbolicExpressionTreeNode>(node.Subtrees); … … 98 100 } 99 101 100 private ISymbolicExpressionTreeNode FindFunctionDefinition(ISymbolicExpressionTreeNode root, string functionName) {102 private static ISymbolicExpressionTreeNode FindFunctionDefinition(ISymbolicExpressionTreeNode root, string functionName) { 101 103 foreach (var subtree in root.Subtrees.OfType<DefunTreeNode>()) { 102 104 if (subtree.FunctionName == functionName) return subtree.GetSubtree(0); … … 109 111 110 112 // arithmetic 111 private bool IsDivision(ISymbolicExpressionTreeNode node) {113 private static bool IsDivision(ISymbolicExpressionTreeNode node) { 112 114 return node.Symbol is Division; 113 115 } 114 116 115 private bool IsMultiplication(ISymbolicExpressionTreeNode node) {117 private static bool IsMultiplication(ISymbolicExpressionTreeNode node) { 116 118 return node.Symbol is Multiplication; 117 119 } 118 120 119 private bool IsSubtraction(ISymbolicExpressionTreeNode node) {121 private static bool IsSubtraction(ISymbolicExpressionTreeNode node) { 120 122 return node.Symbol is Subtraction; 121 123 } 122 124 123 private bool IsAddition(ISymbolicExpressionTreeNode node) {125 private static bool IsAddition(ISymbolicExpressionTreeNode node) { 124 126 return node.Symbol is Addition; 125 127 } 126 128 127 private bool IsAverage(ISymbolicExpressionTreeNode node) {129 private static bool IsAverage(ISymbolicExpressionTreeNode node) { 128 130 return node.Symbol is Average; 129 131 } 130 132 131 133 // exponential 132 private bool IsLog(ISymbolicExpressionTreeNode node) {134 private static bool IsLog(ISymbolicExpressionTreeNode node) { 133 135 return node.Symbol is Logarithm; 134 136 } 135 137 136 private bool IsExp(ISymbolicExpressionTreeNode node) {138 private static bool IsExp(ISymbolicExpressionTreeNode node) { 137 139 return node.Symbol is Exponential; 138 140 } 139 141 140 private bool IsRoot(ISymbolicExpressionTreeNode node) {142 private static bool IsRoot(ISymbolicExpressionTreeNode node) { 141 143 return node.Symbol is Root; 142 144 } 143 145 144 private bool IsSquare(ISymbolicExpressionTreeNode node) {146 private static bool IsSquare(ISymbolicExpressionTreeNode node) { 145 147 return node.Symbol is Square; 146 148 } 147 149 148 private bool IsSquareRoot(ISymbolicExpressionTreeNode node) {150 private static bool IsSquareRoot(ISymbolicExpressionTreeNode node) { 149 151 return node.Symbol is SquareRoot; 150 152 } 151 153 152 private bool IsPower(ISymbolicExpressionTreeNode node) {154 private static bool IsPower(ISymbolicExpressionTreeNode node) { 153 155 return node.Symbol is Power; 154 156 } 155 157 156 158 // trigonometric 157 private bool IsSine(ISymbolicExpressionTreeNode node) {159 private static bool IsSine(ISymbolicExpressionTreeNode node) { 158 160 return node.Symbol is Sine; 159 161 } 160 162 161 private bool IsCosine(ISymbolicExpressionTreeNode node) {163 private static bool IsCosine(ISymbolicExpressionTreeNode node) { 162 164 return node.Symbol is Cosine; 163 165 } 164 166 165 private bool IsTangent(ISymbolicExpressionTreeNode node) {167 private static bool IsTangent(ISymbolicExpressionTreeNode node) { 166 168 return node.Symbol is Tangent; 167 169 } 168 170 169 171 // boolean 170 private bool IsIfThenElse(ISymbolicExpressionTreeNode node) {172 private static bool IsIfThenElse(ISymbolicExpressionTreeNode node) { 171 173 return node.Symbol is IfThenElse; 172 174 } 173 175 174 private bool IsAnd(ISymbolicExpressionTreeNode node) {176 private static bool IsAnd(ISymbolicExpressionTreeNode node) { 175 177 return node.Symbol is And; 176 178 } 177 179 178 private bool IsOr(ISymbolicExpressionTreeNode node) {180 private static bool IsOr(ISymbolicExpressionTreeNode node) { 179 181 return node.Symbol is Or; 180 182 } 181 183 182 private bool IsNot(ISymbolicExpressionTreeNode node) {184 private static bool IsNot(ISymbolicExpressionTreeNode node) { 183 185 return node.Symbol is Not; 184 186 } 185 187 186 188 // comparison 187 private bool IsGreaterThan(ISymbolicExpressionTreeNode node) {189 private static bool IsGreaterThan(ISymbolicExpressionTreeNode node) { 188 190 return node.Symbol is GreaterThan; 189 191 } 190 192 191 private bool IsLessThan(ISymbolicExpressionTreeNode node) {193 private static bool IsLessThan(ISymbolicExpressionTreeNode node) { 192 194 return node.Symbol is LessThan; 193 195 } 194 196 195 private bool IsBoolean(ISymbolicExpressionTreeNode node) {197 private static bool IsBoolean(ISymbolicExpressionTreeNode node) { 196 198 return 197 199 node.Symbol is GreaterThan || … … 202 204 203 205 // terminals 204 private bool IsVariable(ISymbolicExpressionTreeNode node) {206 private static bool IsVariable(ISymbolicExpressionTreeNode node) { 205 207 return node.Symbol is Variable; 206 208 } 207 209 208 private bool IsVariableBase(ISymbolicExpressionTreeNode node) {210 private static bool IsVariableBase(ISymbolicExpressionTreeNode node) { 209 211 return node is VariableTreeNodeBase; 210 212 } 211 213 212 private bool IsFactor(ISymbolicExpressionTreeNode node) {214 private static bool IsFactor(ISymbolicExpressionTreeNode node) { 213 215 return node is FactorVariableTreeNode; 214 216 } 215 217 216 private bool IsBinFactor(ISymbolicExpressionTreeNode node) {218 private static bool IsBinFactor(ISymbolicExpressionTreeNode node) { 217 219 return node is BinaryFactorVariableTreeNode; 218 220 } 219 221 220 private bool IsConstant(ISymbolicExpressionTreeNode node) {222 private static bool IsConstant(ISymbolicExpressionTreeNode node) { 221 223 return node.Symbol is Constant; 222 224 } 223 225 224 226 // dynamic 225 private bool IsTimeLag(ISymbolicExpressionTreeNode node) {227 private static bool IsTimeLag(ISymbolicExpressionTreeNode node) { 226 228 return node.Symbol is TimeLag; 227 229 } 228 230 229 private bool IsIntegral(ISymbolicExpressionTreeNode node) {231 private static bool IsIntegral(ISymbolicExpressionTreeNode node) { 230 232 return node.Symbol is Integral; 231 233 } … … 238 240 /// <param name="original"></param> 239 241 /// <returns></returns> 240 public ISymbolicExpressionTreeNode GetSimplifiedTree(ISymbolicExpressionTreeNode original) {242 public static ISymbolicExpressionTreeNode GetSimplifiedTree(ISymbolicExpressionTreeNode original) { 241 243 if (IsConstant(original) || IsVariableBase(original)) { 242 244 return (ISymbolicExpressionTreeNode)original.Clone(); … … 292 294 #region specific simplification routines 293 295 294 private ISymbolicExpressionTreeNode SimplifyAny(ISymbolicExpressionTreeNode original) {296 private static ISymbolicExpressionTreeNode SimplifyAny(ISymbolicExpressionTreeNode original) { 295 297 // can't simplify this function but simplify all subtrees 296 298 List<ISymbolicExpressionTreeNode> subtrees = new List<ISymbolicExpressionTreeNode>(original.Subtrees); … … 311 313 } 312 314 313 private ISymbolicExpressionTreeNode SimplifyConstantExpression(ISymbolicExpressionTreeNode original) {315 private static ISymbolicExpressionTreeNode SimplifyConstantExpression(ISymbolicExpressionTreeNode original) { 314 316 // not yet implemented 315 317 return original; 316 318 } 317 319 318 private ISymbolicExpressionTreeNode SimplifyAverage(ISymbolicExpressionTreeNode original) {320 private static ISymbolicExpressionTreeNode SimplifyAverage(ISymbolicExpressionTreeNode original) { 319 321 if (original.Subtrees.Count() == 1) { 320 322 return GetSimplifiedTree(original.GetSubtree(0)); … … 329 331 } 330 332 331 private ISymbolicExpressionTreeNode SimplifyDivision(ISymbolicExpressionTreeNode original) {333 private static ISymbolicExpressionTreeNode SimplifyDivision(ISymbolicExpressionTreeNode original) { 332 334 if (original.Subtrees.Count() == 1) { 333 335 return Invert(GetSimplifiedTree(original.GetSubtree(0))); … … 344 346 } 345 347 346 private ISymbolicExpressionTreeNode SimplifyMultiplication(ISymbolicExpressionTreeNode original) {348 private static ISymbolicExpressionTreeNode SimplifyMultiplication(ISymbolicExpressionTreeNode original) { 347 349 if (original.Subtrees.Count() == 1) { 348 350 return GetSimplifiedTree(original.GetSubtree(0)); … … 354 356 } 355 357 356 private ISymbolicExpressionTreeNode SimplifySubtraction(ISymbolicExpressionTreeNode original) {358 private static ISymbolicExpressionTreeNode SimplifySubtraction(ISymbolicExpressionTreeNode original) { 357 359 if (original.Subtrees.Count() == 1) { 358 360 return Negate(GetSimplifiedTree(original.GetSubtree(0))); … … 366 368 } 367 369 368 private ISymbolicExpressionTreeNode SimplifyAddition(ISymbolicExpressionTreeNode original) {370 private static ISymbolicExpressionTreeNode SimplifyAddition(ISymbolicExpressionTreeNode original) { 369 371 if (original.Subtrees.Count() == 1) { 370 372 return GetSimplifiedTree(original.GetSubtree(0)); … … 378 380 } 379 381 380 private ISymbolicExpressionTreeNode SimplifyNot(ISymbolicExpressionTreeNode original) {382 private static ISymbolicExpressionTreeNode SimplifyNot(ISymbolicExpressionTreeNode original) { 381 383 return MakeNot(GetSimplifiedTree(original.GetSubtree(0))); 382 384 } 383 385 384 private ISymbolicExpressionTreeNode SimplifyOr(ISymbolicExpressionTreeNode original) {386 private static ISymbolicExpressionTreeNode SimplifyOr(ISymbolicExpressionTreeNode original) { 385 387 return original.Subtrees 386 388 .Select(GetSimplifiedTree) … … 388 390 } 389 391 390 private ISymbolicExpressionTreeNode SimplifyAnd(ISymbolicExpressionTreeNode original) {392 private static ISymbolicExpressionTreeNode SimplifyAnd(ISymbolicExpressionTreeNode original) { 391 393 return original.Subtrees 392 394 .Select(GetSimplifiedTree) … … 394 396 } 395 397 396 private ISymbolicExpressionTreeNode SimplifyLessThan(ISymbolicExpressionTreeNode original) {398 private static ISymbolicExpressionTreeNode SimplifyLessThan(ISymbolicExpressionTreeNode original) { 397 399 return MakeLessThan(GetSimplifiedTree(original.GetSubtree(0)), GetSimplifiedTree(original.GetSubtree(1))); 398 400 } 399 401 400 private ISymbolicExpressionTreeNode SimplifyGreaterThan(ISymbolicExpressionTreeNode original) {402 private static ISymbolicExpressionTreeNode SimplifyGreaterThan(ISymbolicExpressionTreeNode original) { 401 403 return MakeGreaterThan(GetSimplifiedTree(original.GetSubtree(0)), GetSimplifiedTree(original.GetSubtree(1))); 402 404 } 403 405 404 private ISymbolicExpressionTreeNode SimplifyIfThenElse(ISymbolicExpressionTreeNode original) {406 private static ISymbolicExpressionTreeNode SimplifyIfThenElse(ISymbolicExpressionTreeNode original) { 405 407 return MakeIfThenElse(GetSimplifiedTree(original.GetSubtree(0)), GetSimplifiedTree(original.GetSubtree(1)), 406 408 GetSimplifiedTree(original.GetSubtree(2))); 407 409 } 408 410 409 private ISymbolicExpressionTreeNode SimplifyTangent(ISymbolicExpressionTreeNode original) {411 private static ISymbolicExpressionTreeNode SimplifyTangent(ISymbolicExpressionTreeNode original) { 410 412 return MakeTangent(GetSimplifiedTree(original.GetSubtree(0))); 411 413 } 412 414 413 private ISymbolicExpressionTreeNode SimplifyCosine(ISymbolicExpressionTreeNode original) {415 private static ISymbolicExpressionTreeNode SimplifyCosine(ISymbolicExpressionTreeNode original) { 414 416 return MakeCosine(GetSimplifiedTree(original.GetSubtree(0))); 415 417 } 416 418 417 private ISymbolicExpressionTreeNode SimplifySine(ISymbolicExpressionTreeNode original) {419 private static ISymbolicExpressionTreeNode SimplifySine(ISymbolicExpressionTreeNode original) { 418 420 return MakeSine(GetSimplifiedTree(original.GetSubtree(0))); 419 421 } 420 422 421 private ISymbolicExpressionTreeNode SimplifyExp(ISymbolicExpressionTreeNode original) {423 private static ISymbolicExpressionTreeNode SimplifyExp(ISymbolicExpressionTreeNode original) { 422 424 return MakeExp(GetSimplifiedTree(original.GetSubtree(0))); 423 425 } 424 426 425 private ISymbolicExpressionTreeNode SimplifySquare(ISymbolicExpressionTreeNode original) {427 private static ISymbolicExpressionTreeNode SimplifySquare(ISymbolicExpressionTreeNode original) { 426 428 return MakeSquare(GetSimplifiedTree(original.GetSubtree(0))); 427 429 } 428 430 429 private ISymbolicExpressionTreeNode SimplifySquareRoot(ISymbolicExpressionTreeNode original) {431 private static ISymbolicExpressionTreeNode SimplifySquareRoot(ISymbolicExpressionTreeNode original) { 430 432 return MakeSquareRoot(GetSimplifiedTree(original.GetSubtree(0))); 431 433 } 432 434 433 private ISymbolicExpressionTreeNode SimplifyLog(ISymbolicExpressionTreeNode original) {435 private static ISymbolicExpressionTreeNode SimplifyLog(ISymbolicExpressionTreeNode original) { 434 436 return MakeLog(GetSimplifiedTree(original.GetSubtree(0))); 435 437 } 436 438 437 private ISymbolicExpressionTreeNode SimplifyRoot(ISymbolicExpressionTreeNode original) {439 private static ISymbolicExpressionTreeNode SimplifyRoot(ISymbolicExpressionTreeNode original) { 438 440 return MakeRoot(GetSimplifiedTree(original.GetSubtree(0)), GetSimplifiedTree(original.GetSubtree(1))); 439 441 } 440 442 441 private ISymbolicExpressionTreeNode SimplifyPower(ISymbolicExpressionTreeNode original) {443 private static ISymbolicExpressionTreeNode SimplifyPower(ISymbolicExpressionTreeNode original) { 442 444 return MakePower(GetSimplifiedTree(original.GetSubtree(0)), GetSimplifiedTree(original.GetSubtree(1))); 443 445 } 444 446 445 private ISymbolicExpressionTreeNode SimplifyTimeLag(ISymbolicExpressionTreeNode original) {447 private static ISymbolicExpressionTreeNode SimplifyTimeLag(ISymbolicExpressionTreeNode original) { 446 448 var laggedTreeNode = original as ILaggedTreeNode; 447 449 var simplifiedSubtree = GetSimplifiedTree(original.GetSubtree(0)); … … 453 455 } 454 456 455 private ISymbolicExpressionTreeNode SimplifyIntegral(ISymbolicExpressionTreeNode original) {457 private static ISymbolicExpressionTreeNode SimplifyIntegral(ISymbolicExpressionTreeNode original) { 456 458 var laggedTreeNode = original as ILaggedTreeNode; 457 459 var simplifiedSubtree = GetSimplifiedTree(original.GetSubtree(0)); … … 467 469 #region low level tree restructuring 468 470 469 private ISymbolicExpressionTreeNode MakeTimeLag(ISymbolicExpressionTreeNode subtree, int lag) {471 private static ISymbolicExpressionTreeNode MakeTimeLag(ISymbolicExpressionTreeNode subtree, int lag) { 470 472 if (lag == 0) return subtree; 471 473 if (IsConstant(subtree)) return subtree; … … 476 478 } 477 479 478 private ISymbolicExpressionTreeNode MakeIntegral(ISymbolicExpressionTreeNode subtree, int lag) {480 private static ISymbolicExpressionTreeNode MakeIntegral(ISymbolicExpressionTreeNode subtree, int lag) { 479 481 if (lag == 0) return subtree; 480 482 else if (lag == -1 || lag == 1) { … … 488 490 } 489 491 490 private ISymbolicExpressionTreeNode MakeNot(ISymbolicExpressionTreeNode t) {492 private static ISymbolicExpressionTreeNode MakeNot(ISymbolicExpressionTreeNode t) { 491 493 if (IsConstant(t)) { 492 494 var constNode = t as ConstantTreeNode; … … 509 511 } 510 512 511 private ISymbolicExpressionTreeNode MakeOr(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {513 private static ISymbolicExpressionTreeNode MakeOr(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) { 512 514 if (IsConstant(a) && IsConstant(b)) { 513 515 var constA = a as ConstantTreeNode; … … 539 541 } 540 542 541 private ISymbolicExpressionTreeNode MakeAnd(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {543 private static ISymbolicExpressionTreeNode MakeAnd(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) { 542 544 if (IsConstant(a) && IsConstant(b)) { 543 545 var constA = a as ConstantTreeNode; … … 569 571 } 570 572 571 private ISymbolicExpressionTreeNode MakeLessThan(ISymbolicExpressionTreeNode leftSide,573 private static ISymbolicExpressionTreeNode MakeLessThan(ISymbolicExpressionTreeNode leftSide, 572 574 ISymbolicExpressionTreeNode rightSide) { 573 575 if (IsConstant(leftSide) && IsConstant(rightSide)) { … … 584 586 } 585 587 586 private ISymbolicExpressionTreeNode MakeGreaterThan(ISymbolicExpressionTreeNode leftSide,588 private static ISymbolicExpressionTreeNode MakeGreaterThan(ISymbolicExpressionTreeNode leftSide, 587 589 ISymbolicExpressionTreeNode rightSide) { 588 590 if (IsConstant(leftSide) && IsConstant(rightSide)) { … … 599 601 } 600 602 601 private ISymbolicExpressionTreeNode MakeIfThenElse(ISymbolicExpressionTreeNode condition,603 private static ISymbolicExpressionTreeNode MakeIfThenElse(ISymbolicExpressionTreeNode condition, 602 604 ISymbolicExpressionTreeNode trueBranch, ISymbolicExpressionTreeNode falseBranch) { 603 605 if (IsConstant(condition)) { … … 621 623 } 622 624 623 private ISymbolicExpressionTreeNode MakeSine(ISymbolicExpressionTreeNode node) {625 private static ISymbolicExpressionTreeNode MakeSine(ISymbolicExpressionTreeNode node) { 624 626 if (IsConstant(node)) { 625 627 var constT = node as ConstantTreeNode; … … 638 640 } 639 641 640 private ISymbolicExpressionTreeNode MakeTangent(ISymbolicExpressionTreeNode node) {642 private static ISymbolicExpressionTreeNode MakeTangent(ISymbolicExpressionTreeNode node) { 641 643 if (IsConstant(node)) { 642 644 var constT = node as ConstantTreeNode; … … 655 657 } 656 658 657 private ISymbolicExpressionTreeNode MakeCosine(ISymbolicExpressionTreeNode node) {659 private static ISymbolicExpressionTreeNode MakeCosine(ISymbolicExpressionTreeNode node) { 658 660 if (IsConstant(node)) { 659 661 var constT = node as ConstantTreeNode; … … 674 676 } 675 677 676 private ISymbolicExpressionTreeNode MakeExp(ISymbolicExpressionTreeNode node) {678 private static ISymbolicExpressionTreeNode MakeExp(ISymbolicExpressionTreeNode node) { 677 679 if (IsConstant(node)) { 678 680 var constT = node as ConstantTreeNode; … … 698 700 } 699 701 } 700 private ISymbolicExpressionTreeNode MakeLog(ISymbolicExpressionTreeNode node) {702 private static ISymbolicExpressionTreeNode MakeLog(ISymbolicExpressionTreeNode node) { 701 703 if (IsConstant(node)) { 702 704 var constT = node as ConstantTreeNode; … … 716 718 } 717 719 718 private ISymbolicExpressionTreeNode MakeSquare(ISymbolicExpressionTreeNode node) {720 private static ISymbolicExpressionTreeNode MakeSquare(ISymbolicExpressionTreeNode node) { 719 721 if (IsConstant(node)) { 720 722 var constT = node as ConstantTreeNode; … … 735 737 } 736 738 737 private ISymbolicExpressionTreeNode MakeSquareRoot(ISymbolicExpressionTreeNode node) {739 private static ISymbolicExpressionTreeNode MakeSquareRoot(ISymbolicExpressionTreeNode node) { 738 740 if (IsConstant(node)) { 739 741 var constT = node as ConstantTreeNode; … … 754 756 } 755 757 756 private ISymbolicExpressionTreeNode MakeRoot(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {758 private static ISymbolicExpressionTreeNode MakeRoot(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) { 757 759 if (IsConstant(a) && IsConstant(b)) { 758 760 var constA = a as ConstantTreeNode; … … 809 811 810 812 811 private ISymbolicExpressionTreeNode MakePower(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {813 private static ISymbolicExpressionTreeNode MakePower(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) { 812 814 if (IsConstant(a) && IsConstant(b)) { 813 815 var constA = a as ConstantTreeNode; … … 864 866 865 867 // MakeFraction, MakeProduct and MakeSum take two already simplified trees and create a new simplified tree 866 private ISymbolicExpressionTreeNode MakeFraction(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {868 private static ISymbolicExpressionTreeNode MakeFraction(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) { 867 869 if (IsConstant(a) && IsConstant(b)) { 868 870 // fold constants … … 933 935 } 934 936 935 private ISymbolicExpressionTreeNode MakeSum(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {937 private static ISymbolicExpressionTreeNode MakeSum(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) { 936 938 if (IsConstant(a) && IsConstant(b)) { 937 939 // fold constants … … 1028 1030 1029 1031 // makes sure variable symbols in sums are combined 1030 private void MergeVariablesInSum(ISymbolicExpressionTreeNode sum) {1032 private static void MergeVariablesInSum(ISymbolicExpressionTreeNode sum) { 1031 1033 var subtrees = new List<ISymbolicExpressionTreeNode>(sum.Subtrees); 1032 1034 while (sum.Subtrees.Any()) sum.RemoveSubtree(0); … … 1067 1069 1068 1070 // nodes referencing variables can be grouped if they have 1069 private st ring GroupId(IVariableTreeNode node) {1071 private static string GroupId(IVariableTreeNode node) { 1070 1072 var binaryFactorNode = node as BinaryFactorVariableTreeNode; 1071 1073 var factorNode = node as FactorVariableTreeNode; … … 1086 1088 1087 1089 1088 private ISymbolicExpressionTreeNode MakeProduct(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {1090 private static ISymbolicExpressionTreeNode MakeProduct(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) { 1089 1091 if (IsConstant(a) && IsConstant(b)) { 1090 1092 // fold constants … … 1167 1169 #region helper functions 1168 1170 1169 private bool ContainsVariableCondition(ISymbolicExpressionTreeNode node) {1171 private static bool ContainsVariableCondition(ISymbolicExpressionTreeNode node) { 1170 1172 if (node.Symbol is VariableCondition) return true; 1171 1173 foreach (var subtree in node.Subtrees) … … 1174 1176 } 1175 1177 1176 private ISymbolicExpressionTreeNode AddLagToDynamicNodes(ISymbolicExpressionTreeNode node, int lag) {1178 private static ISymbolicExpressionTreeNode AddLagToDynamicNodes(ISymbolicExpressionTreeNode node, int lag) { 1177 1179 var laggedTreeNode = node as ILaggedTreeNode; 1178 1180 var variableNode = node as VariableTreeNode; … … 1196 1198 } 1197 1199 1198 private bool AreSameTypeAndVariable(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {1200 private static bool AreSameTypeAndVariable(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) { 1199 1201 return GroupId((IVariableTreeNode)a) == GroupId((IVariableTreeNode)b); 1200 1202 } 1201 1203 1202 1204 // helper to combine the constant factors in products and to combine variables (powers of 2, 3...) 1203 private void MergeVariablesAndConstantsInProduct(ISymbolicExpressionTreeNode prod) {1205 private static void MergeVariablesAndConstantsInProduct(ISymbolicExpressionTreeNode prod) { 1204 1206 var subtrees = new List<ISymbolicExpressionTreeNode>(prod.Subtrees); 1205 1207 while (prod.Subtrees.Any()) prod.RemoveSubtree(0); … … 1265 1267 /// <param name="x"></param> 1266 1268 /// <returns>-x</returns> 1267 private ISymbolicExpressionTreeNode Negate(ISymbolicExpressionTreeNode x) {1269 private static ISymbolicExpressionTreeNode Negate(ISymbolicExpressionTreeNode x) { 1268 1270 if (IsConstant(x)) { 1269 1271 ((ConstantTreeNode)x).Value *= -1; … … 1302 1304 /// <param name="x"></param> 1303 1305 /// <returns></returns> 1304 private ISymbolicExpressionTreeNode Invert(ISymbolicExpressionTreeNode x) {1306 private static ISymbolicExpressionTreeNode Invert(ISymbolicExpressionTreeNode x) { 1305 1307 if (IsConstant(x)) { 1306 1308 return MakeConstant(1.0 / ((ConstantTreeNode)x).Value); … … 1316 1318 } 1317 1319 1318 private ISymbolicExpressionTreeNode MakeConstant(double value) {1320 private static ISymbolicExpressionTreeNode MakeConstant(double value) { 1319 1321 ConstantTreeNode constantTreeNode = (ConstantTreeNode)(constSymbol.CreateTreeNode()); 1320 1322 constantTreeNode.Value = value; … … 1322 1324 } 1323 1325 1324 private ISymbolicExpressionTreeNode MakeFactor(FactorVariable sy, string variableName, IEnumerable<double> weights) {1326 private static ISymbolicExpressionTreeNode MakeFactor(FactorVariable sy, string variableName, IEnumerable<double> weights) { 1325 1327 var tree = (FactorVariableTreeNode)sy.CreateTreeNode(); 1326 1328 tree.VariableName = variableName; … … 1328 1330 return tree; 1329 1331 } 1330 private ISymbolicExpressionTreeNode MakeBinFactor(BinaryFactorVariable sy, string variableName, string variableValue, double weight) {1332 private static ISymbolicExpressionTreeNode MakeBinFactor(BinaryFactorVariable sy, string variableName, string variableValue, double weight) { 1331 1333 var tree = (BinaryFactorVariableTreeNode)sy.CreateTreeNode(); 1332 1334 tree.VariableName = variableName; -
stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeToAutoDiffTermConverter.cs
r15143 r15145 23 23 using System.Collections.Generic; 24 24 using System.Linq; 25 using System.Runtime.Serialization; 25 26 using AutoDiff; 26 27 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; … … 29 30 public class TreeToAutoDiffTermConverter { 30 31 public delegate double ParametricFunction(double[] vars, double[] @params); 32 31 33 public delegate Tuple<double[], double> ParametricFunctionGradient(double[] vars, double[] @params); 32 34 … … 62 64 eval: Math.Atan, 63 65 diff: x => 1 / (1 + x * x)); 66 64 67 private static readonly Func<Term, UnaryFunc> sin = UnaryFunc.Factory( 65 68 eval: Math.Sin, 66 69 diff: Math.Cos); 70 67 71 private static readonly Func<Term, UnaryFunc> cos = UnaryFunc.Factory( 68 eval: Math.Cos, 69 diff: x => -Math.Sin(x)); 72 eval: Math.Cos, 73 diff: x => -Math.Sin(x)); 74 70 75 private static readonly Func<Term, UnaryFunc> tan = UnaryFunc.Factory( 71 76 eval: Math.Tan, 72 77 diff: x => 1 + Math.Tan(x) * Math.Tan(x)); 78 73 79 private static readonly Func<Term, UnaryFunc> erf = UnaryFunc.Factory( 74 80 eval: alglib.errorfunction, 75 81 diff: x => 2.0 * Math.Exp(-(x * x)) / Math.Sqrt(Math.PI)); 82 76 83 private static readonly Func<Term, UnaryFunc> norm = UnaryFunc.Factory( 77 84 eval: alglib.normaldistribution, … … 88 95 var transformator = new TreeToAutoDiffTermConverter(makeVariableWeightsVariable); 89 96 AutoDiff.Term term; 90 var success = transformator.TryConvertToAutoDiff(tree.Root.GetSubtree(0), out term);91 if (success) {97 try { 98 term = transformator.ConvertToAutoDiff(tree.Root.GetSubtree(0)); 92 99 var parameterEntries = transformator.parameters.ToArray(); // guarantee same order for keys and values 93 var compiledTerm = term.Compile(transformator.variables.ToArray(), parameterEntries.Select(kvp => kvp.Value).ToArray()); 100 var compiledTerm = term.Compile(transformator.variables.ToArray(), 101 parameterEntries.Select(kvp => kvp.Value).ToArray()); 94 102 parameters = new List<DataForVariable>(parameterEntries.Select(kvp => kvp.Key)); 95 103 initialConstants = transformator.initialConstants.ToArray(); 96 104 func = (vars, @params) => compiledTerm.Evaluate(vars, @params); 97 105 func_grad = (vars, @params) => compiledTerm.Differentiate(vars, @params); 98 } else { 106 return true; 107 } catch (ConversionException) { 99 108 func = null; 100 109 func_grad = null; … … 102 111 initialConstants = null; 103 112 } 104 return success;113 return false; 105 114 } 106 115 107 116 // state for recursive transformation of trees 108 private readonly List<double> initialConstants; 117 private readonly 118 List<double> initialConstants; 109 119 private readonly Dictionary<DataForVariable, AutoDiff.Variable> parameters; 110 120 private readonly List<AutoDiff.Variable> variables; … … 118 128 } 119 129 120 private bool TryConvertToAutoDiff(ISymbolicExpressionTreeNode node, out AutoDiff.Term term) {130 private AutoDiff.Term ConvertToAutoDiff(ISymbolicExpressionTreeNode node) { 121 131 if (node.Symbol is Constant) { 122 132 initialConstants.Add(((ConstantTreeNode)node).Value); 123 133 var var = new AutoDiff.Variable(); 124 134 variables.Add(var); 125 term = var; 126 return true; 135 return var; 127 136 } 128 137 if (node.Symbol is Variable || node.Symbol is BinaryFactorVariable) { … … 137 146 var w = new AutoDiff.Variable(); 138 147 variables.Add(w); 139 term =AutoDiff.TermBuilder.Product(w, par);148 return AutoDiff.TermBuilder.Product(w, par); 140 149 } else { 141 term = varNode.Weight * par; 142 } 143 return true; 150 return varNode.Weight * par; 151 } 144 152 } 145 153 if (node.Symbol is FactorVariable) { … … 155 163 products.Add(AutoDiff.TermBuilder.Product(wVar, par)); 156 164 } 157 term = AutoDiff.TermBuilder.Sum(products); 158 return true; 165 return AutoDiff.TermBuilder.Sum(products); 159 166 } 160 167 if (node.Symbol is LaggedVariable) { … … 166 173 var w = new AutoDiff.Variable(); 167 174 variables.Add(w); 168 term =AutoDiff.TermBuilder.Product(w, par);175 return AutoDiff.TermBuilder.Product(w, par); 169 176 } else { 170 term = varNode.Weight * par; 171 } 172 return true; 177 return varNode.Weight * par; 178 } 173 179 } 174 180 if (node.Symbol is Addition) { 175 181 List<AutoDiff.Term> terms = new List<Term>(); 176 182 foreach (var subTree in node.Subtrees) { 177 AutoDiff.Term t; 178 if (!TryConvertToAutoDiff(subTree, out t)) { 179 term = null; 180 return false; 181 } 182 terms.Add(t); 183 } 184 term = AutoDiff.TermBuilder.Sum(terms); 185 return true; 183 terms.Add(ConvertToAutoDiff(subTree)); 184 } 185 return AutoDiff.TermBuilder.Sum(terms); 186 186 } 187 187 if (node.Symbol is Subtraction) { 188 188 List<AutoDiff.Term> terms = new List<Term>(); 189 189 for (int i = 0; i < node.SubtreeCount; i++) { 190 AutoDiff.Term t; 191 if (!TryConvertToAutoDiff(node.GetSubtree(i), out t)) { 192 term = null; 193 return false; 194 } 190 AutoDiff.Term t = ConvertToAutoDiff(node.GetSubtree(i)); 195 191 if (i > 0) t = -t; 196 192 terms.Add(t); 197 193 } 198 if (terms.Count == 1) term = -terms[0]; 199 else term = AutoDiff.TermBuilder.Sum(terms); 200 return true; 194 if (terms.Count == 1) return -terms[0]; 195 else return AutoDiff.TermBuilder.Sum(terms); 201 196 } 202 197 if (node.Symbol is Multiplication) { 203 198 List<AutoDiff.Term> terms = new List<Term>(); 204 199 foreach (var subTree in node.Subtrees) { 205 AutoDiff.Term t; 206 if (!TryConvertToAutoDiff(subTree, out t)) { 207 term = null; 208 return false; 209 } 210 terms.Add(t); 211 } 212 if (terms.Count == 1) term = terms[0]; 213 else term = terms.Aggregate((a, b) => new AutoDiff.Product(a, b)); 214 return true; 215 200 terms.Add(ConvertToAutoDiff(subTree)); 201 } 202 if (terms.Count == 1) return terms[0]; 203 else return terms.Aggregate((a, b) => new AutoDiff.Product(a, b)); 216 204 } 217 205 if (node.Symbol is Division) { 218 206 List<AutoDiff.Term> terms = new List<Term>(); 219 207 foreach (var subTree in node.Subtrees) { 220 AutoDiff.Term t; 221 if (!TryConvertToAutoDiff(subTree, out t)) { 222 term = null; 223 return false; 224 } 225 terms.Add(t); 226 } 227 if (terms.Count == 1) term = 1.0 / terms[0]; 228 else term = terms.Aggregate((a, b) => new AutoDiff.Product(a, 1.0 / b)); 229 return true; 208 terms.Add(ConvertToAutoDiff(subTree)); 209 } 210 if (terms.Count == 1) return 1.0 / terms[0]; 211 else return terms.Aggregate((a, b) => new AutoDiff.Product(a, 1.0 / b)); 230 212 } 231 213 if (node.Symbol is Logarithm) { 232 AutoDiff.Term t; 233 if (!TryConvertToAutoDiff(node.GetSubtree(0), out t)) { 234 term = null; 235 return false; 236 } else { 237 term = AutoDiff.TermBuilder.Log(t); 238 return true; 239 } 214 return AutoDiff.TermBuilder.Log( 215 ConvertToAutoDiff(node.GetSubtree(0))); 240 216 } 241 217 if (node.Symbol is Exponential) { 242 AutoDiff.Term t; 243 if (!TryConvertToAutoDiff(node.GetSubtree(0), out t)) { 244 term = null; 245 return false; 246 } else { 247 term = AutoDiff.TermBuilder.Exp(t); 248 return true; 249 } 218 return AutoDiff.TermBuilder.Exp( 219 ConvertToAutoDiff(node.GetSubtree(0))); 250 220 } 251 221 if (node.Symbol is Square) { 252 AutoDiff.Term t; 253 if (!TryConvertToAutoDiff(node.GetSubtree(0), out t)) { 254 term = null; 255 return false; 256 } else { 257 term = AutoDiff.TermBuilder.Power(t, 2.0); 258 return true; 259 } 222 return AutoDiff.TermBuilder.Power( 223 ConvertToAutoDiff(node.GetSubtree(0)), 2.0); 260 224 } 261 225 if (node.Symbol is SquareRoot) { 262 AutoDiff.Term t; 263 if (!TryConvertToAutoDiff(node.GetSubtree(0), out t)) { 264 term = null; 265 return false; 266 } else { 267 term = AutoDiff.TermBuilder.Power(t, 0.5); 268 return true; 269 } 226 return AutoDiff.TermBuilder.Power( 227 ConvertToAutoDiff(node.GetSubtree(0)), 0.5); 270 228 } 271 229 if (node.Symbol is Sine) { 272 AutoDiff.Term t; 273 if (!TryConvertToAutoDiff(node.GetSubtree(0), out t)) { 274 term = null; 275 return false; 276 } else { 277 term = sin(t); 278 return true; 279 } 230 return sin( 231 ConvertToAutoDiff(node.GetSubtree(0))); 280 232 } 281 233 if (node.Symbol is Cosine) { 282 AutoDiff.Term t; 283 if (!TryConvertToAutoDiff(node.GetSubtree(0), out t)) { 284 term = null; 285 return false; 286 } else { 287 term = cos(t); 288 return true; 289 } 234 return cos( 235 ConvertToAutoDiff(node.GetSubtree(0))); 290 236 } 291 237 if (node.Symbol is Tangent) { 292 AutoDiff.Term t; 293 if (!TryConvertToAutoDiff(node.GetSubtree(0), out t)) { 294 term = null; 295 return false; 296 } else { 297 term = tan(t); 298 return true; 299 } 238 return tan( 239 ConvertToAutoDiff(node.GetSubtree(0))); 300 240 } 301 241 if (node.Symbol is Erf) { 302 AutoDiff.Term t; 303 if (!TryConvertToAutoDiff(node.GetSubtree(0), out t)) { 304 term = null; 305 return false; 306 } else { 307 term = erf(t); 308 return true; 309 } 242 return erf( 243 ConvertToAutoDiff(node.GetSubtree(0))); 310 244 } 311 245 if (node.Symbol is Norm) { 312 AutoDiff.Term t; 313 if (!TryConvertToAutoDiff(node.GetSubtree(0), out t)) { 314 term = null; 315 return false; 316 } else { 317 term = norm(t); 318 return true; 319 } 246 return norm( 247 ConvertToAutoDiff(node.GetSubtree(0))); 320 248 } 321 249 if (node.Symbol is StartSymbol) { … … 324 252 variables.Add(beta); 325 253 variables.Add(alpha); 326 AutoDiff.Term branchTerm; 327 if (TryConvertToAutoDiff(node.GetSubtree(0), out branchTerm)) { 328 term = branchTerm * alpha + beta; 329 return true; 330 } else { 331 term = null; 332 return false; 333 } 334 } 335 term = null; 336 return false; 254 return ConvertToAutoDiff(node.GetSubtree(0)) * alpha + beta; 255 } 256 throw new ConversionException(); 337 257 } 338 258 … … 357 277 from n in tree.Root.GetSubtree(0).IterateNodesPrefix() 358 278 where 359 !(n.Symbol is Variable) &&360 !(n.Symbol is BinaryFactorVariable) &&361 !(n.Symbol is FactorVariable) &&362 !(n.Symbol is LaggedVariable) &&363 !(n.Symbol is Constant) &&364 !(n.Symbol is Addition) &&365 !(n.Symbol is Subtraction) &&366 !(n.Symbol is Multiplication) &&367 !(n.Symbol is Division) &&368 !(n.Symbol is Logarithm) &&369 !(n.Symbol is Exponential) &&370 !(n.Symbol is SquareRoot) &&371 !(n.Symbol is Square) &&372 !(n.Symbol is Sine) &&373 !(n.Symbol is Cosine) &&374 !(n.Symbol is Tangent) &&375 !(n.Symbol is Erf) &&376 !(n.Symbol is Norm) &&377 !(n.Symbol is StartSymbol)279 !(n.Symbol is Variable) && 280 !(n.Symbol is BinaryFactorVariable) && 281 !(n.Symbol is FactorVariable) && 282 !(n.Symbol is LaggedVariable) && 283 !(n.Symbol is Constant) && 284 !(n.Symbol is Addition) && 285 !(n.Symbol is Subtraction) && 286 !(n.Symbol is Multiplication) && 287 !(n.Symbol is Division) && 288 !(n.Symbol is Logarithm) && 289 !(n.Symbol is Exponential) && 290 !(n.Symbol is SquareRoot) && 291 !(n.Symbol is Square) && 292 !(n.Symbol is Sine) && 293 !(n.Symbol is Cosine) && 294 !(n.Symbol is Tangent) && 295 !(n.Symbol is Erf) && 296 !(n.Symbol is Norm) && 297 !(n.Symbol is StartSymbol) 378 298 select n).Any(); 379 299 return !containsUnknownSymbol; 380 300 } 301 #region exception class 302 [Serializable] 303 public class ConversionException : Exception { 304 305 public ConversionException() { 306 } 307 308 public ConversionException(string message) : base(message) { 309 } 310 311 public ConversionException(string message, Exception inner) : base(message, inner) { 312 } 313 314 protected ConversionException( 315 SerializationInfo info, 316 StreamingContext context) : base(info, context) { 317 } 318 } 319 #endregion 381 320 } 382 321 }
Note: See TracChangeset
for help on using the changeset viewer.