From cedcab21ec2380b05cd23f62d032d120839dc433 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Fri, 2 Aug 2019 11:43:39 +0200 Subject: [PATCH] [poincare] Tidy tests and add TODO for tests that need to be completed --- apps/calculation/test/calculation_store.cpp | 7 +- apps/solver/test/equation_store.cpp | 17 +- ion/test/utf8_decoder.cpp | 5 + poincare/Makefile | 42 +- poincare/test/addition.cpp | 94 -- poincare/test/approximation.cpp | 848 +++++++++++++++ poincare/test/arithmetic.cpp | 70 +- poincare/test/binomial_coefficient_layout.cpp | 10 - poincare/test/complex.cpp | 179 ---- poincare/test/complex_to_expression.cpp | 87 -- .../test/{user_variable.cpp => context.cpp} | 112 +- poincare/test/convert_expression_to_text.cpp | 286 ----- poincare/test/decimal.cpp | 59 -- poincare/test/division.cpp | 20 - poincare/test/expression.cpp | 56 +- poincare/test/expression_order.cpp | 28 +- poincare/test/expression_properties.cpp | 200 ++++ poincare/test/expression_serialization.cpp | 121 +++ poincare/test/expression_to_layout.cpp | 23 + poincare/test/factorial.cpp | 14 - poincare/test/float.cpp | 46 - poincare/test/fraction_layout.cpp | 63 -- poincare/test/function.cpp | 281 ----- poincare/test/function_solver.cpp | 1 + poincare/test/helper.cpp | 211 +--- poincare/test/helper.h | 45 +- poincare/test/infinity.cpp | 51 - poincare/test/layout.cpp | 108 ++ poincare/test/layout_cursor.cpp | 35 + poincare/test/layout_serialization.cpp | 34 + .../{layouts.cpp => layout_to_expression.cpp} | 333 +++--- poincare/test/logarithm.cpp | 63 -- poincare/test/matrix.cpp | 154 --- poincare/test/multiplication.cpp | 74 -- poincare/test/nth_root_layout.cpp | 10 - poincare/test/number.cpp | 44 - poincare/test/parentheses_layout.cpp | 31 - poincare/test/{parser.cpp => parsing.cpp} | 320 +++--- poincare/test/power.cpp | 111 -- poincare/test/print_float.cpp | 162 +++ poincare/test/properties.cpp | 167 --- poincare/test/random.cpp | 27 - poincare/test/rational.cpp | 108 +- poincare/test/simplification.cpp | 993 ++++++++++++++++++ poincare/test/simplify.cpp | 84 -- poincare/test/store.cpp | 69 -- poincare/test/subtraction.cpp | 17 - poincare/test/symbol.cpp | 24 - poincare/test/trigo.cpp | 534 ---------- poincare/test/vertical_offset_layout.cpp | 20 - 50 files changed, 3083 insertions(+), 3415 deletions(-) delete mode 100644 poincare/test/addition.cpp create mode 100644 poincare/test/approximation.cpp delete mode 100644 poincare/test/binomial_coefficient_layout.cpp delete mode 100644 poincare/test/complex.cpp delete mode 100644 poincare/test/complex_to_expression.cpp rename poincare/test/{user_variable.cpp => context.cpp} (58%) delete mode 100644 poincare/test/convert_expression_to_text.cpp delete mode 100644 poincare/test/decimal.cpp delete mode 100644 poincare/test/division.cpp create mode 100644 poincare/test/expression_properties.cpp create mode 100644 poincare/test/expression_serialization.cpp create mode 100644 poincare/test/expression_to_layout.cpp delete mode 100644 poincare/test/factorial.cpp delete mode 100644 poincare/test/float.cpp delete mode 100644 poincare/test/fraction_layout.cpp delete mode 100644 poincare/test/function.cpp create mode 100644 poincare/test/function_solver.cpp delete mode 100644 poincare/test/infinity.cpp create mode 100644 poincare/test/layout.cpp create mode 100644 poincare/test/layout_serialization.cpp rename poincare/test/{layouts.cpp => layout_to_expression.cpp} (69%) delete mode 100644 poincare/test/logarithm.cpp delete mode 100644 poincare/test/matrix.cpp delete mode 100644 poincare/test/multiplication.cpp delete mode 100644 poincare/test/nth_root_layout.cpp delete mode 100644 poincare/test/number.cpp delete mode 100644 poincare/test/parentheses_layout.cpp rename poincare/test/{parser.cpp => parsing.cpp} (68%) delete mode 100644 poincare/test/power.cpp create mode 100644 poincare/test/print_float.cpp delete mode 100644 poincare/test/properties.cpp delete mode 100644 poincare/test/random.cpp create mode 100644 poincare/test/simplification.cpp delete mode 100644 poincare/test/simplify.cpp delete mode 100644 poincare/test/store.cpp delete mode 100644 poincare/test/subtraction.cpp delete mode 100644 poincare/test/symbol.cpp delete mode 100644 poincare/test/trigo.cpp delete mode 100644 poincare/test/vertical_offset_layout.cpp diff --git a/apps/calculation/test/calculation_store.cpp b/apps/calculation/test/calculation_store.cpp index b5f424b17..2062b777f 100644 --- a/apps/calculation/test/calculation_store.cpp +++ b/apps/calculation/test/calculation_store.cpp @@ -63,10 +63,10 @@ void assertCalculationDisplay(const char * input, ::Calculation::Calculation::Di quiz_assert(lastCalculation->exactAndApproximateDisplayedOutputsAreEqual(context) == sign); } if (exactOutput) { - quiz_assert(strcmp(lastCalculation->exactOutputText(), exactOutput) == 0); + quiz_assert_print_if_failure(strcmp(lastCalculation->exactOutputText(), exactOutput) == 0, input); } if (approximateOutput) { - quiz_assert(strcmp(lastCalculation->approximateOutputText(), approximateOutput) == 0); + quiz_assert_print_if_failure(strcmp(lastCalculation->approximateOutputText(), approximateOutput) == 0, input); } store->deleteAll(); } @@ -135,9 +135,6 @@ QUIZ_CASE(calculation_symbolic_computation_and_parametered_expressions) { QUIZ_CASE(calculation_complex_format) { - assert(UCodePointLeftSystemParenthesis == '\u0012'); - assert(UCodePointRightSystemParenthesis == '\u0013'); - Shared::GlobalContext globalContext; CalculationStore store; diff --git a/apps/solver/test/equation_store.cpp b/apps/solver/test/equation_store.cpp index f2e3334b5..3ab0cfe33 100644 --- a/apps/solver/test/equation_store.cpp +++ b/apps/solver/test/equation_store.cpp @@ -13,7 +13,7 @@ namespace Solver { void addEquationWithText(EquationStore * equationStore, const char * text) { Ion::Storage::Record::ErrorStatus err = equationStore->addEmptyModel(); - assert(err == Ion::Storage::Record::ErrorStatus::None); + quiz_assert_print_if_failure(err == Ion::Storage::Record::ErrorStatus::None, text); (void) err; // Silence warning in DEBUG=0 Ion::Storage::Record record = equationStore->recordAtIndex(equationStore->numberOfModels()-1); Shared::ExpiringPointer model = equationStore->modelForRecord(record); @@ -28,29 +28,29 @@ void assert_equation_system_exact_solve_to(const char * equations[], EquationSto addEquationWithText(&equationStore, equations[index++]); } EquationStore::Error err = equationStore.exactSolve(&globalContext); - quiz_assert(err == error); + quiz_assert_print_if_failure(err == error, equations[0]); if (err != EquationStore::Error::NoError) { equationStore.removeAll(); return; } - quiz_assert(equationStore.type() == type); - quiz_assert(equationStore.numberOfSolutions() == numberOfSolutions); + quiz_assert_print_if_failure(equationStore.type() == type, equations[0]); + quiz_assert_print_if_failure(equationStore.numberOfSolutions() == numberOfSolutions, equations[0]); if (numberOfSolutions == INT_MAX) { equationStore.removeAll(); return; } if (type == EquationStore::Type::LinearSystem) { for (int i = 0; i < numberOfSolutions; i++) { - quiz_assert(strcmp(equationStore.variableAtIndex(i),variables[i]) == 0); + quiz_assert_print_if_failure(strcmp(equationStore.variableAtIndex(i),variables[i]) == 0, equations[0]); } } else { - quiz_assert(strcmp(equationStore.variableAtIndex(0), variables[0]) == 0); + quiz_assert_print_if_failure(strcmp(equationStore.variableAtIndex(0), variables[0]) == 0, equations[0]); } constexpr int bufferSize = 200; char buffer[bufferSize]; for (int i = 0; i < numberOfSolutions; i++) { equationStore.exactSolutionLayoutAtIndex(i, true).serializeForParsing(buffer, bufferSize); - quiz_assert(strcmp(buffer, solutions[i]) == 0); + quiz_assert_print_if_failure(strcmp(buffer, solutions[i]) == 0, equations[0]); } equationStore.removeAll(); } @@ -102,9 +102,6 @@ QUIZ_CASE(equation_solve) { const char * equations6[] = {"x-x=0", 0}; assert_equation_system_exact_solve_to(equations6, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variables1, nullptr, INT_MAX); - quiz_assert(UCodePointLeftSystemParenthesis == '\022'); - quiz_assert(UCodePointLeftSystemParenthesis == '\x12'); - const char * variablesx[] = {"x", ""}; // 2x+3=4 const char * equations7[] = {"2x+3=4", 0}; diff --git a/ion/test/utf8_decoder.cpp b/ion/test/utf8_decoder.cpp index 5eb482509..48d055054 100644 --- a/ion/test/utf8_decoder.cpp +++ b/ion/test/utf8_decoder.cpp @@ -25,6 +25,11 @@ void assert_code_point_at_previous_glyph_position_is(const char * string, const quiz_assert(d.nextCodePoint() == c); } +QUIZ_CASE(ion_utf8_code_point_system_parentheses) { + quiz_assert(UCodePointLeftSystemParenthesis == '\u0012'); + quiz_assert(UCodePointRightSystemParenthesis == '\u0013'); +} + QUIZ_CASE(ion_utf8_decode_forward) { assert_decodes_to("\x20", 0x20); assert_decodes_to("\xC2\xA2", 0xA2); diff --git a/poincare/Makefile b/poincare/Makefile index cd8660e92..7de339584 100644 --- a/poincare/Makefile +++ b/poincare/Makefile @@ -141,45 +141,27 @@ poincare_src += $(addprefix poincare/src/parsing/,\ tests_src += $(addprefix poincare/test/,\ tree/tree_handle.cpp\ tree/helpers.cpp\ - addition.cpp\ + approximation.cpp\ arithmetic.cpp\ - binomial_coefficient_layout.cpp\ - complex.cpp\ - complex_to_expression.cpp\ - convert_expression_to_text.cpp\ - decimal.cpp\ - division.cpp\ + context.cpp\ expression.cpp\ expression_order.cpp\ - factorial.cpp\ - float.cpp\ - fraction_layout.cpp\ - function.cpp\ + expression_properties.cpp\ + expression_serialization.cpp\ + expression_to_layout.cpp\ + function_solver.cpp\ helper.cpp\ helpers.cpp\ - infinity.cpp\ integer.cpp\ - layouts.cpp\ + layout.cpp\ layout_cursor.cpp\ - logarithm.cpp\ - matrix.cpp\ - multiplication.cpp\ - nth_root_layout.cpp\ - number.cpp\ - parentheses_layout.cpp\ - parser.cpp\ - power.cpp\ + layout_serialization.cpp\ + layout_to_expression.cpp\ + parsing.cpp\ + print_float.cpp\ print_int.cpp\ - properties.cpp\ rational.cpp\ - random.cpp\ - simplify.cpp\ - store.cpp\ - subtraction.cpp\ - symbol.cpp\ - trigo.cpp\ - user_variable.cpp\ - vertical_offset_layout.cpp\ + simplification.cpp\ ) ifdef POINCARE_TREE_LOG diff --git a/poincare/test/addition.cpp b/poincare/test/addition.cpp deleted file mode 100644 index 709f8b1b9..000000000 --- a/poincare/test/addition.cpp +++ /dev/null @@ -1,94 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include "helper.h" -#include "./tree/helpers.h" - -using namespace Poincare; - -static inline void assert_approximation_equals(const Expression i, float f) { - Shared::GlobalContext c; - quiz_assert(i.approximateToScalar(&c, Cartesian, Degree) == f); -} - -static inline void assert_parsed_expression_is_equal_to(const char * exp, Expression e) { - Expression result = Expression::Parse(exp); - quiz_assert(!result.isUninitialized()); - quiz_assert(result.isIdenticalTo(e)); -} - -QUIZ_CASE(poincare_addition_cast_does_not_copy) { - Rational i1 = Rational::Builder(1); - Rational i2 = Rational::Builder(2); - Addition j = Addition::Builder(i1, i2); - Expression k = j; - quiz_assert(k.identifier() == (static_cast(k)).identifier()); - quiz_assert(i1.identifier() == (static_cast(i1)).identifier()); - quiz_assert(k.identifier() == (static_cast(k)).identifier()); -} - -QUIZ_CASE(poincare_addition_without_parsing) { - Rational i1 = Rational::Builder(1); - Rational i2 = Rational::Builder(2); - Addition j = Addition::Builder(i1, i2); - assert_approximation_equals(j, 3.0f); -} - -QUIZ_CASE(poincare_addition_parsing) { - Rational i1 = Rational::Builder(1); - Rational i2 = Rational::Builder(2); - Addition j1 = Addition::Builder(i1, i2); - assert_parsed_expression_is_equal_to("1+2", j1); -} - -QUIZ_CASE(poincare_addition_evaluate) { - assert_parsed_expression_evaluates_to("1+2", "3"); - assert_parsed_expression_evaluates_to("𝐒", "𝐒"); - assert_parsed_expression_evaluates_to("𝐒+𝐒", "2×𝐒"); - assert_parsed_expression_evaluates_to("2+𝐒+4+𝐒", "6+2×𝐒"); - assert_parsed_expression_evaluates_to("[[1,2][3,4][5,6]]+3", "undef"); - assert_parsed_expression_evaluates_to("[[1,2+𝐒][3,4][5,6]]+3+𝐒", "undef"); - assert_parsed_expression_evaluates_to("3+[[1,2][3,4][5,6]]", "undef"); - assert_parsed_expression_evaluates_to("3+𝐒+[[1,2+𝐒][3,4][5,6]]", "undef"); - assert_parsed_expression_evaluates_to("[[1,2][3,4][5,6]]+[[1,2][3,4][5,6]]", "[[2,4][6,8][10,12]]"); - assert_parsed_expression_evaluates_to("[[1,2+𝐒][3,4][5,6]]+[[1,2+𝐒][3,4][5,6]]", "[[2,4+2×𝐒][6,8][10,12]]"); -} - -QUIZ_CASE(poincare_addition_simplify) { - assert_parsed_expression_simplify_to("1+x", "x+1"); - assert_parsed_expression_simplify_to("1/2+1/3+1/4+1/5+1/6+1/7", "223/140"); - assert_parsed_expression_simplify_to("1+x+4-i-2x", "-i-x+5"); - assert_parsed_expression_simplify_to("2+1", "3"); - assert_parsed_expression_simplify_to("1+2", "3"); - assert_parsed_expression_simplify_to("1+2+3+4+5+6+7", "28"); - assert_parsed_expression_simplify_to("(0+0)", "0"); - assert_parsed_expression_simplify_to("2+A", "A+2"); - assert_parsed_expression_simplify_to("1+2+3+4+5+A+6+7", "A+28"); - assert_parsed_expression_simplify_to("1+A+2+B+3", "A+B+6"); - assert_parsed_expression_simplify_to("-2+6", "4"); - assert_parsed_expression_simplify_to("-2-6", "-8"); - assert_parsed_expression_simplify_to("-A", "-A"); - assert_parsed_expression_simplify_to("A-A", "0"); - assert_parsed_expression_simplify_to("-5Ο€+3Ο€", "-2Γ—Ο€"); - assert_parsed_expression_simplify_to("1-3+A-5+2A-4A", "-A-7"); - assert_parsed_expression_simplify_to("A+B-A-B", "0"); - assert_parsed_expression_simplify_to("A+B+(-1)Γ—A+(-1)Γ—B", "0"); - assert_parsed_expression_simplify_to("2+13cos(2)-23cos(2)", "-10Γ—cos(2)+2"); - assert_parsed_expression_simplify_to("1+1+ln(2)+(5+3Γ—2)/9-4/7+1/98", "(882Γ—ln(2)+2347)/882"); - assert_parsed_expression_simplify_to("1+2+0+cos(2)", "cos(2)+3"); - assert_parsed_expression_simplify_to("A-A+2cos(2)+B-B-cos(2)", "cos(2)"); - assert_parsed_expression_simplify_to("x+3+Ο€+2Γ—x", "3Γ—x+Ο€+3"); - assert_parsed_expression_simplify_to("1/(x+1)+1/(Ο€+2)", "(x+Ο€+3)/(π×x+2Γ—x+Ο€+2)"); - assert_parsed_expression_simplify_to("1/x^2+1/(x^2Γ—Ο€)", "(Ο€+1)/(π×x^2)"); - assert_parsed_expression_simplify_to("1/x^2+1/(x^3Γ—Ο€)", "(π×x+1)/(π×x^3)"); - assert_parsed_expression_simplify_to("4x/x^2+3Ο€/(x^3Γ—Ο€)", "(4Γ—x^2+3)/x^3"); - assert_parsed_expression_simplify_to("3^(1/2)+2^(-2Γ—3^(1/2)Γ—β„―^Ο€)/2", "(2Γ—2^(2Γ—βˆš(3)Γ—β„―^Ο€)Γ—βˆš(3)+1)/(2Γ—2^(2Γ—βˆš(3)Γ—β„―^Ο€))"); - assert_parsed_expression_simplify_to("[[1,2+𝐒][3,4][5,6]]+[[1,2+𝐒][3,4][5,6]]", "[[2,4+2×𝐒][6,8][10,12]]"); - assert_parsed_expression_simplify_to("3+[[1,2][3,4]]", "undef"); - assert_parsed_expression_simplify_to("[[1][3][5]]+[[1,2+𝐒][3,4][5,6]]", "undef"); - assert_parsed_expression_simplify_to("[[1,3]]+confidence(Ο€/4, 6)+[[2,3]]", "[[3,6]]+confidence(Ο€/4,6)"); -} diff --git a/poincare/test/approximation.cpp b/poincare/test/approximation.cpp new file mode 100644 index 000000000..aa82c7fdc --- /dev/null +++ b/poincare/test/approximation.cpp @@ -0,0 +1,848 @@ +#include +#include +#include +#include +#include +#include +#include +#include "helper.h" +#include "./tree/helpers.h" + +using namespace Poincare; + +template +void assert_expression_approximates_to_scalar(const char * expression, T approximation, Preferences::AngleUnit angleUnit = Degree, Preferences::ComplexFormat complexFormat = Cartesian) { + Shared::GlobalContext globalContext; + Expression e = parse_expression(expression, false); + T result = e.approximateToScalar(&globalContext, complexFormat, angleUnit); + quiz_assert_print_if_failure((std::isnan(result) && std::isnan(approximation)) || (std::isinf(result) && std::isinf(approximation) && result*approximation >= 0) || (std::fabs(result - approximation) <= Poincare::Expression::Epsilon()), expression); +} + +QUIZ_CASE(poincare_approximation_decimal) { + assert_expression_approximates_to("-0", "0"); + assert_expression_approximates_to("-0.1", "-0.1"); + assert_expression_approximates_to("-1.", "-1"); + assert_expression_approximates_to("-.1", "-0.1"); + assert_expression_approximates_to("-0ᴇ2", "0"); + assert_expression_approximates_to("-0.1ᴇ2", "-10"); + assert_expression_approximates_to("-1.ᴇ2", "-100"); + assert_expression_approximates_to("-.1ᴇ2", "-10"); + assert_expression_approximates_to("-0ᴇ-2", "0"); + assert_expression_approximates_to("-0.1ᴇ-2", "-0.001"); + assert_expression_approximates_to("-1.ᴇ-2", "-0.01"); + assert_expression_approximates_to("-.1ᴇ-2", "-0.001"); + assert_expression_approximates_to("-.003", "-0.003"); + assert_expression_approximates_to("1.2343ᴇ-2", "0.012343"); + assert_expression_approximates_to("-567.2ᴇ2", "-56720"); + + assert_expression_approximates_to_scalar("-0", 0.0f); + assert_expression_approximates_to_scalar("-1.ᴇ-2", -0.01f); + assert_expression_approximates_to_scalar("-.003", -0.003); + assert_expression_approximates_to_scalar("1.2343ᴇ-2", 0.012343f); + assert_expression_approximates_to_scalar("-567.2ᴇ2", -56720.0); +} + + +QUIZ_CASE(poincare_approximation_rational) { + assert_expression_approximates_to("1/3", "0.3333333"); + assert_expression_approximates_to("123456/1234567", "9.9999432999586ᴇ-2"); + + assert_expression_approximates_to_scalar("1/3", 0.3333333f); + assert_expression_approximates_to_scalar("123456/1234567", 9.9999432999586E-2); +} + +template +void assert_float_approximates_to(Float f, const char * result) { + Shared::GlobalContext globalContext; + int numberOfDigits = sizeof(T) == sizeof(double) ? PrintFloat::k_numberOfStoredSignificantDigits : PrintFloat::k_numberOfPrintedSignificantDigits; + char buffer[500]; + f.template approximate(&globalContext, Cartesian, Radian).serialize(buffer, sizeof(buffer), DecimalMode, numberOfDigits); + quiz_assert_print_if_failure(strcmp(buffer, result) == 0, result); +} + +QUIZ_CASE(poincare_approximation_float) { + assert_float_approximates_to(Float::Builder(-1.23456789E30), "-1.23456789ᴇ30"); + assert_float_approximates_to(Float::Builder(1.23456789E30), "1.23456789ᴇ30"); + assert_float_approximates_to(Float::Builder(-1.23456789E-30), "-1.23456789ᴇ-30"); + assert_float_approximates_to(Float::Builder(-1.2345E-3), "-0.0012345"); + assert_float_approximates_to(Float::Builder(1.2345E-3), "0.0012345"); + assert_float_approximates_to(Float::Builder(1.2345E3), "1234.5"); + assert_float_approximates_to(Float::Builder(-1.2345E3), "-1234.5"); + assert_float_approximates_to(Float::Builder(0.99999999999995), "9.9999999999995ᴇ-1"); + assert_float_approximates_to(Float::Builder(0.00000099999999999995), "9.9999999999995ᴇ-7"); + assert_float_approximates_to(Float::Builder(0.0000009999999999901200121020102010201201201021099995), "9.9999999999012ᴇ-7"); + assert_float_approximates_to(Float::Builder(1.2345E-1), "0.12345"); + assert_float_approximates_to(Float::Builder(1), "1"); + assert_float_approximates_to(Float::Builder(0.9999999999999995), "1"); + assert_float_approximates_to(Float::Builder(1.2345E6), "1234500"); + assert_float_approximates_to(Float::Builder(-1.2345E6), "-1234500"); + assert_float_approximates_to(Float::Builder(0.0000009999999999999995), "0.000001"); + assert_float_approximates_to(Float::Builder(-1.2345E-1), "-0.12345"); + + assert_float_approximates_to(Float::Builder(INFINITY), Infinity::Name()); + assert_float_approximates_to(Float::Builder(0.0f), "0"); + assert_float_approximates_to(Float::Builder(NAN), Undefined::Name()); +} + +QUIZ_CASE(poincare_approximation_infinity) { + assert_expression_approximates_to("10^1000", "inf"); + assert_expression_approximates_to_scalar("10^1000", INFINITY); +} + +QUIZ_CASE(poincare_approximation_addition) { + assert_expression_approximates_to("1+2", "3"); + assert_expression_approximates_to("𝐒+𝐒", "2𝐒"); + assert_expression_approximates_to("2+𝐒+4+𝐒", "6+2𝐒"); + assert_expression_approximates_to("[[1,2][3,4][5,6]]+3", "undef"); + assert_expression_approximates_to("[[1,2+𝐒][3,4][5,6]]+3+𝐒", "undef"); + assert_expression_approximates_to("3+[[1,2][3,4][5,6]]", "undef"); + assert_expression_approximates_to("3+𝐒+[[1,2+𝐒][3,4][5,6]]", "undef"); + assert_expression_approximates_to("[[1,2][3,4][5,6]]+[[1,2][3,4][5,6]]", "[[2,4][6,8][10,12]]"); + assert_expression_approximates_to("[[1,2+𝐒][3,4][5,6]]+[[1,2+𝐒][3,4][5,6]]", "[[2,4+2𝐒][6,8][10,12]]"); + + assert_expression_approximates_to_scalar("1+2", 3.0f); + assert_expression_approximates_to_scalar("𝐒+𝐒", NAN); + assert_expression_approximates_to_scalar("[[1,2][3,4][5,6]]+[[1,2][3,4][5,6]]", NAN); +} + +QUIZ_CASE(poincare_approximation_multiplication) { + assert_expression_approximates_to("1Γ—2", "2"); + assert_expression_approximates_to("(3+𝐒)Γ—(4+𝐒)", "11+7𝐒"); + assert_expression_approximates_to("[[1,2][3,4][5,6]]Γ—2", "[[2,4][6,8][10,12]]"); + assert_expression_approximates_to("[[1,2+𝐒][3,4][5,6]]Γ—(3+𝐒)", "[[3+𝐒,5+5𝐒][9+3𝐒,12+4𝐒][15+5𝐒,18+6𝐒]]"); + assert_expression_approximates_to("2Γ—[[1,2][3,4][5,6]]", "[[2,4][6,8][10,12]]"); + assert_expression_approximates_to("(3+𝐒)Γ—[[1,2+𝐒][3,4][5,6]]", "[[3+𝐒,5+5𝐒][9+3𝐒,12+4𝐒][15+5𝐒,18+6𝐒]]"); + assert_expression_approximates_to("[[1,2][3,4][5,6]]Γ—[[1,2,3,4][5,6,7,8]]", "[[11,14,17,20][23,30,37,44][35,46,57,68]]"); + assert_expression_approximates_to("[[1,2+𝐒][3,4][5,6]]Γ—[[1,2+𝐒,3,4][5,6+𝐒,7,8]]", "[[11+5𝐒,13+9𝐒,17+7𝐒,20+8𝐒][23,30+7𝐒,37,44][35,46+11𝐒,57,68]]"); + + assert_expression_approximates_to_scalar("1Γ—2", 2.0f); + assert_expression_approximates_to_scalar("(3+𝐒)Γ—(4+𝐒)", NAN); + assert_expression_approximates_to_scalar("[[1,2][3,4][5,6]]Γ—2", NAN); +} + +QUIZ_CASE(poincare_approximation_power) { + assert_expression_approximates_to("2^3", "8"); + assert_expression_approximates_to("(3+𝐒)^4", "28+96𝐒"); + assert_expression_approximates_to("4^(3+𝐒)", "11.74125+62.91378𝐒"); + assert_expression_approximates_to("(3+𝐒)^(3+𝐒)", "-11.898191759852+19.592921596609𝐒"); + + assert_expression_approximates_to("0^0", Undefined::Name()); + assert_expression_approximates_to("0^2", "0"); + assert_expression_approximates_to("0^(-2)", Undefined::Name()); + + assert_expression_approximates_to("(-2)^4.2", "14.8690638497+10.8030072384𝐒", Radian, Cartesian, 12); + assert_expression_approximates_to("(-0.1)^4", "0.0001", Radian, Cartesian, 12); + + assert_expression_approximates_to("0^2", "0"); + assert_expression_approximates_to("𝐒^𝐒", "2.0787957635076ᴇ-1"); + assert_expression_approximates_to("1.0066666666667^60", "1.48985", Radian, Cartesian, 6); + assert_expression_approximates_to("1.0066666666667^60", "1.4898457083046"); + assert_expression_approximates_to("β„―^(𝐒×π)", "-1"); + assert_expression_approximates_to("β„―^(𝐒×π)", "-1"); + assert_expression_approximates_to("β„―^(𝐒×π+2)", "-7.38906", Radian, Cartesian, 6); + assert_expression_approximates_to("β„―^(𝐒×π+2)", "-7.3890560989307"); + assert_expression_approximates_to("(-1)^(1/3)", "0.5+0.8660254𝐒"); + assert_expression_approximates_to("(-1)^(1/3)", "0.5+8.6602540378444ᴇ-1𝐒"); + assert_expression_approximates_to("β„―^(𝐒×π/3)", "0.5+0.866025𝐒", Radian, Cartesian, 6); + assert_expression_approximates_to("β„―^(𝐒×π/3)", "0.5+8.6602540378444ᴇ-1𝐒"); + assert_expression_approximates_to("𝐒^(2/3)", "0.5+0.8660254𝐒"); + assert_expression_approximates_to("𝐒^(2/3)", "0.5+8.6602540378444ᴇ-1𝐒"); + + assert_expression_approximates_to_scalar("2^3", 8.0f); + assert_expression_approximates_to_scalar("(3+𝐒)^(4+𝐒)", NAN); + assert_expression_approximates_to_scalar("[[1,2][3,4]]^2", NAN); +} + +QUIZ_CASE(poincare_approximation_subtraction) { + assert_expression_approximates_to("1-2", "-1"); + assert_expression_approximates_to("3+𝐒-(4+𝐒)", "-1"); + assert_expression_approximates_to("[[1,2][3,4][5,6]]-3", "undef"); + assert_expression_approximates_to("[[1,2+𝐒][3,4][5,6]]-(4+𝐒)", "undef"); + assert_expression_approximates_to("3-[[1,2][3,4][5,6]]", "undef"); + assert_expression_approximates_to("3+𝐒-[[1,2+𝐒][3,4][5,6]]", "undef"); + assert_expression_approximates_to("[[1,2][3,4][5,6]]-[[6,5][4,3][2,1]]", "[[-5,-3][-1,1][3,5]]"); + assert_expression_approximates_to("[[1,2+𝐒][3,4][5,6]]-[[1,2+𝐒][3,4][5,6]]", "[[0,0][0,0][0,0]]"); + + assert_expression_approximates_to_scalar("1-2", -1.0f); + assert_expression_approximates_to_scalar("(1)-(4+𝐒)", NAN); + assert_expression_approximates_to_scalar("[[1,2][3,4][5,6]]-[[3,2][3,4][5,6]]", NAN); +} + +QUIZ_CASE(poincare_approximation_constant) { + assert_expression_approximates_to("𝐒", "𝐒"); + assert_expression_approximates_to("Ο€", "3.1415926535898"); + assert_expression_approximates_to("β„―", "2.718282"); + + assert_expression_approximates_to_scalar("𝐒", NAN); + assert_expression_approximates_to_scalar("Ο€", 3.141592653589793238); + assert_expression_approximates_to_scalar("β„―", 2.718281828459045235); +} + +QUIZ_CASE(poincare_approximation_division) { + assert_expression_approximates_to("1/2", "0.5"); + assert_expression_approximates_to("(3+𝐒)/(4+𝐒)", "7.6470588235294ᴇ-1+5.8823529411765ᴇ-2𝐒"); + assert_expression_approximates_to("[[1,2][3,4][5,6]]/2", "[[0.5,1][1.5,2][2.5,3]]"); + assert_expression_approximates_to("[[1,2+𝐒][3,4][5,6]]/(1+𝐒)", "[[0.5-0.5𝐒,1.5-0.5𝐒][1.5-1.5𝐒,2-2𝐒][2.5-2.5𝐒,3-3𝐒]]"); + assert_expression_approximates_to("[[1,2][3,4][5,6]]/2", "[[0.5,1][1.5,2][2.5,3]]"); + assert_expression_approximates_to("[[1,2][3,4]]/[[3,4][6,9]]", "[[-1,6.6666666666667ᴇ-1][1,0]]"); + assert_expression_approximates_to("3/[[3,4][5,6]]", "[[-9,6][7.5,-4.5]]"); + assert_expression_approximates_to("(3+4𝐒)/[[1,𝐒][3,4]]", "[[4𝐒,1][-3𝐒,𝐒]]"); + assert_expression_approximates_to("1ᴇ20/(1ᴇ20+1ᴇ20𝐒)", "0.5-0.5𝐒"); + assert_expression_approximates_to("1ᴇ155/(1ᴇ155+1ᴇ155𝐒)", "0.5-0.5𝐒"); + + assert_expression_approximates_to_scalar("1/2", 0.5f); + assert_expression_approximates_to_scalar("(3+𝐒)/(4+𝐒)", NAN); + assert_expression_approximates_to_scalar("[[1,2][3,4][5,6]]/2", NAN); +} + +QUIZ_CASE(poincare_approximation_logarithm) { + assert_expression_approximates_to("log(2,64)", "0.1666667"); + assert_expression_approximates_to("log(6,7)", "0.9207822211616"); + assert_expression_approximates_to("log(5)", "0.69897"); + assert_expression_approximates_to("ln(5)", "1.6094379124341"); + assert_expression_approximates_to("log(2+5×𝐒,64)", "0.4048317+0.2862042𝐒"); + assert_expression_approximates_to("log(6,7+4×𝐒)", "8.0843880717528ᴇ-1-2.0108238082167ᴇ-1𝐒"); + assert_expression_approximates_to("log(5+2×𝐒)", "0.731199+0.1652518𝐒"); + assert_expression_approximates_to("ln(5+2×𝐒)", "1.6836479149932+3.8050637711236ᴇ-1𝐒"); + assert_expression_approximates_to("log(0,0)", Undefined::Name()); + assert_expression_approximates_to("log(0)", "-inf"); + assert_expression_approximates_to("log(2,0)", "0"); + + // WARNING: evaluate on branch cut can be multivalued + assert_expression_approximates_to("ln(-4)", "1.3862943611199+3.1415926535898𝐒"); +} + +template +void assert_expression_approximation_is_bounded(const char * expression, T lowBound, T upBound, bool upBoundIncluded = false) { + Expression e = parse_expression(expression, true); + Shared::GlobalContext globalContext; + T result = e.approximateToScalar(&globalContext, Cartesian, Radian); + quiz_assert_print_if_failure(result >= lowBound, expression); + quiz_assert_print_if_failure(result < upBound || (result == upBound && upBoundIncluded), expression); +} + +QUIZ_CASE(poincare_approximation_function) { + assert_expression_approximates_to("abs(-1)", "1"); + assert_expression_approximates_to("abs(-1)", "1"); + + assert_expression_approximates_to("abs(3+2𝐒)", "3.605551"); + assert_expression_approximates_to("abs(3+2𝐒)", "3.605551275464"); + + assert_expression_approximates_to("abs([[1,-2][3,-4]])", "[[1,2][3,4]]"); + assert_expression_approximates_to("abs([[1,-2][3,-4]])", "[[1,2][3,4]]"); + + assert_expression_approximates_to("abs([[3+2𝐒,3+4𝐒][5+2𝐒,3+2𝐒]])", "[[3.605551,5][5.385165,3.605551]]"); + assert_expression_approximates_to("abs([[3+2𝐒,3+4𝐒][5+2𝐒,3+2𝐒]])", "[[3.605551275464,5][5.3851648071345,3.605551275464]]"); + + assert_expression_approximates_to("binomial(10, 4)", "210"); + assert_expression_approximates_to("binomial(10, 4)", "210"); + + assert_expression_approximates_to("ceil(0.2)", "1"); + assert_expression_approximates_to("ceil(0.2)", "1"); + + assert_expression_approximates_to("det([[1,23,3][4,5,6][7,8,9]])", "126", Degree, Cartesian, 6); // FIXME: the determinant computation is not precised enough to be displayed with 7 significant digits + assert_expression_approximates_to("det([[1,23,3][4,5,6][7,8,9]])", "126"); + + assert_expression_approximates_to("det([[𝐒,23-2𝐒,3×𝐒][4+𝐒,5×𝐒,6][7,8×𝐒+2,9]])", "126-231𝐒", Degree, Cartesian, 6); // FIXME: the determinant computation is not precised enough to be displayed with 7 significant digits + assert_expression_approximates_to("det([[𝐒,23-2𝐒,3×𝐒][4+𝐒,5×𝐒,6][7,8×𝐒+2,9]])", "126-231𝐒"); + + assert_expression_approximates_to("diff(2Γ—x, x, 2)", "2"); + assert_expression_approximates_to("diff(2Γ—x, x, 2)", "2"); + + assert_expression_approximates_to("diff(2Γ—TO^2, TO, 7)", "28"); + assert_expression_approximates_to("diff(2Γ—TO^2, TO, 7)", "28"); + + assert_expression_approximates_to("floor(2.3)", "2"); + assert_expression_approximates_to("floor(2.3)", "2"); + + assert_expression_approximates_to("frac(2.3)", "0.3"); + assert_expression_approximates_to("frac(2.3)", "0.3"); + + assert_expression_approximates_to("gcd(234,394)", "2"); + assert_expression_approximates_to("gcd(234,394)", "2"); + + assert_expression_approximates_to("im(2+3𝐒)", "3"); + assert_expression_approximates_to("im(2+3𝐒)", "3"); + + assert_expression_approximates_to("lcm(234,394)", "46098"); + assert_expression_approximates_to("lcm(234,394)", "46098"); + + assert_expression_approximates_to("int(x,x, 1, 2)", "1.5"); + assert_expression_approximates_to("int(x,x, 1, 2)", "1.5"); + + assert_expression_approximates_to("ln(2)", "0.6931472"); + assert_expression_approximates_to("ln(2)", "6.9314718055995ᴇ-1"); + + assert_expression_approximates_to("log(2)", "0.30103"); + assert_expression_approximates_to("log(2)", "3.0102999566398ᴇ-1"); + + assert_expression_approximates_to("permute(10, 4)", "5040"); + assert_expression_approximates_to("permute(10, 4)", "5040"); + + assert_expression_approximates_to("product(n,n, 4, 10)", "604800"); + assert_expression_approximates_to("product(n,n, 4, 10)", "604800"); + + assert_expression_approximates_to("quo(29, 10)", "2"); + assert_expression_approximates_to("quo(29, 10)", "2"); + + assert_expression_approximates_to("re(2+𝐒)", "2"); + assert_expression_approximates_to("re(2+𝐒)", "2"); + + assert_expression_approximates_to("rem(29, 10)", "9"); + assert_expression_approximates_to("rem(29, 10)", "9"); + assert_expression_approximates_to("root(2,3)", "1.259921"); + assert_expression_approximates_to("root(2,3)", "1.2599210498949"); + + assert_expression_approximates_to("√(2)", "1.414214"); + assert_expression_approximates_to("√(2)", "1.4142135623731"); + + assert_expression_approximates_to("√(-1)", "𝐒"); + assert_expression_approximates_to("√(-1)", "𝐒"); + + assert_expression_approximates_to("sum(r,r, 4, 10)", "49"); + assert_expression_approximates_to("sum(k,k, 4, 10)", "49"); + + assert_expression_approximates_to("trace([[1,2,3][4,5,6][7,8,9]])", "15"); + assert_expression_approximates_to("trace([[1,2,3][4,5,6][7,8,9]])", "15"); + + assert_expression_approximates_to("confidence(0.1, 100)", "[[0,0.2]]"); + assert_expression_approximates_to("confidence(0.1, 100)", "[[0,0.2]]"); + + assert_expression_approximates_to("dim([[1,2,3][4,5,-6]])", "[[2,3]]"); + assert_expression_approximates_to("dim([[1,2,3][4,5,-6]])", "[[2,3]]"); + + assert_expression_approximates_to("conj(3+2×𝐒)", "3-2𝐒"); + assert_expression_approximates_to("conj(3+2×𝐒)", "3-2𝐒"); + + assert_expression_approximates_to("factor(-23/4)", "-5.75"); + assert_expression_approximates_to("factor(-123/24)", "-5.125"); + + assert_expression_approximates_to("inverse([[1,2,3][4,5,-6][7,8,9]])", "[[-1.2917,-0.083333,0.375][1.0833,0.16667,-0.25][0.041667,-0.083333,0.041667]]", Degree, Cartesian, 5); // inverse is not precise enough to display 7 significative digits + assert_expression_approximates_to("inverse([[1,2,3][4,5,-6][7,8,9]])", "[[-1.2916666666667,-8.3333333333333ᴇ-2,0.375][1.0833333333333,1.6666666666667ᴇ-1,-0.25][4.1666666666667ᴇ-2,-8.3333333333333ᴇ-2,4.1666666666667ᴇ-2]]"); + assert_expression_approximates_to("inverse([[𝐒,23-2𝐒,3×𝐒][4+𝐒,5×𝐒,6][7,8×𝐒+2,9]])", "[[-0.0118-0.0455𝐒,-0.5-0.727𝐒,0.318+0.489𝐒][0.0409+0.00364𝐒,0.04-0.0218𝐒,-0.0255+0.00091𝐒][0.00334-0.00182𝐒,0.361+0.535𝐒,-0.13-0.358𝐒]]", Degree, Cartesian, 3); // inverse is not precise enough to display 7 significative digits + assert_expression_approximates_to("inverse([[𝐒,23-2𝐒,3×𝐒][4+𝐒,5×𝐒,6][7,8×𝐒+2,9]])", "[[-0.0118289353958-0.0454959053685𝐒,-0.500454959054-0.727024567789𝐒,0.31847133758+0.488626023658𝐒][0.0409463148317+3.63967242948ᴇ-3𝐒,0.0400363967243-0.0218380345769𝐒,-0.0254777070064+9.0991810737ᴇ-4𝐒][3.33636639369ᴇ-3-1.81983621474ᴇ-3𝐒,0.36093418259+0.534728541098𝐒,-0.130118289354-0.357597816197𝐒]]", Degree, Cartesian, 12); // FIXME: inverse is not precise enough to display 14 significative digits + + assert_expression_approximates_to("prediction(0.1, 100)", "[[0,0.2]]"); + assert_expression_approximates_to("prediction(0.1, 100)", "[[0,0.2]]"); + + assert_expression_approximates_to("prediction95(0.1, 100)", "[[0.0412,0.1588]]"); + assert_expression_approximates_to("prediction95(0.1, 100)", "[[0.0412,0.1588]]"); + + assert_expression_approximates_to("product(2+k×𝐒,k, 1, 5)", "-100-540𝐒"); + assert_expression_approximates_to("product(2+o×𝐒,o, 1, 5)", "-100-540𝐒"); + + assert_expression_approximates_to("root(3+𝐒, 3)", "1.459366+0.1571201𝐒"); + assert_expression_approximates_to("root(3+𝐒, 3)", "1.4593656008684+1.5712012294394ᴇ-1𝐒"); + + assert_expression_approximates_to("root(3, 3+𝐒)", "1.382007-0.1524428𝐒"); + assert_expression_approximates_to("root(3, 3+𝐒)", "1.3820069623326-0.1524427794159𝐒"); + + assert_expression_approximates_to("root(5^((-𝐒)3^9),𝐒)", "3.504", Degree, Cartesian, 4); + assert_expression_approximates_to("root(5^((-𝐒)3^9),𝐒)", "3.5039410843", Degree, Cartesian, 11); + + assert_expression_approximates_to("√(3+𝐒)", "1.755317+0.2848488𝐒"); + assert_expression_approximates_to("√(3+𝐒)", "1.7553173018244+2.8484878459314ᴇ-1𝐒"); + + assert_expression_approximates_to("sign(-23+1)", "-1"); + assert_expression_approximates_to("sign(inf)", "1"); + assert_expression_approximates_to("sign(-inf)", "-1"); + assert_expression_approximates_to("sign(0)", "0"); + assert_expression_approximates_to("sign(-0)", "0"); + assert_expression_approximates_to("sign(x)", "undef"); + assert_expression_approximates_to("sign(2+𝐒)", "undef"); + assert_expression_approximates_to("sign(undef)", "undef"); + + assert_expression_approximates_to("sum(2+n×𝐒,n,1,5)", "10+15𝐒"); + assert_expression_approximates_to("sum(2+n×𝐒,n,1,5)", "10+15𝐒"); + + assert_expression_approximates_to("transpose([[1,2,3][4,5,-6][7,8,9]])", "[[1,4,7][2,5,8][3,-6,9]]"); + assert_expression_approximates_to("transpose([[1,7,5][4,2,8]])", "[[1,4][7,2][5,8]]"); + assert_expression_approximates_to("transpose([[1,2][4,5][7,8]])", "[[1,4,7][2,5,8]]"); + assert_expression_approximates_to("transpose([[1,2,3][4,5,-6][7,8,9]])", "[[1,4,7][2,5,8][3,-6,9]]"); + assert_expression_approximates_to("transpose([[1,7,5][4,2,8]])", "[[1,4][7,2][5,8]]"); + assert_expression_approximates_to("transpose([[1,2][4,5][7,8]])", "[[1,4,7][2,5,8]]"); + + assert_expression_approximates_to("round(2.3246,3)", "2.325"); + assert_expression_approximates_to("round(2.3245,3)", "2.325"); + + assert_expression_approximates_to("6!", "720"); + assert_expression_approximates_to("6!", "720"); + + assert_expression_approximates_to("√(-1)", "𝐒"); + assert_expression_approximates_to("√(-1)", "𝐒"); + + assert_expression_approximates_to("root(-1,3)", "0.5+0.8660254𝐒"); + assert_expression_approximates_to("root(-1,3)", "0.5+8.6602540378444ᴇ-1𝐒"); + + assert_expression_approximates_to("int(int(xΓ—x,x,0,x),x,0,4)", "21.33333"); + assert_expression_approximates_to("int(int(xΓ—x,x,0,x),x,0,4)", "21.333333333333"); + + assert_expression_approximates_to("int(1+cos(e),e, 0, 180)", "180"); + assert_expression_approximates_to("int(1+cos(e),e, 0, 180)", "180"); + + assert_expression_approximation_is_bounded("random()", 0.0f, 1.0f); + assert_expression_approximation_is_bounded("random()", 0.0, 1.0); + + assert_expression_approximation_is_bounded("randint(4,45)", 4.0f, 45.0f, true); + assert_expression_approximation_is_bounded("randint(4,45)", 4.0, 45.0, true); +} + +QUIZ_CASE(poincare_approximation_trigonometry_functions) { + /* cos: R -> R (oscillator) + * Ri -> R (even) + */ + // On R + assert_expression_approximates_to("cos(2)", "-4.1614683654714ᴇ-1", Radian); + assert_expression_approximates_to("cos(2)", "0.9993908270191", Degree); + // Oscillator + assert_expression_approximates_to("cos(Ο€/2)", "0", Radian); + assert_expression_approximates_to("cos(3Γ—Ο€/2)", "0", Radian); + assert_expression_approximates_to("cos(3Γ—Ο€)", "-1", Radian); + assert_expression_approximates_to("cos(-540)", "-1", Degree); + // On RΓ—i + assert_expression_approximates_to("cos(-2×𝐒)", "3.7621956910836", Radian); + assert_expression_approximates_to("cos(-2×𝐒)", "1.0006092967033", Degree); + // Symmetry: even + assert_expression_approximates_to("cos(2×𝐒)", "3.7621956910836", Radian); + assert_expression_approximates_to("cos(2×𝐒)", "1.0006092967033", Degree); + // On C + assert_expression_approximates_to("cos(𝐒-4)", "-1.008625-0.8893952𝐒", Radian); + assert_expression_approximates_to("cos(𝐒-4)", "0.997716+0.00121754𝐒", Degree, Cartesian, 6); + + /* sin: R -> R (oscillator) + * Ri -> Ri (odd) + */ + // On R + assert_expression_approximates_to("sin(2)", "9.0929742682568ᴇ-1", Radian); + assert_expression_approximates_to("sin(2)", "3.4899496702501ᴇ-2", Degree); + // Oscillator + assert_expression_approximates_to("sin(Ο€/2)", "1", Radian); + assert_expression_approximates_to("sin(3Γ—Ο€/2)", "-1", Radian); + assert_expression_approximates_to("sin(3Γ—Ο€)", "0", Radian); + assert_expression_approximates_to("sin(-540)", "0", Degree); + // On RΓ—i + assert_expression_approximates_to("sin(3×𝐒)", "10.01787492741𝐒", Radian); + assert_expression_approximates_to("sin(3×𝐒)", "0.05238381𝐒", Degree); + // Symmetry: odd + assert_expression_approximates_to("sin(-3×𝐒)", "-10.01787492741𝐒", Radian); + assert_expression_approximates_to("sin(-3×𝐒)", "-0.05238381𝐒", Degree); + // On: C + assert_expression_approximates_to("sin(𝐒-4)", "1.16781-0.768163𝐒", Radian, Cartesian, 6); + assert_expression_approximates_to("sin(𝐒-4)", "-0.0697671+0.0174117𝐒", Degree, Cartesian, 6); + assert_expression_approximates_to("sin(1.234567890123456ᴇ-15)", "1.23457ᴇ-15", Radian, Cartesian, 6); + + /* tan: R -> R (tangent-style) + * Ri -> Ri (odd) + */ + // On R + assert_expression_approximates_to("tan(2)", "-2.1850398632615", Radian); + assert_expression_approximates_to("tan(2)", "3.4920769491748ᴇ-2", Degree); + // Tangent-style + assert_expression_approximates_to("tan(Ο€/2)", Undefined::Name(), Radian); + assert_expression_approximates_to("tan(3Γ—Ο€/2)", Undefined::Name(), Radian); + assert_expression_approximates_to("tan(3Γ—Ο€)", "0", Radian); + assert_expression_approximates_to("tan(-540)", "0", Degree); + // On RΓ—i + assert_expression_approximates_to("tan(-2×𝐒)", "-9.6402758007582ᴇ-1𝐒", Radian); + assert_expression_approximates_to("tan(-2×𝐒)", "-0.03489241𝐒", Degree); + // Symmetry: odd + assert_expression_approximates_to("tan(2×𝐒)", "9.6402758007582ᴇ-1𝐒", Radian); + assert_expression_approximates_to("tan(2×𝐒)", "0.03489241𝐒", Degree); + // On C + assert_expression_approximates_to("tan(𝐒-4)", "-0.273553+1.00281𝐒", Radian, Cartesian, 6); + assert_expression_approximates_to("tan(𝐒-4)", "-0.0699054+0.0175368𝐒", Degree, Cartesian, 6); + + /* acos: [-1,1] -> R + * ]-inf,-1[ -> Ο€+RΓ—i (odd imaginary) + * ]1, inf[ -> RΓ—i (odd imaginary) + * RΓ—i -> Ο€/2+RΓ—i (odd imaginary) + */ + // On [-1, 1] + assert_expression_approximates_to("acos(0.5)", "1.0471975511966", Radian); + assert_expression_approximates_to("acos(0.03)", "1.5407918249714", Radian); + assert_expression_approximates_to("acos(0.5)", "60", Degree); + // On [1, inf[ + assert_expression_approximates_to("acos(2)", "1.3169578969248𝐒", Radian); + assert_expression_approximates_to("acos(2)", "75.456129290217𝐒", Degree); + // Symmetry: odd on imaginary + assert_expression_approximates_to("acos(-2)", "3.1415926535898-1.3169578969248𝐒", Radian); + assert_expression_approximates_to("acos(-2)", "180-75.456129290217𝐒", Degree); + // On ]-inf, -1[ + assert_expression_approximates_to("acos(-32)", "3.14159265359-4.158638853279𝐒", Radian, Cartesian, 13); + assert_expression_approximates_to("acos(-32)", "180-238.3𝐒", Degree, Cartesian, 4); + // On RΓ—i + assert_expression_approximates_to("acos(3×𝐒)", "1.5708-1.8184𝐒", Radian, Cartesian, 5); + assert_expression_approximates_to("acos(3×𝐒)", "90-104.19𝐒", Degree, Cartesian, 5); + // Symmetry: odd on imaginary + assert_expression_approximates_to("acos(-3×𝐒)", "1.5708+1.8184𝐒", Radian, Cartesian, 5); + assert_expression_approximates_to("acos(-3×𝐒)", "90+104.19𝐒", Degree, Cartesian, 5); + // On C + assert_expression_approximates_to("acos(𝐒-4)", "2.8894-2.0966𝐒", Radian, Cartesian, 5); + assert_expression_approximates_to("acos(𝐒-4)", "165.551-120.126𝐒", Degree, Cartesian, 6); + // Key values + assert_expression_approximates_to("acos(0)", "90", Degree); + assert_expression_approximates_to("acos(-1)", "180", Degree); + assert_expression_approximates_to("acos(1)", "0", Degree); + + /* asin: [-1,1] -> R + * ]-inf,-1[ -> -Ο€/2+RΓ—i (odd) + * ]1, inf[ -> Ο€/2+RΓ—i (odd) + * RΓ—i -> RΓ—i (odd) + */ + // On [-1, 1] + assert_expression_approximates_to("asin(0.5)", "0.5235987755983", Radian); + assert_expression_approximates_to("asin(0.03)", "3.0004501823477ᴇ-2", Radian); + assert_expression_approximates_to("asin(0.5)", "30", Degree); + // On [1, inf[ + assert_expression_approximates_to("asin(2)", "1.5707963267949-1.3169578969248𝐒", Radian); + assert_expression_approximates_to("asin(2)", "90-75.456129290217𝐒", Degree); + // Symmetry: odd + assert_expression_approximates_to("asin(-2)", "-1.5707963267949+1.3169578969248𝐒", Radian); + assert_expression_approximates_to("asin(-2)", "-90+75.456129290217𝐒", Degree); + // On ]-inf, -1[ + assert_expression_approximates_to("asin(-32)", "-1.571+4.159𝐒", Radian, Cartesian, 4); + assert_expression_approximates_to("asin(-32)", "-90+238𝐒", Degree, Cartesian, 3); + // On RΓ—i + assert_expression_approximates_to("asin(3×𝐒)", "1.8184464592321𝐒", Radian); + // Symmetry: odd + assert_expression_approximates_to("asin(-3×𝐒)", "-1.8184464592321𝐒", Radian); + // On C + assert_expression_approximates_to("asin(𝐒-4)", "-1.3186+2.0966𝐒", Radian, Cartesian, 5); + assert_expression_approximates_to("asin(𝐒-4)", "-75.551+120.13𝐒", Degree, Cartesian, 5); + // Key values + assert_expression_approximates_to("asin(0)", "0", Degree); + assert_expression_approximates_to("asin(-1)", "-90", Degree); + assert_expression_approximates_to("asin(1)", "90", Degree); + + /* atan: R -> R (odd) + * [-𝐒,𝐒] -> R×𝐒 (odd) + * ]-inf×𝐒,-𝐒[ -> -Ο€/2+R×𝐒 (odd) + * ]𝐒, inf×𝐒[ -> Ο€/2+R×𝐒 (odd) + */ + // On R + assert_expression_approximates_to("atan(2)", "1.1071487177941", Radian); + assert_expression_approximates_to("atan(0.01)", "9.9996666866652ᴇ-3", Radian); + assert_expression_approximates_to("atan(2)", "63.434948822922", Degree); + assert_expression_approximates_to("atan(0.5)", "0.4636476", Radian); + // Symmetry: odd + assert_expression_approximates_to("atan(-2)", "-1.1071487177941", Radian); + // On [-𝐒, 𝐒] + assert_expression_approximates_to("atan(0.2×𝐒)", "0.202733𝐒", Radian, Cartesian, 6); + // Symmetry: odd + assert_expression_approximates_to("atan(-0.2×𝐒)", "-0.202733𝐒", Radian, Cartesian, 6); + // On [𝐒, inf×𝐒[ + assert_expression_approximates_to("atan(26×𝐒)", "1.5707963267949+3.8480520568064ᴇ-2𝐒", Radian); + assert_expression_approximates_to("atan(26×𝐒)", "90+2.2047714220164𝐒", Degree); + // Symmetry: odd + assert_expression_approximates_to("atan(-26×𝐒)", "-1.5707963267949-3.8480520568064ᴇ-2𝐒", Radian); + // On ]-inf×𝐒, -𝐒[ + assert_expression_approximates_to("atan(-3.4×𝐒)", "-1.570796-0.3030679𝐒", Radian); + assert_expression_approximates_to("atan(-3.4×𝐒)", "-90-17.3645𝐒", Degree, Cartesian, 6); + // On C + assert_expression_approximates_to("atan(𝐒-4)", "-1.338973+0.05578589𝐒", Radian); + assert_expression_approximates_to("atan(𝐒-4)", "-76.7175+3.1963𝐒", Degree, Cartesian, 6); + // Key values + assert_expression_approximates_to("atan(0)", "0", Degree); + assert_expression_approximates_to("atan(-𝐒)", "-inf𝐒", Radian); + assert_expression_approximates_to("atan(𝐒)", "inf𝐒", Radian); + + /* cosh: R -> R (even) + * R×𝐒 -> R (oscillator) + */ + // On R + assert_expression_approximates_to("cosh(2)", "3.7621956910836", Radian); + assert_expression_approximates_to("cosh(2)", "3.7621956910836", Degree); + // Symmetry: even + assert_expression_approximates_to("cosh(-2)", "3.7621956910836", Radian); + assert_expression_approximates_to("cosh(-2)", "3.7621956910836", Degree); + // On R×𝐒 + assert_expression_approximates_to("cosh(43×𝐒)", "5.5511330152063ᴇ-1", Radian); + // Oscillator + assert_expression_approximates_to("cosh(π×𝐒/2)", "0", Radian); + assert_expression_approximates_to("cosh(5×π×𝐒/2)", "0", Radian); + assert_expression_approximates_to("cosh(8×π×𝐒/2)", "1", Radian); + assert_expression_approximates_to("cosh(9×π×𝐒/2)", "0", Radian); + // On C + assert_expression_approximates_to("cosh(𝐒-4)", "14.7547-22.9637𝐒", Radian, Cartesian, 6); + assert_expression_approximates_to("cosh(𝐒-4)", "14.7547-22.9637𝐒", Degree, Cartesian, 6); + + /* sinh: R -> R (odd) + * R×𝐒 -> R×𝐒 (oscillator) + */ + // On R + assert_expression_approximates_to("sinh(2)", "3.626860407847", Radian); + assert_expression_approximates_to("sinh(2)", "3.626860407847", Degree); + // Symmetry: odd + assert_expression_approximates_to("sinh(-2)", "-3.626860407847", Radian); + // On R×𝐒 + assert_expression_approximates_to("sinh(43×𝐒)", "-0.8317747426286𝐒", Radian); + // Oscillator + assert_expression_approximates_to("sinh(π×𝐒/2)", "𝐒", Radian); + assert_expression_approximates_to("sinh(5×π×𝐒/2)", "𝐒", Radian); + assert_expression_approximates_to("sinh(7×π×𝐒/2)", "-𝐒", Radian); + assert_expression_approximates_to("sinh(8×π×𝐒/2)", "0", Radian); + assert_expression_approximates_to("sinh(9×π×𝐒/2)", "𝐒", Radian); + // On C + assert_expression_approximates_to("sinh(𝐒-4)", "-14.7448+22.9791𝐒", Radian, Cartesian, 6); + assert_expression_approximates_to("sinh(𝐒-4)", "-14.7448+22.9791𝐒", Degree, Cartesian, 6); + + /* tanh: R -> R (odd) + * R×𝐒 -> R×𝐒 (tangent-style) + */ + // On R + assert_expression_approximates_to("tanh(2)", "9.6402758007582ᴇ-1", Radian); + // Symmetry: odd + assert_expression_approximates_to("tanh(-2)", "-9.6402758007582ᴇ-1", Degree); + // On RΓ—i + assert_expression_approximates_to("tanh(43×𝐒)", "-1.4983873388552𝐒", Radian); + // Tangent-style + // FIXME: this depends on the libm implementation and does not work on travis/appveyor servers + /*assert_expression_approximates_to("tanh(π×𝐒/2)", Undefined::Name(), Radian); + assert_expression_approximates_to("tanh(5×π×𝐒/2)", Undefined::Name(), Radian); + assert_expression_approximates_to("tanh(7×π×𝐒/2)", Undefined::Name(), Radian); + assert_expression_approximates_to("tanh(8×π×𝐒/2)", "0", Radian); + assert_expression_approximates_to("tanh(9×π×𝐒/2)", Undefined::Name(), Radian);*/ + // On C + assert_expression_approximates_to("tanh(𝐒-4)", "-1.00028+0.000610241𝐒", Radian, Cartesian, 6); + assert_expression_approximates_to("tanh(𝐒-4)", "-1.00028+0.000610241𝐒", Degree, Cartesian, 6); + + /* acosh: [-1,1] -> R×𝐒 + * ]-inf,-1[ -> π×𝐒+R (even on real) + * ]1, inf[ -> R (even on real) + * ]-inf×𝐒, 0[ -> -Ο€/2×𝐒+R (even on real) + * ]0, inf*𝐒[ -> Ο€/2×𝐒+R (even on real) + */ + // On [-1,1] + assert_expression_approximates_to("acosh(2)", "1.3169578969248", Radian); + assert_expression_approximates_to("acosh(2)", "1.3169578969248", Degree); + // On ]-inf, -1[ + assert_expression_approximates_to("acosh(-4)", "2.0634370688956+3.1415926535898𝐒", Radian); + assert_expression_approximates_to("acosh(-4)", "2.06344+3.14159𝐒", Radian, Cartesian, 6); + // On ]1,inf[: Symmetry: even on real + assert_expression_approximates_to("acosh(4)", "2.0634370688956", Radian); + assert_expression_approximates_to("acosh(4)", "2.063437", Radian); + // On ]-inf×𝐒, 0[ + assert_expression_approximates_to("acosh(-42×𝐒)", "4.4309584920805-1.5707963267949𝐒", Radian); + assert_expression_approximates_to("acosh(-42×𝐒)", "4.431-1.571𝐒", Radian, Cartesian, 4); + // On ]0, 𝐒×inf[: Symmetry: even on real + assert_expression_approximates_to("acosh(42×𝐒)", "4.4309584920805+1.5707963267949𝐒", Radian); + assert_expression_approximates_to("acosh(42×𝐒)", "4.431+1.571𝐒", Radian, Cartesian, 4); + // On C + assert_expression_approximates_to("acosh(𝐒-4)", "2.0966+2.8894𝐒", Radian, Cartesian, 5); + assert_expression_approximates_to("acosh(𝐒-4)", "2.0966+2.8894𝐒", Degree, Cartesian, 5); + // Key values + //assert_expression_approximates_to("acosh(-1)", "3.1415926535898𝐒", Radian); + assert_expression_approximates_to("acosh(1)", "0", Radian); + assert_expression_approximates_to("acosh(0)", "1.570796𝐒", Radian); + + /* asinh: R -> R (odd) + * [-𝐒,𝐒] -> R*𝐒 (odd) + * ]-inf×𝐒,-𝐒[ -> -Ο€/2×𝐒+R (odd) + * ]𝐒, inf×𝐒[ -> Ο€/2×𝐒+R (odd) + */ + // On R + assert_expression_approximates_to("asinh(2)", "1.4436354751788", Radian); + assert_expression_approximates_to("asinh(2)", "1.4436354751788", Degree); + // Symmetry: odd + assert_expression_approximates_to("asinh(-2)", "-1.4436354751788", Radian); + assert_expression_approximates_to("asinh(-2)", "-1.4436354751788", Degree); + // On [-𝐒,𝐒] + assert_expression_approximates_to("asinh(0.2×𝐒)", "2.0135792079033ᴇ-1𝐒", Radian); + assert_expression_approximates_to("asinh(0.2×𝐒)", "0.2013579𝐒", Degree); + // Symmetry: odd + assert_expression_approximates_to("asinh(-0.2×𝐒)", "-2.0135792079033ᴇ-1𝐒", Radian); + assert_expression_approximates_to("asinh(-0.2×𝐒)", "-0.2013579𝐒", Degree); + // On ]-inf×𝐒, -𝐒[ + assert_expression_approximates_to("asinh(-22×𝐒)", "-3.7836727043295-1.5707963267949𝐒", Radian); + assert_expression_approximates_to("asinh(-22×𝐒)", "-3.784-1.571𝐒", Degree, Cartesian, 4); + // On ]𝐒, inf×𝐒[, Symmetry: odd + assert_expression_approximates_to("asinh(22×𝐒)", "3.7836727043295+1.5707963267949𝐒", Radian); + assert_expression_approximates_to("asinh(22×𝐒)", "3.784+1.571𝐒", Degree, Cartesian, 4); + // On C + assert_expression_approximates_to("asinh(𝐒-4)", "-2.123+0.2383𝐒", Radian, Cartesian, 4); + assert_expression_approximates_to("asinh(𝐒-4)", "-2.123+0.2383𝐒", Degree, Cartesian, 4); + + /* atanh: [-1,1] -> R (odd) + * ]-inf,-1[ -> Ο€/2*𝐒+R (odd) + * ]1, inf[ -> -Ο€/2×𝐒+R (odd) + * R×𝐒 -> R×𝐒 (odd) + */ + // On [-1,1] + assert_expression_approximates_to("atanh(0.4)", "0.4236489301936", Radian); + assert_expression_approximates_to("atanh(0.4)", "0.4236489301936", Degree); + // Symmetry: odd + assert_expression_approximates_to("atanh(-0.4)", "-0.4236489301936", Radian); + assert_expression_approximates_to("atanh(-0.4)", "-0.4236489301936", Degree); + // On ]1, inf[ + assert_expression_approximates_to("atanh(4)", "0.255412811883-1.5707963267949𝐒", Radian); + assert_expression_approximates_to("atanh(4)", "0.2554128-1.570796𝐒", Degree); + // On ]-inf,-1[, Symmetry: odd + assert_expression_approximates_to("atanh(-4)", "-0.255412811883+1.5707963267949𝐒", Radian); + assert_expression_approximates_to("atanh(-4)", "-0.2554128+1.570796𝐒", Degree); + // On R×𝐒 + assert_expression_approximates_to("atanh(4×𝐒)", "1.325817663668𝐒", Radian); + assert_expression_approximates_to("atanh(4×𝐒)", "1.325818𝐒", Radian); + // Symmetry: odd + assert_expression_approximates_to("atanh(-4×𝐒)", "-1.325817663668𝐒", Radian); + assert_expression_approximates_to("atanh(-4×𝐒)", "-1.325818𝐒", Radian); + // On C + assert_expression_approximates_to("atanh(𝐒-4)", "-0.238878+1.50862𝐒", Radian, Cartesian, 6); + assert_expression_approximates_to("atanh(𝐒-4)", "-0.238878+1.50862𝐒", Degree, Cartesian, 6); + + // WARNING: evaluate on branch cut can be multivalued + assert_expression_approximates_to("acos(2)", "1.3169578969248𝐒", Radian); + assert_expression_approximates_to("acos(2)", "75.456129290217𝐒", Degree); + assert_expression_approximates_to("asin(2)", "1.5707963267949-1.3169578969248𝐒", Radian); + assert_expression_approximates_to("asin(2)", "90-75.456129290217𝐒", Degree); + assert_expression_approximates_to("atanh(2)", "5.4930614433405ᴇ-1-1.5707963267949𝐒", Radian); + assert_expression_approximates_to("atan(2𝐒)", "1.5707963267949+5.4930614433405ᴇ-1𝐒", Radian); + assert_expression_approximates_to("atan(2𝐒)", "90+31.472923730945𝐒", Degree); + assert_expression_approximates_to("asinh(2𝐒)", "1.3169578969248+1.5707963267949𝐒", Radian); + assert_expression_approximates_to("acosh(-2)", "1.3169578969248+3.1415926535898𝐒", Radian); +} + +QUIZ_CASE(poincare_approximation_matrix) { + assert_expression_approximates_to("[[1,2,3][4,5,6]]", "[[1,2,3][4,5,6]]"); + assert_expression_approximates_to("[[1,2,3][4,5,6]]", "[[1,2,3][4,5,6]]"); +} + +QUIZ_CASE(poincare_approximation_store) { + assert_expression_approximates_to("1+42β†’A", "43"); + assert_expression_approximates_to("0.123+𝐒→B", "0.123+𝐒"); + + assert_expression_approximates_to_scalar("1+42β†’A", 43.0f); + assert_expression_approximates_to_scalar("0.123+𝐒→B", NAN); + + // Clean the storage for other tests + Ion::Storage::sharedStorage()->recordNamed("A.exp").destroy(); + Ion::Storage::sharedStorage()->recordNamed("B.exp").destroy(); +} + +QUIZ_CASE(poincare_approximation_store_matrix) { + assert_expression_approximates_to("[[7]]β†’a", "[[7]]"); + + assert_expression_approximates_to_scalar("[[7]]β†’a", NAN); + + // Clean the storage for other tests + Ion::Storage::sharedStorage()->recordNamed("a.exp").destroy(); +} + +QUIZ_CASE(poincare_approximation_complex_format) { + // Real + assert_expression_approximates_to("0", "0", Radian, Real); + assert_expression_approximates_to("0", "0", Radian, Real); + assert_expression_approximates_to("10", "10", Radian, Real); + assert_expression_approximates_to("-10", "-10", Radian, Real); + assert_expression_approximates_to("100", "100", Radian, Real); + assert_expression_approximates_to("0.1", "0.1", Radian, Real); + assert_expression_approximates_to("0.1234567", "0.1234567", Radian, Real); + assert_expression_approximates_to("0.123456789012345", "1.2345678901235ᴇ-1", Radian, Real); + assert_expression_approximates_to("1+2×𝐒", "unreal", Radian, Real); + assert_expression_approximates_to("1+𝐒-𝐒", "unreal", Radian, Real); + assert_expression_approximates_to("1+𝐒-1", "unreal", Radian, Real); + assert_expression_approximates_to("1+𝐒", "unreal", Radian, Real); + assert_expression_approximates_to("3+𝐒", "unreal", Radian, Real); + assert_expression_approximates_to("3-𝐒", "unreal", Radian, Real); + assert_expression_approximates_to("3-𝐒-3", "unreal", Radian, Real); + assert_expression_approximates_to("𝐒", "unreal", Radian, Real); + assert_expression_approximates_to("√(-1)", "unreal", Radian, Real); + assert_expression_approximates_to("√(-1)Γ—βˆš(-1)", "unreal", Radian, Real); + assert_expression_approximates_to("ln(-2)", "unreal", Radian, Real); + assert_expression_approximates_to("(-8)^(1/3)", "unreal", Radian, Real); // Power always approximates to the principal root (even if unreal) + assert_expression_approximates_to("root(-8,3)", "-2", Radian, Real); // Root approximates to the first REAL root in Real mode + assert_expression_approximates_to("8^(1/3)", "2", Radian, Real); + assert_expression_approximates_to("(-8)^(2/3)", "unreal", Radian, Real); // Power always approximates to the principal root (even if unreal) + assert_expression_approximates_to("root(-8, 3)^2", "4", Radian, Real); // Root approximates to the first REAL root in Real mode + assert_expression_approximates_to("root(-8,3)", "-2", Radian, Real); + + // Cartesian + assert_expression_approximates_to("0", "0", Radian, Cartesian); + assert_expression_approximates_to("0", "0", Radian, Cartesian); + assert_expression_approximates_to("10", "10", Radian, Cartesian); + assert_expression_approximates_to("-10", "-10", Radian, Cartesian); + assert_expression_approximates_to("100", "100", Radian, Cartesian); + assert_expression_approximates_to("0.1", "0.1", Radian, Cartesian); + assert_expression_approximates_to("0.1234567", "0.1234567", Radian, Cartesian); + assert_expression_approximates_to("0.123456789012345", "1.2345678901235ᴇ-1", Radian, Cartesian); + assert_expression_approximates_to("1+2×𝐒", "1+2𝐒", Radian, Cartesian); + assert_expression_approximates_to("1+𝐒-𝐒", "1", Radian, Cartesian); + assert_expression_approximates_to("1+𝐒-1", "𝐒", Radian, Cartesian); + assert_expression_approximates_to("1+𝐒", "1+𝐒", Radian, Cartesian); + assert_expression_approximates_to("3+𝐒", "3+𝐒", Radian, Cartesian); + assert_expression_approximates_to("3-𝐒", "3-𝐒", Radian, Cartesian); + assert_expression_approximates_to("3-𝐒-3", "-𝐒", Radian, Cartesian); + assert_expression_approximates_to("𝐒", "𝐒", Radian, Cartesian); + assert_expression_approximates_to("√(-1)", "𝐒", Radian, Cartesian); + assert_expression_approximates_to("√(-1)Γ—βˆš(-1)", "-1", Radian, Cartesian); + assert_expression_approximates_to("ln(-2)", "6.9314718055995ᴇ-1+3.1415926535898𝐒", Radian, Cartesian); + assert_expression_approximates_to("(-8)^(1/3)", "1+1.7320508075689𝐒", Radian, Cartesian); + assert_expression_approximates_to("(-8)^(2/3)", "-2+3.464102𝐒", Radian, Cartesian); + assert_expression_approximates_to("root(-8,3)", "1+1.7320508075689𝐒", Radian, Cartesian); + + // Polar + assert_expression_approximates_to("0", "0", Radian, Polar); + assert_expression_approximates_to("0", "0", Radian, Polar); + assert_expression_approximates_to("10", "10", Radian, Polar); + assert_expression_approximates_to("-10", "10β„―^\u00123.1415926535898𝐒\u0013", Radian, Polar); + + assert_expression_approximates_to("100", "100", Radian, Polar); + assert_expression_approximates_to("0.1", "0.1", Radian, Polar); + assert_expression_approximates_to("0.1234567", "0.1234567", Radian, Polar); + assert_expression_approximates_to("0.12345678", "0.12345678", Radian, Polar); + + assert_expression_approximates_to("1+2×𝐒", "2.236068β„―^\u00121.107149𝐒\u0013", Radian, Polar); + assert_expression_approximates_to("1+𝐒-𝐒", "1", Radian, Polar); + assert_expression_approximates_to("1+𝐒-1", "β„―^\u00121.57079632679𝐒\u0013", Radian, Polar, 12); + assert_expression_approximates_to("1+𝐒", "1.414214β„―^\u00120.7853982𝐒\u0013", Radian, Polar); + assert_expression_approximates_to("3+𝐒", "3.16227766017β„―^\u00120.321750554397𝐒\u0013", Radian, Polar,12); + assert_expression_approximates_to("3-𝐒", "3.162278β„―^\u0012-0.3217506𝐒\u0013", Radian, Polar); + assert_expression_approximates_to("3-𝐒-3", "β„―^\u0012-1.57079632679𝐒\u0013", Radian, Polar,12); + assert_expression_approximates_to("2β„―^(𝐒)", "2β„―^𝐒", Radian, Polar, 5); + assert_expression_approximates_to("2β„―^(-𝐒)", "2β„―^\u0012-𝐒\u0013", Radian, Polar, 5); + + assert_expression_approximates_to("𝐒", "β„―^\u00121.570796𝐒\u0013", Radian, Polar); + assert_expression_approximates_to("√(-1)", "β„―^\u00121.5707963267949𝐒\u0013", Radian, Polar); + assert_expression_approximates_to("√(-1)Γ—βˆš(-1)", "β„―^\u00123.1415926535898𝐒\u0013", Radian, Polar); + assert_expression_approximates_to("(-8)^(1/3)", "2β„―^\u00121.0471975511966𝐒\u0013", Radian, Polar); + assert_expression_approximates_to("(-8)^(2/3)", "4β„―^\u00122.094395𝐒\u0013", Radian, Polar); + assert_expression_approximates_to("root(-8,3)", "2β„―^\u00121.0471975511966𝐒\u0013", Radian, Polar); + + // Cartesian to Polar and vice versa + assert_expression_approximates_to("2+3×𝐒", "3.60555127546β„―^\u00120.982793723247𝐒\u0013", Radian, Polar, 12); + assert_expression_approximates_to("3.60555127546β„―^(0.982793723247×𝐒)", "2+3𝐒", Radian, Cartesian, 12); + assert_expression_approximates_to("12.04159457879229548012824103β„―^(1.4876550949×𝐒)", "1+12𝐒", Radian, Cartesian, 5); + + // Overflow + assert_expression_approximates_to("-2ᴇ20+2ᴇ20×𝐒", "-2ᴇ20+2ᴇ20𝐒", Radian, Cartesian); + assert_expression_approximates_to("-2ᴇ20+2ᴇ20×𝐒", "2.828427ᴇ20β„―^\u00122.356194𝐒\u0013", Radian, Polar); + assert_expression_approximates_to("1ᴇ155-1ᴇ155×𝐒", "1ᴇ155-1ᴇ155𝐒", Radian, Cartesian); + assert_expression_approximates_to("1ᴇ155-1ᴇ155×𝐒", "1.41421356237ᴇ155β„―^\u0012-0.785398163397𝐒\u0013", Radian, Polar,12); + assert_expression_approximates_to("-2ᴇ100+2ᴇ100×𝐒", Undefined::Name()); + assert_expression_approximates_to("-2ᴇ360+2ᴇ360×𝐒", Undefined::Name()); + assert_expression_approximates_to("-2ᴇ100+2ᴇ10×𝐒", "-inf+2ᴇ10𝐒"); + assert_expression_approximates_to("-2ᴇ360+2×𝐒", "-inf+2𝐒"); + assert_expression_approximates_to("undef+2ᴇ100×𝐒", Undefined::Name()); + assert_expression_approximates_to("-2ᴇ360+undef×𝐒", Undefined::Name()); +} + +QUIZ_CASE(poincare_approximation_mix) { + assert_expression_approximates_to("-2-3", "-5"); + assert_expression_approximates_to("1.2Γ—β„―^(1)", "3.261938"); + assert_expression_approximates_to("2β„―^(3)", "40.1711", Radian, Cartesian, 6); // WARNING: the 7th significant digit is wrong on blackbos simulator + assert_expression_approximates_to("β„―^2Γ—β„―^(1)", "20.0855", Radian, Cartesian, 6); // WARNING: the 7th significant digit is wrong on simulator + assert_expression_approximates_to("β„―^2Γ—β„―^(1)", "20.085536923188"); + assert_expression_approximates_to("2Γ—3^4+2", "164"); + assert_expression_approximates_to("-2Γ—3^4+2", "-160"); + assert_expression_approximates_to("-sin(3)Γ—2-3", "-3.2822400161197", Radian); + assert_expression_approximates_to("5-2/3", "4.333333"); + assert_expression_approximates_to("2/3-5", "-4.3333333333333"); + assert_expression_approximates_to("-2/3-5", "-5.666667"); + assert_expression_approximates_to("sin(3)2(4+2)", "1.6934400967184", Radian); + assert_expression_approximates_to("4/2Γ—(2+3)", "10"); + assert_expression_approximates_to("4/2Γ—(2+3)", "10"); +} + + +template void assert_expression_approximates_to_scalar(const char * expression, float approximation, Preferences::AngleUnit angleUnit, Preferences::ComplexFormat complexFormat); +template void assert_expression_approximates_to_scalar(const char * expression, double approximation, Preferences::AngleUnit angleUnit, Preferences::ComplexFormat complexFormat); + diff --git a/poincare/test/arithmetic.cpp b/poincare/test/arithmetic.cpp index 39cd532e1..99db22a3c 100644 --- a/poincare/test/arithmetic.cpp +++ b/poincare/test/arithmetic.cpp @@ -6,74 +6,70 @@ #include #include "helper.h" -#if POINCARE_TESTS_PRINT_EXPRESSIONS -#include "../src/expression_debug.h" -#include -using namespace std; -#endif - using namespace Poincare; +void fill_buffer_with(char * buffer, size_t bufferSize, const char * functionName, Integer * a, int numberOfIntegers) { + int numberOfChar = strlcpy(buffer, functionName, bufferSize); + for (int i = 0; i < numberOfIntegers; i++) { + if (i > 0) { + numberOfChar += strlcpy(buffer+numberOfChar, ", ", bufferSize-numberOfChar); + } + numberOfChar += a[i].serialize(buffer+numberOfChar, bufferSize-numberOfChar); + } + strlcpy(buffer+numberOfChar, ")", bufferSize-numberOfChar); +} + void assert_gcd_equals_to(Integer a, Integer b, Integer c) { -#if POINCARE_TESTS_PRINT_EXPRESSIONS - cout << "---- GCD ----" << endl; - cout << "gcd(" << a.approximate(); - cout << ", " << b.approximate() << ") = "; -#endif + constexpr size_t bufferSize = 100; + char failInformationBuffer[bufferSize]; + Integer args[2] = {a, b}; + fill_buffer_with(failInformationBuffer, bufferSize, "gcd(", args, 2); Integer gcd = Arithmetic::GCD(a, b); -#if POINCARE_TESTS_PRINT_EXPRESSIONS - cout << gcd.approximate() << endl; -#endif - quiz_assert(gcd.isEqualTo(c)); + quiz_assert_print_if_failure(gcd.isEqualTo(c), failInformationBuffer); } void assert_lcm_equals_to(Integer a, Integer b, Integer c) { -#if POINCARE_TESTS_PRINT_EXPRESSIONS - cout << "---- LCM ----" << endl; - cout << "lcm(" << a.approximate(); - cout << ", " << b.approximate() << ") = "; -#endif + constexpr size_t bufferSize = 100; + char failInformationBuffer[bufferSize]; + Integer args[2] = {a, b}; + fill_buffer_with(failInformationBuffer, bufferSize, "lcm(", args, 2); Integer lcm = Arithmetic::LCM(a, b); -#if POINCARE_TESTS_PRINT_EXPRESSIONS - cout << lcm.approximate() << endl; -#endif - quiz_assert(lcm.isEqualTo(c)); + quiz_assert_print_if_failure(lcm.isEqualTo(c), failInformationBuffer); } void assert_prime_factorization_equals_to(Integer a, int * factors, int * coefficients, int length) { Integer outputFactors[100]; Integer outputCoefficients[100]; -#if POINCARE_TESTS_PRINT_EXPRESSIONS - cout << "---- Primes factorization ----" << endl; - cout << "Decomp(" << a.approximate() << ") = "; -#endif Arithmetic::PrimeFactorization(a, outputFactors, outputCoefficients, 10); -#if POINCARE_TESTS_PRINT_EXPRESSIONS - print_prime_factorization(outputFactors, outputCoefficients, 10); -#endif + constexpr size_t bufferSize = 100; + char failInformationBuffer[bufferSize]; + fill_buffer_with(failInformationBuffer, bufferSize, "factor(", &a, 1); for (int index = 0; index < length; index++) { - if (outputCoefficients[index].isEqualTo(Integer(0))) { - break; - } /* Cheat: instead of comparing to integers, we compare their approximations * (the relation between integers and their approximation is a surjection, * however different integers are really likely to have different * approximations... */ - quiz_assert(outputFactors[index].approximate() == Integer(factors[index]).approximate()); - quiz_assert(outputCoefficients[index].approximate() == Integer(coefficients[index]).approximate()); + quiz_assert_print_if_failure(outputFactors[index].approximate() == Integer(factors[index]).approximate(), failInformationBuffer); + quiz_assert_print_if_failure(outputCoefficients[index].approximate() == Integer(coefficients[index]).approximate(), failInformationBuffer); } } -QUIZ_CASE(poincare_arithmetic) { +QUIZ_CASE(poincare_arithmetic_gcd) { assert_gcd_equals_to(Integer(11), Integer(121), Integer(11)); assert_gcd_equals_to(Integer(-256), Integer(321), Integer(1)); assert_gcd_equals_to(Integer(-8), Integer(-40), Integer(8)); assert_gcd_equals_to(Integer("1234567899876543456"), Integer("234567890098765445678"), Integer(2)); assert_gcd_equals_to(Integer("45678998789"), Integer("1461727961248"), Integer("45678998789")); +} + +QUIZ_CASE(poincare_arithmetic_lcm) { assert_lcm_equals_to(Integer(11), Integer(121), Integer(121)); assert_lcm_equals_to(Integer(-31), Integer(52), Integer(1612)); assert_lcm_equals_to(Integer(-8), Integer(-40), Integer(40)); assert_lcm_equals_to(Integer("1234567899876543456"), Integer("234567890098765445678"), Integer("144794993728852353909143567804987191584")); +} + +QUIZ_CASE(poincare_arithmetic_factorization) { assert_lcm_equals_to(Integer("45678998789"), Integer("1461727961248"), Integer("1461727961248")); int factors0[5] = {2,3,5,79,1319}; int coefficients0[5] = {2,1,1,1,1}; diff --git a/poincare/test/binomial_coefficient_layout.cpp b/poincare/test/binomial_coefficient_layout.cpp deleted file mode 100644 index c7960c551..000000000 --- a/poincare/test/binomial_coefficient_layout.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include -#include -#include -#include "helper.h" - -using namespace Poincare; - -QUIZ_CASE(poincare_binomial_coefficient_layout_serialize) { - assert_parsed_expression_layout_serialize_to_self("binomial(7,6)"); -} diff --git a/poincare/test/complex.cpp b/poincare/test/complex.cpp deleted file mode 100644 index 2f24eab66..000000000 --- a/poincare/test/complex.cpp +++ /dev/null @@ -1,179 +0,0 @@ -#include -#include -#include -#include -#include "helper.h" - -using namespace Poincare; - -QUIZ_CASE(poincare_complex_evaluate) { - // Real - assert_parsed_expression_evaluates_to("𝐒", "unreal", System, Radian, Real); - assert_parsed_expression_evaluates_to("√(-1)", "unreal", System, Radian, Real); - assert_parsed_expression_evaluates_to("√(-1)Γ—βˆš(-1)", "unreal", System, Radian, Real); - assert_parsed_expression_evaluates_to("ln(-2)", "unreal", System, Radian, Real); - assert_parsed_expression_evaluates_to("(-8)^(1/3)", "-2", System, Radian, Real); - assert_parsed_expression_evaluates_to("8^(1/3)", "2", System, Radian, Real); - assert_parsed_expression_evaluates_to("(-8)^(2/3)", "4", System, Radian, Real); - assert_parsed_expression_evaluates_without_simplifying_to("root(-8,3)", "-2", Radian, Real); - - // Cartesian - assert_parsed_expression_evaluates_to("𝐒", "𝐒", System, Radian, Cartesian); - assert_parsed_expression_evaluates_to("√(-1)", "𝐒", System, Radian, Cartesian); - assert_parsed_expression_evaluates_to("√(-1)Γ—βˆš(-1)", "-1", System, Radian, Cartesian); - assert_parsed_expression_evaluates_to("ln(-2)", "6.9314718055995ᴇ-1+3.1415926535898×𝐒", System, Radian, Cartesian); - assert_parsed_expression_evaluates_to("(-8)^(1/3)", "1+1.7320508075689×𝐒", System, Radian, Cartesian); - assert_parsed_expression_evaluates_to("(-8)^(2/3)", "-2+3.464102×𝐒", System, Radian, Cartesian); - assert_parsed_expression_evaluates_without_simplifying_to("root(-8,3)", "1+1.7320508075689×𝐒", Radian, Cartesian); - - // Polar - assert_parsed_expression_evaluates_to("𝐒", "β„―^(1.570796×𝐒)", System, Radian, Polar); - assert_parsed_expression_evaluates_to("√(-1)", "β„―^(1.5707963267949×𝐒)", System, Radian, Polar); - assert_parsed_expression_evaluates_to("√(-1)Γ—βˆš(-1)", "β„―^(3.1415926535898×𝐒)", System, Radian, Polar); - assert_parsed_expression_evaluates_to("(-8)^(1/3)", "2Γ—β„―^(1.0471975511966×𝐒)", System, Radian, Polar); - assert_parsed_expression_evaluates_to("(-8)^(2/3)", "4Γ—β„―^(2.094395×𝐒)", System, Radian, Polar); - assert_parsed_expression_evaluates_without_simplifying_to("root(-8,3)", "2Γ—β„―^(1.0471975511966×𝐒)", Radian, Polar); -} - -QUIZ_CASE(poincare_complex_simplify) { - // Real - assert_parsed_expression_simplify_to("𝐒", "unreal", User, Radian, Real); - assert_parsed_expression_simplify_to("√(-1)", "unreal", User, Radian, Real); - assert_parsed_expression_simplify_to("√(-1)Γ—βˆš(-1)", "unreal", User, Radian, Real); - assert_parsed_expression_simplify_to("ln(-2)", "unreal", User, Radian, Real); - assert_parsed_expression_simplify_to("(-8)^(2/3)", "4", User, Radian, Real); - assert_parsed_expression_simplify_to("(-8)^(2/5)", "2Γ—root(2,5)", User, Radian, Real); - assert_parsed_expression_simplify_to("(-8)^(1/5)", "-root(8,5)", User, Radian, Real); - assert_parsed_expression_simplify_to("(-8)^(1/4)", "unreal", User, Radian, Real); - assert_parsed_expression_simplify_to("(-8)^(1/3)", "-2", User, Radian, Real); - - // Cartesian - assert_parsed_expression_simplify_to("-2.3ᴇ3", "-2300", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("3", "3", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("inf", "inf", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("1+2+𝐒", "3+𝐒", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("-(5+2×𝐒)", "-5-2×𝐒", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("(5+2×𝐒)", "5+2×𝐒", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("𝐒+𝐒", "2×𝐒", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("-2+2×𝐒", "-2+2×𝐒", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("(3+𝐒)-(2+4×𝐒)", "1-3×𝐒", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("(2+3×𝐒)Γ—(4-2×𝐒)", "14+8×𝐒", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("(3+𝐒)/2", "3/2+1/2×𝐒", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("(3+𝐒)/(2+𝐒)", "7/5-1/5×𝐒", User, Radian, Cartesian); - // The simplification of (3+𝐒)^(2+𝐒) in a Cartesian complex form generates to many nodes - //assert_parsed_expression_simplify_to("(3+𝐒)^(2+𝐒)", "10Γ—cos((-4Γ—atan(3)+ln(2)+ln(5)+2Γ—Ο€)/2)Γ—β„―^((2Γ—atan(3)-Ο€)/2)+10Γ—sin((-4Γ—atan(3)+ln(2)+ln(5)+2Γ—Ο€)/2)Γ—β„―^((2Γ—atan(3)-Ο€)/2)×𝐒", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("(3+𝐒)^(2+𝐒)", "(𝐒+3)^(𝐒+2)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("√(1+6𝐒)", "√(2Γ—βˆš(37)+2)/2+√(2Γ—βˆš(37)-2)/2×𝐒", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("(1+𝐒)^2", "2×𝐒", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("2×𝐒", "2×𝐒", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("𝐒!", "𝐒!", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("3!", "6", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("x!", "x!", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("β„―", "β„―", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("Ο€", "Ο€", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("𝐒", "𝐒", User, Radian, Cartesian); - - assert_parsed_expression_simplify_to("abs(-3)", "3", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("abs(-3+𝐒)", "√(10)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("atan(2)", "atan(2)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("atan(2+𝐒)", "atan(2+𝐒)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("binomial(10, 4)", "210", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("ceil(-1.3)", "-1", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("arg(-2)", "Ο€", User, Radian, Cartesian); - // TODO: confidence is not simplified yet - //assert_parsed_expression_simplify_to("confidence(-2,-3)", "confidence(-2)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("conj(-2)", "-2", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("conj(-2+2×𝐒+𝐒)", "-2-3×𝐒", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("cos(12)", "cos(12)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("cos(12+𝐒)", "cos(12+𝐒)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("diff(3Γ—x, x, 3)", "diff(3Γ—x,x,3)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("quo(34,x)", "quo(34,x)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("rem(5,3)", "2", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("floor(x)", "floor(x)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("frac(x)", "frac(x)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("gcd(x,y)", "gcd(x,y)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("im(1+𝐒)", "1", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("int(x^2, x, 1, 2)", "int(x^2,x,1,2)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("lcm(x,y)", "lcm(x,y)", User, Radian, Cartesian); - // TODO: dim is not simplified yet - //assert_parsed_expression_simplify_to("dim(x)", "dim(x)", User, Radian, Cartesian); - - assert_parsed_expression_simplify_to("root(2,𝐒)", "cos(ln(2))-sin(ln(2))×𝐒", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("root(2,𝐒+1)", "√(2)Γ—cos((90Γ—ln(2))/Ο€)-√(2)Γ—sin((90Γ—ln(2))/Ο€)×𝐒", User, Degree, Cartesian); - assert_parsed_expression_simplify_to("root(2,𝐒+1)", "√(2)Γ—cos(ln(2)/2)-√(2)Γ—sin(ln(2)/2)×𝐒", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("permute(10, 4)", "5040", User, Radian, Cartesian); - // TODO: prediction is not simplified yet - //assert_parsed_expression_simplify_to("prediction(-2,-3)", "prediction(-2)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("randint(2,2)", "2", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("random()", "random()", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("re(x)", "re(x)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("round(x,y)", "round(x,y)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("sign(x)", "sign(x)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("sin(23)", "sin(23)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("sin(23+𝐒)", "sin(23+𝐒)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("√(1-𝐒)", "√(2Γ—βˆš(2)+2)/2-√(2Γ—βˆš(2)-2)/2×𝐒", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("tan(23)", "tan(23)", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("tan(23+𝐒)", "tan(23+𝐒)", User, Radian, Cartesian); - - // User defined variable - assert_parsed_expression_simplify_to("a", "a", User, Radian, Cartesian); - // a = 2+i - assert_simplify("2+𝐒→a"); - assert_parsed_expression_simplify_to("a", "2+𝐒", User, Radian, Cartesian); - // Clean the storage for other tests - Ion::Storage::sharedStorage()->recordNamed("a.exp").destroy(); - // User defined function - assert_parsed_expression_simplify_to("f(3)", "f(3)", User, Radian, Cartesian); - // f : x β†’ x+1 - assert_simplify("x+1+𝐒→f(x)"); - assert_parsed_expression_simplify_to("f(3)", "4+𝐒", User, Radian, Cartesian); - // Clean the storage for other tests - Ion::Storage::sharedStorage()->recordNamed("f.func").destroy(); - - // Polar - assert_parsed_expression_simplify_to("-2.3ᴇ3", "2300Γ—β„―^(π×𝐒)", User, Radian, Polar); - assert_parsed_expression_simplify_to("3", "3", User, Radian, Polar); - assert_parsed_expression_simplify_to("inf", "inf", User, Radian, Polar); - assert_parsed_expression_simplify_to("1+2+𝐒", "√(10)Γ—β„―^((-2Γ—atan(3)+Ο€)/2×𝐒)", User, Radian, Polar); - assert_parsed_expression_simplify_to("1+2+𝐒", "√(10)Γ—β„―^((-π×atan(3)+90Γ—Ο€)/180×𝐒)", User, Degree, Polar); - assert_parsed_expression_simplify_to("-(5+2×𝐒)", "√(29)Γ—β„―^((-2Γ—atan(5/2)-Ο€)/2×𝐒)", User, Radian, Polar); - assert_parsed_expression_simplify_to("(5+2×𝐒)", "√(29)Γ—β„―^((-2Γ—atan(5/2)+Ο€)/2×𝐒)", User, Radian, Polar); - assert_parsed_expression_simplify_to("𝐒+𝐒", "2Γ—β„―^(Ο€/2×𝐒)", User, Radian, Polar); - assert_parsed_expression_simplify_to("𝐒+𝐒", "2Γ—β„―^(Ο€/2×𝐒)", User, Radian, Polar); - assert_parsed_expression_simplify_to("-2+2×𝐒", "2Γ—βˆš(2)Γ—β„―^((3Γ—Ο€)/4×𝐒)", User, Radian, Polar); - assert_parsed_expression_simplify_to("(3+𝐒)-(2+4×𝐒)", "√(10)Γ—β„―^((2Γ—atan(1/3)-Ο€)/2×𝐒)", User, Radian, Polar); - assert_parsed_expression_simplify_to("(2+3×𝐒)Γ—(4-2×𝐒)", "2Γ—βˆš(65)Γ—β„―^((-2Γ—atan(7/4)+Ο€)/2×𝐒)", User, Radian, Polar); - assert_parsed_expression_simplify_to("(3+𝐒)/2", "√(10)/2Γ—β„―^((-2Γ—atan(3)+Ο€)/2×𝐒)", User, Radian, Polar); - assert_parsed_expression_simplify_to("(3+𝐒)/(2+𝐒)", "√(2)Γ—β„―^((2Γ—atan(7)-Ο€)/2×𝐒)", User, Radian, Polar); - // TODO: simplify atan(tan(x)) = xΒ±kΓ—pi? - //assert_parsed_expression_simplify_to("(3+𝐒)^(2+𝐒)", "10Γ—β„―^((2Γ—atan(3)-Ο€)/2)Γ—β„―^((-4Γ—atan(3)+ln(2)+ln(5)+2Γ—Ο€)/2×𝐒)", User, Radian, Polar); - // The simplification of (3+𝐒)^(2+𝐒) in a Polar complex form generates to many nodes - //assert_parsed_expression_simplify_to("(3+𝐒)^(2+𝐒)", "10Γ—β„―^((2Γ—atan(3)-Ο€)/2)Γ—β„―^((atan(tan((-4Γ—atan(3)+ln(2)+ln(5)+2Γ—Ο€)/2))+Ο€)×𝐒)", User, Radian, Polar); - assert_parsed_expression_simplify_to("(3+𝐒)^(2+𝐒)", "(𝐒+3)^(𝐒+2)", User, Radian, Polar); - assert_parsed_expression_simplify_to("(1+𝐒)^2", "2Γ—β„―^(Ο€/2×𝐒)", User, Radian, Polar); - assert_parsed_expression_simplify_to("2×𝐒", "2Γ—β„―^(Ο€/2×𝐒)", User, Radian, Polar); - assert_parsed_expression_simplify_to("3!", "6", User, Radian, Polar); - assert_parsed_expression_simplify_to("x!", "x!", User, Radian, Polar); - assert_parsed_expression_simplify_to("β„―", "β„―", User, Radian, Polar); - assert_parsed_expression_simplify_to("Ο€", "Ο€", User, Radian, Polar); - assert_parsed_expression_simplify_to("𝐒", "β„―^(Ο€/2×𝐒)", User, Radian, Polar); - assert_parsed_expression_simplify_to("abs(-3)", "3", User, Radian, Polar); - assert_parsed_expression_simplify_to("abs(-3+𝐒)", "√(10)", User, Radian, Polar); - assert_parsed_expression_simplify_to("conj(2Γ—β„―^(𝐒×π/2))", "2Γ—β„―^(-Ο€/2×𝐒)", User, Radian, Polar); - assert_parsed_expression_simplify_to("-2Γ—β„―^(𝐒×π/2)", "2Γ—β„―^(-Ο€/2×𝐒)", User, Radian, Polar); - - // User defined variable - assert_parsed_expression_simplify_to("a", "a", User, Radian, Polar); - // a = 2 + 𝐒 - assert_simplify("2+𝐒→a"); - assert_parsed_expression_simplify_to("a", "√(5)Γ—β„―^((-2Γ—atan(2)+Ο€)/2×𝐒)", User, Radian, Polar); - // Clean the storage for other tests - Ion::Storage::sharedStorage()->recordNamed("a.exp").destroy(); - // User defined function - assert_parsed_expression_simplify_to("f(3)", "f(3)", User, Radian, Polar); - // f: x β†’ x+1 - assert_simplify("x+1+𝐒→f(x)"); - assert_parsed_expression_simplify_to("f(3)", "√(17)Γ—β„―^((-2Γ—atan(4)+Ο€)/2×𝐒)", User, Radian, Polar); - // Clean the storage for other tests - Ion::Storage::sharedStorage()->recordNamed("f.func").destroy(); -} diff --git a/poincare/test/complex_to_expression.cpp b/poincare/test/complex_to_expression.cpp deleted file mode 100644 index 3f44d8a0c..000000000 --- a/poincare/test/complex_to_expression.cpp +++ /dev/null @@ -1,87 +0,0 @@ -#include -#include -#include -#include "helper.h" - -using namespace Poincare; - -QUIZ_CASE(poincare_complex_to_expression) { - assert_parsed_expression_evaluates_to("0", "0"); - assert_parsed_expression_evaluates_to("0", "0", System, Radian, Polar); - assert_parsed_expression_evaluates_to("0", "0"); - assert_parsed_expression_evaluates_to("0", "0", System, Radian, Polar); - - assert_parsed_expression_evaluates_to("10", "10"); - assert_parsed_expression_evaluates_to("-10", "-10"); - assert_parsed_expression_evaluates_to("100", "100"); - assert_parsed_expression_evaluates_to("0.1", "0.1"); - assert_parsed_expression_evaluates_to("0.1234567", "0.1234567"); - assert_parsed_expression_evaluates_to("0.12345678", "0.1234568"); - assert_parsed_expression_evaluates_to("1+2×𝐒", "1+2×𝐒"); - assert_parsed_expression_evaluates_to("1+𝐒-𝐒", "1"); - assert_parsed_expression_evaluates_to("1+𝐒-1", "𝐒"); - assert_parsed_expression_evaluates_to("1+𝐒", "1+𝐒"); - assert_parsed_expression_evaluates_to("3+𝐒", "3+𝐒"); - assert_parsed_expression_evaluates_to("3-𝐒", "3-𝐒"); - assert_parsed_expression_evaluates_to("3-𝐒-3", "-𝐒"); - - assert_parsed_expression_evaluates_to("10", "10", System, Radian, Polar); - assert_parsed_expression_evaluates_to("-10", "10Γ—β„―^(3.141593×𝐒)", System, Radian, Polar); - assert_parsed_expression_evaluates_to("100", "100", System, Radian, Polar); - assert_parsed_expression_evaluates_to("0.1", "0.1", System, Radian, Polar); - assert_parsed_expression_evaluates_to("0.1234567", "0.1234567", System, Radian, Polar); - assert_parsed_expression_evaluates_to("0.12345678", "0.1234568", System, Radian, Polar); - assert_parsed_expression_evaluates_to("1+2×𝐒", "2.236068Γ—β„―^(1.107149×𝐒)", System, Radian, Polar); - assert_parsed_expression_evaluates_to("1+𝐒-𝐒", "1", System, Radian, Polar); - assert_parsed_expression_evaluates_to("1+𝐒-1", "β„―^(1.570796×𝐒)", System, Radian, Polar); - assert_parsed_expression_evaluates_to("1+𝐒", "1.414214Γ—β„―^(0.7853982×𝐒)", System, Radian, Polar); - assert_parsed_expression_evaluates_to("3+𝐒", "3.162278Γ—β„―^(0.3217506×𝐒)", System, Radian, Polar); - assert_parsed_expression_evaluates_to("3-𝐒", "3.162278Γ—β„―^(-0.3217506×𝐒)", System, Radian, Polar); - assert_parsed_expression_evaluates_to("3-𝐒-3", "β„―^(-1.570796×𝐒)", System, Radian, Polar); - - assert_parsed_expression_evaluates_to("10", "10"); - assert_parsed_expression_evaluates_to("-10", "-10"); - assert_parsed_expression_evaluates_to("100", "100"); - assert_parsed_expression_evaluates_to("0.1", "0.1"); - assert_parsed_expression_evaluates_to("0.12345678901234", "1.2345678901234ᴇ-1"); - assert_parsed_expression_evaluates_to("0.123456789012345", "1.2345678901235ᴇ-1"); - assert_parsed_expression_evaluates_to("1+2×𝐒", "1+2×𝐒"); - assert_parsed_expression_evaluates_to("1+𝐒-𝐒", "1"); - assert_parsed_expression_evaluates_to("1+𝐒-1", "𝐒"); - assert_parsed_expression_evaluates_to("1+𝐒", "1+𝐒"); - assert_parsed_expression_evaluates_to("3+𝐒", "3+𝐒"); - assert_parsed_expression_evaluates_to("3-𝐒", "3-𝐒"); - assert_parsed_expression_evaluates_to("3-𝐒-3", "-𝐒"); - - assert_parsed_expression_evaluates_to("10", "10", System, Radian, Polar); - assert_parsed_expression_evaluates_to("-10", "10Γ—β„―^(3.1415926535898×𝐒)", System, Radian, Polar); - assert_parsed_expression_evaluates_to("100", "100", System, Radian, Polar); - assert_parsed_expression_evaluates_to("0.1", "0.1", System, Radian, Polar); - assert_parsed_expression_evaluates_to("0.1234567", "0.1234567", System, Radian, Polar); - assert_parsed_expression_evaluates_to("0.12345678", "0.12345678", System, Radian, Polar); - assert_parsed_expression_evaluates_to("1+2×𝐒", "2.2360679775Γ—β„―^(1.10714871779×𝐒)", System, Radian, Polar, 12); - assert_parsed_expression_evaluates_to("1+𝐒-𝐒", "1", System, Radian, Polar); - assert_parsed_expression_evaluates_to("1+𝐒-1", "β„―^(1.57079632679×𝐒)", System, Radian, Polar, 12); - assert_parsed_expression_evaluates_to("1+𝐒", "1.41421356237Γ—β„―^(0.785398163397×𝐒)", System, Radian, Polar, 12); - assert_parsed_expression_evaluates_to("3+𝐒", "3.16227766017Γ—β„―^(0.321750554397×𝐒)", System, Radian, Polar,12); - assert_parsed_expression_evaluates_to("3-𝐒", "3.16227766017Γ—β„―^(-0.321750554397×𝐒)", System, Radian, Polar,12); - assert_parsed_expression_evaluates_to("3-𝐒-3", "β„―^(-1.57079632679×𝐒)", System, Radian, Polar,12); - - assert_parsed_expression_evaluates_to("2+3×𝐒", "3.60555127546Γ—β„―^(0.982793723247×𝐒)", System, Radian, Polar, 12); - assert_parsed_expression_evaluates_to("3.60555127546Γ—β„―^(0.982793723247×𝐒)", "2+3×𝐒", System, Radian, Cartesian, 12); - assert_parsed_expression_evaluates_to("12.04159457879229548012824103Γ—β„―^(1.4876550949×𝐒)", "1+12×𝐒", System, Radian, Cartesian, 5); - assert_parsed_expression_evaluates_to("-2ᴇ20+2ᴇ20×𝐒", "-2ᴇ20+2ᴇ20×𝐒"); - assert_parsed_expression_evaluates_to("-2ᴇ20+2ᴇ20×𝐒", "2.828427ᴇ20Γ—β„―^(2.356194×𝐒)", System, Radian, Polar); - assert_parsed_expression_evaluates_to("1ᴇ155-1ᴇ155×𝐒", "1ᴇ155-1ᴇ155×𝐒"); - assert_parsed_expression_evaluates_to("1ᴇ155-1ᴇ155×𝐒", "1.41421356237ᴇ155Γ—β„―^(-0.785398163397×𝐒)", System, Radian, Polar,12); - - assert_parsed_expression_evaluates_to("-2ᴇ100+2ᴇ100×𝐒", Undefined::Name()); - assert_parsed_expression_evaluates_to("-2ᴇ360+2ᴇ360×𝐒", Undefined::Name()); - assert_parsed_expression_evaluates_to("-2ᴇ100+2ᴇ10×𝐒", "-inf+2ᴇ10×𝐒"); - assert_parsed_expression_evaluates_to("-2ᴇ360+2×𝐒", "-inf+2×𝐒"); - assert_parsed_expression_evaluates_to("undef+2ᴇ100×𝐒", Undefined::Name()); - assert_parsed_expression_evaluates_to("-2ᴇ360+undef×𝐒", Undefined::Name()); - - assert_parsed_expression_evaluates_to("2Γ—β„―^(𝐒)", "2Γ—β„―^𝐒", System, Radian, Polar, 5); - assert_parsed_expression_evaluates_to("2Γ—β„―^(-𝐒)", "2Γ—β„―^(-𝐒)", System, Radian, Polar, 5); -} diff --git a/poincare/test/user_variable.cpp b/poincare/test/context.cpp similarity index 58% rename from poincare/test/user_variable.cpp rename to poincare/test/context.cpp index bf3e2e603..1923b877b 100644 --- a/poincare/test/user_variable.cpp +++ b/poincare/test/context.cpp @@ -7,7 +7,36 @@ using namespace Poincare; -QUIZ_CASE(poincare_user_variable_simple) { +template +void assert_parsed_expression_approximates_with_value_for_symbol(Expression expression, const char * symbol, T value, T approximation, Poincare::Preferences::ComplexFormat complexFormat = Cartesian, Poincare::Preferences::AngleUnit angleUnit = Radian) { + Shared::GlobalContext globalContext; + T result = expression.approximateWithValueForSymbol(symbol, value, &globalContext, complexFormat, angleUnit); + quiz_assert((std::isnan(result) && std::isnan(approximation)) || std::fabs(result - approximation) < Expression::Epsilon()); +} + +QUIZ_CASE(poincare_context_store_overwrite) { + assert_parsed_expression_simplify_to("2β†’g", "2"); + assert_parsed_expression_simplify_to("-1β†’g(x)", "-1"); + assert_expression_approximates_to("g(4)", "-1"); + + // Clean the storage for other tests + Ion::Storage::sharedStorage()->recordNamed("g.func").destroy(); +} + +QUIZ_CASE(poincare_context_store_do_not_overwrite) { + assert_parsed_expression_simplify_to("-1β†’g(x)", "-1"); + assert_parsed_expression_simplify_to("1+g(x)β†’f(x)", "g(x)+1"); + assert_expression_approximates_to("f(1)", "0"); + assert_parsed_expression_simplify_to("2β†’g", Undefined::Name()); + assert_expression_approximates_to("g(4)", "-1"); + assert_expression_approximates_to("f(4)", "0"); + + // Clean the storage for other tests + Ion::Storage::sharedStorage()->recordNamed("f.func").destroy(); + Ion::Storage::sharedStorage()->recordNamed("g.func").destroy(); +} + +QUIZ_CASE(poincare_context_user_variable_simple) { // Fill variable assert_parsed_expression_simplify_to("1+2β†’Adadas", "3"); assert_parsed_expression_simplify_to("Adadas", "3"); @@ -43,24 +72,24 @@ QUIZ_CASE(poincare_user_variable_simple) { Ion::Storage::sharedStorage()->recordNamed("fBoth.func").destroy(); } -QUIZ_CASE(poincare_user_variable_2_circular_variables) { +QUIZ_CASE(poincare_context_user_variable_2_circular_variables) { assert_simplify("aβ†’b"); assert_simplify("bβ†’a"); - assert_parsed_expression_evaluates_to("a", Undefined::Name()); - assert_parsed_expression_evaluates_to("b", Undefined::Name()); + assert_expression_approximates_to("a", Undefined::Name()); + assert_expression_approximates_to("b", Undefined::Name()); // Clean the storage for other tests Ion::Storage::sharedStorage()->recordNamed("a.exp").destroy(); Ion::Storage::sharedStorage()->recordNamed("b.exp").destroy(); } -QUIZ_CASE(poincare_user_variable_3_circular_variables) { +QUIZ_CASE(poincare_context_user_variable_3_circular_variables) { assert_simplify("aβ†’b"); assert_simplify("bβ†’c"); assert_simplify("cβ†’a"); - assert_parsed_expression_evaluates_to("a", Undefined::Name()); - assert_parsed_expression_evaluates_to("b", Undefined::Name()); - assert_parsed_expression_evaluates_to("c", Undefined::Name()); + assert_expression_approximates_to("a", Undefined::Name()); + assert_expression_approximates_to("b", Undefined::Name()); + assert_expression_approximates_to("c", Undefined::Name()); // Clean the storage for other tests Ion::Storage::sharedStorage()->recordNamed("a.exp").destroy(); @@ -68,19 +97,19 @@ QUIZ_CASE(poincare_user_variable_3_circular_variables) { Ion::Storage::sharedStorage()->recordNamed("c.exp").destroy(); } -QUIZ_CASE(poincare_user_variable_1_circular_function) { +QUIZ_CASE(poincare_context_user_variable_1_circular_function) { // g: x β†’ f(x)+1 assert_simplify("f(x)+1β†’g(x)"); - assert_parsed_expression_evaluates_to("g(1)", Undefined::Name()); + assert_expression_approximates_to("g(1)", Undefined::Name()); // f: x β†’ x+1 assert_simplify("x+1β†’f(x)"); - assert_parsed_expression_evaluates_to("g(1)", "3"); - assert_parsed_expression_evaluates_to("f(1)", "2"); + assert_expression_approximates_to("g(1)", "3"); + assert_expression_approximates_to("f(1)", "2"); // h: x β†’ h(x) assert_simplify("h(x)β†’h(x)"); - assert_parsed_expression_evaluates_to("f(1)", "2"); - assert_parsed_expression_evaluates_to("g(1)", "3"); - assert_parsed_expression_evaluates_to("h(1)", Undefined::Name()); + assert_expression_approximates_to("f(1)", "2"); + assert_expression_approximates_to("g(1)", "3"); + assert_expression_approximates_to("h(1)", Undefined::Name()); // Clean the storage for other tests Ion::Storage::sharedStorage()->recordNamed("f.func").destroy(); @@ -88,24 +117,24 @@ QUIZ_CASE(poincare_user_variable_1_circular_function) { Ion::Storage::sharedStorage()->recordNamed("h.func").destroy(); } -QUIZ_CASE(poincare_user_variable_2_circular_functions) { +QUIZ_CASE(poincare_context_user_variable_2_circular_functions) { assert_simplify("f(x)β†’g(x)"); assert_simplify("g(x)β†’f(x)"); - assert_parsed_expression_evaluates_to("f(1)", Undefined::Name()); - assert_parsed_expression_evaluates_to("g(1)", Undefined::Name()); + assert_expression_approximates_to("f(1)", Undefined::Name()); + assert_expression_approximates_to("g(1)", Undefined::Name()); // Clean the storage for other tests Ion::Storage::sharedStorage()->recordNamed("f.func").destroy(); Ion::Storage::sharedStorage()->recordNamed("g.func").destroy(); } -QUIZ_CASE(poincare_user_variable_3_circular_functions) { +QUIZ_CASE(poincare_context_user_variable_3_circular_functions) { assert_simplify("f(x)β†’g(x)"); assert_simplify("g(x)β†’h(x)"); assert_simplify("h(x)β†’f(x)"); - assert_parsed_expression_evaluates_to("f(1)", Undefined::Name()); - assert_parsed_expression_evaluates_to("g(1)", Undefined::Name()); - assert_parsed_expression_evaluates_to("h(1)", Undefined::Name()); + assert_expression_approximates_to("f(1)", Undefined::Name()); + assert_expression_approximates_to("g(1)", Undefined::Name()); + assert_expression_approximates_to("h(1)", Undefined::Name()); // Clean the storage for other tests Ion::Storage::sharedStorage()->recordNamed("f.func").destroy(); @@ -113,13 +142,13 @@ QUIZ_CASE(poincare_user_variable_3_circular_functions) { Ion::Storage::sharedStorage()->recordNamed("h.func").destroy(); } -QUIZ_CASE(poincare_user_variable_circular_variables_and_functions) { +QUIZ_CASE(poincare_context_user_variable_circular_variables_and_functions) { assert_simplify("aβ†’b"); assert_simplify("bβ†’a"); assert_simplify("aβ†’f(x)"); - assert_parsed_expression_evaluates_to("f(1)", Undefined::Name()); - assert_parsed_expression_evaluates_to("a", Undefined::Name()); - assert_parsed_expression_evaluates_to("b", Undefined::Name()); + assert_expression_approximates_to("f(1)", Undefined::Name()); + assert_expression_approximates_to("a", Undefined::Name()); + assert_expression_approximates_to("b", Undefined::Name()); // Clean the storage for other tests Ion::Storage::sharedStorage()->recordNamed("f.func").destroy(); @@ -127,33 +156,33 @@ QUIZ_CASE(poincare_user_variable_circular_variables_and_functions) { Ion::Storage::sharedStorage()->recordNamed("b.exp").destroy(); } -QUIZ_CASE(poincare_user_variable_composed_functions) { +QUIZ_CASE(poincare_context_user_variable_composed_functions) { // f: xβ†’x^2 assert_simplify("x^2β†’f(x)"); // g: xβ†’f(x-2) assert_simplify("f(x-2)β†’g(x)"); - assert_parsed_expression_evaluates_to("f(2)", "4"); - assert_parsed_expression_evaluates_to("g(3)", "1"); - assert_parsed_expression_evaluates_to("g(5)", "9"); + assert_expression_approximates_to("f(2)", "4"); + assert_expression_approximates_to("g(3)", "1"); + assert_expression_approximates_to("g(5)", "9"); // g: xβ†’f(x-2)+f(x+1) assert_simplify("f(x-2)+f(x+1)β†’g(x)"); // Add a sum to bypass simplification - assert_parsed_expression_evaluates_to("g(3)+sum(1, n, 2, 4)", "20"); - assert_parsed_expression_evaluates_to("g(5)", "45"); + assert_expression_approximates_to("g(3)+sum(1, n, 2, 4)", "20"); + assert_expression_approximates_to("g(5)", "45"); // g: xβ†’x+1 assert_simplify("x+1β†’g(x)"); - assert_parsed_expression_evaluates_to("f(g(4))", "25"); + assert_expression_approximates_to("f(g(4))", "25"); // Add a sum to bypass simplification - assert_parsed_expression_evaluates_to("f(g(4))+sum(1, n, 2, 4)", "28"); + assert_expression_approximates_to("f(g(4))+sum(1, n, 2, 4)", "28"); // Clean the storage for other tests Ion::Storage::sharedStorage()->recordNamed("f.func").destroy(); Ion::Storage::sharedStorage()->recordNamed("g.func").destroy(); } -QUIZ_CASE(poincare_user_variable_functions_with_context) { +QUIZ_CASE(poincare_context_user_variable_functions_approximation_with_value_for_symbol) { // f : xβ†’ x^2 assert_simplify("x^2β†’f(x)"); // Approximate f(?-2) with ? = 5 @@ -181,22 +210,22 @@ QUIZ_CASE(poincare_user_variable_functions_with_context) { Ion::Storage::sharedStorage()->recordNamed("f.func").destroy(); } -QUIZ_CASE(poincare_user_variable_properties) { +QUIZ_CASE(poincare_context_user_variable_properties) { Shared::GlobalContext context; - assert_parsed_expression_evaluates_to("[[1]]β†’a", "[[1]]"); + assert_expression_approximates_to("[[1]]β†’a", "[[1]]"); quiz_assert(Symbol::Builder('a').recursivelyMatches(Expression::IsMatrix, &context)); - assert_parsed_expression_evaluates_to("1.2β†’b", "1.2"); + assert_expression_approximates_to("1.2β†’b", "1.2"); quiz_assert(Symbol::Builder('b').recursivelyMatches(Expression::IsApproximate, &context, true)); /* [[x]]β†’f(x) expression contains a matrix, so its simplification is going * to be interrupted. We thus rather approximate it instead of simplifying it. * TODO: use parse_and_simplify when matrix are simplified. */ - assert_parsed_expression_evaluates_to("[[x]]β†’f(x)", "[[undef]]"); + assert_expression_approximates_to("[[x]]β†’f(x)", "[[undef]]"); quiz_assert(Function::Builder("f", 1, Symbol::Builder('x')).recursivelyMatches(Poincare::Expression::IsMatrix, &context)); - assert_parsed_expression_evaluates_to("0.2*xβ†’g(x)", "undef"); + assert_expression_approximates_to("0.2*xβ†’g(x)", "undef"); quiz_assert(Function::Builder("g", 1, Rational::Builder(2)).recursivelyMatches(Expression::IsApproximate, &context, true)); // Clean the storage for other tests @@ -205,3 +234,6 @@ QUIZ_CASE(poincare_user_variable_properties) { Ion::Storage::sharedStorage()->recordNamed("f.func").destroy(); Ion::Storage::sharedStorage()->recordNamed("g.func").destroy(); } + +template void assert_parsed_expression_approximates_with_value_for_symbol(Poincare::Expression, const char *, float, float, Poincare::Preferences::ComplexFormat, Poincare::Preferences::AngleUnit); +template void assert_parsed_expression_approximates_with_value_for_symbol(Poincare::Expression, const char *, double, double, Poincare::Preferences::ComplexFormat, Poincare::Preferences::AngleUnit); diff --git a/poincare/test/convert_expression_to_text.cpp b/poincare/test/convert_expression_to_text.cpp deleted file mode 100644 index 11114b6bf..000000000 --- a/poincare/test/convert_expression_to_text.cpp +++ /dev/null @@ -1,286 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "helper.h" - -using namespace Poincare; - -template -void assert_float_prints_to(T a, const char * result, Preferences::PrintFloatMode mode = ScientificMode, int significantDigits = 7, int bufferSize = PrintFloat::k_maxFloatBufferLength) { - quiz_print(result); - - constexpr int tagSize = 8; - unsigned char tag = 'O'; - char taggedBuffer[250+2*tagSize]; - memset(taggedBuffer, tag, bufferSize+2*tagSize); - char * buffer = taggedBuffer + tagSize; - - PrintFloat::convertFloatToText(a, buffer, bufferSize, significantDigits, mode); - - for (int i=0; i::Builder(-1.23456789E30), "-1.23456789ᴇ30", DecimalMode, 14); - assert_expression_prints_to(Float::Builder(1.23456789E30), "1.23456789ᴇ30", DecimalMode, 14); - assert_expression_prints_to(Float::Builder(-1.23456789E-30), "-1.23456789ᴇ-30", DecimalMode, 14); - assert_expression_prints_to(Float::Builder(-1.2345E-3), "-0.0012345", DecimalMode); - assert_expression_prints_to(Float::Builder(1.2345E-3), "0.0012345", DecimalMode); - assert_expression_prints_to(Float::Builder(1.2345E3), "1234.5", DecimalMode); - assert_expression_prints_to(Float::Builder(-1.2345E3), "-1234.5", DecimalMode); - assert_expression_prints_to(Float::Builder(0.99999999999995), "9.9999999999995ᴇ-1", ScientificMode, 14); - assert_expression_prints_to(Float::Builder(0.00000000099999999999995), "9.9999999999995ᴇ-10", DecimalMode, 14); - assert_expression_prints_to(Float::Builder(0.0000000009999999999901200121020102010201201201021099995), "9.9999999999012ᴇ-10", DecimalMode, 14); - assert_expression_prints_to(Float::Builder(1.2345E-1), "0.12345", DecimalMode); - assert_expression_prints_to(Float::Builder(1), "1", DecimalMode); - assert_expression_prints_to(Float::Builder(0.9999999999999995), "1", DecimalMode); - assert_expression_prints_to(Float::Builder(1.2345E6), "1234500", DecimalMode); - assert_expression_prints_to(Float::Builder(-1.2345E6), "-1234500", DecimalMode); - assert_expression_prints_to(Float::Builder(0.0000009999999999999995), "0.000001", DecimalMode); - assert_expression_prints_to(Float::Builder(-1.2345E-1), "-0.12345", DecimalMode); - - assert_expression_prints_to(Float::Builder(INFINITY), Infinity::Name(), DecimalMode); - assert_expression_prints_to(Float::Builder(0.0f), "0", DecimalMode); - assert_expression_prints_to(Float::Builder(NAN), Undefined::Name(), DecimalMode); - -} diff --git a/poincare/test/decimal.cpp b/poincare/test/decimal.cpp deleted file mode 100644 index f3c17ff3d..000000000 --- a/poincare/test/decimal.cpp +++ /dev/null @@ -1,59 +0,0 @@ -#include -#include -#include -#include "helper.h" -#include "tree/helpers.h" - -using namespace Poincare; - -QUIZ_CASE(poincare_decimal_constructor) { - int initialPoolSize = pool_size(); - Decimal a = Decimal::Builder("123",2); - Decimal b = Decimal::Builder("3456", -4); - Decimal c = Decimal::Builder(2.34f); - Decimal d = Decimal::Builder(2322.34); - assert_pool_size(initialPoolSize+4); -} - -static inline void assert_equal(const Decimal i, const Decimal j) { - quiz_assert(i.isIdenticalTo(j)); -} - -static inline void assert_not_equal(const Decimal i, const Decimal j) { - quiz_assert(!i.isIdenticalTo(j)); -} - -QUIZ_CASE(poincare_decimal_compare) { - assert_equal(Decimal::Builder("25", 3), Decimal::Builder("25", 3)); - assert_equal(Decimal::Builder("1000", -3), Decimal::Builder("1", -3)); - assert_equal(Decimal::Builder("1000", 3), Decimal::Builder("1", 3)); - assert_not_equal(Decimal::Builder(123,234), Decimal::Builder(42, 108)); - assert_not_equal(Decimal::Builder(12,2), Decimal::Builder(123, 2)); - assert_not_equal(Decimal::Builder(1234,2), Decimal::Builder(1234,3)); - assert_not_equal(Decimal::Builder(12345,2), Decimal::Builder(1235,2)); - assert_not_equal(Decimal::Builder(123456, -2),Decimal::Builder(1234567, -3)); - assert_not_equal(Decimal::Builder(12345678, -2),Decimal::Builder(1234567, -2)); -} - -QUIZ_CASE(poincare_decimal_properties) { - quiz_assert(Decimal::Builder(-2, 3).sign() == ExpressionNode::Sign::Negative); - quiz_assert(Decimal::Builder(-2, -3).sign() == ExpressionNode::Sign::Negative); - quiz_assert(Decimal::Builder(2, -3).sign() == ExpressionNode::Sign::Positive); - quiz_assert(Decimal::Builder(2, 3).sign() == ExpressionNode::Sign::Positive); - quiz_assert(Decimal::Builder(0, 1).sign() == ExpressionNode::Sign::Positive); -} - -// Simplify - -QUIZ_CASE(poincare_decimal_simplify) { - assert_parsed_expression_simplify_to("-2.3", "-23/10"); - assert_parsed_expression_simplify_to("-232.2ᴇ-4", "-1161/50000"); - assert_parsed_expression_simplify_to("0000.000000ᴇ-2", "0"); - assert_parsed_expression_simplify_to(".000000", "0"); - assert_parsed_expression_simplify_to("0000", "0"); -} - -QUIZ_CASE(poincare_decimal_approximate) { - assert_parsed_expression_evaluates_to("1.2343ᴇ-2", "0.012343"); - assert_parsed_expression_evaluates_to("-567.2ᴇ2", "-56720"); -} diff --git a/poincare/test/division.cpp b/poincare/test/division.cpp deleted file mode 100644 index 0cd4b9768..000000000 --- a/poincare/test/division.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include -#include -#include -#include -#include "helper.h" - -using namespace Poincare; - -QUIZ_CASE(poincare_division_evaluate) { - assert_parsed_expression_evaluates_to("1/2", "0.5"); - assert_parsed_expression_evaluates_to("(3+𝐒)/(4+𝐒)", "7.6470588235294ᴇ-1+5.8823529411765ᴇ-2×𝐒"); - assert_parsed_expression_evaluates_to("[[1,2][3,4][5,6]]/2", "[[0.5,1][1.5,2][2.5,3]]"); - assert_parsed_expression_evaluates_to("[[1,2+𝐒][3,4][5,6]]/(1+𝐒)", "[[0.5-0.5×𝐒,1.5-0.5×𝐒][1.5-1.5×𝐒,2-2×𝐒][2.5-2.5×𝐒,3-3×𝐒]]"); - assert_parsed_expression_evaluates_to("[[1,2][3,4][5,6]]/2", "[[0.5,1][1.5,2][2.5,3]]"); - assert_parsed_expression_evaluates_to("[[1,2][3,4]]/[[3,4][6,9]]", "[[-1,6.6666666666667ᴇ-1][1,0]]"); - assert_parsed_expression_evaluates_to("3/[[3,4][5,6]]", "[[-9,6][7.5,-4.5]]"); - assert_parsed_expression_evaluates_to("(3+4𝐒)/[[1,𝐒][3,4]]", "[[4×𝐒,1][-3×𝐒,𝐒]]"); - assert_parsed_expression_evaluates_to("1ᴇ20/(1ᴇ20+1ᴇ20𝐒)", "0.5-0.5×𝐒"); - assert_parsed_expression_evaluates_to("1ᴇ155/(1ᴇ155+1ᴇ155𝐒)", "0.5-0.5×𝐒"); -} diff --git a/poincare/test/expression.cpp b/poincare/test/expression.cpp index 3881823bb..a7c69f080 100644 --- a/poincare/test/expression.cpp +++ b/poincare/test/expression.cpp @@ -1,10 +1,13 @@ #include +#include +#include #include #include +#include "tree/helpers.h" using namespace Poincare; -QUIZ_CASE(expression_can_start_uninitialized) { +QUIZ_CASE(poincare_expression_can_start_uninitialized) { Expression e; { Rational i = Rational::Builder(1); @@ -12,8 +15,57 @@ QUIZ_CASE(expression_can_start_uninitialized) { } } -QUIZ_CASE(expression_can_be_copied_even_if_uninitialized) { +QUIZ_CASE(poincare_expression_can_be_copied_even_if_uninitialized) { Expression e; Expression f; f = e; } + +QUIZ_CASE(poincare_expression_cast_does_not_copy) { + Rational i1 = Rational::Builder(1); + Rational i2 = Rational::Builder(2); + Addition j = Addition::Builder(i1, i2); + Expression k = j; + quiz_assert(k.identifier() == (static_cast(k)).identifier()); + quiz_assert(i1.identifier() == (static_cast(i1)).identifier()); + quiz_assert(k.identifier() == (static_cast(k)).identifier()); +} + +static inline void assert_equal(const Decimal i, const Decimal j) { + quiz_assert(i.isIdenticalTo(j)); +} + +static inline void assert_not_equal(const Decimal i, const Decimal j) { + quiz_assert(!i.isIdenticalTo(j)); +} + +QUIZ_CASE(poincare_expression_decimal_constructor) { + int initialPoolSize = pool_size(); + Decimal a = Decimal::Builder("123",2); + Decimal b = Decimal::Builder("3456", -4); + Decimal c = Decimal::Builder(2.34f); + Decimal d = Decimal::Builder(2322.34); + assert_pool_size(initialPoolSize+4); + + assert_equal(Decimal::Builder("25", 3), Decimal::Builder("25", 3)); + assert_equal(Decimal::Builder("1000", -3), Decimal::Builder("1", -3)); + assert_equal(Decimal::Builder("1000", 3), Decimal::Builder("1", 3)); + assert_not_equal(Decimal::Builder(123,234), Decimal::Builder(42, 108)); + assert_not_equal(Decimal::Builder(12,2), Decimal::Builder(123, 2)); + assert_not_equal(Decimal::Builder(1234,2), Decimal::Builder(1234,3)); + assert_not_equal(Decimal::Builder(12345,2), Decimal::Builder(1235,2)); + assert_not_equal(Decimal::Builder(123456, -2),Decimal::Builder(1234567, -3)); + assert_not_equal(Decimal::Builder(12345678, -2),Decimal::Builder(1234567, -2)); +} + +QUIZ_CASE(poincare_expression_rational_constructor) { + int initialPoolSize = pool_size(); + Rational a = Rational::Builder("123","324"); + Rational b = Rational::Builder("3456"); + Rational c = Rational::Builder(123,324); + Rational d = Rational::Builder(3456789); + Integer overflow = Integer::Overflow(false); + Rational e = Rational::Builder(overflow); + Rational f = Rational::Builder(overflow, overflow); + assert_pool_size(initialPoolSize+6); +} diff --git a/poincare/test/expression_order.cpp b/poincare/test/expression_order.cpp index 39a177765..cc739014e 100644 --- a/poincare/test/expression_order.cpp +++ b/poincare/test/expression_order.cpp @@ -7,6 +7,32 @@ using namespace Poincare; +// TODO add tests about expression that override simplificationOrderSameType or simplificationOrderGreaterType + +static inline void assert_equal(const Rational i, const Rational j) { + quiz_assert(Rational::NaturalOrder(i, j) == 0); +} +static inline void assert_not_equal(const Rational i, const Rational j) { + quiz_assert(Rational::NaturalOrder(i, j) != 0); +} + +static inline void assert_lower(const Rational i, const Rational j) { + quiz_assert(Rational::NaturalOrder(i, j) < 0); +} + +static inline void assert_greater(const Rational i, const Rational j) { + quiz_assert(Rational::NaturalOrder(i, j) > 0); +} + +QUIZ_CASE(poincare_expression_order_rational) { + assert_equal(Rational::Builder(123,324), Rational::Builder(41,108)); + assert_not_equal(Rational::Builder(123,234), Rational::Builder(42, 108)); + assert_lower(Rational::Builder(123,234), Rational::Builder(456,567)); + assert_lower(Rational::Builder(-123, 234),Rational::Builder(456, 567)); + assert_greater(Rational::Builder(123, 234),Rational::Builder(-456, 567)); + assert_greater(Rational::Builder(123, 234),Rational::Builder("123456789123456789", "12345678912345678910")); +} + void assert_multiplication_or_addition_is_ordered_as(Expression e1, Expression e2) { Shared::GlobalContext globalContext; if (e1.type() == ExpressionNode::Type::MultiplicationExplicite) { @@ -24,7 +50,7 @@ void assert_multiplication_or_addition_is_ordered_as(Expression e1, Expression e quiz_assert(e1.isIdenticalTo(e2)); } -QUIZ_CASE(poincare_expression_order) { +QUIZ_CASE(poincare_expression_order_addition_multiplication) { { // 2 * 5 -> 2 * 5 Expression e1 = MultiplicationExplicite::Builder(Rational::Builder(2), Rational::Builder(5)); diff --git a/poincare/test/expression_properties.cpp b/poincare/test/expression_properties.cpp new file mode 100644 index 000000000..322986d8a --- /dev/null +++ b/poincare/test/expression_properties.cpp @@ -0,0 +1,200 @@ +#include +#include +#include +#include +#include "helper.h" +#include "tree/helpers.h" + +using namespace Poincare; + +// TODO add tests about expression that override sign + +constexpr Poincare::ExpressionNode::Sign Positive = Poincare::ExpressionNode::Sign::Positive; +constexpr Poincare::ExpressionNode::Sign Negative = Poincare::ExpressionNode::Sign::Negative; +constexpr Poincare::ExpressionNode::Sign Unknown = Poincare::ExpressionNode::Sign::Unknown; + +void assert_reduced_expression_sign(const char * expression, Poincare::ExpressionNode::Sign sign, Preferences::ComplexFormat complexFormat = Cartesian, Preferences::AngleUnit angleUnit = Radian) { + Shared::GlobalContext globalContext; + Expression e = parse_expression(expression, false); + e = e.reduce(&globalContext, complexFormat, angleUnit); + quiz_assert_print_if_failure(e.sign(&globalContext) == sign, expression); +} + +QUIZ_CASE(poincare_properties_decimal_sign) { + quiz_assert(Decimal::Builder(-2, 3).sign() == ExpressionNode::Sign::Negative); + quiz_assert(Decimal::Builder(-2, -3).sign() == ExpressionNode::Sign::Negative); + quiz_assert(Decimal::Builder(2, -3).sign() == ExpressionNode::Sign::Positive); + quiz_assert(Decimal::Builder(2, 3).sign() == ExpressionNode::Sign::Positive); + quiz_assert(Decimal::Builder(0, 1).sign() == ExpressionNode::Sign::Positive); +} + +QUIZ_CASE(poincare_properties_rational_sign) { + quiz_assert(Rational::Builder(-2).sign() == ExpressionNode::Sign::Negative); + quiz_assert(Rational::Builder(-2, 3).sign() == ExpressionNode::Sign::Negative); + quiz_assert(Rational::Builder(2, 3).sign() == ExpressionNode::Sign::Positive); + quiz_assert(Rational::Builder(0, 3).sign() == ExpressionNode::Sign::Positive); +} + +QUIZ_CASE(poincare_properties_sign) { + assert_reduced_expression_sign("abs(-cos(2)+I)", Positive); + assert_reduced_expression_sign("2.345ᴇ-23", Positive); + assert_reduced_expression_sign("-2.345ᴇ-23", Negative); + assert_reduced_expression_sign("2Γ—(-3)Γ—abs(-32)", Negative); + assert_reduced_expression_sign("2Γ—(-3)Γ—abs(-32)Γ—cos(3)", Unknown); + assert_reduced_expression_sign("x", Unknown); + assert_reduced_expression_sign("2^(-abs(3))", Positive); + assert_reduced_expression_sign("(-2)^4", Positive); + assert_reduced_expression_sign("(-2)^3", Negative); + assert_reduced_expression_sign("random()", Positive); + assert_reduced_expression_sign("42/3", Positive); + assert_reduced_expression_sign("-23/32", Negative); + assert_reduced_expression_sign("Ο€", Positive); + assert_reduced_expression_sign("β„―", Positive); + assert_reduced_expression_sign("0", Positive); + assert_reduced_expression_sign("cos(Ο€/2)", Positive); + assert_reduced_expression_sign("cos(90)", Positive, Cartesian, Degree); + assert_reduced_expression_sign("√(-1)", Unknown); + assert_reduced_expression_sign("√(-1)", Unknown, Real); +} + +void assert_reduced_expression_polynomial_degree(const char * expression, int degree, const char * symbolName = "x", Preferences::ComplexFormat complexFormat = Cartesian, Preferences::AngleUnit angleUnit = Radian) { + Shared::GlobalContext globalContext; + Expression e = parse_expression(expression, false); + Expression result = e.reduce(&globalContext, complexFormat, angleUnit); + quiz_assert_print_if_failure(result.polynomialDegree(&globalContext, symbolName) == degree, expression); +} + +QUIZ_CASE(poincare_properties_polynomial_degree) { + assert_reduced_expression_polynomial_degree("x+1", 1); + assert_reduced_expression_polynomial_degree("cos(2)+1", 0); + assert_reduced_expression_polynomial_degree("confidence(0.2,10)+1", -1); + assert_reduced_expression_polynomial_degree("diff(3Γ—x+x,x,2)", -1); + assert_reduced_expression_polynomial_degree("diff(3Γ—x+x,x,x)", -1); + assert_reduced_expression_polynomial_degree("diff(3Γ—x+x,x,x)", 0, "a"); + assert_reduced_expression_polynomial_degree("(3Γ—x+2)/3", 1); + assert_reduced_expression_polynomial_degree("(3Γ—x+2)/x", -1); + assert_reduced_expression_polynomial_degree("int(2Γ—x,x, 0, 1)", -1); + assert_reduced_expression_polynomial_degree("int(2Γ—x,x, 0, 1)", 0, "a"); + assert_reduced_expression_polynomial_degree("[[1,2][3,4]]", -1); + assert_reduced_expression_polynomial_degree("(x^2+2)Γ—(x+1)", 3); + assert_reduced_expression_polynomial_degree("-(x+1)", 1); + assert_reduced_expression_polynomial_degree("(x^2+2)^(3)", 6); + assert_reduced_expression_polynomial_degree("prediction(0.2,10)+1", -1); + assert_reduced_expression_polynomial_degree("2-x-x^3", 3); + assert_reduced_expression_polynomial_degree("π×x", 1); + assert_reduced_expression_polynomial_degree("√(-1)Γ—x", -1, "x", Real); + // f: xβ†’x^2+Ο€x+1 + assert_simplify("1+π×x+x^2β†’f(x)"); + assert_reduced_expression_polynomial_degree("f(x)", 2); +} + +void assert_reduced_expression_has_characteristic_range(Expression e, float range, Preferences::AngleUnit angleUnit = Preferences::AngleUnit::Degree) { + Shared::GlobalContext globalContext; + e = e.reduce(&globalContext, Preferences::ComplexFormat::Cartesian, angleUnit); + if (std::isnan(range)) { + quiz_assert(std::isnan(e.characteristicXRange(&globalContext, angleUnit))); + } else { + quiz_assert(std::fabs(e.characteristicXRange(&globalContext, angleUnit) - range) < 0.0000001f); + } +} + +QUIZ_CASE(poincare_properties_characteristic_range) { + // cos(x), degree + assert_reduced_expression_has_characteristic_range(Cosine::Builder(Symbol::Builder(UCodePointUnknownX)), 360.0f); + // cos(-x), degree + assert_reduced_expression_has_characteristic_range(Cosine::Builder(Opposite::Builder(Symbol::Builder(UCodePointUnknownX))), 360.0f); + // cos(x), radian + assert_reduced_expression_has_characteristic_range(Cosine::Builder(Symbol::Builder(UCodePointUnknownX)), 2.0f*M_PI, Preferences::AngleUnit::Radian); + // cos(-x), radian + assert_reduced_expression_has_characteristic_range(Cosine::Builder(Opposite::Builder(Symbol::Builder(UCodePointUnknownX))), 2.0f*M_PI, Preferences::AngleUnit::Radian); + // sin(9x+10), degree + assert_reduced_expression_has_characteristic_range(Sine::Builder(Addition::Builder(MultiplicationExplicite::Builder(Rational::Builder(9),Symbol::Builder(UCodePointUnknownX)),Rational::Builder(10))), 40.0f); + // sin(9x+10)+cos(x/2), degree + assert_reduced_expression_has_characteristic_range(Addition::Builder(Sine::Builder(Addition::Builder(MultiplicationExplicite::Builder(Rational::Builder(9),Symbol::Builder(UCodePointUnknownX)),Rational::Builder(10))),Cosine::Builder(Division::Builder(Symbol::Builder(UCodePointUnknownX),Rational::Builder(2)))), 720.0f); + // sin(9x+10)+cos(x/2), radian + assert_reduced_expression_has_characteristic_range(Addition::Builder(Sine::Builder(Addition::Builder(MultiplicationExplicite::Builder(Rational::Builder(9),Symbol::Builder(UCodePointUnknownX)),Rational::Builder(10))),Cosine::Builder(Division::Builder(Symbol::Builder(UCodePointUnknownX),Rational::Builder(2)))), 4.0f*M_PI, Preferences::AngleUnit::Radian); + // x, degree + assert_reduced_expression_has_characteristic_range(Symbol::Builder(UCodePointUnknownX), NAN); + // cos(3)+2, degree + assert_reduced_expression_has_characteristic_range(Addition::Builder(Cosine::Builder(Rational::Builder(3)),Rational::Builder(2)), 0.0f); + // log(cos(40x), degree + assert_reduced_expression_has_characteristic_range(CommonLogarithm::Builder(Cosine::Builder(MultiplicationExplicite::Builder(Rational::Builder(40),Symbol::Builder(UCodePointUnknownX)))), 9.0f); + // cos(cos(x)), degree + assert_reduced_expression_has_characteristic_range(Cosine::Builder((Expression)Cosine::Builder(Symbol::Builder(UCodePointUnknownX))), 360.0f); + // f(x) with f : x --> cos(x), degree + assert_simplify("cos(x)β†’f(x)"); + assert_reduced_expression_has_characteristic_range(Function::Builder("f",1,Symbol::Builder(UCodePointUnknownX)), 360.0f); +} + +void assert_expression_has_variables(const char * expression, const char * variables[], int trueNumberOfVariables) { + Expression e = parse_expression(expression, false); + constexpr static int k_maxVariableSize = Poincare::SymbolAbstract::k_maxNameSize; + char variableBuffer[Expression::k_maxNumberOfVariables+1][k_maxVariableSize] = {{0}}; + Shared::GlobalContext globalContext; + int numberOfVariables = e.getVariables(&globalContext, [](const char * symbol) { return true; }, (char *)variableBuffer, k_maxVariableSize); + quiz_assert_print_if_failure(trueNumberOfVariables == numberOfVariables, expression); + if (numberOfVariables < 0) { + // Too many variables + return; + } + int index = 0; + while (variableBuffer[index][0] != 0 || variables[index][0] != 0) { + quiz_assert_print_if_failure(strcmp(variableBuffer[index], variables[index]) == 0, expression); + index++; + } +} + +QUIZ_CASE(poincare_preperties_get_variables) { + const char * variableBuffer1[] = {"x","y",""}; + assert_expression_has_variables("x+y", variableBuffer1, 2); + const char * variableBuffer2[] = {"x","y","z","t",""}; + assert_expression_has_variables("x+y+z+2Γ—t", variableBuffer2, 4); + const char * variableBuffer3[] = {"a","x","y","k","A", ""}; + assert_expression_has_variables("a+x^2+2Γ—y+k!Γ—A", variableBuffer3, 5); + const char * variableBuffer4[] = {"BABA","abab", ""}; + assert_expression_has_variables("BABA+abab", variableBuffer4, 2); + const char * variableBuffer5[] = {"BBBBBB", ""}; + assert_expression_has_variables("BBBBBB", variableBuffer5, 1); + const char * variableBuffer6[] = {""}; + assert_expression_has_variables("a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p+q+r+s+t+aa+bb+cc+dd+ee+ff+gg+hh+ii+jj+kk+ll+mm+nn+oo", variableBuffer6, -1); + // f: xβ†’1+Ο€x+x^2+toto + assert_simplify("1+π×x+x^2+totoβ†’f(x)"); + const char * variableBuffer7[] = {"tata","toto", ""}; + assert_expression_has_variables("f(tata)", variableBuffer7, 2); +} + +void assert_reduced_expression_has_polynomial_coefficient(const char * expression, const char * symbolName, const char ** coefficients, Preferences::ComplexFormat complexFormat = Cartesian, Preferences::AngleUnit angleUnit = Radian) { + Shared::GlobalContext globalContext; + Expression e = parse_expression(expression, false); + e = e.reduce(&globalContext, complexFormat, angleUnit); + Expression coefficientBuffer[Poincare::Expression::k_maxNumberOfPolynomialCoefficients]; + int d = e.getPolynomialReducedCoefficients(symbolName, coefficientBuffer, &globalContext, complexFormat, Radian); + for (int i = 0; i <= d; i++) { + Expression f = parse_expression(coefficients[i], false); + quiz_assert(!f.isUninitialized()); + coefficientBuffer[i] = coefficientBuffer[i].reduce(&globalContext, complexFormat, angleUnit); + f = f.reduce(&globalContext, complexFormat, angleUnit); + quiz_assert_print_if_failure(coefficientBuffer[i].isIdenticalTo(f), expression); + } + quiz_assert_print_if_failure(coefficients[d+1] == 0, expression); +} + +QUIZ_CASE(poincare_properties_get_polynomial_coefficients) { + const char * coefficient0[] = {"2", "1", "1", 0}; + assert_reduced_expression_has_polynomial_coefficient("x^2+x+2", "x", coefficient0); + const char * coefficient1[] = {"12+(-6)Γ—Ο€", "12", "3", 0}; //3Γ—x^2+12Γ—x-6Γ—Ο€+12 + assert_reduced_expression_has_polynomial_coefficient("3Γ—(x+2)^2-6Γ—Ο€", "x", coefficient1); + // TODO: decomment when enable 3-degree polynomes + //const char * coefficient2[] = {"2+32Γ—x", "2", "6", "2", 0}; //2Γ—n^3+6Γ—n^2+2Γ—n+2+32Γ—x + //assert_reduced_expression_has_polynomial_coefficient("2Γ—(n+1)^3-4n+32Γ—x", "n", coefficient2); + const char * coefficient3[] = {"1", "-Ο€", "1", 0}; //x^2-π×x+1 + assert_reduced_expression_has_polynomial_coefficient("x^2-π×x+1", "x", coefficient3); + // f: xβ†’x^2+Px+1 + const char * coefficient4[] = {"1", "Ο€", "1", 0}; //x^2+π×x+1 + assert_simplify("1+π×x+x^2β†’f(x)"); + assert_reduced_expression_has_polynomial_coefficient("f(x)", "x", coefficient4); + const char * coefficient5[] = {"0", "𝐒", 0}; //√(-1)x + assert_reduced_expression_has_polynomial_coefficient("√(-1)x", "x", coefficient5); + const char * coefficient6[] = {0}; //√(-1)x + assert_reduced_expression_has_polynomial_coefficient("√(-1)x", "x", coefficient6, Real); +} diff --git a/poincare/test/expression_serialization.cpp b/poincare/test/expression_serialization.cpp new file mode 100644 index 000000000..54a6a2e92 --- /dev/null +++ b/poincare/test/expression_serialization.cpp @@ -0,0 +1,121 @@ +#include +#include +#include +#include "helper.h" + +using namespace Poincare; + +// TODO: add tests + +void assert_expression_serialize_to(Poincare::Expression expression, const char * serialization, Preferences::PrintFloatMode mode = ScientificMode, int numberOfSignificantDigits = 7) { + constexpr int bufferSize = 500; + char buffer[bufferSize]; + expression.serialize(buffer, bufferSize, mode, numberOfSignificantDigits); + quiz_assert_print_if_failure(strcmp(serialization, buffer) == 0, serialization); +} + +QUIZ_CASE(poincare_serialization_rational) { + assert_expression_serialize_to(Rational::Builder(2,3), "2/3"); + assert_expression_serialize_to(Rational::Builder("12345678910111213","123456789101112131"), "12345678910111213/123456789101112131"); + assert_expression_serialize_to(Rational::Builder("123456789112345678921234567893123456789412345678951234567896123456789612345678971234567898123456789912345678901234567891123456789212345678931234567894123456789512345678961234567896123456789712345678981234567899123456789","1"), "123456789112345678921234567893123456789412345678951234567896123456789612345678971234567898123456789912345678901234567891123456789212345678931234567894123456789512345678961234567896123456789712345678981234567899123456789"); + assert_expression_serialize_to(Rational::Builder(-2, 3), "-2/3"); + assert_expression_serialize_to(Rational::Builder("2345678909876"), "2345678909876"); + assert_expression_serialize_to(Rational::Builder("-2345678909876", "5"), "-2345678909876/5"); + assert_expression_serialize_to(Rational::Builder(MaxIntegerString()), MaxIntegerString()); + Integer one(1); + Integer overflow = Integer::Overflow(false); + assert_expression_serialize_to(Rational::Builder(one, overflow), "1/inf"); + assert_expression_serialize_to(Rational::Builder(overflow), Infinity::Name()); +} + +QUIZ_CASE(poincare_serialization_decimal) { + Decimal d0 = Decimal::Builder(Integer("-123456789"),30); + assert_expression_serialize_to(d0, "-1.23456789ᴇ30", ScientificMode, 14); + assert_expression_serialize_to(d0, "-1.234568ᴇ30", DecimalMode, 7); + Decimal d1 = Decimal::Builder(Integer("123456789"),30); + assert_expression_serialize_to(d1, "1.23456789ᴇ30", ScientificMode, 14); + assert_expression_serialize_to(d1, "1.235ᴇ30", DecimalMode, 4); + Decimal d2 = Decimal::Builder(Integer("-123456789"),-30); + assert_expression_serialize_to(d2, "-1.23456789ᴇ-30", DecimalMode, 14); + assert_expression_serialize_to(d2, "-1.235ᴇ-30", ScientificMode, 4); + Decimal d3 = Decimal::Builder(Integer("-12345"),-3); + assert_expression_serialize_to(d3, "-0.0012345", DecimalMode, 7); + assert_expression_serialize_to(d3, "-0.00123", DecimalMode, 3); + assert_expression_serialize_to(d3, "-0.001235", DecimalMode, 4); + assert_expression_serialize_to(d3, "-1.23ᴇ-3", ScientificMode, 3); + Decimal d4 = Decimal::Builder(Integer("12345"),-3); + assert_expression_serialize_to(d4, "0.0012345", DecimalMode, 7); + assert_expression_serialize_to(d4, "1.2ᴇ-3", ScientificMode, 2); + Decimal d5 = Decimal::Builder(Integer("12345"),3); + assert_expression_serialize_to(d5, "1234.5", DecimalMode, 7); + assert_expression_serialize_to(d5, "1.23ᴇ3", DecimalMode, 3); + assert_expression_serialize_to(d5, "1235", DecimalMode, 4); + assert_expression_serialize_to(d5, "1.235ᴇ3", ScientificMode, 4); + Decimal d6 = Decimal::Builder(Integer("-12345"),3); + assert_expression_serialize_to(d6, "-1234.5", DecimalMode, 7); + assert_expression_serialize_to(d6, "-1.2345ᴇ3", ScientificMode, 10); + Decimal d7 = Decimal::Builder(Integer("12345"),6); + assert_expression_serialize_to(d7, "1234500", DecimalMode, 7); + assert_expression_serialize_to(d7, "1.2345ᴇ6", DecimalMode, 6); + assert_expression_serialize_to(d7, "1.2345ᴇ6", ScientificMode); + Decimal d8 = Decimal::Builder(Integer("-12345"),6); + assert_expression_serialize_to(d8, "-1234500", DecimalMode, 7); + assert_expression_serialize_to(d8, "-1.2345ᴇ6", DecimalMode, 5); + assert_expression_serialize_to(d7, "1.235ᴇ6", ScientificMode, 4); + Decimal d9 = Decimal::Builder(Integer("-12345"),-1); + assert_expression_serialize_to(d9, "-0.12345", DecimalMode, 7); + assert_expression_serialize_to(d9, "-0.1235", DecimalMode, 4); + assert_expression_serialize_to(d9, "-1.235ᴇ-1", ScientificMode, 4); + Decimal d10 = Decimal::Builder(Integer("12345"),-1); + assert_expression_serialize_to(d10, "1.2345ᴇ-1"); + assert_expression_serialize_to(d10, "0.12345", DecimalMode, 7); + assert_expression_serialize_to(d10, "0.1235", DecimalMode, 4); + assert_expression_serialize_to(d10, "1.235ᴇ-1", ScientificMode, 4); + + assert_expression_serialize_to(Decimal::Builder(-1.23456789E30), "-1.23456789ᴇ30", ScientificMode, 14); + assert_expression_serialize_to(Decimal::Builder(1.23456789E30), "1.23456789ᴇ30", ScientificMode, 14); + assert_expression_serialize_to(Decimal::Builder(-1.23456789E-30), "-1.23456789ᴇ-30", ScientificMode, 14); + assert_expression_serialize_to(Decimal::Builder(-1.2345E-3), "-0.0012345", DecimalMode); + assert_expression_serialize_to(Decimal::Builder(1.2345E-3), "0.0012345", DecimalMode); + assert_expression_serialize_to(Decimal::Builder(1.2345E3), "1234.5", DecimalMode); + assert_expression_serialize_to(Decimal::Builder(-1.2345E3), "-1234.5", DecimalMode); + assert_expression_serialize_to(Decimal::Builder(1.2345E6), "1234500", DecimalMode); + assert_expression_serialize_to(Decimal::Builder(-1.2345E6), "-1234500", DecimalMode); + assert_expression_serialize_to(Decimal::Builder(-1.2345E-1), "-0.12345", DecimalMode); + assert_expression_serialize_to(Decimal::Builder(1.2345E-1), "0.12345", DecimalMode); + assert_expression_serialize_to(Decimal::Builder(1.0), "1"); + assert_expression_serialize_to(Decimal::Builder(0.9999999999999996), "1"); + assert_expression_serialize_to(Decimal::Builder(0.99999999999995), "9.9999999999995ᴇ-1", ScientificMode, 14); + assert_expression_serialize_to(Decimal::Builder(0.00000099999999999995), "9.9999999999995ᴇ-7", ScientificMode, 14); + assert_expression_serialize_to(Decimal::Builder(0.000000999999999999995), "0.000001", DecimalMode); + assert_expression_serialize_to(Decimal::Builder(0.000000999999999901200121020102010201201201021099995), "9.999999999012ᴇ-7", DecimalMode, 14); + assert_expression_serialize_to(Decimal::Builder(9999999999999.54), "9999999999999.5", DecimalMode, 14); + assert_expression_serialize_to(Decimal::Builder(99999999999999.54), "1ᴇ14", DecimalMode, 14); + assert_expression_serialize_to(Decimal::Builder(999999999999999.54), "1ᴇ15", DecimalMode, 14); + assert_expression_serialize_to(Decimal::Builder(9999999999999999.54), "1ᴇ16", DecimalMode, 14); + assert_expression_serialize_to(Decimal::Builder(-9.702365051313E-297), "-9.702365051313ᴇ-297", DecimalMode, 14); +} + +QUIZ_CASE(poincare_serialization_float) { + assert_expression_serialize_to(Float::Builder(-1.23456789E30), "-1.23456789ᴇ30", DecimalMode, 14); + assert_expression_serialize_to(Float::Builder(1.23456789E30), "1.23456789ᴇ30", DecimalMode, 14); + assert_expression_serialize_to(Float::Builder(-1.23456789E-30), "-1.23456789ᴇ-30", DecimalMode, 14); + assert_expression_serialize_to(Float::Builder(-1.2345E-3), "-0.0012345", DecimalMode); + assert_expression_serialize_to(Float::Builder(1.2345E-3), "0.0012345", DecimalMode); + assert_expression_serialize_to(Float::Builder(1.2345E3), "1234.5", DecimalMode); + assert_expression_serialize_to(Float::Builder(-1.2345E3), "-1234.5", DecimalMode); + assert_expression_serialize_to(Float::Builder(0.99999999999995), "9.9999999999995ᴇ-1", ScientificMode, 14); + assert_expression_serialize_to(Float::Builder(0.00000000099999999999995), "9.9999999999995ᴇ-10", DecimalMode, 14); + assert_expression_serialize_to(Float::Builder(0.0000000009999999999901200121020102010201201201021099995), "9.9999999999012ᴇ-10", DecimalMode, 14); + assert_expression_serialize_to(Float::Builder(1.2345E-1), "0.12345", DecimalMode); + assert_expression_serialize_to(Float::Builder(1), "1", DecimalMode); + assert_expression_serialize_to(Float::Builder(0.9999999999999995), "1", DecimalMode); + assert_expression_serialize_to(Float::Builder(1.2345E6), "1234500", DecimalMode); + assert_expression_serialize_to(Float::Builder(-1.2345E6), "-1234500", DecimalMode); + assert_expression_serialize_to(Float::Builder(0.0000009999999999999995), "0.000001", DecimalMode); + assert_expression_serialize_to(Float::Builder(-1.2345E-1), "-0.12345", DecimalMode); + + assert_expression_serialize_to(Float::Builder(INFINITY), Infinity::Name(), DecimalMode); + assert_expression_serialize_to(Float::Builder(0.0f), "0", DecimalMode); + assert_expression_serialize_to(Float::Builder(NAN), Undefined::Name(), DecimalMode); +} diff --git a/poincare/test/expression_to_layout.cpp b/poincare/test/expression_to_layout.cpp new file mode 100644 index 000000000..d2a7eb171 --- /dev/null +++ b/poincare/test/expression_to_layout.cpp @@ -0,0 +1,23 @@ +#include +#include +#include "helper.h" +#include "tree/helpers.h" + +using namespace Poincare; + +// TODO: ADD TESTS + +void assert_parsed_expression_layout_serialize_to_self(const char * expressionLayout) { + Expression e = parse_expression(expressionLayout, true); + Layout el = e.createLayout(DecimalMode, PrintFloat::k_numberOfStoredSignificantDigits); + constexpr int bufferSize = 255; + char buffer[bufferSize]; + el.serializeForParsing(buffer, bufferSize); + quiz_assert_print_if_failure(strcmp(expressionLayout, buffer) == 0, expressionLayout); +} + +QUIZ_CASE(poincare_expression_to_layout) { + assert_parsed_expression_layout_serialize_to_self("binomial\u00127,6\u0013"); + assert_parsed_expression_layout_serialize_to_self("root\u00127,3\u0013"); +} + diff --git a/poincare/test/factorial.cpp b/poincare/test/factorial.cpp deleted file mode 100644 index 5ab7884f1..000000000 --- a/poincare/test/factorial.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include -#include -#include -#include "helper.h" - -using namespace Poincare; - -QUIZ_CASE(poincare_factorial_simplify) { - assert_parsed_expression_simplify_to("1/3!", "1/6"); - assert_parsed_expression_simplify_to("5!", "120"); - assert_parsed_expression_simplify_to("(1/3)!", Undefined::Name()); - assert_parsed_expression_simplify_to("Ο€!", Undefined::Name()); - assert_parsed_expression_simplify_to("β„―!", Undefined::Name()); -} diff --git a/poincare/test/float.cpp b/poincare/test/float.cpp deleted file mode 100644 index 39bbd61df..000000000 --- a/poincare/test/float.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "helper.h" - -using namespace Poincare; - -template -void assert_float_evaluates_to(Float f, const char * result) { - Shared::GlobalContext globalContext; - int numberOfDigits = sizeof(T) == sizeof(double) ? PrintFloat::k_numberOfStoredSignificantDigits : PrintFloat::k_numberOfPrintedSignificantDigits; - char buffer[500]; - f.template approximate(&globalContext, Cartesian, Radian).serialize(buffer, sizeof(buffer), DecimalMode, numberOfDigits); - quiz_assert(strcmp(buffer, result) == 0); -} - -QUIZ_CASE(poincare_float_evaluate) { - assert_float_evaluates_to(Float::Builder(-1.23456789E30), "-1.23456789ᴇ30"); - assert_float_evaluates_to(Float::Builder(1.23456789E30), "1.23456789ᴇ30"); - assert_float_evaluates_to(Float::Builder(-1.23456789E-30), "-1.23456789ᴇ-30"); - assert_float_evaluates_to(Float::Builder(-1.2345E-3), "-0.0012345"); - assert_float_evaluates_to(Float::Builder(1.2345E-3), "0.0012345"); - assert_float_evaluates_to(Float::Builder(1.2345E3), "1234.5"); - assert_float_evaluates_to(Float::Builder(-1.2345E3), "-1234.5"); - assert_float_evaluates_to(Float::Builder(0.99999999999995), "9.9999999999995ᴇ-1"); - assert_float_evaluates_to(Float::Builder(0.00000099999999999995), "9.9999999999995ᴇ-7"); - assert_float_evaluates_to(Float::Builder(0.0000009999999999901200121020102010201201201021099995), "9.9999999999012ᴇ-7"); - assert_float_evaluates_to(Float::Builder(1.2345E-1), "0.12345"); - assert_float_evaluates_to(Float::Builder(1), "1"); - assert_float_evaluates_to(Float::Builder(0.9999999999999995), "1"); - assert_float_evaluates_to(Float::Builder(1.2345E6), "1234500"); - assert_float_evaluates_to(Float::Builder(-1.2345E6), "-1234500"); - assert_float_evaluates_to(Float::Builder(0.0000009999999999999995), "0.000001"); - assert_float_evaluates_to(Float::Builder(-1.2345E-1), "-0.12345"); - - assert_float_evaluates_to(Float::Builder(INFINITY), Infinity::Name()); - assert_float_evaluates_to(Float::Builder(0.0f), "0"); - assert_float_evaluates_to(Float::Builder(NAN), Undefined::Name()); - -} diff --git a/poincare/test/fraction_layout.cpp b/poincare/test/fraction_layout.cpp deleted file mode 100644 index e17ec7cf6..000000000 --- a/poincare/test/fraction_layout.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#include -#include -#include -#include -#include "helper.h" - -using namespace Poincare; - -QUIZ_CASE(poincare_fraction_layout_create) { - - /* 12 - * 12|34+5 -> "Divide" -> --- + 5 - * |34 - * */ - HorizontalLayout layout = static_cast(LayoutHelper::String("1234+5", 6)); - LayoutCursor cursor(layout.childAtIndex(2), LayoutCursor::Position::Left); - cursor.addFractionLayoutAndCollapseSiblings(); - assert_expression_layout_serialize_to(layout, "(12)/(34)+5"); - quiz_assert(cursor.isEquivalentTo(LayoutCursor(layout.childAtIndex(0).childAtIndex(1), LayoutCursor::Position::Left))); -} - -QUIZ_CASE(poincare_fraction_layout_delete) { - - /* 12 - * --- -> "BackSpace" -> 12|34 - * |34 - * */ - HorizontalLayout layout1 = HorizontalLayout::Builder( - FractionLayout::Builder( - LayoutHelper::String("12", 2), - LayoutHelper::String("34", 2) - ) - ); - LayoutCursor cursor1(layout1.childAtIndex(0).childAtIndex(1), LayoutCursor::Position::Left); - cursor1.performBackspace(); - assert_expression_layout_serialize_to(layout1, "1234"); - quiz_assert(cursor1.isEquivalentTo(LayoutCursor(layout1.childAtIndex(1), LayoutCursor::Position::Right))); - - /* ΓΈ - * 1 + --- -> "BackSpace" -> 1+|3 - * |3 - * */ - HorizontalLayout layout2 = HorizontalLayout::Builder( - CodePointLayout::Builder('1'), - CodePointLayout::Builder('+'), - FractionLayout::Builder( - EmptyLayout::Builder(), - CodePointLayout::Builder('3') - ) - ); - LayoutCursor cursor2(layout2.childAtIndex(2).childAtIndex(1), LayoutCursor::Position::Left); - cursor2.performBackspace(); - assert_expression_layout_serialize_to(layout2, "1+3"); - quiz_assert(cursor2.isEquivalentTo(LayoutCursor(layout2.childAtIndex(1), LayoutCursor::Position::Right))); -} - -QUIZ_CASE(poincare_fraction_layout_serialize) { - FractionLayout layout = FractionLayout::Builder( - CodePointLayout::Builder('1'), - LayoutHelper::String("2+3", 3) - ); - assert_expression_layout_serialize_to(layout, "(1)/(2+3)"); -} diff --git a/poincare/test/function.cpp b/poincare/test/function.cpp deleted file mode 100644 index 233d77b53..000000000 --- a/poincare/test/function.cpp +++ /dev/null @@ -1,281 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "helper.h" - -using namespace Poincare; - -template -void assert_exp_is_bounded(Expression exp, T lowBound, T upBound, bool upBoundIncluded = false) { - Shared::GlobalContext globalContext; - T result = exp.approximateToScalar(&globalContext, Cartesian, Radian); - quiz_assert(result >= lowBound); - quiz_assert(result < upBound || (result == upBound && upBoundIncluded)); -} - -QUIZ_CASE(poincare_parse_function) { - assert_parsed_expression_type("abs(-1)", ExpressionNode::Type::AbsoluteValue); - assert_parsed_expression_type("binomial(10, 4)", ExpressionNode::Type::BinomialCoefficient); - assert_parsed_expression_type("ceil(0.2)", ExpressionNode::Type::Ceiling); - assert_parsed_expression_type("arg(2+𝐒)", ExpressionNode::Type::ComplexArgument); - assert_parsed_expression_type("det([[1,2,3][4,5,6][7,8,9]])", ExpressionNode::Type::Determinant); - assert_parsed_expression_type("diff(2Γ—x, x, 2)", ExpressionNode::Type::Derivative); - assert_parsed_expression_type("dim([[2]])", ExpressionNode::Type::MatrixDimension); - assert_parsed_expression_type("confidence(0.1, 100)", ExpressionNode::Type::ConfidenceInterval); - assert_parsed_expression_type("conj(2)", ExpressionNode::Type::Conjugate); - assert_parsed_expression_type("factor(23/42)", ExpressionNode::Type::Factor); - assert_parsed_expression_type("floor(2.3)", ExpressionNode::Type::Floor); - assert_parsed_expression_type("frac(2.3)", ExpressionNode::Type::FracPart); - assert_parsed_expression_type("gcd(2,3)", ExpressionNode::Type::GreatCommonDivisor); - assert_parsed_expression_type("im(2+𝐒)", ExpressionNode::Type::ImaginaryPart); - assert_parsed_expression_type("lcm(2,3)", ExpressionNode::Type::LeastCommonMultiple); - assert_parsed_expression_type("int(x, x, 2, 3)", ExpressionNode::Type::Integral); - assert_parsed_expression_type("inverse([[1,2,3][4,5,6][7,8,9]])", ExpressionNode::Type::MatrixInverse); - assert_parsed_expression_type("ln(2)", ExpressionNode::Type::NaperianLogarithm); - assert_parsed_expression_type("log(2)", ExpressionNode::Type::Logarithm); - assert_parsed_expression_type("permute(10, 4)", ExpressionNode::Type::PermuteCoefficient); - assert_parsed_expression_type("prediction(0.1, 100)", ExpressionNode::Type::ConfidenceInterval); - assert_parsed_expression_type("prediction95(0.1, 100)", ExpressionNode::Type::PredictionInterval); - assert_parsed_expression_type("product(y,y, 4, 10)", ExpressionNode::Type::Product); - assert_parsed_expression_type("quo(29, 10)", ExpressionNode::Type::DivisionQuotient); - - assert_parsed_expression_type("random()", ExpressionNode::Type::Random); - assert_parsed_expression_type("randint(1, 2)", ExpressionNode::Type::Randint); - - assert_parsed_expression_type("re(2+𝐒)", ExpressionNode::Type::RealPart); - assert_parsed_expression_type("rem(29, 10)", ExpressionNode::Type::DivisionRemainder); - assert_parsed_expression_type("root(2,3)", ExpressionNode::Type::NthRoot); - assert_parsed_expression_type("√(2)", ExpressionNode::Type::SquareRoot); - assert_parsed_expression_type("round(2,3)", ExpressionNode::Type::Round); - assert_parsed_expression_type("sign(3)", ExpressionNode::Type::SignFunction); - assert_parsed_expression_type("sum(n,n, 4, 10)", ExpressionNode::Type::Sum); - assert_parsed_expression_type("trace([[1,2,3][4,5,6][7,8,9]])", ExpressionNode::Type::MatrixTrace); - assert_parsed_expression_type("transpose([[1,2,3][4,5,6][7,8,9]])", ExpressionNode::Type::MatrixTranspose); - assert_parsed_expression_type("6!", ExpressionNode::Type::Factorial); -} - - -QUIZ_CASE(poincare_function_evaluate) { - assert_parsed_expression_evaluates_to("abs(-1)", "1"); - assert_parsed_expression_evaluates_to("abs(-1)", "1"); - - assert_parsed_expression_evaluates_to("abs(3+2𝐒)", "3.605551"); - assert_parsed_expression_evaluates_to("abs(3+2𝐒)", "3.605551275464"); - - assert_parsed_expression_evaluates_to("abs([[1,-2][3,-4]])", "[[1,2][3,4]]"); - assert_parsed_expression_evaluates_to("abs([[1,-2][3,-4]])", "[[1,2][3,4]]"); - - assert_parsed_expression_evaluates_to("abs([[3+2𝐒,3+4𝐒][5+2𝐒,3+2𝐒]])", "[[3.605551,5][5.385165,3.605551]]"); - assert_parsed_expression_evaluates_to("abs([[3+2𝐒,3+4𝐒][5+2𝐒,3+2𝐒]])", "[[3.605551275464,5][5.3851648071345,3.605551275464]]"); - - assert_parsed_expression_evaluates_to("binomial(10, 4)", "210"); - assert_parsed_expression_evaluates_to("binomial(10, 4)", "210"); - - assert_parsed_expression_evaluates_to("ceil(0.2)", "1"); - assert_parsed_expression_evaluates_to("ceil(0.2)", "1"); - - assert_parsed_expression_evaluates_to("det([[1,23,3][4,5,6][7,8,9]])", "126", System, Degree, Cartesian, 6); // FIXME: the determinant computation is not precised enough to be displayed with 7 significant digits - assert_parsed_expression_evaluates_to("det([[1,23,3][4,5,6][7,8,9]])", "126"); - - assert_parsed_expression_evaluates_to("det([[𝐒,23-2𝐒,3×𝐒][4+𝐒,5×𝐒,6][7,8×𝐒+2,9]])", "126-231×𝐒", System, Degree, Cartesian, 6); // FIXME: the determinant computation is not precised enough to be displayed with 7 significant digits - assert_parsed_expression_evaluates_to("det([[𝐒,23-2𝐒,3×𝐒][4+𝐒,5×𝐒,6][7,8×𝐒+2,9]])", "126-231×𝐒"); - - assert_parsed_expression_evaluates_to("diff(2Γ—x, x, 2)", "2"); - assert_parsed_expression_evaluates_to("diff(2Γ—x, x, 2)", "2"); - - assert_parsed_expression_evaluates_to("diff(2Γ—TO^2, TO, 7)", "28"); - assert_parsed_expression_evaluates_to("diff(2Γ—TO^2, TO, 7)", "28"); - - assert_parsed_expression_evaluates_to("floor(2.3)", "2"); - assert_parsed_expression_evaluates_to("floor(2.3)", "2"); - - assert_parsed_expression_evaluates_to("frac(2.3)", "0.3"); - assert_parsed_expression_evaluates_to("frac(2.3)", "0.3"); - - assert_parsed_expression_evaluates_to("gcd(234,394)", "2"); - assert_parsed_expression_evaluates_to("gcd(234,394)", "2"); - - assert_parsed_expression_evaluates_to("im(2+3𝐒)", "3"); - assert_parsed_expression_evaluates_to("im(2+3𝐒)", "3"); - - assert_parsed_expression_evaluates_to("lcm(234,394)", "46098"); - assert_parsed_expression_evaluates_to("lcm(234,394)", "46098"); - - assert_parsed_expression_evaluates_to("int(x,x, 1, 2)", "1.5"); - assert_parsed_expression_evaluates_to("int(x,x, 1, 2)", "1.5"); - - assert_parsed_expression_evaluates_to("ln(2)", "0.6931472"); - assert_parsed_expression_evaluates_to("ln(2)", "6.9314718055995ᴇ-1"); - - assert_parsed_expression_evaluates_to("log(2)", "0.30103"); - assert_parsed_expression_evaluates_to("log(2)", "3.0102999566398ᴇ-1"); - - assert_parsed_expression_evaluates_to("permute(10, 4)", "5040"); - assert_parsed_expression_evaluates_to("permute(10, 4)", "5040"); - - assert_parsed_expression_evaluates_to("product(n,n, 4, 10)", "604800"); - assert_parsed_expression_evaluates_to("product(n,n, 4, 10)", "604800"); - - assert_parsed_expression_evaluates_to("quo(29, 10)", "2"); - assert_parsed_expression_evaluates_to("quo(29, 10)", "2"); - - assert_parsed_expression_evaluates_to("re(2+𝐒)", "2"); - assert_parsed_expression_evaluates_to("re(2+𝐒)", "2"); - - assert_parsed_expression_evaluates_to("rem(29, 10)", "9"); - assert_parsed_expression_evaluates_to("rem(29, 10)", "9"); - assert_parsed_expression_evaluates_to("root(2,3)", "1.259921"); - assert_parsed_expression_evaluates_to("root(2,3)", "1.2599210498949"); - - assert_parsed_expression_evaluates_to("√(2)", "1.414214"); - assert_parsed_expression_evaluates_to("√(2)", "1.4142135623731"); - - assert_parsed_expression_evaluates_to("√(-1)", "𝐒"); - assert_parsed_expression_evaluates_to("√(-1)", "𝐒"); - - assert_parsed_expression_evaluates_to("sum(r,r, 4, 10)", "49"); - assert_parsed_expression_evaluates_to("sum(k,k, 4, 10)", "49"); - - assert_parsed_expression_evaluates_to("trace([[1,2,3][4,5,6][7,8,9]])", "15"); - assert_parsed_expression_evaluates_to("trace([[1,2,3][4,5,6][7,8,9]])", "15"); - - assert_parsed_expression_evaluates_to("confidence(0.1, 100)", "[[0,0.2]]"); - assert_parsed_expression_evaluates_to("confidence(0.1, 100)", "[[0,0.2]]"); - - assert_parsed_expression_evaluates_to("dim([[1,2,3][4,5,-6]])", "[[2,3]]"); - assert_parsed_expression_evaluates_to("dim([[1,2,3][4,5,-6]])", "[[2,3]]"); - - assert_parsed_expression_evaluates_to("conj(3+2×𝐒)", "3-2×𝐒"); - assert_parsed_expression_evaluates_to("conj(3+2×𝐒)", "3-2×𝐒"); - - assert_parsed_expression_evaluates_to("factor(-23/4)", "-5.75"); - assert_parsed_expression_evaluates_to("factor(-123/24)", "-5.125"); - - assert_parsed_expression_evaluates_to("inverse([[1,2,3][4,5,-6][7,8,9]])", "[[-1.2917,-0.083333,0.375][1.0833,0.16667,-0.25][0.041667,-0.083333,0.041667]]", System, Degree, Cartesian, 5); // inverse is not precise enough to display 7 significative digits - assert_parsed_expression_evaluates_to("inverse([[1,2,3][4,5,-6][7,8,9]])", "[[-1.2916666666667,-8.3333333333333ᴇ-2,0.375][1.0833333333333,1.6666666666667ᴇ-1,-0.25][4.1666666666667ᴇ-2,-8.3333333333333ᴇ-2,4.1666666666667ᴇ-2]]"); - assert_parsed_expression_evaluates_to("inverse([[𝐒,23-2𝐒,3×𝐒][4+𝐒,5×𝐒,6][7,8×𝐒+2,9]])", "[[-0.0118-0.0455×𝐒,-0.5-0.727×𝐒,0.318+0.489×𝐒][0.0409+0.00364×𝐒,0.04-0.0218×𝐒,-0.0255+0.00091×𝐒][0.00334-0.00182×𝐒,0.361+0.535×𝐒,-0.13-0.358×𝐒]]", System, Degree, Cartesian, 3); // inverse is not precise enough to display 7 significative digits - assert_parsed_expression_evaluates_to("inverse([[𝐒,23-2𝐒,3×𝐒][4+𝐒,5×𝐒,6][7,8×𝐒+2,9]])", "[[-0.0118289353958-0.0454959053685×𝐒,-0.500454959054-0.727024567789×𝐒,0.31847133758+0.488626023658×𝐒][0.0409463148317+3.63967242948ᴇ-3×𝐒,0.0400363967243-0.0218380345769×𝐒,-0.0254777070064+9.0991810737ᴇ-4×𝐒][3.33636639369ᴇ-3-1.81983621474ᴇ-3×𝐒,0.36093418259+0.534728541098×𝐒,-0.130118289354-0.357597816197×𝐒]]", System, Degree, Cartesian, 12); // FIXME: inverse is not precise enough to display 14 significative digits - - assert_parsed_expression_evaluates_to("prediction(0.1, 100)", "[[0,0.2]]"); - assert_parsed_expression_evaluates_to("prediction(0.1, 100)", "[[0,0.2]]"); - - assert_parsed_expression_evaluates_to("prediction95(0.1, 100)", "[[0.0412,0.1588]]"); - assert_parsed_expression_evaluates_to("prediction95(0.1, 100)", "[[0.0412,0.1588]]"); - - assert_parsed_expression_evaluates_to("product(2+k×𝐒,k, 1, 5)", "-100-540×𝐒"); - assert_parsed_expression_evaluates_to("product(2+o×𝐒,o, 1, 5)", "-100-540×𝐒"); - - assert_parsed_expression_evaluates_to("root(3+𝐒, 3)", "1.459366+0.1571201×𝐒"); - assert_parsed_expression_evaluates_to("root(3+𝐒, 3)", "1.4593656008684+1.5712012294394ᴇ-1×𝐒"); - - assert_parsed_expression_evaluates_to("root(3, 3+𝐒)", "1.382007-0.1524428×𝐒"); - assert_parsed_expression_evaluates_to("root(3, 3+𝐒)", "1.3820069623326-0.1524427794159×𝐒"); - - assert_parsed_expression_evaluates_to("root(5^((-𝐒)3^9),𝐒)", "3.504", System, Degree, Cartesian, 4); - assert_parsed_expression_evaluates_to("root(5^((-𝐒)3^9),𝐒)", "3.5039410843", System, Degree, Cartesian, 11); - - assert_parsed_expression_evaluates_to("√(3+𝐒)", "1.755317+0.2848488×𝐒"); - assert_parsed_expression_evaluates_to("√(3+𝐒)", "1.7553173018244+2.8484878459314ᴇ-1×𝐒"); - - assert_parsed_expression_evaluates_to("sign(-23+1)", "-1"); - assert_parsed_expression_evaluates_to("sign(inf)", "1"); - assert_parsed_expression_evaluates_to("sign(-inf)", "-1"); - assert_parsed_expression_evaluates_to("sign(0)", "0"); - assert_parsed_expression_evaluates_to("sign(-0)", "0"); - assert_parsed_expression_evaluates_to("sign(x)", "undef"); - assert_parsed_expression_evaluates_to("sign(2+𝐒)", "undef"); - assert_parsed_expression_evaluates_to("sign(undef)", "undef"); - - assert_parsed_expression_evaluates_to("sum(2+n×𝐒,n,1,5)", "10+15×𝐒"); - assert_parsed_expression_evaluates_to("sum(2+n×𝐒,n,1,5)", "10+15×𝐒"); - - assert_parsed_expression_evaluates_to("transpose([[1,2,3][4,5,-6][7,8,9]])", "[[1,4,7][2,5,8][3,-6,9]]"); - assert_parsed_expression_evaluates_to("transpose([[1,7,5][4,2,8]])", "[[1,4][7,2][5,8]]"); - assert_parsed_expression_evaluates_to("transpose([[1,2][4,5][7,8]])", "[[1,4,7][2,5,8]]"); - assert_parsed_expression_evaluates_to("transpose([[1,2,3][4,5,-6][7,8,9]])", "[[1,4,7][2,5,8][3,-6,9]]"); - assert_parsed_expression_evaluates_to("transpose([[1,7,5][4,2,8]])", "[[1,4][7,2][5,8]]"); - assert_parsed_expression_evaluates_to("transpose([[1,2][4,5][7,8]])", "[[1,4,7][2,5,8]]"); - - assert_parsed_expression_evaluates_to("round(2.3246,3)", "2.325"); - assert_parsed_expression_evaluates_to("round(2.3245,3)", "2.325"); - - assert_parsed_expression_evaluates_to("6!", "720"); - assert_parsed_expression_evaluates_to("6!", "720"); - - assert_parsed_expression_evaluates_to("√(-1)", "𝐒"); - assert_parsed_expression_evaluates_to("√(-1)", "𝐒"); - - assert_parsed_expression_evaluates_to("root(-1,3)", "0.5+0.8660254×𝐒"); - assert_parsed_expression_evaluates_to("root(-1,3)", "0.5+8.6602540378444ᴇ-1×𝐒"); - - assert_parsed_expression_evaluates_to("int(int(xΓ—x,x,0,x),x,0,4)", "21.33333"); - assert_parsed_expression_evaluates_to("int(int(xΓ—x,x,0,x),x,0,4)", "21.333333333333"); - - assert_parsed_expression_evaluates_to("int(1+cos(e),e, 0, 180)", "180"); - assert_parsed_expression_evaluates_to("int(1+cos(e),e, 0, 180)", "180"); - - Expression exp = parse_expression("random()"); - assert_exp_is_bounded(exp, 0.0f, 1.0f); - assert_exp_is_bounded(exp, 0.0, 1.0); - - exp = parse_expression("randint(4,45)"); - assert_exp_is_bounded(exp, 4.0f, 45.0f, true); - assert_exp_is_bounded(exp, 4.0, 45.0, true); -} - -QUIZ_CASE(poincare_function_simplify) { - assert_parsed_expression_simplify_to("abs(Ο€)", "Ο€"); - assert_parsed_expression_simplify_to("abs(-Ο€)", "Ο€"); - assert_parsed_expression_simplify_to("abs(1+𝐒)", "√(2)"); - assert_parsed_expression_simplify_to("abs(0)", "0"); - assert_parsed_expression_simplify_to("arg(1+𝐒)", "Ο€/4"); - assert_parsed_expression_simplify_to("binomial(20,3)", "1140"); - assert_parsed_expression_simplify_to("binomial(20,10)", "184756"); - assert_parsed_expression_simplify_to("ceil(-1.3)", "-1"); - assert_parsed_expression_simplify_to("conj(1/2)", "1/2"); - assert_parsed_expression_simplify_to("quo(19,3)", "6"); - assert_parsed_expression_simplify_to("quo(19,0)", Infinity::Name()); - assert_parsed_expression_simplify_to("quo(-19,3)", "-7"); - assert_parsed_expression_simplify_to("rem(19,3)", "1"); - assert_parsed_expression_simplify_to("rem(-19,3)", "2"); - assert_parsed_expression_simplify_to("rem(19,0)", Infinity::Name()); - assert_parsed_expression_simplify_to("99!", "933262154439441526816992388562667004907159682643816214685929638952175999932299156089414639761565182862536979208272237582511852109168640000000000000000000000"); - assert_parsed_expression_simplify_to("factor(-10008/6895)", "-(2^3Γ—3^2Γ—139)/(5Γ—7Γ—197)"); - assert_parsed_expression_simplify_to("factor(1008/6895)", "(2^4Γ—3^2)/(5Γ—197)"); - assert_parsed_expression_simplify_to("factor(10007)", "10007"); - assert_parsed_expression_simplify_to("factor(10007^2)", Undefined::Name()); - assert_parsed_expression_simplify_to("floor(-1.3)", "-2"); - assert_parsed_expression_simplify_to("frac(-1.3)", "7/10"); - assert_parsed_expression_simplify_to("gcd(123,278)", "1"); - assert_parsed_expression_simplify_to("gcd(11,121)", "11"); - assert_parsed_expression_simplify_to("im(1+5×𝐒)", "5"); - assert_parsed_expression_simplify_to("lcm(123,278)", "34194"); - assert_parsed_expression_simplify_to("lcm(11,121)", "121"); - assert_parsed_expression_simplify_to("√(4)", "2"); - assert_parsed_expression_simplify_to("re(1+5×𝐒)", "1"); - assert_parsed_expression_simplify_to("root(4,3)", "root(4,3)"); - assert_parsed_expression_simplify_to("root(4,Ο€)", "4^(1/Ο€)"); - assert_parsed_expression_simplify_to("root(27,3)", "3"); - assert_parsed_expression_simplify_to("round(4.235,2)", "106/25"); - assert_parsed_expression_simplify_to("round(4.23,0)", "4"); - assert_parsed_expression_simplify_to("round(4.9,0)", "5"); - assert_parsed_expression_simplify_to("round(12.9,-1)", "10"); - assert_parsed_expression_simplify_to("round(12.9,-2)", "0"); - assert_parsed_expression_simplify_to("sign(-23)", "-1"); - assert_parsed_expression_simplify_to("sign(-𝐒)", "sign(-𝐒)"); - assert_parsed_expression_simplify_to("sign(0)", "0"); - assert_parsed_expression_simplify_to("sign(inf)", "1"); - assert_parsed_expression_simplify_to("sign(-inf)", "-1"); - assert_parsed_expression_simplify_to("sign(undef)", "undef"); - assert_parsed_expression_simplify_to("sign(23)", "1"); - assert_parsed_expression_simplify_to("sign(log(18))", "1"); - assert_parsed_expression_simplify_to("sign(-√(2))", "-1"); - assert_parsed_expression_simplify_to("sign(x)", "sign(x)"); - assert_parsed_expression_simplify_to("sign(2+𝐒)", "sign(2+𝐒)"); - assert_parsed_expression_simplify_to("permute(99,4)", "90345024"); - assert_parsed_expression_simplify_to("permute(20,-10)", Undefined::Name()); - assert_parsed_expression_simplify_to("re(1/2)", "1/2"); -} diff --git a/poincare/test/function_solver.cpp b/poincare/test/function_solver.cpp new file mode 100644 index 000000000..f19c79de4 --- /dev/null +++ b/poincare/test/function_solver.cpp @@ -0,0 +1 @@ +// TODO: add tests about extremum and root findings on expression diff --git a/poincare/test/helper.cpp b/poincare/test/helper.cpp index 620e9c9cd..7c19733ab 100644 --- a/poincare/test/helper.cpp +++ b/poincare/test/helper.cpp @@ -1,15 +1,7 @@ -#include -#include -#include -#include -#include -#include #include "helper.h" -#if POINCARE_TESTS_PRINT_EXPRESSIONS -#include "../src/expression_debug.h" -#include -using namespace std; -#endif +#include +#include +#include using namespace Poincare; @@ -28,156 +20,41 @@ const char * BigOverflowedIntegerString() { return s; } -bool expressions_are_equal(Poincare::Expression expected, Poincare::Expression got) { - bool identical = expected.isIdenticalTo(got); -#if POINCARE_TREE_LOG - if (!identical) { - std::cout << "Expecting" << std::endl; - expected.log(); - std::cout << "Got" << std::endl; - got.log(); +void quiz_assert_print_if_failure(bool test, const char * information) { + if (!test) { + quiz_print("TEST FAILURE WHILE TESTING:"); + quiz_print(information); } -#endif - return identical; -} - -bool isLeftParenthesisCodePoint(CodePoint c) { - return (c == UCodePointLeftSystemParenthesis) || (c == '('); -} - -bool isRightParenthesisCodePoint(CodePoint c) { - return (c == UCodePointRightSystemParenthesis) || (c == ')'); -} - -int strcmpWithSystemParentheses(const char * s1, const char * s2) { - quiz_assert(UTF8Decoder::CharSizeOfCodePoint(UCodePointLeftSystemParenthesis) == 1); - quiz_assert(UTF8Decoder::CharSizeOfCodePoint(UCodePointRightSystemParenthesis) == 1); - while(*s1 != 0 - && ((*s1 == *s2) - || (isLeftParenthesisCodePoint(*s1) && isLeftParenthesisCodePoint(*s2)) - || (isRightParenthesisCodePoint(*s1) && isRightParenthesisCodePoint(*s2)))) - { - s1++; - s2++; - } - return (*(unsigned char *)s1) - (*(unsigned char *)s2); -} - -Expression parse_expression(const char * expression, bool canBeUnparsable) { - quiz_print(expression); - Expression result = Expression::Parse(expression); - if (!canBeUnparsable) { - quiz_assert(!result.isUninitialized()); - } - return result; -} - -void assert_expression_not_parsable(const char * expression) { - Expression e = parse_expression(expression, true); - quiz_assert(e.isUninitialized()); -} - -void assert_parsed_expression_type(const char * expression, Poincare::ExpressionNode::Type type) { - Expression e = parse_expression(expression); - quiz_assert(e.type() == type); -} - -void assert_parsed_expression_is(const char * expression, Poincare::Expression r) { - Expression e = parse_expression(expression); - quiz_assert(expressions_are_equal(r, e)); -} - -void assert_parsed_expression_polynomial_degree(const char * expression, int degree, const char * symbolName, Preferences::ComplexFormat complexFormat) { - Shared::GlobalContext globalContext; - Expression e = parse_expression(expression); - Expression result = e.clone().reduce(&globalContext, complexFormat, Radian); - if (result.isUninitialized()) { - result = e; - } - quiz_assert(result.polynomialDegree(&globalContext, symbolName) == degree); -} - - -Expression parse_and_simplify(const char * expression) { - Shared::GlobalContext globalContext; - Expression e = parse_expression(expression); - quiz_assert(!e.isUninitialized()); - return e.simplify(&globalContext, Cartesian, Radian); -} - -void assert_simplify(const char * expression) { - quiz_assert(!(parse_and_simplify(expression).isUninitialized())); + quiz_assert(test); } typedef Expression (*ProcessExpression)(Expression, Context * context, ExpressionNode::ReductionTarget target, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit); -void assert_parsed_expression_process_to(const char * expression, const char * result, ExpressionNode::ReductionTarget target, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ProcessExpression process, int numberOfSignifiantDigits = PrintFloat::k_numberOfStoredSignificantDigits) { +void assert_parsed_expression_process_to(const char * expression, const char * result, ExpressionNode::ReductionTarget target, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit, ProcessExpression process, int numberOfSignifiantDigits) { Shared::GlobalContext globalContext; - Expression e = parse_expression(expression); - -#if POINCARE_TESTS_PRINT_EXPRESSIONS - cout << " Entry expression: " << expression << "----" << endl; - print_expression(e, 0); -#endif + Expression e = parse_expression(expression, false); Expression m = process(e, &globalContext, target, complexFormat, angleUnit); constexpr int bufferSize = 500; char buffer[bufferSize]; m.serialize(buffer, bufferSize, DecimalMode, numberOfSignifiantDigits); -#if POINCARE_TESTS_PRINT_EXPRESSIONS - cout << "---- serialize to: " << buffer << " ----" << endl; - cout << "----- compared to: " << result << " ----\n" << endl; -#endif - quiz_assert(strcmpWithSystemParentheses(buffer, result) == 0); + quiz_assert_print_if_failure(strcmp(buffer, result) == 0, result); } -template -void assert_parsed_expression_evaluates_to(const char * expression, const char * approximation, ExpressionNode::ReductionTarget target, Preferences::AngleUnit angleUnit, Preferences::ComplexFormat complexFormat, int numberOfSignificantDigits) { -#if POINCARE_TESTS_PRINT_EXPRESSIONS - cout << "--------- Approximation ---------" << endl; -#endif - int numberOfDigits = sizeof(T) == sizeof(double) ? PrintFloat::k_numberOfStoredSignificantDigits : PrintFloat::k_numberOfPrintedSignificantDigits; - numberOfDigits = numberOfSignificantDigits > 0 ? numberOfSignificantDigits : numberOfDigits; - - assert_parsed_expression_process_to(expression, approximation, target, complexFormat, angleUnit, [](Expression e, Context * context, ExpressionNode::ReductionTarget target, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { - Expression simplified = e.clone(); - Expression result; - if (target == ExpressionNode::ReductionTarget::User) { - // When the reduction target is the User, we always approximate in double - assert(sizeof(T) == sizeof(double)); - simplified.simplifyAndApproximate(&simplified, &result, context, complexFormat, angleUnit); - } else { - simplified = simplified.simplify(context, complexFormat, angleUnit); - result = simplified.approximate(context, complexFormat, angleUnit); - } - // Simplification was interrupted - if (simplified.isUninitialized()) { - return e.approximate(context, complexFormat, angleUnit); - } - return result; - }, numberOfDigits); +Poincare::Expression parse_expression(const char * expression, bool addParentheses) { + Expression result = Expression::Parse(expression, addParentheses); + quiz_assert(!result.isUninitialized()); + return result; } -template -void assert_parsed_expression_evaluates_without_simplifying_to(const char * expression, const char * approximation, Preferences::AngleUnit angleUnit, Preferences::ComplexFormat complexFormat, int numberOfSignificantDigits) { - int numberOfDigits = sizeof(T) == sizeof(double) ? PrintFloat::k_numberOfStoredSignificantDigits : PrintFloat::k_numberOfPrintedSignificantDigits; - numberOfDigits = numberOfSignificantDigits > 0 ? numberOfSignificantDigits : numberOfDigits; - assert_parsed_expression_process_to(expression, approximation, ExpressionNode::ReductionTarget::System, complexFormat, angleUnit, [](Expression e, Context * context, ExpressionNode::ReductionTarget target, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { - return e.approximate(context, complexFormat, angleUnit); - }, numberOfDigits); -} - - -template -void assert_parsed_expression_approximates_with_value_for_symbol(Expression expression, const char * symbol, T value, T approximation, Poincare::Preferences::ComplexFormat complexFormat, Poincare::Preferences::AngleUnit angleUnit) { +void assert_simplify(const char * expression, Preferences::AngleUnit angleUnit, Preferences::ComplexFormat complexFormat) { Shared::GlobalContext globalContext; - T result = expression.approximateWithValueForSymbol(symbol, value, &globalContext, complexFormat, angleUnit); - quiz_assert((std::isnan(result) && std::isnan(approximation)) || std::fabs(result - approximation) < 10.0*Expression::Epsilon()); + Expression e = parse_expression(expression, false); + quiz_assert_print_if_failure(!e.isUninitialized(), expression); + e = e.simplify(&globalContext, complexFormat, angleUnit); + quiz_assert_print_if_failure(!(e.isUninitialized()), expression); } void assert_parsed_expression_simplify_to(const char * expression, const char * simplifiedExpression, ExpressionNode::ReductionTarget target, Preferences::AngleUnit angleUnit, Preferences::ComplexFormat complexFormat) { -#if POINCARE_TESTS_PRINT_EXPRESSIONS - cout << "--------- Simplification ---------" << endl; -#endif assert_parsed_expression_process_to(expression, simplifiedExpression, target, complexFormat, angleUnit, [](Expression e, Context * context, ExpressionNode::ReductionTarget target, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { Expression copy = e.clone(); if (target == ExpressionNode::ReductionTarget::User) { @@ -192,28 +69,20 @@ void assert_parsed_expression_simplify_to(const char * expression, const char * }); } -void assert_parsed_expression_serialize_to(Expression expression, const char * serializedExpression, Preferences::PrintFloatMode mode, int numberOfSignifiantDigits) { -#if POINCARE_TESTS_PRINT_EXPRESSIONS - cout << "--------- Serialization ---------" << endl; -#endif - char buffer[500]; - expression.serialize(buffer, sizeof(buffer), mode, numberOfSignifiantDigits); - quiz_assert(strcmp(buffer, serializedExpression) == 0); +template +void assert_expression_approximates_to(const char * expression, const char * approximation, Preferences::AngleUnit angleUnit, Preferences::ComplexFormat complexFormat, int numberOfSignificantDigits) { + int numberOfDigits = sizeof(T) == sizeof(double) ? PrintFloat::k_numberOfStoredSignificantDigits : PrintFloat::k_numberOfPrintedSignificantDigits; + numberOfDigits = numberOfSignificantDigits > 0 ? numberOfSignificantDigits : numberOfDigits; + assert_parsed_expression_process_to(expression, approximation, ExpressionNode::ReductionTarget::System, complexFormat, angleUnit, [](Expression e, Context * context, ExpressionNode::ReductionTarget target, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) { + return e.approximate(context, complexFormat, angleUnit); + }, numberOfDigits); } -void assert_parsed_expression_layout_serialize_to_self(const char * expressionLayout) { - Expression e = parse_expression(expressionLayout); -#if POINCARE_TESTS_PRINT_EXPRESSIONS - cout << "---- Serialize: " << expressionLayout << "----" << endl; -#endif - Layout el = e.createLayout(DecimalMode, PrintFloat::k_numberOfStoredSignificantDigits); +void assert_layout_serialize_to(Poincare::Layout layout, const char * serialization) { constexpr int bufferSize = 255; char buffer[bufferSize]; - el.serializeForParsing(buffer, bufferSize); -#if POINCARE_TESTS_PRINT_EXPRESSIONS - cout << "---- serialized to: " << buffer << " ----\n" << endl; -#endif - quiz_assert(strcmpWithSystemParentheses(expressionLayout, buffer) == 0); + layout.serializeForParsing(buffer, bufferSize); + quiz_assert_print_if_failure(strcmp(serialization, buffer) == 0, serialization); } void assert_expression_layouts_as(Poincare::Expression expression, Poincare::Layout layout) { @@ -221,21 +90,5 @@ void assert_expression_layouts_as(Poincare::Expression expression, Poincare::Lay quiz_assert(l.isIdenticalTo(layout)); } -void assert_expression_layout_serialize_to(Poincare::Layout layout, const char * serialization) { - constexpr int bufferSize = 255; - char buffer[bufferSize]; - layout.serializeForParsing(buffer, bufferSize); -#if POINCARE_TESTS_PRINT_EXPRESSIONS - cout << "---- Serialize: " << serialization << "----" << endl; - cout << "---- serialized to: " << buffer << " ----" << endl; - cout << "----- compared to: " << serialization << " ----\n" << endl; -#endif - quiz_assert(strcmpWithSystemParentheses(serialization, buffer) == 0); -} - -template void assert_parsed_expression_evaluates_to(char const*, char const *, Poincare::ExpressionNode::ReductionTarget, Poincare::Preferences::AngleUnit, Poincare::Preferences::ComplexFormat, int); -template void assert_parsed_expression_evaluates_to(char const*, char const *, Poincare::ExpressionNode::ReductionTarget, Poincare::Preferences::AngleUnit, Poincare::Preferences::ComplexFormat, int); -template void assert_parsed_expression_evaluates_without_simplifying_to(char const*, char const *, Poincare::Preferences::AngleUnit, Poincare::Preferences::ComplexFormat, int); -template void assert_parsed_expression_evaluates_without_simplifying_to(char const*, char const *, Poincare::Preferences::AngleUnit, Poincare::Preferences::ComplexFormat, int); -template void assert_parsed_expression_approximates_with_value_for_symbol(Poincare::Expression, const char *, float, float, Poincare::Preferences::ComplexFormat, Poincare::Preferences::AngleUnit); -template void assert_parsed_expression_approximates_with_value_for_symbol(Poincare::Expression, const char *, double, double, Poincare::Preferences::ComplexFormat, Poincare::Preferences::AngleUnit); +template void assert_expression_approximates_to(char const*, char const *, Poincare::Preferences::AngleUnit, Poincare::Preferences::ComplexFormat, int); +template void assert_expression_approximates_to(char const*, char const *, Poincare::Preferences::AngleUnit, Poincare::Preferences::ComplexFormat, int); diff --git a/poincare/test/helper.h b/poincare/test/helper.h index 91d728ce0..165e73e3e 100644 --- a/poincare/test/helper.h +++ b/poincare/test/helper.h @@ -1,8 +1,5 @@ #include #include -#include "poincare/src/parsing/parser.h" - -// Expressions const char * MaxIntegerString(); // (2^32)^k_maxNumberOfDigits-1 const char * OverflowedIntegerString(); // (2^32)^k_maxNumberOfDigits @@ -18,32 +15,32 @@ constexpr Poincare::Preferences::ComplexFormat Real = Poincare::Preferences::Com constexpr Poincare::Preferences::PrintFloatMode DecimalMode = Poincare::Preferences::PrintFloatMode::Decimal; constexpr Poincare::Preferences::PrintFloatMode ScientificMode = Poincare::Preferences::PrintFloatMode::Scientific; -int strcmpWithSystemParentheses(const char * s1, const char * s2); +void quiz_assert_print_if_failure(bool test, const char * information); -bool expressions_are_equal(Poincare::Expression expected, Poincare::Expression got); -Poincare::Expression parse_expression(const char * expression, bool canBeUnparsable = false); -Poincare::Expression parse_and_simplify(const char * expression); +typedef Poincare::Expression (*ProcessExpression)(Poincare::Expression, Poincare::Context * context, Poincare::ExpressionNode::ReductionTarget target, Poincare::Preferences::ComplexFormat complexFormat, Poincare::Preferences::AngleUnit angleUnit); -void assert_expression_not_parsable(const char * expression); -void assert_parsed_expression_type(const char * expression, Poincare::ExpressionNode::Type type); -void assert_parsed_expression_is(const char * expression, Poincare::Expression r); -void assert_parsed_expression_polynomial_degree(const char * expression, int degree, const char * symbolName = "x", Poincare::Preferences::ComplexFormat complexFormat = Cartesian); -void assert_simplify(const char * expression); +void assert_parsed_expression_process_to(const char * expression, const char * result, Poincare::ExpressionNode::ReductionTarget target, Poincare::Preferences::ComplexFormat complexFormat, Poincare::Preferences::AngleUnit angleUnit, ProcessExpression process, int numberOfSignifiantDigits = Poincare::PrintFloat::k_numberOfStoredSignificantDigits); + +// Parsing + +Poincare::Expression parse_expression(const char * expression, bool addParentheses); + +// Simplification + +void assert_simplify(const char * expression, Poincare::Preferences::AngleUnit angleUnit = Radian, Poincare::Preferences::ComplexFormat complexFormat = Cartesian); + +void assert_parsed_expression_simplify_to(const char * expression, const char * simplifiedExpression, Poincare::ExpressionNode::ReductionTarget target = User, Poincare::Preferences::AngleUnit angleUnit = Radian, Poincare::Preferences::ComplexFormat complexFormat = Cartesian); + +// Approximation template -void assert_parsed_expression_evaluates_to(const char * expression, const char * approximation, Poincare::ExpressionNode::ReductionTarget target = System, Poincare::Preferences::AngleUnit angleUnit = Degree, Poincare::Preferences::ComplexFormat complexFormat = Cartesian, int numberOfSignificantDigits = -1); +void assert_expression_approximates_to(const char * expression, const char * approximation, Poincare::Preferences::AngleUnit angleUnit = Degree, Poincare::Preferences::ComplexFormat complexFormat = Cartesian, int numberOfSignificantDigits = -1); -template -void assert_parsed_expression_evaluates_without_simplifying_to(const char * expression, const char * approximation, Poincare::Preferences::AngleUnit angleUnit = Degree, Poincare::Preferences::ComplexFormat complexFormat = Cartesian, int numberOfSignificantDigits = -1); -template -void assert_parsed_expression_approximates_with_value_for_symbol(Poincare::Expression expression, const char * symbol, T value, T approximation, Poincare::Preferences::ComplexFormat complexFormat = Cartesian, Poincare::Preferences::AngleUnit angleUnit = Degree); +// Layout serializing + +void assert_layout_serialize_to(Poincare::Layout layout, const char * serialization); + +// Expression layouting -void assert_parsed_expression_simplify_to(const char * expression, const char * simplifiedExpression, Poincare::ExpressionNode::ReductionTarget target = Poincare::ExpressionNode::ReductionTarget::User, Poincare::Preferences::AngleUnit angleUnit = Poincare::Preferences::AngleUnit::Radian, Poincare::Preferences::ComplexFormat complexFormat = Poincare::Preferences::ComplexFormat::Cartesian); -void assert_parsed_expression_serialize_to(Poincare::Expression expression, const char * serializedExpression, Poincare::Preferences::PrintFloatMode mode = DecimalMode, int numberOfSignifiantDigits = 7); void assert_expression_layouts_as(Poincare::Expression expression, Poincare::Layout layout); - - -// Layouts -void assert_parsed_expression_layout_serialize_to_self(const char * expressionLayout); -void assert_expression_layout_serialize_to(Poincare::Layout layout, const char * serialization); diff --git a/poincare/test/infinity.cpp b/poincare/test/infinity.cpp deleted file mode 100644 index 91f21dc29..000000000 --- a/poincare/test/infinity.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include -#include -#include "helper.h" - -using namespace Poincare; - -QUIZ_CASE(poincare_infinity) { - - // 0 and infinity - assert_parsed_expression_simplify_to("0/0", Undefined::Name()); - assert_parsed_expression_simplify_to("0/inf", "0"); - assert_parsed_expression_simplify_to("inf/0", Undefined::Name()); - assert_parsed_expression_simplify_to("0Γ—inf", Undefined::Name()); - assert_parsed_expression_simplify_to("3Γ—inf/inf", "undef"); - assert_parsed_expression_simplify_to("1ᴇ1000", "inf"); - assert_parsed_expression_simplify_to("-1ᴇ1000", "-inf"); - assert_parsed_expression_simplify_to("-1ᴇ-1000", "0"); - assert_parsed_expression_simplify_to("1ᴇ-1000", "0"); - assert_parsed_expression_evaluates_to("1Γ—10^1000", "inf"); - - assert_parsed_expression_simplify_to("inf^0", "undef"); - assert_parsed_expression_simplify_to("1^inf", "1^inf"); - assert_parsed_expression_simplify_to("1^(X^inf)", "1^(X^inf)"); - assert_parsed_expression_simplify_to("inf^(-1)", "0"); - assert_parsed_expression_simplify_to("(-inf)^(-1)", "0"); - assert_parsed_expression_simplify_to("inf^(-√(2))", "0"); - assert_parsed_expression_simplify_to("(-inf)^(-√(2))", "0"); - assert_parsed_expression_simplify_to("inf^2", "inf"); - assert_parsed_expression_simplify_to("(-inf)^2", "inf"); - assert_parsed_expression_simplify_to("inf^√(2)", "inf"); - assert_parsed_expression_simplify_to("(-inf)^√(2)", "infΓ—(-1)^√(2)"); - assert_parsed_expression_simplify_to("inf^x", "inf^x"); - assert_parsed_expression_simplify_to("1/inf+24", "24"); - assert_parsed_expression_simplify_to("β„―^(inf)/inf", "0Γ—β„―^inf"); - - // Logarithm - assert_parsed_expression_simplify_to("log(inf,0)", "undef"); - assert_parsed_expression_simplify_to("log(inf,1)", "undef"); - assert_parsed_expression_simplify_to("log(0,inf)", "undef"); - assert_parsed_expression_simplify_to("log(1,inf)", "0"); - assert_parsed_expression_simplify_to("log(inf,inf)", "undef"); - - assert_parsed_expression_simplify_to("ln(inf)", "inf"); - assert_parsed_expression_simplify_to("log(inf,-3)", "log(inf,-3)"); - assert_parsed_expression_simplify_to("log(inf,3)", "inf"); - assert_parsed_expression_simplify_to("log(inf,0.3)", "-inf"); - assert_parsed_expression_simplify_to("log(inf,x)", "log(inf,x)"); - assert_parsed_expression_simplify_to("ln(inf)*0", "undef"); - -} diff --git a/poincare/test/layout.cpp b/poincare/test/layout.cpp new file mode 100644 index 000000000..1b7837604 --- /dev/null +++ b/poincare/test/layout.cpp @@ -0,0 +1,108 @@ +#include +#include +#include +#include +#include +#include "helper.h" +#include "./tree/helpers.h" + +using namespace Poincare; + +QUIZ_CASE(poincare_layout_constructors) { + EmptyLayout e0 = EmptyLayout::Builder(); + AbsoluteValueLayout e1 = AbsoluteValueLayout::Builder(e0); + CodePointLayout e2 = CodePointLayout::Builder('a'); + BinomialCoefficientLayout e3 = BinomialCoefficientLayout::Builder(e1, e2); + CeilingLayout e4 = CeilingLayout::Builder(e3); + RightParenthesisLayout e5 = RightParenthesisLayout::Builder(); + RightSquareBracketLayout e6 = RightSquareBracketLayout::Builder(); + CondensedSumLayout e7 = CondensedSumLayout::Builder(e4, e5, e6); + ConjugateLayout e8 = ConjugateLayout::Builder(e7); + LeftParenthesisLayout e10 = LeftParenthesisLayout::Builder(); + FloorLayout e11 = FloorLayout::Builder(e10); + FractionLayout e12 = FractionLayout::Builder(e8, e11); + HorizontalLayout e13 = HorizontalLayout::Builder(); + LeftSquareBracketLayout e14 = LeftSquareBracketLayout::Builder(); + IntegralLayout e15 = IntegralLayout::Builder(e11, e12, e13, e14); + NthRootLayout e16 = NthRootLayout::Builder(e15); + MatrixLayout e17 = MatrixLayout::Builder(); + EmptyLayout e18 = EmptyLayout::Builder(); + EmptyLayout e19 = EmptyLayout::Builder(); + EmptyLayout e20 = EmptyLayout::Builder(); + ProductLayout e21 = ProductLayout::Builder(e17, e18, e19, e20); + EmptyLayout e22 = EmptyLayout::Builder(); + EmptyLayout e23 = EmptyLayout::Builder(); + EmptyLayout e24 = EmptyLayout::Builder(); + SumLayout e25 = SumLayout::Builder(e21, e22, e23, e24); + VerticalOffsetLayout e26 = VerticalOffsetLayout::Builder(e25, VerticalOffsetLayoutNode::Position::Superscript); +} + +QUIZ_CASE(poincare_layout_comparison) { + Layout e0 = CodePointLayout::Builder('a'); + Layout e1 = CodePointLayout::Builder('a'); + Layout e2 = CodePointLayout::Builder('b'); + quiz_assert(e0.isIdenticalTo(e1)); + quiz_assert(!e0.isIdenticalTo(e2)); + + Layout e3 = EmptyLayout::Builder(); + Layout e4 = EmptyLayout::Builder(); + quiz_assert(e3.isIdenticalTo(e4)); + quiz_assert(!e3.isIdenticalTo(e0)); + + Layout e5 = NthRootLayout::Builder(e0); + Layout e6 = NthRootLayout::Builder(e1); + Layout e7 = NthRootLayout::Builder(e2); + quiz_assert(e5.isIdenticalTo(e6)); + quiz_assert(!e5.isIdenticalTo(e7)); + quiz_assert(!e5.isIdenticalTo(e0)); + + Layout e8 = VerticalOffsetLayout::Builder(e5, VerticalOffsetLayoutNode::Position::Superscript); + Layout e9 = VerticalOffsetLayout::Builder(e6, VerticalOffsetLayoutNode::Position::Superscript); + Layout e10 = VerticalOffsetLayout::Builder(NthRootLayout::Builder(CodePointLayout::Builder('a')), VerticalOffsetLayoutNode::Position::Subscript); + quiz_assert(e8.isIdenticalTo(e9)); + quiz_assert(!e8.isIdenticalTo(e10)); + quiz_assert(!e8.isIdenticalTo(e0)); + + Layout e11 = SumLayout::Builder(e0, e3, e6, e2); + Layout e12 = SumLayout::Builder(CodePointLayout::Builder('a'), EmptyLayout::Builder(), NthRootLayout::Builder(CodePointLayout::Builder('a')), CodePointLayout::Builder('b')); + Layout e13 = ProductLayout::Builder(CodePointLayout::Builder('a'), EmptyLayout::Builder(), NthRootLayout::Builder(CodePointLayout::Builder('a')), CodePointLayout::Builder('b')); + quiz_assert(e11.isIdenticalTo(e12)); + quiz_assert(!e11.isIdenticalTo(e13)); +} + +QUIZ_CASE(poincare_layout_fraction_create) { + + /* 12 + * 12|34+5 -> "Divide" -> --- + 5 + * |34 + * */ + HorizontalLayout layout = static_cast(LayoutHelper::String("1234+5", 6)); + LayoutCursor cursor(layout.childAtIndex(2), LayoutCursor::Position::Left); + cursor.addFractionLayoutAndCollapseSiblings(); + assert_layout_serialize_to(layout, "\u0012\u001212\u0013/\u001234\u0013\u0013+5"); + quiz_assert(cursor.isEquivalentTo(LayoutCursor(layout.childAtIndex(0).childAtIndex(1), LayoutCursor::Position::Left))); +} + +QUIZ_CASE(poincare_layout_parentheses_size) { + /* 3 + * (2+(---)6)1 + * 4 + * Assert that the first and last parentheses have the same size. + */ + HorizontalLayout layout = HorizontalLayout::Builder(); + LeftParenthesisLayout leftPar = LeftParenthesisLayout::Builder(); + RightParenthesisLayout rightPar = RightParenthesisLayout::Builder(); + layout.addChildAtIndex(leftPar, 0, 0, nullptr); + layout.addChildAtIndex(CodePointLayout::Builder('2'), 1, 1, nullptr); + layout.addChildAtIndex(CodePointLayout::Builder('+'), 2, 2, nullptr); + layout.addChildAtIndex(LeftParenthesisLayout::Builder(), 3, 3, nullptr); + layout.addChildAtIndex(FractionLayout::Builder( + CodePointLayout::Builder('3'), + CodePointLayout::Builder('4')), + 4, 4, nullptr); + layout.addChildAtIndex(RightParenthesisLayout::Builder(), 4, 4, nullptr); + layout.addChildAtIndex(CodePointLayout::Builder('6'), 5, 5, nullptr); + layout.addChildAtIndex(rightPar, 7, 7, nullptr); + layout.addChildAtIndex(CodePointLayout::Builder('1'), 8, 8, nullptr); + quiz_assert(leftPar.layoutSize().height() == rightPar.layoutSize().height()); +} diff --git a/poincare/test/layout_cursor.cpp b/poincare/test/layout_cursor.cpp index ee883705c..9ab31a613 100644 --- a/poincare/test/layout_cursor.cpp +++ b/poincare/test/layout_cursor.cpp @@ -72,3 +72,38 @@ QUIZ_CASE(poincare_layout_cursor_computation) { EmptyExpression::Builder()); assert_inserted_layout_points_to(l, &e, l.childAtIndex(2)); } + +QUIZ_CASE(poincare_layout_cursor_delete) { + + /* 12 + * --- -> "BackSpace" -> 12|34 + * |34 + * */ + HorizontalLayout layout1 = HorizontalLayout::Builder( + FractionLayout::Builder( + LayoutHelper::String("12", 2), + LayoutHelper::String("34", 2) + ) + ); + LayoutCursor cursor1(layout1.childAtIndex(0).childAtIndex(1), LayoutCursor::Position::Left); + cursor1.performBackspace(); + assert_layout_serialize_to(layout1, "1234"); + quiz_assert(cursor1.isEquivalentTo(LayoutCursor(layout1.childAtIndex(1), LayoutCursor::Position::Right))); + + /* ΓΈ + * 1 + --- -> "BackSpace" -> 1+|3 + * |3 + * */ + HorizontalLayout layout2 = HorizontalLayout::Builder( + CodePointLayout::Builder('1'), + CodePointLayout::Builder('+'), + FractionLayout::Builder( + EmptyLayout::Builder(), + CodePointLayout::Builder('3') + ) + ); + LayoutCursor cursor2(layout2.childAtIndex(2).childAtIndex(1), LayoutCursor::Position::Left); + cursor2.performBackspace(); + assert_layout_serialize_to(layout2, "1+3"); + quiz_assert(cursor2.isEquivalentTo(LayoutCursor(layout2.childAtIndex(1), LayoutCursor::Position::Right))); +} diff --git a/poincare/test/layout_serialization.cpp b/poincare/test/layout_serialization.cpp new file mode 100644 index 000000000..a01e45e92 --- /dev/null +++ b/poincare/test/layout_serialization.cpp @@ -0,0 +1,34 @@ +#include +#include +#include +#include +#include "helper.h" + +using namespace Poincare; + +// TODO: add tests about layout serialization (especially all serialization that add system parentheses) + +QUIZ_CASE(poincare_layout_serialization) { + // Binomial coefficient layout + assert_layout_serialize_to(BinomialCoefficientLayout::Builder(CodePointLayout::Builder('7'), CodePointLayout::Builder('6')), "binomial\u00127,6\u0013"); + + // Fraction layout + Layout layout = FractionLayout::Builder( + CodePointLayout::Builder('1'), + LayoutHelper::String("2+3", 3) + ); + assert_layout_serialize_to(layout, "\u0012\u00121\u0013/\u00122+3\u0013\u0013"); // 1/(2+3) + + // Nth root layout + assert_layout_serialize_to(NthRootLayout::Builder(CodePointLayout::Builder('7'), CodePointLayout::Builder('6')), "root\u00127,6\u0013"); + + // Vertical offset layout + layout = HorizontalLayout::Builder( + CodePointLayout::Builder('2'), + VerticalOffsetLayout::Builder( + LayoutHelper::String("x+5", 3), + VerticalOffsetLayoutNode::Position::Superscript + ) + ); + assert_layout_serialize_to(layout, "2^\x12x+5\x13"); +} diff --git a/poincare/test/layouts.cpp b/poincare/test/layout_to_expression.cpp similarity index 69% rename from poincare/test/layouts.cpp rename to poincare/test/layout_to_expression.cpp index d112d0556..d15522f58 100644 --- a/poincare/test/layouts.cpp +++ b/poincare/test/layout_to_expression.cpp @@ -8,74 +8,125 @@ using namespace Poincare; -void assert_parsed_layout_is(Layout l, Poincare::Expression r) { - Shared::GlobalContext context; - constexpr int bufferSize = 500; - char buffer[bufferSize]; - l.serializeForParsing(buffer, bufferSize); - Expression e = parse_expression(buffer); - Expression eSimplified; - e.clone().simplifyAndApproximate(&eSimplified, nullptr, &context, Cartesian, Degree); - if (eSimplified.isUninitialized()) { - /* In case the simplification is impossible (if there are matrices for - * instance), use the non simplified expression */ - eSimplified = e; - } - Expression rSimplified; - r.clone().simplifyAndApproximate(&rSimplified, nullptr, &context, Cartesian, Degree); - if (rSimplified.isUninitialized()) { - /* In case the simplification is impossible (if there are matrices for - * instance), use the non simplified expression */ - rSimplified = r; - } - - bool identical = eSimplified.isIdenticalTo(rSimplified); -#if POINCARE_TREE_LOG - if (!identical) { - std::cout << "Expecting" << std::endl; - rSimplified.log(); - std::cout << "Got" << std::endl; - eSimplified.log(); - } -#endif - quiz_assert(identical); -} - void assert_layout_is_not_parsed(Layout l) { constexpr int bufferSize = 500; char buffer[bufferSize]; l.serializeForParsing(buffer, bufferSize); - Expression e = parse_expression(buffer, true); - quiz_assert(e.isUninitialized()); + Expression e = Expression::Parse(buffer, false); + quiz_assert_print_if_failure(e.isUninitialized(), buffer); } -QUIZ_CASE(poincare_create_all_layouts) { - EmptyLayout e0 = EmptyLayout::Builder(); - AbsoluteValueLayout e1 = AbsoluteValueLayout::Builder(e0); - CodePointLayout e2 = CodePointLayout::Builder('a'); - BinomialCoefficientLayout e3 = BinomialCoefficientLayout::Builder(e1, e2); - CeilingLayout e4 = CeilingLayout::Builder(e3); - RightParenthesisLayout e5 = RightParenthesisLayout::Builder(); - RightSquareBracketLayout e6 = RightSquareBracketLayout::Builder(); - CondensedSumLayout e7 = CondensedSumLayout::Builder(e4, e5, e6); - ConjugateLayout e8 = ConjugateLayout::Builder(e7); - LeftParenthesisLayout e10 = LeftParenthesisLayout::Builder(); - FloorLayout e11 = FloorLayout::Builder(e10); - FractionLayout e12 = FractionLayout::Builder(e8, e11); - HorizontalLayout e13 = HorizontalLayout::Builder(); - LeftSquareBracketLayout e14 = LeftSquareBracketLayout::Builder(); - IntegralLayout e15 = IntegralLayout::Builder(e11, e12, e13, e14); - NthRootLayout e16 = NthRootLayout::Builder(e15); - MatrixLayout e17 = MatrixLayout::Builder(); - EmptyLayout e18 = EmptyLayout::Builder(); - EmptyLayout e19 = EmptyLayout::Builder(); - EmptyLayout e20 = EmptyLayout::Builder(); - ProductLayout e21 = ProductLayout::Builder(e17, e18, e19, e20); - EmptyLayout e22 = EmptyLayout::Builder(); - EmptyLayout e23 = EmptyLayout::Builder(); - EmptyLayout e24 = EmptyLayout::Builder(); - SumLayout e25 = SumLayout::Builder(e21, e22, e23, e24); - VerticalOffsetLayout e26 = VerticalOffsetLayout::Builder(e25, VerticalOffsetLayoutNode::Position::Superscript); +QUIZ_CASE(poincare_layout_to_expression_unparsable) { + { + /* (1 + * --- + * 2) + * */ + Layout l = FractionLayout::Builder( + HorizontalLayout::Builder( + LeftParenthesisLayout::Builder(), + CodePointLayout::Builder('1')), + HorizontalLayout::Builder( + CodePointLayout::Builder('2'), + RightParenthesisLayout::Builder())); + assert_layout_is_not_parsed(l); + } + + { + // ( √2) + Layout l = HorizontalLayout::Builder( + LeftParenthesisLayout::Builder(), + NthRootLayout::Builder( + HorizontalLayout::Builder( + CodePointLayout::Builder('2'), + RightParenthesisLayout::Builder()))); + assert_layout_is_not_parsed(l); + } + + { + /* 2)+(1 + * βˆ‘ (5) + * n=1 + */ + constexpr int childrenCount = 5; + Layout children[childrenCount] = { + CodePointLayout::Builder('2'), + RightParenthesisLayout::Builder(), + CodePointLayout::Builder('+'), + LeftParenthesisLayout::Builder(), + CodePointLayout::Builder('1')}; + + Layout l = SumLayout::Builder( + CodePointLayout::Builder('5'), + CodePointLayout::Builder('n'), + CodePointLayout::Builder('1'), + HorizontalLayout::Builder(children, childrenCount)); + assert_layout_is_not_parsed(l); + } + + { + /* 2)+(1 + * Ο€ (5) + * n=1 + */ + constexpr int childrenCount = 5; + Layout children[childrenCount] = { + CodePointLayout::Builder('2'), + RightParenthesisLayout::Builder(), + CodePointLayout::Builder('+'), + LeftParenthesisLayout::Builder(), + CodePointLayout::Builder('1')}; + + Layout l = ProductLayout::Builder( + CodePointLayout::Builder('5'), + CodePointLayout::Builder('n'), + CodePointLayout::Builder('1'), + HorizontalLayout::Builder(children, childrenCount)); + assert_layout_is_not_parsed(l); + } + + { + /* 2)+(1 + * ∫ (5)dx + * 1 + */ + constexpr int childrenCount = 5; + Layout children[childrenCount] = { + CodePointLayout::Builder('2'), + RightParenthesisLayout::Builder(), + CodePointLayout::Builder('+'), + LeftParenthesisLayout::Builder(), + CodePointLayout::Builder('1')}; + + Layout l = ProductLayout::Builder( + CodePointLayout::Builder('5'), + CodePointLayout::Builder('x'), + CodePointLayout::Builder('1'), + HorizontalLayout::Builder(children, childrenCount)); + assert_layout_is_not_parsed(l); + } + + { + // |3)+(1| + constexpr int childrenCount = 5; + Layout children[childrenCount] = { + CodePointLayout::Builder('3'), + RightParenthesisLayout::Builder(), + CodePointLayout::Builder('+'), + LeftParenthesisLayout::Builder(), + CodePointLayout::Builder('1')}; + + Layout l = AbsoluteValueLayout::Builder(HorizontalLayout::Builder(children, childrenCount)); + assert_layout_is_not_parsed(l); + } +} + +void assert_parsed_layout_is(Layout l, Poincare::Expression r) { + constexpr int bufferSize = 500; + char buffer[bufferSize]; + l.serializeForParsing(buffer, bufferSize); + Expression e = parse_expression(buffer, true); + quiz_assert_print_if_failure(e.isIdenticalTo(r), buffer); } Matrix BuildOneChildMatrix(Expression entry) { @@ -84,7 +135,7 @@ Matrix BuildOneChildMatrix(Expression entry) { return m; } -QUIZ_CASE(poincare_parse_layouts) { +QUIZ_CASE(poincare_layout_to_expression_parsable) { Layout l; Expression e; @@ -234,14 +285,15 @@ QUIZ_CASE(poincare_parse_layouts) { CodePointLayout::Builder('+'), CodePointLayout::Builder('5'))), CodePointLayout::Builder('3')); - e = MultiplicationExplicite::Builder( + e = MultiplicationImplicite::Builder( Rational::Builder(5), - Division::Builder( - Rational::Builder(6), - Addition::Builder( - Rational::Builder(7), - Rational::Builder(5))), - Rational::Builder(3)); + MultiplicationImplicite::Builder( + Division::Builder( + Rational::Builder(6), + Addition::Builder( + Rational::Builder(7), + Rational::Builder(5))), + Rational::Builder(3))); assert_parsed_layout_is(l, e); // [[3^2!, 7][4,5] @@ -296,145 +348,6 @@ QUIZ_CASE(poincare_parse_layouts) { VerticalOffsetLayout::Builder( CodePointLayout::Builder('3'), VerticalOffsetLayoutNode::Position::Superscript)); - e = MultiplicationExplicite::Builder(Rational::Builder(2),Power::Builder(Constant::Builder(UCodePointScriptSmallE),Parenthesis::Builder(Rational::Builder(3)))); - assert_parsed_expression_is("2β„―^(3)", MultiplicationExplicite::Builder(Rational::Builder(2),Power::Builder(Constant::Builder(UCodePointScriptSmallE),Parenthesis::Builder(Rational::Builder(3))))); + e = MultiplicationImplicite::Builder(Rational::Builder(2),Power::Builder(Constant::Builder(UCodePointScriptSmallE), Rational::Builder(3))); assert_parsed_layout_is(l, e); } - -QUIZ_CASE(poincare_layouts_comparison) { - Layout e0 = CodePointLayout::Builder('a'); - Layout e1 = CodePointLayout::Builder('a'); - Layout e2 = CodePointLayout::Builder('b'); - quiz_assert(e0.isIdenticalTo(e1)); - quiz_assert(!e0.isIdenticalTo(e2)); - - Layout e3 = EmptyLayout::Builder(); - Layout e4 = EmptyLayout::Builder(); - quiz_assert(e3.isIdenticalTo(e4)); - quiz_assert(!e3.isIdenticalTo(e0)); - - Layout e5 = NthRootLayout::Builder(e0); - Layout e6 = NthRootLayout::Builder(e1); - Layout e7 = NthRootLayout::Builder(e2); - quiz_assert(e5.isIdenticalTo(e6)); - quiz_assert(!e5.isIdenticalTo(e7)); - quiz_assert(!e5.isIdenticalTo(e0)); - - Layout e8 = VerticalOffsetLayout::Builder(e5, VerticalOffsetLayoutNode::Position::Superscript); - Layout e9 = VerticalOffsetLayout::Builder(e6, VerticalOffsetLayoutNode::Position::Superscript); - Layout e10 = VerticalOffsetLayout::Builder(NthRootLayout::Builder(CodePointLayout::Builder('a')), VerticalOffsetLayoutNode::Position::Subscript); - quiz_assert(e8.isIdenticalTo(e9)); - quiz_assert(!e8.isIdenticalTo(e10)); - quiz_assert(!e8.isIdenticalTo(e0)); - - Layout e11 = SumLayout::Builder(e0, e3, e6, e2); - Layout e12 = SumLayout::Builder(CodePointLayout::Builder('a'), EmptyLayout::Builder(), NthRootLayout::Builder(CodePointLayout::Builder('a')), CodePointLayout::Builder('b')); - Layout e13 = ProductLayout::Builder(CodePointLayout::Builder('a'), EmptyLayout::Builder(), NthRootLayout::Builder(CodePointLayout::Builder('a')), CodePointLayout::Builder('b')); - quiz_assert(e11.isIdenticalTo(e12)); - quiz_assert(!e11.isIdenticalTo(e13)); -} - -QUIZ_CASE(poincare_unparsable_layouts) { - { - /* (1 - * --- - * 2) - * */ - Layout l = FractionLayout::Builder( - HorizontalLayout::Builder( - LeftParenthesisLayout::Builder(), - CodePointLayout::Builder('1')), - HorizontalLayout::Builder( - CodePointLayout::Builder('2'), - RightParenthesisLayout::Builder())); - assert_layout_is_not_parsed(l); - } - - { - // ( √2) - Layout l = HorizontalLayout::Builder( - LeftParenthesisLayout::Builder(), - NthRootLayout::Builder( - HorizontalLayout::Builder( - CodePointLayout::Builder('2'), - RightParenthesisLayout::Builder()))); - assert_layout_is_not_parsed(l); - } - - { - /* 2)+(1 - * βˆ‘ (5) - * n=1 - */ - constexpr int childrenCount = 5; - Layout children[childrenCount] = { - CodePointLayout::Builder('2'), - RightParenthesisLayout::Builder(), - CodePointLayout::Builder('+'), - LeftParenthesisLayout::Builder(), - CodePointLayout::Builder('1')}; - - Layout l = SumLayout::Builder( - CodePointLayout::Builder('5'), - CodePointLayout::Builder('n'), - CodePointLayout::Builder('1'), - HorizontalLayout::Builder(children, childrenCount)); - assert_layout_is_not_parsed(l); - } - - { - /* 2)+(1 - * Ο€ (5) - * n=1 - */ - constexpr int childrenCount = 5; - Layout children[childrenCount] = { - CodePointLayout::Builder('2'), - RightParenthesisLayout::Builder(), - CodePointLayout::Builder('+'), - LeftParenthesisLayout::Builder(), - CodePointLayout::Builder('1')}; - - Layout l = ProductLayout::Builder( - CodePointLayout::Builder('5'), - CodePointLayout::Builder('n'), - CodePointLayout::Builder('1'), - HorizontalLayout::Builder(children, childrenCount)); - assert_layout_is_not_parsed(l); - } - - { - /* 2)+(1 - * ∫ (5)dx - * 1 - */ - constexpr int childrenCount = 5; - Layout children[childrenCount] = { - CodePointLayout::Builder('2'), - RightParenthesisLayout::Builder(), - CodePointLayout::Builder('+'), - LeftParenthesisLayout::Builder(), - CodePointLayout::Builder('1')}; - - Layout l = ProductLayout::Builder( - CodePointLayout::Builder('5'), - CodePointLayout::Builder('x'), - CodePointLayout::Builder('1'), - HorizontalLayout::Builder(children, childrenCount)); - assert_layout_is_not_parsed(l); - } - - { - // |3)+(1| - constexpr int childrenCount = 5; - Layout children[childrenCount] = { - CodePointLayout::Builder('3'), - RightParenthesisLayout::Builder(), - CodePointLayout::Builder('+'), - LeftParenthesisLayout::Builder(), - CodePointLayout::Builder('1')}; - - Layout l = AbsoluteValueLayout::Builder(HorizontalLayout::Builder(children, childrenCount)); - assert_layout_is_not_parsed(l); - } -} diff --git a/poincare/test/logarithm.cpp b/poincare/test/logarithm.cpp deleted file mode 100644 index a9df86dc0..000000000 --- a/poincare/test/logarithm.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#include -#include -#include -#include "helper.h" - -using namespace Poincare; - -QUIZ_CASE(poincare_logarithm_evaluate) { - assert_parsed_expression_evaluates_to("log(2,64)", "0.1666667"); - assert_parsed_expression_evaluates_to("log(6,7)", "0.9207822211616"); - assert_parsed_expression_evaluates_to("log(5)", "0.69897"); - assert_parsed_expression_evaluates_to("ln(5)", "1.6094379124341"); - assert_parsed_expression_evaluates_to("log(2+5×𝐒,64)", "0.4048317+0.2862042×𝐒"); - assert_parsed_expression_evaluates_to("log(6,7+4×𝐒)", "8.0843880717528ᴇ-1-2.0108238082167ᴇ-1×𝐒"); - assert_parsed_expression_evaluates_to("log(5+2×𝐒)", "0.731199+0.1652518×𝐒"); - assert_parsed_expression_evaluates_to("ln(5+2×𝐒)", "1.6836479149932+3.8050637711236ᴇ-1×𝐒"); - assert_parsed_expression_evaluates_to("log(0,0)", Undefined::Name()); - assert_parsed_expression_evaluates_to("log(0)", "-inf"); - assert_parsed_expression_evaluates_to("log(2,0)", "0"); - - // WARNING: evaluate on branch cut can be multivalued - assert_parsed_expression_evaluates_to("ln(-4)", "1.3862943611199+3.1415926535898×𝐒"); -} - -QUIZ_CASE(poincare_logarithm_simplify) { - assert_parsed_expression_simplify_to("log(0,0)", Undefined::Name()); - assert_parsed_expression_simplify_to("log(0,1)", Undefined::Name()); - assert_parsed_expression_simplify_to("log(1,0)", "0"); - assert_parsed_expression_simplify_to("log(2,0)", "0"); - assert_parsed_expression_simplify_to("log(0,14)", "-inf"); - assert_parsed_expression_simplify_to("log(0,0.14)", Infinity::Name()); - assert_parsed_expression_simplify_to("log(0,0.14+𝐒)", Undefined::Name()); - assert_parsed_expression_simplify_to("log(2,1)", Undefined::Name()); - assert_parsed_expression_simplify_to("log(x,1)", Undefined::Name()); - assert_parsed_expression_simplify_to("log(12925)", "log(47)+log(11)+2Γ—log(5)"); - assert_parsed_expression_simplify_to("ln(12925)", "ln(47)+ln(11)+2Γ—ln(5)"); - assert_parsed_expression_simplify_to("log(1742279/12925, 6)", "-log(47,6)+log(17,6)+3Γ—log(11,6)+log(7,6)-2Γ—log(5,6)"); - assert_parsed_expression_simplify_to("ln(2/3)", "-ln(3)+ln(2)"); - assert_parsed_expression_simplify_to("log(1742279/12925, -6)", "log(158389/1175,-6)"); - assert_parsed_expression_simplify_to("ln(√(2))", "ln(2)/2"); - assert_parsed_expression_simplify_to("ln(β„―^3)", "3"); - assert_parsed_expression_simplify_to("log(10)", "1"); - assert_parsed_expression_simplify_to("log(√(3),√(3))", "1"); - assert_parsed_expression_simplify_to("log(1/√(2))", "-log(2)/2"); - assert_parsed_expression_simplify_to("log(-𝐒)", "log(-𝐒)"); - assert_parsed_expression_simplify_to("ln(β„―^(𝐒π/7))", "Ο€/7×𝐒"); - assert_parsed_expression_simplify_to("log(10^24)", "24"); - assert_parsed_expression_simplify_to("log((23Ο€)^4,23Ο€)", "4"); - assert_parsed_expression_simplify_to("log(10^(2+Ο€))", "Ο€+2"); - assert_parsed_expression_simplify_to("ln(1881676377434183981909562699940347954480361860897069)", "ln(1881676377434183981909562699940347954480361860897069)"); - /* log(1002101470343) does no reduce to 3Γ—log(10007) because it involves - * prime factors above k_biggestPrimeFactor */ - assert_parsed_expression_simplify_to("log(1002101470343)", "log(1002101470343)"); - assert_parsed_expression_simplify_to("log(64,2)", "6"); - assert_parsed_expression_simplify_to("log(2,64)", "log(2,64)"); - assert_parsed_expression_simplify_to("log(1476225,5)", "10Γ—log(3,5)+2"); - - assert_parsed_expression_simplify_to("log(100)", "2"); - assert_parsed_expression_simplify_to("log(1000000)", "6"); - assert_parsed_expression_simplify_to("log(70992768,14)", "log(11,14)+log(3,14)+2Γ—log(2,14)+5"); - assert_parsed_expression_simplify_to("log(1/6991712,14)", "-log(13,14)-5"); - assert_parsed_expression_simplify_to("log(4,10)", "2Γ—log(2)"); -} diff --git a/poincare/test/matrix.cpp b/poincare/test/matrix.cpp deleted file mode 100644 index 5499f7284..000000000 --- a/poincare/test/matrix.cpp +++ /dev/null @@ -1,154 +0,0 @@ -#include -#include -#include "helper.h" - -using namespace Poincare; - -QUIZ_CASE(poincare_matrix_evaluate) { - assert_parsed_expression_evaluates_to("[[1,2,3][4,5,6]]", "[[1,2,3][4,5,6]]"); - assert_parsed_expression_evaluates_to("[[1,2,3][4,5,6]]", "[[1,2,3][4,5,6]]"); -} - -QUIZ_CASE(poincare_matrix_simplify) { - // Addition Matrix - assert_parsed_expression_simplify_to("1+[[1,2,3][4,5,6]]", Undefined::Name()); - assert_parsed_expression_simplify_to("[[1,2,3][4,5,6]]+1", Undefined::Name()); - assert_parsed_expression_simplify_to("[[1,2][3,4]]+[[1,2,3][4,5,6]]", Undefined::Name()); - assert_parsed_expression_simplify_to("2+[[1,2,3][4,5,6]]+[[1,2,3][4,5,6]]", Undefined::Name()); - assert_parsed_expression_simplify_to("[[1,2,3][4,5,6]]+cos(2)+[[1,2,3][4,5,6]]", Undefined::Name()); - assert_parsed_expression_simplify_to("[[1,2,3][4,5,6]]+[[1,2,3][4,5,6]]", "[[2,4,6][8,10,12]]"); - - // Multiplication Matrix - assert_parsed_expression_simplify_to("2*[[1,2,3][4,5,6]]", "[[2,4,6][8,10,12]]"); - assert_parsed_expression_simplify_to("[[1,2,3][4,5,6]]Γ—βˆš(2)", "[[√(2),2Γ—βˆš(2),3Γ—βˆš(2)][4Γ—βˆš(2),5Γ—βˆš(2),6Γ—βˆš(2)]]"); - assert_parsed_expression_simplify_to("[[1,2][3,4]]*[[1,2,3][4,5,6]]", "[[9,12,15][19,26,33]]"); - assert_parsed_expression_simplify_to("[[1,2,3][4,5,6]]*[[1,2][2,3][5,6]]", "[[20,26][44,59]]"); - assert_parsed_expression_simplify_to("[[1,2,3,4][4,5,6,5]]*[[1,2][2,3][5,6]]", Undefined::Name()); - assert_parsed_expression_simplify_to("[[1,2][3,4]]^(-3)*[[1,2][3,4]]", "[[11/2,-5/2][-15/4,7/4]]"); - assert_parsed_expression_simplify_to("[[1,2][3,4]]^(-3)*[[1,2,3][3,4,5]]*[[1,2][3,2][4,5]]*4", "[[-176,-186][122,129]]"); - - // Power Matrix - assert_parsed_expression_simplify_to("[[1,2,3][4,5,6][7,8,9]]^3", "[[468,576,684][1062,1305,1548][1656,2034,2412]]"); - assert_parsed_expression_simplify_to("[[1,2,3][4,5,6]]^(-1)", Undefined::Name()); - assert_parsed_expression_simplify_to("[[1,2][3,4]]^(-1)", "[[-2,1][3/2,-1/2]]"); - - // Determinant - assert_parsed_expression_simplify_to("det(Ο€+Ο€)", "2Γ—Ο€"); - assert_parsed_expression_simplify_to("det([[Ο€+Ο€]])", "2Γ—Ο€"); - assert_parsed_expression_simplify_to("det([[1,2][3,4]])", "-2"); - assert_parsed_expression_simplify_to("det([[2,2][3,4]])", "2"); - assert_parsed_expression_simplify_to("det([[2,2][3,4][3,4]])", Undefined::Name()); - assert_parsed_expression_simplify_to("det([[2,2][3,3]])", "0"); - assert_parsed_expression_simplify_to("det([[1,2,3][4,5,6][7,8,9]])", "0"); - assert_parsed_expression_simplify_to("det([[1,2,3][4,5,6][7,8,9]])", "0"); - assert_parsed_expression_simplify_to("det([[1,2,3][4Ο€,5,6][7,8,9]])", "24Γ—Ο€-24"); - - // Dimension - assert_parsed_expression_simplify_to("dim(3)", "[[1,1]]"); - assert_parsed_expression_simplify_to("dim([[1/√(2),1/2,3][2,1,-3]])", "[[2,3]]"); - - // Inverse - assert_parsed_expression_simplify_to("inverse([[1/√(2),1/2,3][2,1,-3]])", Undefined::Name()); - assert_parsed_expression_simplify_to("inverse([[1,2][3,4]])", "[[-2,1][3/2,-1/2]]"); - assert_parsed_expression_simplify_to("inverse([[Ο€,2Ο€][3,2]])", "[[-1/(2Γ—Ο€),1/2][3/(4Γ—Ο€),-1/4]]"); - - // Trace - assert_parsed_expression_simplify_to("trace([[1/√(2),1/2,3][2,1,-3]])", Undefined::Name()); - assert_parsed_expression_simplify_to("trace([[√(2),2][4,3+log(3)]])", "log(3)+√(2)+3"); - assert_parsed_expression_simplify_to("trace(√(2)+log(3))", "log(3)+√(2)"); - - // Transpose - assert_parsed_expression_simplify_to("transpose([[1/√(2),1/2,3][2,1,-3]])", "[[√(2)/2,2][1/2,1][3,-3]]"); - assert_parsed_expression_simplify_to("transpose(√(4))", "2"); -} - -QUIZ_CASE(poincare_matrix_simplify_with_functions) { - assert_parsed_expression_simplify_to("abs([[1,-1][2,-3]])", "[[1,1][2,3]]"); - assert_parsed_expression_simplify_to("acos([[1/√(2),1/2][1,-1]])", "[[Ο€/4,Ο€/3][0,Ο€]]"); - assert_parsed_expression_simplify_to("acos([[1,0]])", "[[0,Ο€/2]]"); - assert_parsed_expression_simplify_to("asin([[1/√(2),1/2][1,-1]])", "[[Ο€/4,Ο€/6][Ο€/2,-Ο€/2]]"); - assert_parsed_expression_simplify_to("asin([[1,0]])", "[[Ο€/2,0]]"); - assert_parsed_expression_simplify_to("atan([[√(3),1][1/√(3),-1]])", "[[Ο€/3,Ο€/4][Ο€/6,-Ο€/4]]"); - assert_parsed_expression_simplify_to("atan([[1,0]])", "[[Ο€/4,0]]"); - assert_parsed_expression_simplify_to("binomial([[0,180]],1)", Undefined::Name()); - assert_parsed_expression_simplify_to("binomial(1,[[0,180]])", Undefined::Name()); - assert_parsed_expression_simplify_to("binomial([[0,180]],[[1]])", Undefined::Name()); - assert_parsed_expression_simplify_to("ceil([[0.3,180]])", "[[1,180]]"); - assert_parsed_expression_simplify_to("arg([[1,1+𝐒]])", "[[0,Ο€/4]]"); - assert_parsed_expression_simplify_to("confidence([[0,180]],1)", Undefined::Name()); - assert_parsed_expression_simplify_to("confidence(1,[[0,180]])", Undefined::Name()); - assert_parsed_expression_simplify_to("confidence([[0,180]],[[1]])", Undefined::Name()); - assert_parsed_expression_simplify_to("confidence(1/3, 25)", "[[2/15,8/15]]"); - assert_parsed_expression_simplify_to("confidence(45, 25)", Undefined::Name()); - assert_parsed_expression_simplify_to("confidence(1/3, -34)", Undefined::Name()); - assert_parsed_expression_simplify_to("conj([[1,1+𝐒]])", "[[1,1-𝐒]]"); - assert_parsed_expression_simplify_to("cos([[Ο€/3,0][Ο€/7,Ο€/2]])", "[[1/2,1][cos(Ο€/7),0]]"); - assert_parsed_expression_simplify_to("cos([[0,Ο€]])", "[[1,-1]]"); - assert_parsed_expression_simplify_to("diff([[0,180]],x,1)", Undefined::Name()); - assert_parsed_expression_simplify_to("diff(1,x,[[0,180]])", Undefined::Name()); - assert_parsed_expression_simplify_to("quo([[0,180]],1)", Undefined::Name()); - assert_parsed_expression_simplify_to("quo(1,[[0,180]])", Undefined::Name()); - assert_parsed_expression_simplify_to("quo([[0,180]],[[1]])", Undefined::Name()); - assert_parsed_expression_simplify_to("rem([[0,180]],1)", Undefined::Name()); - assert_parsed_expression_simplify_to("rem(1,[[0,180]])", Undefined::Name()); - assert_parsed_expression_simplify_to("rem([[0,180]],[[1]])", Undefined::Name()); - assert_parsed_expression_simplify_to("factor([[0,180]])", Undefined::Name()); - assert_parsed_expression_simplify_to("[[1,3]]!", "[[1,6]]"); - assert_parsed_expression_simplify_to("[[1,2][3,4]]!", "[[1,2][6,24]]"); - assert_parsed_expression_simplify_to("floor([[1/√(2),1/2][1,-1.3]])", "[[floor(√(2)/2),0][1,-2]]"); - assert_parsed_expression_simplify_to("floor([[0.3,180]])", "[[0,180]]"); - assert_parsed_expression_simplify_to("frac([[1/√(2),1/2][1,-1.3]])", "[[frac(√(2)/2),1/2][0,7/10]]"); - assert_parsed_expression_simplify_to("frac([[0.3,180]])", "[[3/10,0]]"); - assert_parsed_expression_simplify_to("gcd([[0,180]],1)", Undefined::Name()); - assert_parsed_expression_simplify_to("gcd(1,[[0,180]])", Undefined::Name()); - assert_parsed_expression_simplify_to("gcd([[0,180]],[[1]])", Undefined::Name()); - assert_parsed_expression_simplify_to("acosh([[0,Ο€]])", "[[acosh(0),acosh(Ο€)]]"); - assert_parsed_expression_simplify_to("asinh([[0,Ο€]])", "[[asinh(0),asinh(Ο€)]]"); - assert_parsed_expression_simplify_to("atanh([[0,Ο€]])", "[[atanh(0),atanh(Ο€)]]"); - assert_parsed_expression_simplify_to("cosh([[0,Ο€]])", "[[cosh(0),cosh(Ο€)]]"); - assert_parsed_expression_simplify_to("sinh([[0,Ο€]])", "[[sinh(0),sinh(Ο€)]]"); - assert_parsed_expression_simplify_to("tanh([[0,Ο€]])", "[[tanh(0),tanh(Ο€)]]"); - assert_parsed_expression_simplify_to("im([[1/√(2),1/2][1,-1]])", "[[0,0][0,0]]"); - assert_parsed_expression_simplify_to("im([[1,1+𝐒]])", "[[0,1]]"); - assert_parsed_expression_simplify_to("int([[0,180]],x,1,2)", Undefined::Name()); - assert_parsed_expression_simplify_to("int(1,x,[[0,180]],1)", Undefined::Name()); - assert_parsed_expression_simplify_to("int(1,x,1,[[0,180]])", Undefined::Name()); - assert_parsed_expression_simplify_to("log([[2,3]])", "[[log(2),log(3)]]"); - assert_parsed_expression_simplify_to("log([[2,3]],5)", "[[log(2,5),log(3,5)]]"); - assert_parsed_expression_simplify_to("log(5,[[2,3]])", Undefined::Name()); - assert_parsed_expression_simplify_to("log([[√(2),1/2][1,3]])", "[[log(2)/2,-log(2)][0,log(3)]]"); - assert_parsed_expression_simplify_to("log([[1/√(2),1/2][1,-3]])", "[[-log(2)/2,-log(2)][0,log(-3)]]"); // ComplexFormat is Cartesian - assert_parsed_expression_simplify_to("log([[1/√(2),1/2][1,-3]],3)", "[[-log(2,3)/2,-log(2,3)][0,log(-3,3)]]"); - assert_parsed_expression_simplify_to("ln([[2,3]])", "[[ln(2),ln(3)]]"); - assert_parsed_expression_simplify_to("ln([[√(2),1/2][1,3]])", "[[ln(2)/2,-ln(2)][0,ln(3)]]"); - assert_parsed_expression_simplify_to("root([[2,3]],5)", Undefined::Name()); - assert_parsed_expression_simplify_to("root(5,[[2,3]])", Undefined::Name()); - assert_parsed_expression_simplify_to("-[[1/√(2),1/2,3][2,1,-3]]", "[[-√(2)/2,-1/2,-3][-2,-1,3]]"); - assert_parsed_expression_simplify_to("permute([[2,3]],5)", Undefined::Name()); - assert_parsed_expression_simplify_to("permute(5,[[2,3]])", Undefined::Name()); - assert_parsed_expression_simplify_to("prediction([[2,3]],5)", Undefined::Name()); - assert_parsed_expression_simplify_to("prediction(5,[[2,3]])", Undefined::Name()); - assert_parsed_expression_simplify_to("prediction95([[2,3]],5)", Undefined::Name()); - assert_parsed_expression_simplify_to("prediction95(5,[[2,3]])", Undefined::Name()); - assert_parsed_expression_simplify_to("prediction95(1/3, 25)", "[[(-49Γ—βˆš(2)+125)/375,(49Γ—βˆš(2)+125)/375]]"); - assert_parsed_expression_simplify_to("prediction95(45, 25)", Undefined::Name()); - assert_parsed_expression_simplify_to("prediction95(1/3, -34)", Undefined::Name()); - assert_parsed_expression_simplify_to("product(1,x,[[0,180]],1)", Undefined::Name()); - assert_parsed_expression_simplify_to("product(1,x,1,[[0,180]])", Undefined::Name()); - assert_parsed_expression_simplify_to("randint([[2,3]],5)", Undefined::Name()); - assert_parsed_expression_simplify_to("randint(5,[[2,3]])", Undefined::Name()); - assert_parsed_expression_simplify_to("re([[1,𝐒]])", "[[1,0]]"); - assert_parsed_expression_simplify_to("round([[2.12,3.42]], 1)", "[[21/10,17/5]]"); - assert_parsed_expression_simplify_to("round(1.3, [[2.1,3.4]])", Undefined::Name()); - assert_parsed_expression_simplify_to("round(1.3, [[2.1,3.4]])", Undefined::Name()); - assert_parsed_expression_simplify_to("sign([[2.1,3.4]])", Undefined::Name()); - assert_parsed_expression_simplify_to("sin([[Ο€/3,0][Ο€/7,Ο€/2]])", "[[√(3)/2,0][sin(Ο€/7),1]]"); - assert_parsed_expression_simplify_to("sin([[0,Ο€]])", "[[0,0]]"); - assert_parsed_expression_simplify_to("sum(1,x,[[0,180]],1)", Undefined::Name()); - assert_parsed_expression_simplify_to("sum(1,x,1,[[0,180]])", Undefined::Name()); - assert_parsed_expression_simplify_to("√([[2.1,3.4]])", Undefined::Name()); - assert_parsed_expression_simplify_to("[[2,3.4]]-[[0.1,3.1]]", "[[19/10,3/10]]"); - assert_parsed_expression_simplify_to("[[2,3.4]]-1", Undefined::Name()); - assert_parsed_expression_simplify_to("1-[[0.1,3.1]]", Undefined::Name()); - assert_parsed_expression_simplify_to("tan([[0,Ο€/4]])", "[[0,1]]"); -} diff --git a/poincare/test/multiplication.cpp b/poincare/test/multiplication.cpp deleted file mode 100644 index d953d3e5f..000000000 --- a/poincare/test/multiplication.cpp +++ /dev/null @@ -1,74 +0,0 @@ -#include -#include -#include -#include "helper.h" - -using namespace Poincare; - -QUIZ_CASE(poincare_multiplication_evaluate) { - assert_parsed_expression_evaluates_to("1Γ—2", "2"); - assert_parsed_expression_evaluates_to("(3+𝐒)Γ—(4+𝐒)", "11+7×𝐒"); - assert_parsed_expression_evaluates_to("[[1,2][3,4][5,6]]Γ—2", "[[2,4][6,8][10,12]]"); - assert_parsed_expression_evaluates_to("[[1,2+𝐒][3,4][5,6]]Γ—(3+𝐒)", "[[3+𝐒,5+5×𝐒][9+3×𝐒,12+4×𝐒][15+5×𝐒,18+6×𝐒]]"); - assert_parsed_expression_evaluates_to("2Γ—[[1,2][3,4][5,6]]", "[[2,4][6,8][10,12]]"); - assert_parsed_expression_evaluates_to("(3+𝐒)Γ—[[1,2+𝐒][3,4][5,6]]", "[[3+𝐒,5+5×𝐒][9+3×𝐒,12+4×𝐒][15+5×𝐒,18+6×𝐒]]"); - assert_parsed_expression_evaluates_to("[[1,2][3,4][5,6]]Γ—[[1,2,3,4][5,6,7,8]]", "[[11,14,17,20][23,30,37,44][35,46,57,68]]"); - assert_parsed_expression_evaluates_to("[[1,2+𝐒][3,4][5,6]]Γ—[[1,2+𝐒,3,4][5,6+𝐒,7,8]]", "[[11+5×𝐒,13+9×𝐒,17+7×𝐒,20+8×𝐒][23,30+7×𝐒,37,44][35,46+11×𝐒,57,68]]"); -} - -QUIZ_CASE(poincare_multiplication_simplify) { - assert_parsed_expression_simplify_to("undefΓ—x", "undef"); - assert_parsed_expression_simplify_to("0Γ—x+B", "B"); - assert_parsed_expression_simplify_to("0Γ—xΓ—0Γ—32Γ—cos(3)", "0"); - assert_parsed_expression_simplify_to("3Γ—A^4Γ—B^xΓ—B^2Γ—(A^2+2)Γ—2Γ—1.2", "(36Γ—A^6Γ—B^(x+2)+72Γ—A^4Γ—B^(x+2))/5"); - assert_parsed_expression_simplify_to("AΓ—(B+C)Γ—(D+3)", "3Γ—AΓ—B+3Γ—AΓ—C+AΓ—BΓ—D+AΓ—CΓ—D"); - assert_parsed_expression_simplify_to("A/B", "A/B"); - assert_parsed_expression_simplify_to("(AΓ—B)^2", "A^2Γ—B^2"); - assert_parsed_expression_simplify_to("(1/2)Γ—A/B", "A/(2Γ—B)"); - assert_parsed_expression_simplify_to("1+2+3+4+5+6", "21"); - assert_parsed_expression_simplify_to("1-2+3-4+5-6", "-3"); - assert_parsed_expression_simplify_to("987654321123456789Γ—998877665544332211", "986545842648570754445552922919330479"); - assert_parsed_expression_simplify_to("2/3", "2/3"); - assert_parsed_expression_simplify_to("9/17+5/4", "121/68"); - assert_parsed_expression_simplify_to("1/2Γ—3/4", "3/8"); - assert_parsed_expression_simplify_to("0Γ—2/3", "0"); - assert_parsed_expression_simplify_to("1+(1/(1+1/(1+1/(1+1))))", "8/5"); - assert_parsed_expression_simplify_to("1+2/(3+4/(5+6/(7+8)))", "155/101"); - assert_parsed_expression_simplify_to("3/4Γ—16/12", "1"); - assert_parsed_expression_simplify_to("3/4Γ—(8+8)/12", "1"); - assert_parsed_expression_simplify_to("916791/794976477", "305597/264992159"); - assert_parsed_expression_simplify_to("321654987123456789/112233445566778899", "3249040273974311/1133671167341201"); - assert_parsed_expression_simplify_to("0.1+0.2", "3/10"); - assert_parsed_expression_simplify_to("2^3", "8"); - assert_parsed_expression_simplify_to("(-1)Γ—(-1)", "1"); - assert_parsed_expression_simplify_to("(-2)^2", "4"); - assert_parsed_expression_simplify_to("(-3)^3", "-27"); - assert_parsed_expression_simplify_to("(1/2)^-1", "2"); - assert_parsed_expression_simplify_to("√(2)Γ—βˆš(3)", "√(6)"); - assert_parsed_expression_simplify_to("2Γ—2^Ο€", "2Γ—2^Ο€"); - assert_parsed_expression_simplify_to("A^3Γ—BΓ—A^(-3)", "B"); - assert_parsed_expression_simplify_to("A^3Γ—A^(-3)", "1"); - assert_parsed_expression_simplify_to("2^π×(1/2)^Ο€", "1"); - assert_parsed_expression_simplify_to("A^3Γ—A^(-3)", "1"); - assert_parsed_expression_simplify_to("(x+1)Γ—(x+2)", "x^2+3Γ—x+2"); - assert_parsed_expression_simplify_to("(x+1)Γ—(x-1)", "x^2-1"); - assert_parsed_expression_simplify_to("11Ο€/(22Ο€+11Ο€)", "1/3"); - assert_parsed_expression_simplify_to("11/(22Ο€+11Ο€)", "1/(3Γ—Ο€)"); - assert_parsed_expression_simplify_to("-11/(22Ο€+11Ο€)", "-1/(3Γ—Ο€)"); - assert_parsed_expression_simplify_to("A^2Γ—BΓ—A^(-2)Γ—B^(-2)", "1/B"); - assert_parsed_expression_simplify_to("A^(-1)Γ—B^(-1)", "1/(AΓ—B)"); - assert_parsed_expression_simplify_to("x+x", "2Γ—x"); - assert_parsed_expression_simplify_to("2Γ—x+x", "3Γ—x"); - assert_parsed_expression_simplify_to("xΓ—2+x", "3Γ—x"); - assert_parsed_expression_simplify_to("2Γ—x+2Γ—x", "4Γ—x"); - assert_parsed_expression_simplify_to("xΓ—2+2Γ—n", "2Γ—n+2Γ—x"); - assert_parsed_expression_simplify_to("x+x+n+n", "2Γ—n+2Γ—x"); - assert_parsed_expression_simplify_to("x-x-n+n", "0"); - assert_parsed_expression_simplify_to("x+n-x-n", "0"); - assert_parsed_expression_simplify_to("x-x", "0"); - assert_parsed_expression_simplify_to("π×3^(1/2)Γ—(5Ο€)^(1/2)Γ—(4/5)^(1/2)", "2Γ—βˆš(3)Γ—Ο€^(3/2)"); - assert_parsed_expression_simplify_to("12^(1/4)Γ—(Ο€/6)Γ—(12Γ—Ο€)^(1/4)", "(√(3)Γ—Ο€^(5/4))/3"); - assert_parsed_expression_simplify_to("[[1,2+𝐒][3,4][5,6]]Γ—[[1,2+𝐒,3,4][5,6+𝐒,7,8]]", "[[11+5×𝐒,13+9×𝐒,17+7×𝐒,20+8×𝐒][23,30+7×𝐒,37,44][35,46+11×𝐒,57,68]]"); - assert_parsed_expression_simplify_to("[[1,2][3,4]]Γ—[[1,3][5,6]]Γ—[[2,3][4,6]]", "[[82,123][178,267]]"); - assert_parsed_expression_simplify_to("π×confidence(Ο€/5,3)[[1,2]]", "π×confidence(Ο€/5,3)Γ—[[1,2]]"); -} diff --git a/poincare/test/nth_root_layout.cpp b/poincare/test/nth_root_layout.cpp deleted file mode 100644 index ea0debc7e..000000000 --- a/poincare/test/nth_root_layout.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include -#include -#include -#include "helper.h" - -using namespace Poincare; - -QUIZ_CASE(poincare_nth_root_layout_serialize) { - assert_parsed_expression_layout_serialize_to_self("root(7,3)"); -} diff --git a/poincare/test/number.cpp b/poincare/test/number.cpp deleted file mode 100644 index 922190419..000000000 --- a/poincare/test/number.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include "tree/helpers.h" -#include "helper.h" - -using namespace Poincare; - -QUIZ_CASE(poincare_number_parser) { - // Integer - assert_parsed_expression_is("123456789012345678765434567", Rational::Builder("123456789012345678765434567")); - assert_parsed_expression_is(MaxIntegerString(), Rational::Builder(MaxIntegerString())); - - // Integer parsed in Decimal because they overflow Integer - assert_parsed_expression_is(OverflowedIntegerString(), Decimal::Builder(Integer("17976931348623"), 308)); - assert_parsed_expression_is("179769313486235590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137216", Decimal::Builder(Integer("17976931348624"), 308)); - - // Decimal with rounding when digits are above 14 - assert_parsed_expression_is("0.0000012345678901234", Decimal::Builder(Integer("12345678901234"), -6)); - assert_parsed_expression_is("0.00000123456789012345", Decimal::Builder(Integer("12345678901235"), -6)); - assert_parsed_expression_is("0.00000123456789012341", Decimal::Builder(Integer("12345678901234"), -6)); - assert_parsed_expression_is("1234567890123.4", Decimal::Builder(Integer("12345678901234"), 12)); - assert_parsed_expression_is("123456789012345.2", Decimal::Builder(Integer("12345678901235"), 14)); - assert_parsed_expression_is("123456789012341.2", Decimal::Builder(Integer("12345678901234"), 14)); - assert_parsed_expression_is("12.34567", Decimal::Builder(Integer("1234567"), 1)); - assert_parsed_expression_is(".999999999999990", Decimal::Builder(Integer("99999999999999"), -1)); - assert_parsed_expression_is("9.99999999999994", Decimal::Builder(Integer("99999999999999"), 0)); - assert_parsed_expression_is("99.9999999999995", Decimal::Builder(Integer("100000000000000"), 2)); - assert_parsed_expression_is("999.999999999999", Decimal::Builder(Integer("100000000000000"), 3)); - assert_parsed_expression_is("9999.99199999999", Decimal::Builder(Integer("99999920000000"), 3)); - assert_parsed_expression_is("99299.9999999999", Decimal::Builder(Integer("99300000000000"), 4)); - - // Infinity - assert_parsed_expression_is("23ᴇ1000", Infinity::Builder(false)); - assert_parsed_expression_is("2.3ᴇ1000", Decimal::Builder(Integer(23), 1000)); - - // Zero - assert_parsed_expression_is("0.23ᴇ-1000", Decimal::Builder(Integer(0), 0)); - assert_parsed_expression_is("0.23ᴇ-999", Decimal::Builder(Integer(23), -1000)); -} diff --git a/poincare/test/parentheses_layout.cpp b/poincare/test/parentheses_layout.cpp deleted file mode 100644 index 241ac6f02..000000000 --- a/poincare/test/parentheses_layout.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include -#include -#include -#include -#include "helper.h" - -using namespace Poincare; - -QUIZ_CASE(poincare_parenthesis_layout_size) { - /* 3 - * (2+(---)6)1 - * 4 - * Assert that the first and last parentheses have the same size. - */ - HorizontalLayout layout = HorizontalLayout::Builder(); - LeftParenthesisLayout leftPar = LeftParenthesisLayout::Builder(); - RightParenthesisLayout rightPar = RightParenthesisLayout::Builder(); - layout.addChildAtIndex(leftPar, 0, 0, nullptr); - layout.addChildAtIndex(CodePointLayout::Builder('2'), 1, 1, nullptr); - layout.addChildAtIndex(CodePointLayout::Builder('+'), 2, 2, nullptr); - layout.addChildAtIndex(LeftParenthesisLayout::Builder(), 3, 3, nullptr); - layout.addChildAtIndex(FractionLayout::Builder( - CodePointLayout::Builder('3'), - CodePointLayout::Builder('4')), - 4, 4, nullptr); - layout.addChildAtIndex(RightParenthesisLayout::Builder(), 4, 4, nullptr); - layout.addChildAtIndex(CodePointLayout::Builder('6'), 5, 5, nullptr); - layout.addChildAtIndex(rightPar, 7, 7, nullptr); - layout.addChildAtIndex(CodePointLayout::Builder('1'), 8, 8, nullptr); - quiz_assert(leftPar.layoutSize().height() == rightPar.layoutSize().height()); -} diff --git a/poincare/test/parser.cpp b/poincare/test/parsing.cpp similarity index 68% rename from poincare/test/parser.cpp rename to poincare/test/parsing.cpp index 2b8df0278..aad5b2da4 100644 --- a/poincare/test/parser.cpp +++ b/poincare/test/parsing.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "tree/helpers.h" #include "helper.h" @@ -12,7 +13,7 @@ void assert_tokenizes_as(const Token::Type * tokenTypes, const char * string) { Tokenizer tokenizer(string); while (true) { Token token = tokenizer.popToken(); - quiz_assert(token.type() == *tokenTypes); + quiz_assert_print_if_failure(token.type() == *tokenTypes, string); if (token.type() == Token::EndOfStream) { return; } @@ -32,19 +33,24 @@ void assert_tokenizes_as_undefined_token(const char * string) { if (token.type() == Token::Undefined) { return; } - if (token.type() == Token::EndOfStream) { - quiz_assert(false); - } + quiz_assert_print_if_failure(token.type() != Token::EndOfStream, string); } } -void assert_raises_parsing_error(const char * text) { +void assert_text_not_parsable(const char * text) { Parser p(text); Expression result = p.parse(); - quiz_assert(p.getStatus() != Parser::Status::Success); + quiz_assert_print_if_failure(p.getStatus() != Parser::Status::Success, text); } -QUIZ_CASE(poincare_parser_tokenize_numbers) { +void assert_parsed_expression_is(const char * expression, Poincare::Expression r, bool addParentheses = false) { + Expression e = parse_expression(expression, addParentheses); + quiz_assert_print_if_failure(e.isIdenticalTo(r), expression); +} + +void assert_parsed_expression_with_user_parentheses_is(const char * expression, Poincare::Expression r) { return assert_parsed_expression_is(expression, r, true); } + +QUIZ_CASE(poincare_parsing_tokenize_numbers) { assert_tokenizes_as_number("1"); assert_tokenizes_as_number("12"); assert_tokenizes_as_number("123"); @@ -69,28 +75,11 @@ QUIZ_CASE(poincare_parser_tokenize_numbers) { assert_tokenizes_as_undefined_token("1ᴇ2ᴇ4"); } -QUIZ_CASE(poincare_parser_parse_numbers) { +QUIZ_CASE(poincare_parsing_memory_exhaustion) { int initialPoolSize = pool_size(); - assert_parsed_expression_type("2+3", ExpressionNode::Type::Addition); + assert_parsed_expression_is("2+3",Addition::Builder(Rational::Builder(2), Rational::Builder(3))); assert_pool_size(initialPoolSize); - // Parse digits - assert_parsed_expression_is("0", Rational::Builder(0)); - assert_parsed_expression_is("0.1", Decimal::Builder(0.1)); - assert_parsed_expression_is("1.", Rational::Builder(1)); - assert_parsed_expression_is(".1", Decimal::Builder(0.1)); - assert_parsed_expression_is("0ᴇ2", Decimal::Builder(0.0)); - assert_parsed_expression_is("0.1ᴇ2", Decimal::Builder(10.0)); - assert_parsed_expression_is("1.ᴇ2", Decimal::Builder(100.0)); - assert_parsed_expression_is(".1ᴇ2", Decimal::Builder(10.0)); - assert_parsed_expression_is("0ᴇ-2", Decimal::Builder(0.0)); - assert_parsed_expression_is("0.1ᴇ-2", Decimal::Builder(0.001)); - assert_parsed_expression_is("1.ᴇ-2", Decimal::Builder(0.01)); - assert_parsed_expression_is(".1ᴇ-2", Decimal::Builder(0.001)); -} - -QUIZ_CASE(poincare_parser_memory_exhaustion) { - int initialPoolSize = pool_size(); int memoryFailureHasBeenHandled = false; { Poincare::ExceptionCheckpoint ecp; @@ -113,7 +102,53 @@ QUIZ_CASE(poincare_parser_memory_exhaustion) { * ruining everything */ } -QUIZ_CASE(poincare_parser_parse) { +QUIZ_CASE(poincare_parsing_parse_numbers) { + // Parse decimal + assert_parsed_expression_is("0", Rational::Builder(0)); + assert_parsed_expression_is("0.1", Decimal::Builder(0.1)); + assert_parsed_expression_is("1.", Rational::Builder(1)); + assert_parsed_expression_is(".1", Decimal::Builder(0.1)); + assert_parsed_expression_is("0ᴇ2", Decimal::Builder(0.0)); + assert_parsed_expression_is("0.1ᴇ2", Decimal::Builder(10.0)); + assert_parsed_expression_is("1.ᴇ2", Decimal::Builder(100.0)); + assert_parsed_expression_is(".1ᴇ2", Decimal::Builder(10.0)); + assert_parsed_expression_is("0ᴇ-2", Decimal::Builder(0.0)); + assert_parsed_expression_is("0.1ᴇ-2", Decimal::Builder(0.001)); + assert_parsed_expression_is("1.ᴇ-2", Decimal::Builder(0.01)); + assert_parsed_expression_is(".1ᴇ-2", Decimal::Builder(0.001)); + // Decimal with rounding when digits are above 14 + assert_parsed_expression_is("0.0000012345678901234", Decimal::Builder(Integer("12345678901234"), -6)); + assert_parsed_expression_is("0.00000123456789012345", Decimal::Builder(Integer("12345678901235"), -6)); + assert_parsed_expression_is("0.00000123456789012341", Decimal::Builder(Integer("12345678901234"), -6)); + assert_parsed_expression_is("1234567890123.4", Decimal::Builder(Integer("12345678901234"), 12)); + assert_parsed_expression_is("123456789012345.2", Decimal::Builder(Integer("12345678901235"), 14)); + assert_parsed_expression_is("123456789012341.2", Decimal::Builder(Integer("12345678901234"), 14)); + assert_parsed_expression_is("12.34567", Decimal::Builder(Integer("1234567"), 1)); + assert_parsed_expression_is(".999999999999990", Decimal::Builder(Integer("99999999999999"), -1)); + assert_parsed_expression_is("9.99999999999994", Decimal::Builder(Integer("99999999999999"), 0)); + assert_parsed_expression_is("99.9999999999995", Decimal::Builder(Integer("100000000000000"), 2)); + assert_parsed_expression_is("999.999999999999", Decimal::Builder(Integer("100000000000000"), 3)); + assert_parsed_expression_is("9999.99199999999", Decimal::Builder(Integer("99999920000000"), 3)); + assert_parsed_expression_is("99299.9999999999", Decimal::Builder(Integer("99300000000000"), 4)); + + // Parse integer + assert_parsed_expression_is("123456789012345678765434567", Rational::Builder("123456789012345678765434567")); + assert_parsed_expression_is(MaxIntegerString(), Rational::Builder(MaxIntegerString())); + + // Integer parsed in Decimal because they overflow Integer + assert_parsed_expression_is(OverflowedIntegerString(), Decimal::Builder(Integer("17976931348623"), 308)); + assert_parsed_expression_is("179769313486235590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137216", Decimal::Builder(Integer("17976931348624"), 308)); + + // Infinity + assert_parsed_expression_is("23ᴇ1000", Infinity::Builder(false)); + assert_parsed_expression_is("2.3ᴇ1000", Decimal::Builder(Integer(23), 1000)); + + // Zero + assert_parsed_expression_is("0.23ᴇ-1000", Decimal::Builder(Integer(0), 0)); + assert_parsed_expression_is("0.23ᴇ-999", Decimal::Builder(Integer(23), -1000)); +} + +QUIZ_CASE(poincare_parsing_parse) { assert_parsed_expression_is("1", Rational::Builder(1)); assert_parsed_expression_is("(1)", Parenthesis::Builder(Rational::Builder(1))); assert_parsed_expression_is("((1))", Parenthesis::Builder((Expression)Parenthesis::Builder(Rational::Builder(1)))); @@ -136,8 +171,8 @@ QUIZ_CASE(poincare_parser_parse) { assert_parsed_expression_is("1^2", Power::Builder(Rational::Builder(1),Rational::Builder(2))); assert_parsed_expression_is("1^2^3", Power::Builder(Rational::Builder(1),Power::Builder(Rational::Builder(2),Rational::Builder(3)))); assert_parsed_expression_is("1=2", Equal::Builder(Rational::Builder(1),Rational::Builder(2))); - assert_raises_parsing_error("=5"); - assert_raises_parsing_error("1=2=3"); + assert_text_not_parsable("=5"); + assert_text_not_parsable("1=2=3"); assert_parsed_expression_is("-1", Opposite::Builder(Rational::Builder(1))); assert_parsed_expression_is("(-1)", Parenthesis::Builder(Opposite::Builder(Rational::Builder(1)))); assert_parsed_expression_is("1-2", Subtraction::Builder(Rational::Builder(1),Rational::Builder(2))); @@ -154,6 +189,7 @@ QUIZ_CASE(poincare_parser_parse) { assert_parsed_expression_is("2--2+-1", Addition::Builder(Subtraction::Builder(Rational::Builder(2),Opposite::Builder(Rational::Builder(2))),Opposite::Builder(Rational::Builder(1)))); assert_parsed_expression_is("2--2Γ—-1", Subtraction::Builder(Rational::Builder(2),Opposite::Builder(MultiplicationExplicite::Builder(Rational::Builder(2),Opposite::Builder(Rational::Builder(1)))))); assert_parsed_expression_is("-1^2", Opposite::Builder(Power::Builder(Rational::Builder(1),Rational::Builder(2)))); + assert_parsed_expression_is("2β„―^(3)", MultiplicationImplicite::Builder(Rational::Builder(2),Power::Builder(Constant::Builder(UCodePointScriptSmallE),Parenthesis::Builder(Rational::Builder(3))))); assert_parsed_expression_is("2/-3/-4", Division::Builder(Division::Builder(Rational::Builder(2),Opposite::Builder(Rational::Builder(3))),Opposite::Builder(Rational::Builder(4)))); assert_parsed_expression_is("1Γ—2-3Γ—4", Subtraction::Builder(MultiplicationExplicite::Builder(Rational::Builder(1),Rational::Builder(2)),MultiplicationExplicite::Builder(Rational::Builder(3),Rational::Builder(4)))); assert_parsed_expression_is("-1Γ—2", Opposite::Builder(MultiplicationExplicite::Builder(Rational::Builder(1), Rational::Builder(2)))); @@ -174,22 +210,22 @@ QUIZ_CASE(poincare_parser_parse) { assert_parsed_expression_is("1!^2", Power::Builder(Factorial::Builder(Rational::Builder(1)),Rational::Builder(2))); assert_parsed_expression_is("1!^2!", Power::Builder(Factorial::Builder(Rational::Builder(1)),Factorial::Builder(Rational::Builder(2)))); assert_parsed_expression_is("(1)!", Factorial::Builder(Parenthesis::Builder(Rational::Builder(1)))); - assert_raises_parsing_error("1+"); - assert_raises_parsing_error(")"); - assert_raises_parsing_error(")("); - assert_raises_parsing_error("()"); - assert_raises_parsing_error("(1"); - assert_raises_parsing_error("1)"); - assert_raises_parsing_error("1++2"); - assert_raises_parsing_error("1//2"); - assert_raises_parsing_error("Γ—1"); - assert_raises_parsing_error("1^^2"); - assert_raises_parsing_error("^1"); - assert_raises_parsing_error("t0000000"); - assert_raises_parsing_error("[[t0000000["); - assert_raises_parsing_error("0β†’x=0"); - assert_raises_parsing_error("0=0β†’x"); - assert_raises_parsing_error("1ᴇ2ᴇ3"); + assert_text_not_parsable("1+"); + assert_text_not_parsable(")"); + assert_text_not_parsable(")("); + assert_text_not_parsable("()"); + assert_text_not_parsable("(1"); + assert_text_not_parsable("1)"); + assert_text_not_parsable("1++2"); + assert_text_not_parsable("1//2"); + assert_text_not_parsable("Γ—1"); + assert_text_not_parsable("1^^2"); + assert_text_not_parsable("^1"); + assert_text_not_parsable("t0000000"); + assert_text_not_parsable("[[t0000000["); + assert_text_not_parsable("0β†’x=0"); + assert_text_not_parsable("0=0β†’x"); + assert_text_not_parsable("1ᴇ2ᴇ3"); } Matrix BuildMatrix(int rows, int columns, Expression entries[]) { @@ -205,7 +241,7 @@ Matrix BuildMatrix(int rows, int columns, Expression entries[]) { return m; } -QUIZ_CASE(poincare_parser_matrices) { +QUIZ_CASE(poincare_parsing_matrices) { Expression m1[] = {Rational::Builder(1)}; assert_parsed_expression_is("[[1]]", BuildMatrix(1,1,m1)); Expression m2[] = {Rational::Builder(1),Rational::Builder(2),Rational::Builder(3)}; @@ -214,23 +250,23 @@ QUIZ_CASE(poincare_parser_matrices) { assert_parsed_expression_is("[[1,2,3][4,5,6]]", BuildMatrix(2,3,m3)); Expression m4[] = {Rational::Builder(1), BuildMatrix(1,1,m1)}; assert_parsed_expression_is("[[1,[[1]]]]", BuildMatrix(1,2,m4)); - assert_raises_parsing_error("["); - assert_raises_parsing_error("]"); - assert_raises_parsing_error("[["); - assert_raises_parsing_error("]["); - assert_raises_parsing_error("[]"); - assert_raises_parsing_error("[1]"); - assert_raises_parsing_error("[[1,2],[3]]"); - assert_raises_parsing_error("[[]"); - assert_raises_parsing_error("[[1]"); - assert_raises_parsing_error("[1]]"); - assert_raises_parsing_error("[[,]]"); - assert_raises_parsing_error("[[1,]]"); - assert_raises_parsing_error(","); - assert_raises_parsing_error("[,]"); + assert_text_not_parsable("["); + assert_text_not_parsable("]"); + assert_text_not_parsable("[["); + assert_text_not_parsable("]["); + assert_text_not_parsable("[]"); + assert_text_not_parsable("[1]"); + assert_text_not_parsable("[[1,2],[3]]"); + assert_text_not_parsable("[[]"); + assert_text_not_parsable("[[1]"); + assert_text_not_parsable("[1]]"); + assert_text_not_parsable("[[,]]"); + assert_text_not_parsable("[[1,]]"); + assert_text_not_parsable(","); + assert_text_not_parsable("[,]"); } -QUIZ_CASE(poincare_parser_symbols_and_functions) { +QUIZ_CASE(poincare_parsing_symbols_and_functions) { // User-defined symbols assert_parsed_expression_is("a", Symbol::Builder("a", 1)); assert_parsed_expression_is("x", Symbol::Builder("x", 1)); @@ -240,8 +276,8 @@ QUIZ_CASE(poincare_parser_symbols_and_functions) { assert_parsed_expression_is("tot12", Symbol::Builder("tot12", 5)); assert_parsed_expression_is("TOto", Symbol::Builder("TOto", 4)); assert_parsed_expression_is("TO12_Or", Symbol::Builder("TO12_Or", 7)); - assert_raises_parsing_error("_a"); - assert_raises_parsing_error("abcdefgh"); + assert_text_not_parsable("_a"); + assert_text_not_parsable("abcdefgh"); // User-defined functions assert_parsed_expression_is("f(x)", Function::Builder("f", 1, Symbol::Builder("x",1))); @@ -251,9 +287,9 @@ QUIZ_CASE(poincare_parser_symbols_and_functions) { assert_parsed_expression_is("f(g(x))", Function::Builder("f", 1, Function::Builder("g", 1, Symbol::Builder("x",1)))); assert_parsed_expression_is("f(g(1))", Function::Builder("f", 1, Function::Builder("g", 1, Rational::Builder(1)))); assert_parsed_expression_is("f((1))", Function::Builder("f", 1, Parenthesis::Builder(Rational::Builder(1)))); - assert_raises_parsing_error("f(1,2)"); - assert_raises_parsing_error("f(f)"); - assert_raises_parsing_error("abcdefgh(1)"); + assert_text_not_parsable("f(1,2)"); + assert_text_not_parsable("f(f)"); + assert_text_not_parsable("abcdefgh(1)"); // Reserved symbols assert_parsed_expression_is("ans", Symbol::Builder("ans", 3)); @@ -263,8 +299,8 @@ QUIZ_CASE(poincare_parser_symbols_and_functions) { assert_parsed_expression_is(Infinity::Name(), Infinity::Builder(false)); assert_parsed_expression_is(Undefined::Name(), Undefined::Builder()); - assert_raises_parsing_error("u"); - assert_raises_parsing_error("v"); + assert_text_not_parsable("u"); + assert_text_not_parsable("v"); // Reserved functions assert_parsed_expression_is("acos(1)", ArcCosine::Builder(Rational::Builder(1))); @@ -278,7 +314,7 @@ QUIZ_CASE(poincare_parser_symbols_and_functions) { assert_parsed_expression_is("binomial(2,1)", BinomialCoefficient::Builder(Rational::Builder(2),Rational::Builder(1))); assert_parsed_expression_is("ceil(1)", Ceiling::Builder(Rational::Builder(1))); assert_parsed_expression_is("confidence(1,2)", ConfidenceInterval::Builder(Rational::Builder(1),Rational::Builder(2))); - assert_raises_parsing_error("diff(1,2,3)"); + assert_text_not_parsable("diff(1,2,3)"); assert_parsed_expression_is("diff(1,x,3)", Derivative::Builder(Rational::Builder(1),Symbol::Builder("x",1),Rational::Builder(3))); assert_parsed_expression_is("dim(1)", MatrixDimension::Builder(Rational::Builder(1))); assert_parsed_expression_is("conj(1)", Conjugate::Builder(Rational::Builder(1))); @@ -291,7 +327,7 @@ QUIZ_CASE(poincare_parser_symbols_and_functions) { assert_parsed_expression_is("gcd(1,2)", GreatCommonDivisor::Builder(Rational::Builder(1),Rational::Builder(2))); assert_parsed_expression_is("im(1)", ImaginaryPart::Builder(Rational::Builder(1))); assert_parsed_expression_is("int(1,x,2,3)", Integral::Builder(Rational::Builder(1),Symbol::Builder("x",1),Rational::Builder(2),Rational::Builder(3))); - assert_raises_parsing_error("int(1,2,3,4)"); + assert_text_not_parsable("int(1,2,3,4)"); assert_parsed_expression_is("inverse(1)", MatrixInverse::Builder(Rational::Builder(1))); assert_parsed_expression_is("lcm(1,2)", LeastCommonMultiple::Builder(Rational::Builder(1),Rational::Builder(2))); assert_parsed_expression_is("ln(1)", NaperianLogarithm::Builder(Rational::Builder(1))); @@ -302,7 +338,7 @@ QUIZ_CASE(poincare_parser_symbols_and_functions) { assert_parsed_expression_is("prediction95(1,2)", PredictionInterval::Builder(Rational::Builder(1),Rational::Builder(2))); assert_parsed_expression_is("prediction(1,2)", SimplePredictionInterval::Builder(Rational::Builder(1),Rational::Builder(2))); assert_parsed_expression_is("product(1,n,2,3)", Product::Builder(Rational::Builder(1),Symbol::Builder("n",1),Rational::Builder(2),Rational::Builder(3))); - assert_raises_parsing_error("product(1,2,3,4)"); + assert_text_not_parsable("product(1,2,3,4)"); assert_parsed_expression_is("quo(1,2)", DivisionQuotient::Builder(Rational::Builder(1),Rational::Builder(2))); assert_parsed_expression_is("random()", Random::Builder()); assert_parsed_expression_is("randint(1,2)", Randint::Builder(Rational::Builder(1),Rational::Builder(2))); @@ -311,19 +347,20 @@ QUIZ_CASE(poincare_parser_symbols_and_functions) { assert_parsed_expression_is("root(1,2)", NthRoot::Builder(Rational::Builder(1),Rational::Builder(2))); assert_parsed_expression_is("round(1,2)", Round::Builder(Rational::Builder(1),Rational::Builder(2))); assert_parsed_expression_is("sin(1)", Sine::Builder(Rational::Builder(1))); + assert_parsed_expression_is("sign(1)", SignFunction::Builder(Rational::Builder(1))); assert_parsed_expression_is("sinh(1)", HyperbolicSine::Builder(Rational::Builder(1))); assert_parsed_expression_is("sum(1,n,2,3)", Sum::Builder(Rational::Builder(1),Symbol::Builder("n",1),Rational::Builder(2),Rational::Builder(3))); - assert_raises_parsing_error("sum(1,2,3,4)"); + assert_text_not_parsable("sum(1,2,3,4)"); assert_parsed_expression_is("tan(1)", Tangent::Builder(Rational::Builder(1))); assert_parsed_expression_is("tanh(1)", HyperbolicTangent::Builder(Rational::Builder(1))); assert_parsed_expression_is("trace(1)", MatrixTrace::Builder(Rational::Builder(1))); assert_parsed_expression_is("transpose(1)", MatrixTranspose::Builder(Rational::Builder(1))); assert_parsed_expression_is("√(1)", SquareRoot::Builder(Rational::Builder(1))); - assert_raises_parsing_error("cos(1,2)"); - assert_raises_parsing_error("log(1,2,3)"); + assert_text_not_parsable("cos(1,2)"); + assert_text_not_parsable("log(1,2,3)"); } -QUIZ_CASE(poincare_parser_parse_store) { +QUIZ_CASE(poincare_parsing_parse_store) { assert_parsed_expression_is("1β†’a", Store::Builder(Rational::Builder(1),Symbol::Builder("a",1))); assert_parsed_expression_is("1β†’e", Store::Builder(Rational::Builder(1),Symbol::Builder("e",1))); assert_parsed_expression_is("1β†’f(x)", Store::Builder(Rational::Builder(1),Function::Builder("f",1,Symbol::Builder("x",1)))); @@ -331,87 +368,68 @@ QUIZ_CASE(poincare_parser_parse_store) { assert_parsed_expression_is("nβ†’f(x)", Store::Builder(Symbol::Builder("n",1),Function::Builder("f",1,Symbol::Builder("x",1)))); Expression m0[] = {Symbol::Builder('x')}; assert_parsed_expression_is("[[x]]β†’f(x)", Store::Builder(BuildMatrix(1,1,m0), Function::Builder("f", 1, Symbol::Builder('x')))); - assert_raises_parsing_error("aβ†’bβ†’c"); - assert_raises_parsing_error("1β†’2"); - assert_raises_parsing_error("1β†’"); - assert_raises_parsing_error("β†’2"); - assert_raises_parsing_error("(1β†’a)"); - assert_raises_parsing_error("1β†’u(n)"); - assert_raises_parsing_error("1β†’u(n+1)"); - assert_raises_parsing_error("1β†’v(n)"); - assert_raises_parsing_error("1β†’v(n+1)"); - assert_raises_parsing_error("1β†’u_{n}"); - assert_raises_parsing_error("1β†’u_{n+1}"); - assert_raises_parsing_error("1β†’v_{n}"); - assert_raises_parsing_error("1β†’v_{n+1}"); - assert_raises_parsing_error("1β†’inf"); - assert_raises_parsing_error("1β†’undef"); - assert_raises_parsing_error("1β†’Ο€"); - assert_raises_parsing_error("1→𝐒"); - assert_raises_parsing_error("1β†’β„―"); - assert_raises_parsing_error("1β†’\1"); // UnknownX - assert_raises_parsing_error("1β†’\2"); // UnknownN - assert_raises_parsing_error("1β†’acos"); - assert_raises_parsing_error("1β†’f(2)"); - assert_raises_parsing_error("1β†’f(f)"); - assert_raises_parsing_error("1β†’ans"); - assert_raises_parsing_error("ansβ†’ans"); + assert_text_not_parsable("aβ†’bβ†’c"); + assert_text_not_parsable("1β†’2"); + assert_text_not_parsable("1β†’"); + assert_text_not_parsable("β†’2"); + assert_text_not_parsable("(1β†’a)"); + assert_text_not_parsable("1β†’u(n)"); + assert_text_not_parsable("1β†’u(n+1)"); + assert_text_not_parsable("1β†’v(n)"); + assert_text_not_parsable("1β†’v(n+1)"); + assert_text_not_parsable("1β†’u_{n}"); + assert_text_not_parsable("1β†’u_{n+1}"); + assert_text_not_parsable("1β†’v_{n}"); + assert_text_not_parsable("1β†’v_{n+1}"); + assert_text_not_parsable("1β†’inf"); + assert_text_not_parsable("1β†’undef"); + assert_text_not_parsable("1β†’Ο€"); + assert_text_not_parsable("1→𝐒"); + assert_text_not_parsable("1β†’β„―"); + assert_text_not_parsable("1β†’\1"); // UnknownX + assert_text_not_parsable("1β†’\2"); // UnknownN + assert_text_not_parsable("1β†’acos"); + assert_text_not_parsable("1β†’f(2)"); + assert_text_not_parsable("1β†’f(f)"); + assert_text_not_parsable("3β†’f(g(4))"); + assert_text_not_parsable("1β†’ans"); + assert_text_not_parsable("ansβ†’ans"); } -QUIZ_CASE(poincare_parser_implicit_multiplication) { - assert_raises_parsing_error(".1.2"); - assert_raises_parsing_error("1 2"); - assert_parsed_expression_is("1x", MultiplicationExplicite::Builder(Rational::Builder(1),Symbol::Builder("x", 1))); - assert_parsed_expression_is("1ans", MultiplicationExplicite::Builder(Rational::Builder(1),Symbol::Builder("ans", 3))); +QUIZ_CASE(poincare_parsing_implicit_multiplication) { + assert_text_not_parsable(".1.2"); + assert_text_not_parsable("1 2"); + assert_parsed_expression_is("1x", MultiplicationImplicite::Builder(Rational::Builder(1),Symbol::Builder("x", 1))); + assert_parsed_expression_is("1ans", MultiplicationImplicite::Builder(Rational::Builder(1),Symbol::Builder("ans", 3))); assert_parsed_expression_is("x1", Symbol::Builder("x1", 2)); - assert_parsed_expression_is("1x+2", Addition::Builder(MultiplicationExplicite::Builder(Rational::Builder(1),Symbol::Builder("x", 1)),Rational::Builder(2))); - assert_parsed_expression_is("1Ο€", MultiplicationExplicite::Builder(Rational::Builder(1),Constant::Builder(UCodePointGreekSmallLetterPi))); - assert_parsed_expression_is("1x-2", Subtraction::Builder(MultiplicationExplicite::Builder(Rational::Builder(1),Symbol::Builder("x", 1)),Rational::Builder(2))); - assert_parsed_expression_is("-1x", Opposite::Builder(MultiplicationExplicite::Builder(Rational::Builder(1),Symbol::Builder("x", 1)))); - assert_parsed_expression_is("2Γ—1x", MultiplicationExplicite::Builder(Rational::Builder(2),MultiplicationExplicite::Builder(Rational::Builder(1),Symbol::Builder("x", 1)))); - assert_parsed_expression_is("2^1x", MultiplicationExplicite::Builder(Power::Builder(Rational::Builder(2),Rational::Builder(1)),Symbol::Builder("x", 1))); - assert_parsed_expression_is("1x^2", MultiplicationExplicite::Builder(Rational::Builder(1),Power::Builder(Symbol::Builder("x", 1),Rational::Builder(2)))); - assert_parsed_expression_is("2/1x", Division::Builder(Rational::Builder(2),MultiplicationExplicite::Builder(Rational::Builder(1),Symbol::Builder("x", 1)))); - assert_parsed_expression_is("1x/2", Division::Builder(MultiplicationExplicite::Builder(Rational::Builder(1),Symbol::Builder("x", 1)),Rational::Builder(2))); - assert_parsed_expression_is("(1)2", MultiplicationExplicite::Builder(Parenthesis::Builder(Rational::Builder(1)),Rational::Builder(2))); - assert_parsed_expression_is("1(2)", MultiplicationExplicite::Builder(Rational::Builder(1),Parenthesis::Builder(Rational::Builder(2)))); - assert_parsed_expression_is("sin(1)2", MultiplicationExplicite::Builder(Sine::Builder(Rational::Builder(1)),Rational::Builder(2))); - assert_parsed_expression_is("1cos(2)", MultiplicationExplicite::Builder(Rational::Builder(1),Cosine::Builder(Rational::Builder(2)))); - assert_parsed_expression_is("1!2", MultiplicationExplicite::Builder(Factorial::Builder(Rational::Builder(1)),Rational::Builder(2))); - assert_parsed_expression_is("2β„―^(3)", MultiplicationExplicite::Builder(Rational::Builder(2),Power::Builder(Constant::Builder(UCodePointScriptSmallE),Parenthesis::Builder(Rational::Builder(3))))); + assert_parsed_expression_is("1x+2", Addition::Builder(MultiplicationImplicite::Builder(Rational::Builder(1),Symbol::Builder("x", 1)),Rational::Builder(2))); + assert_parsed_expression_is("1Ο€", MultiplicationImplicite::Builder(Rational::Builder(1),Constant::Builder(UCodePointGreekSmallLetterPi))); + assert_parsed_expression_is("1x-2", Subtraction::Builder(MultiplicationImplicite::Builder(Rational::Builder(1),Symbol::Builder("x", 1)),Rational::Builder(2))); + assert_parsed_expression_is("-1x", Opposite::Builder(MultiplicationImplicite::Builder(Rational::Builder(1),Symbol::Builder("x", 1)))); + assert_parsed_expression_is("2Γ—1x", MultiplicationExplicite::Builder(Rational::Builder(2),MultiplicationImplicite::Builder(Rational::Builder(1),Symbol::Builder("x", 1)))); + assert_parsed_expression_is("2^1x", MultiplicationImplicite::Builder(Power::Builder(Rational::Builder(2),Rational::Builder(1)),Symbol::Builder("x", 1))); + assert_parsed_expression_is("1x^2", MultiplicationImplicite::Builder(Rational::Builder(1),Power::Builder(Symbol::Builder("x", 1),Rational::Builder(2)))); + assert_parsed_expression_is("2/1x", Division::Builder(Rational::Builder(2),MultiplicationImplicite::Builder(Rational::Builder(1),Symbol::Builder("x", 1)))); + assert_parsed_expression_is("1x/2", Division::Builder(MultiplicationImplicite::Builder(Rational::Builder(1),Symbol::Builder("x", 1)),Rational::Builder(2))); + assert_parsed_expression_is("(1)2", MultiplicationImplicite::Builder(Parenthesis::Builder(Rational::Builder(1)),Rational::Builder(2))); + assert_parsed_expression_is("1(2)", MultiplicationImplicite::Builder(Rational::Builder(1),Parenthesis::Builder(Rational::Builder(2)))); + assert_parsed_expression_is("sin(1)2", MultiplicationImplicite::Builder(Sine::Builder(Rational::Builder(1)),Rational::Builder(2))); + assert_parsed_expression_is("1cos(2)", MultiplicationImplicite::Builder(Rational::Builder(1),Cosine::Builder(Rational::Builder(2)))); + assert_parsed_expression_is("1!2", MultiplicationImplicite::Builder(Factorial::Builder(Rational::Builder(1)),Rational::Builder(2))); + assert_parsed_expression_is("2β„―^(3)", MultiplicationImplicite::Builder(Rational::Builder(2),Power::Builder(Constant::Builder(UCodePointScriptSmallE),Parenthesis::Builder(Rational::Builder(3))))); Expression m1[] = {Rational::Builder(1)}; Matrix M1 = BuildMatrix(1,1,m1); Expression m2[] = {Rational::Builder(2)}; Matrix M2 = BuildMatrix(1,1,m2); - assert_parsed_expression_is("[[1]][[2]]", MultiplicationExplicite::Builder(M1,M2)); + assert_parsed_expression_is("[[1]][[2]]", MultiplicationImplicite::Builder(M1,M2)); } -QUIZ_CASE(poincare_parser_expression_evaluation) { - assert_parsed_expression_evaluates_to("-0", "0"); - assert_parsed_expression_evaluates_to("-0.1", "-0.1"); - assert_parsed_expression_evaluates_to("-1.", "-1"); - assert_parsed_expression_evaluates_to("-.1", "-0.1"); - assert_parsed_expression_evaluates_to("-0ᴇ2", "0"); - assert_parsed_expression_evaluates_to("-0.1ᴇ2", "-10"); - assert_parsed_expression_evaluates_to("-1.ᴇ2", "-100"); - assert_parsed_expression_evaluates_to("-.1ᴇ2", "-10"); - assert_parsed_expression_evaluates_to("-0ᴇ-2", "0"); - assert_parsed_expression_evaluates_to("-0.1ᴇ-2", "-0.001"); - assert_parsed_expression_evaluates_to("-1.ᴇ-2", "-0.01"); - assert_parsed_expression_evaluates_to("-.1ᴇ-2", "-0.001"); - - assert_parsed_expression_evaluates_to("-2-3", "-5"); - assert_parsed_expression_evaluates_to("1.2Γ—β„―^(1)", "3.261938"); - assert_parsed_expression_evaluates_to("2β„―^(3)", "40.1711", System, Radian, Cartesian, 6); // WARNING: the 7th significant digit is wrong on blackbos simulator - assert_parsed_expression_evaluates_to("β„―^2Γ—β„―^(1)", "20.0855", System, Radian, Cartesian, 6); // WARNING: the 7th significant digit is wrong on simulator - assert_parsed_expression_evaluates_to("β„―^2Γ—β„―^(1)", "20.085536923188"); - assert_parsed_expression_evaluates_to("2Γ—3^4+2", "164"); - assert_parsed_expression_evaluates_to("-2Γ—3^4+2", "-160"); - assert_parsed_expression_evaluates_to("-sin(3)Γ—2-3", "-3.2822400161197", System, Radian); - assert_parsed_expression_evaluates_to("-.003", "-0.003"); - assert_parsed_expression_evaluates_to(".02ᴇ2", "2"); - assert_parsed_expression_evaluates_to("5-2/3", "4.333333"); - assert_parsed_expression_evaluates_to("2/3-5", "-4.3333333333333"); - assert_parsed_expression_evaluates_to("-2/3-5", "-5.666667"); - assert_parsed_expression_evaluates_to("sin(3)2(4+2)", "1.6934400967184", System, Radian); - assert_parsed_expression_evaluates_to("4/2Γ—(2+3)", "10"); - assert_parsed_expression_evaluates_to("4/2Γ—(2+3)", "10"); +QUIZ_CASE(poincare_parsing_adding_missing_parentheses) { + assert_parsed_expression_with_user_parentheses_is("1+-2", Addition::Builder(Rational::Builder(1),Parenthesis::Builder(Opposite::Builder(Rational::Builder(2))))); + assert_parsed_expression_with_user_parentheses_is("1--2", Subtraction::Builder(Rational::Builder(1),Parenthesis::Builder(Opposite::Builder(Rational::Builder(2))))); + assert_parsed_expression_with_user_parentheses_is("1+conj(-2)", Addition::Builder(Rational::Builder(1),Parenthesis::Builder(Conjugate::Builder(Opposite::Builder(Rational::Builder(2)))))); + assert_parsed_expression_with_user_parentheses_is("1-conj(-2)", Subtraction::Builder(Rational::Builder(1),Parenthesis::Builder(Conjugate::Builder(Opposite::Builder(Rational::Builder(2)))))); + assert_parsed_expression_with_user_parentheses_is("3conj(1+𝐒)", MultiplicationImplicite::Builder(Rational::Builder(3), Parenthesis::Builder(Conjugate::Builder(Addition::Builder(Rational::Builder(1), Constant::Builder(UCodePointMathematicalBoldSmallI)))))); + assert_parsed_expression_with_user_parentheses_is("2Γ—-3", MultiplicationExplicite::Builder(Rational::Builder(2), Parenthesis::Builder(Opposite::Builder(Rational::Builder(3))))); + assert_parsed_expression_with_user_parentheses_is("2Γ—-3", MultiplicationExplicite::Builder(Rational::Builder(2), Parenthesis::Builder(Opposite::Builder(Rational::Builder(3))))); + assert_parsed_expression_with_user_parentheses_is("--2", Opposite::Builder(Parenthesis::Builder(Opposite::Builder(Rational::Builder(2))))); + assert_parsed_expression_with_user_parentheses_is("\u00122/3\u0013^2", Power::Builder(Parenthesis::Builder(Division::Builder(Rational::Builder(2), Rational::Builder(3))), Rational::Builder(2))); } diff --git a/poincare/test/power.cpp b/poincare/test/power.cpp deleted file mode 100644 index 739fb31df..000000000 --- a/poincare/test/power.cpp +++ /dev/null @@ -1,111 +0,0 @@ -#include -#include -#include -#include -#include "helper.h" - -using namespace Poincare; - -QUIZ_CASE(poincare_power_evaluate) { - assert_parsed_expression_evaluates_to("2^3", "8"); - assert_parsed_expression_evaluates_to("(3+𝐒)^4", "28+96×𝐒"); - assert_parsed_expression_evaluates_to("4^(3+𝐒)", "11.74125+62.91378×𝐒"); - assert_parsed_expression_evaluates_to("(3+𝐒)^(3+𝐒)", "-11.898191759852+19.592921596609×𝐒"); - - assert_parsed_expression_evaluates_to("0^0", Undefined::Name()); - assert_parsed_expression_evaluates_to("0^2", "0"); - assert_parsed_expression_evaluates_to("0^(-2)", Undefined::Name()); - - assert_parsed_expression_evaluates_to("(-2)^4.2", "14.8690638497+10.8030072384×𝐒", System, Radian, Cartesian, 12); - assert_parsed_expression_evaluates_to("(-0.1)^4", "0.0001", System, Radian, Cartesian, 12); - - assert_parsed_expression_evaluates_to("0^2", "0"); - assert_parsed_expression_evaluates_to("𝐒^𝐒", "2.0787957635076ᴇ-1"); - assert_parsed_expression_evaluates_to("1.0066666666667^60", "1.48985", System, Radian, Cartesian, 6); - assert_parsed_expression_evaluates_to("1.0066666666667^60", "1.4898457083046"); - assert_parsed_expression_evaluates_to("β„―^(𝐒×π)", "-1"); - assert_parsed_expression_evaluates_to("β„―^(𝐒×π)", "-1"); - assert_parsed_expression_evaluates_to("β„―^(𝐒×π+2)", "-7.38906", System, Radian, Cartesian, 6); - assert_parsed_expression_evaluates_to("β„―^(𝐒×π+2)", "-7.3890560989307"); - assert_parsed_expression_evaluates_to("(-1)^(1/3)", "0.5+0.8660254×𝐒"); - assert_parsed_expression_evaluates_to("(-1)^(1/3)", "0.5+8.6602540378444ᴇ-1×𝐒"); - assert_parsed_expression_evaluates_to("β„―^(𝐒×π/3)", "0.5+0.8660254×𝐒"); - assert_parsed_expression_evaluates_to("β„―^(𝐒×π/3)", "0.5+8.6602540378444ᴇ-1×𝐒"); - assert_parsed_expression_evaluates_to("𝐒^(2/3)", "0.5+0.8660254×𝐒"); - assert_parsed_expression_evaluates_to("𝐒^(2/3)", "0.5+8.6602540378444ᴇ-1×𝐒"); -} - -QUIZ_CASE(poincare_power_simplify) { - assert_parsed_expression_simplify_to("3^4", "81"); - assert_parsed_expression_simplify_to("3^(-4)", "1/81"); - assert_parsed_expression_simplify_to("(-3)^3", "-27"); - assert_parsed_expression_simplify_to("1256^(1/3)Γ—x", "2Γ—root(157,3)Γ—x"); - assert_parsed_expression_simplify_to("1256^(-1/3)", "1/(2Γ—root(157,3))"); - assert_parsed_expression_simplify_to("32^(-1/5)", "1/2"); - assert_parsed_expression_simplify_to("(2+3-4)^(x)", "1"); - assert_parsed_expression_simplify_to("1^x", "1"); - assert_parsed_expression_simplify_to("x^1", "x"); - assert_parsed_expression_simplify_to("0^3", "0"); - assert_parsed_expression_simplify_to("0^0", Undefined::Name()); - assert_parsed_expression_simplify_to("0^(-3)", Undefined::Name()); - assert_parsed_expression_simplify_to("4^0.5", "2"); - assert_parsed_expression_simplify_to("8^0.5", "2Γ—βˆš(2)"); - assert_parsed_expression_simplify_to("(12^4Γ—3)^(0.5)", "144Γ—βˆš(3)"); - assert_parsed_expression_simplify_to("(Ο€^3)^4", "Ο€^12"); - assert_parsed_expression_simplify_to("(AΓ—B)^3", "A^3Γ—B^3"); - assert_parsed_expression_simplify_to("(12^4Γ—x)^(0.5)", "144Γ—βˆš(x)"); - assert_parsed_expression_simplify_to("√(32)", "4Γ—βˆš(2)"); - assert_parsed_expression_simplify_to("√(-1)", "𝐒"); - assert_parsed_expression_simplify_to("√(-1Γ—βˆš(-1))", "√(2)/2-√(2)/2×𝐒"); - assert_parsed_expression_simplify_to("√(3^2)", "3"); - assert_parsed_expression_simplify_to("2^(2+Ο€)", "4Γ—2^Ο€"); - assert_parsed_expression_simplify_to("√(5513219850886344455940081)", "2348024669991"); - assert_parsed_expression_simplify_to("√(154355776)", "12424"); - assert_parsed_expression_simplify_to("√(Ο€)^2", "Ο€"); - assert_parsed_expression_simplify_to("√(Ο€^2)", "Ο€"); - assert_parsed_expression_simplify_to("√((-Ο€)^2)", "Ο€"); - assert_parsed_expression_simplify_to("√(xΓ—144)", "12Γ—βˆš(x)"); - assert_parsed_expression_simplify_to("√(xΓ—144Γ—Ο€^2)", "12Γ—Ο€Γ—βˆš(x)"); - assert_parsed_expression_simplify_to("√(xΓ—144Γ—Ο€)", "12Γ—βˆš(Ο€)Γ—βˆš(x)"); - assert_parsed_expression_simplify_to("(-1)Γ—(2+(-4Γ—βˆš(2)))", "4Γ—βˆš(2)-2"); - assert_parsed_expression_simplify_to("x^(1/2)", "√(x)"); - assert_parsed_expression_simplify_to("x^(-1/2)", "1/√(x)"); - assert_parsed_expression_simplify_to("x^(1/7)", "root(x,7)"); - assert_parsed_expression_simplify_to("x^(-1/7)", "1/root(x,7)"); - assert_parsed_expression_simplify_to("1/(3√(2))", "√(2)/6"); - assert_parsed_expression_simplify_to("β„―^ln(3)", "3"); - assert_parsed_expression_simplify_to("β„―^ln(√(3))", "√(3)"); - assert_parsed_expression_simplify_to("Ο€^log(√(3),Ο€)", "√(3)"); - assert_parsed_expression_simplify_to("10^log(Ο€)", "Ο€"); - assert_parsed_expression_simplify_to("β„―^ln(65)", "65"); - assert_parsed_expression_simplify_to("β„―^ln(Ο€β„―)", "π×ℯ"); - assert_parsed_expression_simplify_to("β„―^log(Ο€β„―)", "β„―^(log(β„―)+log(Ο€))"); - assert_parsed_expression_simplify_to("√(β„―^2)", "β„―"); - assert_parsed_expression_simplify_to("999^(10000/3)", "999^(10000/3)"); - /* This does not reduce but should not as the integer is above - * k_maxNumberOfPrimeFactors and thus it prime decomposition might overflow - * 32 factors. */ - assert_parsed_expression_simplify_to("1881676377434183981909562699940347954480361860897069^(1/3)", "root(1881676377434183981909562699940347954480361860897069,3)"); - /* This does not reduce but should not as the prime decomposition involves - * factors above k_maxNumberOfPrimeFactors. */ - assert_parsed_expression_simplify_to("1002101470343^(1/3)", "root(1002101470343,3)"); - assert_parsed_expression_simplify_to("π×π×π", "Ο€^3"); - assert_parsed_expression_simplify_to("(x+Ο€)^(3)", "x^3+3×π×x^2+3Γ—Ο€^2Γ—x+Ο€^3"); - assert_parsed_expression_simplify_to("(5+√(2))^(-8)", "(-1003320Γ—βˆš(2)+1446241)/78310985281"); - assert_parsed_expression_simplify_to("(5Γ—Ο€+√(2))^(-5)", "1/(3125Γ—Ο€^5+3125Γ—βˆš(2)Γ—Ο€^4+2500Γ—Ο€^3+500Γ—βˆš(2)Γ—Ο€^2+100Γ—Ο€+4Γ—βˆš(2))"); - assert_parsed_expression_simplify_to("(1+√(2)+√(3))^5", "120Γ—βˆš(6)+184Γ—βˆš(3)+224Γ—βˆš(2)+296"); - assert_parsed_expression_simplify_to("(Ο€+√(2)+√(3)+x)^(-3)", "1/(x^3+3×π×x^2+3Γ—βˆš(3)Γ—x^2+3Γ—βˆš(2)Γ—x^2+3Γ—Ο€^2Γ—x+6Γ—βˆš(3)×π×x+6Γ—βˆš(2)×π×x+6Γ—βˆš(6)Γ—x+15Γ—x+Ο€^3+3Γ—βˆš(3)Γ—Ο€^2+3Γ—βˆš(2)Γ—Ο€^2+6Γ—βˆš(6)Γ—Ο€+15Γ—Ο€+9Γ—βˆš(3)+11Γ—βˆš(2))"); - assert_parsed_expression_simplify_to("1.0066666666667^60", "(10066666666667/10000000000000)^60"); - assert_parsed_expression_simplify_to("2^(6+Ο€+x)", "64Γ—2^(x+Ο€)"); - assert_parsed_expression_simplify_to("𝐒^(2/3)", "1/2+√(3)/2×𝐒"); - assert_parsed_expression_simplify_to("β„―^(𝐒×π/3)", "1/2+√(3)/2×𝐒"); - assert_parsed_expression_simplify_to("(-1)^(1/3)", "1/2+√(3)/2×𝐒"); - assert_parsed_expression_simplify_to("R(-x)", "R(-x)"); - assert_parsed_expression_simplify_to("√(x)^2", "x", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("√(-3)^2", "unreal", User, Radian, Real); - // Principal angle of root of unity - assert_parsed_expression_simplify_to("(-5)^(-1/3)", "1/(2Γ—root(5,3))-√(3)/(2Γ—root(5,3))×𝐒", User, Radian, Cartesian); - assert_parsed_expression_simplify_to("1+((8+√(6))^(1/2))^-1+(8+√(6))^(1/2)", "(√(√(6)+8)+√(6)+9)/√(√(6)+8)", User, Radian, Real); - assert_parsed_expression_simplify_to("[[1,2][3,4]]^(-3)", "[[-59/4,27/4][81/8,-37/8]]"); - assert_parsed_expression_simplify_to("[[1,2][3,4]]^3", "[[37,54][81,118]]"); -} diff --git a/poincare/test/print_float.cpp b/poincare/test/print_float.cpp new file mode 100644 index 000000000..30934e641 --- /dev/null +++ b/poincare/test/print_float.cpp @@ -0,0 +1,162 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "helper.h" + +using namespace Poincare; + +template +void assert_float_prints_to(T a, const char * result, Preferences::PrintFloatMode mode = ScientificMode, int significantDigits = 7, int bufferSize = PrintFloat::k_maxFloatBufferLength) { + constexpr int tagSize = 8; + unsigned char tag = 'O'; + char taggedBuffer[250+2*tagSize]; + memset(taggedBuffer, tag, bufferSize+2*tagSize); + char * buffer = taggedBuffer + tagSize; + + PrintFloat::convertFloatToText(a, buffer, bufferSize, significantDigits, mode); + + for (int i=0; i -#include -#include -#include -#include -#include "helper.h" - -using namespace Poincare; - -constexpr Poincare::ExpressionNode::Sign Positive = Poincare::ExpressionNode::Sign::Positive; -constexpr Poincare::ExpressionNode::Sign Negative = Poincare::ExpressionNode::Sign::Negative; -constexpr Poincare::ExpressionNode::Sign Unknown = Poincare::ExpressionNode::Sign::Unknown; - -void assert_parsed_expression_sign(const char * expression, Poincare::ExpressionNode::Sign sign, Poincare::Preferences::ComplexFormat complexFormat = Cartesian) { - Shared::GlobalContext globalContext; - Expression e = parse_expression(expression); - quiz_assert(!e.isUninitialized()); - e = e.reduce(&globalContext, complexFormat, Degree); - quiz_assert(e.sign(&globalContext) == sign); -} - -QUIZ_CASE(poincare_sign) { - assert_parsed_expression_sign("abs(-cos(2)+I)", Positive); - assert_parsed_expression_sign("2.345ᴇ-23", Positive); - assert_parsed_expression_sign("-2.345ᴇ-23", Negative); - assert_parsed_expression_sign("2Γ—(-3)Γ—abs(-32)", Negative); - assert_parsed_expression_sign("2Γ—(-3)Γ—abs(-32)Γ—cos(3)", Unknown); - assert_parsed_expression_sign("x", Unknown); - assert_parsed_expression_sign("2^(-abs(3))", Positive); - assert_parsed_expression_sign("(-2)^4", Positive); - assert_parsed_expression_sign("(-2)^3", Negative); - assert_parsed_expression_sign("random()", Positive); - assert_parsed_expression_sign("42/3", Positive); - assert_parsed_expression_sign("-23/32", Negative); - assert_parsed_expression_sign("Ο€", Positive); - assert_parsed_expression_sign("β„―", Positive); - assert_parsed_expression_sign("0", Positive); - assert_parsed_expression_sign("cos(90)", Positive); - assert_parsed_expression_sign("√(-1)", Unknown); - assert_parsed_expression_sign("√(-1)", Unknown, Real); -} - -QUIZ_CASE(poincare_polynomial_degree) { - assert_parsed_expression_polynomial_degree("x+1", 1); - assert_parsed_expression_polynomial_degree("cos(2)+1", 0); - assert_parsed_expression_polynomial_degree("confidence(0.2,10)+1", -1); - assert_parsed_expression_polynomial_degree("diff(3Γ—x+x,x,2)", -1); - assert_parsed_expression_polynomial_degree("diff(3Γ—x+x,x,x)", -1); - assert_parsed_expression_polynomial_degree("diff(3Γ—x+x,x,x)", 0, "a"); - assert_parsed_expression_polynomial_degree("(3Γ—x+2)/3", 1); - assert_parsed_expression_polynomial_degree("(3Γ—x+2)/x", -1); - assert_parsed_expression_polynomial_degree("int(2Γ—x,x, 0, 1)", -1); - assert_parsed_expression_polynomial_degree("int(2Γ—x,x, 0, 1)", 0, "a"); - assert_parsed_expression_polynomial_degree("[[1,2][3,4]]", -1); - assert_parsed_expression_polynomial_degree("(x^2+2)Γ—(x+1)", 3); - assert_parsed_expression_polynomial_degree("-(x+1)", 1); - assert_parsed_expression_polynomial_degree("(x^2+2)^(3)", 6); - assert_parsed_expression_polynomial_degree("prediction(0.2,10)+1", -1); - assert_parsed_expression_polynomial_degree("2-x-x^3", 3); - assert_parsed_expression_polynomial_degree("π×x", 1); - assert_parsed_expression_polynomial_degree("√(-1)Γ—x", -1, "x", Real); - // f: xβ†’x^2+Ο€x+1 - assert_simplify("1+π×x+x^2β†’f(x)"); - assert_parsed_expression_polynomial_degree("f(x)", 2); -} - -void assert_expression_has_characteristic_range(Expression e, float range, Preferences::AngleUnit angleUnit = Preferences::AngleUnit::Degree) { - Shared::GlobalContext globalContext; - quiz_assert(!e.isUninitialized()); - e = e.reduce(&globalContext, Preferences::ComplexFormat::Cartesian, angleUnit); - if (std::isnan(range)) { - quiz_assert(std::isnan(e.characteristicXRange(&globalContext, angleUnit))); - } else { - quiz_assert(std::fabs(e.characteristicXRange(&globalContext, angleUnit) - range) < 0.0000001f); - } -} - -QUIZ_CASE(poincare_characteristic_range) { - assert_expression_has_characteristic_range(Cosine::Builder(Symbol::Builder(UCodePointUnknownX)), 360.0f); - assert_expression_has_characteristic_range(Cosine::Builder(Opposite::Builder(Symbol::Builder(UCodePointUnknownX))), 360.0f); - assert_expression_has_characteristic_range(Cosine::Builder(Symbol::Builder(UCodePointUnknownX)), 2.0f*M_PI, Preferences::AngleUnit::Radian); - assert_expression_has_characteristic_range(Cosine::Builder(Opposite::Builder(Symbol::Builder(UCodePointUnknownX))), 2.0f*M_PI, Preferences::AngleUnit::Radian); - assert_expression_has_characteristic_range(Sine::Builder(Addition::Builder(MultiplicationExplicite::Builder(Rational::Builder(9),Symbol::Builder(UCodePointUnknownX)),Rational::Builder(10))), 40.0f); - assert_expression_has_characteristic_range(Addition::Builder(Sine::Builder(Addition::Builder(MultiplicationExplicite::Builder(Rational::Builder(9),Symbol::Builder(UCodePointUnknownX)),Rational::Builder(10))),Cosine::Builder(Division::Builder(Symbol::Builder(UCodePointUnknownX),Rational::Builder(2)))), 720.0f); - assert_expression_has_characteristic_range(Addition::Builder(Sine::Builder(Addition::Builder(MultiplicationExplicite::Builder(Rational::Builder(9),Symbol::Builder(UCodePointUnknownX)),Rational::Builder(10))),Cosine::Builder(Division::Builder(Symbol::Builder(UCodePointUnknownX),Rational::Builder(2)))), 4.0f*M_PI, Preferences::AngleUnit::Radian); - assert_expression_has_characteristic_range(Symbol::Builder(UCodePointUnknownX), NAN); - assert_expression_has_characteristic_range(Addition::Builder(Cosine::Builder(Rational::Builder(3)),Rational::Builder(2)), 0.0f); - assert_expression_has_characteristic_range(CommonLogarithm::Builder(Cosine::Builder(MultiplicationExplicite::Builder(Rational::Builder(40),Symbol::Builder(UCodePointUnknownX)))), 9.0f); - assert_expression_has_characteristic_range(Cosine::Builder((Expression)Cosine::Builder(Symbol::Builder(UCodePointUnknownX))), 360.0f); - assert_simplify("cos(x)β†’f(x)"); - assert_expression_has_characteristic_range(Function::Builder("f",1,Symbol::Builder(UCodePointUnknownX)), 360.0f); -} - -void assert_parsed_expression_has_variables(const char * expression, const char * variables[], int trueNumberOfVariables) { - Expression e = parse_expression(expression); - quiz_assert(!e.isUninitialized()); - constexpr static int k_maxVariableSize = Poincare::SymbolAbstract::k_maxNameSize; - char variableBuffer[Expression::k_maxNumberOfVariables+1][k_maxVariableSize] = {{0}}; - Shared::GlobalContext globalContext; - int numberOfVariables = e.getVariables(&globalContext, [](const char * symbol) { return true; }, (char *)variableBuffer, k_maxVariableSize); - quiz_assert(trueNumberOfVariables == numberOfVariables); - if (numberOfVariables < 0) { - // Too many variables - return; - } - int index = 0; - while (variableBuffer[index][0] != 0 || variables[index][0] != 0) { - quiz_assert(strcmp(variableBuffer[index], variables[index]) == 0); - index++; - } -} - -QUIZ_CASE(poincare_get_variables) { - const char * variableBuffer1[] = {"x","y",""}; - assert_parsed_expression_has_variables("x+y", variableBuffer1, 2); - const char * variableBuffer2[] = {"x","y","z","t",""}; - assert_parsed_expression_has_variables("x+y+z+2Γ—t", variableBuffer2, 4); - const char * variableBuffer3[] = {"a","x","y","k","A", ""}; - assert_parsed_expression_has_variables("a+x^2+2Γ—y+k!Γ—A", variableBuffer3, 5); - const char * variableBuffer4[] = {"BABA","abab", ""}; - assert_parsed_expression_has_variables("BABA+abab", variableBuffer4, 2); - const char * variableBuffer5[] = {"BBBBBB", ""}; - assert_parsed_expression_has_variables("BBBBBB", variableBuffer5, 1); - const char * variableBuffer6[] = {""}; - assert_parsed_expression_has_variables("a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p+q+r+s+t+aa+bb+cc+dd+ee+ff+gg+hh+ii+jj+kk+ll+mm+nn+oo", variableBuffer6, -1); - // f: xβ†’1+Ο€x+x^2+toto - assert_simplify("1+π×x+x^2+totoβ†’f(x)"); - const char * variableBuffer7[] = {"tata","toto", ""}; - assert_parsed_expression_has_variables("f(tata)", variableBuffer7, 2); -} - -void assert_parsed_expression_has_polynomial_coefficient(const char * expression, const char * symbolName, const char ** coefficients, Preferences::ComplexFormat complexFormat = Preferences::ComplexFormat::Cartesian, Preferences::AngleUnit angleUnit = Preferences::AngleUnit::Degree) { - Shared::GlobalContext globalContext; - Expression e = parse_expression(expression); - quiz_assert(!e.isUninitialized()); - e = e.reduce(&globalContext, complexFormat, angleUnit); - Expression coefficientBuffer[Poincare::Expression::k_maxNumberOfPolynomialCoefficients]; - int d = e.getPolynomialReducedCoefficients(symbolName, coefficientBuffer, &globalContext, complexFormat, Radian); - for (int i = 0; i <= d; i++) { - Expression f = parse_expression(coefficients[i]); - quiz_assert(!f.isUninitialized()); - coefficientBuffer[i] = coefficientBuffer[i].reduce(&globalContext, complexFormat, angleUnit); - f = f.reduce(&globalContext, complexFormat, angleUnit); - quiz_assert(coefficientBuffer[i].isIdenticalTo(f)); - } - quiz_assert(coefficients[d+1] == 0); -} - -QUIZ_CASE(poincare_get_polynomial_coefficients) { - const char * coefficient0[] = {"2", "1", "1", 0}; - assert_parsed_expression_has_polynomial_coefficient("x^2+x+2", "x", coefficient0); - const char * coefficient1[] = {"12+(-6)Γ—Ο€", "12", "3", 0}; //3Γ—x^2+12Γ—x-6Γ—Ο€+12 - assert_parsed_expression_has_polynomial_coefficient("3Γ—(x+2)^2-6Γ—Ο€", "x", coefficient1); - // TODO: decomment when enable 3-degree polynomes - //const char * coefficient2[] = {"2+32Γ—x", "2", "6", "2", 0}; //2Γ—n^3+6Γ—n^2+2Γ—n+2+32Γ—x - //assert_parsed_expression_has_polynomial_coefficient("2Γ—(n+1)^3-4n+32Γ—x", "n", coefficient2); - const char * coefficient3[] = {"1", "-Ο€", "1", 0}; //x^2-π×x+1 - assert_parsed_expression_has_polynomial_coefficient("x^2-π×x+1", "x", coefficient3); - // f: xβ†’x^2+Px+1 - const char * coefficient4[] = {"1", "Ο€", "1", 0}; //x^2+π×x+1 - assert_simplify("1+π×x+x^2β†’f(x)"); - assert_parsed_expression_has_polynomial_coefficient("f(x)", "x", coefficient4); - const char * coefficient5[] = {"0", "𝐒", 0}; //√(-1)x - assert_parsed_expression_has_polynomial_coefficient("√(-1)x", "x", coefficient5); - const char * coefficient6[] = {0}; //√(-1)x - assert_parsed_expression_has_polynomial_coefficient("√(-1)x", "x", coefficient6, Real); -} diff --git a/poincare/test/random.cpp b/poincare/test/random.cpp deleted file mode 100644 index b8dd06c3a..000000000 --- a/poincare/test/random.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include -#include -#include -#include -#include -#include "helper.h" -#include "tree/helpers.h" - -using namespace Poincare; - -QUIZ_CASE(poincare_random_simplify) { - assert_parsed_expression_simplify_to("1/random()+1/3+1/4", "1/random()+7/12"); - assert_parsed_expression_simplify_to("random()+random()", "random()+random()"); - assert_parsed_expression_simplify_to("random()-random()", "-random()+random()"); - assert_parsed_expression_simplify_to("1/random()+1/3+1/4+1/random()", "1/random()+1/random()+7/12"); - assert_parsed_expression_simplify_to("random()Γ—random()", "random()Γ—random()"); - assert_parsed_expression_simplify_to("random()/random()", "random()/random()"); - assert_parsed_expression_simplify_to("3^random()Γ—3^random()", "3^random()Γ—3^random()"); - assert_parsed_expression_simplify_to("random()Γ—ln(2)Γ—3+random()Γ—ln(2)Γ—5", "5Γ—ln(2)Γ—random()+3Γ—ln(2)Γ—random()"); -} - -QUIZ_CASE(poincare_randint_simplify) { - assert_parsed_expression_simplify_to("1/randint(2,2)+1/2", "1"); - assert_parsed_expression_simplify_to("randint(1, inf)", "undef"); - assert_parsed_expression_simplify_to("randint(-inf, 3)", "undef"); - assert_parsed_expression_simplify_to("randint(4, 3)", "undef"); -} diff --git a/poincare/test/rational.cpp b/poincare/test/rational.cpp index fd0a0589a..a38389e91 100644 --- a/poincare/test/rational.cpp +++ b/poincare/test/rational.cpp @@ -7,47 +7,7 @@ using namespace Poincare; -QUIZ_CASE(poincare_rational_constructor) { - int initialPoolSize = pool_size(); - Rational a = Rational::Builder("123","324"); - Rational b = Rational::Builder("3456"); - Rational c = Rational::Builder(123,324); - Rational d = Rational::Builder(3456789); - Integer overflow = Integer::Overflow(false); - Rational e = Rational::Builder(overflow); - Rational f = Rational::Builder(overflow, overflow); - assert_pool_size(initialPoolSize+6); -} - -static inline void assert_equal(const Rational i, const Rational j) { - quiz_assert(Rational::NaturalOrder(i, j) == 0); -} -static inline void assert_not_equal(const Rational i, const Rational j) { - quiz_assert(Rational::NaturalOrder(i, j) != 0); -} - -static inline void assert_lower(const Rational i, const Rational j) { - quiz_assert(Rational::NaturalOrder(i, j) < 0); -} - -static inline void assert_greater(const Rational i, const Rational j) { - quiz_assert(Rational::NaturalOrder(i, j) > 0); -} - -QUIZ_CASE(poincare_rational_compare) { - assert_equal(Rational::Builder(123,324), Rational::Builder(41,108)); - assert_not_equal(Rational::Builder(123,234), Rational::Builder(42, 108)); - assert_lower(Rational::Builder(123,234), Rational::Builder(456,567)); - assert_lower(Rational::Builder(-123, 234),Rational::Builder(456, 567)); - assert_greater(Rational::Builder(123, 234),Rational::Builder(-456, 567)); - assert_greater(Rational::Builder(123, 234),Rational::Builder("123456789123456789", "12345678912345678910")); -} - -QUIZ_CASE(poincare_rational_properties) { - quiz_assert(Rational::Builder(-2).sign() == ExpressionNode::Sign::Negative); - quiz_assert(Rational::Builder(-2, 3).sign() == ExpressionNode::Sign::Negative); - quiz_assert(Rational::Builder(2, 3).sign() == ExpressionNode::Sign::Positive); - quiz_assert(Rational::Builder(0, 3).sign() == ExpressionNode::Sign::Positive); +QUIZ_CASE(poincare_rational_specific_properties) { quiz_assert(Rational::Builder(0).isZero()); quiz_assert(!Rational::Builder(231).isZero()); quiz_assert(Rational::Builder(1).isOne()); @@ -85,69 +45,3 @@ QUIZ_CASE(poincare_rational_power) { assert_pow_to(Rational::Builder(4,5), Rational::Builder(3).signedIntegerNumerator(), Rational::Builder(64,125)); assert_pow_to(Rational::Builder(4,5), Rational::Builder(-3).signedIntegerNumerator(), Rational::Builder(125,64)); } - -// Simplify - -QUIZ_CASE(poincare_rational_simplify) { - // 1/MaxIntegerString() - char buffer[400] = "1/"; - strlcpy(buffer+2, MaxIntegerString(), 400-2); - assert_parsed_expression_simplify_to(buffer, buffer); - // 1/OverflowedIntegerString() - strlcpy(buffer+2, BigOverflowedIntegerString(), 400-2); - assert_parsed_expression_simplify_to(buffer, "0"); - // MaxIntegerString() - assert_parsed_expression_simplify_to(MaxIntegerString(), MaxIntegerString()); - // OverflowedIntegerString() - assert_parsed_expression_simplify_to(BigOverflowedIntegerString(), Infinity::Name()); - assert_parsed_expression_simplify_to(BigOverflowedIntegerString(), Infinity::Name()); - // -OverflowedIntegerString() - buffer[0] = '-'; - strlcpy(buffer+1, BigOverflowedIntegerString(), 400-1); - assert_parsed_expression_simplify_to(buffer, "-inf"); - - assert_parsed_expression_simplify_to("-1/3", "-1/3"); - assert_parsed_expression_simplify_to("22355/45325", "4471/9065"); - assert_parsed_expression_simplify_to("0000.000000", "0"); - assert_parsed_expression_simplify_to(".000000", "0"); - assert_parsed_expression_simplify_to("0000", "0"); - assert_parsed_expression_simplify_to("0.1234567", "1234567/10000000"); - assert_parsed_expression_simplify_to("123.4567", "1234567/10000"); - assert_parsed_expression_simplify_to("0.1234", "617/5000"); - assert_parsed_expression_simplify_to("0.1234000", "617/5000"); - assert_parsed_expression_simplify_to("001234000", "1234000"); - assert_parsed_expression_simplify_to("001.234000ᴇ3", "1234"); - assert_parsed_expression_simplify_to("001234000ᴇ-4", "617/5"); - assert_parsed_expression_simplify_to("3/4+5/4-12+1/567", "-5669/567"); - assert_parsed_expression_simplify_to("34/78+67^(-1)", "1178/2613"); - assert_parsed_expression_simplify_to("12348/34564", "3087/8641"); - assert_parsed_expression_simplify_to("1-0.3-0.7", "0"); - assert_parsed_expression_simplify_to("123456789123456789+112233445566778899", "235690234690235688"); - assert_parsed_expression_simplify_to("56^56", "79164324866862966607842406018063254671922245312646690223362402918484170424104310169552592050323456"); - assert_parsed_expression_simplify_to("999^999", "999^999"); - assert_parsed_expression_simplify_to("999^-999", "1/999^999"); - assert_parsed_expression_simplify_to("0^0", Undefined::Name()); - assert_parsed_expression_simplify_to("x^0", "1"); - assert_parsed_expression_simplify_to("Ο€^0", "1"); - assert_parsed_expression_simplify_to("A^0", "1"); - assert_parsed_expression_simplify_to("(-3)^0", "1"); -} - -QUIZ_CASE(poincare_rational_approximate) { - assert_parsed_expression_evaluates_to("1/3", "0.3333333"); - assert_parsed_expression_evaluates_to("123456/1234567", "9.9999432999586ᴇ-2"); -} - - -//Serialize - -QUIZ_CASE(poincare_rational_serialize) { - assert_parsed_expression_serialize_to(Rational::Builder(-2, 3), "-2/3"); - assert_parsed_expression_serialize_to(Rational::Builder("2345678909876"), "2345678909876"); - assert_parsed_expression_serialize_to(Rational::Builder("-2345678909876", "5"), "-2345678909876/5"); - assert_parsed_expression_serialize_to(Rational::Builder(MaxIntegerString()), MaxIntegerString()); - Integer one(1); - Integer overflow = Integer::Overflow(false); - assert_parsed_expression_serialize_to(Rational::Builder(one, overflow), "1/inf"); - assert_parsed_expression_serialize_to(Rational::Builder(overflow), Infinity::Name()); -} diff --git a/poincare/test/simplification.cpp b/poincare/test/simplification.cpp new file mode 100644 index 000000000..87bdfaab6 --- /dev/null +++ b/poincare/test/simplification.cpp @@ -0,0 +1,993 @@ +#include +#include +#include +#include +#include +#include +#include +#include "helper.h" +#include "./tree/helpers.h" + +using namespace Poincare; + +QUIZ_CASE(poincare_simplification_decimal) { + assert_parsed_expression_simplify_to("-2.3", "-23/10"); + assert_parsed_expression_simplify_to("-232.2ᴇ-4", "-1161/50000"); + assert_parsed_expression_simplify_to("0000.000000ᴇ-2", "0"); + assert_parsed_expression_simplify_to(".000000", "0"); + assert_parsed_expression_simplify_to("0000", "0"); +} + +QUIZ_CASE(poincare_simplification_rational) { + // 1/MaxIntegerString() + char buffer[400] = "1/"; + strlcpy(buffer+2, MaxIntegerString(), 400-2); + assert_parsed_expression_simplify_to(buffer, buffer); + // 1/OverflowedIntegerString() + strlcpy(buffer+2, BigOverflowedIntegerString(), 400-2); + assert_parsed_expression_simplify_to(buffer, "0"); + // MaxIntegerString() + assert_parsed_expression_simplify_to(MaxIntegerString(), MaxIntegerString()); + // OverflowedIntegerString() + assert_parsed_expression_simplify_to(BigOverflowedIntegerString(), Infinity::Name()); + assert_parsed_expression_simplify_to(BigOverflowedIntegerString(), Infinity::Name()); + // -OverflowedIntegerString() + buffer[0] = '-'; + strlcpy(buffer+1, BigOverflowedIntegerString(), 400-1); + assert_parsed_expression_simplify_to(buffer, "-inf"); + + assert_parsed_expression_simplify_to("-1/3", "-1/3"); + assert_parsed_expression_simplify_to("22355/45325", "4471/9065"); + assert_parsed_expression_simplify_to("0000.000000", "0"); + assert_parsed_expression_simplify_to(".000000", "0"); + assert_parsed_expression_simplify_to("0000", "0"); + assert_parsed_expression_simplify_to("0.1234567", "1234567/10000000"); + assert_parsed_expression_simplify_to("123.4567", "1234567/10000"); + assert_parsed_expression_simplify_to("0.1234", "617/5000"); + assert_parsed_expression_simplify_to("0.1234000", "617/5000"); + assert_parsed_expression_simplify_to("001234000", "1234000"); + assert_parsed_expression_simplify_to("001.234000ᴇ3", "1234"); + assert_parsed_expression_simplify_to("001234000ᴇ-4", "617/5"); + assert_parsed_expression_simplify_to("3/4+5/4-12+1/567", "-5669/567"); + assert_parsed_expression_simplify_to("34/78+67^(-1)", "1178/2613"); + assert_parsed_expression_simplify_to("12348/34564", "3087/8641"); + assert_parsed_expression_simplify_to("1-0.3-0.7", "0"); + assert_parsed_expression_simplify_to("123456789123456789+112233445566778899", "235690234690235688"); + assert_parsed_expression_simplify_to("56^56", "79164324866862966607842406018063254671922245312646690223362402918484170424104310169552592050323456"); + assert_parsed_expression_simplify_to("999^999", "999^999"); + assert_parsed_expression_simplify_to("999^-999", "1/999^999"); + assert_parsed_expression_simplify_to("0^0", Undefined::Name()); + assert_parsed_expression_simplify_to("x^0", "1"); + assert_parsed_expression_simplify_to("Ο€^0", "1"); + assert_parsed_expression_simplify_to("A^0", "1"); + assert_parsed_expression_simplify_to("(-3)^0", "1"); +} + +QUIZ_CASE(poincare_simplification_infinity) { + // 0 and infinity + assert_parsed_expression_simplify_to("0/0", Undefined::Name()); + assert_parsed_expression_simplify_to("0/inf", "0"); + assert_parsed_expression_simplify_to("inf/0", Undefined::Name()); + assert_parsed_expression_simplify_to("0Γ—inf", Undefined::Name()); + assert_parsed_expression_simplify_to("3Γ—inf/inf", "undef"); + assert_parsed_expression_simplify_to("1ᴇ1000", "inf"); + assert_parsed_expression_simplify_to("-1ᴇ1000", "-inf"); + assert_parsed_expression_simplify_to("-1ᴇ-1000", "0"); + assert_parsed_expression_simplify_to("1ᴇ-1000", "0"); + //assert_parsed_expression_simplify_to("1Γ—10^1000", "inf"); + + assert_parsed_expression_simplify_to("inf^0", "undef"); + assert_parsed_expression_simplify_to("1^inf", "1^inf"); + assert_parsed_expression_simplify_to("1^(X^inf)", "1^\u0012X^inf\u0013"); + assert_parsed_expression_simplify_to("inf^(-1)", "0"); + assert_parsed_expression_simplify_to("(-inf)^(-1)", "0"); + assert_parsed_expression_simplify_to("inf^(-√(2))", "0"); + assert_parsed_expression_simplify_to("(-inf)^(-√(2))", "0"); + assert_parsed_expression_simplify_to("inf^2", "inf"); + assert_parsed_expression_simplify_to("(-inf)^2", "inf"); + assert_parsed_expression_simplify_to("inf^√(2)", "inf"); + assert_parsed_expression_simplify_to("(-inf)^√(2)", "inf(-1)^√(2)"); + assert_parsed_expression_simplify_to("inf^x", "inf^x"); + assert_parsed_expression_simplify_to("1/inf+24", "24"); + assert_parsed_expression_simplify_to("β„―^(inf)/inf", "0β„―^inf"); + + // Logarithm + assert_parsed_expression_simplify_to("log(inf,0)", "undef"); + assert_parsed_expression_simplify_to("log(inf,1)", "undef"); + assert_parsed_expression_simplify_to("log(0,inf)", "undef"); + assert_parsed_expression_simplify_to("log(1,inf)", "0"); + assert_parsed_expression_simplify_to("log(inf,inf)", "undef"); + + assert_parsed_expression_simplify_to("ln(inf)", "inf"); + assert_parsed_expression_simplify_to("log(inf,-3)", "log(inf,-3)"); + assert_parsed_expression_simplify_to("log(inf,3)", "inf"); + assert_parsed_expression_simplify_to("log(inf,0.3)", "-inf"); + assert_parsed_expression_simplify_to("log(inf,x)", "log(inf,x)"); + assert_parsed_expression_simplify_to("ln(inf)*0", "undef"); +} + +QUIZ_CASE(poincare_simplification_addition) { + assert_parsed_expression_simplify_to("1+x", "x+1"); + assert_parsed_expression_simplify_to("1/2+1/3+1/4+1/5+1/6+1/7", "223/140"); + assert_parsed_expression_simplify_to("1+x+4-i-2x", "-i-x+5"); + assert_parsed_expression_simplify_to("2+1", "3"); + assert_parsed_expression_simplify_to("1+2", "3"); + assert_parsed_expression_simplify_to("1+2+3+4+5+6+7", "28"); + assert_parsed_expression_simplify_to("(0+0)", "0"); + assert_parsed_expression_simplify_to("2+A", "A+2"); + assert_parsed_expression_simplify_to("1+2+3+4+5+A+6+7", "A+28"); + assert_parsed_expression_simplify_to("1+A+2+B+3", "A+B+6"); + assert_parsed_expression_simplify_to("-2+6", "4"); + assert_parsed_expression_simplify_to("-2-6", "-8"); + assert_parsed_expression_simplify_to("-A", "-A"); + assert_parsed_expression_simplify_to("A-A", "0"); + assert_parsed_expression_simplify_to("-5Ο€+3Ο€", "-2Ο€"); + assert_parsed_expression_simplify_to("1-3+A-5+2A-4A", "-A-7"); + assert_parsed_expression_simplify_to("A+B-A-B", "0"); + assert_parsed_expression_simplify_to("A+B+(-1)Γ—A+(-1)Γ—B", "0"); + assert_parsed_expression_simplify_to("2+13cos(2)-23cos(2)", "-10Γ—cos(2)+2"); + assert_parsed_expression_simplify_to("1+1+ln(2)+(5+3Γ—2)/9-4/7+1/98", "\u0012882Γ—ln(2)+2347\u0013/882"); + assert_parsed_expression_simplify_to("1+2+0+cos(2)", "cos(2)+3"); + assert_parsed_expression_simplify_to("A-A+2cos(2)+B-B-cos(2)", "cos(2)"); + assert_parsed_expression_simplify_to("x+3+Ο€+2Γ—x", "3Γ—x+Ο€+3"); + assert_parsed_expression_simplify_to("1/(x+1)+1/(Ο€+2)", "\u0012x+Ο€+3\u0013/\u0012π×x+2Γ—x+Ο€+2\u0013"); + assert_parsed_expression_simplify_to("1/x^2+1/(x^2Γ—Ο€)", "\u0012Ο€+1\u0013/\u0012π×x^2\u0013"); + assert_parsed_expression_simplify_to("1/x^2+1/(x^3Γ—Ο€)", "\u0012π×x+1\u0013/\u0012π×x^3\u0013"); + assert_parsed_expression_simplify_to("4x/x^2+3Ο€/(x^3Γ—Ο€)", "\u00124Γ—x^2+3\u0013/x^3"); + assert_parsed_expression_simplify_to("3^(1/2)+2^(-2Γ—3^(1/2)Γ—β„―^Ο€)/2", "\u00122Γ—2^\u00122√(3)β„―^Ο€\u0013√(3)+1\u0013/\u00122Γ—2^\u00122√(3)β„―^Ο€\u0013\u0013"); + assert_parsed_expression_simplify_to("[[1,2+𝐒][3,4][5,6]]+[[1,2+𝐒][3,4][5,6]]", "[[2,4+2𝐒][6,8][10,12]]"); + assert_parsed_expression_simplify_to("3+[[1,2][3,4]]", "undef"); + assert_parsed_expression_simplify_to("[[1][3][5]]+[[1,2+𝐒][3,4][5,6]]", "undef"); + assert_parsed_expression_simplify_to("[[1,3]]+confidence(Ο€/4, 6)+[[2,3]]", "[[3,6]]+confidence(Ο€/4,6)"); +} + +QUIZ_CASE(poincare_simplification_multiplication) { + assert_parsed_expression_simplify_to("undefΓ—x", "undef"); + assert_parsed_expression_simplify_to("0Γ—x+B", "B"); + assert_parsed_expression_simplify_to("0Γ—xΓ—0Γ—32Γ—cos(3)", "0"); + assert_parsed_expression_simplify_to("3Γ—A^4Γ—B^xΓ—B^2Γ—(A^2+2)Γ—2Γ—1.2", "\u001236Γ—A^6Γ—B^\u0012x+2\u0013+72Γ—A^4Γ—B^\u0012x+2\u0013\u0013/5"); + assert_parsed_expression_simplify_to("AΓ—(B+C)Γ—(D+3)", "3Γ—AΓ—B+3Γ—AΓ—C+AΓ—BΓ—D+AΓ—CΓ—D"); + assert_parsed_expression_simplify_to("A/B", "A/B"); + assert_parsed_expression_simplify_to("(AΓ—B)^2", "A^2Γ—B^2"); + assert_parsed_expression_simplify_to("(1/2)Γ—A/B", "A/\u00122Γ—B\u0013"); + assert_parsed_expression_simplify_to("1+2+3+4+5+6", "21"); + assert_parsed_expression_simplify_to("1-2+3-4+5-6", "-3"); + assert_parsed_expression_simplify_to("987654321123456789Γ—998877665544332211", "986545842648570754445552922919330479"); + assert_parsed_expression_simplify_to("2/3", "2/3"); + assert_parsed_expression_simplify_to("9/17+5/4", "121/68"); + assert_parsed_expression_simplify_to("1/2Γ—3/4", "3/8"); + assert_parsed_expression_simplify_to("0Γ—2/3", "0"); + assert_parsed_expression_simplify_to("1+(1/(1+1/(1+1/(1+1))))", "8/5"); + assert_parsed_expression_simplify_to("1+2/(3+4/(5+6/(7+8)))", "155/101"); + assert_parsed_expression_simplify_to("3/4Γ—16/12", "1"); + assert_parsed_expression_simplify_to("3/4Γ—(8+8)/12", "1"); + assert_parsed_expression_simplify_to("916791/794976477", "305597/264992159"); + assert_parsed_expression_simplify_to("321654987123456789/112233445566778899", "3249040273974311/1133671167341201"); + assert_parsed_expression_simplify_to("0.1+0.2", "3/10"); + assert_parsed_expression_simplify_to("2^3", "8"); + assert_parsed_expression_simplify_to("(-1)Γ—(-1)", "1"); + assert_parsed_expression_simplify_to("(-2)^2", "4"); + assert_parsed_expression_simplify_to("(-3)^3", "-27"); + assert_parsed_expression_simplify_to("(1/2)^-1", "2"); + assert_parsed_expression_simplify_to("√(2)Γ—βˆš(3)", "√(6)"); + assert_parsed_expression_simplify_to("2Γ—2^Ο€", "2Γ—2^Ο€"); + assert_parsed_expression_simplify_to("A^3Γ—BΓ—A^(-3)", "B"); + assert_parsed_expression_simplify_to("A^3Γ—A^(-3)", "1"); + assert_parsed_expression_simplify_to("2^π×(1/2)^Ο€", "1"); + assert_parsed_expression_simplify_to("A^3Γ—A^(-3)", "1"); + assert_parsed_expression_simplify_to("(x+1)Γ—(x+2)", "x^2+3Γ—x+2"); + assert_parsed_expression_simplify_to("(x+1)Γ—(x-1)", "x^2-1"); + assert_parsed_expression_simplify_to("11Ο€/(22Ο€+11Ο€)", "1/3"); + assert_parsed_expression_simplify_to("11/(22Ο€+11Ο€)", "1/3Ο€"); + assert_parsed_expression_simplify_to("-11/(22Ο€+11Ο€)", "-1/3Ο€"); + assert_parsed_expression_simplify_to("A^2Γ—BΓ—A^(-2)Γ—B^(-2)", "1/B"); + assert_parsed_expression_simplify_to("A^(-1)Γ—B^(-1)", "1/\u0012AΓ—B\u0013"); + assert_parsed_expression_simplify_to("x+x", "2Γ—x"); + assert_parsed_expression_simplify_to("2Γ—x+x", "3Γ—x"); + assert_parsed_expression_simplify_to("xΓ—2+x", "3Γ—x"); + assert_parsed_expression_simplify_to("2Γ—x+2Γ—x", "4Γ—x"); + assert_parsed_expression_simplify_to("xΓ—2+2Γ—n", "2Γ—n+2Γ—x"); + assert_parsed_expression_simplify_to("x+x+n+n", "2Γ—n+2Γ—x"); + assert_parsed_expression_simplify_to("x-x-n+n", "0"); + assert_parsed_expression_simplify_to("x+n-x-n", "0"); + assert_parsed_expression_simplify_to("x-x", "0"); + assert_parsed_expression_simplify_to("π×3^(1/2)Γ—(5Ο€)^(1/2)Γ—(4/5)^(1/2)", "2√(3)Ο€^\u00123/2\u0013"); + assert_parsed_expression_simplify_to("12^(1/4)Γ—(Ο€/6)Γ—(12Γ—Ο€)^(1/4)", "√(3)Ο€^\u00125/4\u0013/3"); + assert_parsed_expression_simplify_to("[[1,2+𝐒][3,4][5,6]]Γ—[[1,2+𝐒,3,4][5,6+𝐒,7,8]]", "[[11+5𝐒,13+9𝐒,17+7𝐒,20+8𝐒][23,30+7𝐒,37,44][35,46+11𝐒,57,68]]"); + assert_parsed_expression_simplify_to("[[1,2][3,4]]Γ—[[1,3][5,6]]Γ—[[2,3][4,6]]", "[[82,123][178,267]]"); + assert_parsed_expression_simplify_to("π×confidence(Ο€/5,3)[[1,2]]", "π×confidence(Ο€/5,3)[[1,2]]"); +} + +QUIZ_CASE(poincare_simplification_power) { + assert_parsed_expression_simplify_to("3^4", "81"); + assert_parsed_expression_simplify_to("3^(-4)", "1/81"); + assert_parsed_expression_simplify_to("(-3)^3", "-27"); + assert_parsed_expression_simplify_to("1256^(1/3)Γ—x", "2Γ—root(157,3)Γ—x"); + assert_parsed_expression_simplify_to("1256^(-1/3)", "1/\u00122Γ—root(157,3)\u0013"); + assert_parsed_expression_simplify_to("32^(-1/5)", "1/2"); + assert_parsed_expression_simplify_to("(2+3-4)^(x)", "1"); + assert_parsed_expression_simplify_to("1^x", "1"); + assert_parsed_expression_simplify_to("x^1", "x"); + assert_parsed_expression_simplify_to("0^3", "0"); + assert_parsed_expression_simplify_to("0^0", Undefined::Name()); + assert_parsed_expression_simplify_to("0^(-3)", Undefined::Name()); + assert_parsed_expression_simplify_to("4^0.5", "2"); + assert_parsed_expression_simplify_to("8^0.5", "2√(2)"); + assert_parsed_expression_simplify_to("(12^4Γ—3)^(0.5)", "144√(3)"); + assert_parsed_expression_simplify_to("(Ο€^3)^4", "Ο€^12"); + assert_parsed_expression_simplify_to("(AΓ—B)^3", "A^3Γ—B^3"); + assert_parsed_expression_simplify_to("(12^4Γ—x)^(0.5)", "144√(x)"); + assert_parsed_expression_simplify_to("√(32)", "4√(2)"); + assert_parsed_expression_simplify_to("√(-1)", "𝐒"); + assert_parsed_expression_simplify_to("√(-1Γ—βˆš(-1))", "√(2)/2-\u0012√(2)/2\u0013𝐒"); + assert_parsed_expression_simplify_to("√(3^2)", "3"); + assert_parsed_expression_simplify_to("2^(2+Ο€)", "4Γ—2^Ο€"); + assert_parsed_expression_simplify_to("√(5513219850886344455940081)", "2348024669991"); + assert_parsed_expression_simplify_to("√(154355776)", "12424"); + assert_parsed_expression_simplify_to("√(Ο€)^2", "Ο€"); + assert_parsed_expression_simplify_to("√(Ο€^2)", "Ο€"); + assert_parsed_expression_simplify_to("√((-Ο€)^2)", "Ο€"); + assert_parsed_expression_simplify_to("√(xΓ—144)", "12√(x)"); + assert_parsed_expression_simplify_to("√(xΓ—144Γ—Ο€^2)", "12Ο€βˆš(x)"); + assert_parsed_expression_simplify_to("√(xΓ—144Γ—Ο€)", "12√(Ο€)√(x)"); + assert_parsed_expression_simplify_to("(-1)Γ—(2+(-4Γ—βˆš(2)))", "4√(2)-2"); + assert_parsed_expression_simplify_to("x^(1/2)", "√(x)"); + assert_parsed_expression_simplify_to("x^(-1/2)", "1/√(x)"); + assert_parsed_expression_simplify_to("x^(1/7)", "root(x,7)"); + assert_parsed_expression_simplify_to("x^(-1/7)", "1/root(x,7)"); + assert_parsed_expression_simplify_to("1/(3√(2))", "√(2)/6"); + assert_parsed_expression_simplify_to("β„―^ln(3)", "3"); + assert_parsed_expression_simplify_to("β„―^ln(√(3))", "√(3)"); + assert_parsed_expression_simplify_to("Ο€^log(√(3),Ο€)", "√(3)"); + assert_parsed_expression_simplify_to("10^log(Ο€)", "Ο€"); + assert_parsed_expression_simplify_to("β„―^ln(65)", "65"); + assert_parsed_expression_simplify_to("β„―^ln(Ο€β„―)", "Ο€β„―"); + assert_parsed_expression_simplify_to("β„―^log(Ο€β„―)", "β„―^\u0012log(β„―)+log(Ο€)\u0013"); + assert_parsed_expression_simplify_to("√(β„―^2)", "β„―"); + assert_parsed_expression_simplify_to("999^(10000/3)", "999^\u001210000/3\u0013"); + /* This does not reduce but should not as the integer is above + * k_maxNumberOfPrimeFactors and thus it prime decomposition might overflow + * 32 factors. */ + assert_parsed_expression_simplify_to("1881676377434183981909562699940347954480361860897069^(1/3)", "root(1881676377434183981909562699940347954480361860897069,3)"); + /* This does not reduce but should not as the prime decomposition involves + * factors above k_maxNumberOfPrimeFactors. */ + assert_parsed_expression_simplify_to("1002101470343^(1/3)", "root(1002101470343,3)"); + assert_parsed_expression_simplify_to("π×π×π", "Ο€^3"); + assert_parsed_expression_simplify_to("(x+Ο€)^(3)", "x^3+3π×x^2+3Ο€^2Γ—x+Ο€^3"); + assert_parsed_expression_simplify_to("(5+√(2))^(-8)", "\u0012-1003320√(2)+1446241\u0013/78310985281"); + assert_parsed_expression_simplify_to("(5Γ—Ο€+√(2))^(-5)", "1/\u00123125Ο€^5+3125√(2)Ο€^4+2500Ο€^3+500√(2)Ο€^2+100Ο€+4√(2)\u0013"); + assert_parsed_expression_simplify_to("(1+√(2)+√(3))^5", "120√(6)+184√(3)+224√(2)+296"); + assert_parsed_expression_simplify_to("(Ο€+√(2)+√(3)+x)^(-3)", "1/\u0012x^3+3π×x^2+3√(3)Γ—x^2+3√(2)Γ—x^2+3Ο€^2Γ—x+6√(3)π×x+6√(2)π×x+6√(6)Γ—x+15Γ—x+Ο€^3+3√(3)Ο€^2+3√(2)Ο€^2+6√(6)Ο€+15Ο€+9√(3)+11√(2)\u0013"); + assert_parsed_expression_simplify_to("1.0066666666667^60", "(10066666666667/10000000000000)^60"); + assert_parsed_expression_simplify_to("2^(6+Ο€+x)", "64Γ—2^\u0012x+Ο€\u0013"); + assert_parsed_expression_simplify_to("𝐒^(2/3)", "1/2+\u0012√(3)/2\u0013𝐒"); + assert_parsed_expression_simplify_to("β„―^(𝐒×π/3)", "1/2+\u0012√(3)/2\u0013𝐒"); + assert_parsed_expression_simplify_to("(-1)^(1/3)", "1/2+\u0012√(3)/2\u0013𝐒"); + assert_parsed_expression_simplify_to("R(-x)", "R(-x)"); + assert_parsed_expression_simplify_to("√(x)^2", "x", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("√(-3)^2", "unreal", User, Radian, Real); + // Principal angle of root of unity + assert_parsed_expression_simplify_to("(-5)^(-1/3)", "1/\u00122Γ—root(5,3)\u0013-\u0012√(3)/\u00122Γ—root(5,3)\u0013\u0013𝐒", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("1+((8+√(6))^(1/2))^-1+(8+√(6))^(1/2)", "\u0012√(√(6)+8)+√(6)+9\u0013/√(√(6)+8)", User, Radian, Real); + assert_parsed_expression_simplify_to("[[1,2][3,4]]^(-3)", "[[-59/4,27/4][81/8,-37/8]]"); + assert_parsed_expression_simplify_to("[[1,2][3,4]]^3", "[[37,54][81,118]]"); +} + +QUIZ_CASE(poincare_simplification_factorial) { + assert_parsed_expression_simplify_to("1/3!", "1/6"); + assert_parsed_expression_simplify_to("5!", "120"); + assert_parsed_expression_simplify_to("(1/3)!", Undefined::Name()); + assert_parsed_expression_simplify_to("Ο€!", Undefined::Name()); + assert_parsed_expression_simplify_to("β„―!", Undefined::Name()); +} + +QUIZ_CASE(poincare_simplification_logarithm) { + assert_parsed_expression_simplify_to("log(0,0)", Undefined::Name()); + assert_parsed_expression_simplify_to("log(0,1)", Undefined::Name()); + assert_parsed_expression_simplify_to("log(1,0)", "0"); + assert_parsed_expression_simplify_to("log(2,0)", "0"); + assert_parsed_expression_simplify_to("log(0,14)", "-inf"); + assert_parsed_expression_simplify_to("log(0,0.14)", Infinity::Name()); + assert_parsed_expression_simplify_to("log(0,0.14+𝐒)", Undefined::Name()); + assert_parsed_expression_simplify_to("log(2,1)", Undefined::Name()); + assert_parsed_expression_simplify_to("log(x,1)", Undefined::Name()); + assert_parsed_expression_simplify_to("log(12925)", "log(47)+log(11)+2Γ—log(5)"); + assert_parsed_expression_simplify_to("ln(12925)", "ln(47)+ln(11)+2Γ—ln(5)"); + assert_parsed_expression_simplify_to("log(1742279/12925, 6)", "-log(47,6)+log(17,6)+3Γ—log(11,6)+log(7,6)-2Γ—log(5,6)"); + assert_parsed_expression_simplify_to("ln(2/3)", "-ln(3)+ln(2)"); + assert_parsed_expression_simplify_to("log(1742279/12925, -6)", "log(158389/1175,-6)"); + assert_parsed_expression_simplify_to("ln(√(2))", "ln(2)/2"); + assert_parsed_expression_simplify_to("ln(β„―^3)", "3"); + assert_parsed_expression_simplify_to("log(10)", "1"); + assert_parsed_expression_simplify_to("log(√(3),√(3))", "1"); + assert_parsed_expression_simplify_to("log(1/√(2))", "-log(2)/2"); + assert_parsed_expression_simplify_to("log(-𝐒)", "log(-𝐒)"); + assert_parsed_expression_simplify_to("ln(β„―^(𝐒π/7))", "\u0012Ο€/7\u0013𝐒"); + assert_parsed_expression_simplify_to("log(10^24)", "24"); + assert_parsed_expression_simplify_to("log((23Ο€)^4,23Ο€)", "4"); + assert_parsed_expression_simplify_to("log(10^(2+Ο€))", "Ο€+2"); + assert_parsed_expression_simplify_to("ln(1881676377434183981909562699940347954480361860897069)", "ln(1881676377434183981909562699940347954480361860897069)"); + /* log(1002101470343) does no reduce to 3Γ—log(10007) because it involves + * prime factors above k_biggestPrimeFactor */ + assert_parsed_expression_simplify_to("log(1002101470343)", "log(1002101470343)"); + assert_parsed_expression_simplify_to("log(64,2)", "6"); + assert_parsed_expression_simplify_to("log(2,64)", "log(2,64)"); + assert_parsed_expression_simplify_to("log(1476225,5)", "10Γ—log(3,5)+2"); + + assert_parsed_expression_simplify_to("log(100)", "2"); + assert_parsed_expression_simplify_to("log(1000000)", "6"); + assert_parsed_expression_simplify_to("log(70992768,14)", "log(11,14)+log(3,14)+2Γ—log(2,14)+5"); + assert_parsed_expression_simplify_to("log(1/6991712,14)", "-log(13,14)-5"); + assert_parsed_expression_simplify_to("log(4,10)", "2Γ—log(2)"); +} + +QUIZ_CASE(poincare_simplification_random) { + assert_parsed_expression_simplify_to("1/random()+1/3+1/4", "1/random()+7/12"); + assert_parsed_expression_simplify_to("random()+random()", "random()+random()"); + assert_parsed_expression_simplify_to("random()-random()", "-random()+random()"); + assert_parsed_expression_simplify_to("1/random()+1/3+1/4+1/random()", "1/random()+1/random()+7/12"); + assert_parsed_expression_simplify_to("random()Γ—random()", "random()Γ—random()"); + assert_parsed_expression_simplify_to("random()/random()", "random()/random()"); + assert_parsed_expression_simplify_to("3^random()Γ—3^random()", "3^random()Γ—3^random()"); + assert_parsed_expression_simplify_to("random()Γ—ln(2)Γ—3+random()Γ—ln(2)Γ—5", "5Γ—ln(2)Γ—random()+3Γ—ln(2)Γ—random()"); +} + +QUIZ_CASE(poincare_simplification_randint) { + assert_parsed_expression_simplify_to("1/randint(2,2)+1/2", "1"); + assert_parsed_expression_simplify_to("randint(1, inf)", "undef"); + assert_parsed_expression_simplify_to("randint(-inf, 3)", "undef"); + assert_parsed_expression_simplify_to("randint(4, 3)", "undef"); +} + +QUIZ_CASE(poincare_simplification_function) { + assert_parsed_expression_simplify_to("abs(Ο€)", "Ο€"); + assert_parsed_expression_simplify_to("abs(-Ο€)", "Ο€"); + assert_parsed_expression_simplify_to("abs(1+𝐒)", "√(2)"); + assert_parsed_expression_simplify_to("abs(0)", "0"); + assert_parsed_expression_simplify_to("arg(1+𝐒)", "Ο€/4"); + assert_parsed_expression_simplify_to("binomial(20,3)", "1140"); + assert_parsed_expression_simplify_to("binomial(20,10)", "184756"); + assert_parsed_expression_simplify_to("ceil(-1.3)", "-1"); + assert_parsed_expression_simplify_to("conj(1/2)", "1/2"); + assert_parsed_expression_simplify_to("quo(19,3)", "6"); + assert_parsed_expression_simplify_to("quo(19,0)", Infinity::Name()); + assert_parsed_expression_simplify_to("quo(-19,3)", "-7"); + assert_parsed_expression_simplify_to("rem(19,3)", "1"); + assert_parsed_expression_simplify_to("rem(-19,3)", "2"); + assert_parsed_expression_simplify_to("rem(19,0)", Infinity::Name()); + assert_parsed_expression_simplify_to("99!", "933262154439441526816992388562667004907159682643816214685929638952175999932299156089414639761565182862536979208272237582511852109168640000000000000000000000"); + assert_parsed_expression_simplify_to("factor(-10008/6895)", "-\u00122^3Γ—3^2Γ—139\u0013/\u00125Γ—7Γ—197\u0013"); + assert_parsed_expression_simplify_to("factor(1008/6895)", "\u00122^4Γ—3^2\u0013/\u00125Γ—197\u0013"); + assert_parsed_expression_simplify_to("factor(10007)", "10007"); + assert_parsed_expression_simplify_to("factor(10007^2)", Undefined::Name()); + assert_parsed_expression_simplify_to("floor(-1.3)", "-2"); + assert_parsed_expression_simplify_to("frac(-1.3)", "7/10"); + assert_parsed_expression_simplify_to("gcd(123,278)", "1"); + assert_parsed_expression_simplify_to("gcd(11,121)", "11"); + assert_parsed_expression_simplify_to("im(1+5×𝐒)", "5"); + assert_parsed_expression_simplify_to("lcm(123,278)", "34194"); + assert_parsed_expression_simplify_to("lcm(11,121)", "121"); + assert_parsed_expression_simplify_to("√(4)", "2"); + assert_parsed_expression_simplify_to("re(1+5×𝐒)", "1"); + assert_parsed_expression_simplify_to("root(4,3)", "root(4,3)"); + assert_parsed_expression_simplify_to("root(4,Ο€)", "4^\u00121/Ο€\u0013"); + assert_parsed_expression_simplify_to("root(27,3)", "3"); + assert_parsed_expression_simplify_to("round(4.235,2)", "106/25"); + assert_parsed_expression_simplify_to("round(4.23,0)", "4"); + assert_parsed_expression_simplify_to("round(4.9,0)", "5"); + assert_parsed_expression_simplify_to("round(12.9,-1)", "10"); + assert_parsed_expression_simplify_to("round(12.9,-2)", "0"); + assert_parsed_expression_simplify_to("sign(-23)", "-1"); + assert_parsed_expression_simplify_to("sign(-𝐒)", "sign(-𝐒)"); + assert_parsed_expression_simplify_to("sign(0)", "0"); + assert_parsed_expression_simplify_to("sign(inf)", "1"); + assert_parsed_expression_simplify_to("sign(-inf)", "-1"); + assert_parsed_expression_simplify_to("sign(undef)", "undef"); + assert_parsed_expression_simplify_to("sign(23)", "1"); + assert_parsed_expression_simplify_to("sign(log(18))", "1"); + assert_parsed_expression_simplify_to("sign(-√(2))", "-1"); + assert_parsed_expression_simplify_to("sign(x)", "sign(x)"); + assert_parsed_expression_simplify_to("sign(2+𝐒)", "sign(2+𝐒)"); + assert_parsed_expression_simplify_to("permute(99,4)", "90345024"); + assert_parsed_expression_simplify_to("permute(20,-10)", Undefined::Name()); + assert_parsed_expression_simplify_to("re(1/2)", "1/2"); +} + +QUIZ_CASE(poincare_simplication_trigonometry_functions) { + // -- sin/cos -> tan + assert_parsed_expression_simplify_to("sin(x)/cos(x)", "tan(x)"); + assert_parsed_expression_simplify_to("cos(x)/sin(x)", "1/tan(x)"); + assert_parsed_expression_simplify_to("sin(x)Γ—Ο€/cos(x)", "π×tan(x)"); + assert_parsed_expression_simplify_to("sin(x)/(π×cos(x))", "tan(x)/Ο€"); + assert_parsed_expression_simplify_to("1Γ—tan(2)Γ—tan(5)", "tan(2)Γ—tan(5)"); + assert_parsed_expression_simplify_to("tan(62Ο€/21)", "-tan(Ο€/21)"); + assert_parsed_expression_simplify_to("cos(26Ο€/21)/sin(25Ο€/17)", "cos(5Ο€/21)/sin(8Ο€/17)"); + assert_parsed_expression_simplify_to("cos(62Ο€/21)×π×3/sin(62Ο€/21)", "-3Ο€/tan(Ο€/21)"); + assert_parsed_expression_simplify_to("cos(62Ο€/21)/(π×3Γ—sin(62Ο€/21))", "-1/\u00123π×tan(Ο€/21)\u0013"); + assert_parsed_expression_simplify_to("sin(62Ο€/21)×π×3/cos(62Ο€/21)", "-3π×tan(Ο€/21)"); + assert_parsed_expression_simplify_to("sin(62Ο€/21)/(π×3cos(62Ο€/21))", "-tan(Ο€/21)/3Ο€"); + assert_parsed_expression_simplify_to("-cos(Ο€/62)ln(3)/(sin(Ο€/62)Ο€)", "-ln(3)/\u0012π×tan(Ο€/62)\u0013"); + assert_parsed_expression_simplify_to("-2cos(Ο€/62)ln(3)/(sin(Ο€/62)Ο€)", "-\u00122Γ—ln(3)\u0013/\u0012π×tan(Ο€/62)\u0013"); + // -- cos + assert_parsed_expression_simplify_to("cos(0)", "1"); + assert_parsed_expression_simplify_to("cos(Ο€)", "-1"); + assert_parsed_expression_simplify_to("cos(π×4/7)", "-cos(3Ο€/7)"); + assert_parsed_expression_simplify_to("cos(π×35/29)", "-cos(6Ο€/29)"); + assert_parsed_expression_simplify_to("cos(-π×35/29)", "-cos(6Ο€/29)"); + assert_parsed_expression_simplify_to("cos(π×340000)", "1"); + assert_parsed_expression_simplify_to("cos(-π×340001)", "-1"); + assert_parsed_expression_simplify_to("cos(-Ο€Γ—βˆš(2))", "cos(√(2)Ο€)"); + assert_parsed_expression_simplify_to("cos(1311Ο€/6)", "0"); + assert_parsed_expression_simplify_to("cos(Ο€/12)", "\u0012√(6)+√(2)\u0013/4"); + assert_parsed_expression_simplify_to("cos(-Ο€/12)", "\u0012√(6)+√(2)\u0013/4"); + assert_parsed_expression_simplify_to("cos(-Ο€17/8)", "√(√(2)+2)/2"); + assert_parsed_expression_simplify_to("cos(41Ο€/6)", "-√(3)/2"); + assert_parsed_expression_simplify_to("cos(Ο€/4+1000Ο€)", "√(2)/2"); + assert_parsed_expression_simplify_to("cos(-Ο€/3)", "1/2"); + assert_parsed_expression_simplify_to("cos(41Ο€/5)", "\u0012√(5)+1\u0013/4"); + assert_parsed_expression_simplify_to("cos(7Ο€/10)", "-√(2)√(-√(5)+5)/4"); + assert_parsed_expression_simplify_to("cos(0)", "1", User, Degree); + assert_parsed_expression_simplify_to("cos(180)", "-1", User, Degree); + assert_parsed_expression_simplify_to("cos(720/7)", "-cos(540/7)", User, Degree); + assert_parsed_expression_simplify_to("cos(6300/29)", "-cos(1080/29)", User, Degree); + assert_parsed_expression_simplify_to("cos(-6300/29)", "-cos(1080/29)", User, Degree); + assert_parsed_expression_simplify_to("cos(61200000)", "1", User, Degree); + assert_parsed_expression_simplify_to("cos(-61200180)", "-1", User, Degree); + assert_parsed_expression_simplify_to("cos(-180Γ—βˆš(2))", "cos(180√(2))", User, Degree); + assert_parsed_expression_simplify_to("cos(39330)", "0", User, Degree); + assert_parsed_expression_simplify_to("cos(15)", "\u0012√(6)+√(2)\u0013/4", User, Degree); + assert_parsed_expression_simplify_to("cos(-15)", "\u0012√(6)+√(2)\u0013/4", User, Degree); + assert_parsed_expression_simplify_to("cos(-765/2)", "√(√(2)+2)/2", User, Degree); + assert_parsed_expression_simplify_to("cos(7380/6)", "-√(3)/2", User, Degree); + assert_parsed_expression_simplify_to("cos(180045)", "√(2)/2", User, Degree); + assert_parsed_expression_simplify_to("cos(-60)", "1/2", User, Degree); + assert_parsed_expression_simplify_to("cos(7380/5)", "\u0012√(5)+1\u0013/4", User, Degree); + assert_parsed_expression_simplify_to("cos(112.5)", "-√(-√(2)+2)/2", User, Degree); + // -- sin + assert_parsed_expression_simplify_to("sin(0)", "0"); + assert_parsed_expression_simplify_to("sin(Ο€)", "0"); + assert_parsed_expression_simplify_to("sin(π×35/29)", "-sin(6Ο€/29)"); + assert_parsed_expression_simplify_to("sin(-π×35/29)", "sin(6Ο€/29)"); + assert_parsed_expression_simplify_to("sin(π×340000)", "0"); + assert_parsed_expression_simplify_to("sin(π×340001)", "0"); + assert_parsed_expression_simplify_to("sin(-π×340001)", "0"); + assert_parsed_expression_simplify_to("sin(Ο€/12)", "\u0012√(6)-√(2)\u0013/4"); + assert_parsed_expression_simplify_to("sin(-Ο€/12)", "\u0012-√(6)+√(2)\u0013/4"); + assert_parsed_expression_simplify_to("sin(-Ο€Γ—βˆš(2))", "-sin(√(2)Ο€)"); + assert_parsed_expression_simplify_to("sin(1311Ο€/6)", "1"); + assert_parsed_expression_simplify_to("sin(-Ο€17/8)", "-√(-√(2)+2)/2"); + assert_parsed_expression_simplify_to("sin(41Ο€/6)", "1/2"); + assert_parsed_expression_simplify_to("sin(-3Ο€/10)", "\u0012-√(5)-1\u0013/4"); + assert_parsed_expression_simplify_to("sin(Ο€/4+1000Ο€)", "√(2)/2"); + assert_parsed_expression_simplify_to("sin(-Ο€/3)", "-√(3)/2"); + assert_parsed_expression_simplify_to("sin(17Ο€/5)", "-√(2)√(√(5)+5)/4"); + assert_parsed_expression_simplify_to("sin(Ο€/5)", "√(2)√(-√(5)+5)/4"); + assert_parsed_expression_simplify_to("sin(0)", "0", User, Degree); + assert_parsed_expression_simplify_to("sin(180)", "0", User, Degree); + assert_parsed_expression_simplify_to("sin(6300/29)", "-sin(1080/29)", User, Degree); + assert_parsed_expression_simplify_to("sin(-6300/29)", "sin(1080/29)", User, Degree); + assert_parsed_expression_simplify_to("sin(61200000)", "0", User, Degree); + assert_parsed_expression_simplify_to("sin(61200180)", "0", User, Degree); + assert_parsed_expression_simplify_to("sin(-61200180)", "0", User, Degree); + assert_parsed_expression_simplify_to("sin(15)", "\u0012√(6)-√(2)\u0013/4", User, Degree); + assert_parsed_expression_simplify_to("sin(-15)", "\u0012-√(6)+√(2)\u0013/4", User, Degree); + assert_parsed_expression_simplify_to("sin(-180Γ—βˆš(2))", "-sin(180√(2))", User, Degree); + assert_parsed_expression_simplify_to("sin(39330)", "1", User, Degree); + assert_parsed_expression_simplify_to("sin(-765/2)", "-√(-√(2)+2)/2", User, Degree); + assert_parsed_expression_simplify_to("sin(1230)", "1/2", User, Degree); + assert_parsed_expression_simplify_to("sin(180045)", "√(2)/2", User, Degree); + assert_parsed_expression_simplify_to("sin(-60)", "-√(3)/2", User, Degree); + assert_parsed_expression_simplify_to("sin(612)", "-√(2)√(√(5)+5)/4", User, Degree); + assert_parsed_expression_simplify_to("sin(36)", "√(2)√(-√(5)+5)/4", User, Degree); + // -- tan + assert_parsed_expression_simplify_to("tan(0)", "0"); + assert_parsed_expression_simplify_to("tan(Ο€)", "0"); + assert_parsed_expression_simplify_to("tan(π×35/29)", "tan(6Ο€/29)"); + assert_parsed_expression_simplify_to("tan(-π×35/29)", "-tan(6Ο€/29)"); + assert_parsed_expression_simplify_to("tan(π×340000)", "0"); + assert_parsed_expression_simplify_to("tan(π×340001)", "0"); + assert_parsed_expression_simplify_to("tan(-π×340001)", "0"); + assert_parsed_expression_simplify_to("tan(Ο€/12)", "-√(3)+2"); + assert_parsed_expression_simplify_to("tan(-Ο€/12)", "√(3)-2"); + assert_parsed_expression_simplify_to("tan(-Ο€Γ—βˆš(2))", "-tan(√(2)Ο€)"); + assert_parsed_expression_simplify_to("tan(1311Ο€/6)", Undefined::Name()); + assert_parsed_expression_simplify_to("tan(-Ο€17/8)", "-√(2)+1"); + assert_parsed_expression_simplify_to("tan(41Ο€/6)", "-√(3)/3"); + assert_parsed_expression_simplify_to("tan(Ο€/4+1000Ο€)", "1"); + assert_parsed_expression_simplify_to("tan(-Ο€/3)", "-√(3)"); + assert_parsed_expression_simplify_to("tan(-Ο€/10)", "-√(5)√(-2√(5)+5)/5"); + assert_parsed_expression_simplify_to("tan(0)", "0", User, Degree); + assert_parsed_expression_simplify_to("tan(180)", "0", User, Degree); + assert_parsed_expression_simplify_to("tan(6300/29)", "tan(1080/29)", User, Degree); + assert_parsed_expression_simplify_to("tan(-6300/29)", "-tan(1080/29)", User, Degree); + assert_parsed_expression_simplify_to("tan(61200000)", "0", User, Degree); + assert_parsed_expression_simplify_to("tan(61200180)", "0", User, Degree); + assert_parsed_expression_simplify_to("tan(-61200180)", "0", User, Degree); + assert_parsed_expression_simplify_to("tan(15)", "-√(3)+2", User, Degree); + assert_parsed_expression_simplify_to("tan(-15)", "√(3)-2", User, Degree); + assert_parsed_expression_simplify_to("tan(-180Γ—βˆš(2))", "-tan(180√(2))", User, Degree); + assert_parsed_expression_simplify_to("tan(39330)", Undefined::Name(), User, Degree); + assert_parsed_expression_simplify_to("tan(-382.5)", "-√(2)+1", User, Degree); + assert_parsed_expression_simplify_to("tan(1230)", "-√(3)/3", User, Degree); + assert_parsed_expression_simplify_to("tan(180045)", "1", User, Degree); + assert_parsed_expression_simplify_to("tan(-60)", "-√(3)", User, Degree); + assert_parsed_expression_simplify_to("tan(tan(tan(tan(9))))", "tan(tan(tan(tan(9))))"); + // -- acos + assert_parsed_expression_simplify_to("acos(-1/2)", "2Ο€/3"); + assert_parsed_expression_simplify_to("acos(-1.2)", "-acos(6/5)+Ο€"); + assert_parsed_expression_simplify_to("acos(cos(2/3))", "2/3"); + 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(4Ο€/7))", "4Ο€/7"); + assert_parsed_expression_simplify_to("acos(-cos(2))", "Ο€-2"); + assert_parsed_expression_simplify_to("acos(-1/2)", "120", User, Degree); + assert_parsed_expression_simplify_to("acos(-1.2)", "-acos(6/5)+180", User, Degree); + assert_parsed_expression_simplify_to("acos(cos(2/3))", "2/3", User, Degree); + assert_parsed_expression_simplify_to("acos(cos(190))", "170", User, Degree); + assert_parsed_expression_simplify_to("acos(cos(75))", "75", User, Degree); + assert_parsed_expression_simplify_to("cos(acos(190))", "190", User, Degree); + assert_parsed_expression_simplify_to("cos(acos(75))", "75", User, Degree); + assert_parsed_expression_simplify_to("acos(cos(12))", "12", User, Degree); + assert_parsed_expression_simplify_to("acos(cos(720/7))", "720/7", User, Degree); + // -- asin + assert_parsed_expression_simplify_to("asin(-1/2)", "-Ο€/6"); + assert_parsed_expression_simplify_to("asin(-1.2)", "-asin(6/5)"); + assert_parsed_expression_simplify_to("asin(sin(2/3))", "2/3"); + 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(-Ο€/7))", "-Ο€/7"); + assert_parsed_expression_simplify_to("asin(sin(-√(2)))", "-√(2)"); + assert_parsed_expression_simplify_to("asin(-1/2)", "-30", User, Degree); + assert_parsed_expression_simplify_to("asin(-1.2)", "-asin(6/5)", User, Degree); + assert_parsed_expression_simplify_to("asin(sin(75))", "75", User, Degree); + assert_parsed_expression_simplify_to("sin(asin(75))", "75", User, Degree); + assert_parsed_expression_simplify_to("sin(asin(190))", "190", User, Degree); + assert_parsed_expression_simplify_to("asin(sin(32))", "32", User, Degree); + assert_parsed_expression_simplify_to("asin(sin(400))", "40", User, Degree); + assert_parsed_expression_simplify_to("asin(sin(-180/7))", "-180/7", User, Degree); + // -- atan + assert_parsed_expression_simplify_to("atan(-1)", "-Ο€/4"); + assert_parsed_expression_simplify_to("atan(-1.2)", "-atan(6/5)"); + 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(-Ο€/7))", "-Ο€/7"); + assert_parsed_expression_simplify_to("atan(√(3))", "Ο€/3"); + assert_parsed_expression_simplify_to("atan(tan(-√(2)))", "-√(2)"); + assert_parsed_expression_simplify_to("atan(-1)", "-45", User, Degree); + assert_parsed_expression_simplify_to("atan(-1.2)", "-atan(6/5)", User, Degree); + assert_parsed_expression_simplify_to("atan(tan(-45))", "-45", User, Degree); + assert_parsed_expression_simplify_to("tan(atan(120))", "120", User, Degree); + assert_parsed_expression_simplify_to("tan(atan(2293))", "2293", User, Degree); + assert_parsed_expression_simplify_to("atan(tan(2293))", "-47", User, Degree); + assert_parsed_expression_simplify_to("atan(tan(1808))", "8", User, Degree); + assert_parsed_expression_simplify_to("atan(tan(-180/7))", "-180/7", User, Degree); + assert_parsed_expression_simplify_to("atan(√(3))", "60", User, Degree); + assert_parsed_expression_simplify_to("atan(1/x)", "\u0012π×sign(x)-2Γ—atan(x)\u0013/2", User, Degree); + + // cos(asin) + assert_parsed_expression_simplify_to("cos(asin(x))", "√(-x^2+1)", User, Degree); + assert_parsed_expression_simplify_to("cos(asin(-x))", "√(-x^2+1)", User, Degree); + // cos(atan) + assert_parsed_expression_simplify_to("cos(atan(x))", "1/√(x^2+1)", User, Degree); + assert_parsed_expression_simplify_to("cos(atan(-x))", "1/√(x^2+1)", User, Degree); + // sin(acos) + assert_parsed_expression_simplify_to("sin(acos(x))", "√(-x^2+1)", User, Degree); + assert_parsed_expression_simplify_to("sin(acos(-x))", "√(-x^2+1)", User, Degree); + // sin(atan) + assert_parsed_expression_simplify_to("sin(atan(x))", "x/√(x^2+1)", User, Degree); + assert_parsed_expression_simplify_to("sin(atan(-x))", "-x/√(x^2+1)", User, Degree); + // tan(acos) + assert_parsed_expression_simplify_to("tan(acos(x))", "√(-x^2+1)/x", User, Degree); + assert_parsed_expression_simplify_to("tan(acos(-x))", "-√(-x^2+1)/x", User, Degree); + // tan(asin) + assert_parsed_expression_simplify_to("tan(asin(x))", "x/√(-x^2+1)", User, Degree); + assert_parsed_expression_simplify_to("tan(asin(-x))", "-x/√(-x^2+1)", User, Degree); +} + +QUIZ_CASE(poincare_simplication_matrix) { + // Addition Matrix + assert_parsed_expression_simplify_to("1+[[1,2,3][4,5,6]]", Undefined::Name()); + assert_parsed_expression_simplify_to("[[1,2,3][4,5,6]]+1", Undefined::Name()); + assert_parsed_expression_simplify_to("[[1,2][3,4]]+[[1,2,3][4,5,6]]", Undefined::Name()); + assert_parsed_expression_simplify_to("2+[[1,2,3][4,5,6]]+[[1,2,3][4,5,6]]", Undefined::Name()); + assert_parsed_expression_simplify_to("[[1,2,3][4,5,6]]+cos(2)+[[1,2,3][4,5,6]]", Undefined::Name()); + assert_parsed_expression_simplify_to("[[1,2,3][4,5,6]]+[[1,2,3][4,5,6]]", "[[2,4,6][8,10,12]]"); + + // Multiplication Matrix + assert_parsed_expression_simplify_to("2*[[1,2,3][4,5,6]]", "[[2,4,6][8,10,12]]"); + assert_parsed_expression_simplify_to("[[1,2,3][4,5,6]]Γ—βˆš(2)", "[[√(2),2√(2),3√(2)][4√(2),5√(2),6√(2)]]"); + assert_parsed_expression_simplify_to("[[1,2][3,4]]*[[1,2,3][4,5,6]]", "[[9,12,15][19,26,33]]"); + assert_parsed_expression_simplify_to("[[1,2,3][4,5,6]]*[[1,2][2,3][5,6]]", "[[20,26][44,59]]"); + assert_parsed_expression_simplify_to("[[1,2,3,4][4,5,6,5]]*[[1,2][2,3][5,6]]", Undefined::Name()); + assert_parsed_expression_simplify_to("[[1,2][3,4]]^(-3)*[[1,2][3,4]]", "[[11/2,-5/2][-15/4,7/4]]"); + assert_parsed_expression_simplify_to("[[1,2][3,4]]^(-3)*[[1,2,3][3,4,5]]*[[1,2][3,2][4,5]]*4", "[[-176,-186][122,129]]"); + + // Power Matrix + assert_parsed_expression_simplify_to("[[1,2,3][4,5,6][7,8,9]]^3", "[[468,576,684][1062,1305,1548][1656,2034,2412]]"); + assert_parsed_expression_simplify_to("[[1,2,3][4,5,6]]^(-1)", Undefined::Name()); + assert_parsed_expression_simplify_to("[[1,2][3,4]]^(-1)", "[[-2,1][3/2,-1/2]]"); + + // Determinant + assert_parsed_expression_simplify_to("det(Ο€+Ο€)", "2Ο€"); + assert_parsed_expression_simplify_to("det([[Ο€+Ο€]])", "2Ο€"); + assert_parsed_expression_simplify_to("det([[1,2][3,4]])", "-2"); + assert_parsed_expression_simplify_to("det([[2,2][3,4]])", "2"); + assert_parsed_expression_simplify_to("det([[2,2][3,4][3,4]])", Undefined::Name()); + assert_parsed_expression_simplify_to("det([[2,2][3,3]])", "0"); + assert_parsed_expression_simplify_to("det([[1,2,3][4,5,6][7,8,9]])", "0"); + assert_parsed_expression_simplify_to("det([[1,2,3][4,5,6][7,8,9]])", "0"); + assert_parsed_expression_simplify_to("det([[1,2,3][4Ο€,5,6][7,8,9]])", "24Ο€-24"); + + // Dimension + assert_parsed_expression_simplify_to("dim(3)", "[[1,1]]"); + assert_parsed_expression_simplify_to("dim([[1/√(2),1/2,3][2,1,-3]])", "[[2,3]]"); + + // Inverse + assert_parsed_expression_simplify_to("inverse([[1/√(2),1/2,3][2,1,-3]])", Undefined::Name()); + assert_parsed_expression_simplify_to("inverse([[1,2][3,4]])", "[[-2,1][3/2,-1/2]]"); + assert_parsed_expression_simplify_to("inverse([[Ο€,2Ο€][3,2]])", "[[-1/2Ο€,1/2][3/4Ο€,-1/4]]"); + + // Trace + assert_parsed_expression_simplify_to("trace([[1/√(2),1/2,3][2,1,-3]])", Undefined::Name()); + assert_parsed_expression_simplify_to("trace([[√(2),2][4,3+log(3)]])", "log(3)+√(2)+3"); + assert_parsed_expression_simplify_to("trace(√(2)+log(3))", "log(3)+√(2)"); + + // Transpose + assert_parsed_expression_simplify_to("transpose([[1/√(2),1/2,3][2,1,-3]])", "[[√(2)/2,2][1/2,1][3,-3]]"); + assert_parsed_expression_simplify_to("transpose(√(4))", "2"); +} + +QUIZ_CASE(poincare_simplification_functions_of_matrices) { + assert_parsed_expression_simplify_to("abs([[1,-1][2,-3]])", "[[1,1][2,3]]"); + assert_parsed_expression_simplify_to("acos([[1/√(2),1/2][1,-1]])", "[[Ο€/4,Ο€/3][0,Ο€]]"); + assert_parsed_expression_simplify_to("acos([[1,0]])", "[[0,Ο€/2]]"); + assert_parsed_expression_simplify_to("asin([[1/√(2),1/2][1,-1]])", "[[Ο€/4,Ο€/6][Ο€/2,-Ο€/2]]"); + assert_parsed_expression_simplify_to("asin([[1,0]])", "[[Ο€/2,0]]"); + assert_parsed_expression_simplify_to("atan([[√(3),1][1/√(3),-1]])", "[[Ο€/3,Ο€/4][Ο€/6,-Ο€/4]]"); + assert_parsed_expression_simplify_to("atan([[1,0]])", "[[Ο€/4,0]]"); + assert_parsed_expression_simplify_to("binomial([[0,180]],1)", Undefined::Name()); + assert_parsed_expression_simplify_to("binomial(1,[[0,180]])", Undefined::Name()); + assert_parsed_expression_simplify_to("binomial([[0,180]],[[1]])", Undefined::Name()); + assert_parsed_expression_simplify_to("ceil([[0.3,180]])", "[[1,180]]"); + assert_parsed_expression_simplify_to("arg([[1,1+𝐒]])", "[[0,Ο€/4]]"); + assert_parsed_expression_simplify_to("confidence([[0,180]],1)", Undefined::Name()); + assert_parsed_expression_simplify_to("confidence(1,[[0,180]])", Undefined::Name()); + assert_parsed_expression_simplify_to("confidence([[0,180]],[[1]])", Undefined::Name()); + assert_parsed_expression_simplify_to("confidence(1/3, 25)", "[[2/15,8/15]]"); + assert_parsed_expression_simplify_to("confidence(45, 25)", Undefined::Name()); + assert_parsed_expression_simplify_to("confidence(1/3, -34)", Undefined::Name()); + assert_parsed_expression_simplify_to("conj([[1,1+𝐒]])", "[[1,1-𝐒]]"); + assert_parsed_expression_simplify_to("cos([[Ο€/3,0][Ο€/7,Ο€/2]])", "[[1/2,1][cos(Ο€/7),0]]"); + assert_parsed_expression_simplify_to("cos([[0,Ο€]])", "[[1,-1]]"); + assert_parsed_expression_simplify_to("diff([[0,180]],x,1)", Undefined::Name()); + assert_parsed_expression_simplify_to("diff(1,x,[[0,180]])", Undefined::Name()); + assert_parsed_expression_simplify_to("quo([[0,180]],1)", Undefined::Name()); + assert_parsed_expression_simplify_to("quo(1,[[0,180]])", Undefined::Name()); + assert_parsed_expression_simplify_to("quo([[0,180]],[[1]])", Undefined::Name()); + assert_parsed_expression_simplify_to("rem([[0,180]],1)", Undefined::Name()); + assert_parsed_expression_simplify_to("rem(1,[[0,180]])", Undefined::Name()); + assert_parsed_expression_simplify_to("rem([[0,180]],[[1]])", Undefined::Name()); + assert_parsed_expression_simplify_to("factor([[0,180]])", Undefined::Name()); + assert_parsed_expression_simplify_to("[[1,3]]!", "[[1,6]]"); + assert_parsed_expression_simplify_to("[[1,2][3,4]]!", "[[1,2][6,24]]"); + assert_parsed_expression_simplify_to("floor([[1/√(2),1/2][1,-1.3]])", "[[floor(√(2)/2),0][1,-2]]"); + assert_parsed_expression_simplify_to("floor([[0.3,180]])", "[[0,180]]"); + assert_parsed_expression_simplify_to("frac([[1/√(2),1/2][1,-1.3]])", "[[frac(√(2)/2),1/2][0,7/10]]"); + assert_parsed_expression_simplify_to("frac([[0.3,180]])", "[[3/10,0]]"); + assert_parsed_expression_simplify_to("gcd([[0,180]],1)", Undefined::Name()); + assert_parsed_expression_simplify_to("gcd(1,[[0,180]])", Undefined::Name()); + assert_parsed_expression_simplify_to("gcd([[0,180]],[[1]])", Undefined::Name()); + assert_parsed_expression_simplify_to("acosh([[0,Ο€]])", "[[acosh(0),acosh(Ο€)]]"); + assert_parsed_expression_simplify_to("asinh([[0,Ο€]])", "[[asinh(0),asinh(Ο€)]]"); + assert_parsed_expression_simplify_to("atanh([[0,Ο€]])", "[[atanh(0),atanh(Ο€)]]"); + assert_parsed_expression_simplify_to("cosh([[0,Ο€]])", "[[cosh(0),cosh(Ο€)]]"); + assert_parsed_expression_simplify_to("sinh([[0,Ο€]])", "[[sinh(0),sinh(Ο€)]]"); + assert_parsed_expression_simplify_to("tanh([[0,Ο€]])", "[[tanh(0),tanh(Ο€)]]"); + assert_parsed_expression_simplify_to("im([[1/√(2),1/2][1,-1]])", "[[0,0][0,0]]"); + assert_parsed_expression_simplify_to("im([[1,1+𝐒]])", "[[0,1]]"); + assert_parsed_expression_simplify_to("int([[0,180]],x,1,2)", Undefined::Name()); + assert_parsed_expression_simplify_to("int(1,x,[[0,180]],1)", Undefined::Name()); + assert_parsed_expression_simplify_to("int(1,x,1,[[0,180]])", Undefined::Name()); + assert_parsed_expression_simplify_to("log([[2,3]])", "[[log(2),log(3)]]"); + assert_parsed_expression_simplify_to("log([[2,3]],5)", "[[log(2,5),log(3,5)]]"); + assert_parsed_expression_simplify_to("log(5,[[2,3]])", Undefined::Name()); + assert_parsed_expression_simplify_to("log([[√(2),1/2][1,3]])", "[[log(2)/2,-log(2)][0,log(3)]]"); + assert_parsed_expression_simplify_to("log([[1/√(2),1/2][1,-3]])", "[[-log(2)/2,-log(2)][0,log(-3)]]"); // ComplexFormat is Cartesian + assert_parsed_expression_simplify_to("log([[1/√(2),1/2][1,-3]],3)", "[[-log(2,3)/2,-log(2,3)][0,log(-3,3)]]"); + assert_parsed_expression_simplify_to("ln([[2,3]])", "[[ln(2),ln(3)]]"); + assert_parsed_expression_simplify_to("ln([[√(2),1/2][1,3]])", "[[ln(2)/2,-ln(2)][0,ln(3)]]"); + assert_parsed_expression_simplify_to("root([[2,3]],5)", Undefined::Name()); + assert_parsed_expression_simplify_to("root(5,[[2,3]])", Undefined::Name()); + assert_parsed_expression_simplify_to("-[[1/√(2),1/2,3][2,1,-3]]", "[[-√(2)/2,-1/2,-3][-2,-1,3]]"); + assert_parsed_expression_simplify_to("permute([[2,3]],5)", Undefined::Name()); + assert_parsed_expression_simplify_to("permute(5,[[2,3]])", Undefined::Name()); + assert_parsed_expression_simplify_to("prediction([[2,3]],5)", Undefined::Name()); + assert_parsed_expression_simplify_to("prediction(5,[[2,3]])", Undefined::Name()); + assert_parsed_expression_simplify_to("prediction95([[2,3]],5)", Undefined::Name()); + assert_parsed_expression_simplify_to("prediction95(5,[[2,3]])", Undefined::Name()); + assert_parsed_expression_simplify_to("prediction95(1/3, 25)", "[[\u0012-49√(2)+125\u0013/375,\u001249√(2)+125\u0013/375]]"); + assert_parsed_expression_simplify_to("prediction95(45, 25)", Undefined::Name()); + assert_parsed_expression_simplify_to("prediction95(1/3, -34)", Undefined::Name()); + assert_parsed_expression_simplify_to("product(1,x,[[0,180]],1)", Undefined::Name()); + assert_parsed_expression_simplify_to("product(1,x,1,[[0,180]])", Undefined::Name()); + assert_parsed_expression_simplify_to("randint([[2,3]],5)", Undefined::Name()); + assert_parsed_expression_simplify_to("randint(5,[[2,3]])", Undefined::Name()); + assert_parsed_expression_simplify_to("re([[1,𝐒]])", "[[1,0]]"); + assert_parsed_expression_simplify_to("round([[2.12,3.42]], 1)", "[[21/10,17/5]]"); + assert_parsed_expression_simplify_to("round(1.3, [[2.1,3.4]])", Undefined::Name()); + assert_parsed_expression_simplify_to("round(1.3, [[2.1,3.4]])", Undefined::Name()); + assert_parsed_expression_simplify_to("sign([[2.1,3.4]])", Undefined::Name()); + assert_parsed_expression_simplify_to("sin([[Ο€/3,0][Ο€/7,Ο€/2]])", "[[√(3)/2,0][sin(Ο€/7),1]]"); + assert_parsed_expression_simplify_to("sin([[0,Ο€]])", "[[0,0]]"); + assert_parsed_expression_simplify_to("sum(1,x,[[0,180]],1)", Undefined::Name()); + assert_parsed_expression_simplify_to("sum(1,x,1,[[0,180]])", Undefined::Name()); + assert_parsed_expression_simplify_to("√([[2.1,3.4]])", Undefined::Name()); + assert_parsed_expression_simplify_to("[[2,3.4]]-[[0.1,3.1]]", "[[19/10,3/10]]"); + assert_parsed_expression_simplify_to("[[2,3.4]]-1", Undefined::Name()); + assert_parsed_expression_simplify_to("1-[[0.1,3.1]]", Undefined::Name()); + assert_parsed_expression_simplify_to("tan([[0,Ο€/4]])", "[[0,1]]"); +} + +QUIZ_CASE(poincare_simplification_store) { + assert_parsed_expression_simplify_to("1+2β†’x", "3"); + assert_parsed_expression_simplify_to("0.1+0.2β†’x", "3/10"); + assert_parsed_expression_simplify_to("a+aβ†’x", "2Γ—a"); + + // Clean the storage for other tests + Ion::Storage::sharedStorage()->recordNamed("x.exp").destroy(); +} + +QUIZ_CASE(poincare_simplification_store_matrix) { + assert_parsed_expression_simplify_to("1+1β†’a", "2"); + assert_parsed_expression_simplify_to("[[8]]β†’f(x)", "[[8]]"); + assert_parsed_expression_simplify_to("[[x]]β†’f(x)", "[[x]]"); + + // Clean the storage for other tests + Ion::Storage::sharedStorage()->recordNamed("a.exp").destroy(); + Ion::Storage::sharedStorage()->recordNamed("f.func").destroy(); +} + +QUIZ_CASE(poincare_simplification_complex_format) { + // Real + assert_parsed_expression_simplify_to("𝐒", "unreal", User, Radian, Real); + assert_parsed_expression_simplify_to("√(-1)", "unreal", User, Radian, Real); + assert_parsed_expression_simplify_to("√(-1)Γ—βˆš(-1)", "unreal", User, Radian, Real); + assert_parsed_expression_simplify_to("ln(-2)", "unreal", User, Radian, Real); + assert_parsed_expression_simplify_to("(-8)^(2/3)", "4", User, Radian, Real); + assert_parsed_expression_simplify_to("(-8)^(2/5)", "2Γ—root(2,5)", User, Radian, Real); + assert_parsed_expression_simplify_to("(-8)^(1/5)", "-root(8,5)", User, Radian, Real); + assert_parsed_expression_simplify_to("(-8)^(1/4)", "unreal", User, Radian, Real); + assert_parsed_expression_simplify_to("(-8)^(1/3)", "-2", User, Radian, Real); + + // User defined variable + assert_parsed_expression_simplify_to("a", "a", User, Radian, Real); + // a = 2+i + assert_simplify("2+𝐒→a", Radian, Real); + assert_parsed_expression_simplify_to("a", "unreal", User, Radian, Real); + // Clean the storage for other tests + Ion::Storage::sharedStorage()->recordNamed("a.exp").destroy(); + // User defined function + assert_parsed_expression_simplify_to("f(3)", "f(3)", User, Radian, Real); + // f : x β†’ x+1 + assert_simplify("x+1+𝐒→f(x)", Radian, Real); + assert_parsed_expression_simplify_to("f(3)", "unreal", User, Radian, Real); + // Clean the storage for other tests + Ion::Storage::sharedStorage()->recordNamed("f.func").destroy(); + + + // Cartesian + assert_parsed_expression_simplify_to("-2.3ᴇ3", "-2300", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("3", "3", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("inf", "inf", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("1+2+𝐒", "3+𝐒", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("-(5+2×𝐒)", "-5-2𝐒", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("(5+2×𝐒)", "5+2𝐒", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("𝐒+𝐒", "2𝐒", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("-2+2×𝐒", "-2+2𝐒", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("(3+𝐒)-(2+4×𝐒)", "1-3𝐒", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("(2+3×𝐒)Γ—(4-2×𝐒)", "14+8𝐒", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("(3+𝐒)/2", "3/2+\u00121/2\u0013𝐒", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("(3+𝐒)/(2+𝐒)", "7/5-\u00121/5\u0013𝐒", User, Radian, Cartesian); + // The simplification of (3+𝐒)^(2+𝐒) in a Cartesian complex form generates to many nodes + //assert_parsed_expression_simplify_to("(3+𝐒)^(2+𝐒)", "10Γ—cos((-4Γ—atan(3)+ln(2)+ln(5)+2Γ—Ο€)/2)Γ—β„―^((2Γ—atan(3)-Ο€)/2)+10Γ—sin((-4Γ—atan(3)+ln(2)+ln(5)+2Γ—Ο€)/2)Γ—β„―^((2Γ—atan(3)-Ο€)/2)𝐒", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("(3+𝐒)^(2+𝐒)", "(𝐒+3)^\u0012𝐒+2\u0013", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("√(1+6𝐒)", "√(2√(37)+2)/2+\u0012√(2√(37)-2)/2\u0013𝐒", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("(1+𝐒)^2", "2𝐒", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("2×𝐒", "2𝐒", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("𝐒!", "𝐒!", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("3!", "6", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("x!", "x!", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("β„―", "β„―", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("Ο€", "Ο€", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("𝐒", "𝐒", User, Radian, Cartesian); + + assert_parsed_expression_simplify_to("abs(-3)", "3", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("abs(-3+𝐒)", "√(10)", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("atan(2)", "atan(2)", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("atan(2+𝐒)", "atan(2+𝐒)", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("binomial(10, 4)", "210", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("ceil(-1.3)", "-1", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("arg(-2)", "Ο€", User, Radian, Cartesian); + // TODO: confidence is not simplified yet + //assert_parsed_expression_simplify_to("confidence(-2,-3)", "confidence(-2)", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("conj(-2)", "-2", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("conj(-2+2×𝐒+𝐒)", "-2-3𝐒", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("cos(12)", "cos(12)", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("cos(12+𝐒)", "cos(12+𝐒)", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("diff(3Γ—x, x, 3)", "diff(3Γ—x,x,3)", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("quo(34,x)", "quo(34,x)", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("rem(5,3)", "2", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("floor(x)", "floor(x)", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("frac(x)", "frac(x)", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("gcd(x,y)", "gcd(x,y)", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("im(1+𝐒)", "1", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("int(x^2, x, 1, 2)", "int(x^2,x,1,2)", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("lcm(x,y)", "lcm(x,y)", User, Radian, Cartesian); + // TODO: dim is not simplified yet + //assert_parsed_expression_simplify_to("dim(x)", "dim(x)", User, Radian, Cartesian); + + assert_parsed_expression_simplify_to("root(2,𝐒)", "cos(ln(2))-sin(ln(2))𝐒", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("root(2,𝐒+1)", "√(2)Γ—cos(\u001290Γ—ln(2)\u0013/Ο€)-√(2)Γ—sin(\u001290Γ—ln(2)\u0013/Ο€)𝐒", User, Degree, Cartesian); + assert_parsed_expression_simplify_to("root(2,𝐒+1)", "√(2)Γ—cos(ln(2)/2)-√(2)Γ—sin(ln(2)/2)𝐒", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("permute(10, 4)", "5040", User, Radian, Cartesian); + // TODO: prediction is not simplified yet + //assert_parsed_expression_simplify_to("prediction(-2,-3)", "prediction(-2)", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("randint(2,2)", "2", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("random()", "random()", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("re(x)", "re(x)", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("round(x,y)", "round(x,y)", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("sign(x)", "sign(x)", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("sin(23)", "sin(23)", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("sin(23+𝐒)", "sin(23+𝐒)", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("√(1-𝐒)", "√(2√(2)+2)/2-\u0012√(2√(2)-2)/2\u0013𝐒", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("tan(23)", "tan(23)", User, Radian, Cartesian); + assert_parsed_expression_simplify_to("tan(23+𝐒)", "tan(23+𝐒)", User, Radian, Cartesian); + + // User defined variable + assert_parsed_expression_simplify_to("a", "a", User, Radian, Cartesian); + // a = 2+i + assert_simplify("2+𝐒→a", Radian, Cartesian); + assert_parsed_expression_simplify_to("a", "2+𝐒", User, Radian, Cartesian); + // Clean the storage for other tests + Ion::Storage::sharedStorage()->recordNamed("a.exp").destroy(); + // User defined function + assert_parsed_expression_simplify_to("f(3)", "f(3)", User, Radian, Cartesian); + // f : x β†’ x+1 + assert_simplify("x+1+𝐒→f(x)", Radian, Cartesian); + assert_parsed_expression_simplify_to("f(3)", "4+𝐒", User, Radian, Cartesian); + // Clean the storage for other tests + Ion::Storage::sharedStorage()->recordNamed("f.func").destroy(); + + // Polar + assert_parsed_expression_simplify_to("-2.3ᴇ3", "2300β„―^\u0012π𝐒\u0013", User, Radian, Polar); + assert_parsed_expression_simplify_to("3", "3", User, Radian, Polar); + assert_parsed_expression_simplify_to("inf", "inf", User, Radian, Polar); + assert_parsed_expression_simplify_to("1+2+𝐒", "√(10)β„―^\u0012\u0012\u0012-2Γ—atan(3)+Ο€\u0013/2\u0013𝐒\u0013", User, Radian, Polar); + assert_parsed_expression_simplify_to("1+2+𝐒", "√(10)β„―^\u0012\u0012\u0012-π×atan(3)+90Ο€\u0013/180\u0013𝐒\u0013", User, Degree, Polar); + assert_parsed_expression_simplify_to("-(5+2×𝐒)", "√(29)β„―^\u0012\u0012\u0012-2Γ—atan(5/2)-Ο€\u0013/2\u0013𝐒\u0013", User, Radian, Polar); + assert_parsed_expression_simplify_to("(5+2×𝐒)", "√(29)β„―^\u0012\u0012\u0012-2Γ—atan(5/2)+Ο€\u0013/2\u0013𝐒\u0013", User, Radian, Polar); + assert_parsed_expression_simplify_to("𝐒+𝐒", "2β„―^\u0012\u0012Ο€/2\u0013𝐒\u0013", User, Radian, Polar); + assert_parsed_expression_simplify_to("𝐒+𝐒", "2β„―^\u0012\u0012Ο€/2\u0013𝐒\u0013", User, Radian, Polar); + assert_parsed_expression_simplify_to("-2+2×𝐒", "2√(2)β„―^\u0012\u00123Ο€/4\u0013𝐒\u0013", User, Radian, Polar); + assert_parsed_expression_simplify_to("(3+𝐒)-(2+4×𝐒)", "√(10)β„―^\u0012\u0012\u00122Γ—atan(1/3)-Ο€\u0013/2\u0013𝐒\u0013", User, Radian, Polar); + assert_parsed_expression_simplify_to("(2+3×𝐒)Γ—(4-2×𝐒)", "2√(65)β„―^\u0012\u0012\u0012-2Γ—atan(7/4)+Ο€\u0013/2\u0013𝐒\u0013", User, Radian, Polar); + assert_parsed_expression_simplify_to("(3+𝐒)/2", "\u0012√(10)/2\u0013β„―^\u0012\u0012\u0012-2Γ—atan(3)+Ο€\u0013/2\u0013𝐒\u0013", User, Radian, Polar); + assert_parsed_expression_simplify_to("(3+𝐒)/(2+𝐒)", "√(2)β„―^\u0012\u0012\u00122Γ—atan(7)-Ο€\u0013/2\u0013𝐒\u0013", User, Radian, Polar); + // TODO: simplify atan(tan(x)) = xΒ±kΓ—pi? + //assert_parsed_expression_simplify_to("(3+𝐒)^(2+𝐒)", "10β„―^\u0012\u00122Γ—atan(3)-Ο€\u0013/2\u0013Γ—β„―^\u0012\u0012\u0012-4Γ—atan(3)+ln(2)+ln(5)+2Ο€\u0013/2\u0013𝐒\u0013", User, Radian, Polar); + // The simplification of (3+𝐒)^(2+𝐒) in a Polar complex form generates to many nodes + //assert_parsed_expression_simplify_to("(3+𝐒)^(2+𝐒)", "10β„―^\u0012\u00122Γ—atan(3)-Ο€\u0013/2\u0013Γ—β„―^\u0012\u0012atan(tan((-4Γ—atan(3)+ln(2)+ln(5)+2Γ—Ο€)/2))+Ο€\u0013𝐒\u0013", User, Radian, Polar); + assert_parsed_expression_simplify_to("(3+𝐒)^(2+𝐒)", "(𝐒+3)^\u0012𝐒+2\u0013", User, Radian, Polar); + assert_parsed_expression_simplify_to("(1+𝐒)^2", "2β„―^\u0012\u0012Ο€/2\u0013𝐒\u0013", User, Radian, Polar); + assert_parsed_expression_simplify_to("2×𝐒", "2β„―^\u0012\u0012Ο€/2\u0013𝐒\u0013", User, Radian, Polar); + assert_parsed_expression_simplify_to("3!", "6", User, Radian, Polar); + assert_parsed_expression_simplify_to("x!", "x!", User, Radian, Polar); + assert_parsed_expression_simplify_to("β„―", "β„―", User, Radian, Polar); + assert_parsed_expression_simplify_to("Ο€", "Ο€", User, Radian, Polar); + assert_parsed_expression_simplify_to("𝐒", "β„―^\u0012\u0012Ο€/2\u0013𝐒\u0013", User, Radian, Polar); + assert_parsed_expression_simplify_to("abs(-3)", "3", User, Radian, Polar); + assert_parsed_expression_simplify_to("abs(-3+𝐒)", "√(10)", User, Radian, Polar); + assert_parsed_expression_simplify_to("conj(2Γ—β„―^(𝐒×π/2))", "2β„―^\u0012-\u0012Ο€/2\u0013𝐒\u0013", User, Radian, Polar); + assert_parsed_expression_simplify_to("-2Γ—β„―^(𝐒×π/2)", "2β„―^\u0012-\u0012Ο€/2\u0013𝐒\u0013", User, Radian, Polar); + + // User defined variable + assert_parsed_expression_simplify_to("a", "a", User, Radian, Polar); + // a = 2 + 𝐒 + assert_simplify("2+𝐒→a", Radian, Polar); + assert_parsed_expression_simplify_to("a", "√(5)β„―^\u0012\u0012\u0012-2Γ—atan(2)+Ο€\u0013/2\u0013𝐒\u0013", User, Radian, Polar); + // Clean the storage for other tests + Ion::Storage::sharedStorage()->recordNamed("a.exp").destroy(); + // User defined function + assert_parsed_expression_simplify_to("f(3)", "f(3)", User, Radian, Polar); + // f: x β†’ x+1 + assert_simplify("x+1+𝐒→f(x)", Radian, Polar); + assert_parsed_expression_simplify_to("f(3)", "√(17)β„―^\u0012\u0012\u0012-2Γ—atan(4)+Ο€\u0013/2\u0013𝐒\u0013", User, Radian, Polar); + // Clean the storage for other tests + Ion::Storage::sharedStorage()->recordNamed("f.func").destroy(); +} + +QUIZ_CASE(poincare_simplification_reduction_target) { + assert_parsed_expression_simplify_to("1/Ο€+1/x", "1/x+1/Ο€", System); + assert_parsed_expression_simplify_to("1/Ο€+1/x", "\u0012x+Ο€\u0013/\u0012π×x\u0013", User); + + assert_parsed_expression_simplify_to("1/(1+𝐒)", "1/\u0012𝐒+1\u0013", System); + assert_parsed_expression_simplify_to("1/(1+𝐒)", "1/2-\u00121/2\u0013𝐒", User); + + assert_parsed_expression_simplify_to("sin(x)/(cos(x)Γ—cos(x))", "sin(x)/cos(x)^2", System); + assert_parsed_expression_simplify_to("sin(x)/(cos(x)Γ—cos(x))", "tan(x)/cos(x)", User); + + assert_parsed_expression_simplify_to("x^0", "x^0", System); + assert_parsed_expression_simplify_to("x^0", "1", User); + + assert_parsed_expression_simplify_to("x^(2/3)", "root(x,3)^2", System); + assert_parsed_expression_simplify_to("x^(2/3)", "x^\u00122/3\u0013", User); + assert_parsed_expression_simplify_to("x^(1/3)", "root(x,3)", System); + assert_parsed_expression_simplify_to("x^(1/3)", "root(x,3)", System); + assert_parsed_expression_simplify_to("x^2", "x^2", System); + assert_parsed_expression_simplify_to("x^2", "x^2", User); + + assert_parsed_expression_simplify_to("1/(√(2)+√(3))", "1/\u0012√(3)+√(2)\u0013", System); + assert_parsed_expression_simplify_to("1/(√(2)+√(3))", "√(3)-√(2)", User); + + assert_parsed_expression_simplify_to("sign(abs(x))", "sign(abs(x))", System); + assert_parsed_expression_simplify_to("sign(abs(x))", "1", User); + + assert_parsed_expression_simplify_to("atan(1/x)", "atan(1/x)", System); + assert_parsed_expression_simplify_to("atan(1/x)", "\u0012π×sign(x)-2Γ—atan(x)\u0013/2", User); + + assert_parsed_expression_simplify_to("(1+x)/(1+x)", "(x+1)^0", System); + assert_parsed_expression_simplify_to("(1+x)/(1+x)", "1", User); +} + +QUIZ_CASE(poincare_simplification_mix) { + // Root at denominator + assert_parsed_expression_simplify_to("1/(√(2)+√(3))", "√(3)-√(2)"); + assert_parsed_expression_simplify_to("1/(5+√(3))", "\u0012-√(3)+5\u0013/22"); + assert_parsed_expression_simplify_to("1/(√(2)+4)", "\u0012-√(2)+4\u0013/14"); + assert_parsed_expression_simplify_to("1/(2√(2)-4)", "\u0012-√(2)-2\u0013/4"); + assert_parsed_expression_simplify_to("1/(-2√(2)+4)", "\u0012√(2)+2\u0013/4"); + assert_parsed_expression_simplify_to("45^2", "2025"); + assert_parsed_expression_simplify_to("1/(√(2)ln(3))", "√(2)/\u00122Γ—ln(3)\u0013"); + assert_parsed_expression_simplify_to("√(3/2)", "√(6)/2"); + + // Common operation mix + assert_parsed_expression_simplify_to("(√(2)Γ—Ο€ + √(2)Γ—β„―)/√(2)", "β„―+Ο€"); + assert_parsed_expression_simplify_to("Ο€+(3√(2)-2√(3))/25", "\u001225Ο€-2√(3)+3√(2)\u0013/25"); + assert_parsed_expression_simplify_to("ln(2+3)", "ln(5)"); + assert_parsed_expression_simplify_to("3Γ—AΓ—BΓ—C+4Γ—cos(2)-2Γ—AΓ—BΓ—C+AΓ—BΓ—C+ln(3)+4Γ—AΓ—B-5Γ—AΓ—BΓ—C+cos(3)Γ—ln(5)+cos(2)-45Γ—cos(2)", "cos(3)Γ—ln(5)+ln(3)-40Γ—cos(2)+4Γ—AΓ—B-3Γ—AΓ—BΓ—C"); + assert_parsed_expression_simplify_to("2Γ—A+3Γ—cos(2)+3+4Γ—ln(5)+5Γ—A+2Γ—ln(5)+1+0", "6Γ—ln(5)+3Γ—cos(2)+7Γ—A+4"); + assert_parsed_expression_simplify_to("2.3Γ—A+3Γ—cos(2)+3+4Γ—ln(5)+5Γ—A+2Γ—ln(5)+1.2+0.235", "\u00121200Γ—ln(5)+600Γ—cos(2)+1460Γ—A+887\u0013/200"); + assert_parsed_expression_simplify_to("2Γ—AΓ—BΓ—C+2.3Γ—AΓ—B+3Γ—A^2+5.2Γ—AΓ—BΓ—C+4Γ—A^2", "\u001270Γ—A^2+23Γ—AΓ—B+72Γ—AΓ—BΓ—C\u0013/10"); + assert_parsed_expression_simplify_to("(AΓ—B)^2Γ—A+4Γ—A^3", "4Γ—A^3+A^3Γ—B^2"); + assert_parsed_expression_simplify_to("(AΓ—3)^2Γ—A+4Γ—A^3", "13Γ—A^3"); + assert_parsed_expression_simplify_to("A^2^2Γ—A+4Γ—A^3", "A^5+4Γ—A^3"); + assert_parsed_expression_simplify_to("0.5+4Γ—AΓ—B-2.3+2Γ—AΓ—B-2Γ—BΓ—A^C-cos(4)+2Γ—A^CΓ—B+AΓ—BΓ—CΓ—D", "\u0012-5Γ—cos(4)+30Γ—AΓ—B+5Γ—AΓ—BΓ—CΓ—D-9\u0013/5"); + assert_parsed_expression_simplify_to("(1+√(2))/5", "\u0012√(2)+1\u0013/5"); + assert_parsed_expression_simplify_to("(2+√(6))^2", "4√(6)+10"); + assert_parsed_expression_simplify_to("tan(3)ln(2)+Ο€", "tan(3)Γ—ln(2)+Ο€"); + + // Complex + assert_parsed_expression_simplify_to("𝐒", "𝐒"); + assert_parsed_expression_simplify_to("√(-33)", "√(33)𝐒"); + assert_parsed_expression_simplify_to("𝐒^(3/5)", "√(2)√(-√(5)+5)/4+\u0012\u0012√(5)+1\u0013/4\u0013𝐒"); + assert_parsed_expression_simplify_to("𝐒𝐒𝐒𝐒", "1"); + assert_parsed_expression_simplify_to("√(-𝐒)", "√(2)/2-\u0012√(2)/2\u0013𝐒"); + 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-\u0012√(2)/32\u0013𝐒"); + assert_parsed_expression_simplify_to("root(5^((-𝐒)3^9),𝐒)", "1/β„―^atan(tan(19683Γ—ln(5)))"); + 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"); + + //assert_parsed_expression_simplify_to("log(cos(9)^ln(6), cos(9))", "ln(2)+ln(3)"); // TODO: for this to work, we must know the sign of cos(9) + //assert_parsed_expression_simplify_to("log(cos(9)^ln(6), 9)", "ln(6)Γ—log(cos(9), 9)"); // TODO: for this to work, we must know the sign of cos(9) + assert_parsed_expression_simplify_to("(((√(6)-√(2))/4)/((√(6)+√(2))/4))+1", "-√(3)+3"); + assert_parsed_expression_simplify_to("1/√(𝐒) Γ— (√(2)-π’Γ—βˆš(2))", "-2𝐒"); // TODO: get rid of complex at denominator? +} diff --git a/poincare/test/simplify.cpp b/poincare/test/simplify.cpp deleted file mode 100644 index 101f85e8c..000000000 --- a/poincare/test/simplify.cpp +++ /dev/null @@ -1,84 +0,0 @@ -#include -#include -#include -#include "helper.h" - -using namespace Poincare; -QUIZ_CASE(poincare_reduction_target) { - assert_parsed_expression_simplify_to("1/Ο€+1/x", "1/x+1/Ο€", System); - assert_parsed_expression_simplify_to("1/Ο€+1/x", "(x+Ο€)/(π×x)", User); - - assert_parsed_expression_simplify_to("1/(1+𝐒)", "1/(𝐒+1)", System); - assert_parsed_expression_simplify_to("1/(1+𝐒)", "1/2-1/2×𝐒", User); - - assert_parsed_expression_simplify_to("sin(x)/(cos(x)Γ—cos(x))", "sin(x)/cos(x)^2", System); - assert_parsed_expression_simplify_to("sin(x)/(cos(x)Γ—cos(x))", "tan(x)/cos(x)", User); - - assert_parsed_expression_simplify_to("x^0", "x^0", System); - assert_parsed_expression_simplify_to("x^0", "1", User); - - assert_parsed_expression_simplify_to("x^(2/3)", "root(x,3)^2", System); - assert_parsed_expression_simplify_to("x^(2/3)", "x^(2/3)", User); - assert_parsed_expression_simplify_to("x^(1/3)", "root(x,3)", System); - assert_parsed_expression_simplify_to("x^(1/3)", "root(x,3)", System); - assert_parsed_expression_simplify_to("x^2", "x^2", System); - assert_parsed_expression_simplify_to("x^2", "x^2", User); - - assert_parsed_expression_simplify_to("1/(√(2)+√(3))", "1/(√(3)+√(2))", System); - assert_parsed_expression_simplify_to("1/(√(2)+√(3))", "√(3)-√(2)", User); - - assert_parsed_expression_simplify_to("sign(abs(x))", "sign(abs(x))", System); - assert_parsed_expression_simplify_to("sign(abs(x))", "1", User); - - assert_parsed_expression_simplify_to("atan(1/x)", "atan(1/x)", System); - assert_parsed_expression_simplify_to("atan(1/x)", "(π×sign(x)-2Γ—atan(x))/2", User); - - assert_parsed_expression_simplify_to("(1+x)/(1+x)", "(x+1)^0", System); - assert_parsed_expression_simplify_to("(1+x)/(1+x)", "1", User); -} - -QUIZ_CASE(poincare_simplify_mix) { - // Root at denominator - assert_parsed_expression_simplify_to("1/(√(2)+√(3))", "√(3)-√(2)"); - assert_parsed_expression_simplify_to("1/(5+√(3))", "(-√(3)+5)/22"); - assert_parsed_expression_simplify_to("1/(√(2)+4)", "(-√(2)+4)/14"); - assert_parsed_expression_simplify_to("1/(2√(2)-4)", "(-√(2)-2)/4"); - assert_parsed_expression_simplify_to("1/(-2√(2)+4)", "(√(2)+2)/4"); - assert_parsed_expression_simplify_to("45^2", "2025"); - assert_parsed_expression_simplify_to("1/(√(2)ln(3))", "√(2)/(2Γ—ln(3))"); - assert_parsed_expression_simplify_to("√(3/2)", "√(6)/2"); - - // Common operation mix - assert_parsed_expression_simplify_to("(√(2)Γ—Ο€ + √(2)Γ—β„―)/√(2)", "β„―+Ο€"); - assert_parsed_expression_simplify_to("Ο€+(3√(2)-2√(3))/25", "(25Γ—Ο€-2Γ—βˆš(3)+3Γ—βˆš(2))/25"); - assert_parsed_expression_simplify_to("ln(2+3)", "ln(5)"); - assert_parsed_expression_simplify_to("3Γ—AΓ—BΓ—C+4Γ—cos(2)-2Γ—AΓ—BΓ—C+AΓ—BΓ—C+ln(3)+4Γ—AΓ—B-5Γ—AΓ—BΓ—C+cos(3)Γ—ln(5)+cos(2)-45Γ—cos(2)", "cos(3)Γ—ln(5)+ln(3)-40Γ—cos(2)+4Γ—AΓ—B-3Γ—AΓ—BΓ—C"); - assert_parsed_expression_simplify_to("2Γ—A+3Γ—cos(2)+3+4Γ—ln(5)+5Γ—A+2Γ—ln(5)+1+0", "6Γ—ln(5)+3Γ—cos(2)+7Γ—A+4"); - assert_parsed_expression_simplify_to("2.3Γ—A+3Γ—cos(2)+3+4Γ—ln(5)+5Γ—A+2Γ—ln(5)+1.2+0.235", "(1200Γ—ln(5)+600Γ—cos(2)+1460Γ—A+887)/200"); - assert_parsed_expression_simplify_to("2Γ—AΓ—BΓ—C+2.3Γ—AΓ—B+3Γ—A^2+5.2Γ—AΓ—BΓ—C+4Γ—A^2", "(70Γ—A^2+23Γ—AΓ—B+72Γ—AΓ—BΓ—C)/10"); - assert_parsed_expression_simplify_to("(AΓ—B)^2Γ—A+4Γ—A^3", "4Γ—A^3+A^3Γ—B^2"); - assert_parsed_expression_simplify_to("(AΓ—3)^2Γ—A+4Γ—A^3", "13Γ—A^3"); - assert_parsed_expression_simplify_to("A^2^2Γ—A+4Γ—A^3", "A^5+4Γ—A^3"); - assert_parsed_expression_simplify_to("0.5+4Γ—AΓ—B-2.3+2Γ—AΓ—B-2Γ—BΓ—A^C-cos(4)+2Γ—A^CΓ—B+AΓ—BΓ—CΓ—D", "(-5Γ—cos(4)+30Γ—AΓ—B+5Γ—AΓ—BΓ—CΓ—D-9)/5"); - assert_parsed_expression_simplify_to("(1+√(2))/5", "(√(2)+1)/5"); - assert_parsed_expression_simplify_to("(2+√(6))^2", "4Γ—βˆš(6)+10"); - assert_parsed_expression_simplify_to("tan(3)ln(2)+Ο€", "tan(3)Γ—ln(2)+Ο€"); - - // Complex - assert_parsed_expression_simplify_to("𝐒", "𝐒"); - assert_parsed_expression_simplify_to("√(-33)", "√(33)×𝐒"); - assert_parsed_expression_simplify_to("𝐒^(3/5)", "(√(2)Γ—βˆš(-√(5)+5))/4+(√(5)+1)/4×𝐒"); - assert_parsed_expression_simplify_to("𝐒𝐒𝐒𝐒", "1"); - 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("𝐒^𝐒", "1/β„―^(Ο€/2)"); - assert_parsed_expression_simplify_to("𝐒/(1+π’Γ—βˆš(x))", "𝐒/(√(x)×𝐒+1)"); - assert_parsed_expression_simplify_to("x+𝐒/(1+π’Γ—βˆš(x))", "(x^(3/2)×𝐒+𝐒+x)/(√(x)×𝐒+1)"); - - //assert_parsed_expression_simplify_to("log(cos(9)^ln(6), cos(9))", "ln(2)+ln(3)"); // TODO: for this to work, we must know the sign of cos(9) - //assert_parsed_expression_simplify_to("log(cos(9)^ln(6), 9)", "ln(6)Γ—log(cos(9), 9)"); // TODO: for this to work, we must know the sign of cos(9) - assert_parsed_expression_simplify_to("(((√(6)-√(2))/4)/((√(6)+√(2))/4))+1", "-√(3)+3"); - //assert_parsed_expression_simplify_to("1/√(𝐒) Γ— (√(2)-π’Γ—βˆš(2))", "-2𝐒"); // TODO: get rid of complex at denominator? -} diff --git a/poincare/test/store.cpp b/poincare/test/store.cpp deleted file mode 100644 index bcd7d9387..000000000 --- a/poincare/test/store.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#include -#include -#include -#include "helper.h" - -using namespace Poincare; - -QUIZ_CASE(poincare_store_evaluate) { - assert_parsed_expression_evaluates_to("1+42β†’A", "43"); - assert_parsed_expression_evaluates_to("0.123+𝐒→B", "0.123+𝐒"); - - // Clean the storage for other tests - Ion::Storage::sharedStorage()->recordNamed("A.exp").destroy(); - Ion::Storage::sharedStorage()->recordNamed("B.exp").destroy(); -} - -QUIZ_CASE(poincare_store_simplify) { - assert_parsed_expression_simplify_to("1+2β†’x", "3"); - assert_parsed_expression_simplify_to("0.1+0.2β†’x", "3/10"); - assert_parsed_expression_simplify_to("a+aβ†’x", "2Γ—a"); - - // Clean the storage for other tests - Ion::Storage::sharedStorage()->recordNamed("x.exp").destroy(); -} - -QUIZ_CASE(poincare_store_matrix) { - assert_parsed_expression_evaluates_to("[[7]]β†’a", "[[7]]"); - assert_parsed_expression_simplify_to("1+1β†’a", "2"); - assert_parsed_expression_simplify_to("[[8]]β†’f(x)", "[[8]]"); - assert_parsed_expression_simplify_to("[[x]]β†’f(x)", "[[x]]"); - - // Clean the storage for other tests - Ion::Storage::sharedStorage()->recordNamed("a.exp").destroy(); - Ion::Storage::sharedStorage()->recordNamed("f.func").destroy(); -} - -QUIZ_CASE(poincare_store_that_should_fail) { - // Create a helper function - assert_parsed_expression_simplify_to("1β†’g(x)", "1"); - - // Store only works on variables or functions - assert_expression_not_parsable("2β†’f(2)"); - assert_expression_not_parsable("3β†’f(g(4))"); - - // Clean the storage for other tests - Ion::Storage::sharedStorage()->recordNamed("g.func").destroy(); -} - -QUIZ_CASE(poincare_store_overwrite) { - assert_parsed_expression_simplify_to("2β†’g", "2"); - assert_parsed_expression_simplify_to("-1β†’g(x)", "-1"); - assert_parsed_expression_evaluates_to("g(4)", "-1"); - - // Clean the storage for other tests - Ion::Storage::sharedStorage()->recordNamed("g.func").destroy(); -} - -QUIZ_CASE(poincare_store_do_not_overwrite) { - assert_parsed_expression_simplify_to("-1β†’g(x)", "-1"); - assert_parsed_expression_simplify_to("1+g(x)β†’f(x)", "g(x)+1"); - assert_parsed_expression_evaluates_to("f(1)", "0"); - assert_parsed_expression_simplify_to("2β†’g", Undefined::Name()); - assert_parsed_expression_evaluates_to("g(4)", "-1"); - assert_parsed_expression_evaluates_to("f(4)", "0"); - - // Clean the storage for other tests - Ion::Storage::sharedStorage()->recordNamed("f.func").destroy(); - Ion::Storage::sharedStorage()->recordNamed("g.func").destroy(); -} diff --git a/poincare/test/subtraction.cpp b/poincare/test/subtraction.cpp deleted file mode 100644 index f6822c1af..000000000 --- a/poincare/test/subtraction.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include -#include -#include -#include "helper.h" - -using namespace Poincare; - -QUIZ_CASE(poincare_subtraction_evaluate) { - assert_parsed_expression_evaluates_to("1-2", "-1"); - assert_parsed_expression_evaluates_to("3+𝐒-(4+𝐒)", "-1"); - assert_parsed_expression_evaluates_to("[[1,2][3,4][5,6]]-3", "undef"); - assert_parsed_expression_evaluates_to("[[1,2+𝐒][3,4][5,6]]-(4+𝐒)", "undef"); - assert_parsed_expression_evaluates_to("3-[[1,2][3,4][5,6]]", "undef"); - assert_parsed_expression_evaluates_to("3+𝐒-[[1,2+𝐒][3,4][5,6]]", "undef"); - assert_parsed_expression_evaluates_to("[[1,2][3,4][5,6]]-[[6,5][4,3][2,1]]", "[[-5,-3][-1,1][3,5]]"); - assert_parsed_expression_evaluates_to("[[1,2+𝐒][3,4][5,6]]-[[1,2+𝐒][3,4][5,6]]", "[[0,0][0,0][0,0]]"); -} diff --git a/poincare/test/symbol.cpp b/poincare/test/symbol.cpp deleted file mode 100644 index f2532e52f..000000000 --- a/poincare/test/symbol.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include -#include -#include -#include -#include "helper.h" - -using namespace Poincare; - -QUIZ_CASE(poincare_parse_symbol) { - assert_parsed_expression_type("Ο€", ExpressionNode::Type::Constant); - assert_parsed_expression_type("β„―", ExpressionNode::Type::Constant); - assert_parsed_expression_type("𝐒", ExpressionNode::Type::Constant); - assert_parsed_expression_type("1.2ᴇ3", ExpressionNode::Type::Decimal); - assert_parsed_expression_type("ans", ExpressionNode::Type::Symbol); -} - - -QUIZ_CASE(poincare_symbol_approximate) { - assert_parsed_expression_evaluates_to("Ο€", "3.1415926535898"); - assert_parsed_expression_evaluates_to("β„―", "2.718282"); - assert_parsed_expression_evaluates_to("1.2ᴇ3", "1200"); -} - diff --git a/poincare/test/trigo.cpp b/poincare/test/trigo.cpp deleted file mode 100644 index c7a9df4a7..000000000 --- a/poincare/test/trigo.cpp +++ /dev/null @@ -1,534 +0,0 @@ -#include -#include -#include -#include -#include "helper.h" - -using namespace Poincare; - -QUIZ_CASE(poincare_parse_trigo) { - assert_parsed_expression_type("sin(0)", ExpressionNode::Type::Sine); - assert_parsed_expression_type("cos(0)", ExpressionNode::Type::Cosine); - assert_parsed_expression_type("tan(0)", ExpressionNode::Type::Tangent); - assert_parsed_expression_type("cosh(0)", ExpressionNode::Type::HyperbolicCosine); - assert_parsed_expression_type("sinh(0)", ExpressionNode::Type::HyperbolicSine); - assert_parsed_expression_type("tanh(0)", ExpressionNode::Type::HyperbolicTangent); - assert_parsed_expression_type("acos(0)", ExpressionNode::Type::ArcCosine); - assert_parsed_expression_type("asin(0)", ExpressionNode::Type::ArcSine); - assert_parsed_expression_type("atan(0)", ExpressionNode::Type::ArcTangent); - assert_parsed_expression_type("acosh(0)", ExpressionNode::Type::HyperbolicArcCosine); - assert_parsed_expression_type("asinh(0)", ExpressionNode::Type::HyperbolicArcSine); - assert_parsed_expression_type("atanh(0)", ExpressionNode::Type::HyperbolicArcTangent); -} - -QUIZ_CASE(poincare_trigo_evaluate) { - /* cos: R -> R (oscillator) - * Ri -> R (even) - */ - // On R - assert_parsed_expression_evaluates_to("cos(2)", "-4.1614683654714ᴇ-1", System, Radian); - assert_parsed_expression_evaluates_to("cos(2)", "0.9993908270191", System, Degree); - // Oscillator - assert_parsed_expression_evaluates_to("cos(Ο€/2)", "0", System, Radian); - assert_parsed_expression_evaluates_to("cos(3Γ—Ο€/2)", "0", System, Radian); - assert_parsed_expression_evaluates_to("cos(3Γ—Ο€)", "-1", System, Radian); - assert_parsed_expression_evaluates_to("cos(-540)", "-1", System, Degree); - // On RΓ—i - assert_parsed_expression_evaluates_to("cos(-2×𝐒)", "3.7621956910836", System, Radian); - assert_parsed_expression_evaluates_to("cos(-2×𝐒)", "1.0006092967033", System, Degree); - // Symmetry: even - assert_parsed_expression_evaluates_to("cos(2×𝐒)", "3.7621956910836", System, Radian); - assert_parsed_expression_evaluates_to("cos(2×𝐒)", "1.0006092967033", System, Degree); - // On C - assert_parsed_expression_evaluates_to("cos(𝐒-4)", "-1.008625-0.8893952×𝐒", System, Radian); - assert_parsed_expression_evaluates_to("cos(𝐒-4)", "0.997716+0.00121754×𝐒", System, Degree, Cartesian, 6); - - /* sin: R -> R (oscillator) - * Ri -> Ri (odd) - */ - // On R - assert_parsed_expression_evaluates_to("sin(2)", "9.0929742682568ᴇ-1", System, Radian); - assert_parsed_expression_evaluates_to("sin(2)", "3.4899496702501ᴇ-2", System, Degree); - // Oscillator - assert_parsed_expression_evaluates_to("sin(Ο€/2)", "1", System, Radian); - assert_parsed_expression_evaluates_to("sin(3Γ—Ο€/2)", "-1", System, Radian); - assert_parsed_expression_evaluates_to("sin(3Γ—Ο€)", "0", System, Radian); - assert_parsed_expression_evaluates_to("sin(-540)", "0", System, Degree); - // On RΓ—i - assert_parsed_expression_evaluates_to("sin(3×𝐒)", "10.01787492741×𝐒", System, Radian); - assert_parsed_expression_evaluates_to("sin(3×𝐒)", "0.05238381×𝐒", System, Degree); - // Symmetry: odd - assert_parsed_expression_evaluates_to("sin(-3×𝐒)", "-10.01787492741×𝐒", System, Radian); - assert_parsed_expression_evaluates_to("sin(-3×𝐒)", "-0.05238381×𝐒", System, Degree); - // On: C - assert_parsed_expression_evaluates_to("sin(𝐒-4)", "1.16781-0.768163×𝐒", System, Radian, Cartesian, 6); - assert_parsed_expression_evaluates_to("sin(𝐒-4)", "-0.0697671+0.0174117×𝐒", System, Degree, Cartesian, 6); - assert_parsed_expression_evaluates_to("sin(1.234567890123456ᴇ-15)", "1.23457ᴇ-15", System, Radian, Cartesian, 6); - - /* tan: R -> R (tangent-style) - * Ri -> Ri (odd) - */ - // On R - assert_parsed_expression_evaluates_to("tan(2)", "-2.1850398632615", System, Radian); - assert_parsed_expression_evaluates_to("tan(2)", "3.4920769491748ᴇ-2", System, Degree); - // Tangent-style - assert_parsed_expression_evaluates_to("tan(Ο€/2)", Undefined::Name(), System, Radian); - assert_parsed_expression_evaluates_to("tan(3Γ—Ο€/2)", Undefined::Name(), System, Radian); - assert_parsed_expression_evaluates_to("tan(3Γ—Ο€)", "0", System, Radian); - assert_parsed_expression_evaluates_to("tan(-540)", "0", System, Degree); - // On RΓ—i - assert_parsed_expression_evaluates_to("tan(-2×𝐒)", "-9.6402758007582ᴇ-1×𝐒", System, Radian); - assert_parsed_expression_evaluates_to("tan(-2×𝐒)", "-0.03489241×𝐒", System, Degree); - // Symmetry: odd - assert_parsed_expression_evaluates_to("tan(2×𝐒)", "9.6402758007582ᴇ-1×𝐒", System, Radian); - assert_parsed_expression_evaluates_to("tan(2×𝐒)", "0.03489241×𝐒", System, Degree); - // On C - assert_parsed_expression_evaluates_to("tan(𝐒-4)", "-0.273553+1.00281×𝐒", System, Radian, Cartesian, 6); - assert_parsed_expression_evaluates_to("tan(𝐒-4)", "-0.0699054+0.0175368×𝐒", System, Degree, Cartesian, 6); - - /* acos: [-1,1] -> R - * ]-inf,-1[ -> Ο€+RΓ—i (odd imaginary) - * ]1, inf[ -> RΓ—i (odd imaginary) - * RΓ—i -> Ο€/2+RΓ—i (odd imaginary) - */ - // On [-1, 1] - assert_parsed_expression_evaluates_to("acos(0.5)", "1.0471975511966", System, Radian); - assert_parsed_expression_evaluates_to("acos(0.03)", "1.5407918249714", System, Radian); - assert_parsed_expression_evaluates_to("acos(0.5)", "60", System, Degree); - // On [1, inf[ - assert_parsed_expression_evaluates_to("acos(2)", "1.3169578969248×𝐒", System, Radian); - assert_parsed_expression_evaluates_to("acos(2)", "75.456129290217×𝐒", System, Degree); - // Symmetry: odd on imaginary - assert_parsed_expression_evaluates_to("acos(-2)", "3.1415926535898-1.3169578969248×𝐒", System, Radian); - assert_parsed_expression_evaluates_to("acos(-2)", "180-75.456129290217×𝐒", System, Degree); - // On ]-inf, -1[ - assert_parsed_expression_evaluates_to("acos(-32)", "3.1415926535898-4.1586388532792×𝐒", System, Radian); - assert_parsed_expression_evaluates_to("acos(-32)", "180-238.2725×𝐒", System, Degree); - // On RΓ—i - assert_parsed_expression_evaluates_to("acos(3×𝐒)", "1.5708-1.8184×𝐒", System, Radian, Cartesian, 5); - assert_parsed_expression_evaluates_to("acos(3×𝐒)", "90-104.19×𝐒", System, Degree, Cartesian, 5); - // Symmetry: odd on imaginary - assert_parsed_expression_evaluates_to("acos(-3×𝐒)", "1.5708+1.8184×𝐒", System, Radian, Cartesian, 5); - assert_parsed_expression_evaluates_to("acos(-3×𝐒)", "90+104.19×𝐒", System, Degree, Cartesian, 5); - // On C - assert_parsed_expression_evaluates_to("acos(𝐒-4)", "2.8894-2.0966×𝐒", System, Radian, Cartesian, 5); - assert_parsed_expression_evaluates_to("acos(𝐒-4)", "165.551-120.126×𝐒", System, Degree, Cartesian, 6); - // Key values - assert_parsed_expression_evaluates_to("acos(0)", "90", System, Degree); - assert_parsed_expression_evaluates_to("acos(-1)", "180", System, Degree); - assert_parsed_expression_evaluates_to("acos(1)", "0", System, Degree); - - /* asin: [-1,1] -> R - * ]-inf,-1[ -> -Ο€/2+RΓ—i (odd) - * ]1, inf[ -> Ο€/2+RΓ—i (odd) - * RΓ—i -> RΓ—i (odd) - */ - // On [-1, 1] - assert_parsed_expression_evaluates_to("asin(0.5)", "0.5235987755983", System, Radian); - assert_parsed_expression_evaluates_to("asin(0.03)", "3.0004501823477ᴇ-2", System, Radian); - assert_parsed_expression_evaluates_to("asin(0.5)", "30", System, Degree); - // On [1, inf[ - assert_parsed_expression_evaluates_to("asin(2)", "1.5707963267949-1.3169578969248×𝐒", System, Radian); - assert_parsed_expression_evaluates_to("asin(2)", "90-75.456129290217×𝐒", System, Degree); - // Symmetry: odd - assert_parsed_expression_evaluates_to("asin(-2)", "-1.5707963267949+1.3169578969248×𝐒", System, Radian); - assert_parsed_expression_evaluates_to("asin(-2)", "-90+75.456129290217×𝐒", System, Degree); - // On ]-inf, -1[ - assert_parsed_expression_evaluates_to("asin(-32)", "-1.571+4.159×𝐒", System, Radian, Cartesian, 4); - assert_parsed_expression_evaluates_to("asin(-32)", "-90+238×𝐒", System, Degree, Cartesian, 3); - // On RΓ—i - assert_parsed_expression_evaluates_to("asin(3×𝐒)", "1.8184464592321×𝐒", System, Radian); - // Symmetry: odd - assert_parsed_expression_evaluates_to("asin(-3×𝐒)", "-1.8184464592321×𝐒", System, Radian); - // On C - assert_parsed_expression_evaluates_to("asin(𝐒-4)", "-1.3186+2.0966×𝐒", System, Radian, Cartesian, 5); - assert_parsed_expression_evaluates_to("asin(𝐒-4)", "-75.551+120.13×𝐒", System, Degree, Cartesian, 5); - // Key values - assert_parsed_expression_evaluates_to("asin(0)", "0", System, Degree); - assert_parsed_expression_evaluates_to("asin(-1)", "-90", System, Degree); - assert_parsed_expression_evaluates_to("asin(1)", "90", System, Degree); - - /* atan: R -> R (odd) - * [-𝐒,𝐒] -> R×𝐒 (odd) - * ]-inf×𝐒,-𝐒[ -> -Ο€/2+R×𝐒 (odd) - * ]𝐒, inf×𝐒[ -> Ο€/2+R×𝐒 (odd) - */ - // On R - assert_parsed_expression_evaluates_to("atan(2)", "1.1071487177941", System, Radian); - assert_parsed_expression_evaluates_to("atan(0.01)", "9.9996666866652ᴇ-3", System, Radian); - assert_parsed_expression_evaluates_to("atan(2)", "63.434948822922", System, Degree); - assert_parsed_expression_evaluates_to("atan(0.5)", "0.4636476", System, Radian); - // Symmetry: odd - assert_parsed_expression_evaluates_to("atan(-2)", "-1.1071487177941", System, Radian); - // On [-𝐒, 𝐒] - assert_parsed_expression_evaluates_to("atan(0.2×𝐒)", "0.202733×𝐒", System, Radian, Cartesian, 6); - // Symmetry: odd - assert_parsed_expression_evaluates_to("atan(-0.2×𝐒)", "-0.202733×𝐒", System, Radian, Cartesian, 6); - // On [𝐒, inf×𝐒[ - assert_parsed_expression_evaluates_to("atan(26×𝐒)", "1.5707963267949+3.8480520568064ᴇ-2×𝐒", System, Radian); - assert_parsed_expression_evaluates_to("atan(26×𝐒)", "90+2.2047714220164×𝐒", System, Degree); - // Symmetry: odd - assert_parsed_expression_evaluates_to("atan(-26×𝐒)", "-1.5707963267949-3.8480520568064ᴇ-2×𝐒", System, Radian); - // On ]-inf×𝐒, -𝐒[ - assert_parsed_expression_evaluates_to("atan(-3.4×𝐒)", "-1.570796-0.3030679×𝐒", System, Radian); - assert_parsed_expression_evaluates_to("atan(-3.4×𝐒)", "-90-17.3645×𝐒", System, Degree, Cartesian, 6); - // On C - assert_parsed_expression_evaluates_to("atan(𝐒-4)", "-1.338973+0.05578589×𝐒", System, Radian); - assert_parsed_expression_evaluates_to("atan(𝐒-4)", "-76.7175+3.1963×𝐒", System, Degree, Cartesian, 6); - // Key values - assert_parsed_expression_evaluates_to("atan(0)", "0", System, Degree); - assert_parsed_expression_evaluates_to("atan(-𝐒)", "-inf×𝐒", System, Radian); - assert_parsed_expression_evaluates_to("atan(𝐒)", "inf×𝐒", System, Radian); - - /* cosh: R -> R (even) - * R×𝐒 -> R (oscillator) - */ - // On R - assert_parsed_expression_evaluates_to("cosh(2)", "3.7621956910836", System, Radian); - assert_parsed_expression_evaluates_to("cosh(2)", "3.7621956910836", System, Degree); - // Symmetry: even - assert_parsed_expression_evaluates_to("cosh(-2)", "3.7621956910836", System, Radian); - assert_parsed_expression_evaluates_to("cosh(-2)", "3.7621956910836", System, Degree); - // On R×𝐒 - assert_parsed_expression_evaluates_to("cosh(43×𝐒)", "5.5511330152063ᴇ-1", System, Radian); - // Oscillator - assert_parsed_expression_evaluates_to("cosh(π×𝐒/2)", "0", System, Radian); - assert_parsed_expression_evaluates_to("cosh(5×π×𝐒/2)", "0", System, Radian); - assert_parsed_expression_evaluates_to("cosh(8×π×𝐒/2)", "1", System, Radian); - assert_parsed_expression_evaluates_to("cosh(9×π×𝐒/2)", "0", System, Radian); - // On C - assert_parsed_expression_evaluates_to("cosh(𝐒-4)", "14.7547-22.9637×𝐒", System, Radian, Cartesian, 6); - assert_parsed_expression_evaluates_to("cosh(𝐒-4)", "14.7547-22.9637×𝐒", System, Degree, Cartesian, 6); - - /* sinh: R -> R (odd) - * R×𝐒 -> R×𝐒 (oscillator) - */ - // On R - assert_parsed_expression_evaluates_to("sinh(2)", "3.626860407847", System, Radian); - assert_parsed_expression_evaluates_to("sinh(2)", "3.626860407847", System, Degree); - // Symmetry: odd - assert_parsed_expression_evaluates_to("sinh(-2)", "-3.626860407847", System, Radian); - // On R×𝐒 - assert_parsed_expression_evaluates_to("sinh(43×𝐒)", "-0.8317747426286×𝐒", System, Radian); - // Oscillator - assert_parsed_expression_evaluates_to("sinh(π×𝐒/2)", "𝐒", System, Radian); - assert_parsed_expression_evaluates_to("sinh(5×π×𝐒/2)", "𝐒", System, Radian); - assert_parsed_expression_evaluates_to("sinh(7×π×𝐒/2)", "-𝐒", System, Radian); - assert_parsed_expression_evaluates_to("sinh(8×π×𝐒/2)", "0", System, Radian); - assert_parsed_expression_evaluates_to("sinh(9×π×𝐒/2)", "𝐒", System, Radian); - // On C - assert_parsed_expression_evaluates_to("sinh(𝐒-4)", "-14.7448+22.9791×𝐒", System, Radian, Cartesian, 6); - assert_parsed_expression_evaluates_to("sinh(𝐒-4)", "-14.7448+22.9791×𝐒", System, Degree, Cartesian, 6); - - /* tanh: R -> R (odd) - * R×𝐒 -> R×𝐒 (tangent-style) - */ - // On R - assert_parsed_expression_evaluates_to("tanh(2)", "9.6402758007582ᴇ-1", System, Radian); - // Symmetry: odd - assert_parsed_expression_evaluates_to("tanh(-2)", "-9.6402758007582ᴇ-1", System, Degree); - // On RΓ—i - assert_parsed_expression_evaluates_to("tanh(43×𝐒)", "-1.4983873388552×𝐒", System, Radian); - // Tangent-style - // FIXME: this depends on the libm implementation and does not work on travis/appveyor servers - /*assert_parsed_expression_evaluates_to("tanh(π×𝐒/2)", Undefined::Name(), System, Radian); - assert_parsed_expression_evaluates_to("tanh(5×π×𝐒/2)", Undefined::Name(), System, Radian); - assert_parsed_expression_evaluates_to("tanh(7×π×𝐒/2)", Undefined::Name(), System, Radian); - assert_parsed_expression_evaluates_to("tanh(8×π×𝐒/2)", "0", System, Radian); - assert_parsed_expression_evaluates_to("tanh(9×π×𝐒/2)", Undefined::Name(), System, Radian);*/ - // On C - assert_parsed_expression_evaluates_to("tanh(𝐒-4)", "-1.00028+0.000610241×𝐒", System, Radian, Cartesian, 6); - assert_parsed_expression_evaluates_to("tanh(𝐒-4)", "-1.00028+0.000610241×𝐒", System, Degree, Cartesian, 6); - - /* acosh: [-1,1] -> R×𝐒 - * ]-inf,-1[ -> π×𝐒+R (even on real) - * ]1, inf[ -> R (even on real) - * ]-inf×𝐒, 0[ -> -Ο€/2×𝐒+R (even on real) - * ]0, inf*𝐒[ -> Ο€/2×𝐒+R (even on real) - */ - // On [-1,1] - assert_parsed_expression_evaluates_to("acosh(2)", "1.3169578969248", System, Radian); - assert_parsed_expression_evaluates_to("acosh(2)", "1.3169578969248", System, Degree); - // On ]-inf, -1[ - assert_parsed_expression_evaluates_to("acosh(-4)", "2.0634370688956+3.1415926535898×𝐒", System, Radian); - assert_parsed_expression_evaluates_to("acosh(-4)", "2.06344+3.14159×𝐒", System, Radian, Cartesian, 6); - // On ]1,inf[: Symmetry: even on real - assert_parsed_expression_evaluates_to("acosh(4)", "2.0634370688956", System, Radian); - assert_parsed_expression_evaluates_to("acosh(4)", "2.063437", System, Radian); - // On ]-inf×𝐒, 0[ - assert_parsed_expression_evaluates_to("acosh(-42×𝐒)", "4.4309584920805-1.5707963267949×𝐒", System, Radian); - assert_parsed_expression_evaluates_to("acosh(-42×𝐒)", "4.431-1.571×𝐒", System, Radian, Cartesian, 4); - // On ]0, 𝐒×inf[: Symmetry: even on real - assert_parsed_expression_evaluates_to("acosh(42×𝐒)", "4.4309584920805+1.5707963267949×𝐒", System, Radian); - assert_parsed_expression_evaluates_to("acosh(42×𝐒)", "4.431+1.571×𝐒", System, Radian, Cartesian, 4); - // On C - assert_parsed_expression_evaluates_to("acosh(𝐒-4)", "2.0966+2.8894×𝐒", System, Radian, Cartesian, 5); - assert_parsed_expression_evaluates_to("acosh(𝐒-4)", "2.0966+2.8894×𝐒", System, Degree, Cartesian, 5); - // Key values - //assert_parsed_expression_evaluates_to("acosh(-1)", "3.1415926535898×𝐒", System, Radian); - assert_parsed_expression_evaluates_to("acosh(1)", "0", System, Radian); - assert_parsed_expression_evaluates_to("acosh(0)", "1.570796×𝐒", System, Radian); - - /* asinh: R -> R (odd) - * [-𝐒,𝐒] -> R*𝐒 (odd) - * ]-inf×𝐒,-𝐒[ -> -Ο€/2×𝐒+R (odd) - * ]𝐒, inf×𝐒[ -> Ο€/2×𝐒+R (odd) - */ - // On R - assert_parsed_expression_evaluates_to("asinh(2)", "1.4436354751788", System, Radian); - assert_parsed_expression_evaluates_to("asinh(2)", "1.4436354751788", System, Degree); - // Symmetry: odd - assert_parsed_expression_evaluates_to("asinh(-2)", "-1.4436354751788", System, Radian); - assert_parsed_expression_evaluates_to("asinh(-2)", "-1.4436354751788", System, Degree); - // On [-𝐒,𝐒] - assert_parsed_expression_evaluates_to("asinh(0.2×𝐒)", "2.0135792079033ᴇ-1×𝐒", System, Radian); - assert_parsed_expression_evaluates_to("asinh(0.2×𝐒)", "0.2013579×𝐒", System, Degree); - // Symmetry: odd - assert_parsed_expression_evaluates_to("asinh(-0.2×𝐒)", "-2.0135792079033ᴇ-1×𝐒", System, Radian); - assert_parsed_expression_evaluates_to("asinh(-0.2×𝐒)", "-0.2013579×𝐒", System, Degree); - // On ]-inf×𝐒, -𝐒[ - assert_parsed_expression_evaluates_to("asinh(-22×𝐒)", "-3.7836727043295-1.5707963267949×𝐒", System, Radian); - assert_parsed_expression_evaluates_to("asinh(-22×𝐒)", "-3.784-1.571×𝐒", System, Degree, Cartesian, 4); - // On ]𝐒, inf×𝐒[, Symmetry: odd - assert_parsed_expression_evaluates_to("asinh(22×𝐒)", "3.7836727043295+1.5707963267949×𝐒", System, Radian); - assert_parsed_expression_evaluates_to("asinh(22×𝐒)", "3.784+1.571×𝐒", System, Degree, Cartesian, 4); - // On C - assert_parsed_expression_evaluates_to("asinh(𝐒-4)", "-2.123+0.2383×𝐒", System, Radian, Cartesian, 4); - assert_parsed_expression_evaluates_to("asinh(𝐒-4)", "-2.123+0.2383×𝐒", System, Degree, Cartesian, 4); - - /* atanh: [-1,1] -> R (odd) - * ]-inf,-1[ -> Ο€/2*𝐒+R (odd) - * ]1, inf[ -> -Ο€/2×𝐒+R (odd) - * R×𝐒 -> R×𝐒 (odd) - */ - // On [-1,1] - assert_parsed_expression_evaluates_to("atanh(0.4)", "0.4236489301936", System, Radian); - assert_parsed_expression_evaluates_to("atanh(0.4)", "0.4236489301936", System, Degree); - // Symmetry: odd - assert_parsed_expression_evaluates_to("atanh(-0.4)", "-0.4236489301936", System, Radian); - assert_parsed_expression_evaluates_to("atanh(-0.4)", "-0.4236489301936", System, Degree); - // On ]1, inf[ - assert_parsed_expression_evaluates_to("atanh(4)", "0.255412811883-1.5707963267949×𝐒", System, Radian); - assert_parsed_expression_evaluates_to("atanh(4)", "0.2554128-1.570796×𝐒", System, Degree); - // On ]-inf,-1[, Symmetry: odd - assert_parsed_expression_evaluates_to("atanh(-4)", "-0.255412811883+1.5707963267949×𝐒", System, Radian); - assert_parsed_expression_evaluates_to("atanh(-4)", "-0.2554128+1.570796×𝐒", System, Degree); - // On R×𝐒 - assert_parsed_expression_evaluates_to("atanh(4×𝐒)", "1.325817663668×𝐒", System, Radian); - assert_parsed_expression_evaluates_to("atanh(4×𝐒)", "1.325818×𝐒", System, Radian); - // Symmetry: odd - assert_parsed_expression_evaluates_to("atanh(-4×𝐒)", "-1.325817663668×𝐒", System, Radian); - assert_parsed_expression_evaluates_to("atanh(-4×𝐒)", "-1.325818×𝐒", System, Radian); - // On C - assert_parsed_expression_evaluates_to("atanh(𝐒-4)", "-0.238878+1.50862×𝐒", System, Radian, Cartesian, 6); - assert_parsed_expression_evaluates_to("atanh(𝐒-4)", "-0.238878+1.50862×𝐒", System, Degree, Cartesian, 6); - - // WARNING: evaluate on branch cut can be multivalued - assert_parsed_expression_evaluates_to("acos(2)", "1.3169578969248×𝐒", System, Radian); - assert_parsed_expression_evaluates_to("acos(2)", "75.456129290217×𝐒", System, Degree); - assert_parsed_expression_evaluates_to("asin(2)", "1.5707963267949-1.3169578969248×𝐒", System, Radian); - assert_parsed_expression_evaluates_to("asin(2)", "90-75.456129290217×𝐒", System, Degree); - assert_parsed_expression_evaluates_to("atanh(2)", "5.4930614433405ᴇ-1-1.5707963267949×𝐒", System, Radian); - assert_parsed_expression_evaluates_to("atan(2𝐒)", "1.5707963267949+5.4930614433405ᴇ-1×𝐒", System, Radian); - assert_parsed_expression_evaluates_to("atan(2𝐒)", "90+31.472923730945×𝐒", System, Degree); - assert_parsed_expression_evaluates_to("asinh(2𝐒)", "1.3169578969248+1.5707963267949×𝐒", System, Radian); - assert_parsed_expression_evaluates_to("acosh(-2)", "1.3169578969248+3.1415926535898×𝐒", System, Radian); -} - -QUIZ_CASE(poincare_trigo_simplify) { - // -- sin/cos -> tan - assert_parsed_expression_simplify_to("sin(x)/cos(x)", "tan(x)"); - assert_parsed_expression_simplify_to("cos(x)/sin(x)", "1/tan(x)"); - assert_parsed_expression_simplify_to("sin(x)Γ—Ο€/cos(x)", "π×tan(x)"); - assert_parsed_expression_simplify_to("sin(x)/(π×cos(x))", "tan(x)/Ο€"); - assert_parsed_expression_simplify_to("1Γ—tan(2)Γ—tan(5)", "tan(2)Γ—tan(5)"); - assert_parsed_expression_simplify_to("tan(62Ο€/21)", "-tan(Ο€/21)"); - assert_parsed_expression_simplify_to("cos(26Ο€/21)/sin(25Ο€/17)", "cos((5Γ—Ο€)/21)/sin((8Γ—Ο€)/17)"); - assert_parsed_expression_simplify_to("cos(62Ο€/21)×π×3/sin(62Ο€/21)", "-(3Γ—Ο€)/tan(Ο€/21)"); - assert_parsed_expression_simplify_to("cos(62Ο€/21)/(π×3Γ—sin(62Ο€/21))", "-1/(3×π×tan(Ο€/21))"); - assert_parsed_expression_simplify_to("sin(62Ο€/21)×π×3/cos(62Ο€/21)", "-3×π×tan(Ο€/21)"); - assert_parsed_expression_simplify_to("sin(62Ο€/21)/(π×3cos(62Ο€/21))", "-tan(Ο€/21)/(3Γ—Ο€)"); - assert_parsed_expression_simplify_to("-cos(Ο€/62)ln(3)/(sin(Ο€/62)Ο€)", "-ln(3)/(π×tan(Ο€/62))"); - assert_parsed_expression_simplify_to("-2cos(Ο€/62)ln(3)/(sin(Ο€/62)Ο€)", "-(2Γ—ln(3))/(π×tan(Ο€/62))"); - // -- cos - assert_parsed_expression_simplify_to("cos(0)", "1"); - assert_parsed_expression_simplify_to("cos(Ο€)", "-1"); - assert_parsed_expression_simplify_to("cos(π×4/7)", "-cos((3Γ—Ο€)/7)"); - assert_parsed_expression_simplify_to("cos(π×35/29)", "-cos((6Γ—Ο€)/29)"); - assert_parsed_expression_simplify_to("cos(-π×35/29)", "-cos((6Γ—Ο€)/29)"); - assert_parsed_expression_simplify_to("cos(π×340000)", "1"); - assert_parsed_expression_simplify_to("cos(-π×340001)", "-1"); - assert_parsed_expression_simplify_to("cos(-Ο€Γ—βˆš(2))", "cos(√(2)Γ—Ο€)"); - assert_parsed_expression_simplify_to("cos(1311Ο€/6)", "0"); - assert_parsed_expression_simplify_to("cos(Ο€/12)", "(√(6)+√(2))/4"); - assert_parsed_expression_simplify_to("cos(-Ο€/12)", "(√(6)+√(2))/4"); - assert_parsed_expression_simplify_to("cos(-Ο€17/8)", "√(√(2)+2)/2"); - assert_parsed_expression_simplify_to("cos(41Ο€/6)", "-√(3)/2"); - assert_parsed_expression_simplify_to("cos(Ο€/4+1000Ο€)", "√(2)/2"); - assert_parsed_expression_simplify_to("cos(-Ο€/3)", "1/2"); - assert_parsed_expression_simplify_to("cos(41Ο€/5)", "(√(5)+1)/4"); - assert_parsed_expression_simplify_to("cos(7Ο€/10)", "-(√(2)Γ—βˆš(-√(5)+5))/4"); - assert_parsed_expression_simplify_to("cos(0)", "1", User, Degree); - assert_parsed_expression_simplify_to("cos(180)", "-1", User, Degree); - assert_parsed_expression_simplify_to("cos(720/7)", "-cos(540/7)", User, Degree); - assert_parsed_expression_simplify_to("cos(6300/29)", "-cos(1080/29)", User, Degree); - assert_parsed_expression_simplify_to("cos(-6300/29)", "-cos(1080/29)", User, Degree); - assert_parsed_expression_simplify_to("cos(61200000)", "1", User, Degree); - assert_parsed_expression_simplify_to("cos(-61200180)", "-1", User, Degree); - assert_parsed_expression_simplify_to("cos(-180Γ—βˆš(2))", "cos(180Γ—βˆš(2))", User, Degree); - assert_parsed_expression_simplify_to("cos(39330)", "0", User, Degree); - assert_parsed_expression_simplify_to("cos(15)", "(√(6)+√(2))/4", User, Degree); - assert_parsed_expression_simplify_to("cos(-15)", "(√(6)+√(2))/4", User, Degree); - assert_parsed_expression_simplify_to("cos(-765/2)", "√(√(2)+2)/2", User, Degree); - assert_parsed_expression_simplify_to("cos(7380/6)", "-√(3)/2", User, Degree); - assert_parsed_expression_simplify_to("cos(180045)", "√(2)/2", User, Degree); - assert_parsed_expression_simplify_to("cos(-60)", "1/2", User, Degree); - assert_parsed_expression_simplify_to("cos(7380/5)", "(√(5)+1)/4", User, Degree); - assert_parsed_expression_simplify_to("cos(112.5)", "-√(-√(2)+2)/2", User, Degree); - // -- sin - assert_parsed_expression_simplify_to("sin(0)", "0"); - assert_parsed_expression_simplify_to("sin(Ο€)", "0"); - assert_parsed_expression_simplify_to("sin(π×35/29)", "-sin((6Γ—Ο€)/29)"); - assert_parsed_expression_simplify_to("sin(-π×35/29)", "sin((6Γ—Ο€)/29)"); - assert_parsed_expression_simplify_to("sin(π×340000)", "0"); - assert_parsed_expression_simplify_to("sin(π×340001)", "0"); - assert_parsed_expression_simplify_to("sin(-π×340001)", "0"); - assert_parsed_expression_simplify_to("sin(Ο€/12)", "(√(6)-√(2))/4"); - assert_parsed_expression_simplify_to("sin(-Ο€/12)", "(-√(6)+√(2))/4"); - assert_parsed_expression_simplify_to("sin(-Ο€Γ—βˆš(2))", "-sin(√(2)Γ—Ο€)"); - assert_parsed_expression_simplify_to("sin(1311Ο€/6)", "1"); - assert_parsed_expression_simplify_to("sin(-Ο€17/8)", "-√(-√(2)+2)/2"); - assert_parsed_expression_simplify_to("sin(41Ο€/6)", "1/2"); - assert_parsed_expression_simplify_to("sin(-3Ο€/10)", "(-√(5)-1)/4"); - assert_parsed_expression_simplify_to("sin(Ο€/4+1000Ο€)", "√(2)/2"); - assert_parsed_expression_simplify_to("sin(-Ο€/3)", "-√(3)/2"); - assert_parsed_expression_simplify_to("sin(17Ο€/5)", "-(√(2)Γ—βˆš(√(5)+5))/4"); - assert_parsed_expression_simplify_to("sin(Ο€/5)", "(√(2)Γ—βˆš(-√(5)+5))/4"); - assert_parsed_expression_simplify_to("sin(0)", "0", User, Degree); - assert_parsed_expression_simplify_to("sin(180)", "0", User, Degree); - assert_parsed_expression_simplify_to("sin(6300/29)", "-sin(1080/29)", User, Degree); - assert_parsed_expression_simplify_to("sin(-6300/29)", "sin(1080/29)", User, Degree); - assert_parsed_expression_simplify_to("sin(61200000)", "0", User, Degree); - assert_parsed_expression_simplify_to("sin(61200180)", "0", User, Degree); - assert_parsed_expression_simplify_to("sin(-61200180)", "0", User, Degree); - assert_parsed_expression_simplify_to("sin(15)", "(√(6)-√(2))/4", User, Degree); - assert_parsed_expression_simplify_to("sin(-15)", "(-√(6)+√(2))/4", User, Degree); - assert_parsed_expression_simplify_to("sin(-180Γ—βˆš(2))", "-sin(180Γ—βˆš(2))", User, Degree); - assert_parsed_expression_simplify_to("sin(39330)", "1", User, Degree); - assert_parsed_expression_simplify_to("sin(-765/2)", "-√(-√(2)+2)/2", User, Degree); - assert_parsed_expression_simplify_to("sin(1230)", "1/2", User, Degree); - assert_parsed_expression_simplify_to("sin(180045)", "√(2)/2", User, Degree); - assert_parsed_expression_simplify_to("sin(-60)", "-√(3)/2", User, Degree); - assert_parsed_expression_simplify_to("sin(612)", "-(√(2)Γ—βˆš(√(5)+5))/4", User, Degree); - assert_parsed_expression_simplify_to("sin(36)", "(√(2)Γ—βˆš(-√(5)+5))/4", User, Degree); - // -- tan - assert_parsed_expression_simplify_to("tan(0)", "0"); - assert_parsed_expression_simplify_to("tan(Ο€)", "0"); - assert_parsed_expression_simplify_to("tan(π×35/29)", "tan((6Γ—Ο€)/29)"); - assert_parsed_expression_simplify_to("tan(-π×35/29)", "-tan((6Γ—Ο€)/29)"); - assert_parsed_expression_simplify_to("tan(π×340000)", "0"); - assert_parsed_expression_simplify_to("tan(π×340001)", "0"); - assert_parsed_expression_simplify_to("tan(-π×340001)", "0"); - assert_parsed_expression_simplify_to("tan(Ο€/12)", "-√(3)+2"); - assert_parsed_expression_simplify_to("tan(-Ο€/12)", "√(3)-2"); - assert_parsed_expression_simplify_to("tan(-Ο€Γ—βˆš(2))", "-tan(√(2)Γ—Ο€)"); - assert_parsed_expression_simplify_to("tan(1311Ο€/6)", Undefined::Name()); - assert_parsed_expression_simplify_to("tan(-Ο€17/8)", "-√(2)+1"); - assert_parsed_expression_simplify_to("tan(41Ο€/6)", "-√(3)/3"); - assert_parsed_expression_simplify_to("tan(Ο€/4+1000Ο€)", "1"); - assert_parsed_expression_simplify_to("tan(-Ο€/3)", "-√(3)"); - assert_parsed_expression_simplify_to("tan(-Ο€/10)", "-(√(5)Γ—βˆš(-2Γ—βˆš(5)+5))/5"); - assert_parsed_expression_simplify_to("tan(0)", "0", User, Degree); - assert_parsed_expression_simplify_to("tan(180)", "0", User, Degree); - assert_parsed_expression_simplify_to("tan(6300/29)", "tan(1080/29)", User, Degree); - assert_parsed_expression_simplify_to("tan(-6300/29)", "-tan(1080/29)", User, Degree); - assert_parsed_expression_simplify_to("tan(61200000)", "0", User, Degree); - assert_parsed_expression_simplify_to("tan(61200180)", "0", User, Degree); - assert_parsed_expression_simplify_to("tan(-61200180)", "0", User, Degree); - assert_parsed_expression_simplify_to("tan(15)", "-√(3)+2", User, Degree); - assert_parsed_expression_simplify_to("tan(-15)", "√(3)-2", User, Degree); - assert_parsed_expression_simplify_to("tan(-180Γ—βˆš(2))", "-tan(180Γ—βˆš(2))", User, Degree); - assert_parsed_expression_simplify_to("tan(39330)", Undefined::Name(), User, Degree); - assert_parsed_expression_simplify_to("tan(-382.5)", "-√(2)+1", User, Degree); - assert_parsed_expression_simplify_to("tan(1230)", "-√(3)/3", User, Degree); - assert_parsed_expression_simplify_to("tan(180045)", "1", User, Degree); - assert_parsed_expression_simplify_to("tan(-60)", "-√(3)", User, Degree); - assert_parsed_expression_simplify_to("tan(tan(tan(tan(9))))", "tan(tan(tan(tan(9))))"); - // -- acos - assert_parsed_expression_simplify_to("acos(-1/2)", "(2Γ—Ο€)/3"); - assert_parsed_expression_simplify_to("acos(-1.2)", "-acos(6/5)+Ο€"); - assert_parsed_expression_simplify_to("acos(cos(2/3))", "2/3"); - 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(4Ο€/7))", "(4Γ—Ο€)/7"); - assert_parsed_expression_simplify_to("acos(-cos(2))", "Ο€-2"); - assert_parsed_expression_simplify_to("acos(-1/2)", "120", User, Degree); - assert_parsed_expression_simplify_to("acos(-1.2)", "-acos(6/5)+180", User, Degree); - assert_parsed_expression_simplify_to("acos(cos(2/3))", "2/3", User, Degree); - assert_parsed_expression_simplify_to("acos(cos(190))", "170", User, Degree); - assert_parsed_expression_simplify_to("acos(cos(75))", "75", User, Degree); - assert_parsed_expression_simplify_to("cos(acos(190))", "190", User, Degree); - assert_parsed_expression_simplify_to("cos(acos(75))", "75", User, Degree); - assert_parsed_expression_simplify_to("acos(cos(12))", "12", User, Degree); - assert_parsed_expression_simplify_to("acos(cos(720/7))", "720/7", User, Degree); - // -- asin - assert_parsed_expression_simplify_to("asin(-1/2)", "-Ο€/6"); - assert_parsed_expression_simplify_to("asin(-1.2)", "-asin(6/5)"); - assert_parsed_expression_simplify_to("asin(sin(2/3))", "2/3"); - 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(-Ο€/7))", "-Ο€/7"); - assert_parsed_expression_simplify_to("asin(sin(-√(2)))", "-√(2)"); - assert_parsed_expression_simplify_to("asin(-1/2)", "-30", User, Degree); - assert_parsed_expression_simplify_to("asin(-1.2)", "-asin(6/5)", User, Degree); - assert_parsed_expression_simplify_to("asin(sin(75))", "75", User, Degree); - assert_parsed_expression_simplify_to("sin(asin(75))", "75", User, Degree); - assert_parsed_expression_simplify_to("sin(asin(190))", "190", User, Degree); - assert_parsed_expression_simplify_to("asin(sin(32))", "32", User, Degree); - assert_parsed_expression_simplify_to("asin(sin(400))", "40", User, Degree); - assert_parsed_expression_simplify_to("asin(sin(-180/7))", "-180/7", User, Degree); - // -- atan - assert_parsed_expression_simplify_to("atan(-1)", "-Ο€/4"); - assert_parsed_expression_simplify_to("atan(-1.2)", "-atan(6/5)"); - 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(-Ο€/7))", "-Ο€/7"); - assert_parsed_expression_simplify_to("atan(√(3))", "Ο€/3"); - assert_parsed_expression_simplify_to("atan(tan(-√(2)))", "-√(2)"); - assert_parsed_expression_simplify_to("atan(-1)", "-45", User, Degree); - assert_parsed_expression_simplify_to("atan(-1.2)", "-atan(6/5)", User, Degree); - assert_parsed_expression_simplify_to("atan(tan(-45))", "-45", User, Degree); - assert_parsed_expression_simplify_to("tan(atan(120))", "120", User, Degree); - assert_parsed_expression_simplify_to("tan(atan(2293))", "2293", User, Degree); - assert_parsed_expression_simplify_to("atan(tan(2293))", "-47", User, Degree); - assert_parsed_expression_simplify_to("atan(tan(1808))", "8", User, Degree); - assert_parsed_expression_simplify_to("atan(tan(-180/7))", "-180/7", User, Degree); - assert_parsed_expression_simplify_to("atan(√(3))", "60", User, Degree); - assert_parsed_expression_simplify_to("atan(1/x)", "(π×sign(x)-2Γ—atan(x))/2", User, Degree); - - // cos(asin) - assert_parsed_expression_simplify_to("cos(asin(x))", "√(-x^2+1)", User, Degree); - assert_parsed_expression_simplify_to("cos(asin(-x))", "√(-x^2+1)", User, Degree); - // cos(atan) - assert_parsed_expression_simplify_to("cos(atan(x))", "1/√(x^2+1)", User, Degree); - assert_parsed_expression_simplify_to("cos(atan(-x))", "1/√(x^2+1)", User, Degree); - // sin(acos) - assert_parsed_expression_simplify_to("sin(acos(x))", "√(-x^2+1)", User, Degree); - assert_parsed_expression_simplify_to("sin(acos(-x))", "√(-x^2+1)", User, Degree); - // sin(atan) - assert_parsed_expression_simplify_to("sin(atan(x))", "x/√(x^2+1)", User, Degree); - assert_parsed_expression_simplify_to("sin(atan(-x))", "-x/√(x^2+1)", User, Degree); - // tan(acos) - assert_parsed_expression_simplify_to("tan(acos(x))", "√(-x^2+1)/x", User, Degree); - assert_parsed_expression_simplify_to("tan(acos(-x))", "-√(-x^2+1)/x", User, Degree); - // tan(asin) - assert_parsed_expression_simplify_to("tan(asin(x))", "x/√(-x^2+1)", User, Degree); - assert_parsed_expression_simplify_to("tan(asin(-x))", "-x/√(-x^2+1)", User, Degree); -} diff --git a/poincare/test/vertical_offset_layout.cpp b/poincare/test/vertical_offset_layout.cpp deleted file mode 100644 index 7b49f98c3..000000000 --- a/poincare/test/vertical_offset_layout.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include -#include -#include -#include -#include "helper.h" - -using namespace Poincare; - -QUIZ_CASE(poincare_vertical_offset_layout_serialize) { - HorizontalLayout layout = HorizontalLayout::Builder( - CodePointLayout::Builder('2'), - VerticalOffsetLayout::Builder( - LayoutHelper::String("x+5", 3), - VerticalOffsetLayoutNode::Position::Superscript - ) - ); - assert(UCodePointLeftSystemParenthesis == '\x12'); - assert(UCodePointRightSystemParenthesis == '\x13'); - assert_expression_layout_serialize_to(layout, "2^\x12x+5\x13"); -}