void GLaguer::GetPhylipLaguer(const int categs, MDOUBLE alpha, Vdouble & points, Vdouble & weights) { /* calculate rates and probabilities to approximate Gamma distribution of rates with "categs" categories and shape parameter "alpha" using rates and weights from Generalized Laguerre quadrature */ points.resize(categs, 0.0); weights.resize(categs, 0.0); long i; raterootarray lgroot; /* roots of GLaguerre polynomials */ double f, x, xi, y; alpha = alpha - 1.0; lgroot[1][1] = 1.0+alpha; for (i = 2; i <= categs; i++) { cerr<<lgroot[i][1]<<"\t"; lgr(i, alpha, lgroot); /* get roots for L^(a)_n */ cerr<<lgroot[i][1]<<endl; } /* here get weights */ /* Gamma weights are (1+a)(1+a/2) ... (1+a/n)*x_i/((n+1)^2 [L_{n+1}^a(x_i)]^2) */ f = 1; for (i = 1; i <= categs; i++) f *= (1.0+alpha/i); for (i = 1; i <= categs; i++) { xi = lgroot[categs][i]; y = glaguerre(categs+1, alpha, xi); x = f*xi/((categs+1)*(categs+1)*y*y); points[i-1] = xi/(1.0+alpha); weights[i-1] = x; } }
MDOUBLE siteSpecificRateGL::computeML_siteSpecificRate(Vdouble & ratesV, Vdouble & likelihoodsV, const Vint& spAttributesVec, const Vint& treeAttributesVec, const vector<tree> & etVec, const vector<const stochasticProcess *> & spVec, const sequenceContainer& sc, const MDOUBLE maxRate, const MDOUBLE tol){ MDOUBLE Lsum = 0.0; ratesV.resize(sc.seqLen()); // the rates themselves likelihoodsV.resize(sc.seqLen()); // the log likelihood of each position for (int pos=0; pos < sc.seqLen(); ++pos) { LOG(5,<<"."); MDOUBLE bestR=-1.0; // tree1 // MDOUBLE LmaxR1=0; // getting the right tree for the specific position: const tree* treeForThisPosition=NULL; if ((etVec.size() >0 ) && (treeAttributesVec[pos]>0)) { treeForThisPosition = & etVec[ treeAttributesVec[pos] -1]; } else { errorMsg::reportError("tree vector is empty, or treeAttribute is empty, or treeAttribute[pos] is zero (it should be one)"); } // getting the right stochastic process for the specific position: const stochasticProcess* spForThisPosition=NULL; if ((spVec.size() >0 ) && (spAttributesVec[pos]>0)) { spForThisPosition = spVec[ spAttributesVec[pos] -1]; } else { errorMsg::reportError("stochastic process vector is empty, or spAttributesVec is empty, or spAttribute[pos] is zero (it should be one)"); } siteSpecificRateGL::computeML_siteSpecificRate(pos,sc,*spForThisPosition,*treeForThisPosition,bestR,likelihoodsV[pos],maxRate,tol); ratesV[pos] = bestR; assert(likelihoodsV[pos]>0.0); Lsum += log(likelihoodsV[pos]); LOG(5,<<" rate of pos: "<<pos<<" = "<<ratesV[pos]<<endl); } LOG(5,<<" number of sites: "<<sc.seqLen()<<endl); return Lsum; }
//Input: alf = the alpha parameter of the Laguerre polynomials // pointsNum = the polynom order //Output: the abscissas and weights are stored in the vecotrs x and w, respectively. //Discreption: given alf, the alpha parameter of the Laguerre polynomials, the function returns the abscissas and weights // of the n-point Guass-Laguerre quadrature formula. // The smallest abscissa is stored in x[0], the largest in x[pointsNum - 1]. void GLaguer::gaulag(Vdouble &x, Vdouble &w, const MDOUBLE alf, const int pointsNum) { x.resize(pointsNum, 0.0); w.resize(pointsNum, 0.0); const int MAXIT=10000; const MDOUBLE EPS=1.0e-6; int i,its,j; MDOUBLE ai,p1,p2,p3,pp,z=0.0,z1; int n= x.size(); for (i=0;i<n;i++) { //loops over the desired roots if (i == 0) { //initial guess for the smallest root z=(1.0+alf)*(3.0+0.92*alf)/(1.0+2.4*n+1.8*alf); } else if (i == 1) {//initial guess for the second smallest root z += (15.0+6.25*alf)/(1.0+0.9*alf+2.5*n); } else { //initial guess for the other roots ai=i-1; z += ((1.0+2.55*ai)/(1.9*ai)+1.26*ai*alf/ (1.0+3.5*ai))*(z-x[i-2])/(1.0+0.3*alf); } for (its=0;its<MAXIT;its++) { //refinement by Newton's method p1=1.0; p2=0.0; for (j=0;j<n;j++) { //Loop up the recurrence relation to get the Laguerre polynomial evaluated at z. p3=p2; p2=p1; p1=((2*j+1+alf-z)*p2-(j+alf)*p3)/(j+1); } //p1 is now the desired Laguerre polynomial. We next compute pp, its derivative, //by a standard relation involving also p2, the polynomial of one lower order. pp=(n*p1-(n+alf)*p2)/z; z1=z; z=z1-p1/pp; //Newton's formula if (fabs(z-z1) <= EPS) break; } if (its >= MAXIT) errorMsg::reportError("too many iterations in gaulag"); x[i]=z; w[i] = -exp(gammln(alf+n)-gammln(MDOUBLE(n)))/(pp*n*p2); } }
MDOUBLE siteSpecificRateGL::computeML_siteSpecificRate(Vdouble & ratesV, Vdouble & likelihoodsV, const sequenceContainer& sc, const stochasticProcess& sp, const tree& et, const MDOUBLE maxRate,//20.0f const MDOUBLE tol){//=0.0001f; ratesV.resize(sc.seqLen()); likelihoodsV.resize(sc.seqLen()); MDOUBLE Lsum = 0.0; for (int pos=0; pos < sc.seqLen(); ++pos) { siteSpecificRateGL::computeML_siteSpecificRate(pos,sc,sp,et,ratesV[pos],likelihoodsV[pos],maxRate,tol); assert(likelihoodsV[pos]>0.0); Lsum += log(likelihoodsV[pos]); LOG(5,<<" rate of pos: "<<pos<<" = "<<ratesV[pos]<<endl); } LOG(5,<<" number of sites: "<<sc.seqLen()<<endl); return Lsum; }