diff --git a/apps/probability/distribution/fisher_distribution.cpp b/apps/probability/distribution/fisher_distribution.cpp index 12642ffac..5bfcedc86 100644 --- a/apps/probability/distribution/fisher_distribution.cpp +++ b/apps/probability/distribution/fisher_distribution.cpp @@ -1,10 +1,13 @@ #include "fisher_distribution.h" -#include +#include +#include #include #include namespace Probability { +static inline double maxDouble(double x, double y) { return x > y ? x : y; } + float FisherDistribution::xMin() const { return -k_displayLeftMarginRatio * xMax(); } @@ -39,7 +42,15 @@ I18n::Message FisherDistribution::parameterDefinitionAtIndex(int index) { } float FisherDistribution::evaluateAtAbscissa(float x) const { - return 1.0; //TODO LEA Poincare::FisherDistribution::EvaluateAtAbscissa(x, m_parameter1, m_parameter2); + if (x < 0.0f) { + return NAN; + } + const float d1 = m_parameter1; + const float d2 = m_parameter2; + const float f = d1*x/(d1*x+d2); + const float numerator = std::pow(f, d1/2.0f) * std::pow(1.0f - f, d2/2.0f); + const float denominator = x * Poincare::BetaFunction(d1/2.0f, d2/2.0f); + return numerator / denominator; } bool FisherDistribution::authorizedValueAtIndex(float x, int index) const { @@ -53,11 +64,22 @@ void FisherDistribution::setParameterAtIndex(float f, int index) { } double FisherDistribution::cumulativeDistributiveFunctionAtAbscissa(double x) const { - return 1.0; //TODO LEA + const double d1 = m_parameter1; + const double d2 = m_parameter2; + return Poincare::RegularizedIncompleteBetaFunction(d1/2.0, d2/2.0, d1*x/(d1*x+d2)); } double FisherDistribution::cumulativeDistributiveInverseForProbability(double * probability) { - return 1.0; //TODO LEA + /* We have to compute the values of the interval in which to look for x. + * We cannot put xMin because xMin is < 0 for display purposes, and negative + * values are not accepted. + * The maximum of the interval: we want */ + if (*probability < DBL_EPSILON) { + return 0.0; + } + return cumulativeDistributiveInverseForProbabilityUsingIncreasingFunctionRoot(probability, DBL_EPSILON, maxDouble(xMax(), 100.0)); // Ad-hoc value; + + } } diff --git a/poincare/Makefile b/poincare/Makefile index a46ab4bac..718600d50 100644 --- a/poincare/Makefile +++ b/poincare/Makefile @@ -30,6 +30,7 @@ poincare_src += $(addprefix poincare/src/,\ poincare_src += $(addprefix poincare/src/,\ init.cpp \ + beta_function.cpp \ binomial_distribution.cpp \ erf_inv.cpp \ exception_checkpoint.cpp \ diff --git a/poincare/include/poincare/beta_function.h b/poincare/include/poincare/beta_function.h new file mode 100644 index 000000000..b8353ad28 --- /dev/null +++ b/poincare/include/poincare/beta_function.h @@ -0,0 +1,37 @@ +#ifndef POINCARE_BETA_FUNCTION_H +#define POINCARE_BETA_FUNCTION_H + +/* + * zlib License + * + * Regularized Incomplete Beta Function + * + * Copyright (c) 2016, 2017 Lewis Van Winkle + * http://CodePlea.com + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgement in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + + +// WARNING: this code has been modified +namespace Poincare { + +double BetaFunction(double a, double b); + +} + +#endif diff --git a/poincare/src/beta_function.cpp b/poincare/src/beta_function.cpp new file mode 100644 index 000000000..44b57e432 --- /dev/null +++ b/poincare/src/beta_function.cpp @@ -0,0 +1,14 @@ +#include +#include +#include + +namespace Poincare { + +double BetaFunction(double a, double b) { + if (a < 0.0 || b < 0.0) { + return NAN; + } + return std::exp(std::lgamma(a) + std::lgamma(b) - std::lgamma(a+b)); +} + +}