mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[poicare/logarithm] Implemented didDerivate and unaryFunctionDifferential for Logarithm
Derivation now computes as expected on logarithms, as long as their base is not a function of the derivation variable. Change-Id: Ia56da1c1151c0ddf3887be84ddb4bd02664c5188
This commit is contained in:
committed by
Émilie Feral
parent
407d4bce6e
commit
eab8167a56
@@ -32,6 +32,9 @@ public:
|
||||
Expression shallowBeautify(ReductionContext reductionContext) override;
|
||||
LayoutShape leftLayoutShape() const override { return LayoutShape::MoreLetters; };
|
||||
LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; }
|
||||
// Derivation
|
||||
bool didDerivate(ReductionContext reductionContext, Expression symbol, Expression symbolValue) override;
|
||||
Expression unaryFunctionDifferential() override;
|
||||
// Evaluation
|
||||
template<typename U> static Complex<U> computeOnComplex(const std::complex<U> c, Preferences::ComplexFormat, Preferences::AngleUnit angleUnit) {
|
||||
/* log has a branch cut on ]-inf, 0]: it is then multivalued on this cut. We
|
||||
@@ -53,6 +56,8 @@ public:
|
||||
|
||||
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
|
||||
Expression shallowBeautify();
|
||||
bool didDerivate(ExpressionNode::ReductionContext reductionContext, Expression symbol, Expression symbolValue);
|
||||
Expression unaryFunctionDifferential();
|
||||
|
||||
private:
|
||||
void deepReduceChildren(ExpressionNode::ReductionContext reductionContext);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <poincare/approximation_helper.h>
|
||||
#include <poincare/arithmetic.h>
|
||||
#include <poincare/constant.h>
|
||||
#include <poincare/derivative.h>
|
||||
#include <poincare/division.h>
|
||||
#include <poincare/infinity.h>
|
||||
#include <poincare/layout_helper.h>
|
||||
@@ -68,6 +69,31 @@ Expression LogarithmNode<2>::shallowReduce(ExpressionNode::ReductionContext redu
|
||||
return Logarithm(this).shallowReduce(reductionContext);
|
||||
}
|
||||
|
||||
template <>
|
||||
bool LogarithmNode<2>::didDerivate(ReductionContext reductionContext, Expression symbol, Expression symbolValue) {
|
||||
return Logarithm(this).didDerivate(reductionContext, symbol, symbolValue);
|
||||
}
|
||||
|
||||
template <>
|
||||
Expression LogarithmNode<2>::unaryFunctionDifferential() {
|
||||
return Logarithm(this).unaryFunctionDifferential();
|
||||
}
|
||||
|
||||
/* Those two methods will not be called, as CommonLogarithm disappears in
|
||||
* reduction */
|
||||
template <>
|
||||
bool LogarithmNode<1>::didDerivate(ReductionContext reductionContext, Expression symbol, Expression symbolValue) {
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
template <>
|
||||
Expression LogarithmNode<1>::unaryFunctionDifferential() {
|
||||
assert(false);
|
||||
return Expression();
|
||||
}
|
||||
/**/
|
||||
|
||||
template<>
|
||||
Expression LogarithmNode<1>::shallowBeautify(ReductionContext reductionContext) {
|
||||
return CommonLogarithm(this);
|
||||
@@ -329,6 +355,24 @@ Integer Logarithm::simplifyLogarithmIntegerBaseInteger(Integer i, Integer & base
|
||||
return i;
|
||||
}
|
||||
|
||||
bool Logarithm::didDerivate(ExpressionNode::ReductionContext reductionContext, Expression symbol, Expression symbolValue) {
|
||||
/* We do nothing if the base is a function of the derivation variable, as the
|
||||
* log is then not an unary function anymore.
|
||||
* TODO : Check whether we want to deal with the case log(..., f(x)). */
|
||||
if (childAtIndex(1).polynomialDegree(reductionContext.context(), symbol.convert<Symbol>().name()) != 0) {
|
||||
return false;
|
||||
}
|
||||
Derivative::DerivateUnaryFunction(*this, symbol, symbolValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
Expression Logarithm::unaryFunctionDifferential() {
|
||||
/* log(x, b)` = (ln(x)/ln(b))`
|
||||
* = 1 / (x * ln(b))
|
||||
*/
|
||||
return Power::Builder(Multiplication::Builder(childAtIndex(0).clone(), NaperianLogarithm::Builder(childAtIndex(1).clone())), Rational::Builder(-1));
|
||||
}
|
||||
|
||||
Expression Logarithm::splitLogarithmInteger(Integer i, bool isDenominator, ExpressionNode::ReductionContext reductionContext) {
|
||||
assert(!i.isZero());
|
||||
assert(!i.isNegative());
|
||||
|
||||
@@ -46,4 +46,9 @@ QUIZ_CASE(poicare_differential_unary_functions) {
|
||||
assert_parses_and_reduces_as("diff(sin(2x)+sin(3x),x,π/6)","1");
|
||||
|
||||
assert_parses_and_reduces_as("diff(cos(x),x,π/2)","-1");
|
||||
|
||||
assert_parses_and_reduces_as("diff(ln(x),x,x)","1/x");
|
||||
assert_parses_and_reduces_as("diff(log(x,10),x,x)","1/(x*ln(10))");
|
||||
|
||||
assert_parses_and_reduces_as("diff(ln(cos(x)),x,a)","-tan(a)");
|
||||
}
|
||||
Reference in New Issue
Block a user