/[PAMELA software]/PamUnfold/src/RanGen.cpp
ViewVC logotype

Contents of /PamUnfold/src/RanGen.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (show annotations) (download)
Thu Aug 30 16:51:05 2018 UTC (6 years, 3 months ago) by mayorov
Branch: MAIN
CVS Tags: PU1r1, HEAD
PamUnfold was upload to CVS

1 #include <RanGen.h>
2
3 using namespace std;
4
5 ClassImp(RanGen);
6
7 RanGen::RanGen(Int_t seed) : TRandom3(seed){
8 }
9
10 RanGen::~RanGen(){};
11
12 Double_t RanGen::Gamma(Int_t n, Double_t theta){
13
14 Double_t value = 0;
15
16 for(Int_t i=0; i<n; i++) value -= TMath::Log( this->Uniform() );
17
18 return value;
19
20 }
21
22
23 vector<Double_t> RanGen::Dirichlet(Int_t n, vector<Int_t> x){
24
25 Double_t sum = 0;
26 vector<Double_t> gammas(n);
27 vector<Double_t> value(n);
28
29 for(Int_t i=0; i<n; i++){
30 gammas[i] = Gamma(x[i], 1);
31 sum += gammas[i];
32 }
33
34 for(Int_t i=0; i<n; i++){
35 if(sum)
36 value[i] = gammas[i]/sum;
37 else
38 value[i] = 0;
39 }
40
41 return value;
42
43 }
44
45
46 Int_t RanGen::Binomial(Int_t n, Double_t p){
47 unsigned int i, a, b, k = 0;
48 while (n > 10) /* This parameter is tunable */
49 {
50 double X;
51 a = 1 + (n / 2);
52 b = 1 + n - a;
53
54 X = this->Beta((Int_t) a, (Int_t) b);
55
56 if (X >= p)
57 {
58 n = a - 1;
59 p /= X;
60 }
61 else
62 {
63 k += a;
64 n = b - 1;
65 p = (p - X) / (1 - X);
66 }
67 }
68
69 for (i = 0; i < n; i++)
70 {
71 double u = this->Uniform();
72 if (u < p)
73 k++;
74 }
75
76 return k;
77
78 }
79
80 Double_t RanGen::Beta(const Int_t a, const Int_t b){
81 double x1 = this->Gamma(a, 1.0);
82 double x2 = this->Gamma(b, 1.0);
83
84 return x1 / (x1 + x2);
85 }
86
87 vector<Int_t> RanGen::Multinomial(Int_t N, vector<Double_t> p){
88
89 /* From the GSL Library:
90 The multinomial distribution has the form
91
92 N! n_1 n_2 n_K
93 prob(n_1, n_2, ... n_K) = -------------------- p_1 p_2 ... p_K
94 (n_1! n_2! ... n_K!)
95
96 where n_1, n_2, ... n_K are nonnegative integers, sum_{k=1,K} n_k = N,
97 and p = (p_1, p_2, ..., p_K) is a probability distribution.
98
99 Random variates are generated using the conditional binomial method.
100 This scales well with N and does not require a setup step.
101
102 Ref:
103 C.S. David, The computer generation of multinomial random variates,
104 Comp. Stat. Data Anal. 16 (1993) 205-217
105 */
106
107 size_t K = p.size();
108 vector<Int_t> n(K);
109
110 size_t k;
111 double norm = 0.0;
112 double sum_p = 0.0;
113
114 unsigned int sum_n = 0;
115
116 /* p[k] may contain non-negative weights that do not sum to 1.0.
117 * Even a probability distribution will not exactly sum to 1.0
118 * due to rounding errors.
119 */
120
121 for (k = 0; k < K; k++)
122 {
123 norm += p[k];
124 }
125
126 for (k = 0; k < K; k++)
127 {
128 if (p[k] > 0.0)
129 {
130 n[k] = this->Binomial(N - sum_n, p[k] / (norm - sum_p));
131 }
132 else
133 {
134 n[k] = 0;
135 }
136
137 sum_p += p[k];
138 sum_n += n[k];
139 }
140 return n;
141
142 }

  ViewVC Help
Powered by ViewVC 1.1.23