-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdirichlet.cpp
134 lines (103 loc) · 2.93 KB
/
dirichlet.cpp
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
#include "global_defs.h"
#include <math.h>
double dirichlet(double vectX[],double vectA[],int arraySize)
/*This function returns the log of the dirichlet density with parameters vectA
for a vectorX */
{
int i;
double Sumlogxi;
double Sumloggamma,SumDirAlphas;
double density; //this is the density that will be returned by the function
// float gammaln(float xx);
Sumloggamma=0;
Sumlogxi=0;
SumDirAlphas=0;
for (i=0;i<arraySize;i++)
{
Sumloggamma += gammaln(vectA[i]);
Sumlogxi += (vectA[i]-1.)*logl(vectX[i]);
SumDirAlphas += vectA[i];
}
density = gammaln(SumDirAlphas) - Sumloggamma + Sumlogxi;
return (density);
}
float DumRan;
//----------------------------------
/* This function generates a vector (of dimension arraySize) of Dirichlet
random variables with parameters vectA and stores them in vect. */
void dirichlet_dev(double vectX[],double vectA[],int arraySize)
{
int i;
double sum=0.0;
double rstgam(double alpha1);
// now we get the deviates
for (i=0;i<arraySize;i++)
{
if (vectA[i]>1.0)
vectX[i]=rstgam(vectA[i]);
else if (vectA[i]<1.0)
{
/*do {
DumRan = ranf();
}
while (DumRan >= 1);*/
DumRan=randgen.randDblExc();
vectX[i]=rstgam(vectA[i]+1.0)*pow((double) DumRan,1.0/vectA[i]);
}
else
{
/* do {
DumRan = ranf();
}
while (DumRan >= 1);*/
DumRan=randgen.randDblExc();
vectX[i]=(-logl((double) DumRan));
}
sum += vectX[i];
}
for (i=0;i<arraySize;i++)
vectX[i]=vectX[i]/sum;
return;
}
/* Chen and Feast algorithm (algorithm 3.20 in Ripley 1988) for generating a
standard Gamma random variable with shape parameter alpha>1) */
double rstgam(double alpha1)
{
int acpt;
double c1,c2,c3,c4,c5,u1,u2,w;
c1=alpha1-1.0;
c2=(alpha1-(1.0/(6.0*alpha1)))/c1;
c3=2.0/c1;
c4=c3+2.0;
c5=1.0/sqrt(alpha1);
do
{
do
{
/*do {
DumRan = ranf();
}
while (DumRan >= 1);
u1=DumRan;*/
u1=randgen.randDblExc();
/*do {
DumRan = ranf();
}
while (DumRan >= 1);
u2=DumRan;*/
u2=randgen.randDblExc();
if (alpha1>2.5)
u1=u2+c5*(1.0-(1.86*u1));
}
while (u1>=1.0 || u1<=0);
w=(c2*u2)/u1;
if ((c3*u1+w+(1.0/w))<=c4)
acpt=1;
else if ((c3*logl(u1)-logl(w)+w)>=1.0) //repeat outer do loop
acpt=0;
else
acpt=1;
}
while (acpt!=1);
return c1*w;
}