mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-26 17:20:53 +01:00
[poincare/normal_distribution] ExpressionParametersAreOK
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#ifndef POINCARE_NORMAL_DISTRIBUTION_H
|
||||
#define POINCARE_NORMAL_DISTRIBUTION_H
|
||||
|
||||
#include <poincare/expression.h>
|
||||
#include <poincare/preferences.h>
|
||||
|
||||
namespace Poincare {
|
||||
@@ -11,6 +12,9 @@ public:
|
||||
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.
|
||||
* The result of the verification is *result. */
|
||||
static bool ExpressionParametersAreOK(bool * result, const Expression & mu, const Expression & var, 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
|
||||
|
||||
@@ -51,40 +51,26 @@ Expression InvNorm::shallowReduce(ExpressionNode::ReductionContext reductionCont
|
||||
Expression c2 = childAtIndex(2);
|
||||
Context * context = reductionContext.context();
|
||||
|
||||
if (c0.deepIsMatrix(context) || c1.deepIsMatrix(context) || c2.deepIsMatrix(context)) {
|
||||
// Check mu and var
|
||||
bool muAndVarOK = false;
|
||||
bool couldCheckMuAndVar = NormalDistribution::ExpressionParametersAreOK(&muAndVarOK, c1, c2, context);
|
||||
if (!couldCheckMuAndVar) {
|
||||
return *this;
|
||||
}
|
||||
if (!muAndVarOK) {
|
||||
return replaceWithUndefinedInPlace();
|
||||
}
|
||||
|
||||
if (!c1.isReal(context) || !c2.isReal(context)) {
|
||||
// If we cannot check that mu and variance are real, return
|
||||
return *this;
|
||||
// Check a
|
||||
if (c0.deepIsMatrix(context)) {
|
||||
return replaceWithUndefinedInPlace();
|
||||
}
|
||||
|
||||
{
|
||||
ExpressionNode::Sign s = c2.sign(context);
|
||||
if (s == ExpressionNode::Sign::Negative) {
|
||||
return replaceWithUndefinedInPlace();
|
||||
}
|
||||
// If we cannot check that the variance is positive, return
|
||||
if (s != ExpressionNode::Sign::Positive) {
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
||||
// If we cannot check that the variance is not null, return
|
||||
if (c2.type() != ExpressionNode::Type::Rational) {
|
||||
return *this;
|
||||
}
|
||||
{
|
||||
Rational r2 = static_cast<Rational &>(c2);
|
||||
if (r2.isZero()) {
|
||||
return replaceWithUndefinedInPlace();
|
||||
}
|
||||
}
|
||||
|
||||
if (c0.type() != ExpressionNode::Type::Rational) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Special values
|
||||
|
||||
// Undef if x < 0 or x > 1
|
||||
Rational r0 = static_cast<Rational &>(c0);
|
||||
if (r0.isNegative()) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <poincare/normal_distribution.h>
|
||||
#include <poincare/erf_inv.h>
|
||||
#include <poincare/rational.h>
|
||||
#include <cmath>
|
||||
#include <float.h>
|
||||
#include <assert.h>
|
||||
@@ -38,6 +39,44 @@ bool NormalDistribution::ParametersAreOK(T mu, T var) {
|
||||
&& var > (T)0.0;
|
||||
}
|
||||
|
||||
bool NormalDistribution::ExpressionParametersAreOK(bool * result, const Expression & mu, const Expression & var, Context * context) {
|
||||
assert(result != nullptr);
|
||||
if (mu.deepIsMatrix(context) || var.deepIsMatrix(context)) {
|
||||
*result = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!mu.isReal(context) || !var.isReal(context)) {
|
||||
// We cannot check that mu and variance are real
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
ExpressionNode::Sign s = var.sign(context);
|
||||
if (s == ExpressionNode::Sign::Negative) {
|
||||
*result = false;
|
||||
return true;
|
||||
}
|
||||
// We cannot check that the variance is positive
|
||||
if (s != ExpressionNode::Sign::Positive) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (var.type() != ExpressionNode::Type::Rational) {
|
||||
// We cannot check that the variance is not null
|
||||
return false;
|
||||
}
|
||||
|
||||
const Rational rationalVar = static_cast<const Rational &>(var);
|
||||
if (rationalVar.isZero()) {
|
||||
*result = false;
|
||||
return true;
|
||||
}
|
||||
*result = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T NormalDistribution::StandardNormalCumulativeDistributiveFunctionAtAbscissa(T abscissa) {
|
||||
if (std::isnan(abscissa) || std::isinf(abscissa)) {
|
||||
|
||||
Reference in New Issue
Block a user