mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-18 21:30:38 +01:00
[AbsoluteValue] Adding formal derivate to absolute value
This will prevent diff(|x|, x, 0) to be evaluated to 0 instead of undef This fixes issue #1393 Change-Id: I73f40aa29f04c373cd3e9edbbd4fbe7be6d7a988
This commit is contained in:
committed by
Émilie Feral
parent
f562886a7e
commit
58b69c2779
@@ -41,6 +41,8 @@ public:
|
||||
// Simplification
|
||||
Expression shallowReduce(ReductionContext reductionContext) override;
|
||||
LayoutShape leftLayoutShape() const override { return LayoutShape::BoundaryPunctuation; }
|
||||
private:
|
||||
bool derivate(ReductionContext reductionContext, Expression symbol, Expression symbolValue) override;
|
||||
};
|
||||
|
||||
class AbsoluteValue final : public Expression {
|
||||
@@ -52,6 +54,7 @@ public:
|
||||
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("abs", 1, &UntypedBuilderOneChild<AbsoluteValue>);
|
||||
|
||||
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
|
||||
bool derivate(ExpressionNode::ReductionContext reductionContext, Expression symbol, Expression symbolValue);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include <poincare/absolute_value_layout.h>
|
||||
#include <poincare/complex_cartesian.h>
|
||||
#include <poincare/multiplication.h>
|
||||
#include <poincare/power.h>
|
||||
#include <poincare/derivative.h>
|
||||
#include <assert.h>
|
||||
#include <cmath>
|
||||
|
||||
@@ -31,6 +33,10 @@ Expression AbsoluteValueNode::shallowReduce(ReductionContext reductionContext) {
|
||||
return AbsoluteValue(this).shallowReduce(reductionContext);
|
||||
}
|
||||
|
||||
bool AbsoluteValueNode::derivate(ReductionContext reductionContext, Expression symbol, Expression symbolValue) {
|
||||
return AbsoluteValue(this).derivate(reductionContext, symbol, symbolValue);
|
||||
}
|
||||
|
||||
Expression AbsoluteValue::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
|
||||
Expression e = Expression::defaultShallowReduce();
|
||||
e = e.defaultHandleUnitsInChildren();
|
||||
@@ -113,4 +119,18 @@ Expression AbsoluteValue::shallowReduce(ExpressionNode::ReductionContext reducti
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Derivate of |f(x)| is f'(x)*sg(x) (and undef in 0) = f'(x)*(f(x)/|f(x)|)
|
||||
bool AbsoluteValue::derivate(ExpressionNode::ReductionContext reductionContext, Expression symbol, Expression symbolValue) {
|
||||
Expression f = childAtIndex(0);
|
||||
Multiplication result = Multiplication::Builder();
|
||||
result.addChildAtIndexInPlace(Derivative::Builder(f.clone(),
|
||||
symbol.clone().convert<Symbol>(),
|
||||
symbolValue.clone()
|
||||
),0,0);
|
||||
result.addChildAtIndexInPlace(f.clone(),1,1);
|
||||
replaceWithInPlace(result);
|
||||
result.addChildAtIndexInPlace(Power::Builder(*this,Rational::Builder(-1)),2,2);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -159,6 +159,10 @@ QUIZ_CASE(poincare_derivative_functions) {
|
||||
assert_parses_and_reduces_as("diff(diff(ln(x),x,1/tan(x)),x,z)", "undef");
|
||||
assert_parses_and_reduces_as("diff(sinh(x),x,z)", "undef");
|
||||
assert_parses_and_reduces_as("diff(cosh(x),x,z)", "undef");
|
||||
|
||||
assert_parses_and_reduces_as("diff(abs(x),x,0)", "undef");
|
||||
assert_parses_and_reduces_as("diff(abs(x),x,1)", "1");
|
||||
assert_parses_and_reduces_as("diff(abs(-2x),x,1)", "2");
|
||||
#endif
|
||||
|
||||
emptyGlobalContext();
|
||||
|
||||
Reference in New Issue
Block a user