📄 proml.c
字号:
sum = 0.0; for (j = 0; j < rcategs; j++) { for (k = 0; k < categs; k++) { make_pmatrix(pmatrices[0][j][k], dpmatrix[j][k], ddpmatrix[j][k], 2, y, tbl[j][k], eigmat, probmat); } } for (i = 0; i < endsite; i++) { k = category[alias[i]-1] - 1; for (j = 0; j < rcategs; j++) { memcpy(x1, p->protx[i][j], sizeof(psitelike)); memcpy(x2, q->protx[i][j], sizeof(psitelike)); pmat = pmatrices[0][j][k]; dpmat = dpmatrix[j][k]; ddpmat = ddpmatrix[j][k]; prod4 = 0.0; prod5 = 0.0; prod6 = 0.0; for (m = 0; m <= 19; m++) { prod4m = 0.0; prod5m = 0.0; prod6m = 0.0; frexm = x1[m] * freqaa[m]; for (l = 0; l <= 19; l++) { prod4m += x2[l] * pmat[m][l]; prod5m += x2[l] * dpmat[m][l]; prod6m += x2[l] * ddpmat[m][l]; } prod4 += frexm * prod4m; prod5 += frexm * prod5m; prod6 += frexm * prod6m; } term[i][j] = prod4; slopeterm[i][j] = prod5; curveterm[i][j] = prod6; } sumterm = 0.0; for (j = 0; j < rcategs; j++) sumterm += probcat[j] * term[i][j]; if (sumterm < 0.0) sumterm = 0.00000001; /* ??? */ lterm = log(sumterm); for (j = 0; j < rcategs; j++) { term[i][j] = term[i][j] / sumterm; slopeterm[i][j] = slopeterm[i][j] / sumterm; curveterm[i][j] = curveterm[i][j] / sumterm; } sum += (aliasweight[i] * lterm); } for (i = 0; i < rcategs; i++) { thelike[i] = 1.0; theslope[i] = 0.0; thecurve[i] = 0.0; } for (i = 0; i < sites; i++) { sumc = 0.0; sumcs = 0.0; sumcc = 0.0; for (k = 0; k < rcategs; k++) { sumc += probcat[k] * thelike[k]; sumcs += probcat[k] * theslope[k]; sumcc += probcat[k] * thecurve[k]; } sumc *= lambda; sumcs *= lambda; sumcc *= lambda; if ((ally[i] > 0) && (location[ally[i]-1] > 0)) { lai = location[ally[i] - 1]; memcpy(clai, term[lai - 1], rcategs*sizeof(double)); memcpy(cslai, slopeterm[lai - 1], rcategs*sizeof(double)); memcpy(cclai, curveterm[lai - 1], rcategs*sizeof(double)); if (weight[i] > 1) { for (j = 0; j < rcategs; j++) { if (clai[j] > 0.0) clai[j] = exp(weight[i]*log(clai[j])); else clai[j] = 0.0; if (cslai[j] > 0.0) cslai[j] = exp(weight[i]*log(cslai[j])); else cslai[j] = 0.0; if (cclai[j] > 0.0) cclai[j] = exp(weight[i]*log(cclai[j])); else cclai[j] = 0.0; } } for (j = 0; j < rcategs; j++) { nulike[j] = ((1.0 - lambda) * thelike[j] + sumc) * clai[j]; nuslope[j] = ((1.0 - lambda) * theslope[j] + sumcs) * clai[j] + ((1.0 - lambda) * thelike[j] + sumc) * cslai[j]; nucurve[j] = ((1.0 - lambda) * thecurve[j] + sumcc) * clai[j] + 2.0 * ((1.0 - lambda) * theslope[j] + sumcs) * cslai[j] + ((1.0 - lambda) * thelike[j] + sumc) * cclai[j]; } } else { for (j = 0; j < rcategs; j++) { nulike[j] = ((1.0 - lambda) * thelike[j] + sumc); nuslope[j] = ((1.0 - lambda) * theslope[j] + sumcs); nucurve[j] = ((1.0 - lambda) * thecurve[j] + sumcc); } } memcpy(thelike, nulike, rcategs*sizeof(double)); memcpy(theslope, nuslope, rcategs*sizeof(double)); memcpy(thecurve, nucurve, rcategs*sizeof(double)); } sum2 = 0.0; slope2 = 0.0; curve2 = 0.0; for (i = 0; i < rcategs; i++) { sum2 += probcat[i] * thelike[i]; slope2 += probcat[i] * theslope[i]; curve2 += probcat[i] * thecurve[i]; } sum += log(sum2); (*like) = sum; (*slope) = slope2 / sum2; (*curve) = (curve2 - slope2 * slope2 / sum2) / sum2;} /* prot_slopecurv */void makenewv(node *p){ /* Newton-Raphson algorithm improvement of a branch length */ long it, ite; double y, yold=0, yorig, like, slope, curve, oldlike=0; boolean done, firsttime, better; node *q; q = p->back; y = p->v; yorig = y; done = false; firsttime = true; it = 1; ite = 0; while ((it < iterations) && (ite < 20) && (!done)) { prot_slopecurv(p, y, &like, &slope, &curve); better = false; if (firsttime) { yold = y; oldlike = like; firsttime = false; better = true; } else { if (like > oldlike) { yold = y; oldlike = like; better = true; it++; } } if (better) { y = y + slope/fabs(curve); if (y < epsilon) y = epsilon; } else { if (fabs(y - yold) < epsilon) ite = 20; y = (y + (7 * yold)) / 8; } ite++; done = fabs(y-yold) < epsilon; } smoothed = (fabs(yold-yorig) < epsilon) && (yorig > 1000.0*epsilon); p->v = yold; q->v = yold; curtree.likelihood = oldlike;} /* makenewv */void update(node *p){ long num_sibs, i; node *sib_ptr; if (!p->tip && !p->initialized) prot_nuview(p); if (!p->back->tip && !p->back->initialized) prot_nuview(p->back); if (p->iter) { makenewv(p); if (!p->tip) { num_sibs = count_sibs(p); sib_ptr = p; for (i=0; i < num_sibs; i++) { sib_ptr = sib_ptr->next; sib_ptr->initialized = false; } } if (!p->back->tip) { num_sibs = count_sibs(p->back); sib_ptr = p->back; for (i=0; i < num_sibs; i++) { sib_ptr = sib_ptr->next; sib_ptr->initialized = false; } } }} /* update */void smooth(node *p){ long i, num_sibs; node *sib_ptr; smoothed = false; update(p); if (p->tip) return; num_sibs = count_sibs(p); sib_ptr = p; for (i=0; i < num_sibs; i++) { sib_ptr = sib_ptr->next; if (polishing || (smoothit && !smoothed)) { smooth(sib_ptr->back); p->initialized = false; sib_ptr->initialized = false; } }} /* smooth */void make_pmatrix(double **matrix, double **dmat, double **ddmat, long derivative, double lz, double rat, double *eigmat, double **probmat){ /* Computes the R matrix such that matrix[m][l] is the joint probability */ /* of m and l. */ /* Computes a P matrix such that matrix[m][l] is the conditional */ /* probability of m given l. This is accomplished by dividing all terms */ /* in the R matrix by freqaa[m], the frequency of l. */ long k, l, m; /* (l) original character state */ /* (m) final character state */ /* (k) lambda counter */ double p0, p1, p2, q; double elambdat[20], delambdat[20], ddelambdat[20]; /* exponential term for matrix */ /* and both derivative matrices */ for (k = 0; k <= 19; k++) { elambdat[k] = exp(lz * rat * eigmat[k]); if(derivative != 0) { delambdat[k] = (elambdat[k] * rat * eigmat[k]); ddelambdat[k] = (delambdat[k] * rat * eigmat[k]); } } for (m = 0; m <= 19; m++) { for (l = 0; l <= 19; l++) { p0 = 0.0; p1 = 0.0; p2 = 0.0; for (k = 0; k <= 19; k++) { q = probmat[k][m] * probmat[k][l]; p0 += (q * elambdat[k]); if(derivative !=0) { p1 += (q * delambdat[k]); p2 += (q * ddelambdat[k]); } } matrix[m][l] = p0 / freqaa[m]; if(derivative != 0) { dmat[m][l] = p1 / freqaa[m]; ddmat[m][l] = p2 / freqaa[m]; } } }} /* make_pmatrix */double prot_evaluate(node *p, boolean saveit){ contribarr tterm; double sum, sum2, sumc, y, prod4, prodl, frexm, sumterm, lterm; double **pmat; long i, j, k, l, m, lai; node *q; psitelike x1, x2; sum = 0.0; q = p->back; y = p->v; for (j = 0; j < rcategs; j++) for (k = 0; k < categs; k++) make_pmatrix(pmatrices[0][j][k],NULL,NULL,0,y,tbl[j][k],eigmat,probmat); for (i = 0; i < endsite; i++) { k = category[alias[i]-1] - 1; for (j = 0; j < rcategs; j++) { memcpy(x1, p->protx[i][j], sizeof(psitelike)); memcpy(x2, q->protx[i][j], sizeof(psitelike)); prod4 = 0.0; pmat = pmatrices[0][j][k]; for (m = 0; m <= 19; m++) { prodl = 0.0; for (l = 0; l <= 19; l++) prodl += (pmat[m][l] * x2[l]); frexm = x1[m] * freqaa[m]; prod4 += (prodl * frexm); } tterm[j] = prod4; } sumterm = 0.0; for (j = 0; j < rcategs; j++) sumterm += probcat[j] * tterm[j]; if (sumterm < 0.0) sumterm = 0.00000001; /* ??? */ lterm = log(sumterm); for (j = 0; j < rcategs; j++) clai[j] = tterm[j] / sumterm; memcpy(contribution[i], clai, rcategs*sizeof(double)); if (saveit && !auto_ && usertree) l0gf[which - 1][i] = lterm; sum += aliasweight[i] * lterm; } for (j = 0; j < rcategs; j++) like[j] = 1.0; for (i = 0; i < sites; i++) { sumc = 0.0; for (k = 0; k < rcategs; k++) sumc += probcat[k] * like[k]; sumc *= lambda; if ((ally[i] > 0) && (location[ally[i]-1] > 0)) { lai = location[ally[i] - 1]; memcpy(clai, contribution[lai - 1], rcategs*sizeof(double)); for (j = 0; j < rcategs; j++) nulike[j] = ((1.0 - lambda) * like[j] + sumc) * clai[j]; } else { for (j = 0; j < rcategs; j++) nulike[j] = ((1.0 - lambda) * like[j] + sumc); } memcpy(like, nulike, rcategs*sizeof(double)); } sum2 = 0.0; for (i = 0; i < rcategs; i++) sum2 += probcat[i] * like[i]; sum += log(sum2); curtree.likelihood = sum; if (!saveit || auto_ || !usertree) return sum; l0gl[which - 1] = sum; if (which == 1) { maxwhich = 1; maxlogl = sum; return sum; } if (sum > maxlogl) { maxwhich = which; maxlogl = sum; } return sum;} /* prot_evaluate */void treevaluate(){ /* evaluate a user tree */ long i; inittravtree(curtree.start); polishing = true; smoothit = true; for (i = 1; i <= smoothings * 4; i++) smooth (curtree.start); dummy = prot_evaluate(curtree.start, true);} /* treevaluate */void promlcopy(tree *a, tree *b, long nonodes, long categs){ /* used in proml */ long i, j=0; node *p, *q; for (i = 0; i < spp; i++) { prot_copynode(a->nodep[i], b->nodep[i], categs); if (a->nodep[i]->back) { if (a->nodep[i]->back == a->nodep[a->nodep[i]->back->index - 1]) b->nodep[i]->back = b->nodep[a->nodep[i]->back->index - 1]; else if (a->nodep[i]->back == a->nodep[a->nodep[i]->back->index - 1]->next) b->nodep[i]->back = b->nodep[a->nodep[i]->back->index - 1]->next; else b->nodep[i]->back = b->nodep[a->nodep[i]->back->index - 1]->next->next; } else b->nodep[i]->back = NULL; } for (i = spp; i < nonodes; i++) { p = a->nodep[i]; q = b->nodep[i]; for (j = 1; j <= 3; j++) { prot_copynode(p, q, categs); if (p->back) { if (p->back == a->nodep[p->back->index - 1]) q->back = b->nodep[p->back->index - 1]; else if (p->back == a->nodep[p->back->index - 1]->next) q->back = b->nodep[p->back->index - 1]->next; else q->back = b->nodep[p->back->index - 1]->next->next; } else q->back = NULL; p = p->next; q = q->next; } } b->likelihood = a->likelihood; b->start = a->start; /* start used in dnaml only */ b->root = a->root; /* root used in dnamlk only */} /* promlcopy */void proml_re_move(node **p, node **q){ /* remove p and record in q where it was */ long i; /** assumes bifurcations */ *q = (*p)->next->back; hookup(*q, (*p)->next->next->back);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -