Changeset 17102
- Timestamp:
- 07/08/19 00:03:06 (5 years ago)
- Location:
- stable
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
stable
- Property svn:mergeinfo changed
/trunk merged: 16358,16494,16543,16737
- Property svn:mergeinfo changed
-
stable/HeuristicLab.Problems.DataAnalysis.Symbolic
- Property svn:mergeinfo changed
/trunk/HeuristicLab.Problems.DataAnalysis.Symbolic merged: 16543,16737
- Property svn:mergeinfo changed
-
stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/DerivativeCalculator.cs
r17097 r17102 48 48 private static readonly Cosine cosSy = new Cosine(); 49 49 private static readonly Square sqrSy = new Square(); 50 private static readonly Absolute absSy = new Absolute(); 51 private static readonly SquareRoot sqrtSy = new SquareRoot(); 50 52 51 53 public static ISymbolicExpressionTreeNode Derive(ISymbolicExpressionTreeNode branch, string variableName) { … … 81 83 if (branch.SubtreeCount >= 2) { 82 84 var f = (ISymbolicExpressionTreeNode)branch.GetSubtree(0).Clone(); 83 var g = (ISymbolicExpressionTreeNode)branch.GetSubtree(1).Clone();84 85 var fprime = Derive(f, variableName); 85 var gprime = Derive(g, variableName); 86 var fgPrime = Sum(Product(f, gprime), Product(fprime, g)); 87 for (int i = 2; i < branch.SubtreeCount; i++) { 86 for (int i = 1; i < branch.SubtreeCount; i++) { 87 var g = (ISymbolicExpressionTreeNode)branch.GetSubtree(i).Clone(); 88 88 var fg = Product((ISymbolicExpressionTreeNode)f.Clone(), (ISymbolicExpressionTreeNode)g.Clone()); 89 var h = (ISymbolicExpressionTreeNode)branch.GetSubtree(i).Clone(); 90 var hPrime = Derive(h, variableName); 91 fgPrime = Sum(Product(fgPrime, h), Product(fg, hPrime)); 89 var gPrime = Derive(g, variableName); 90 var fgPrime = Sum(Product(fprime, g), Product(gPrime, f)); 91 // prepare for next iteration 92 f = fg; 93 fprime = fgPrime; 92 94 } 93 return f gPrime;95 return fprime; 94 96 } else 95 97 // multiplication with only one argument has no effect -> derive the argument … … 138 140 return Product(Div(CreateConstant(1.0), Product(CreateConstant(2.0), f)), Derive(u, variableName)); 139 141 } 142 if (branch.Symbol is CubeRoot) { 143 var f = (ISymbolicExpressionTreeNode)branch.Clone(); 144 var u = (ISymbolicExpressionTreeNode)branch.GetSubtree(0).Clone(); 145 return Product(Div(CreateConstant(1.0), Product(CreateConstant(3.0), Square(f))), Derive(u, variableName)); 146 } 147 if (branch.Symbol is Cube) { 148 var f = (ISymbolicExpressionTreeNode)branch.GetSubtree(0).Clone(); 149 return Product(Product(CreateConstant(3.0), Square(f)), Derive(f, variableName)); 150 } 151 if (branch.Symbol is Absolute) { 152 var f = (ISymbolicExpressionTreeNode)branch.GetSubtree(0).Clone(); 153 var absf = Abs((ISymbolicExpressionTreeNode)f.Clone()); 154 return Product(Div(f, absf), Derive(f, variableName)); 155 } 156 if (branch.Symbol is AnalyticQuotient) { 157 // aq(a(x), b(x)) = a(x) / sqrt(b(x)²+1) 158 var a = (ISymbolicExpressionTreeNode)branch.GetSubtree(0).Clone(); 159 var b = (ISymbolicExpressionTreeNode)branch.GetSubtree(1).Clone(); 160 161 var definition = Div(a, SquareRoot(Sum(Square(b), CreateConstant(1.0)))); 162 return Derive(definition, variableName); 163 } 140 164 if (branch.Symbol is Sine) { 141 165 var u = (ISymbolicExpressionTreeNode)branch.GetSubtree(0).Clone(); … … 195 219 return cos; 196 220 } 221 private static ISymbolicExpressionTreeNode Abs(ISymbolicExpressionTreeNode f) { 222 var abs = absSy.CreateTreeNode(); 223 abs.AddSubtree(f); 224 return abs; 225 } 197 226 private static ISymbolicExpressionTreeNode Square(ISymbolicExpressionTreeNode f) { 198 227 var sqr = sqrSy.CreateTreeNode(); 199 228 sqr.AddSubtree(f); 200 229 return sqr; 230 } 231 private static ISymbolicExpressionTreeNode SquareRoot(ISymbolicExpressionTreeNode f) { 232 var sqrt = sqrtSy.CreateTreeNode(); 233 sqrt.AddSubtree(f); 234 return sqrt; 201 235 } 202 236 … … 221 255 !(n.Symbol is Square) && 222 256 !(n.Symbol is SquareRoot) && 257 !(n.Symbol is Cube) && 258 !(n.Symbol is CubeRoot) && 259 !(n.Symbol is Absolute) && 260 !(n.Symbol is AnalyticQuotient) && 223 261 !(n.Symbol is Sine) && 224 262 !(n.Symbol is Cosine) && -
stable/HeuristicLab.Tests
- Property svn:mergeinfo changed
/trunk/HeuristicLab.Tests merged: 16358,16494,16543,16737
- Property svn:mergeinfo changed
-
stable/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/DeriveTest.cs
r17097 r17102 60 60 Assert.AreEqual("(1 / (SQR(COS((3*'x'))) * 0.333333333333333))", Derive("tan(3*x)", "x")); // diff(tan(f(x)), x) = 1.0 / cos²(f(x)), simplifier puts constant factor into the denominator 61 61 62 Assert.AreEqual("((9*'x') / ABS((3*'x')))", Derive("abs(3*x)", "x")); 63 Assert.AreEqual("(SQR('x') * 3)", Derive("cube(x)", "x")); 64 Assert.AreEqual("(1 / (SQR(CUBEROOT('x')) * 3))", Derive("cuberoot(x)", "x")); 65 66 Assert.AreEqual("0", Derive("(a+b)/(x+SQR(x))", "y")); // df(a,b,x) / dy = 0 67 68 69 Assert.AreEqual("('a' * 'b' * 'c')", Derive("a*b*c*d", "d")); 70 Assert.AreEqual("('a' / ('b' * 'c' * SQR('d') * (-1)))", Derive("a/b/c/d", "d")); 71 62 72 { 63 73 // special case: Inv(x) using only one argument to the division symbol … … 113 123 var t = new SymbolicExpressionTree(root); 114 124 115 Assert.AreEqual("(('y' * 'z' * 60) / SQR(('y' * 'z' * 20)))", // actually 3 / (4y 5z) but simplifier is not smart enough to cancel numerator and denominator116 // 60 y z / y² z² 20² == 6 / y z 40 == 3 / y z 20125 Assert.AreEqual("(('y' * 'z' * 60) / (SQR('y') * SQR('z') * 400))", // actually 3 / (4y 5z) but simplifier is not smart enough to cancel numerator and denominator 126 // 60 y z / y² z² 20² == 6 / y z 40 == 3 / y z 20 117 127 formatter.Format(DerivativeCalculator.Derive(t, "x"))); 118 Assert.AreEqual("(('x' * 'z' * (-60)) / SQR(('y' * 'z' * 20)))", // actually 3x * -(4 5 z) / (4y 5z)² = -3x / (20 y² z)119 // -3 4 5 x z / 4² y² 5² z² = -60 x z / 20² z² y² == -60 x z / y² z² 20²128 Assert.AreEqual("(('x' * 'z' * (-60)) / (SQR('y') * SQR('z') * 400))", // actually 3x * -(4 5 z) / (4y 5z)² = -3x / (20 y² z) 129 // -3 4 5 x z / 4² y² 5² z² = -60 x z / 20² z² y² == -60 x z / y² z² 20² 120 130 formatter.Format(DerivativeCalculator.Derive(t, "y"))); 121 Assert.AreEqual("(('x' * 'y' * (-60)) / SQR(('y' * 'z' * 20)))",131 Assert.AreEqual("(('x' * 'y' * (-60)) / (SQR('y') * SQR('z') * 400))", 122 132 formatter.Format(DerivativeCalculator.Derive(t, "z"))); 123 133 }
Note: See TracChangeset
for help on using the changeset viewer.