diff --git a/apps/probability/law/binomial_law.cpp b/apps/probability/law/binomial_law.cpp index 33dae4776..21a15678b 100644 --- a/apps/probability/law/binomial_law.cpp +++ b/apps/probability/law/binomial_law.cpp @@ -5,7 +5,7 @@ namespace Probability { BinomialLaw::BinomialLaw() : - TwoParameterLaw() + TwoParameterLaw(20.0f, 0.5f) { } @@ -44,23 +44,41 @@ float BinomialLaw::xMin() { } float BinomialLaw::xMax() { - if (m_parameter1 == 0) { - return 1.0f; - } - return m_parameter1; + return m_parameter1 + 1.0f; } float BinomialLaw::yMin() { - return -0.2f; + int maxAbscissa = m_parameter2 < 1.0f ? (m_parameter1+1)*m_parameter2 : m_parameter1; + float result = k_minMarginFactor*evaluateAtAbscissa(maxAbscissa); + if (result >= 0.0f || isnan(result)) { + result = -0.2f; + } + return result; } float BinomialLaw::yMax() { - return 1.0f; + int maxAbscissa = m_parameter2 < 1.0f ? (m_parameter1+1)*m_parameter2 : m_parameter1; + float result = k_maxMarginFactor*evaluateAtAbscissa(maxAbscissa); + if (result <= 0.0f || result == yMin() || isnan(result)) { + result = yMin() + 1.0f; + } + return result; } float BinomialLaw::evaluateAtAbscissa(float x) const { - //m_expression = Expression::parse("binomial(a, b)*b^t*(1-b)^(a-t)"); - return powf(m_parameter2, (int)x)*powf(1-m_parameter2, m_parameter1-(int)x); + if (m_parameter1 == 0.0f && (m_parameter2 == 0.0f || m_parameter2 == 1.0f)) { + return NAN; + } + if (m_parameter2 == 1.0f) { + if ((int)x == m_parameter1) { + return 1.0f; + } + return 0.0f; + } + if (x > m_parameter1) { + return 0.0f; + } + return expf(lgammaf(m_parameter1+1) - lgammaf((int)x+1) - lgammaf(m_parameter1 - (int)x+1))*powf(m_parameter2, (int)x)*powf(1-m_parameter2, m_parameter1-(int)x); } } diff --git a/apps/probability/law/exponential_law.cpp b/apps/probability/law/exponential_law.cpp index 9ebf71916..34d3bff4e 100644 --- a/apps/probability/law/exponential_law.cpp +++ b/apps/probability/law/exponential_law.cpp @@ -5,7 +5,7 @@ namespace Probability { ExponentialLaw::ExponentialLaw() : - OneParameterLaw() + OneParameterLaw(1.0f) { } @@ -36,23 +36,20 @@ float ExponentialLaw::xMin() { } float ExponentialLaw::xMax() { - if (m_parameter1 == 0.0f) { - return 100.0f; - } + assert(m_parameter1 != 0.0f); return 5.0f/m_parameter1; } float ExponentialLaw::yMin() { - return -0.2f; + return k_minMarginFactor*m_parameter1; } float ExponentialLaw::yMax() { - return 1.0f; + return k_maxMarginFactor*m_parameter1; } float ExponentialLaw::evaluateAtAbscissa(float x) const { -// TODO: change 2.7f for the right constant - return m_parameter1*powf(2.7f, -m_parameter1*x); + return m_parameter1*expf(-m_parameter1*x); } } diff --git a/apps/probability/law/law.h b/apps/probability/law/law.h index 8a44462a7..497b7ad6f 100644 --- a/apps/probability/law/law.h +++ b/apps/probability/law/law.h @@ -35,6 +35,8 @@ protected: constexpr static float k_oneUnit = 1.0f; constexpr static float k_twoUnit = 2.0f; constexpr static float k_fiveUnit = 5.0f; + constexpr static float k_minMarginFactor = -0.2f; + constexpr static float k_maxMarginFactor = 1.2f; }; } diff --git a/apps/probability/law/normal_law.cpp b/apps/probability/law/normal_law.cpp index 1476ac3a3..e3742dbfb 100644 --- a/apps/probability/law/normal_law.cpp +++ b/apps/probability/law/normal_law.cpp @@ -5,7 +5,7 @@ namespace Probability { NormalLaw::NormalLaw() : - TwoParameterLaw() + TwoParameterLaw(0.0f, 1.0f) { } @@ -54,16 +54,28 @@ float NormalLaw::xMax() { } float NormalLaw::yMin() { - return -0.2f; + float maxAbscissa = m_parameter1; + float result = k_minMarginFactor*evaluateAtAbscissa(maxAbscissa); + if (result >= 0.0f) { + result = -0.2f; + } + return result; } float NormalLaw::yMax() { - return 1.0f; + float maxAbscissa = m_parameter1; + float result = k_maxMarginFactor*evaluateAtAbscissa(maxAbscissa); + if (result <= 0.0f || result == yMin()) { + result = yMin() + 1.0f; + } + return result; } float NormalLaw::evaluateAtAbscissa(float x) const { - // TODO: 3.14f -> Pi and 2.7f -> e - return (1.0f/(m_parameter2*sqrtf(2*3.14f)))*powf(2.7f, -0.5f*powf((x-m_parameter1)/m_parameter2,2)); + if (m_parameter2 == 0.0f) { + return NAN; + } + return (1.0f/(m_parameter2*sqrtf(2.0f*M_PI)))*expf(-0.5f*powf((x-m_parameter1)/m_parameter2,2)); } } diff --git a/apps/probability/law/one_parameter_law.cpp b/apps/probability/law/one_parameter_law.cpp index 5b86ec8ac..617c60af1 100644 --- a/apps/probability/law/one_parameter_law.cpp +++ b/apps/probability/law/one_parameter_law.cpp @@ -3,8 +3,8 @@ namespace Probability { -OneParameterLaw::OneParameterLaw() : - m_parameter1(0.5f) +OneParameterLaw::OneParameterLaw(float parameterValue) : + m_parameter1(parameterValue) { } diff --git a/apps/probability/law/one_parameter_law.h b/apps/probability/law/one_parameter_law.h index 17dfbd1ea..25f7bfc1d 100644 --- a/apps/probability/law/one_parameter_law.h +++ b/apps/probability/law/one_parameter_law.h @@ -7,7 +7,7 @@ namespace Probability { class OneParameterLaw : public Law { public: - OneParameterLaw(); + OneParameterLaw(float parameterValue); virtual ~OneParameterLaw() {}; int numberOfParameter() override; float parameterValueAtIndex(int index) override; diff --git a/apps/probability/law/poisson_law.cpp b/apps/probability/law/poisson_law.cpp index e7379f876..294452d1b 100644 --- a/apps/probability/law/poisson_law.cpp +++ b/apps/probability/law/poisson_law.cpp @@ -5,7 +5,7 @@ namespace Probability { PoissonLaw::PoissonLaw() : - OneParameterLaw() + OneParameterLaw(4.0f) { } @@ -36,23 +36,22 @@ float PoissonLaw::xMin() { } float PoissonLaw::xMax() { - if (m_parameter1 == 0.0f) { - return 1.0f; - } + assert(m_parameter1 != 0); return m_parameter1 + 5.0f*sqrtf(m_parameter1); } float PoissonLaw::yMin() { - return -0.2f; + int maxAbscissa = (int)m_parameter1; + return k_minMarginFactor*evaluateAtAbscissa(maxAbscissa); } float PoissonLaw::yMax() { - return 1.0f; + int maxAbscissa = (int)m_parameter1; + return k_maxMarginFactor*evaluateAtAbscissa(maxAbscissa); } float PoissonLaw::evaluateAtAbscissa(float x) const { - // TODO: 2.7f -> e and factio - return powf(2.7f, -m_parameter1)*powf(m_parameter1, x)/(x); + return expf(-m_parameter1)*powf(m_parameter1, (int)x)/expf(lgammaf((int)x+1)); } } diff --git a/apps/probability/law/two_parameter_law.cpp b/apps/probability/law/two_parameter_law.cpp index 4418707ec..bdee5f63f 100644 --- a/apps/probability/law/two_parameter_law.cpp +++ b/apps/probability/law/two_parameter_law.cpp @@ -3,9 +3,9 @@ namespace Probability { -TwoParameterLaw::TwoParameterLaw() : - m_parameter1(0.0f), - m_parameter2(0.0f) +TwoParameterLaw::TwoParameterLaw(float parameterValue1, float parameterValue2) : + m_parameter1(parameterValue1), + m_parameter2(parameterValue2) { } diff --git a/apps/probability/law/two_parameter_law.h b/apps/probability/law/two_parameter_law.h index df96ac85a..ccbad1c56 100644 --- a/apps/probability/law/two_parameter_law.h +++ b/apps/probability/law/two_parameter_law.h @@ -7,7 +7,7 @@ namespace Probability { class TwoParameterLaw : public Law { public: - TwoParameterLaw(); + TwoParameterLaw(float parameterValue1, float parameterValue2); virtual ~TwoParameterLaw() {}; int numberOfParameter() override; float parameterValueAtIndex(int index) override; diff --git a/apps/probability/law/uniform_law.cpp b/apps/probability/law/uniform_law.cpp index d0edcffd0..0945c65e7 100644 --- a/apps/probability/law/uniform_law.cpp +++ b/apps/probability/law/uniform_law.cpp @@ -4,7 +4,7 @@ namespace Probability { UniformLaw::UniformLaw() : - TwoParameterLaw() + TwoParameterLaw(-1.0f, 1.0f) { } @@ -39,25 +39,20 @@ const char * UniformLaw::parameterDefinitionAtIndex(int index) { } float UniformLaw::xMin() { - if (m_parameter2 < m_parameter1) { - return m_parameter2 - 3.0f; - } - return m_parameter1 - 3.0f; + assert(m_parameter2 >= m_parameter1); + return m_parameter1 - 0.6f*(m_parameter2 - m_parameter1); } float UniformLaw::xMax() { - if (m_parameter2 < m_parameter1) { - return m_parameter1 + 3.0f; - } - return m_parameter2 + 3.0f;; + return m_parameter2 + 0.6f*(m_parameter2 - m_parameter1); } float UniformLaw::yMin() { - return -0.2f; + return k_minMarginFactor*(1.0f/(m_parameter2-m_parameter1)); } float UniformLaw::yMax() { - return 1.0f; + return k_maxMarginFactor*(1.0f/(m_parameter2-m_parameter1)); } float UniformLaw::evaluateAtAbscissa(float t) const {