- Timestamp:
- 02/12/11 15:27:58 (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/SymbolicSimplifier.cs
r5445 r5455 39 39 private Constant constSymbol = new Constant(); 40 40 private Variable varSymbol = new Variable(); 41 private Logarithm logSymbol = new Logarithm(); 42 private Exponential expSymbol = new Exponential(); 43 private Sine sineSymbol = new Sine(); 44 private Cosine cosineSymbol = new Cosine(); 45 private Tangent tanSymbol = new Tangent(); 46 private IfThenElse ifThenElseSymbol = new IfThenElse(); 47 private And andSymbol = new And(); 48 private Or orSymbol = new Or(); 49 private Not notSymbol = new Not(); 50 private GreaterThan gtSymbol = new GreaterThan(); 51 private LessThan ltSymbol = new LessThan(); 41 52 42 53 public SymbolicExpressionTree Simplify(SymbolicExpressionTree originalTree) { … … 84 95 85 96 #region symbol predicates 86 private bool IsDivision(SymbolicExpressionTreeNode original) { 87 return original.Symbol is Division; 88 } 89 90 private bool IsMultiplication(SymbolicExpressionTreeNode original) { 91 return original.Symbol is Multiplication; 92 } 93 94 private bool IsSubtraction(SymbolicExpressionTreeNode original) { 95 return original.Symbol is Subtraction; 96 } 97 98 private bool IsAddition(SymbolicExpressionTreeNode original) { 99 return original.Symbol is Addition; 100 } 101 102 private bool IsVariable(SymbolicExpressionTreeNode original) { 103 return original.Symbol is Variable; 104 } 105 106 private bool IsConstant(SymbolicExpressionTreeNode original) { 107 return original.Symbol is Constant; 108 } 109 110 private bool IsAverage(SymbolicExpressionTreeNode original) { 111 return original.Symbol is Average; 112 } 113 private bool IsLog(SymbolicExpressionTreeNode original) { 114 return original.Symbol is Logarithm; 115 } 116 private bool IsIfThenElse(SymbolicExpressionTreeNode original) { 117 return original.Symbol is IfThenElse; 118 } 97 // arithmetic 98 private bool IsDivision(SymbolicExpressionTreeNode node) { 99 return node.Symbol is Division; 100 } 101 102 private bool IsMultiplication(SymbolicExpressionTreeNode node) { 103 return node.Symbol is Multiplication; 104 } 105 106 private bool IsSubtraction(SymbolicExpressionTreeNode node) { 107 return node.Symbol is Subtraction; 108 } 109 110 private bool IsAddition(SymbolicExpressionTreeNode node) { 111 return node.Symbol is Addition; 112 } 113 114 private bool IsAverage(SymbolicExpressionTreeNode node) { 115 return node.Symbol is Average; 116 } 117 // exponential 118 private bool IsLog(SymbolicExpressionTreeNode node) { 119 return node.Symbol is Logarithm; 120 } 121 private bool IsExp(SymbolicExpressionTreeNode node) { 122 return node.Symbol is Exponential; 123 } 124 // trigonometric 125 private bool IsSine(SymbolicExpressionTreeNode node) { 126 return node.Symbol is Sine; 127 } 128 private bool IsCosine(SymbolicExpressionTreeNode node) { 129 return node.Symbol is Cosine; 130 } 131 private bool IsTangent(SymbolicExpressionTreeNode node) { 132 return node.Symbol is Tangent; 133 } 134 // boolean 135 private bool IsIfThenElse(SymbolicExpressionTreeNode node) { 136 return node.Symbol is IfThenElse; 137 } 138 private bool IsAnd(SymbolicExpressionTreeNode node) { 139 return node.Symbol is And; 140 } 141 private bool IsOr(SymbolicExpressionTreeNode node) { 142 return node.Symbol is Or; 143 } 144 private bool IsNot(SymbolicExpressionTreeNode node) { 145 return node.Symbol is Not; 146 } 147 // comparison 148 private bool IsGreaterThan(SymbolicExpressionTreeNode node) { 149 return node.Symbol is GreaterThan; 150 } 151 private bool IsLessThan(SymbolicExpressionTreeNode node) { 152 return node.Symbol is LessThan; 153 } 154 155 // terminals 156 private bool IsVariable(SymbolicExpressionTreeNode node) { 157 return node.Symbol is Variable; 158 } 159 160 private bool IsConstant(SymbolicExpressionTreeNode node) { 161 return node.Symbol is Constant; 162 } 163 119 164 #endregion 120 165 … … 138 183 return SimplifyAverage(original); 139 184 } else if (IsLog(original)) { 140 // TODO simplify logarithm 185 return SimplifyLog(original); 186 } else if (IsExp(original)) { 187 return SimplifyExp(original); 188 } else if (IsSine(original)) { 189 return SimplifySine(original); 190 } else if (IsCosine(original)) { 191 return SimplifyCosine(original); 192 } else if (IsTangent(original)) { 193 return SimplifyTangent(original); 194 } else if (IsIfThenElse(original)) { 195 return SimplifyIfThenElse(original); 196 } else if (IsGreaterThan(original)) { 197 return SimplifyGreaterThan(original); 198 } else if (IsLessThan(original)) { 199 return SimplifyLessThan(original); 200 } else if (IsAnd(original)) { 201 return SimplifyAnd(original); 202 } else if (IsOr(original)) { 203 return SimplifyOr(original); 204 } else if (IsNot(original)) { 205 return SimplifyNot(original); 206 } else { 141 207 return SimplifyAny(original); 142 } else if (IsIfThenElse(original)) { 143 // TODO simplify conditionals 144 return SimplifyAny(original); 145 } else if (IsAverage(original)) { 146 return SimplifyAverage(original); 147 } else { 148 return SimplifyAny(original); 149 } 150 } 208 } 209 } 210 151 211 152 212 #region specific simplification routines … … 239 299 } 240 300 } 301 302 private SymbolicExpressionTreeNode SimplifyNot(SymbolicExpressionTreeNode original) { 303 return MakeNot(GetSimplifiedTree(original.SubTrees[0])); 304 } 305 private SymbolicExpressionTreeNode SimplifyOr(SymbolicExpressionTreeNode original) { 306 return original.SubTrees 307 .Select(x => GetSimplifiedTree(x)) 308 .Aggregate((a, b) => MakeOr(a, b)); 309 } 310 private SymbolicExpressionTreeNode SimplifyAnd(SymbolicExpressionTreeNode original) { 311 return original.SubTrees 312 .Select(x => GetSimplifiedTree(x)) 313 .Aggregate((a, b) => MakeAnd(a, b)); 314 } 315 private SymbolicExpressionTreeNode SimplifyLessThan(SymbolicExpressionTreeNode original) { 316 return MakeLessThan(GetSimplifiedTree(original.SubTrees[0]), GetSimplifiedTree(original.SubTrees[1])); 317 } 318 private SymbolicExpressionTreeNode SimplifyGreaterThan(SymbolicExpressionTreeNode original) { 319 return MakeGreaterThan(GetSimplifiedTree(original.SubTrees[0]), GetSimplifiedTree(original.SubTrees[1])); 320 } 321 private SymbolicExpressionTreeNode SimplifyIfThenElse(SymbolicExpressionTreeNode original) { 322 return MakeIfThenElse(GetSimplifiedTree(original.SubTrees[0]), GetSimplifiedTree(original.SubTrees[1]), GetSimplifiedTree(original.SubTrees[2])); 323 } 324 private SymbolicExpressionTreeNode SimplifyTangent(SymbolicExpressionTreeNode original) { 325 return MakeTangent(GetSimplifiedTree(original.SubTrees[0])); 326 } 327 private SymbolicExpressionTreeNode SimplifyCosine(SymbolicExpressionTreeNode original) { 328 return MakeCosine(GetSimplifiedTree(original.SubTrees[0])); 329 } 330 private SymbolicExpressionTreeNode SimplifySine(SymbolicExpressionTreeNode original) { 331 return MakeSine(GetSimplifiedTree(original.SubTrees[0])); 332 } 333 private SymbolicExpressionTreeNode SimplifyExp(SymbolicExpressionTreeNode original) { 334 return MakeExp(GetSimplifiedTree(original.SubTrees[0])); 335 } 336 337 private SymbolicExpressionTreeNode SimplifyLog(SymbolicExpressionTreeNode original) { 338 return MakeLog(GetSimplifiedTree(original.SubTrees[0])); 339 } 340 241 341 #endregion 242 342 … … 244 344 245 345 #region low level tree restructuring 346 private SymbolicExpressionTreeNode MakeNot(SymbolicExpressionTreeNode t) { 347 return MakeProduct(t, MakeConstant(-1.0)); 348 } 349 350 private SymbolicExpressionTreeNode MakeOr(SymbolicExpressionTreeNode a, SymbolicExpressionTreeNode b) { 351 if (IsConstant(a) && IsConstant(b)) { 352 var constA = a as ConstantTreeNode; 353 var constB = b as ConstantTreeNode; 354 if (constA.Value > 0.0 || constB.Value > 0.0) { 355 return MakeConstant(1.0); 356 } else { 357 return MakeConstant(-1.0); 358 } 359 } else if (IsConstant(a)) { 360 return MakeOr(b, a); 361 } else if (IsConstant(b)) { 362 var constT = b as ConstantTreeNode; 363 if (constT.Value > 0.0) { 364 // boolean expression is necessarily true 365 return MakeConstant(1.0); 366 } else { 367 // the constant value has no effect on the result of the boolean condition so we can drop the constant term 368 var orNode = orSymbol.CreateTreeNode(); 369 orNode.AddSubTree(a); 370 return orNode; 371 } 372 } else { 373 var orNode = orSymbol.CreateTreeNode(); 374 orNode.AddSubTree(a); 375 orNode.AddSubTree(b); 376 return orNode; 377 } 378 } 379 private SymbolicExpressionTreeNode MakeAnd(SymbolicExpressionTreeNode a, SymbolicExpressionTreeNode b) { 380 if (IsConstant(a) && IsConstant(b)) { 381 var constA = a as ConstantTreeNode; 382 var constB = b as ConstantTreeNode; 383 if (constA.Value > 0.0 && constB.Value > 0.0) { 384 return MakeConstant(1.0); 385 } else { 386 return MakeConstant(-1.0); 387 } 388 } else if (IsConstant(a)) { 389 return MakeAnd(b, a); 390 } else if (IsConstant(b)) { 391 var constB = b as ConstantTreeNode; 392 if (constB.Value > 0.0) { 393 // the constant value has no effect on the result of the boolean condition so we can drop the constant term 394 var andNode = andSymbol.CreateTreeNode(); 395 andNode.AddSubTree(a); 396 return andNode; 397 } else { 398 // boolean expression is necessarily false 399 return MakeConstant(-1.0); 400 } 401 } else { 402 var andNode = andSymbol.CreateTreeNode(); 403 andNode.AddSubTree(a); 404 andNode.AddSubTree(b); 405 return andNode; 406 } 407 } 408 private SymbolicExpressionTreeNode MakeLessThan(SymbolicExpressionTreeNode leftSide, SymbolicExpressionTreeNode rightSide) { 409 if (IsConstant(leftSide) && IsConstant(rightSide)) { 410 var lsConst = leftSide as ConstantTreeNode; 411 var rsConst = rightSide as ConstantTreeNode; 412 if (lsConst.Value < rsConst.Value) return MakeConstant(1.0); 413 else return MakeConstant(-1.0); 414 } else { 415 var ltNode = ltSymbol.CreateTreeNode(); 416 ltNode.AddSubTree(leftSide); 417 ltNode.AddSubTree(rightSide); 418 return ltNode; 419 } 420 } 421 private SymbolicExpressionTreeNode MakeGreaterThan(SymbolicExpressionTreeNode leftSide, SymbolicExpressionTreeNode rightSide) { 422 if (IsConstant(leftSide) && IsConstant(rightSide)) { 423 var lsConst = leftSide as ConstantTreeNode; 424 var rsConst = rightSide as ConstantTreeNode; 425 if (lsConst.Value > rsConst.Value) return MakeConstant(1.0); 426 else return MakeConstant(-1.0); 427 } else { 428 var gtNode = gtSymbol.CreateTreeNode(); 429 gtNode.AddSubTree(leftSide); 430 gtNode.AddSubTree(rightSide); 431 return gtNode; 432 } 433 } 434 private SymbolicExpressionTreeNode MakeIfThenElse(SymbolicExpressionTreeNode condition, SymbolicExpressionTreeNode trueBranch, SymbolicExpressionTreeNode falseBranch) { 435 if (IsConstant(condition)) { 436 var constT = condition as ConstantTreeNode; 437 if (constT.Value > 0.0) return trueBranch; 438 else return falseBranch; 439 } else { 440 var ifNode = ifThenElseSymbol.CreateTreeNode(); 441 ifNode.AddSubTree(condition); 442 ifNode.AddSubTree(trueBranch); 443 ifNode.AddSubTree(falseBranch); 444 return ifNode; 445 } 446 } 447 private SymbolicExpressionTreeNode MakeSine(SymbolicExpressionTreeNode node) { 448 // todo implement more transformation rules 449 if (IsConstant(node)) { 450 var constT = node as ConstantTreeNode; 451 return MakeConstant(Math.Sin(constT.Value)); 452 } else { 453 var sineNode = sineSymbol.CreateTreeNode(); 454 sineNode.AddSubTree(node); 455 return sineNode; 456 } 457 } 458 private SymbolicExpressionTreeNode MakeTangent(SymbolicExpressionTreeNode node) { 459 // todo implement more transformation rules 460 if (IsConstant(node)) { 461 var constT = node as ConstantTreeNode; 462 return MakeConstant(Math.Tan(constT.Value)); 463 } else { 464 var tanNode = tanSymbol.CreateTreeNode(); 465 tanNode.AddSubTree(node); 466 return tanNode; 467 } 468 } 469 private SymbolicExpressionTreeNode MakeCosine(SymbolicExpressionTreeNode node) { 470 // todo implement more transformation rules 471 if (IsConstant(node)) { 472 var constT = node as ConstantTreeNode; 473 return MakeConstant(Math.Cos(constT.Value)); 474 } else { 475 var cosNode = cosineSymbol.CreateTreeNode(); 476 cosNode.AddSubTree(node); 477 return cosNode; 478 } 479 } 480 private SymbolicExpressionTreeNode MakeExp(SymbolicExpressionTreeNode node) { 481 // todo implement more transformation rules 482 if (IsConstant(node)) { 483 var constT = node as ConstantTreeNode; 484 return MakeConstant(Math.Exp(constT.Value)); 485 } else { 486 var expNode = expSymbol.CreateTreeNode(); 487 expNode.AddSubTree(node); 488 return expNode; 489 } 490 } 491 private SymbolicExpressionTreeNode MakeLog(SymbolicExpressionTreeNode node) { 492 // todo implement more transformation rules 493 if (IsConstant(node)) { 494 var constT = node as ConstantTreeNode; 495 return MakeConstant(Math.Log(constT.Value)); 496 } else { 497 var logNode = logSymbol.CreateTreeNode(); 498 logNode.AddSubTree(node); 499 return logNode; 500 } 501 } 502 503 246 504 // MakeFraction, MakeProduct and MakeSum take two already simplified trees and create a new simplified tree 247 505 … … 357 615 group node by node.VariableName + lag into g 358 616 select g; 359 360 617 var unchangedSubTrees = subtrees.Where(t => !(t is VariableTreeNode)); 361 618
Note: See TracChangeset
for help on using the changeset viewer.