Changeset 18113 for branches/3140_NumberSymbol/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeSimplifier.cs
- Timestamp:
- 12/11/21 12:26:27 (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/3140_NumberSymbol/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeSimplifier.cs
r17963 r18113 36 36 private static readonly Multiplication mulSymbol = new Multiplication(); 37 37 private static readonly Division divSymbol = new Division(); 38 private static readonly Number numberSymbol = new Number(); 38 39 private static readonly Constant constSymbol = new Constant(); 39 40 private static readonly Absolute absSymbol = new Absolute(); … … 240 241 } 241 242 243 private static bool IsNumber(ISymbolicExpressionTreeNode node) { 244 return node.Symbol is Number; 245 } 246 242 247 private static bool IsConstant(ISymbolicExpressionTreeNode node) { 243 248 return node.Symbol is Constant; 244 249 } 245 246 250 // dynamic 247 251 private static bool IsTimeLag(ISymbolicExpressionTreeNode node) { … … 261 265 /// <returns></returns> 262 266 public static ISymbolicExpressionTreeNode GetSimplifiedTree(ISymbolicExpressionTreeNode original) { 263 if (Is Constant(original) || IsVariableBase(original)) {267 if (IsNumber(original) || IsConstant(original) || IsVariableBase(original)) { 264 268 return (ISymbolicExpressionTreeNode)original.Clone(); 265 269 } else if (IsAbsolute(original)) { … … 335 339 clone.AddSubtree(simplifiedSubtree); 336 340 } 337 if (simplifiedSubtrees.TrueForAll( t => IsConstant(t))) {341 if (simplifiedSubtrees.TrueForAll(IsNumber)) { 338 342 SimplifyConstantExpression(clone); 339 343 } … … 501 505 var laggedTreeNode = original as ILaggedTreeNode; 502 506 var simplifiedSubtree = GetSimplifiedTree(original.GetSubtree(0)); 503 if (Is Constant(simplifiedSubtree)) {507 if (IsNumber(simplifiedSubtree)) { 504 508 return GetSimplifiedTree(MakeProduct(simplifiedSubtree, MakeConstant(-laggedTreeNode.Lag))); 505 509 } else { … … 514 518 private static ISymbolicExpressionTreeNode MakeTimeLag(ISymbolicExpressionTreeNode subtree, int lag) { 515 519 if (lag == 0) return subtree; 516 if (Is Constant(subtree)) return subtree;520 if (IsNumber(subtree)) return subtree; 517 521 var lagNode = (LaggedTreeNode)timeLagSymbol.CreateTreeNode(); 518 522 lagNode.Lag = lag; … … 534 538 535 539 private static ISymbolicExpressionTreeNode MakeNot(ISymbolicExpressionTreeNode t) { 536 if (Is Constant(t)) {537 var constNode = t as ConstantTreeNode;540 if (IsNumber(t)) { 541 var constNode = t as NumberTreeNode; 538 542 if (constNode.Value > 0) return MakeConstant(-1.0); 539 543 else return MakeConstant(1.0); … … 555 559 556 560 private static ISymbolicExpressionTreeNode MakeOr(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) { 557 if (Is Constant(a) && IsConstant(b)) {558 var constA = a as ConstantTreeNode;559 var constB = b as ConstantTreeNode;561 if (IsNumber(a) && IsNumber(b)) { 562 var constA = a as NumberTreeNode; 563 var constB = b as NumberTreeNode; 560 564 if (constA.Value > 0.0 || constB.Value > 0.0) { 561 565 return MakeConstant(1.0); … … 563 567 return MakeConstant(-1.0); 564 568 } 565 } else if (Is Constant(a)) {569 } else if (IsNumber(a)) { 566 570 return MakeOr(b, a); 567 } else if (Is Constant(b)) {568 var constT = b as ConstantTreeNode;571 } else if (IsNumber(b)) { 572 var constT = b as NumberTreeNode; 569 573 if (constT.Value > 0.0) { 570 574 // boolean expression is necessarily true … … 585 589 586 590 private static ISymbolicExpressionTreeNode MakeAnd(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) { 587 if (Is Constant(a) && IsConstant(b)) {588 var constA = a as ConstantTreeNode;589 var constB = b as ConstantTreeNode;591 if (IsNumber(a) && IsNumber(b)) { 592 var constA = a as NumberTreeNode; 593 var constB = b as NumberTreeNode; 590 594 if (constA.Value > 0.0 && constB.Value > 0.0) { 591 595 return MakeConstant(1.0); … … 593 597 return MakeConstant(-1.0); 594 598 } 595 } else if (Is Constant(a)) {599 } else if (IsNumber(a)) { 596 600 return MakeAnd(b, a); 597 } else if (Is Constant(b)) {598 var constB = b as ConstantTreeNode;601 } else if (IsNumber(b)) { 602 var constB = b as NumberTreeNode; 599 603 if (constB.Value > 0.0) { 600 604 // the constant value has no effect on the result of the boolean condition so we can drop the constant term … … 616 620 private static ISymbolicExpressionTreeNode MakeLessThan(ISymbolicExpressionTreeNode leftSide, 617 621 ISymbolicExpressionTreeNode rightSide) { 618 if (Is Constant(leftSide) && IsConstant(rightSide)) {619 var lsConst = leftSide as ConstantTreeNode;620 var rsConst = rightSide as ConstantTreeNode;622 if (IsNumber(leftSide) && IsNumber(rightSide)) { 623 var lsConst = leftSide as NumberTreeNode; 624 var rsConst = rightSide as NumberTreeNode; 621 625 if (lsConst.Value < rsConst.Value) return MakeConstant(1.0); 622 626 else return MakeConstant(-1.0); … … 631 635 private static ISymbolicExpressionTreeNode MakeGreaterThan(ISymbolicExpressionTreeNode leftSide, 632 636 ISymbolicExpressionTreeNode rightSide) { 633 if (Is Constant(leftSide) && IsConstant(rightSide)) {634 var lsConst = leftSide as ConstantTreeNode;635 var rsConst = rightSide as ConstantTreeNode;637 if (IsNumber(leftSide) && IsNumber(rightSide)) { 638 var lsConst = leftSide as NumberTreeNode; 639 var rsConst = rightSide as NumberTreeNode; 636 640 if (lsConst.Value > rsConst.Value) return MakeConstant(1.0); 637 641 else return MakeConstant(-1.0); … … 646 650 private static ISymbolicExpressionTreeNode MakeIfThenElse(ISymbolicExpressionTreeNode condition, 647 651 ISymbolicExpressionTreeNode trueBranch, ISymbolicExpressionTreeNode falseBranch) { 648 if (Is Constant(condition)) {649 var constT = condition as ConstantTreeNode;652 if (IsNumber(condition)) { 653 var constT = condition as NumberTreeNode; 650 654 if (constT.Value > 0.0) return trueBranch; 651 655 else return falseBranch; … … 667 671 668 672 private static ISymbolicExpressionTreeNode MakeSine(ISymbolicExpressionTreeNode node) { 669 if (Is Constant(node)) {670 var constT = node as ConstantTreeNode;673 if (IsNumber(node)) { 674 var constT = node as NumberTreeNode; 671 675 return MakeConstant(Math.Sin(constT.Value)); 672 676 } else if (IsFactor(node)) { … … 684 688 685 689 private static ISymbolicExpressionTreeNode MakeTangent(ISymbolicExpressionTreeNode node) { 686 if (Is Constant(node)) {687 var constT = node as ConstantTreeNode;690 if (IsNumber(node)) { 691 var constT = node as NumberTreeNode; 688 692 return MakeConstant(Math.Tan(constT.Value)); 689 693 } else if (IsFactor(node)) { … … 701 705 702 706 private static ISymbolicExpressionTreeNode MakeCosine(ISymbolicExpressionTreeNode node) { 703 if (Is Constant(node)) {704 var constT = node as ConstantTreeNode;707 if (IsNumber(node)) { 708 var constT = node as NumberTreeNode; 705 709 return MakeConstant(Math.Cos(constT.Value)); 706 710 } else if (IsFactor(node)) { … … 720 724 721 725 private static ISymbolicExpressionTreeNode MakeExp(ISymbolicExpressionTreeNode node) { 722 if (Is Constant(node)) {723 var constT = node as ConstantTreeNode;726 if (IsNumber(node)) { 727 var constT = node as NumberTreeNode; 724 728 return MakeConstant(Math.Exp(constT.Value)); 725 729 } else if (IsFactor(node)) { … … 744 748 } 745 749 private static ISymbolicExpressionTreeNode MakeLog(ISymbolicExpressionTreeNode node) { 746 if (Is Constant(node)) {747 var constT = node as ConstantTreeNode;750 if (IsNumber(node)) { 751 var constT = node as NumberTreeNode; 748 752 return MakeConstant(Math.Log(constT.Value)); 749 753 } else if (IsFactor(node)) { … … 762 766 763 767 private static ISymbolicExpressionTreeNode MakeSquare(ISymbolicExpressionTreeNode node) { 764 if (Is Constant(node)) {765 var constT = node as ConstantTreeNode;768 if (IsNumber(node)) { 769 var constT = node as NumberTreeNode; 766 770 return MakeConstant(constT.Value * constT.Value); 767 771 } else if (IsFactor(node)) { … … 796 800 797 801 private static ISymbolicExpressionTreeNode MakeCube(ISymbolicExpressionTreeNode node) { 798 if (Is Constant(node)) {799 var constT = node as ConstantTreeNode;802 if (IsNumber(node)) { 803 var constT = node as NumberTreeNode; 800 804 return MakeConstant(constT.Value * constT.Value * constT.Value); 801 805 } else if (IsFactor(node)) { … … 821 825 822 826 private static ISymbolicExpressionTreeNode MakeAbs(ISymbolicExpressionTreeNode node) { 823 if (Is Constant(node)) {824 var constT = node as ConstantTreeNode;827 if (IsNumber(node)) { 828 var constT = node as NumberTreeNode; 825 829 return MakeConstant(Math.Abs(constT.Value)); 826 830 } else if (IsFactor(node)) { … … 853 857 // constant folding only 854 858 private static ISymbolicExpressionTreeNode MakeAnalyticalQuotient(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) { 855 if (Is Constant(b)) {856 var c = b as ConstantTreeNode;859 if (IsNumber(b)) { 860 var c = b as NumberTreeNode; 857 861 return MakeFraction(a, MakeConstant(Math.Sqrt(1.0 + c.Value * c.Value))); 858 862 } else if (IsFactor(b)) { … … 871 875 872 876 private static ISymbolicExpressionTreeNode MakeSquareRoot(ISymbolicExpressionTreeNode node) { 873 if (Is Constant(node)) {874 var constT = node as ConstantTreeNode;877 if (IsNumber(node)) { 878 var constT = node as NumberTreeNode; 875 879 return MakeConstant(Math.Sqrt(constT.Value)); 876 880 } else if (IsFactor(node)) { … … 890 894 891 895 private static ISymbolicExpressionTreeNode MakeCubeRoot(ISymbolicExpressionTreeNode node) { 892 if (Is Constant(node)) {893 var constT = node as ConstantTreeNode;896 if (IsNumber(node)) { 897 var constT = node as NumberTreeNode; 894 898 return MakeConstant(Math.Pow(constT.Value, 1.0 / 3.0)); 895 899 } else if (IsFactor(node)) { … … 909 913 910 914 private static ISymbolicExpressionTreeNode MakeRoot(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) { 911 if (Is Constant(a) && IsConstant(b)) {912 var constA = a as ConstantTreeNode;913 var constB = b as ConstantTreeNode;915 if (IsNumber(a) && IsNumber(b)) { 916 var constA = a as NumberTreeNode; 917 var constB = b as NumberTreeNode; 914 918 return MakeConstant(Math.Pow(constA.Value, 1.0 / Math.Round(constB.Value))); 915 } else if (IsFactor(a) && Is Constant(b)) {919 } else if (IsFactor(a) && IsNumber(b)) { 916 920 var factNode = a as FactorVariableTreeNode; 917 var constNode = b as ConstantTreeNode;921 var constNode = b as NumberTreeNode; 918 922 return MakeFactor(factNode.Symbol, factNode.VariableName, 919 923 factNode.Weights.Select(w => Math.Pow(w, 1.0 / Math.Round(constNode.Value)))); 920 } else if (IsBinFactor(a) && Is Constant(b)) {924 } else if (IsBinFactor(a) && IsNumber(b)) { 921 925 var binFactor = a as BinaryFactorVariableTreeNode; 922 var constNode = b as ConstantTreeNode;926 var constNode = b as NumberTreeNode; 923 927 return MakeBinFactor(binFactor.Symbol, binFactor.VariableName, binFactor.VariableValue, Math.Pow(binFactor.Weight, 1.0 / Math.Round(constNode.Value))); 924 } else if (Is Constant(a) && IsFactor(b)) {925 var constNode = a as ConstantTreeNode;928 } else if (IsNumber(a) && IsFactor(b)) { 929 var constNode = a as NumberTreeNode; 926 930 var factNode = b as FactorVariableTreeNode; 927 931 return MakeFactor(factNode.Symbol, factNode.VariableName, factNode.Weights.Select(w => Math.Pow(constNode.Value, 1.0 / Math.Round(w)))); 928 } else if (Is Constant(a) && IsBinFactor(b)) {929 var constNode = a as ConstantTreeNode;932 } else if (IsNumber(a) && IsBinFactor(b)) { 933 var constNode = a as NumberTreeNode; 930 934 var factNode = b as BinaryFactorVariableTreeNode; 931 935 return MakeBinFactor(factNode.Symbol, factNode.VariableName, factNode.VariableValue, Math.Pow(constNode.Value, 1.0 / Math.Round(factNode.Weight))); … … 934 938 var node1 = b as FactorVariableTreeNode; 935 939 return MakeFactor(node0.Symbol, node0.VariableName, node0.Weights.Zip(node1.Weights, (u, v) => Math.Pow(u, 1.0 / Math.Round(v)))); 936 } else if (Is Constant(b)) {937 var constB = b as ConstantTreeNode;940 } else if (IsNumber(b)) { 941 var constB = b as NumberTreeNode; 938 942 var constBValue = Math.Round(constB.Value); 939 943 if (constBValue == 1.0) { … … 969 973 970 974 private static ISymbolicExpressionTreeNode MakePower(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) { 971 if (Is Constant(a) && IsConstant(b)) {972 var constA = a as ConstantTreeNode;973 var constB = b as ConstantTreeNode;975 if (IsNumber(a) && IsNumber(b)) { 976 var constA = a as NumberTreeNode; 977 var constB = b as NumberTreeNode; 974 978 return MakeConstant(Math.Pow(constA.Value, Math.Round(constB.Value))); 975 } else if (IsFactor(a) && Is Constant(b)) {979 } else if (IsFactor(a) && IsNumber(b)) { 976 980 var factNode = a as FactorVariableTreeNode; 977 var constNode = b as ConstantTreeNode;981 var constNode = b as NumberTreeNode; 978 982 return MakeFactor(factNode.Symbol, factNode.VariableName, factNode.Weights.Select(w => Math.Pow(w, Math.Round(constNode.Value)))); 979 } else if (IsBinFactor(a) && Is Constant(b)) {983 } else if (IsBinFactor(a) && IsNumber(b)) { 980 984 var binFactor = a as BinaryFactorVariableTreeNode; 981 var constNode = b as ConstantTreeNode;985 var constNode = b as NumberTreeNode; 982 986 return MakeBinFactor(binFactor.Symbol, binFactor.VariableName, binFactor.VariableValue, Math.Pow(binFactor.Weight, Math.Round(constNode.Value))); 983 } else if (Is Constant(a) && IsFactor(b)) {984 var constNode = a as ConstantTreeNode;987 } else if (IsNumber(a) && IsFactor(b)) { 988 var constNode = a as NumberTreeNode; 985 989 var factNode = b as FactorVariableTreeNode; 986 990 return MakeFactor(factNode.Symbol, factNode.VariableName, factNode.Weights.Select(w => Math.Pow(constNode.Value, Math.Round(w)))); 987 } else if (Is Constant(a) && IsBinFactor(b)) {988 var constNode = a as ConstantTreeNode;991 } else if (IsNumber(a) && IsBinFactor(b)) { 992 var constNode = a as NumberTreeNode; 989 993 var factNode = b as BinaryFactorVariableTreeNode; 990 994 return MakeBinFactor(factNode.Symbol, factNode.VariableName, factNode.VariableValue, Math.Pow(constNode.Value, Math.Round(factNode.Weight))); … … 993 997 var node1 = b as FactorVariableTreeNode; 994 998 return MakeFactor(node0.Symbol, node0.VariableName, node0.Weights.Zip(node1.Weights, (u, v) => Math.Pow(u, Math.Round(v)))); 995 } else if (Is Constant(b)) {996 var constB = b as ConstantTreeNode;999 } else if (IsNumber(b)) { 1000 var constB = b as NumberTreeNode; 997 1001 double exponent = Math.Round(constB.Value); 998 1002 if (exponent == 0.0) { … … 1028 1032 // MakeFraction, MakeProduct and MakeSum take two already simplified trees and create a new simplified tree 1029 1033 private static ISymbolicExpressionTreeNode MakeFraction(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) { 1030 if (Is Constant(a) && IsConstant(b)) {1034 if (IsNumber(a) && IsNumber(b)) { 1031 1035 // fold constants 1032 return MakeConstant((( ConstantTreeNode)a).Value / ((ConstantTreeNode)b).Value);1033 } else if ((Is Constant(a) && ((ConstantTreeNode)a).Value != 1.0)) {1036 return MakeConstant(((NumberTreeNode)a).Value / ((NumberTreeNode)b).Value); 1037 } else if ((IsNumber(a) && ((NumberTreeNode)a).Value != 1.0)) { 1034 1038 // a / x => (a * 1/a) / (x * 1/a) => 1 / (x * 1/a) 1035 1039 return MakeFraction(MakeConstant(1.0), MakeProduct(b, Invert(a))); 1036 } else if (IsVariableBase(a) && Is Constant(b)) {1040 } else if (IsVariableBase(a) && IsNumber(b)) { 1037 1041 // merge constant values into variable weights 1038 var constB = (( ConstantTreeNode)b).Value;1042 var constB = ((NumberTreeNode)b).Value; 1039 1043 ((VariableTreeNodeBase)a).Weight /= constB; 1040 1044 return a; 1041 } else if (IsFactor(a) && Is Constant(b)) {1045 } else if (IsFactor(a) && IsNumber(b)) { 1042 1046 var factNode = a as FactorVariableTreeNode; 1043 var constNode = b as ConstantTreeNode;1047 var constNode = b as NumberTreeNode; 1044 1048 return MakeFactor(factNode.Symbol, factNode.VariableName, factNode.Weights.Select(w => w / constNode.Value)); 1045 } else if (IsBinFactor(a) && Is Constant(b)) {1049 } else if (IsBinFactor(a) && IsNumber(b)) { 1046 1050 var factNode = a as BinaryFactorVariableTreeNode; 1047 var constNode = b as ConstantTreeNode;1051 var constNode = b as NumberTreeNode; 1048 1052 return MakeBinFactor(factNode.Symbol, factNode.VariableName, factNode.VariableValue, factNode.Weight / constNode.Value); 1049 1053 } else if (IsFactor(a) && IsFactor(b) && AreSameTypeAndVariable(a, b)) { … … 1070 1074 var bVar = b as VariableTreeNode; 1071 1075 return MakeConstant(aVar.Weight / bVar.Weight); 1072 } else if (IsAddition(a) && Is Constant(b)) {1076 } else if (IsAddition(a) && IsNumber(b)) { 1073 1077 return a.Subtrees 1074 1078 .Select(x => GetSimplifiedTree(x)) 1075 1079 .Select(x => MakeFraction(x, GetSimplifiedTree(b))) 1076 1080 .Aggregate((c, d) => MakeSum(c, d)); 1077 } else if (IsMultiplication(a) && Is Constant(b)) {1081 } else if (IsMultiplication(a) && IsNumber(b)) { 1078 1082 return MakeProduct(a, Invert(b)); 1079 } else if (IsDivision(a) && Is Constant(b)) {1083 } else if (IsDivision(a) && IsNumber(b)) { 1080 1084 // (a1 / a2) / c => (a1 / (a2 * c)) 1081 1085 return MakeFraction(a.GetSubtree(0), MakeProduct(a.GetSubtree(1), b)); … … 1100 1104 1101 1105 private static ISymbolicExpressionTreeNode MakeSum(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) { 1102 if (Is Constant(a) && IsConstant(b)) {1106 if (IsNumber(a) && IsNumber(b)) { 1103 1107 // fold constants 1104 (( ConstantTreeNode)a).Value += ((ConstantTreeNode)b).Value;1108 ((NumberTreeNode)a).Value += ((NumberTreeNode)b).Value; 1105 1109 return a; 1106 } else if (Is Constant(a)) {1110 } else if (IsNumber(a)) { 1107 1111 // c + x => x + c 1108 1112 // b is not constant => make sure constant is on the right 1109 1113 return MakeSum(b, a); 1110 } else if (Is Constant(b) && ((ConstantTreeNode)b).Value == 0.0) {1114 } else if (IsNumber(b) && ((NumberTreeNode)b).Value == 0.0) { 1111 1115 // x + 0 => x 1112 1116 return a; 1113 } else if (IsFactor(a) && Is Constant(b)) {1117 } else if (IsFactor(a) && IsNumber(b)) { 1114 1118 var factNode = a as FactorVariableTreeNode; 1115 var constNode = b as ConstantTreeNode;1119 var constNode = b as NumberTreeNode; 1116 1120 return MakeFactor(factNode.Symbol, factNode.VariableName, factNode.Weights.Select((w) => w + constNode.Value)); 1117 1121 } else if (IsFactor(a) && IsFactor(b) && AreSameTypeAndVariable(a, b)) { … … 1138 1142 for (int i = 0; i < a.Subtrees.Count() - 1; i++) add.AddSubtree(a.GetSubtree(i)); 1139 1143 for (int i = 0; i < b.Subtrees.Count() - 1; i++) add.AddSubtree(b.GetSubtree(i)); 1140 if (Is Constant(a.Subtrees.Last()) && IsConstant(b.Subtrees.Last())) {1144 if (IsNumber(a.Subtrees.Last()) && IsNumber(b.Subtrees.Last())) { 1141 1145 add.AddSubtree(MakeSum(a.Subtrees.Last(), b.Subtrees.Last())); 1142 } else if (Is Constant(a.Subtrees.Last())) {1146 } else if (IsNumber(a.Subtrees.Last())) { 1143 1147 add.AddSubtree(b.Subtrees.Last()); 1144 1148 add.AddSubtree(a.Subtrees.Last()); … … 1155 1159 } else if (IsAddition(b)) { 1156 1160 return MakeSum(b, a); 1157 } else if (IsAddition(a) && Is Constant(b)) {1161 } else if (IsAddition(a) && IsNumber(b)) { 1158 1162 // a is an addition and b is a constant => append b to a and make sure the constants are merged 1159 1163 var add = addSymbol.CreateTreeNode(); 1160 1164 // add all sub trees except for the last 1161 1165 for (int i = 0; i < a.Subtrees.Count() - 1; i++) add.AddSubtree(a.GetSubtree(i)); 1162 if (Is Constant(a.Subtrees.Last()))1166 if (IsNumber(a.Subtrees.Last())) 1163 1167 add.AddSubtree(MakeSum(a.Subtrees.Last(), b)); 1164 1168 else { … … 1201 1205 group node by GroupId(node) into g 1202 1206 select g; 1203 var constant = (from node in subtrees.OfType< ConstantTreeNode>()1207 var constant = (from node in subtrees.OfType<NumberTreeNode>() 1204 1208 select node.Value).DefaultIfEmpty(0.0).Sum(); 1205 var unchangedSubtrees = subtrees.Where(t => t.SubtreeCount > 0 || !(t is IVariableTreeNode) && !(t is ConstantTreeNode));1209 var unchangedSubtrees = subtrees.Where(t => t.SubtreeCount > 0 || !(t is IVariableTreeNode) && !(t is NumberTreeNode)); 1206 1210 1207 1211 foreach (var variableNodeGroup in groupedVarNodes) { … … 1250 1254 1251 1255 private static ISymbolicExpressionTreeNode MakeProduct(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) { 1252 if (Is Constant(a) && IsConstant(b)) {1256 if (IsNumber(a) && IsNumber(b)) { 1253 1257 // fold constants 1254 return MakeConstant((( ConstantTreeNode)a).Value * ((ConstantTreeNode)b).Value);1255 } else if (Is Constant(a)) {1258 return MakeConstant(((NumberTreeNode)a).Value * ((NumberTreeNode)b).Value); 1259 } else if (IsNumber(a)) { 1256 1260 // a * $ => $ * a 1257 1261 return MakeProduct(b, a); … … 1264 1268 var node1 = b as BinaryFactorVariableTreeNode; 1265 1269 return MakeBinFactor(node0.Symbol, node0.VariableName, node0.VariableValue, node0.Weight * node1.Weight); 1266 } else if (IsFactor(a) && Is Constant(b)) {1270 } else if (IsFactor(a) && IsNumber(b)) { 1267 1271 var node0 = a as FactorVariableTreeNode; 1268 var node1 = b as ConstantTreeNode;1272 var node1 = b as NumberTreeNode; 1269 1273 return MakeFactor(node0.Symbol, node0.VariableName, node0.Weights.Select(w => w * node1.Value)); 1270 } else if (IsBinFactor(a) && Is Constant(b)) {1274 } else if (IsBinFactor(a) && IsNumber(b)) { 1271 1275 var node0 = a as BinaryFactorVariableTreeNode; 1272 var node1 = b as ConstantTreeNode;1276 var node1 = b as NumberTreeNode; 1273 1277 return MakeBinFactor(node0.Symbol, node0.VariableName, node0.VariableValue, node0.Weight * node1.Value); 1274 1278 } else if (IsBinFactor(a) && IsFactor(b)) { … … 1282 1286 if (wi < 0) throw new ArgumentException(); 1283 1287 return MakeBinFactor(node1.Symbol, node1.VariableName, node1.VariableValue, node1.Weight * node0.Weights[wi]); 1284 } else if (Is Constant(b) && ((ConstantTreeNode)b).Value == 1.0) {1288 } else if (IsNumber(b) && ((NumberTreeNode)b).Value == 1.0) { 1285 1289 // $ * 1.0 => $ 1286 1290 return a; 1287 } else if (Is Constant(b) && ((ConstantTreeNode)b).Value == 0.0) {1291 } else if (IsNumber(b) && ((NumberTreeNode)b).Value == 0.0) { 1288 1292 return MakeConstant(0); 1289 } else if (Is Constant(b) && IsVariableBase(a)) {1293 } else if (IsNumber(b) && IsVariableBase(a)) { 1290 1294 // multiply constants into variables weights 1291 ((VariableTreeNodeBase)a).Weight *= (( ConstantTreeNode)b).Value;1295 ((VariableTreeNodeBase)a).Weight *= ((NumberTreeNode)b).Value; 1292 1296 return a; 1293 } else if (Is Constant(b) && IsAddition(a) ||1297 } else if (IsNumber(b) && IsAddition(a) || 1294 1298 IsFactor(b) && IsAddition(a) || 1295 1299 IsBinFactor(b) && IsAddition(a)) { … … 1321 1325 } else if (IsAbsolute(a) && IsAbsolute(b)) { 1322 1326 return MakeAbs(MakeProduct(a.GetSubtree(0), b.GetSubtree(0))); 1323 } else if (IsAbsolute(a) && Is Constant(b)) {1324 var constNode = b as ConstantTreeNode;1327 } else if (IsAbsolute(a) && IsNumber(b)) { 1328 var constNode = b as NumberTreeNode; 1325 1329 var posF = Math.Abs(constNode.Value); 1326 1330 if (constNode.Value > 0) { … … 1391 1395 var constantProduct = (from node in subtrees.OfType<VariableTreeNodeBase>() 1392 1396 select node.Weight) 1393 .Concat(from node in subtrees.OfType< ConstantTreeNode>()1397 .Concat(from node in subtrees.OfType<NumberTreeNode>() 1394 1398 select node.Value) 1395 1399 .DefaultIfEmpty(1.0) … … 1397 1401 1398 1402 var unchangedSubtrees = from tree in subtrees 1399 where tree.SubtreeCount > 0 || !(tree is IVariableTreeNode) && !(tree is ConstantTreeNode)1403 where tree.SubtreeCount > 0 || !(tree is IVariableTreeNode) && !(tree is NumberTreeNode) 1400 1404 select tree; 1401 1405 … … 1446 1450 /// <returns>-x</returns> 1447 1451 private static ISymbolicExpressionTreeNode Negate(ISymbolicExpressionTreeNode x) { 1448 if (Is Constant(x)) {1449 (( ConstantTreeNode)x).Value *= -1;1452 if (IsNumber(x)) { 1453 ((NumberTreeNode)x).Value *= -1; 1450 1454 } else if (IsVariableBase(x)) { 1451 1455 var variableTree = (VariableTreeNodeBase)x; … … 1483 1487 /// <returns></returns> 1484 1488 private static ISymbolicExpressionTreeNode Invert(ISymbolicExpressionTreeNode x) { 1485 if (Is Constant(x)) {1486 return MakeConstant(1.0 / (( ConstantTreeNode)x).Value);1489 if (IsNumber(x)) { 1490 return MakeConstant(1.0 / ((NumberTreeNode)x).Value); 1487 1491 } else if (IsFactor(x)) { 1488 1492 var factorNode = (FactorVariableTreeNode)x; … … 1497 1501 1498 1502 private static ISymbolicExpressionTreeNode MakeConstant(double value) { 1499 ConstantTreeNode constantTreeNode = (ConstantTreeNode)(constSymbol.CreateTreeNode());1500 constantTreeNode.Value = value;1501 return constantTreeNode;1503 NumberTreeNode numberTreeNode = (NumberTreeNode)(numberSymbol.CreateTreeNode()); 1504 numberTreeNode.Value = value; 1505 return numberTreeNode; 1502 1506 } 1503 1507
Note: See TracChangeset
for help on using the changeset viewer.