📄 trees.c
字号:
}
tvalid[loop_limit].next = NULL;
/*
* IMPROVEMENT 1, STEP 3 : Calculate the sum of score value that
* is sequence[i] to others.
*/
sumd = 0.0;
for (lpj=tvalid[0].next ; lpj!=NULL ; lpj = lpj->next) {
double tmp_sum = 0.0;
j = lpj->n;
/* calculate sum_rows[j] */
for (lpi=tvalid[0].next ; lpi->n < j ; lpi = lpi->next) {
i = lpi->n;
tmp_sum += tmat[i][j];
/* tmat[j][i] = tmat[i][j]; */
}
sum_rows[j] = tmp_sum;
tmp_sum = 0.0;
/* Set lpi to that lpi->n is greater than j */
if ((lpi != NULL) && (lpi->n == j)) {
lpi = lpi->next;
}
/* calculate sum_cols[j] */
for( ; lpi!=NULL ; lpi = lpi->next) {
i = lpi->n;
tmp_sum += tmat[j][i];
/* tmat[i][j] = tmat[j][i]; */
}
sum_cols[j] = tmp_sum;
}
/*********************** Enter The Main Cycle ***************************/
for(nc=1, loop_limit = (last_seq-first_seq+1-3); nc<=loop_limit; ++nc) {
sumd = 0.0;
/* IMPROVEMENT 1, STEP 4 : use sum value */
for(lpj=tvalid[0].next ; lpj!=NULL ; lpj = lpj->next) {
sumd += sum_cols[lpj->n];
}
/* IMPROVEMENT 3, STEP 0 : multiply tmin and 2*fnseqs2 */
fnseqs2 = fnseqs - 2.0; /* Set fnseqs2 at this point. */
tmin = 99999.0 * 2.0 * fnseqs2;
/*.................compute SMATij values and find the smallest one ........*/
mini = minj = 0;
/* jj must starts at least 2 */
if ((tvalid[0].next != NULL) && (tvalid[0].next->n == 1)) {
lpjj = tvalid[0].next->next;
} else {
lpjj = tvalid[0].next;
}
for( ; lpjj != NULL; lpjj = lpjj->next) {
jj = lpjj->n;
for(lpii=tvalid[0].next ; lpii->n < jj ; lpii = lpii->next) {
ii = lpii->n;
diq = djq = 0.0;
/* IMPROVEMENT 1, STEP 4 : use sum value */
diq = sum_cols[ii] + sum_rows[ii];
djq = sum_cols[jj] + sum_rows[jj];
/*
* always ii < jj in this point. Use upper
* triangle of score matrix.
*/
dij = tmat[ii][jj];
/*
* IMPROVEMENT 3, STEP 1 : fnseqs2 is
* already calculated.
*/
/* fnseqs2 = fnseqs - 2.0 */
/* IMPROVEMENT 4 : transform the equation */
/*-------------------------------------------------------------------*
* OPTIMIZE of expression 'total = d2r + fnseqs2*dij + dr*2.0' *
* total = d2r + fnseq2*dij + 2.0*dr *
* = d2r + fnseq2*dij + 2(sumd - dij - d2r) *
* = d2r + fnseq2*dij + 2*sumd - 2*dij - 2*d2r *
* = fnseq2*dij + 2*sumd - 2*dij - 2*d2r + d2r *
* = fnseq2*dij + 2*sumd - 2*dij - d2r *
* = fnseq2*dij + 2*sumd - 2*dij - (diq + djq - 2*dij) *
* = fnseq2*dij + 2*sumd - 2*dij - diq - djq + 2*dij *
* = fnseq2*dij + 2*sumd - 2*dij + 2*dij - diq - djq *
* = fnseq2*dij + 2*sumd - diq - djq *
*-------------------------------------------------------------------*/
total = fnseqs2*dij + 2.0*sumd - diq - djq;
/*
* IMPROVEMENT 3, STEP 2 : abbrevlate
* the division on comparison between
* total and tmin.
*/
/* total = total / (2.0*fnseqs2); */
if(total < tmin) {
tmin = total;
mini = ii;
minj = jj;
}
}
}
/* MEMO: always ii < jj in avobe loop, so mini < minj */
/*.................compute branch lengths and print the results ........*/
dio = djo = 0.0;
/* IMPROVEMENT 1, STEP 4 : use sum value */
dio = sum_cols[mini] + sum_rows[mini];
djo = sum_cols[minj] + sum_rows[minj];
dmin = tmat[mini][minj];
dio = (dio - dmin) / fnseqs2;
djo = (djo - dmin) / fnseqs2;
bi = (dmin + dio - djo) * 0.5;
bj = dmin - bi;
bi = bi - av[mini];
bj = bj - av[minj];
if( av[mini] > 0.0 )
typei = 0;
else
typei = 1;
if( av[minj] > 0.0 )
typej = 0;
else
typej = 1;
if(verbose)
fprintf(tree,"\n Cycle%4d = ",(pint)nc);
/*
set negative branch lengths to zero. Also set any tiny positive
branch lengths to zero.
*/ if( fabs(bi) < 0.0001) bi = 0.0;
if( fabs(bj) < 0.0001) bj = 0.0;
if(verbose) {
if(typei == 0)
fprintf(tree,"Node:%4d (%9.5f) joins ",(pint)mini,bi);
else
fprintf(tree," SEQ:%4d (%9.5f) joins ",(pint)mini,bi);
if(typej == 0)
fprintf(tree,"Node:%4d (%9.5f)",(pint)minj,bj);
else
fprintf(tree," SEQ:%4d (%9.5f)",(pint)minj,bj);
fprintf(tree,"\n");
}
left_branch[nc] = bi;
right_branch[nc] = bj;
for(i=1; i<=last_seq-first_seq+1; i++)
tree_description[nc][i] = 0;
if(typei == 0) {
for(i=nc-1; i>=1; i--)
if(tree_description[i][mini] == 1) {
for(j=1; j<=last_seq-first_seq+1; j++)
if(tree_description[i][j] == 1)
tree_description[nc][j] = 1;
break;
}
}
else
tree_description[nc][mini] = 1;
if(typej == 0) {
for(i=nc-1; i>=1; i--)
if(tree_description[i][minj] == 1) {
for(j=1; j<=last_seq-first_seq+1; j++)
if(tree_description[i][j] == 1)
tree_description[nc][j] = 1;
break;
}
}
else
tree_description[nc][minj] = 1;
/*
Here is where the -0.00005 branch lengths come from for 3 or more
identical seqs.
*/
/* if(dmin <= 0.0) dmin = 0.0001; */
if(dmin <= 0.0) dmin = 0.000001;
av[mini] = dmin * 0.5;
/*........................Re-initialisation................................*/
fnseqs = fnseqs - 1.0;
tkill[minj] = 1;
/* IMPROVEMENT 2, STEP 3 : Remove tvalid[minj] from chain list. */
/* [ Before ]
* +---------+ +---------+ +---------+
* |prev |<-------|prev |<-------|prev |<---
* | n | | n(=minj)| | n |
* | next|------->| next|------->| next|----
* +---------+ +---------+ +---------+
*
* [ After ]
* +---------+ +---------+
* |prev |<--------------------------|prev |<---
* | n | | n |
* | next|-------------------------->| next|----
* +---------+ +---------+
* +---------+
* NULL---|prev |
* | n(=minj)|
* | next|---NULL
* +---------+
*/
(tvalid[minj].prev)->next = tvalid[minj].next;
if (tvalid[minj].next != NULL) {
(tvalid[minj].next)->prev = tvalid[minj].prev;
}
tvalid[minj].prev = tvalid[minj].next = NULL;
/* IMPROVEMENT 1, STEP 5 : re-calculate sum values. */
for(lpj=tvalid[0].next ; lpj != NULL ; lpj = lpj->next) {
double tmp_di = 0.0;
double tmp_dj = 0.0;
j = lpj->n;
/*
* subtrace a score value related with 'minj' from
* sum arrays .
*/
if (j < minj) {
tmp_dj = tmat[j][minj];
sum_cols[j] -= tmp_dj;
} else if (j > minj) {
tmp_dj = tmat[minj][j];
sum_rows[j] -= tmp_dj;
} /* nothing to do when j is equal to minj. */
/*
* subtrace a score value related with 'mini' from
* sum arrays .
*/
if (j < mini) {
tmp_di = tmat[j][mini];
sum_cols[j] -= tmp_di;
} else if (j > mini) {
tmp_di = tmat[mini][j];
sum_rows[j] -= tmp_di;
} /* nothing to do when j is equal to mini. */
/*
* calculate a score value of the new inner node.
* then, store it temporary to join[] array.
*/
join[j] = (tmp_dj + tmp_di) * 0.5;
}
/*
* 1)
* Set the score values (stored in join[]) into the matrix,
* row/column position is 'mini'.
* 2)
* Add a score value of the new inner node to sum arrays.
*/
for(lpj=tvalid[0].next ; lpj != NULL; lpj = lpj->next) {
j = lpj->n;
if (j < mini) {
tmat[j][mini] = join[j];
sum_cols[j] += join[j];
} else if (j > mini) {
tmat[mini][j] = join[j];
sum_rows[j] += join[j];
} /* nothing to do when j is equal to mini. */
}
/* Re-calculate sum_rows[mini],sum_cols[mini]. */
sum_cols[mini] = sum_rows[mini] = 0.0;
/* calculate sum_rows[mini] */
da = 0.0;
for(lpj=tvalid[0].next ; lpj->n < mini ; lpj = lpj->next) {
da += join[lpj->n];
}
sum_rows[mini] = da;
/* skip if 'lpj->n' is equal to 'mini' */
if ((lpj != NULL) && (lpj->n == mini)) {
lpj = lpj->next;
}
/* calculate sum_cols[mini] */
da = 0.0;
for( ; lpj != NULL; lpj = lpj->next) {
da += join[lpj->n];
}
sum_cols[mini] = da;
/*
* Clean up sum_rows[minj], sum_cols[minj] and score matrix
* related with 'minj'.
*/
sum_cols[minj] = sum_rows[minj] = 0.0;
for(j=1; j<=last_seq-first_seq+1; ++j)
tmat[minj][j] = tmat[j][minj] = join[j] = 0.0;
/****/ } /**end main cycle**/
/******************************Last Cycle (3 Seqs. left)********************/
nude = 1;
for(lpi=tvalid[0].next; lpi != NULL; lpi = lpi->next) {
l[nude] = lpi->n;
++nude;
}
b1 = (tmat[l[1]][l[2]] + tmat[l[1]][l[3]] - tmat[l[2]][l[3]]) * 0.5;
b2 = tmat[l[1]][l[2]] - b1;
b3 = tmat[l[1]][l[3]] - b1;
branch[1] = b1 - av[l[1]];
branch[2] = b2 - av[l[2]];
branch[3] = b3 - av[l[3]];
/* Reset tiny negative and positive branch lengths to zero */
if( fabs(branch[1]) < 0.0001) branch[1] = 0.0;
if( fabs(branch[2]) < 0.0001) branch[2] = 0.0;
if( fabs(branch[3]) < 0.0001) branch[3] = 0.0;
left_branch[last_seq-first_seq+1-2] = branch[1];
left_branch[last_seq-first_seq+1-1] = branch[2];
left_branch[last_seq-first_seq+1] = branch[3];
for(i=1; i<=last_seq-first_seq+1; i++)
tree_description[last_seq-first_seq+1-2][i] = 0;
if(verbose)
fprintf(tree,"\n Cycle%4d (Last cycle, trichotomy):\n",(pint)nc);
for(i=1; i<=3; ++i) {
if( av[l[i]] > 0.0) {
if(verbose)
fprintf(tree,"\n\t\t Node:%4d (%9.5f) ",(pint)l[i],branch[i]);
for(k=last_seq-first_seq+1-3; k>=1; k--)
if(tree_description[k][l[i]] == 1) {
for(j=1; j<=last_seq-first_seq+1; j++)
if(tree_description[k][j] == 1)
tree_description[last_seq-first_seq+1-2][j] = i;
break;
}
}
else {
if(verbose)
fprintf(tree,"\n\t\t SEQ:%4d (%9.5f) ",(pint)l[i],branch[i]);
tree_description[last_seq-first_seq+1-2][l[i]] = i;
}
if(i < 3) {
if(verbose)
fprintf(tree,"joins");
}
}
if(verbose)
fprintf(tree,"\n");
/* IMPROVEMENT 1, STEP 6 : release memory area */
ckfree(sum_cols);
ckfree(sum_rows);
ckfree(join);
/* IMPROVEMENT 2, STEP 4 : release memory area */
ckfree(tvalid);
}
#endif /* ORIGINAL_NJ_TREE */
void bootstrap_tree(char *phylip_name,char *clustal_name, char *nexus_name)
{
sint i,j;
int ranno;
char path[MAXLINE+1];
char dummy[10];
char err_mess[1024];
static char **sample_tree;
static char **standard_tree;
static char **save_tree;
sint total_dists, overspill = 0, total_overspill = 0;
sint nfails = 0;
if(empty) {
error("You must load an alignment first");
return;
}
if(nseqs<4) {
error("Alignment has only %d sequences",nseqs);
return;
}
if(!output_tree_clustal && !output_tree_phylip && !output_tree_nexus) {
error("You must select either clustal or phylip or nexus tree output format");
return;
}
get_path(seqname, path);
if (output_tree_clustal) {
if (clustal_name[0]!=EOS) {
if((clustal_phy_tree_file = open_explicit_file(
clustal_name))==NULL) return;
}
else {
if((clustal_phy_tree_file = open_output_file(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -