[Probability] Changed distribution parameter's type to double

Plots are still rendered in float but computations are now in double

Change-Id: I7e0a38effb780861b1443ee92a097cd319de3bc8
This commit is contained in:
Arthur Camouseigt
2020-06-22 15:51:26 +02:00
committed by Émilie Feral
parent 082f9819e9
commit 018dd91ca1
13 changed files with 38 additions and 37 deletions

View File

@@ -29,7 +29,7 @@ float BinomialDistribution::evaluateAtAbscissa(float x) const {
float BinomialDistribution::xMin() const {
float min = 0.0f;
float max = m_parameter1 > 0.0f ? m_parameter1 : 1.0f;
float max = m_parameter1 > 0.0 ? m_parameter1 : 1.0f;
return min - k_displayLeftMarginRatio * (max - min);
}
@@ -43,7 +43,7 @@ float BinomialDistribution::xMax() const {
}
float BinomialDistribution::yMax() const {
int maxAbscissa = m_parameter2 < 1.0f ? (m_parameter1+1)*m_parameter2 : m_parameter1;
int maxAbscissa = m_parameter2 < 1.0 ? (m_parameter1+1)*m_parameter2 : m_parameter1;
float result = evaluateAtAbscissa(maxAbscissa);
if (result <= 0.0f || std::isnan(result)) {
result = 1.0f;
@@ -66,7 +66,7 @@ double BinomialDistribution::cumulativeDistributiveInverseForProbability(double
}
double BinomialDistribution::rightIntegralInverseForProbability(double * probability) {
if (m_parameter1 == 0.0f && (m_parameter2 == 0.0f || m_parameter2 == 1.0f)) {
if (m_parameter1 == 0.0 && (m_parameter2 == 0.0 || m_parameter2 == 1.0)) {
return NAN;
}
if (*probability <= 0.0) {
@@ -76,7 +76,7 @@ double BinomialDistribution::rightIntegralInverseForProbability(double * probabi
}
double BinomialDistribution::evaluateAtDiscreteAbscissa(int k) const {
return Poincare::BinomialDistribution::EvaluateAtAbscissa<double>((double) k, (double)m_parameter1, (double)m_parameter2);
return Poincare::BinomialDistribution::EvaluateAtAbscissa<double>((double) k, m_parameter1, m_parameter2);
}
}

View File

@@ -10,7 +10,7 @@ float ChiSquaredDistribution::xMin() const {
}
float ChiSquaredDistribution::xMax() const {
assert(m_parameter1 != 0.0f);
assert(m_parameter1 != 0.0);
return (m_parameter1 + 5.0f * std::sqrt(m_parameter1)) * (1.0f + k_displayRightMarginRatio);
}
@@ -28,7 +28,7 @@ float ChiSquaredDistribution::evaluateAtAbscissa(float x) const {
if (x < 0.0f) {
return NAN;
}
const float halfk = m_parameter1/2.0f;
const float halfk = m_parameter1/2.0;
const float halfX = x/2.0f;
return std::exp(-lgamma(halfk) - halfX + (halfk-1.0f) * std::log(halfX)) / 2.0f;
}
@@ -43,7 +43,7 @@ double ChiSquaredDistribution::cumulativeDistributiveFunctionAtAbscissa(double x
return 0.0;
}
double result = 0.0;
if (regularizedGamma(m_parameter1/2.0f, x/2.0, k_regularizedGammaPrecision, k_maxRegularizedGammaIterations, &result)) {
if (regularizedGamma(m_parameter1/2.0, x/2.0, k_regularizedGammaPrecision, k_maxRegularizedGammaIterations, &result)) {
return result;
}
return NAN;
@@ -72,9 +72,9 @@ double ChiSquaredDistribution::cumulativeDistributiveInverseForProbability(doubl
return 0.0;
}
const double k = m_parameter1;
const double ceilKOver2 = std::ceil(k/2.0f);
const double kOver2Minus1 = k/2.0f - 1.0f;
double xmax = m_parameter1 > 2.0f ?
const double ceilKOver2 = std::ceil(k/2.0);
const double kOver2Minus1 = k/2.0 - 1.0;
double xmax = m_parameter1 > 2.0 ?
2.0 * *probability * std::exp(std::lgamma(ceilKOver2)) / (exp(-kOver2Minus1) * std::pow(kOver2Minus1, kOver2Minus1)) :
30.0; // Ad hoc value
xmax = std::isnan(xmax) ? 1000000000.0 : xmax;

View File

@@ -26,7 +26,7 @@ public:
virtual Type type() const = 0;
virtual bool isContinuous() const = 0;
virtual int numberOfParameter() = 0;
virtual float parameterValueAtIndex(int index) = 0;
virtual double parameterValueAtIndex(int index) = 0;
virtual I18n::Message parameterNameAtIndex(int index) = 0;
virtual I18n::Message parameterDefinitionAtIndex(int index) = 0;
virtual void setParameterAtIndex(float f, int index) = 0;

View File

@@ -36,7 +36,8 @@ float ExponentialDistribution::evaluateAtAbscissa(float x) const {
if (x < 0.0f) {
return NAN;
}
return m_parameter1 * std::exp(-m_parameter1 * x);
float parameter = m_parameter1;
return parameter * std::exp(-parameter * x);
}
bool ExponentialDistribution::authorizedValueAtIndex(float x, int index) const {
@@ -50,7 +51,7 @@ double ExponentialDistribution::cumulativeDistributiveFunctionAtAbscissa(double
if (x < 0.0) {
return 0.0;
}
return 1.0 - std::exp((double)(-m_parameter1 * x));
return 1.0 - std::exp((-m_parameter1 * x));
}
double ExponentialDistribution::cumulativeDistributiveInverseForProbability(double * probability) {
@@ -60,7 +61,7 @@ double ExponentialDistribution::cumulativeDistributiveInverseForProbability(doub
if (*probability <= 0.0) {
return 0.0;
}
return -std::log(1.0 - *probability)/(double)m_parameter1;
return -std::log(1.0 - *probability)/m_parameter1;
}
}

View File

@@ -60,9 +60,7 @@ void FisherDistribution::setParameterAtIndex(float f, int index) {
}
double FisherDistribution::cumulativeDistributiveFunctionAtAbscissa(double x) const {
const double d1 = m_parameter1;
const double d2 = m_parameter2;
return Poincare::RegularizedIncompleteBetaFunction(d1/2.0, d2/2.0, d1*x/(d1*x+d2));
return Poincare::RegularizedIncompleteBetaFunction(m_parameter1/2.0, m_parameter2/2.0, m_parameter1*x/(m_parameter1*x+m_parameter2));
}
double FisherDistribution::cumulativeDistributiveInverseForProbability(double * probability) {

View File

@@ -27,13 +27,13 @@ public:
return I18n::Message::SuccessProbability;
}
float evaluateAtAbscissa(float x) const override {
return templatedApproximateAtAbscissa(x);
return templatedApproximateAtAbscissa<float>(x);
}
bool authorizedValueAtIndex(float x, int index) const override;
double defaultComputedValue() const override { return 1.0f; }
double defaultComputedValue() const override { return 1.0; }
private:
double evaluateAtDiscreteAbscissa(int k) const override {
return templatedApproximateAtAbscissa((double)k);
return templatedApproximateAtAbscissa<double>(static_cast<double>(k));
}
template<typename T> T templatedApproximateAtAbscissa(T x) const;
};

View File

@@ -31,7 +31,7 @@ I18n::Message NormalDistribution::parameterDefinitionAtIndex(int index) {
}
float NormalDistribution::evaluateAtAbscissa(float x) const {
return Poincare::NormalDistribution::EvaluateAtAbscissa(x, m_parameter1, m_parameter2);
return Poincare::NormalDistribution::EvaluateAtAbscissa<float>(x, m_parameter1, m_parameter2);
}
bool NormalDistribution::authorizedValueAtIndex(float x, int index) const {
@@ -52,11 +52,11 @@ void NormalDistribution::setParameterAtIndex(float f, int index) {
}
double NormalDistribution::cumulativeDistributiveFunctionAtAbscissa(double x) const {
return Poincare::NormalDistribution::CumulativeDistributiveFunctionAtAbscissa<float>(x, m_parameter1, m_parameter2);
return Poincare::NormalDistribution::CumulativeDistributiveFunctionAtAbscissa<double>(x, m_parameter1, m_parameter2);
}
double NormalDistribution::cumulativeDistributiveInverseForProbability(double * probability) {
return Poincare::NormalDistribution::CumulativeDistributiveInverseForProbability<float>(*probability, m_parameter1, m_parameter2);
return Poincare::NormalDistribution::CumulativeDistributiveInverseForProbability<double>(*probability, m_parameter1, m_parameter2);
}
float NormalDistribution::xExtremum(bool min) const {

View File

@@ -10,7 +10,7 @@ class OneParameterDistribution : public Distribution {
public:
OneParameterDistribution(float parameterValue) : m_parameter1(parameterValue) {}
int numberOfParameter() override { return 1; }
float parameterValueAtIndex(int index) override {
double parameterValueAtIndex(int index) override {
assert(index == 0);
return m_parameter1;
}
@@ -19,7 +19,7 @@ public:
m_parameter1 = f;
}
protected:
float m_parameter1;
double m_parameter1;
};
}

View File

@@ -23,12 +23,12 @@ public:
return I18n::Message::LambdaPoissonDefinition;
}
float evaluateAtAbscissa(float x) const override {
return templatedApproximateAtAbscissa(x);
return templatedApproximateAtAbscissa<float>(x);
}
bool authorizedValueAtIndex(float x, int index) const override;
private:
double evaluateAtDiscreteAbscissa(int k) const override {
return templatedApproximateAtAbscissa((double)k);
return templatedApproximateAtAbscissa<double>(static_cast<double>(k));
}
template<typename T> T templatedApproximateAtAbscissa(T x) const;
};

View File

@@ -36,7 +36,7 @@ double StudentDistribution::cumulativeDistributiveFunctionAtAbscissa(double x) c
/* TODO There are some computation errors, where the probability falsly jumps to 1.
* k = 0.001 and P(x < 42000000) (for 41000000 it is around 0.5)
* k = 0.01 and P(x < 8400000) (for 41000000 it is around 0.6) */
const float k = m_parameter1;
const double k = m_parameter1;
const double sqrtXSquaredPlusK = std::sqrt(x*x + k);
double t = (x + sqrtXSquaredPlusK) / (2.0 * sqrtXSquaredPlusK);
return Poincare::RegularizedIncompleteBetaFunction(k/2.0, k/2.0, t);

View File

@@ -3,7 +3,7 @@
namespace Probability {
float TwoParameterDistribution::parameterValueAtIndex(int index) {
double TwoParameterDistribution::parameterValueAtIndex(int index) {
assert(index >= 0 && index < 2);
if (index == 0) {
return m_parameter1;

View File

@@ -12,11 +12,11 @@ public:
m_parameter2(parameterValue2)
{}
int numberOfParameter() override { return 2; }
float parameterValueAtIndex(int index) override;
double parameterValueAtIndex(int index) override;
void setParameterAtIndex(float f, int index) override;
protected:
float m_parameter1;
float m_parameter2;
double m_parameter1;
double m_parameter2;
};
}

View File

@@ -48,14 +48,16 @@ float UniformDistribution::yMax() const {
}
float UniformDistribution::evaluateAtAbscissa(float t) const {
if (m_parameter2 - m_parameter1 < FLT_EPSILON) {
if (m_parameter1 - k_diracWidth<= t && t <= m_parameter2 + k_diracWidth) {
float parameter1 = m_parameter1;
float parameter2 = m_parameter2;
if (parameter2 - parameter1 < FLT_EPSILON) {
if (parameter1 - k_diracWidth<= t && t <= parameter2 + k_diracWidth) {
return 2.0f * k_diracMaximum;
}
return 0.0f;
}
if (m_parameter1 <= t && t <= m_parameter2) {
return (1.0f/(m_parameter2 - m_parameter1));
if (parameter1 <= t && t <= parameter2) {
return (1.0f/(parameter2 - parameter1));
}
return 0.0f;
}
@@ -73,7 +75,7 @@ bool UniformDistribution::authorizedValueAtIndex(float x, int index) const {
void UniformDistribution::setParameterAtIndex(float f, int index) {
TwoParameterDistribution::setParameterAtIndex(f, index);
if (index == 0 && m_parameter2 < m_parameter1) {
m_parameter2 = m_parameter1 + 1.0f;
m_parameter2 = m_parameter1 + 1.0;
}
}