BCESolve
bcedistr.hpp
1// This file is part of the BCESolve library for games of incomplete
2// information
3// Copyright (C) 2022 Benjamin A. Brooks
4//
5// BCESolve free software: you can redistribute it and/or modify it
6// under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// BCESolve is distributed in the hope that it will be useful, but
11// WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13// General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program. If not, see
17// <http://www.gnu.org/licenses/>.
18//
19// Benjamin A. Brooks
20// ben@benjaminbrooks.net
21// Chicago, IL
22
23#ifndef BCEDISTR_HPP
24#define BCEDISTR_HPP
25
26#include <cmath>
27#include <vector>
28
29using namespace std;
30
32
39{
40public:
42 virtual double CDF(double v0, double v1) const = 0;
43
45
47 double PDF(double v0, double incr0,
48 double v1, double incr1) const
49 {
50 return (CDF(v0,v1) + CDF(v0-incr0,v1-incr1)
51 - CDF(v0-incr0,v1) - CDF(v0,v1-incr1));
52 }
53
55
57 double PDF(double v0, double v1, double incr) const
58 {
59 return PDF(v0,incr,v1,incr);
60 }
61
63 virtual ~BCEDistr() {}
64};
65
67
70class BCEDistrArray : public BCEDistr
71{
72public:
74 vector<BCEDistr*> distributions;
76 vector<double> weights;
77
79
81
83
85 {
86 vector<BCEDistr*>::iterator distr;
87 for (distr = distributions.begin();
88 distr != distributions.end();
89 distr++)
90 delete *distr;
91 }
92
94
97 bool push_back(BCEDistr* newDistr, double newWeight)
98 {
99 // Avoid recursive catastrophes!
100 if (!contains(newDistr))
101 {
102 distributions.push_back(newDistr);
103 weights.push_back(newWeight);
104 return false;
105 }
106 return true;
107 }
108
110
117 bool contains(BCEDistr * distr) const
118 {
119 // First check if this object is itself distr.
120 if (this==distr)
121 return true;
122
123 // Now check if any of the elements of distributions are distr. If
124 // any of the elements of distributions are themselves arrays,
125 // initiate a recursive check.
126 for (vector<BCEDistr*>::const_iterator it = distributions.begin();
127 it != distributions.end();
128 ++it)
129 {
130 BCEDistrArray * distrArray = dynamic_cast<BCEDistrArray *>(distr);
131
132 if (distr == *it
133 || (distrArray != NULL
134 && distrArray->contains(distr) ) )
135 return true;
136 }
137
138 return false;
139 }
140
142 void clear()
143 {
144 vector<BCEDistr*>::iterator distr;
145 for (distr = distributions.begin();
146 distr != distributions.end();
147 distr++)
148 delete *distr;
149 distributions.clear();
150 weights.clear();
151 }
152
154 double CDF(double v0, double v1) const
155 {
156 vector<BCEDistr*>::const_iterator distr;
157 vector<double>::const_iterator weight;
158
159 double p = 0;
160 for (distr = distributions.begin(),
161 weight = weights.begin();
162 distr != distributions.end();
163 distr++, weight++)
164 p += *weight * (*distr)->CDF(v0,v1);
165 return p;
166 }
167};
168
170
173class unimodal: public BCEDistr
174{
175 double m0;
176 double c0;
177 double d0;
178 double e0;
179 int k0;
180
181 double m1;
182 double c1;
183 double d1;
184 double e1;
185 int k1;
186
187public:
188 unimodal(double _c0, double _m0, int _k0,
189 double _c1, double _m1, int _k1):
190 c0(_c0), k0(_k0), m0(_m0),
191 c1(_c1), k1(_k1), m1(_m1)
192 {
193 e0 = pow(-m0,k0);
194 d0 = 1.0/c0+pow(1-m0,k0)-e0;
195 e1 = pow(-m1,k1);
196 d1 = 1.0/c1+pow(1-m1,k1)-e1;
197 }
198
199 unimodal(double _c, double _m, int _k):
200 c0(_c), k0(_k), m0(_m),
201 c1(_c), k1(_k), m1(_m)
202 {
203 e0 = pow(-m0,k0);
204 d0 = 1.0/c0+pow(1-m0,k0)-e0;
205 e1 = e0; d1 = d0;
206 }
207
208 double CDF (double v0, double v1) const
209 {
210 double p = 1.0;
211 if (v0<0)
212 return 0.0;
213 else if (v0<1.0)
214 p *= c0*( d0*v0 + pow(v0-m0,k0) + e0 );
215
216 if (v1<0)
217 return 0.0;
218 else if (v1 < 1)
219 p *= c1*( d1*v1 + pow(v1-m1,k1) + e1 );
220
221 return p;
222 }
223
224}; // unimodal
225
227{
228public:
230
231 double CDF(double v0, double v1) const
232 {
233 v0 = min(max(v0,0.0),1.0);
234 v1 = min(max(v1,0.0),1.0);
235 return (v0+v1)*(v0+v1)*v0*v1/4;
236 }
237}; // additiveCorrelated
238
240class uniform: public BCEDistr
241{
242public:
243 uniform() {};
244
245 double CDF(double v0, double v1) const
246 {
247 double p = 1.0;
248 if (v0<0)
249 return 0.0;
250 else if (v0<1)
251 p *= v0;
252
253 if (v1<0)
254 return 0.0;
255 else if (v1 < 1)
256 p *= v1;
257
258 return p;
259 }
260
261}; // uniform
262
264class bernoulli: public BCEDistr
265{
266private:
267 double lowProb;
268public:
269 bernoulli(double _lowProb): lowProb(_lowProb) {};
270
271 double CDF(double v0, double v1) const
272 {
273 double p = 1.0;
274 if (v0<0)
275 return 0.0;
276 else if (v0<1)
277 p *= lowProb;
278
279 if (v1<0)
280 return 0.0;
281 else if (v1 < 1)
282 p *= lowProb;
283
284 return p;
285 }
286
287}; // bernoulli
288
291{
292 double alpha;
293
294public:
296 uniformWithMassPnt(double _alpha): alpha(_alpha) {}
297
298 double CDF(double v0, double v1) const
299 {
300 double p = 1.0;
301 if (v0<-1e-10)
302 return 0.0;
303 else if (v0<1e-10)
304 p *= alpha;
305 else if (v0<1)
306 p *= (1-alpha)*v0;
307
308 if (v1<-1e-10)
309 return 0.0;
310 else if (v1<1e-10)
311 p *= alpha;
312 else if (v1 < 1)
313 p *= (1-alpha)*v1;
314
315 return p;
316 }
317
318}; // uniform
319
322{
323 int k;
324
325public:
326 uniformNoTie() {}
327 uniformNoTie(int _k): k(_k) {}
328
329 double CDF(double v0, double v1) const
330 {
331 double p = 1.0;
332 if (v0<0)
333 return 0.0;
334 else if (v0<1)
335 p *= v0;
336
337 if (v1<0)
338 return 0.0;
339 else if (v1 < 1)
340 p *= v1;
341
342 if (abs(v0-v1)<(0.5/k))
343 p -= 1.0/(k*k);
344
345 return p;
346 }
347
348}; // uniformNoTie
349
352{
353 double alpha0;
354 double alpha1;
355
356public:
357 vToTheAlpha() {}
358
359 vToTheAlpha(double a0, double a1):
360 alpha0(a0),
361 alpha1(a1)
362 {}
363
364 vToTheAlpha(double a):
365 alpha0(a),
366 alpha1(a)
367 {}
368
369 double CDF(double v0, double v1) const
370 {
371 double p = 1.0;
372 if (v0<0)
373 return 0.0;
374 else if (v0<1)
375 p *= pow(v0,alpha0);
376
377 if (v1<0)
378 return 0.0;
379 else if (v1 < 1)
380 p *= pow(v1,alpha1);
381
382 return p;
383 } // CDF
384
385}; // vToTheAlpha
386
388class truncated: public BCEDistr
389{
390public:
394 double min0;
396 double min1;
398 double max0;
400 double max1;
401
403
406 dist(_dist),
407 min0(0),
408 min1(0),
409 max0(1),
410 max1(1)
411 {}
412
414
417 double _min, double _max):
418 dist(_dist),
419 min0(_min),
420 min1(_min),
421 max0(_max),
422 max1(_max)
423 {}
424
426
429 double _min0, double _min1,
430 double _max0, double _max1):
431 dist(_dist),
432 min0(_min0),
433 min1(_min1),
434 max0(_max0),
435 max1(_max1)
436 {
437 assert(max0 >= min0);
438 assert(max1 >= min1);
439 }
440
442 double CDF(double v0, double v1) const
443 {
444 // if (v0 < min0)
445 // v0 = min0;
446 // else if (v0 > max0)
447 // v0 = max0;
448
449 // if (v1 < min1)
450 // v1 = min1;
451 // else if (v1 > max1)
452 // v1 = max1;
453
454 if (v0 < min0-1e-13 || v1 < min1-1e-13)
455 return 0;
456
457 return dist->CDF(v0,v1)-dist->CDF(min0,min1);
458 } // CDF
459};
460
461#endif
Weighted sum of distributions.
Definition: bcedistr.hpp:71
vector< double > weights
Weights corresponding to distributions.
Definition: bcedistr.hpp:76
vector< BCEDistr * > distributions
Vector of pointers to distributions.
Definition: bcedistr.hpp:74
bool contains(BCEDistr *distr) const
Recursive check if BCEDistr contains distr.
Definition: bcedistr.hpp:117
~BCEDistrArray()
Destructor.
Definition: bcedistr.hpp:84
bool push_back(BCEDistr *newDistr, double newWeight)
Add a new distribution to the array.
Definition: bcedistr.hpp:97
void clear()
Deletes all of the distributions in the array.
Definition: bcedistr.hpp:142
BCEDistrArray()
Default constructor.
Definition: bcedistr.hpp:80
double CDF(double v0, double v1) const
Implements BCEDistr::CDF to calculate the weighted sum of CDFs.
Definition: bcedistr.hpp:154
Utility class for probability distributions.
Definition: bcedistr.hpp:39
double PDF(double v0, double v1, double incr) const
Discretized PDF for the BCEDistr.
Definition: bcedistr.hpp:57
virtual double CDF(double v0, double v1) const =0
The joint CDF of the distribution.
virtual ~BCEDistr()
Virtual destructor.
Definition: bcedistr.hpp:63
double PDF(double v0, double incr0, double v1, double incr1) const
Discretized PDF for the BCEDistr.
Definition: bcedistr.hpp:47
Definition: bcedistr.hpp:227
double CDF(double v0, double v1) const
The joint CDF of the distribution.
Definition: bcedistr.hpp:231
Bernoulli distribution.
Definition: bcedistr.hpp:265
double CDF(double v0, double v1) const
The joint CDF of the distribution.
Definition: bcedistr.hpp:271
Truncated version of a distribution.
Definition: bcedistr.hpp:389
double CDF(double v0, double v1) const
Implements BCEDistr::CDF.
Definition: bcedistr.hpp:442
BCEDistr * dist
The distribution being truncated.
Definition: bcedistr.hpp:392
double min1
Minimum 1 coordinate.
Definition: bcedistr.hpp:396
truncated(BCEDistr *_dist, double _min, double _max)
Constructor.
Definition: bcedistr.hpp:416
truncated(BCEDistr *_dist)
Constructor.
Definition: bcedistr.hpp:405
double max0
Maximum 0 coordinate.
Definition: bcedistr.hpp:398
double min0
Minimum 0 coordinate.
Definition: bcedistr.hpp:394
double max1
Maximum 1 coordinate.
Definition: bcedistr.hpp:400
truncated(BCEDistr *_dist, double _min0, double _min1, double _max0, double _max1)
Constructor.
Definition: bcedistr.hpp:428
Uniform distribution.
Definition: bcedistr.hpp:241
double CDF(double v0, double v1) const
The joint CDF of the distribution.
Definition: bcedistr.hpp:245
Uniform distribution with no ties.
Definition: bcedistr.hpp:322
double CDF(double v0, double v1) const
The joint CDF of the distribution.
Definition: bcedistr.hpp:329
Uniform w/ mass at zero.
Definition: bcedistr.hpp:291
double CDF(double v0, double v1) const
The joint CDF of the distribution.
Definition: bcedistr.hpp:298
Unimodal distribution.
Definition: bcedistr.hpp:174
double CDF(double v0, double v1) const
The joint CDF of the distribution.
Definition: bcedistr.hpp:208
CDF is of the form .
Definition: bcedistr.hpp:352
double CDF(double v0, double v1) const
The joint CDF of the distribution.
Definition: bcedistr.hpp:369