Changeset 4878
- Timestamp:
- 11/20/10 21:57:28 (14 years ago)
- Location:
- branches/SymbolicSimplifier
- Files:
-
- 1 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
branches/SymbolicSimplifier/3.3/Symbolic/SymbolicSimplifier.cs
r4477 r4878 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 … … 164 224 clone.AddSubTree(simplifiedSubtree); 165 225 } 166 if (simplifiedSubTrees.TrueForAll(t => IsConstant(t))) {167 SimplifyConstantExpression(clone);168 }169 226 return clone; 170 }171 172 private SymbolicExpressionTreeNode SimplifyConstantExpression(SymbolicExpressionTreeNode original) {173 // not yet implemented174 return original;175 227 } 176 228 … … 239 291 } 240 292 } 293 294 private SymbolicExpressionTreeNode SimplifyNot(SymbolicExpressionTreeNode original) { 295 return MakeNot(GetSimplifiedTree(original.SubTrees[0])); 296 } 297 private SymbolicExpressionTreeNode SimplifyOr(SymbolicExpressionTreeNode original) { 298 return original.SubTrees 299 .Select(x => GetSimplifiedTree(x)) 300 .Aggregate((a, b) => MakeOr(a, b)); 301 } 302 private SymbolicExpressionTreeNode SimplifyAnd(SymbolicExpressionTreeNode original) { 303 return original.SubTrees 304 .Select(x => GetSimplifiedTree(x)) 305 .Aggregate((a, b) => MakeAnd(a, b)); 306 } 307 private SymbolicExpressionTreeNode SimplifyLessThan(SymbolicExpressionTreeNode original) { 308 return MakeLessThan(GetSimplifiedTree(original.SubTrees[0]), GetSimplifiedTree(original.SubTrees[1])); 309 } 310 private SymbolicExpressionTreeNode SimplifyGreaterThan(SymbolicExpressionTreeNode original) { 311 return MakeGreaterThan(GetSimplifiedTree(original.SubTrees[0]), GetSimplifiedTree(original.SubTrees[1])); 312 } 313 private SymbolicExpressionTreeNode SimplifyIfThenElse(SymbolicExpressionTreeNode original) { 314 return MakeIfThenElse(GetSimplifiedTree(original.SubTrees[0]), GetSimplifiedTree(original.SubTrees[1]), GetSimplifiedTree(original.SubTrees[2])); 315 } 316 private SymbolicExpressionTreeNode SimplifyTangent(SymbolicExpressionTreeNode original) { 317 return MakeTangent(GetSimplifiedTree(original.SubTrees[0])); 318 } 319 private SymbolicExpressionTreeNode SimplifyCosine(SymbolicExpressionTreeNode original) { 320 return MakeCosine(GetSimplifiedTree(original.SubTrees[0])); 321 } 322 private SymbolicExpressionTreeNode SimplifySine(SymbolicExpressionTreeNode original) { 323 return MakeSine(GetSimplifiedTree(original.SubTrees[0])); 324 } 325 private SymbolicExpressionTreeNode SimplifyExp(SymbolicExpressionTreeNode original) { 326 return MakeExp(GetSimplifiedTree(original.SubTrees[0])); 327 } 328 329 private SymbolicExpressionTreeNode SimplifyLog(SymbolicExpressionTreeNode original) { 330 return MakeLog(GetSimplifiedTree(original.SubTrees[0])); 331 } 332 241 333 #endregion 242 334 … … 244 336 245 337 #region low level tree restructuring 338 private SymbolicExpressionTreeNode MakeNot(SymbolicExpressionTreeNode t) { 339 return MakeProduct(t, MakeConstant(-1.0)); 340 } 341 342 private SymbolicExpressionTreeNode MakeOr(SymbolicExpressionTreeNode a, SymbolicExpressionTreeNode b) { 343 if (IsConstant(a) && IsConstant(b)) { 344 var constA = a as ConstantTreeNode; 345 var constB = b as ConstantTreeNode; 346 if (constA.Value > 0.0 || constB.Value > 0.0) { 347 return MakeConstant(1.0); 348 } else { 349 return MakeConstant(-1.0); 350 } 351 } else if (IsConstant(a)) { 352 return MakeOr(b, a); 353 } else if (IsConstant(b)) { 354 var constT = b as ConstantTreeNode; 355 if (constT.Value > 0.0) { 356 // boolean expression is necessarily true 357 return MakeConstant(1.0); 358 } else { 359 // the constant value has no effect on the result of the boolean condition so we can drop the constant term 360 var orNode = orSymbol.CreateTreeNode(); 361 orNode.AddSubTree(a); 362 return orNode; 363 } 364 } else { 365 var orNode = orSymbol.CreateTreeNode(); 366 orNode.AddSubTree(a); 367 orNode.AddSubTree(b); 368 return orNode; 369 } 370 } 371 private SymbolicExpressionTreeNode MakeAnd(SymbolicExpressionTreeNode a, SymbolicExpressionTreeNode b) { 372 if (IsConstant(a) && IsConstant(b)) { 373 var constA = a as ConstantTreeNode; 374 var constB = b as ConstantTreeNode; 375 if (constA.Value > 0.0 && constB.Value > 0.0) { 376 return MakeConstant(1.0); 377 } else { 378 return MakeConstant(-1.0); 379 } 380 } else if (IsConstant(a)) { 381 return MakeAnd(b, a); 382 } else if (IsConstant(b)) { 383 var constB = b as ConstantTreeNode; 384 if (constB.Value > 0.0) { 385 // the constant value has no effect on the result of the boolean condition so we can drop the constant term 386 var andNode = andSymbol.CreateTreeNode(); 387 andNode.AddSubTree(a); 388 return andNode; 389 } else { 390 // boolean expression is necessarily false 391 return MakeConstant(-1.0); 392 } 393 } else { 394 var andNode = andSymbol.CreateTreeNode(); 395 andNode.AddSubTree(a); 396 andNode.AddSubTree(b); 397 return andNode; 398 } 399 } 400 private SymbolicExpressionTreeNode MakeLessThan(SymbolicExpressionTreeNode leftSide, SymbolicExpressionTreeNode rightSide) { 401 if (IsConstant(leftSide) && IsConstant(rightSide)) { 402 var lsConst = leftSide as ConstantTreeNode; 403 var rsConst = rightSide as ConstantTreeNode; 404 if (lsConst.Value < rsConst.Value) return MakeConstant(1.0); 405 else return MakeConstant(-1.0); 406 } else { 407 var ltNode = ltSymbol.CreateTreeNode(); 408 ltNode.AddSubTree(leftSide); 409 ltNode.AddSubTree(rightSide); 410 return ltNode; 411 } 412 } 413 private SymbolicExpressionTreeNode MakeGreaterThan(SymbolicExpressionTreeNode leftSide, SymbolicExpressionTreeNode rightSide) { 414 if (IsConstant(leftSide) && IsConstant(rightSide)) { 415 var lsConst = leftSide as ConstantTreeNode; 416 var rsConst = rightSide as ConstantTreeNode; 417 if (lsConst.Value > rsConst.Value) return MakeConstant(1.0); 418 else return MakeConstant(-1.0); 419 } else { 420 var gtNode = gtSymbol.CreateTreeNode(); 421 gtNode.AddSubTree(leftSide); 422 gtNode.AddSubTree(rightSide); 423 return gtNode; 424 } 425 } 426 private SymbolicExpressionTreeNode MakeIfThenElse(SymbolicExpressionTreeNode condition, SymbolicExpressionTreeNode trueBranch, SymbolicExpressionTreeNode falseBranch) { 427 if (IsConstant(condition)) { 428 var constT = condition as ConstantTreeNode; 429 if (constT.Value > 0.0) return trueBranch; 430 else return falseBranch; 431 } else { 432 var ifNode = ifThenElseSymbol.CreateTreeNode(); 433 ifNode.AddSubTree(condition); 434 ifNode.AddSubTree(trueBranch); 435 ifNode.AddSubTree(falseBranch); 436 return ifNode; 437 } 438 } 439 private SymbolicExpressionTreeNode MakeSine(SymbolicExpressionTreeNode node) { 440 // todo implement more transformation rules 441 if (IsConstant(node)) { 442 var constT = node as ConstantTreeNode; 443 return MakeConstant(Math.Sin(constT.Value)); 444 } else { 445 var sineNode = sineSymbol.CreateTreeNode(); 446 sineNode.AddSubTree(node); 447 return sineNode; 448 } 449 } 450 private SymbolicExpressionTreeNode MakeTangent(SymbolicExpressionTreeNode node) { 451 // todo implement more transformation rules 452 if (IsConstant(node)) { 453 var constT = node as ConstantTreeNode; 454 return MakeConstant(Math.Tan(constT.Value)); 455 } else { 456 var tanNode = tanSymbol.CreateTreeNode(); 457 tanNode.AddSubTree(node); 458 return tanNode; 459 } 460 } 461 private SymbolicExpressionTreeNode MakeCosine(SymbolicExpressionTreeNode node) { 462 // todo implement more transformation rules 463 if (IsConstant(node)) { 464 var constT = node as ConstantTreeNode; 465 return MakeConstant(Math.Cos(constT.Value)); 466 } else { 467 var cosNode = cosineSymbol.CreateTreeNode(); 468 cosNode.AddSubTree(node); 469 return cosNode; 470 } 471 } 472 private SymbolicExpressionTreeNode MakeExp(SymbolicExpressionTreeNode node) { 473 // todo implement more transformation rules 474 if (IsConstant(node)) { 475 var constT = node as ConstantTreeNode; 476 return MakeConstant(Math.Exp(constT.Value)); 477 } else { 478 var expNode = expSymbol.CreateTreeNode(); 479 expNode.AddSubTree(node); 480 return expNode; 481 } 482 } 483 private SymbolicExpressionTreeNode MakeLog(SymbolicExpressionTreeNode node) { 484 // todo implement more transformation rules 485 if (IsConstant(node)) { 486 var constT = node as ConstantTreeNode; 487 return MakeConstant(Math.Log(constT.Value)); 488 } else { 489 var logNode = logSymbol.CreateTreeNode(); 490 logNode.AddSubTree(node); 491 return logNode; 492 } 493 } 494 495 246 496 // MakeFraction, MakeProduct and MakeSum take two already simplified trees and create a new simplified tree 247 497
Note: See TracChangeset
for help on using the changeset viewer.