binomial_law.cpp
3.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include "binomial_law.h"
#include <assert.h>
#include <cmath>
namespace Probability {
BinomialLaw::BinomialLaw() :
TwoParameterLaw(20.0, 0.5)
{
}
I18n::Message BinomialLaw::title() {
return I18n::Message::BinomialLaw;
}
Law::Type BinomialLaw::type() const {
return Type::Binomial;
}
bool BinomialLaw::isContinuous() const {
return false;
}
I18n::Message BinomialLaw::parameterNameAtIndex(int index) {
assert(index >= 0 && index < 2);
if (index == 0) {
return I18n::Message::N;
} else {
return I18n::Message::P;
}
}
I18n::Message BinomialLaw::parameterDefinitionAtIndex(int index) {
assert(index >= 0 && index < 2);
if (index == 0) {
return I18n::Message::RepetitionNumber;
} else {
return I18n::Message::SuccessProbability;
}
}
float BinomialLaw::xMin() {
float min = 0.0f;
float max = m_parameter1 > 0.0f ? m_parameter1 : 1.0f;
return min - k_displayLeftMarginRatio * (max - min);
}
float BinomialLaw::xMax() {
float min = 0.0f;
float max = m_parameter1;
if (max <= min) {
max = min + 1.0f;
}
return max + k_displayRightMarginRatio*(max - min);
}
float BinomialLaw::yMin() {
return -k_displayBottomMarginRatio*yMax();
}
float BinomialLaw::yMax() {
int maxAbscissa = m_parameter2 < 1.0f ? (m_parameter1+1)*m_parameter2 : m_parameter1;
float result = evaluateAtAbscissa(maxAbscissa);
if (result <= 0.0f || std::isnan(result)) {
result = 1.0f;
}
return result*(1.0f+ k_displayTopMarginRatio);
}
bool BinomialLaw::authorizedValueAtIndex(float x, int index) const {
if (index == 0) {
if (x != (int)x || x < 0.0f || x > 999.0f) {
return false;
}
return true;
}
if (x < 0.0f || x > 1.0f) {
return false;
}
return true;
}
double BinomialLaw::cumulativeDistributiveInverseForProbability(double * probability) {
if (m_parameter1 == 0.0 && (m_parameter2 == 0.0 || m_parameter2 == 1.0)) {
return NAN;
}
if (*probability >= 1.0) {
return m_parameter1;
}
return Law::cumulativeDistributiveInverseForProbability(probability);
}
double BinomialLaw::rightIntegralInverseForProbability(double * probability) {
if (m_parameter1 == 0.0 && (m_parameter2 == 0.0 || m_parameter2 == 1.0)) {
return NAN;
}
if (*probability <= 0.0) {
return m_parameter1;
}
return Law::rightIntegralInverseForProbability(probability);
}
template<typename T>
T BinomialLaw::templatedApproximateAtAbscissa(T x) const {
if (m_parameter1 == 0) {
if (m_parameter2 == 0 || m_parameter2 == 1) {
return NAN;
}
if (floor(x) == 0) {
return 1;
}
return 0;
}
if (m_parameter2 == 1) {
if (floor(x) == m_parameter1) {
return 1;
}
return 0;
}
if (m_parameter2 == 0) {
if (floor(x) == 0) {
return 1;
}
return 0;
}
if (x > m_parameter1) {
return 0;
}
T lResult = std::lgamma(m_parameter1+1) - std::lgamma(std::floor(x)+1) - std::lgamma((T)m_parameter1 - std::floor(x)+1)+
std::floor(x)*std::log(m_parameter2) + (m_parameter1-std::floor(x))*std::log(1-m_parameter2);
return std::exp(lResult);
}
}
template float Probability::BinomialLaw::templatedApproximateAtAbscissa(float x) const;
template double Probability::BinomialLaw::templatedApproximateAtAbscissa(double x) const;