From 47ce822c42262623128bdb121bbf5f7fb439d577 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Fri, 13 Oct 2017 14:30:10 +0200 Subject: [PATCH] [poincare] Improve Cosine::immediateSimplify Change-Id: Icc6329625895c9b33cf8342ab4cdea4ee748d5d4 --- poincare/Makefile | 1 + poincare/include/poincare/trigonometry.h | 20 ++++++++++++++++++++ poincare/src/cosine.cpp | 5 +++++ poincare/src/dynamic_hierarchy.cpp | 2 +- poincare/src/trigonometry.cpp | 23 +++++++++++++++++++++++ poincare/test/simplify_easy.cpp | 1 + 6 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 poincare/include/poincare/trigonometry.h create mode 100644 poincare/src/trigonometry.cpp diff --git a/poincare/Makefile b/poincare/Makefile index ddcad1875..f54152165 100644 --- a/poincare/Makefile +++ b/poincare/Makefile @@ -77,6 +77,7 @@ objs += $(addprefix poincare/src/,\ sum.o\ symbol.o\ tangent.o\ + trigonometry.o\ undefined.o\ variable_context.o\ ) diff --git a/poincare/include/poincare/trigonometry.h b/poincare/include/poincare/trigonometry.h new file mode 100644 index 000000000..bf49ce3dc --- /dev/null +++ b/poincare/include/poincare/trigonometry.h @@ -0,0 +1,20 @@ +#ifndef POINCARE_TRIGONOMETRY_H +#define POINCARE_TRIGONOMETRY_H + +#include + +namespace Poincare { + +class Trigonometry { +public: + enum class Function { + Cosine = 0, + Sine = 1, + }; + static Expression * table(const Expression * e, Function f, bool inverse); // , Function f, bool inverse + constexpr static int k_numberOfEntries = 3; +}; + +} + +#endif diff --git a/poincare/src/cosine.cpp b/poincare/src/cosine.cpp index 78af3ba93..c82d740c6 100644 --- a/poincare/src/cosine.cpp +++ b/poincare/src/cosine.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include extern "C" { #include @@ -42,6 +43,10 @@ Expression * Cosine::immediateSimplify() { } assert(r->sign() > 0); assert(r->numerator().isLowerThan(r->denominator())); + Expression * lookup = Trigonometry::table(operand(0), Trigonometry::Function::Cosine, false); + if (lookup != nullptr) { + return replaceWith(lookup, true); + } } return this; } diff --git a/poincare/src/dynamic_hierarchy.cpp b/poincare/src/dynamic_hierarchy.cpp index 742555e7f..18a8a4d78 100644 --- a/poincare/src/dynamic_hierarchy.cpp +++ b/poincare/src/dynamic_hierarchy.cpp @@ -152,8 +152,8 @@ void DynamicHierarchy::sortChildren() { } Expression * DynamicHierarchy::squashUnaryHierarchy() { - assert(parent() != nullptr); if (numberOfOperands() == 1) { + assert(parent() != nullptr); Expression * o = const_cast(operand(0)); replaceWith(o, true); return o; diff --git a/poincare/src/trigonometry.cpp b/poincare/src/trigonometry.cpp new file mode 100644 index 000000000..7ab73a03d --- /dev/null +++ b/poincare/src/trigonometry.cpp @@ -0,0 +1,23 @@ +#include +#include + +namespace Poincare { + +static_assert('\x89' == Ion::Charset::SmallPi, "Incorrect"); +constexpr const char * cheatTable[Trigonometry::k_numberOfEntries][3] = {{"\x89*12^(-1)", "\x89*5*12^(-1)", "6^(1/2)*4^(-1)+2^(1/2)*4^(-1)"}, {"\x89*8^(-1)", "\x89*3*8^(-1)", "(2+2^(1/2))^(1/2)*2^(-1)"}, {"\x89*6^(-1)", "\x89*3^(-1)", "3^(1/2)*2^(-1)"}}; + +Expression * Trigonometry::table(const Expression * e, Function f, bool inverse) { + int inputIndex = inverse ? 2 : (int)f; + int outputIndex = inverse ? (int)f : 2; + for (int i = 0; i < k_numberOfEntries; i++) { + Expression * input = Expression::parse(cheatTable[i][inputIndex]); + input->simplify(); // input expression does not change, no root needed and we can use entry after + if (input->compareTo(e) == 0) { + Expression * output = Expression::parse(cheatTable[i][outputIndex]); + return output->simplify(); + } + } + return nullptr; +} + +} diff --git a/poincare/test/simplify_easy.cpp b/poincare/test/simplify_easy.cpp index ca5733936..06b0abb89 100644 --- a/poincare/test/simplify_easy.cpp +++ b/poincare/test/simplify_easy.cpp @@ -149,6 +149,7 @@ QUIZ_CASE(poincare_simplify_easy) { assert_parsed_expression_simplify_to("cos(-P*35/29)", "cos(P*6/29)"); assert_parsed_expression_simplify_to("cos(P*340000)", "1"); assert_parsed_expression_simplify_to("cos(-P*340000)", "1"); + assert_parsed_expression_simplify_to("cos(P/12)", "(R(6)+R(2))/4"); /* This does not work but should not as it is above k_primorial32 = 1*3*5*7*11*... (product of first 32 primes. */ //assert_parsed_expression_simplify_to("1881676377434183981909562699940347954480361860897069^(1/3)", "123456789123456789");