- Timestamp:
- 12/06/18 18:59:09 (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2915-AbsoluteSymbol/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeSimplifier.cs
r16240 r16344 263 263 if (IsConstant(original) || IsVariableBase(original)) { 264 264 return (ISymbolicExpressionTreeNode)original.Clone(); 265 } else if (IsAbsolute(original)) { 266 return SimplifyAbsolute(original); 265 267 } else if (IsAddition(original)) { 266 268 return SimplifyAddition(original); … … 771 773 } else if (IsSquareRoot(node)) { 772 774 return node.GetSubtree(0); 775 } else if (IsMultiplication(node)) { 776 // sqr( x * y ) = sqr(x) * sqr(y) 777 var mulNode = mulSymbol.CreateTreeNode(); 778 foreach (var subtree in node.Subtrees) { 779 mulNode.AddSubtree(MakeSquare(subtree)); 780 } 781 return mulNode; 782 } else if (IsAbsolute(node)) { 783 return MakeSquare(node.GetSubtree(0)); // sqr(abs(x)) = sqr(x) 784 } else if (IsExp(node)) { 785 return MakeExp(MakeProduct(node.GetSubtree(0), MakeConstant(2.0))); // sqr(exp(x)) = exp(2x) 786 } else if (IsCube(node)) { 787 return MakePower(node.GetSubtree(0), MakeConstant(6)); 773 788 } else { 774 789 var sqrNode = sqrSymbol.CreateTreeNode(); … … 790 805 } else if (IsCubeRoot(node)) { 791 806 return node.GetSubtree(0); // NOTE: not really accurate because cuberoot(x) with negative x is evaluated to NaN and after this simplification we evaluate as x 807 } else if (IsExp(node)) { 808 return MakeExp(MakeProduct(node.GetSubtree(0), MakeConstant(3))); 809 } else if (IsSquare(node)) { 810 return MakePower(node.GetSubtree(0), MakeConstant(6)); 792 811 } else { 793 812 var cubeNode = cubeSymbol.CreateTreeNode(); … … 807 826 var binFactor = node as BinaryFactorVariableTreeNode; 808 827 return MakeBinFactor(binFactor.Symbol, binFactor.VariableName, binFactor.VariableValue, Math.Abs(binFactor.Weight)); 828 } else if (IsSquare(node) || IsExp(node) || IsSquareRoot(node) || IsCubeRoot(node)) { 829 return node; // abs(sqr(x)) = sqr(x), abs(exp(x)) = exp(x) ... 830 } else if (IsMultiplication(node)) { 831 var mul = mulSymbol.CreateTreeNode(); 832 foreach (var st in node.Subtrees) { 833 mul.AddSubtree(MakeAbs(st)); 834 } 835 return mul; 836 } else if (IsDivision(node)) { 837 var div = divSymbol.CreateTreeNode(); 838 foreach (var st in node.Subtrees) { 839 div.AddSubtree(MakeAbs(st)); 840 } 841 return div; 809 842 } else { 810 843 var absNode = absSymbol.CreateTreeNode(); … … 815 848 816 849 // constant folding only 817 private static ISymbolicExpressionTreeNode MakeAnalyticalQuotient(ISymbolicExpressionTreeNode x1, ISymbolicExpressionTreeNode x2) {818 if (IsConstant( x2)) {819 var c = x2as ConstantTreeNode;820 return MakeFraction( x1, MakeConstant(Math.Sqrt(1.0 + c.Value*c.Value)));821 } else if (IsFactor( x2)) {822 var factNode = x2as FactorVariableTreeNode;823 return MakeFraction( x1, MakeFactor(factNode.Symbol, factNode.VariableName, factNode.Weights.Select(w => Math.Sqrt(1.0 + w * w))));824 } else if (IsBinFactor( x2)) {825 var binFactor = x2as BinaryFactorVariableTreeNode;826 return MakeFraction( x1, MakeBinFactor(binFactor.Symbol, binFactor.VariableName, binFactor.VariableValue, Math.Sqrt(1.0 + binFactor.Weight * binFactor.Weight)));850 private static ISymbolicExpressionTreeNode MakeAnalyticalQuotient(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) { 851 if (IsConstant(b)) { 852 var c = b as ConstantTreeNode; 853 return MakeFraction(a, MakeConstant(Math.Sqrt(1.0 + c.Value * c.Value))); 854 } else if (IsFactor(b)) { 855 var factNode = b as FactorVariableTreeNode; 856 return MakeFraction(a, MakeFactor(factNode.Symbol, factNode.VariableName, factNode.Weights.Select(w => Math.Sqrt(1.0 + w * w)))); 857 } else if (IsBinFactor(b)) { 858 var binFactor = b as BinaryFactorVariableTreeNode; 859 return MakeFraction(a, MakeBinFactor(binFactor.Symbol, binFactor.VariableName, binFactor.VariableValue, Math.Sqrt(1.0 + binFactor.Weight * binFactor.Weight))); 827 860 } else { 828 861 var aqNode = aqSymbol.CreateTreeNode(); 829 aqNode.AddSubtree( x1);830 aqNode.AddSubtree( x2);862 aqNode.AddSubtree(a); 863 aqNode.AddSubtree(b); 831 864 return aqNode; 832 865 } … … 1042 1075 // a / (b1 / b2) => (a * b2) / b1 1043 1076 return MakeFraction(MakeProduct(a, b.GetSubtree(1)), b.GetSubtree(0)); 1077 } else if (IsAnalyticalQuotient(a)) { 1078 return MakeAnalyticalQuotient(a.GetSubtree(0), MakeProduct(a.GetSubtree(1), b)); 1044 1079 } else { 1045 1080 var div = divSymbol.CreateTreeNode(); … … 1270 1305 MergeVariablesAndConstantsInProduct(a); 1271 1306 return a; 1307 } else if (IsAbsolute(a) && IsAbsolute(b)) { 1308 return MakeAbs(MakeProduct(a.GetSubtree(0), b.GetSubtree(0))); 1309 } else if (IsAbsolute(a) && IsConstant(b)) { 1310 var constNode = b as ConstantTreeNode; 1311 var posF = Math.Abs(constNode.Value); 1312 if (constNode.Value > 0) { 1313 return MakeAbs(MakeProduct(a.GetSubtree(0), MakeConstant(posF))); 1314 } else { 1315 var mul = mulSymbol.CreateTreeNode(); 1316 mul.AddSubtree(MakeAbs(MakeProduct(a.GetSubtree(0), MakeConstant(posF)))); 1317 mul.AddSubtree(MakeConstant(-1.0)); 1318 return mul; 1319 } 1320 } else if (IsAnalyticalQuotient(a)) { 1321 return MakeAnalyticalQuotient(MakeProduct(a.GetSubtree(0), b), a.GetSubtree(1)); 1272 1322 } else { 1273 1323 var mul = mulSymbol.CreateTreeNode();
Note: See TracChangeset
for help on using the changeset viewer.