int DiscreteGamma (double freqK[], double rK[], double alfa, double beta, int K, int median) { /* discretization of gamma distribution with equal proportions in each category */ int i; double gap05=1.0/(2.0*K), t, factor=alfa/beta*K, lnga1; if (median) { for (i=0; i<K; i++) rK[i]=PointGamma((i*2.0+1)*gap05, alfa, beta); for (i=0,t=0; i<K; i++) t+=rK[i]; for (i=0; i<K; i++) rK[i]*=factor/t; } else { lnga1=LnGamma(alfa+1); for (i=0; i<K-1; i++) freqK[i]=PointGamma((i+1.0)/K, alfa, beta); for (i=0; i<K-1; i++) freqK[i]=IncompleteGamma(freqK[i]*beta, alfa+1, lnga1); rK[0] = freqK[0]*factor; rK[K-1] = (1-freqK[K-2])*factor; for (i=1; i<K-1; i++) rK[i] = (freqK[i]-freqK[i-1])*factor; } for (i=0; i<K; i++) freqK[i]=1.0/K; return (0); }
void DGamRateProcess::UpdateDiscreteCategories() { if (withpinv) { double* x = new double[GetNcat()-1]; double* y = new double[GetNcat()-1]; double lg = rnd::GetRandom().logGamma(alpha+1.0); for (int i=0; i<GetNcat()-1; i++) { x[i] = PointGamma((i+1.0)/(GetNcat()-1),alpha,alpha); } for (int i=0; i<GetNcat()-2; i++) { y[i] = IncompleteGamma(alpha*x[i],alpha+1,lg); } y[GetNcat()-2] = 1.0; rate[0] = 0; rate[1] = (GetNcat()-1) * y[0]; for (int i=1; i<(GetNcat()-1); i++) { rate[i+1] = (GetNcat()-1) * (y[i] - y[i-1]); } delete[] x; delete[] y; } else { double* x = new double[GetNcat()]; double* y = new double[GetNcat()]; double lg = rnd::GetRandom().logGamma(alpha+1.0); for (int i=0; i<GetNcat(); i++) { x[i] = PointGamma((i+1.0)/GetNcat(),alpha,alpha); } for (int i=0; i<GetNcat()-1; i++) { y[i] = IncompleteGamma(alpha*x[i],alpha+1,lg); } y[GetNcat()-1] = 1.0; rate[0] = GetNcat() * y[0]; for (int i=1; i<GetNcat(); i++) { rate[i] = GetNcat() * (y[i] - y[i-1]); } delete[] x; delete[] y; } }