📄 phylip.c
字号:
done = true; for (i = 0; i < categs; i++){ scanned = sscanf(line,"%lf %[^\n]", &rate[i],rest); if ((scanned < 2 && i < (categs - 1)) || (scanned < 1 && i == (categs - 1))){ printf("Please enter exactly %ld values.\n",categs); done = false; break; } strcpy(line,rest); } if (done) break; countup(&loopcount, 100); }} /*initcategs*/void initprobcat(long categs, double *probsum, double *probcat){ /* input probabilities of rate categores for HMM rates */ long i, loopcount, scanned; boolean done; char line[100], rest[100]; loopcount = 0; do { printf("Probability for each category?"); printf(" (use a space to separate)\n"); getstryng(line); done = true; for (i = 0; i < categs; i++){ scanned = sscanf(line,"%lf %[^\n]",&probcat[i],rest); if ((scanned < 2 && i < (categs - 1)) || (scanned < 1 && i == (categs - 1))){ done = false; printf("Please enter exactly %ld values.\n",categs); break;} strcpy(line,rest); } if (!done) continue; *probsum = 0.0; for (i = 0; i < categs; i++) *probsum += probcat[i]; if (fabs(1.0 - (*probsum)) > 0.001) { done = false; printf("Probabilities must add up to"); printf(" 1.0, plus or minus 0.001.\n"); } countup(&loopcount, 100); } while (!done);} /*initprobcat*/void lgr(long m, double b, raterootarray lgroot){ /* For use by initgammacat. Get roots of m-th Generalized Laguerre polynomial, given roots of (m-1)-th, these are to be stored in lgroot[m][] */ long i; double upper, lower, x, y; boolean dwn; /* is function declining in this interval? */ if (m == 1) { lgroot[1][1] = 1.0+b; } else { dwn = true; for (i=1; i<=m; i++) { if (i < m) { if (i == 1) lower = 0.0; else lower = lgroot[m-1][i-1]; upper = lgroot[m-1][i]; } else { /* i == m, must search above */ lower = lgroot[m-1][i-1]; x = lgroot[m-1][m-1]; do { x = 2.0*x; y = glaguerre(m, b,x); } while ((dwn && (y > 0.0)) || ((!dwn) && (y < 0.0))); upper = x; } while (upper-lower > 0.000000001) { x = (upper+lower)/2.0; if (glaguerre(m, b, 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 logfac (long n){ /* log(n!) values were calculated with Mathematica with a precision of 30 digits */ long i; double x; switch (n) { case 0: return 0.; case 1: return 0.; case 2: return 0.693147180559945309417232121458; case 3: return 1.791759469228055000812477358381; case 4: return 3.1780538303479456196469416013; case 5: return 4.78749174278204599424770093452; case 6: return 6.5792512120101009950601782929; case 7: return 8.52516136106541430016553103635; case 8: return 10.60460290274525022841722740072; case 9: return 12.80182748008146961120771787457; case 10: return 15.10441257307551529522570932925; case 11: return 17.50230784587388583928765290722; case 12: return 19.98721449566188614951736238706; default: x = 19.98721449566188614951736238706; for (i = 13; i <= n; i++) x += log(i); return x; }} double 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 */void initlaguerrecat(long categs, double alpha, double *rate, double *probcat){ /* 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 */ 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++) lgr(i, alpha, lgroot); /* get roots for L^(a)_n */ /* 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); rate[i-1] = xi/(1.0+alpha); probcat[i-1] = x; }} /* initlaguerrecat */double hermite(long n, double x){ /* calculates hermite polynomial with degree n and parameter x */ /* seems to be unprecise for n>13 -> root finder does not converge*/ double h1 = 1.; double h2 = 2. * x; double xx = 2. * x; long i; for (i = 1; i < n; i++) { xx = 2. * x * h2 - 2. * (i) * h1; h1 = h2; h2 = xx; } return xx;} /* hermite */void root_hermite(long n, double *hroot){ /* find roots of Hermite polynmials */ long z; long ii; long start; if (n % 2 == 0) { start = n/2; z = 1; } else { start = n/2 + 1; z=2; hroot[start-1] = 0.0; } for (ii = start; ii < n; ii++) { /* search only upwards*/ hroot[ii] = halfroot(hermite,n,hroot[ii-1]+EPSILON, 1./n); hroot[start - z] = -hroot[ii]; z++; }} /* root_hermite */double halfroot(double (*func)(long m, double x), long n, double startx, double delta){ /* searches from the bound (startx) only in one direction (by positive or negative delta, which results in other-bound=startx+delta) delta should be small. (*func) is a function with two arguments */ double xl; double xu; double xm; double fu; double fl; double fm = 100000.; double gradient; boolean dwn; /* decide if we search above or below startx and escapes to trace back to the starting point that most often will be the root from the previous calculation */ if (delta < 0) { xu = startx; xl = xu + delta; } else { xl = startx; xu = xl + delta; } delta = fabs(delta); fu = (*func)(n, xu); fl = (*func)(n, xl); gradient = (fl-fu)/(xl-xu); while(fabs(fm) > EPSILON) { /* is root outside of our bracket?*/ if ((fu<0.0 && fl<0.0) || (fu>0.0 && fl > 0.0)) { xu += delta; fu = (*func)(n, xu); fl = (*func)(n, xl); gradient = (fl-fu)/(xl-xu); dwn = (gradient < 0.0) ? true : false; } else { xm = xl - fl / gradient; fm = (*func)(n, xm); if (dwn) { if (fm > 0.) { xl = xm; fl = fm; } else { xu = xm; fu = fm; } } else { if (fm > 0.) { xu = xm; fu = fm; } else { xl = xm; fl = fm; } } gradient = (fl-fu)/(xl-xu); } } return xm;} /* halfroot */void hermite_weight(long n, double * hroot, double * weights){ /* calculate the weights for the hermite polynomial at the roots using formula Abramowitz and Stegun chapter 25.4.46 p.890 */ long i; double hr2; double numerator; numerator = exp(0.6931471805599 * ( n-1.) + logfac(n)) / (n*n); for (i = 0; i < n; i++) { hr2 = hermite(n-1, hroot[i]); weights[i] = numerator / (hr2*hr2); }} /* hermiteweight */void inithermitcat(long categs, double alpha, double *rate, double *probcat){ /* calculates rates and probabilities */ long i; double *hroot; double std; std = SQRT2 /sqrt(alpha); hroot = (double *) Malloc((categs+1) * sizeof(double)); root_hermite(categs, hroot); /* calculate roots */ hermite_weight(categs, hroot, probcat); /* set weights */ for (i=0; i<categs; i++) { /* set rates */ rate[i] = 1.0 + std * hroot[i]; probcat[i] = probcat[i]; } free(hroot);} /* inithermitcat */void initgammacat (long categs, double alpha, double *rate, double *probcat){ /* 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 or from Hermite quadrature */ if (alpha >= 100.0) inithermitcat(categs, alpha, rate, probcat); else initlaguerrecat(categs, alpha, rate, probcat);} /* initgammacat */void inithowmany(long *howmany, long howoften){/* input how many cycles */ long loopcount; loopcount = 0; do { printf("How many cycles of %4ld trees?\n", howoften); scanf("%ld%*[^\n]", howmany); getchar(); countup(&loopcount, 10); } while (*howmany <= 0);} /*inithowmany*/void inithowoften(long *howoften){ /* input how many trees per cycle */ long loopcount; loopcount = 0; do { printf("How many trees per cycle?\n"); scanf("%ld%*[^\n]", howoften); getchar(); countup(&loopcount, 10); } while (*howoften <= 0);} /*inithowoften*/void initlambda(double *lambda){ /* input patch length parameter for autocorrelated HMM rates */ long loopcount; loopcount = 0; do { printf("Mean block length of sites having the same rate (greater than 1)?\n"); scanf("%lf%*[^\n]", lambda); getchar(); countup(&loopcount, 10); } while (*lambda <= 1.0); *lambda = 1.0 / *lambda;} /*initlambda*/void initfreqs(double *freqa, double *freqc, double *freqg, double *freqt){ /* input frequencies of the four bases */ char input[100]; long scanned, loopcount; printf("Base frequencies for A, C, G, T/U (use blanks to separate)?\n"); loopcount = 0; do { getstryng(input); scanned = sscanf(input,"%lf%lf%lf%lf%*[^\n]", freqa, freqc, freqg, freqt); if (scanned == 4) break; else printf("Please enter exactly 4 values.\n"); countup(&loopcount, 100); } while (1);} /* initfreqs */void initratio(double *ttratio){ /* input transition/transversion ratio */ long loopcount; loopcount = 0; do { printf("Transition/transversion ratio?\n"); scanf("%lf%*[^\n]", ttratio); getchar(); countup(&loopcount, 10); } while (*ttratio < 0.0);} /* initratio */void initpower(double *power){ printf("New power?\n"); scanf("%lf%*[^\n]", power); getchar();} /*initpower*/void initdatasets(long *datasets){ /* handle multi-data set option */ long loopcount; boolean done; loopcount = 0; do { printf("How many data sets?\n"); scanf("%ld%*[^\n]", datasets); getchar(); done = (*datasets > 1); if (!done) printf("Bad data sets number: it must be greater than 1\n"); countup(&loopcount, 10); } while (!done);} /* initdatasets */void justweights(long *datasets){ /* handle multi-data set option by weights */ long loopcount; boolean done; loopcount = 0; do { printf("How many sets of weights?\n"); scanf("%ld%*[^\n]", datasets); getchar(); done = (*datasets >= 1); if (!done) printf("BAD NUMBER: it must be greater than 1\n"); countup(&loopcount, 10); } while (!done);} /* justweights */void initterminal(boolean *ibmpc, boolean *ansi){ /* handle terminal option */ if (*ibmpc) { *ibmpc = false; *ansi = true; } else if (*ansi) *ansi = false; else *ibmpc = true;} /*initterminal*/void initnumlines(long *screenlines){ long loopcount; loopcount = 0; do { *screenlines = readlong("Number of lines on screen?\n"); countup(&loopcount, 10); } while (*screenlines <= 12);} /*initnumlines*/void initbestrees(bestelm *bestrees, long maxtrees, boolean glob){ /* initializes either global or local field of each array in bestrees */ long i; if (glob) for (i = 0; i < maxtrees; i++) bestrees[i].gloreange = false; else for (i = 0; i < maxtrees; i++) bestrees[i].locreange = false;} /* initbestrees */void newline(FILE *filename, long i, long j, long k)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -