Changeset 5461
- Timestamp:
- 02/15/11 10:34:38 (14 years ago)
- Location:
- trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/SymbolicSimplifier.cs
r5455 r5461 35 35 public class SymbolicSimplifier { 36 36 private Addition addSymbol = new Addition(); 37 private Subtraction subSymbol = new Subtraction(); 37 38 private Multiplication mulSymbol = new Multiplication(); 38 39 private Division divSymbol = new Division(); … … 151 152 private bool IsLessThan(SymbolicExpressionTreeNode node) { 152 153 return node.Symbol is LessThan; 154 } 155 156 private bool IsBoolean(SymbolicExpressionTreeNode node) { 157 return 158 node.Symbol is GreaterThan || 159 node.Symbol is LessThan || 160 node.Symbol is And || 161 node.Symbol is Or; 153 162 } 154 163 … … 439 448 } else { 440 449 var ifNode = ifThenElseSymbol.CreateTreeNode(); 441 ifNode.AddSubTree(condition); 450 if (IsBoolean(condition)) { 451 ifNode.AddSubTree(condition); 452 } else { 453 var gtNode = gtSymbol.CreateTreeNode(); 454 gtNode.AddSubTree(condition); gtNode.AddSubTree(MakeConstant(0.0)); 455 ifNode.AddSubTree(gtNode); 456 } 442 457 ifNode.AddSubTree(trueBranch); 443 458 ifNode.AddSubTree(falseBranch); … … 445 460 } 446 461 } 462 447 463 private SymbolicExpressionTreeNode MakeSine(SymbolicExpressionTreeNode node) { 448 464 // todo implement more transformation rules … … 483 499 var constT = node as ConstantTreeNode; 484 500 return MakeConstant(Math.Exp(constT.Value)); 501 } else if (IsLog(node)) { 502 return node.SubTrees[0]; 485 503 } else { 486 504 var expNode = expSymbol.CreateTreeNode(); … … 494 512 var constT = node as ConstantTreeNode; 495 513 return MakeConstant(Math.Log(constT.Value)); 514 } else if (IsExp(node)) { 515 return node.SubTrees[0]; 516 } else if (IsMultiplication(node)) { 517 return node.SubTrees.Select(s => MakeLog(s)).Aggregate((x, y) => MakeSum(x, y)); 518 } else if (IsDivision(node)) { 519 var subtractionNode = subSymbol.CreateTreeNode(); 520 foreach (var subTree in node.SubTrees) { 521 subtractionNode.AddSubTree(MakeLog(subTree)); 522 } 523 return subtractionNode; 496 524 } else { 497 525 var logNode = logSymbol.CreateTreeNode(); … … 503 531 504 532 // MakeFraction, MakeProduct and MakeSum take two already simplified trees and create a new simplified tree 505 506 533 private SymbolicExpressionTreeNode MakeFraction(SymbolicExpressionTreeNode a, SymbolicExpressionTreeNode b) { 507 534 if (IsConstant(a) && IsConstant(b)) { … … 515 542 ((VariableTreeNode)a).Weight /= constB; 516 543 return a; 544 } else if (IsVariable(a) && IsVariable(b) && AreSameVariable(a, b)) { 545 // cancel variables 546 var aVar = a as VariableTreeNode; 547 var bVar = b as VariableTreeNode; 548 return MakeConstant(aVar.Weight / bVar.Weight); 517 549 } else if (IsAddition(a) && IsConstant(b)) { 518 550 return a.SubTrees … … 574 606 } 575 607 MergeVariablesInSum(add); 576 return add; 608 if (add.SubTrees.Count == 1) { 609 return add.SubTrees[0]; 610 } else { 611 return add; 612 } 577 613 } else if (IsAddition(b)) { 578 614 return MakeSum(b, a); … … 596 632 } 597 633 MergeVariablesInSum(add); 598 return add; 634 if (add.SubTrees.Count == 1) { 635 return add.SubTrees[0]; 636 } else { 637 return add; 638 } 599 639 } else { 600 640 var add = addSymbol.CreateTreeNode(); … … 602 642 add.AddSubTree(b); 603 643 MergeVariablesInSum(add); 604 return add; 644 if (add.SubTrees.Count == 1) { 645 return add.SubTrees[0]; 646 } else { 647 return add; 648 } 605 649 } 606 650 } 607 651 608 652 // makes sure variable symbols in sums are combined 609 // possible improv ment: combine sums of products where the products only reference the same variable653 // possible improvement: combine sums of products where the products only reference the same variable 610 654 private void MergeVariablesInSum(SymbolicExpressionTreeNode sum) { 611 655 var subtrees = new List<SymbolicExpressionTreeNode>(sum.SubTrees); … … 683 727 #endregion 684 728 729 730 #region helper functions 731 732 private bool AreSameVariable(SymbolicExpressionTreeNode a, SymbolicExpressionTreeNode b) { 733 var aLaggedVar = a as LaggedVariableTreeNode; 734 var bLaggedVar = b as LaggedVariableTreeNode; 735 if (aLaggedVar != null && bLaggedVar != null) { 736 return aLaggedVar.VariableName == bLaggedVar.VariableName && 737 aLaggedVar.Lag == bLaggedVar.Lag; 738 } 739 var aVar = a as VariableTreeNode; 740 var bVar = b as VariableTreeNode; 741 if (aVar != null && bVar != null) { 742 return aVar.VariableName == bVar.VariableName; 743 } 744 return false; 745 } 746 685 747 // helper to combine the constant factors in products and to combine variables (powers of 2, 3...) 686 748 private void MergeVariablesAndConstantsInProduct(SymbolicExpressionTreeNode prod) { … … 727 789 728 790 729 #region helper functions730 791 /// <summary> 731 792 /// x => x * -1 -
trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Tests/SymbolicSimplifierTest.cs
r5460 r5461 140 140 } 141 141 #endregion 142 #region constant and variable folding 143 { 144 var actualTree = simplifier.Simplify(importer.Import("(+ 1.0 2.0)")); 145 var expectedTree = importer.Import("3.0"); 146 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 147 } 148 { 149 var actualTree = simplifier.Simplify(importer.Import("(+ (variable 2.0 a) (variable 2.0 a))")); 150 var expectedTree = importer.Import("(variable 4.0 a)"); 151 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 152 } 153 { 154 var actualTree = simplifier.Simplify(importer.Import("(- (variable 2.0 a) (variable 1.0 a))")); 155 var expectedTree = importer.Import("(variable 1.0 a)"); 156 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 157 } 158 { 159 var actualTree = simplifier.Simplify(importer.Import("(* (variable 2.0 a) (variable 2.0 a))")); 160 var expectedTree = importer.Import("(* (* (variable 1.0 a) (variable 1.0 a)) 4.0)"); 161 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 162 } 163 { 164 var actualTree = simplifier.Simplify(importer.Import("(/ (variable 1.0 a) (variable 2.0 a))")); 165 var expectedTree = importer.Import("0.5"); 166 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 167 } 168 #endregion 142 169 #region logarithm rules 143 170 { … … 155 182 { 156 183 // log transformation 157 var actualTree = simplifier.Simplify(importer.Import("(log (* (variable 2.0 a) (variable 3.0 b)) "));158 var expectedTree = importer.Import("(+ (log (variable 2.0 a)) (log (variable 3.0 b)))");184 var actualTree = simplifier.Simplify(importer.Import("(log (* (variable 2.0 a) (variable 3.0 b)))")); 185 var expectedTree = importer.Import("(+ (log (variable 1.0 a)) (log (variable 1.0 b)) 1.7918)"); 159 186 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 160 187 } 161 188 { 162 189 // log transformation 163 var actualTree = simplifier.Simplify(importer.Import("(log (/ (variable 2.0 a) (variable 3.0 b)) "));190 var actualTree = simplifier.Simplify(importer.Import("(log (/ (variable 2.0 a) (variable 3.0 b)))")); 164 191 var expectedTree = importer.Import("(- (log (variable 2.0 a)) (log (variable 3.0 b)))"); 165 192 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); … … 194 221 // constant not 195 222 var actualTree = simplifier.Simplify(importer.Import("(not -2.0)")); 196 var expectedTree = importer.Import(" 1.0");223 var expectedTree = importer.Import("2.0"); 197 224 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 198 225 } … … 200 227 // constant not 201 228 var actualTree = simplifier.Simplify(importer.Import("(not 2.0)")); 202 var expectedTree = importer.Import("- 1.0");229 var expectedTree = importer.Import("-2.0"); 203 230 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 204 231 } … … 206 233 // constant not 207 234 var actualTree = simplifier.Simplify(importer.Import("(not 0.0)")); 208 var expectedTree = importer.Import(" 1.0");235 var expectedTree = importer.Import("0.0"); 209 236 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 210 237 } … … 245 272 var actualTree = simplifier.Simplify(importer.Import("(if (variable 1.0 a) (variable 2.0 a) (variable 3.0 a))")); 246 273 var expectedTree = importer.Import("(if (> (variable 1.0 a) 0.0) (variable 2.0 a) (variable 3.0 a))"); 247 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));248 }249 #endregion250 #region constant and variable folding251 {252 var actualTree = simplifier.Simplify(importer.Import("(+ 1.0 2.0)"));253 var expectedTree = importer.Import("3.0");254 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));255 }256 {257 var actualTree = simplifier.Simplify(importer.Import("(+ (variable 2.0 a) (variable 2.0 a))"));258 var expectedTree = importer.Import("(variable 4.0 a)");259 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));260 }261 {262 var actualTree = simplifier.Simplify(importer.Import("(- (variable 2.0 a) (variable 1.0 a))"));263 var expectedTree = importer.Import("(variable 1.0 a)");264 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));265 }266 {267 var actualTree = simplifier.Simplify(importer.Import("(* (variable 2.0 a) (variable 2.0 a))"));268 var expectedTree = importer.Import("(* (* (variable 1.0 a) (variable 1.0 a)) 4.0)");269 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));270 }271 {272 var actualTree = simplifier.Simplify(importer.Import("(/ (variable 1.0 a) (variable 2.0 a))"));273 var expectedTree = importer.Import("0.5");274 274 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 275 275 }
Note: See TracChangeset
for help on using the changeset viewer.