1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.hipparchus.distribution.discrete;
23
24 import java.util.ArrayList;
25 import java.util.HashMap;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.Map.Entry;
29
30 import org.hipparchus.distribution.EnumeratedDistribution;
31 import org.hipparchus.exception.MathIllegalArgumentException;
32 import org.hipparchus.util.MathUtils;
33 import org.hipparchus.util.Pair;
34
35
36
37
38
39
40
41
42
43
44 public class EnumeratedIntegerDistribution extends AbstractIntegerDistribution {
45
46
47 private static final long serialVersionUID = 20130308L;
48
49
50
51
52
53 private final EnumeratedDistribution<Integer> innerDistribution;
54
55
56
57
58
59
60
61
62
63
64
65 public EnumeratedIntegerDistribution(final int[] singletons, final double[] probabilities)
66 throws MathIllegalArgumentException {
67 innerDistribution =
68 new EnumeratedDistribution<>(createDistribution(singletons, probabilities));
69 }
70
71
72
73
74
75
76
77
78 public EnumeratedIntegerDistribution(final int[] data) {
79 final Map<Integer, Integer> dataMap = new HashMap<>();
80 for (int value : data) {
81 Integer count = dataMap.get(value);
82 if (count == null) {
83 count = 0;
84 }
85 dataMap.put(value, ++count);
86 }
87 final int massPoints = dataMap.size();
88 final double denom = data.length;
89 final int[] values = new int[massPoints];
90 final double[] probabilities = new double[massPoints];
91 int index = 0;
92 for (Entry<Integer, Integer> entry : dataMap.entrySet()) {
93 values[index] = entry.getKey();
94 probabilities[index] = entry.getValue().intValue() / denom;
95 index++;
96 }
97 innerDistribution =
98 new EnumeratedDistribution<>(createDistribution(values, probabilities));
99 }
100
101
102
103
104
105
106
107
108
109 private static List<Pair<Integer, Double>> createDistribution(int[] singletons,
110 double[] probabilities) {
111 MathUtils.checkDimension(singletons.length, probabilities.length);
112 final List<Pair<Integer, Double>> samples = new ArrayList<>(singletons.length);
113
114 final double[] normalizedProbabilities = EnumeratedDistribution.checkAndNormalize(probabilities);
115 for (int i = 0; i < singletons.length; i++) {
116 samples.add(new Pair<>(singletons[i], normalizedProbabilities[i]));
117 }
118 return samples;
119 }
120
121
122
123
124 @Override
125 public double probability(final int x) {
126 return innerDistribution.probability(x);
127 }
128
129
130
131
132 @Override
133 public double cumulativeProbability(final int x) {
134 double probability = 0;
135
136 for (final Pair<Integer, Double> sample : innerDistribution.getPmf()) {
137 if (sample.getKey() <= x) {
138 probability += sample.getValue();
139 }
140 }
141
142 return probability;
143 }
144
145
146
147
148
149
150 @Override
151 public double getNumericalMean() {
152 double mean = 0;
153
154 for (final Pair<Integer, Double> sample : innerDistribution.getPmf()) {
155 mean += sample.getValue() * sample.getKey();
156 }
157
158 return mean;
159 }
160
161
162
163
164
165
166 @Override
167 public double getNumericalVariance() {
168 double mean = 0;
169 double meanOfSquares = 0;
170
171 for (final Pair<Integer, Double> sample : innerDistribution.getPmf()) {
172 mean += sample.getValue() * sample.getKey();
173 meanOfSquares += sample.getValue() * sample.getKey() * sample.getKey();
174 }
175
176 return meanOfSquares - mean * mean;
177 }
178
179
180
181
182
183
184
185
186 @Override
187 public int getSupportLowerBound() {
188 int min = Integer.MAX_VALUE;
189 for (final Pair<Integer, Double> sample : innerDistribution.getPmf()) {
190 if (sample.getKey() < min && sample.getValue() > 0) {
191 min = sample.getKey();
192 }
193 }
194
195 return min;
196 }
197
198
199
200
201
202
203
204
205 @Override
206 public int getSupportUpperBound() {
207 int max = Integer.MIN_VALUE;
208 for (final Pair<Integer, Double> sample : innerDistribution.getPmf()) {
209 if (sample.getKey() > max && sample.getValue() > 0) {
210 max = sample.getKey();
211 }
212 }
213
214 return max;
215 }
216
217
218
219
220
221
222
223
224 @Override
225 public boolean isSupportConnected() {
226 return true;
227 }
228
229
230
231
232
233
234 public List<Pair<Integer, Double>> getPmf() {
235 return innerDistribution.getPmf();
236 }
237
238 }