[poincare/normal_distribution] Uses sigma, not var

This commit is contained in:
Léa Saviot
2019-09-30 15:46:09 +02:00
committed by EmilieNumworks
parent 141b2ee9f4
commit 5acda9069c
8 changed files with 48 additions and 46 deletions

View File

@@ -8,13 +8,13 @@ namespace Poincare {
class NormalDistribution final {
public:
template<typename T> static T EvaluateAtAbscissa(T x, T mu, T var);
template<typename T> static T CumulativeDistributiveFunctionAtAbscissa(T x, T mu, T var);
template<typename T> static T CumulativeDistributiveInverseForProbability(T probability, T mu, T var);
template<typename T> static bool ParametersAreOK(T mu, T var);
/* ExpressionParametersAreOK returns true if the expression could be verified.
template<typename T> static T EvaluateAtAbscissa(T x, T mu, T sigma);
template<typename T> static T CumulativeDistributiveFunctionAtAbscissa(T x, T mu, T sigma);
template<typename T> static T CumulativeDistributiveInverseForProbability(T probability, T mu, T sigma);
template<typename T> 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

View File

@@ -33,10 +33,10 @@ Evaluation<T> 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<T>::Builder(NormalDistribution::CumulativeDistributiveInverseForProbability<T>(a, mu, var));
return Complex<T>::Builder(NormalDistribution::CumulativeDistributiveInverseForProbability<T>(a, mu, sigma));
}
Expression InvNorm::shallowReduce(ExpressionNode::ReductionContext reductionContext) {

View File

@@ -31,10 +31,10 @@ Evaluation<T> 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<T>::Builder(NormalDistribution::CumulativeDistributiveFunctionAtAbscissa(a, mu, var));
return Complex<T>::Builder(NormalDistribution::CumulativeDistributiveFunctionAtAbscissa(a, mu, sigma));
}
}

View File

@@ -33,15 +33,15 @@ Evaluation<T> 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<T>::Undefined();
}
if (b <= a) {
return Complex<T>::Builder((T)0.0);
}
return Complex<T>::Builder(NormalDistribution::CumulativeDistributiveFunctionAtAbscissa(b, mu, var) - NormalDistribution::CumulativeDistributiveFunctionAtAbscissa(a, mu, var));
return Complex<T>::Builder(NormalDistribution::CumulativeDistributiveFunctionAtAbscissa(b, mu, sigma) - NormalDistribution::CumulativeDistributiveFunctionAtAbscissa(a, mu, sigma));
}
}

View File

@@ -31,10 +31,10 @@ Evaluation<T> 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<T>::Builder(NormalDistribution::EvaluateAtAbscissa(x, mu, var));
return Complex<T>::Builder(NormalDistribution::EvaluateAtAbscissa(x, mu, sigma));
}
}

View File

@@ -8,38 +8,38 @@
namespace Poincare {
template<typename T>
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<typename T>
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<T>((x-mu)/std::fabs(var));
return StandardNormalCumulativeDistributiveFunctionAtAbscissa<T>((x-mu)/std::fabs(sigma));
}
template<typename T>
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<typename T>
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<floa
template double NormalDistribution::CumulativeDistributiveFunctionAtAbscissa<double>(double, double, double);
template float NormalDistribution::CumulativeDistributiveInverseForProbability<float>(float, float, float);
template double NormalDistribution::CumulativeDistributiveInverseForProbability<double>(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);
}

View File

@@ -1,5 +1,6 @@
#include <poincare/normal_distribution_function.h>
#include <poincare/normal_distribution.h>
#include <poincare/square_root.h>
#include <assert.h>
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;
}

View File

@@ -279,8 +279,8 @@ QUIZ_CASE(poincare_approximation_function) {
assert_expression_approximates_to<float>("invbinom(0.9647324002, 15, 0.7)", "13");
assert_expression_approximates_to<double>("invbinom(0.9647324002, 15, 0.7)", "13");
assert_expression_approximates_to<float>("invnorm(0.56, 1.3, 2.4)", "1.662326");
//assert_expression_approximates_to<double>("invnorm(0.56, 1.3, 2.4)", "1.6623258450088"); FIXME precision error
assert_expression_approximates_to<float>("invnorm(0.56, 1.3, 5.76)", "1.662326");
//assert_expression_approximates_to<double>("invnorm(0.56, 1.3, 5.76)", "1.6623258450088"); FIXME precision error
assert_expression_approximates_to<float>("ln(2)", "0.6931472");
assert_expression_approximates_to<double>("ln(2)", "6.9314718055995ᴇ-1");
@@ -288,13 +288,13 @@ QUIZ_CASE(poincare_approximation_function) {
assert_expression_approximates_to<float>("log(2)", "0.30103");
assert_expression_approximates_to<double>("log(2)", "3.0102999566398ᴇ-1");
assert_expression_approximates_to<float>("normcdf(1.2, 3.4, 5.6)", "0.3472125");
assert_expression_approximates_to<double>("normcdf(1.2, 3.4, 5.6)", "3.4721249841587ᴇ-1");
assert_expression_approximates_to<float>("normcdf(1.2, 3.4, 31.36)", "0.3472125");
assert_expression_approximates_to<double>("normcdf(1.2, 3.4, 31.36)", "3.4721249841587ᴇ-1");
assert_expression_approximates_to<float>("normcdf2(0.5, 3.6, 1.3, 3.4)", "0.3436388");
assert_expression_approximates_to<double>("normcdf2(0.5, 3.6, 1.3, 3.4)", "3.4363881299147ᴇ-1");
assert_expression_approximates_to<float>("normcdf2(0.5, 3.6, 1.3, 11.56)", "0.3436388");
assert_expression_approximates_to<double>("normcdf2(0.5, 3.6, 1.3, 11.56)", "3.4363881299147ᴇ-1");
assert_expression_approximates_to<float>("normpdf(1.2, 3.4, 5.6)", "0.06594901");
assert_expression_approximates_to<float>("normpdf(1.2, 3.4, 31.36)", "0.06594901");
assert_expression_approximates_to<float>("permute(10, 4)", "5040");
assert_expression_approximates_to<double>("permute(10, 4)", "5040");