Changeset 16543


Ignore:
Timestamp:
01/21/19 18:07:37 (8 months ago)
Author:
gkronber
Message:

#2948: added support for deriving cube, cuberoot, abs, analytic-quotient

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/DerivativeCalculator.cs

    r16294 r16543  
    4848    private static readonly Cosine cosSy = new Cosine();
    4949    private static readonly Square sqrSy = new Square();
     50    private static readonly Absolute absSy = new Absolute();
     51    private static readonly SquareRoot sqrtSy = new SquareRoot();
    5052
    5153    public static ISymbolicExpressionTreeNode Derive(ISymbolicExpressionTreeNode branch, string variableName) {
     
    138140        return Product(Div(CreateConstant(1.0), Product(CreateConstant(2.0), f)), Derive(u, variableName));
    139141      }
     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      }
    140164      if (branch.Symbol is Sine) {
    141165        var u = (ISymbolicExpressionTreeNode)branch.GetSubtree(0).Clone();
     
    195219      return cos;
    196220    }
     221    private static ISymbolicExpressionTreeNode Abs(ISymbolicExpressionTreeNode f) {
     222      var abs = absSy.CreateTreeNode();
     223      abs.AddSubtree(f);
     224      return abs;
     225    }
    197226    private static ISymbolicExpressionTreeNode Square(ISymbolicExpressionTreeNode f) {
    198227      var sqr = sqrSy.CreateTreeNode();
    199228      sqr.AddSubtree(f);
    200229      return sqr;
     230    }
     231    private static ISymbolicExpressionTreeNode SquareRoot(ISymbolicExpressionTreeNode f) {
     232      var sqrt = sqrtSy.CreateTreeNode();
     233      sqrt.AddSubtree(f);
     234      return sqrt;
    201235    }
    202236
     
    221255          !(n.Symbol is Square) &&
    222256          !(n.Symbol is SquareRoot) &&
     257          !(n.Symbol is Cube) &&
     258          !(n.Symbol is CubeRoot) &&
     259          !(n.Symbol is Absolute) &&
     260          !(n.Symbol is AnalyticQuotient) &&
    223261          !(n.Symbol is Sine) &&
    224262          !(n.Symbol is Cosine) &&
  • trunk/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/DeriveTest.cs

    r16494 r16543  
    5959      Assert.AreEqual("(SIN((3*'x')) * (-3))", Derive("cos(3*x)", "x"));
    6060      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
     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"));
    6165
    6266      Assert.AreEqual("0", Derive("(a+b)/(x+SQR(x))", "y")); // df(a,b,x) / dy = 0
Note: See TracChangeset for help on using the changeset viewer.