diff --git a/poincare/include/poincare/normal_distribution.h b/poincare/include/poincare/normal_distribution.h index bf459783e..4806a1467 100644 --- a/poincare/include/poincare/normal_distribution.h +++ b/poincare/include/poincare/normal_distribution.h @@ -8,13 +8,13 @@ namespace Poincare { class NormalDistribution final { public: - template static T EvaluateAtAbscissa(T x, T mu, T var); - template static T CumulativeDistributiveFunctionAtAbscissa(T x, T mu, T var); - template static T CumulativeDistributiveInverseForProbability(T probability, T mu, T var); - template static bool ParametersAreOK(T mu, T var); - /* ExpressionParametersAreOK returns true if the expression could be verified. + template static T EvaluateAtAbscissa(T x, T mu, T sigma); + template static T CumulativeDistributiveFunctionAtAbscissa(T x, T mu, T sigma); + template static T CumulativeDistributiveInverseForProbability(T probability, T mu, T sigma); + template static bool MuAndSigmaAreOK(T mu, T sigma); + /* ExpressionMuAndVarAreOK returns true if the expression could be verified. * The result of the verification is *result. */ - static bool ExpressionParametersAreOK(bool * result, const Expression & mu, const Expression & var, Context * context); + static bool ExpressionMuAndVarAreOK(bool * result, const Expression & mu, const Expression & sigma, Context * context); private: /* For the standard normal distribution, P(X < y) > 0.9999995 for y >= 4.892 so the * value displayed is 1. But this is dependent on the fact that we display diff --git a/poincare/src/inv_norm.cpp b/poincare/src/inv_norm.cpp index 67d9a0510..7971f8ac0 100644 --- a/poincare/src/inv_norm.cpp +++ b/poincare/src/inv_norm.cpp @@ -33,10 +33,10 @@ Evaluation InvNormNode::templatedApproximate(Context * context, Preferences:: T a = aEvaluation.toScalar(); T mu = muEvaluation.toScalar(); - T var = varEvaluation.toScalar(); + T sigma = std::sqrt(varEvaluation.toScalar()); // CumulativeDistributiveInverseForProbability handles bad mu and var values - return Complex::Builder(NormalDistribution::CumulativeDistributiveInverseForProbability(a, mu, var)); + return Complex::Builder(NormalDistribution::CumulativeDistributiveInverseForProbability(a, mu, sigma)); } Expression InvNorm::shallowReduce(ExpressionNode::ReductionContext reductionContext) { diff --git a/poincare/src/norm_cdf.cpp b/poincare/src/norm_cdf.cpp index 29e8f1b6a..52c8f1761 100644 --- a/poincare/src/norm_cdf.cpp +++ b/poincare/src/norm_cdf.cpp @@ -31,10 +31,10 @@ Evaluation NormCDFNode::templatedApproximate(Context * context, Preferences:: const T a = aEvaluation.toScalar(); const T mu = muEvaluation.toScalar(); - const T var = varEvaluation.toScalar(); + const T sigma = std::sqrt(varEvaluation.toScalar()); // CumulativeDistributiveFunctionAtAbscissa handles bad mu and var values - return Complex::Builder(NormalDistribution::CumulativeDistributiveFunctionAtAbscissa(a, mu, var)); + return Complex::Builder(NormalDistribution::CumulativeDistributiveFunctionAtAbscissa(a, mu, sigma)); } } diff --git a/poincare/src/norm_cdf2.cpp b/poincare/src/norm_cdf2.cpp index 0e9cac2c4..b655a10de 100644 --- a/poincare/src/norm_cdf2.cpp +++ b/poincare/src/norm_cdf2.cpp @@ -33,15 +33,15 @@ Evaluation NormCDF2Node::templatedApproximate(Context * context, Preferences: T a = aEvaluation.toScalar(); T b = bEvaluation.toScalar(); T mu = muEvaluation.toScalar(); - T var = varEvaluation.toScalar(); + T sigma = std::sqrt(varEvaluation.toScalar()); - if (std::isnan(a) || std::isnan(b) || !NormalDistribution::ParametersAreOK(mu,var)) { + if (std::isnan(a) || std::isnan(b) || !NormalDistribution::MuAndSigmaAreOK(mu,sigma)) { return Complex::Undefined(); } if (b <= a) { return Complex::Builder((T)0.0); } - return Complex::Builder(NormalDistribution::CumulativeDistributiveFunctionAtAbscissa(b, mu, var) - NormalDistribution::CumulativeDistributiveFunctionAtAbscissa(a, mu, var)); + return Complex::Builder(NormalDistribution::CumulativeDistributiveFunctionAtAbscissa(b, mu, sigma) - NormalDistribution::CumulativeDistributiveFunctionAtAbscissa(a, mu, sigma)); } } diff --git a/poincare/src/norm_pdf.cpp b/poincare/src/norm_pdf.cpp index 00e329c3d..af19c69c6 100644 --- a/poincare/src/norm_pdf.cpp +++ b/poincare/src/norm_pdf.cpp @@ -31,10 +31,10 @@ Evaluation NormPDFNode::templatedApproximate(Context * context, Preferences:: T x = xEvaluation.toScalar(); T mu = muEvaluation.toScalar(); - T var = varEvaluation.toScalar(); + T sigma = std::sqrt(varEvaluation.toScalar()); // EvaluateAtAbscissa handles bad mu and var values - return Complex::Builder(NormalDistribution::EvaluateAtAbscissa(x, mu, var)); + return Complex::Builder(NormalDistribution::EvaluateAtAbscissa(x, mu, sigma)); } } diff --git a/poincare/src/normal_distribution.cpp b/poincare/src/normal_distribution.cpp index 7319341a4..0d27f41a3 100644 --- a/poincare/src/normal_distribution.cpp +++ b/poincare/src/normal_distribution.cpp @@ -8,38 +8,38 @@ namespace Poincare { template -T NormalDistribution::EvaluateAtAbscissa(T x, T mu, T var) { - if (std::isnan(x) || std::isinf(x) || !ParametersAreOK(mu, var)){ +T NormalDistribution::EvaluateAtAbscissa(T x, T mu, T sigma) { + if (std::isnan(x) || std::isinf(x) || !MuAndSigmaAreOK(mu, sigma)){ return NAN; } - const float xMinusMuOverVar = (x - mu)/var; - return ((T)1.0)/(std::fabs(var) * std::sqrt(((T)2.0) * M_PI)) * std::exp(-((T)0.5) * xMinusMuOverVar * xMinusMuOverVar); + const float xMinusMuOverVar = (x - mu)/sigma; + return ((T)1.0)/(std::fabs(sigma) * std::sqrt(((T)2.0) * M_PI)) * std::exp(-((T)0.5) * xMinusMuOverVar * xMinusMuOverVar); } template -T NormalDistribution::CumulativeDistributiveFunctionAtAbscissa(T x, T mu, T var) { - if (!ParametersAreOK(mu, var)) { +T NormalDistribution::CumulativeDistributiveFunctionAtAbscissa(T x, T mu, T sigma) { + if (!MuAndSigmaAreOK(mu, sigma)) { return NAN; } - return StandardNormalCumulativeDistributiveFunctionAtAbscissa((x-mu)/std::fabs(var)); + return StandardNormalCumulativeDistributiveFunctionAtAbscissa((x-mu)/std::fabs(sigma)); } template -T NormalDistribution::CumulativeDistributiveInverseForProbability(T probability, T mu, T var) { - if (!ParametersAreOK(mu, var)) { +T NormalDistribution::CumulativeDistributiveInverseForProbability(T probability, T mu, T sigma) { + if (!MuAndSigmaAreOK(mu, sigma)) { return NAN; } - return StandardNormalCumulativeDistributiveInverseForProbability(probability) * std::fabs(var) + mu; + return StandardNormalCumulativeDistributiveInverseForProbability(probability) * std::fabs(sigma) + mu; } template -bool NormalDistribution::ParametersAreOK(T mu, T var) { - return !std::isnan(mu) && !std::isnan(var) - && !std::isinf(mu) && !std::isinf(var) - && var > (T)0.0; +bool NormalDistribution::MuAndSigmaAreOK(T mu, T sigma) { + return !std::isnan(mu) && !std::isnan(sigma) + && !std::isinf(mu) && !std::isinf(sigma) + && sigma > (T)0.0; } -bool NormalDistribution::ExpressionParametersAreOK(bool * result, const Expression & mu, const Expression & var, Context * context) { +bool NormalDistribution::ExpressionMuAndVarAreOK(bool * result, const Expression & mu, const Expression & var, Context * context) { assert(result != nullptr); if (mu.deepIsMatrix(context) || var.deepIsMatrix(context)) { *result = false; @@ -51,7 +51,7 @@ bool NormalDistribution::ExpressionParametersAreOK(bool * result, const Expressi return true; } if (!mu.isReal(context) || !var.isReal(context)) { - // We cannot check that mu and variance are real + // We cannot check that mu and var are real return false; } @@ -61,14 +61,14 @@ bool NormalDistribution::ExpressionParametersAreOK(bool * result, const Expressi *result = false; return true; } - // We cannot check that the variance is positive + // We cannot check that var is positive if (s != ExpressionNode::Sign::Positive) { return false; } } if (var.type() != ExpressionNode::Type::Rational) { - // We cannot check that the variance is not null + // We cannot check that var is not null return false; } @@ -122,7 +122,7 @@ template float NormalDistribution::CumulativeDistributiveFunctionAtAbscissa(double, double, double); template float NormalDistribution::CumulativeDistributiveInverseForProbability(float, float, float); template double NormalDistribution::CumulativeDistributiveInverseForProbability(double, double, double); -template bool NormalDistribution::ParametersAreOK(float mu, float var); -template bool NormalDistribution::ParametersAreOK(double mu, double var); +template bool NormalDistribution::MuAndSigmaAreOK(float mu, float sigma); +template bool NormalDistribution::MuAndSigmaAreOK(double mu, double sigma); } diff --git a/poincare/src/normal_distribution_function.cpp b/poincare/src/normal_distribution_function.cpp index e0bfb96e5..898023283 100644 --- a/poincare/src/normal_distribution_function.cpp +++ b/poincare/src/normal_distribution_function.cpp @@ -1,5 +1,6 @@ #include #include +#include #include namespace Poincare { @@ -19,12 +20,13 @@ Expression NormalDistributionFunction::shallowReduce(Context * context, bool * s } } - Expression mu = childAtIndex(muIndex()); - Expression var = childAtIndex(varIndex()); - // Check mu and var bool muAndVarOK = false; - bool couldCheckMuAndVar = NormalDistribution::ExpressionParametersAreOK(&muAndVarOK, mu, var, context); + bool couldCheckMuAndVar = NormalDistribution::ExpressionMuAndVarAreOK( + &muAndVarOK, + childAtIndex(muIndex()), + childAtIndex(varIndex()), + context); if (!couldCheckMuAndVar) { return *this; } diff --git a/poincare/test/approximation.cpp b/poincare/test/approximation.cpp index fd22ce01d..9418e94f9 100644 --- a/poincare/test/approximation.cpp +++ b/poincare/test/approximation.cpp @@ -279,8 +279,8 @@ QUIZ_CASE(poincare_approximation_function) { assert_expression_approximates_to("invbinom(0.9647324002, 15, 0.7)", "13"); assert_expression_approximates_to("invbinom(0.9647324002, 15, 0.7)", "13"); - assert_expression_approximates_to("invnorm(0.56, 1.3, 2.4)", "1.662326"); - //assert_expression_approximates_to("invnorm(0.56, 1.3, 2.4)", "1.6623258450088"); FIXME precision error + assert_expression_approximates_to("invnorm(0.56, 1.3, 5.76)", "1.662326"); + //assert_expression_approximates_to("invnorm(0.56, 1.3, 5.76)", "1.6623258450088"); FIXME precision error assert_expression_approximates_to("ln(2)", "0.6931472"); assert_expression_approximates_to("ln(2)", "6.9314718055995ᴇ-1"); @@ -288,13 +288,13 @@ QUIZ_CASE(poincare_approximation_function) { assert_expression_approximates_to("log(2)", "0.30103"); assert_expression_approximates_to("log(2)", "3.0102999566398ᴇ-1"); - assert_expression_approximates_to("normcdf(1.2, 3.4, 5.6)", "0.3472125"); - assert_expression_approximates_to("normcdf(1.2, 3.4, 5.6)", "3.4721249841587ᴇ-1"); + assert_expression_approximates_to("normcdf(1.2, 3.4, 31.36)", "0.3472125"); + assert_expression_approximates_to("normcdf(1.2, 3.4, 31.36)", "3.4721249841587ᴇ-1"); - assert_expression_approximates_to("normcdf2(0.5, 3.6, 1.3, 3.4)", "0.3436388"); - assert_expression_approximates_to("normcdf2(0.5, 3.6, 1.3, 3.4)", "3.4363881299147ᴇ-1"); + assert_expression_approximates_to("normcdf2(0.5, 3.6, 1.3, 11.56)", "0.3436388"); + assert_expression_approximates_to("normcdf2(0.5, 3.6, 1.3, 11.56)", "3.4363881299147ᴇ-1"); - assert_expression_approximates_to("normpdf(1.2, 3.4, 5.6)", "0.06594901"); + assert_expression_approximates_to("normpdf(1.2, 3.4, 31.36)", "0.06594901"); assert_expression_approximates_to("permute(10, 4)", "5040"); assert_expression_approximates_to("permute(10, 4)", "5040");