Changeset 16344
 Timestamp:
 12/06/18 18:59:09 (13 days ago)
 Location:
 branches/2915AbsoluteSymbol
 Files:

 2 edited
Legend:
 Unmodified
 Added
 Removed

branches/2915AbsoluteSymbol/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(); 
branches/2915AbsoluteSymbol/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic3.4/SymbolicDataAnalysisExpressionTreeSimplifierTest.cs
r15583 r16344 228 228 AssertEqualAfterSimplification("( (factor a 2.0 3.0) (binfactor a x0 2.0))", "(factor a 0.0 3.0)"); 229 229 #endregion 230 231 #region abs 232 AssertEqualAfterSimplification("(abs 2.0)", "2.0"); 233 AssertEqualAfterSimplification("(abs 2.0)", "2.0"); // constant folding 234 AssertEqualAfterSimplification("(abs (exp (variable 2.0 x)))", "(exp (variable 2.0 x)))"); // exp is always positive 235 AssertEqualAfterSimplification("(abs (exp (variable 2.0 x)))", "(exp (variable 2.0 x)))"); // exp is always positive 236 AssertEqualAfterSimplification("(abs (sqr (variable 2.0 a)))", "(sqr (variable 2.0 a))"); // sqr is always positive 237 AssertEqualAfterSimplification("(abs (sqrt (variable 2.0 a)))", "(sqrt (variable 2.0 a))"); // sqrt is always positive (for our cases) 238 AssertEqualAfterSimplification("(abs (cuberoot (variable 2.0 a)))", "(cuberoot (variable 2.0 a))"); // cuberoot is always positive (for our cases) 239 240 AssertEqualAfterSimplification("(* (abs (variable 2.0 x)) 2.0)", "(abs (variable 4.0 x))"); // can multiply positive constants into abs 241 AssertEqualAfterSimplification("(* (abs (variable 2.0 x)) 2.0)", "(* (abs (variable 4.0 x)) 1.0)"); // for negative constants keep the sign 242 243 AssertEqualAfterSimplification("(abs (* (variable 1.0 a) (variable 2.0 b)))", "(* (abs (variable 1.0 a)) (abs (variable 1.0 b)) 2.0))"); 244 AssertEqualAfterSimplification("(abs (/ (variable 1.0 a) (variable 2.0 b)))", "(/ (abs (variable 1.0 a)) (abs (variable 2.0 b))))"); 245 #endregion 246 247 #region square and sqrt 248 AssertEqualAfterSimplification("(sqr (sqrt (variable 2.0 x)))", "(variable 2.0 x)"); 249 AssertEqualAfterSimplification("(sqrt (sqr (variable 2.0 x)))", "(variable 2.0 x)"); 250 AssertEqualAfterSimplification("(sqr (abs (variable 2.0 a)))", "(sqr (variable 2.0 a))"); 251 AssertEqualAfterSimplification("(sqr (exp (variable 2.0 x)))", "(exp (variable 4.0 x))"); 252 253 AssertEqualAfterSimplification("(sqr (* (variable 2.0 a) (variable 3.0 b) (variable 4.0 c)))", 254 "(* (sqr (variable 1.0 a)) (sqr (variable 1.0 b)) (sqr (variable 1.0 c)) 576)"); // 2²*3²*4² 255 #endregion 256 257 #region cube and cuberoot 258 AssertEqualAfterSimplification("(cube (cuberoot (variable 2.0 x)))", "(variable 2.0 x)"); 259 AssertEqualAfterSimplification("(cuberoot (cube (variable 2.0 x)))", "(variable 2.0 x)"); 260 AssertEqualAfterSimplification("(cube (exp (variable 2.0 x)))", "(exp (variable 6.0 x))"); 261 262 AssertEqualAfterSimplification("(sqr (cube (variable 2.0 x)))", "(pow (variable 2.0 x) 6)"); 263 AssertEqualAfterSimplification("(cube (sqr (variable 2.0 x)))", "(pow (variable 2.0 x) 6)"); 264 #endregion 265 266 #region AQ 267 AssertEqualAfterSimplification("(* (aq (variable 1.0 x) (variable 1.0 y)) 2.0)", "(aq (variable 2.0 x) (variable 1.0 y))"); 268 AssertEqualAfterSimplification("(/ (aq (variable 1.0 x) (variable 1.0 y)) 2.0)", "(aq (variable 0.5 x) (variable 1.0 y))"); 269 270 #endregion 230 271 } 231 272
Note: See TracChangeset
for help on using the changeset viewer.