Changeset 16239 for branches/2915-AbsoluteSymbol
- Timestamp:
- 10/18/18 16:07:20 (6 years ago)
- Location:
- branches/2915-AbsoluteSymbol/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2915-AbsoluteSymbol/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeSimplifier.cs
r15583 r16239 37 37 private static readonly Division divSymbol = new Division(); 38 38 private static readonly Constant constSymbol = new Constant(); 39 private static readonly Absolute absSymbol = new Absolute(); 39 40 private static readonly Logarithm logSymbol = new Logarithm(); 40 41 private static readonly Exponential expSymbol = new Exponential(); … … 42 43 private static readonly Square sqrSymbol = new Square(); 43 44 private static readonly SquareRoot sqrtSymbol = new SquareRoot(); 45 private static readonly AnalyticalQuotient aqSymbol = new AnalyticalQuotient(); 46 private static readonly Cube cubeSymbol = new Cube(); 47 private static readonly CubeRoot cubeRootSymbol = new CubeRoot(); 44 48 private static readonly Power powSymbol = new Power(); 45 49 private static readonly Sine sineSymbol = new Sine(); … … 131 135 } 132 136 137 private static bool IsAbsolute(ISymbolicExpressionTreeNode node) { 138 return node.Symbol is Absolute; 139 } 140 133 141 // exponential 134 142 private static bool IsLog(ISymbolicExpressionTreeNode node) { … … 152 160 } 153 161 162 private static bool IsCube(ISymbolicExpressionTreeNode node) { 163 return node.Symbol is Cube; 164 } 165 166 private static bool IsCubeRoot(ISymbolicExpressionTreeNode node) { 167 return node.Symbol is CubeRoot; 168 } 169 154 170 private static bool IsPower(ISymbolicExpressionTreeNode node) { 155 171 return node.Symbol is Power; … … 167 183 private static bool IsTangent(ISymbolicExpressionTreeNode node) { 168 184 return node.Symbol is Tangent; 185 } 186 187 private static bool IsAnalyticalQuotient(ISymbolicExpressionTreeNode node) { 188 return node.Symbol is AnalyticalQuotient; 169 189 } 170 190 … … 261 281 } else if (IsSquareRoot(original)) { 262 282 return SimplifySquareRoot(original); 283 } else if (IsCube(original)) { 284 return SimplifyCube(original); 285 } else if (IsCubeRoot(original)) { 286 return SimplifyCubeRoot(original); 263 287 } else if (IsPower(original)) { 264 288 return SimplifyPower(original); … … 271 295 } else if (IsTangent(original)) { 272 296 return SimplifyTangent(original); 297 } else if (IsAnalyticalQuotient(original)) { 298 return SimplifyAnalyticalQuotient(original); 273 299 } else if (IsIfThenElse(original)) { 274 300 return SimplifyIfThenElse(original); … … 380 406 } 381 407 408 private static ISymbolicExpressionTreeNode SimplifyAbsolute(ISymbolicExpressionTreeNode original) { 409 return MakeAbs(GetSimplifiedTree(original.GetSubtree(0))); 410 } 411 382 412 private static ISymbolicExpressionTreeNode SimplifyNot(ISymbolicExpressionTreeNode original) { 383 413 return MakeNot(GetSimplifiedTree(original.GetSubtree(0))); … … 432 462 return MakeSquareRoot(GetSimplifiedTree(original.GetSubtree(0))); 433 463 } 464 private static ISymbolicExpressionTreeNode SimplifyCube(ISymbolicExpressionTreeNode original) { 465 return MakeCube(GetSimplifiedTree(original.GetSubtree(0))); 466 } 467 468 private static ISymbolicExpressionTreeNode SimplifyCubeRoot(ISymbolicExpressionTreeNode original) { 469 return MakeCubeRoot(GetSimplifiedTree(original.GetSubtree(0))); 470 } 434 471 435 472 private static ISymbolicExpressionTreeNode SimplifyLog(ISymbolicExpressionTreeNode original) { … … 443 480 private static ISymbolicExpressionTreeNode SimplifyPower(ISymbolicExpressionTreeNode original) { 444 481 return MakePower(GetSimplifiedTree(original.GetSubtree(0)), GetSimplifiedTree(original.GetSubtree(1))); 482 } 483 484 private static ISymbolicExpressionTreeNode SimplifyAnalyticalQuotient(ISymbolicExpressionTreeNode original) { 485 return MakeAnalyticalQuotient(GetSimplifiedTree(original.GetSubtree(0)), GetSimplifiedTree(original.GetSubtree(1))); 445 486 } 446 487 … … 737 778 } 738 779 780 private static ISymbolicExpressionTreeNode MakeCube(ISymbolicExpressionTreeNode node) { 781 if (IsConstant(node)) { 782 var constT = node as ConstantTreeNode; 783 return MakeConstant(constT.Value * constT.Value * constT.Value); 784 } else if (IsFactor(node)) { 785 var factNode = node as FactorVariableTreeNode; 786 return MakeFactor(factNode.Symbol, factNode.VariableName, factNode.Weights.Select(w => w * w * w)); 787 } else if (IsBinFactor(node)) { 788 var binFactor = node as BinaryFactorVariableTreeNode; 789 return MakeBinFactor(binFactor.Symbol, binFactor.VariableName, binFactor.VariableValue, binFactor.Weight * binFactor.Weight * binFactor.Weight); 790 } else if (IsCubeRoot(node)) { 791 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 792 } else { 793 var cubeNode = cubeSymbol.CreateTreeNode(); 794 cubeNode.AddSubtree(node); 795 return cubeNode; 796 } 797 } 798 799 private static ISymbolicExpressionTreeNode MakeAbs(ISymbolicExpressionTreeNode node) { 800 if (IsConstant(node)) { 801 var constT = node as ConstantTreeNode; 802 return MakeConstant(Math.Abs(constT.Value)); 803 } else if (IsFactor(node)) { 804 var factNode = node as FactorVariableTreeNode; 805 return MakeFactor(factNode.Symbol, factNode.VariableName, factNode.Weights.Select(w => Math.Abs(w))); 806 } else if (IsBinFactor(node)) { 807 var binFactor = node as BinaryFactorVariableTreeNode; 808 return MakeBinFactor(binFactor.Symbol, binFactor.VariableName, binFactor.VariableValue, Math.Abs(binFactor.Weight)); 809 } else { 810 var absNode = absSymbol.CreateTreeNode(); 811 absNode.AddSubtree(node); 812 return absNode; 813 } 814 } 815 816 // constant folding only 817 private static ISymbolicExpressionTreeNode MakeAnalyticalQuotient(ISymbolicExpressionTreeNode x1, ISymbolicExpressionTreeNode x2) { 818 if (IsConstant(x2)) { 819 var c = x2 as ConstantTreeNode; 820 return MakeFraction(x1, MakeConstant(Math.Sqrt(1.0 + c.Value*c.Value))); 821 } else if (IsFactor(x2)) { 822 var factNode = x2 as 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 = x2 as BinaryFactorVariableTreeNode; 826 return MakeFraction(x1, MakeBinFactor(binFactor.Symbol, binFactor.VariableName, binFactor.VariableValue, Math.Sqrt(1.0 + binFactor.Weight * binFactor.Weight))); 827 } else { 828 var aqNode = aqSymbol.CreateTreeNode(); 829 aqNode.AddSubtree(x1); 830 aqNode.AddSubtree(x2); 831 return aqNode; 832 } 833 } 834 739 835 private static ISymbolicExpressionTreeNode MakeSquareRoot(ISymbolicExpressionTreeNode node) { 740 836 if (IsConstant(node)) { … … 748 844 return MakeBinFactor(binFactor.Symbol, binFactor.VariableName, binFactor.VariableValue, Math.Sqrt(binFactor.Weight)); 749 845 } else if (IsSquare(node)) { 750 return node.GetSubtree(0); 846 return node.GetSubtree(0); // NOTE: not really accurate because sqrt(x) with negative x is evaluated to NaN and after this simplification we evaluate as x 751 847 } else { 752 848 var sqrtNode = sqrtSymbol.CreateTreeNode(); 753 849 sqrtNode.AddSubtree(node); 754 850 return sqrtNode; 851 } 852 } 853 854 private static ISymbolicExpressionTreeNode MakeCubeRoot(ISymbolicExpressionTreeNode node) { 855 if (IsConstant(node)) { 856 var constT = node as ConstantTreeNode; 857 return MakeConstant(Math.Pow(constT.Value, 1.0 / 3.0)); 858 } else if (IsFactor(node)) { 859 var factNode = node as FactorVariableTreeNode; 860 return MakeFactor(factNode.Symbol, factNode.VariableName, factNode.Weights.Select(w => Math.Pow(w, 1.0 / 3.0))); 861 } else if (IsBinFactor(node)) { 862 var binFactor = node as BinaryFactorVariableTreeNode; 863 return MakeBinFactor(binFactor.Symbol, binFactor.VariableName, binFactor.VariableValue, Math.Sqrt(Math.Pow(binFactor.Weight, 1.0 / 3.0))); 864 } else if (IsCube(node)) { 865 return node.GetSubtree(0); 866 } else { 867 var cubeRootNode = cubeRootSymbol.CreateTreeNode(); 868 cubeRootNode.AddSubtree(node); 869 return cubeRootNode; 755 870 } 756 871 } -
branches/2915-AbsoluteSymbol/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeToAutoDiffTermConverter.cs
r16236 r16239 85 85 diff: x => -(Math.Exp(-(x * x)) * Math.Sqrt(Math.Exp(x * x)) * x) / Math.Sqrt(2 * Math.PI)); 86 86 87 private static readonly Func<Term, UnaryFunc> abs = UnaryFunc.Factory( 88 eval: Math.Abs, 89 diff: x => Math.Sign(x) 90 ); 91 87 92 #endregion 88 93 … … 213 218 else return terms.Aggregate((a, b) => new AutoDiff.Product(a, 1.0 / b)); 214 219 } 215 if(node.Symbol is AnalyticalQuotient) { 220 if (node.Symbol is Absolute) { 221 var x1 = ConvertToAutoDiff(node.GetSubtree(0)); 222 return abs(x1); 223 } 224 if (node.Symbol is AnalyticalQuotient) { 216 225 var x1 = ConvertToAutoDiff(node.GetSubtree(0)); 217 226 var x2 = ConvertToAutoDiff(node.GetSubtree(1)); … … 233 242 return AutoDiff.TermBuilder.Power( 234 243 ConvertToAutoDiff(node.GetSubtree(0)), 0.5); 244 } 245 if (node.Symbol is Cube) { 246 return AutoDiff.TermBuilder.Power( 247 ConvertToAutoDiff(node.GetSubtree(0)), 3.0); 248 } 249 if (node.Symbol is CubeRoot) { 250 return AutoDiff.TermBuilder.Power( 251 ConvertToAutoDiff(node.GetSubtree(0)), 1.0/3.0); 235 252 } 236 253 if (node.Symbol is Sine) { … … 306 323 !(n.Symbol is Erf) && 307 324 !(n.Symbol is Norm) && 308 !(n.Symbol is StartSymbol) 325 !(n.Symbol is StartSymbol) && 326 !(n.Symbol is Absolute) && 327 !(n.Symbol is AnalyticalQuotient) && 328 !(n.Symbol is Cube) && 329 !(n.Symbol is CubeRoot) 309 330 select n).Any(); 310 331 return !containsUnknownSymbol; -
branches/2915-AbsoluteSymbol/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/InfixExpressionParser.cs
r15944 r16239 102 102 { "SQR", new Square() }, 103 103 { "SQRT", new SquareRoot() }, 104 { "CUBE", new Cube() }, 105 { "CUBEROOT", new CubeRoot() }, 104 106 { "SIN",new Sine()}, 105 107 { "COS", new Cosine()}, … … 120 122 { "DAWSON", new Dawson()}, 121 123 { "EXPINT", new ExponentialIntegralEi()}, 124 { "AQ", new AnalyticalQuotient() }, 122 125 { "MEAN", new Average()}, 123 126 { "IF", new IfThenElse()}, -
branches/2915-AbsoluteSymbol/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/SymbolicExpressionImporter.cs
r15583 r16239 41 41 {"*", new Multiplication()}, 42 42 {"-", new Subtraction()}, 43 {"ABS", new Absolute() }, 43 44 {"EXP", new Exponential()}, 44 45 {"LOG", new Logarithm()}, … … 47 48 {"SQR", new Square()}, 48 49 {"SQRT", new SquareRoot()}, 50 {"CUBE", new Cube()}, 51 {"CUBEROOT", new CubeRoot()}, 49 52 {"SIN",new Sine()}, 50 53 {"COS", new Cosine()}, … … 65 68 {"DAWSON", new Dawson()}, 66 69 {"EXPINT", new ExponentialIntegralEi()}, 70 {"AQ", new AnalyticalQuotient() }, 67 71 {"MEAN", new Average()}, 68 72 {"IF", new IfThenElse()}, -
branches/2915-AbsoluteSymbol/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeLinearInterpreter.cs
r16238 r16239 233 233 } else if (instr.opCode == OpCodes.Tan) { 234 234 instr.value = Math.Tan(code[instr.childIndex].value); 235 } else if (instr.opCode == OpCodes.Square) {235 } else if (instr.opCode == OpCodes.Square) { 236 236 instr.value = Math.Pow(code[instr.childIndex].value, 2); 237 } else if (instr.opCode == OpCodes.Cube) {237 } else if (instr.opCode == OpCodes.Cube) { 238 238 instr.value = Math.Pow(code[instr.childIndex].value, 3); 239 239 } else if (instr.opCode == OpCodes.Power) { … … 241 241 double y = Math.Round(code[instr.childIndex + 1].value); 242 242 instr.value = Math.Pow(x, y); 243 } else if (instr.opCode == OpCodes.SquareRoot) {243 } else if (instr.opCode == OpCodes.SquareRoot) { 244 244 instr.value = Math.Sqrt(code[instr.childIndex].value); 245 } else if (instr.opCode == OpCodes.CubeRoot) {245 } else if (instr.opCode == OpCodes.CubeRoot) { 246 246 instr.value = Math.Pow(code[instr.childIndex].value, 1.0 / 3.0); 247 247 } else if (instr.opCode == OpCodes.Root) {
Note: See TracChangeset
for help on using the changeset viewer.