📄 treesub.c
字号:
if (1-fd/b<=0) return (fd);
if (alpha<=0) return (-b*log (1-fd/b));
else return (-b*gammap(1-fd/b,alpha));
case (K80) :
a1=1-2*(P1+P2)-Q; b=1-2*Q;
/* if (a1<=0 || b<=0) return (-1); */
if (a1<=0 || b<=0) return (fd);
if (alpha<=0) { a1=-log(a1); b=-log(b); }
else { a1=-gammap(a1,alpha); b=-gammap(b,alpha); }
a1=.5*a1-.25*b; b=.25*b;
if(b>small) *kappa = a1/b; else *kappa=largek;
/*
fprintf (frst, "%9.3e %9.3e %9.4f", P1+P2, Q, (P1+P2)/Q);
*/
return (a1+2*b);
case (F84):
a1=(2*(tc+ag)+2*(tc*R/Y+ag*Y/R)*(1-Q/(2*Y*R)) -P1-P2) / (2*tc/Y+2*ag/R);
b = 1 - Q/(2*Y*R);
/* if (a1<=0 || b<=0) return (-1); */
if (a1<=0 || b<=0) return (fd);
if (alpha<=0) { a1=-log(a1); b=-log(b); }
else { a1=-gammap(a1,alpha); b=-gammap(b,alpha); }
a1=.5*a1; b=.5*b;
*kappa = a1/b-1;
/* *kappa = min2(*kappa, largek); */ *kappa = max2(*kappa, -.5);
return 4*b*(tc*(1+ *kappa/Y)+ag*(1+ *kappa/R)+Y*R);
case (TN93): /* TN93 */
a1=1-Y*P1/(2*tc)-Q/(2*Y); a2=1-R*P2/(2*ag)-Q/(2*R); b=1-Q/(2*Y*R);
/* if (a1<=0 || a2<=0 || b<=0) return (-1); */
if (a1<=0 || a2<=0 || b<=0) return (fd);
if (alpha<=0) { a1=-log(a1); a2=-log(a2); b=-log(b); }
else { a1=-gammap(a1,alpha); a2=-gammap(a2,alpha); b=-gammap(b,alpha);}
a1=.5/Y*(a1-R*b); a2=.5/R*(a2-Y*b); b=.5*b;
*kappa = largek;
if (b>0) *kappa = min2((a1+a2)/2/b, largek);
return 4*p[0]*p[1]*a1 + 4*p[2]*p[3]*a2 + 4*Y*R*b;
case (T92):
*kappa = largek;
GC=p[1]+p[3];
a1 = 1 - Q - (P1+P2)/(2*GC*(1-GC)); b=1-2*Q;
if (a1<=0 || b<=0) return (fd);
if (alpha<=0) { a1=-log(a1); b=-log(b); }
else { a1=-gammap(a1,alpha); b=-gammap(b,alpha);}
if(Q>0) *kappa = 2*a1/b-1;
return 2*GC*(1-GC)*a1 + (1-2*GC*(1-GC))/2*b;
}
return (-1);
}
#ifdef LSDISTANCE
#ifdef REALSEQUENCE
extern double *SeqDistance;
int DistanceMatNuc (FILE *fout, FILE*f2base, int model, double alpha)
{
/* This calculates pairwise distances. The data may be clean and coded
(com.cleandata==1) or not.
In the latter case, ambiguity sites are not used (pairwise deletion).
Site patterns are used.
*/
char *models[]={"JC69", "K80", "F81", "F84", "TN93", "T92", "TN93"};
int is,js,k1,k2, h, miss=0, status=0, nc=4;
double x[16], kappat=0, t,bigD=5;
fprintf(f2base,"%6d\n", com.ns);
if (model==HKY85 || model>=REV) model=TN93; /* TN93 here */
if (fout) {
fprintf(fout,"\nDistances:%5s", models[model]);
if (model!=JC69 && model!=F81) fprintf (fout, " (kappa) ");
fprintf(fout," (alpha set at %.2f)\n", alpha);
fprintf(fout,"\nThis matrix is not used in later m.l. analysis.\n");
if(!com.cleandata) fputs("\n(Pairwise deletion.)",fout);
}
for (is=0; is<com.ns; is++) {
if (fout)
if(com.readfpatt) fprintf(fout,"\n#%-10d ", is+1);
else fprintf(fout,"\n%-15s ", com.spname[is]);
if(f2base) fprintf(f2base,"%-15s ", com.spname[is]);
FOR (js, is) {
if(com.cleandata)
for (h=0,zero(x,16); h<com.npatt; h++)
x[com.z[is][h]*nc+com.z[js][h]] += com.fpatt[h];
else
for (h=0,zero(x,16); h<com.npatt; h++) {
for(k1=0;k1<nc;k1++) if(BASEs[k1]==com.z[is][h]) break;
for(k2=0;k2<nc;k2++) if(BASEs[k2]==com.z[js][h]) break;
if(k1<nc && k2<nc) x[k1*nc+k2] += com.fpatt[h];
else miss=1;
}
abyx(1./sum(x,16),x,16);
if ((t=SeqDivergence(x, model, alpha, &kappat)) < 0)
{ t=-1; status=-1; }
SeqDistance[is*(is-1)/2+js] = (t>=0?t:bigD);
if(f2base) fprintf(f2base," %7.4f", t);
if (fout) fprintf(fout,"%8.4f", t);
if (fout && (model==K80 || model==F84 || model==T92 || model==TN93))
fprintf(fout,"(%7.4f)", kappat);
/*
fprintf(frst,"%5d%5d %8.6f\n", is+1,js+1, t);
*/
}
if(f2base) FPN(f2base);
}
/*
fflush(frst);
*/
FPN(fout);
if(status) puts("\ndistance formula sometimes inapplicable..");
/*
fprintf(frst, " %-15s %5d", com.spname[0], com.ls);
FOR(h,6) fprintf(frst,"%10.5f", SeqDistance[h]);
fprintf(frst," %10.5f", (SeqDistance[3]+SeqDistance[4]+SeqDistance[5])/3);
*/
return(status);
}
#endif
#endif
#ifdef BASEMLG
extern int CijkIs0[];
#endif
extern int nR;
extern double Cijk[], Root[];
int RootTN93 (int model, double kappa1, double kappa2, double pi[],
double *f, double Root[])
{
double T=pi[0],C=pi[1],A=pi[2],G=pi[3],Y=T+C,R=A+G;
if (model==F84) { kappa2=1+kappa1/R; kappa1=1+kappa1/Y; }
*f=1/(2*T*C*kappa1+2*A*G*kappa2 + 2*Y*R);
Root[0] = 0;
Root[1] = - (*f);
Root[2] = -(Y+R*kappa2) * (*f);
Root[3] = -(Y*kappa1+R) * (*f);
return (0);
}
int EigenTN93 (int model, double kappa1, double kappa2, double pi[],
int *nR, double Root[], double Cijk[])
{
/* initialize Cijk[] & Root[], which are the only part to be changed
for a new substitution model
for JC69, K80, F81, F84, HKY85, TN93
Root: real Root divided by v, the number of nucleotide substitutions.
*/
int i,j,k, nr;
double f, U[16],V[16], t;
double T=pi[0],C=pi[1],A=pi[2],G=pi[3],Y=T+C,R=A+G;
if (model==JC69 || model==F81) kappa1=kappa2=com.kappa=1;
else if (com.model<TN93) kappa2=kappa1;
RootTN93 (model, kappa1, kappa2, pi, &f, Root);
*nR=nr = 2+(model==K80||model>=F84)+(model>=HKY85);
U[0*4+0]=U[1*4+0]=U[2*4+0]=U[3*4+0]=1;
U[0*4+1]=U[1*4+1]=1/Y; U[2*4+1]=U[3*4+1]=-1/R;
U[0*4+2]=U[1*4+2]=0; U[2*4+2]=G/R; U[3*4+2]=-A/R;
U[2*4+3]=U[3*4+3]=0; U[0*4+3]=C/Y; U[1*4+3]=-T/Y;
xtoy (pi, V, 4);
V[1*4+0]=R*T; V[1*4+1]=R*C;
V[1*4+2]=-Y*A; V[1*4+3]=-Y*G;
V[2*4+0]=V[2*4+1]=0; V[2*4+2]=1; V[2*4+3]=-1;
V[3*4+0]=1; V[3*4+1]=-1; V[3*4+2]=V[3*4+3]=0;
FOR (i,4) FOR (j,4) {
Cijk[i*4*nr+j*nr+0]=U[i*4+0]*V[0*4+j];
switch (model) {
case JC69:
case F81:
for (k=1,t=0; k<4; k++) t += U[i*4+k]*V[k*4+j];
Cijk[i*4*nr+j*nr+1] = t;
break;
case K80:
case F84:
Cijk[i*4*nr+j*nr+1]=U[i*4+1]*V[1*4+j];
for (k=2,t=0; k<4; k++) t += U[i*4+k]*V[k*4+j];
Cijk[i*4*nr+j*nr+2]=t;
break;
case HKY85: case T92: case TN93:
for (k=1; k<4; k++) Cijk[i*4*nr+j*nr+k] = U[i*4+k]*V[k*4+j];
break;
default:
error2("model in EigenTN93");
}
}
#ifdef BASEMLG
FOR (i,64) CijkIs0[i] = (Cijk[i]==0);
#endif
return(0);
}
#ifdef EIGEN
int EigenQREVbase (FILE* fout, double kappa[],
double pi[], double pi_sqrt[], int npi0,
int *nR, double Root[], double Cijk[])
{
/* pi[] is constant
*/
int i,j,k;
double Q[16], U[16], V[16], mr;
NPMatUVRoot=0;
*nR=4;
zero (Q, 16);
if(com.model==REV) {
for(i=0,k=0,Q[3*4+2]=Q[2*4+3]=1; i<3; i++) for (j=i+1; j<4; j++)
if(i*4+j!=11) Q[i*4+j]=Q[j*4+i]=kappa[k++];
}
else /* (model==REVu) */
FOR(i,3) for(j=i+1; j<4; j++)
Q[i*4+j]=Q[j*4+i] = (StepMatrix[i*4+j] ? kappa[StepMatrix[i*4+j]-1] : 1);
FOR(i,4) FOR(j,4) Q[i*4+j] *= pi[j];
for (i=0,mr=0; i<4; i++)
{ Q[i*4+i]=0; Q[i*4+i]=-sum(Q+i*4, 4); mr-=pi[i]*Q[i*4+i]; }
abyx (1/mr, Q, 16);
if (fout) {
mr=2*(pi[0]*Q[0*4+1]+pi[2]*Q[2*4+3]);
fprintf(fout, "Rate parameters: ");
FOR(j,5) fprintf(fout, " %8.5f", kappa[j]);
fprintf(fout, "\nBase frequencies: ");
FOR(j,4) fprintf(fout," %8.5f", pi[j]);
fprintf (fout, "\nRate matrix Q, Average Ts/Tv =%9.4f", mr/(1-mr));
matout (fout, Q, 4,4);
}
else {
eigenQREV(Q, pi, pi_sqrt, 4, npi0, Root, U, V);
FOR (i,4) FOR(j,4) FOR(k,4) Cijk[i*4*4+j*4+k] = U[i*4+k]*V[k*4+j];
}
return (0);
}
int EigenQunrest(FILE *fout, double kappa[], double pi[],
int *nR, complex cRoot[], complex cU[], complex cV[])
{
/* pi[] is changed
*/
int i,j,k;
double Q0[16], Q[16], U[16], V[16], T1[16], T2[16], mr;
NPMatUVRoot=0;
*nR=4;
if(com.model==UNREST) {
for (i=0,k=0,Q[14]=1; i<4; i++) FOR(j,4)
if (i!=j && i*4+j != 14) Q[i*4+j]=kappa[k++];
}
else /* (model==UNRESTu) */
FOR(i,4) FOR(j,4)
if(i!=j)
Q[i*4+j] = (StepMatrix[i*4+j] ? kappa[StepMatrix[i*4+j]-1] : 1);
FOR(i,4) { Q[i*4+i]=0; Q[i*4+i]=-sum(Q+i*4, 4); }
xtoy(Q,Q0,16);
i = eigen (1, Q, 4, Root, T1, U, V, T2) ;
FOR (i, 4) { cRoot[i].re=Root[i], cRoot[i].im=T1[i]; }
FOR (i, 16) { cU[i].re=cV[i].re=U[i]; cU[i].im=cV[i].im=V[i]; }
cmatinv (cV, 4, 4, T1);
FOR (i, 4) pi[i]=cV[0*4+i].re;
abyx (1/sum(pi,4), pi, 4);
for (i=0,mr=0; i<4; i++) mr -= pi[i]*Q0[i*4+i];
FOR (i,4) { cRoot[i].re /= mr; cRoot[i].im /= mr; }
if (fout) {
abyx (1/mr, Q0, 16);
mr=pi[0]*Q0[0*4+1]+pi[1]*Q0[1*4+0]+pi[2]*Q0[2*4+3]+pi[3]*Q0[3*4+2];
fprintf(fout, "Rate parameters: ");
FOR(j,11) fprintf(fout, " %8.5f", kappa[j]);
fprintf(fout, "\nBase frequencies: ");
FOR(j,4) fprintf(fout," %8.5f", pi[j]);
fprintf (fout,"\nrate matrix Q, Average Ts/Tv (similar to kappa/2) =%9.4f",mr/(1-mr));
matout (fout, Q0, 4, 4);
}
return (0);
}
int cPMat (double P[],double t,int n,complex cU[],complex cV[],complex cRoot[])
{
/* P(t) = cU * exp{cRoot*t} * cV
*/
int i,j,k, status=0;
complex cUd[NCODE*NCODE], cP, cY;
double sum;
if (t<1e-6) { identity (P, n); return(0); }
FOR (i,n) cUd[i*n+0]=cU[i*n+0];
for (j=1; j<n; j++) {
cY.re=cRoot[j].re*t; cY.im=cRoot[j].im*t; cY=cexp(cY);
for (i=0; i<n; i++) cUd[i*n+j]=cby(cU[i*n+j],cY);
}
FOR (i,n) {
for (j=0,sum=0; j<n; j++) {
for (k=0,cP=compl(0,0); k<n; k++) {
cY = cby(cUd[i*n+k],cV[k*n+j]);
cP.re+=cY.re; cP.im+=cY.im;
}
P[i*n+j]=cP.re;
sum+=P[i*n+j];
if (P[i*n+j]<=0 || fabs(cP.im)>1e-4) status=-1;
}
if (fabs(sum-1)>1e-4) status=-1;
}
if (status)
{ printf ("\nerr cPMat.."); matout (F0, P, n, n); getchar(); }
return (0);
}
#endif /* ifdef BASEML */
#endif /* if (NCODE==4) */
#ifdef LSDISTANCE
double *SeqDistance=NULL;
int *ancestor=NULL;
int SetAncestor()
{
/* This finds the most recent common ancestor of species is and js.
*/
int is, js, it, a1, a2;
FOR(is,com.ns) FOR(js,is) {
it=is*(is-1)/2+js;
ancestor[it]=-1;
for (a1=is; a1!=-1; a1=nodes[a1].father) {
for (a2=js; a2!=-1; a2=nodes[a2].father)
if (a1==a2) { ancestor[it]=a1; break; }
if (ancestor[it] != -1) break;
}
if (ancestor[it] == -1) error2("no ancestor");
}
return(0);
}
int fun_LS (double x[], double diff[], int np, int npair);
int fun_LS (double x[], double diff[], int np, int npair)
{
int i,j, aa, it=-np;
double dexp;
if (SetBranch(x) && noisy>2) puts ("branch len.");
if (npair != com.ns*(com.ns-1)/2) error2("# seq pairs err.");
FOR(i,com.ns) FOR(j, i) {
it=i*(i-1)/2+j;
for (aa=i,dexp=0; aa!=ancestor[it]; aa=nodes[aa].father)
dexp += nodes[aa].branch;
for (aa=j; aa!=ancestor[it]; aa=nodes[aa].father)
dexp += nodes[aa].branch;
diff[it]=SeqDistance[it]-dexp;
}
return(0);
}
int LSDistance (double *ss,double x[],int (*testx)(double x[],int np))
{
/* get Least Squares estimates of branch lengths for a given tree topology
*/
int i;
if ((*testx)(x, com.ntime)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -