// $Id: GLaguer.cpp 962 2006-11-07 15:13:34Z privmane $ #include "definitions.h" #include "GLaguer.h" #include "errorMsg.h" #include "gammaUtilities.h" GLaguer::GLaguer(const int pointsNum, const MDOUBLE alf, Vdouble & points, Vdouble & weights) { gaulag(_points, _weights, alf, pointsNum); weights = _weights; points = _points; } //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= MAXIT) errorMsg::reportError("too many iterations in gaulag"); x[i]=z; w[i] = -exp(gammln(alf+n)-gammln(MDOUBLE(n)))/(pp*n*p2); } } 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< 0.0)) || ((!dwn) && (y < 0.0))); upper = x; } while (upper-lower > 0.000000001) { x = (upper+lower)/2.0; if (glaguerre(m, alpha, x) > 0.0) { if (dwn) lower = x; else upper = x; } else { if (dwn) upper = x; else lower = x; } } lgroot[m][i] = (lower+upper)/2.0; dwn = !dwn; // switch for next one } } } /* lgr */ double GLaguer::glaguerre(long m, double b, double x) { /* Generalized Laguerre polynomial computed recursively. For use by initgammacat */ long i; double gln, glnm1, glnp1; /* L_n, L_(n-1), L_(n+1) */ if (m == 0) return 1.0; else { if (m == 1) return 1.0 + b - x; else { gln = 1.0+b-x; glnm1 = 1.0; for (i=2; i <= m; i++) { glnp1 = ((2*(i-1)+b+1.0-x)*gln - (i-1+b)*glnm1)/i; glnm1 = gln; gln = glnp1; } return gln; } } } /* glaguerre */