mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-18 16:27:34 +01:00
[poincare/normal_distribution] Uses sigma, not var
This commit is contained in:
committed by
EmilieNumworks
parent
141b2ee9f4
commit
5acda9069c
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user