[apps/probability] Improve law models

Change-Id: Ibfbf9df3f7c94b0fb1c4cef6900b5680e5ea3b7d
This commit is contained in:
Émilie Feral
2016-12-15 12:03:51 +01:00
parent 69593fd174
commit 8a01e8e2d3
10 changed files with 71 additions and 48 deletions

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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;
};
}

View File

@@ -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));
}
}

View File

@@ -3,8 +3,8 @@
namespace Probability {
OneParameterLaw::OneParameterLaw() :
m_parameter1(0.5f)
OneParameterLaw::OneParameterLaw(float parameterValue) :
m_parameter1(parameterValue)
{
}

View File

@@ -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;

View File

@@ -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));
}
}

View File

@@ -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)
{
}

View File

@@ -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;

View File

@@ -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 {