mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-18 21:30:38 +01:00
[poincare/trigonometry] Modified shallowReduceInverseFunction
This fixes issues #1541. Formulas as asin(sin(X)) with X a large number were failling to simplify themselves into the image interval of asin ex : previous version asin(sin(6)) = 6 new version asin(sin(6)) = -2pi+6 Change-Id: Ia6200b67914224cecd2cd943bcf9bc2ff6e0447a
This commit is contained in:
committed by
Émilie Feral
parent
5569ba92a2
commit
b7bfc253eb
@@ -14,10 +14,12 @@
|
||||
#include <poincare/symbol.h>
|
||||
#include <poincare/trigonometry_cheat_table.h>
|
||||
#include <poincare/undefined.h>
|
||||
#include <poincare/opposite.h>
|
||||
#include <ion.h>
|
||||
#include <assert.h>
|
||||
#include <cmath>
|
||||
#include <float.h>
|
||||
#include <limits.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
@@ -296,7 +298,7 @@ Expression Trigonometry::shallowReduceDirectFunction(Expression & e, ExpressionN
|
||||
return e;
|
||||
}
|
||||
|
||||
Expression Trigonometry::shallowReduceInverseFunction(Expression & e, ExpressionNode::ReductionContext reductionContext) {
|
||||
Expression Trigonometry::shallowReduceInverseFunction(Expression & e, ExpressionNode::ReductionContext reductionContext) {
|
||||
assert(isInverseTrigonometryFunction(e));
|
||||
// Step 0. Map on matrix child if possible
|
||||
{
|
||||
@@ -310,13 +312,29 @@ Expression Trigonometry::shallowReduceInverseFunction(Expression & e, Expressio
|
||||
|
||||
// Step 1. Look for an expression of type "acos(cos(x))", return x
|
||||
if (AreInverseFunctions(e.childAtIndex(0), e)) {
|
||||
float trigoOp = e.childAtIndex(0).childAtIndex(0).node()->approximate(float(), reductionContext.context(), reductionContext.complexFormat(), angleUnit).toScalar();
|
||||
if ((e.type() == ExpressionNode::Type::ArcCosine && trigoOp >= 0.0f && trigoOp <= pi) ||
|
||||
(e.type() == ExpressionNode::Type::ArcSine && trigoOp >= -pi/2.0f && trigoOp <= pi/2.0f) ||
|
||||
(e.type() == ExpressionNode::Type::ArcTangent && trigoOp >= -pi/2.0f && trigoOp <= pi/2.0f)) {
|
||||
float x = e.childAtIndex(0).childAtIndex(0).node()->approximate(float(), reductionContext.context(), reductionContext.complexFormat(), angleUnit).toScalar();
|
||||
if (!(std::isinf(x) || std::isnan(x))) {
|
||||
Expression result = e.childAtIndex(0).childAtIndex(0);
|
||||
// We translate the result within [-π,π] for acos(cos), [-π/2,π/2] for asin(sin) and atan(tan)
|
||||
float k = (e.type() == ExpressionNode::Type::ArcCosine) ? std::floor(x/pi) : std::floor((x+pi/2.0f)/pi);
|
||||
if (!std::isinf(k) && !std::isnan(k) && std::fabs(k) <= static_cast<float>(INT_MAX)) {
|
||||
int kInt = static_cast<int>(k);
|
||||
Multiplication mult = Multiplication::Builder(Rational::Builder(-kInt), piExpression(reductionContext.angleUnit()));
|
||||
result = Addition::Builder(result.clone(), mult);
|
||||
mult.shallowReduce(reductionContext);
|
||||
if ((e.type() == ExpressionNode::Type::ArcCosine) && ((int)k%2 == 1)) {
|
||||
Expression sub = Subtraction::Builder(piExpression(reductionContext.angleUnit()), result);
|
||||
result.shallowReduce(reductionContext);
|
||||
result = sub;
|
||||
}
|
||||
if ((e.type() == ExpressionNode::Type::ArcSine) && ((int)k%2 == 1)) {
|
||||
Expression add = result;
|
||||
result = Opposite::Builder(add);
|
||||
add.shallowReduce(reductionContext);
|
||||
}
|
||||
}
|
||||
e.replaceWithInPlace(result);
|
||||
return result;
|
||||
return result.shallowReduce(reductionContext);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -801,7 +801,20 @@ QUIZ_CASE(poincare_simplification_trigonometry_functions) {
|
||||
assert_parsed_expression_simplify_to("acos(cos(3/2))", "3/2");
|
||||
assert_parsed_expression_simplify_to("cos(acos(3/2))", "3/2");
|
||||
assert_parsed_expression_simplify_to("cos(acos(2/3))", "2/3");
|
||||
assert_parsed_expression_simplify_to("acos(cos(12))", "acos(cos(12))");
|
||||
|
||||
assert_parsed_expression_simplify_to("acos(cos(12))", "4×π-12");
|
||||
assert_parsed_expression_simplify_to("acos(cos(2*1ᴇ10))", "20000000000");
|
||||
assert_parsed_expression_simplify_to("acos(cos(inf))", "acos(cos(inf))");
|
||||
assert_parsed_expression_simplify_to("acos(cos(9))", "-2×π+9");
|
||||
assert_parsed_expression_simplify_to("acos(cos(10^125))", "acos(cos(10^125))");
|
||||
assert_parsed_expression_simplify_to("acos(cos(1/0))", Undefined::Name());
|
||||
assert_parsed_expression_simplify_to("acos(cos(-8.8))", "\u0012-10×π+44\u0013/5");
|
||||
assert_parsed_expression_simplify_to("acos(cos(π+26))", "9×π-26");
|
||||
assert_parsed_expression_simplify_to("acos(cos(0))", "0");
|
||||
assert_parsed_expression_simplify_to("acos(cos(9π))", "π");
|
||||
assert_parsed_expression_simplify_to("acos(cos(2*1ᴇ10))", "160", User, Degree);
|
||||
assert_parsed_expression_simplify_to("acos(cos(180+50))", "130", User, Degree);
|
||||
|
||||
assert_parsed_expression_simplify_to("acos(cos(4π/7))", "\u00124×π\u0013/7");
|
||||
assert_parsed_expression_simplify_to("acos(-cos(2))", "π-2");
|
||||
assert_parsed_expression_simplify_to("acos(-1/2)", "120", User, Degree);
|
||||
@@ -820,7 +833,16 @@ QUIZ_CASE(poincare_simplification_trigonometry_functions) {
|
||||
assert_parsed_expression_simplify_to("sin(asin(2/3))", "2/3");
|
||||
assert_parsed_expression_simplify_to("sin(asin(3/2))", "3/2");
|
||||
assert_parsed_expression_simplify_to("asin(sin(3/2))", "3/2");
|
||||
assert_parsed_expression_simplify_to("asin(sin(12))", "asin(sin(12))");
|
||||
assert_parsed_expression_simplify_to("asin(sin(3.6))", "\u00125×π-18\u0013/5");
|
||||
assert_parsed_expression_simplify_to("asin(sin(-2.23))", "\u0012-100×π+223\u0013/100");
|
||||
assert_parsed_expression_simplify_to("asin(sin(-18.39))", "\u0012600×π-1839\u0013/100");
|
||||
|
||||
|
||||
assert_parsed_expression_simplify_to("asin(sin(12))", "-4×π+12");
|
||||
assert_parsed_expression_simplify_to("asin(sin(2+π))", "-π+2");
|
||||
assert_parsed_expression_simplify_to("asin(sin(90+6800))", "50", User, Degree);
|
||||
assert_parsed_expression_simplify_to("asin(sin(60-9×9×9))", "51", User, Degree);
|
||||
|
||||
assert_parsed_expression_simplify_to("asin(sin(-π/7))", "-π/7");
|
||||
assert_parsed_expression_simplify_to("asin(sin(-√(2)))", "-√(2)");
|
||||
assert_parsed_expression_simplify_to("asin(-1/2)", "-30", User, Degree);
|
||||
@@ -837,8 +859,7 @@ QUIZ_CASE(poincare_simplification_trigonometry_functions) {
|
||||
assert_parsed_expression_simplify_to("atan(tan(2/3))", "2/3");
|
||||
assert_parsed_expression_simplify_to("tan(atan(2/3))", "2/3");
|
||||
assert_parsed_expression_simplify_to("tan(atan(5/2))", "5/2");
|
||||
assert_parsed_expression_simplify_to("atan(tan(5/2))", "atan(tan(5/2))");
|
||||
assert_parsed_expression_simplify_to("atan(tan(5/2))", "atan(tan(5/2))");
|
||||
assert_parsed_expression_simplify_to("atan(tan(5/2))", "\u0012-2×π+5\u0013/2");
|
||||
assert_parsed_expression_simplify_to("atan(tan(-π/7))", "-π/7");
|
||||
assert_parsed_expression_simplify_to("atan(√(3))", "π/3");
|
||||
assert_parsed_expression_simplify_to("atan(tan(-√(2)))", "-√(2)");
|
||||
@@ -1406,7 +1427,7 @@ QUIZ_CASE(poincare_simplification_mix) {
|
||||
assert_parsed_expression_simplify_to("√(-𝐢)", "√(2)/2-√(2)/2×𝐢");
|
||||
assert_parsed_expression_simplify_to("A×cos(9)𝐢𝐢ln(2)", "-A×cos(9)×ln(2)");
|
||||
assert_parsed_expression_simplify_to("(√(2)+√(2)×𝐢)/2(√(2)+√(2)×𝐢)/2(√(2)+√(2)×𝐢)/2", "√(2)/32-√(2)/32×𝐢");
|
||||
assert_parsed_expression_simplify_to("root(5^((-𝐢)3^9),𝐢)", "1/ℯ^atan(tan(19683×ln(5)))");
|
||||
assert_parsed_expression_simplify_to("root(5^((-𝐢)3^9),𝐢)", "ℯ^\x12-19683×ln(5)+10084×π\x13");
|
||||
assert_parsed_expression_simplify_to("𝐢^𝐢", "1/ℯ^\u0012π/2\u0013");
|
||||
assert_parsed_expression_simplify_to("𝐢/(1+𝐢×√(x))", "𝐢/\u0012√(x)×𝐢+1\u0013");
|
||||
assert_parsed_expression_simplify_to("x+𝐢/(1+𝐢×√(x))", "\u0012x^\u00123/2\u0013×𝐢+𝐢+x\u0013/\u0012√(x)×𝐢+1\u0013");
|
||||
|
||||
Reference in New Issue
Block a user