diff --git a/poincare/src/inv_norm.cpp b/poincare/src/inv_norm.cpp index 107cc7544..447645efd 100644 --- a/poincare/src/inv_norm.cpp +++ b/poincare/src/inv_norm.cpp @@ -1,6 +1,9 @@ #include +#include +#include #include #include +#include #include #include @@ -45,7 +48,44 @@ Expression InvNorm::shallowReduce(ExpressionNode::ReductionContext reductionCont return e; } } - //TODO LEA + Expression c0 = childAtIndex(0); + Expression c1 = childAtIndex(1); + { + Context * context = reductionContext.context(); + Expression c2 = childAtIndex(2); + if (c0.deepIsMatrix(context) || c1.deepIsMatrix(context) || c2.deepIsMatrix(context)) { + return replaceWithUndefinedInPlace(); + } + if (c0.type() != ExpressionNode::Type::Rational) { + return *this; + } + } + // Undef if x < 0 or x > 1 + Rational r0 = static_cast(c0); + if (r0.isNegative()) { + return replaceWithUndefinedInPlace(); + } + Integer a = r0.unsignedIntegerNumerator(); + Integer b = r0.integerDenominator(); + if (b.isLowerThan(a)) { + return replaceWithUndefinedInPlace(); + } + + // -INF if x == 0 and +INF if x == 1 + bool is0 = r0.isZero(); + bool is1 = !is0 && r0.isOne(); + if (is0 || is1) { + Expression result = Infinity::Builder(is0); + replaceWithInPlace(result); + return result; + } + + // mu if x == 0.5 + if (r0.isHalf()) { + replaceWithInPlace(c1); + return c1; + } + return *this; } diff --git a/poincare/src/normal_distribution.cpp b/poincare/src/normal_distribution.cpp index c5005b622..b50ad3a32 100644 --- a/poincare/src/normal_distribution.cpp +++ b/poincare/src/normal_distribution.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include namespace Poincare { @@ -47,10 +48,14 @@ T NormalDistribution::StandardNormalCumulativeDistributiveFunctionAtAbscissa(T a template T NormalDistribution::StandardNormalCumulativeDistributiveInverseForProbability(T probability) { - if (probability >= (T)1.0) { + if (probability > (T)1.0 || probability < (T)0.0) { + return NAN; + } + T precision = sizeof(T) == sizeof(double) ? DBL_EPSILON : FLT_EPSILON; + if (((T)1.0) - probability < precision) { return INFINITY; } - if (probability <= (T)0.0) { + if (probability < precision) { return -INFINITY; } if (probability < (T)0.5) { diff --git a/poincare/test/simplification.cpp b/poincare/test/simplification.cpp index 740388303..e7dc628a4 100644 --- a/poincare/test/simplification.cpp +++ b/poincare/test/simplification.cpp @@ -1059,3 +1059,11 @@ QUIZ_CASE(poincare_hyperbolic_trigonometry) { assert_parsed_expression_simplify_to("atanh(tanh(0.5))", "1/2", User, Radian, Real); assert_parsed_expression_simplify_to("atanh(tanh(-3))", "-3", User, Radian, Real); } + +QUIZ_CASE(poincare_probabolity) { + assert_parsed_expression_simplify_to("invnorm(-1.3,2,3)", Undefined::Name()); + assert_parsed_expression_simplify_to("invnorm(0,2,3)", "-inf"); + assert_parsed_expression_simplify_to("invnorm(0.5,2,3)", "2"); + assert_parsed_expression_simplify_to("invnorm(1,2,3)", "inf"); + assert_parsed_expression_simplify_to("invnorm(1.3,2,3)", "undef"); +}