/* Returns the median score of a potenial median with respect to three specified "vertex" genomes. "gens" is assumed to be an array of at least three pointers to genome_structs, and all genomes are assumed to be of size "ngenes". Currently, a circular measure is always used. */ int median_score ( struct genome_struct **gens, struct genome_struct *median, int ngenes, distmem_t * distmem ) { return ( invdist_noncircular ( median, gens[0], 0, ngenes, distmem ) + invdist_noncircular ( median, gens[1], 0, ngenes, distmem ) + invdist_noncircular ( median, gens[2], 0, ngenes, distmem ) ); }
/* unichromosomal reversal distance, linear Uses same parameter list as function of same name in GRAPPA _v versions: graphstats return structure included (used to be "verbose option is included") */ int invdist_circular(struct genome_struct *g1, struct genome_struct *g2, int num_genes, distmem_t *distmem) { int offset; offset = calculate_offset(g1, g2, num_genes); return invdist_noncircular(g1, g2, offset, num_genes, distmem); }
void calc_invmatrix(struct genome_struct *genomes, int num_genes, int num_genomes, distmem_t *distmem, int CIRCULAR) { int i, j; int dist; for (i=0 ; i<num_genomes ; i++) { for (j=i+1 ; j<num_genomes ; j++) { if (CIRCULAR) dist = invdist_circular(genomes+i, genomes+j, num_genes, distmem); else dist = invdist_noncircular(genomes+i, genomes+j, 0, num_genes, distmem); } } return (void) dist; }
int invdist_noncircular_nomem(struct genome_struct *g1, struct genome_struct *g2, int offset, int num_genes) { distmem_t distmem; int dist; mcdist_allocmem(num_genes, 0, /* num_chromosomes */ &distmem); dist = invdist_noncircular(g1, g2, offset, num_genes, &distmem); mcdist_freemem(&distmem); return (dist); }
int uhc_dist( struct uhc_mem *uhcmem, int i1, int i2, int num_genes, int num_chromosomes, int circular) { int d; struct genome_struct *g1, *g2; /* some of the distance routines modify the gene data, so we must * work on copies */ if (num_chromosomes == 0) { /* unichromosomal does not modify the input genomes */ g1 = &uhcmem->genome_list[i1]; g2 = &uhcmem->genome_list[i2]; } else { /* multichromosomal does modify the genomes */ g1 = uhcmem->g1; g2 = uhcmem->g2; copy_genes(uhcmem->genome_list[i1].genes, g1->genes, num_genes); copy_genes(uhcmem->genome_list[i2].genes, g2->genes, num_genes); } if (num_chromosomes == 0) { if (circular) { /* unichromosomal circular */ d = invdist_circular(g1, g2, num_genes, uhcmem->distmem); } else { /* unichromosomal linear */ d = invdist_noncircular(g1, g2, 0, num_genes, uhcmem->distmem); } } else { /* multichromosomal */ d = mcdist_noncircular(g1, g2, num_genes, num_chromosomes, uhcmem->distmem, (graphstats_t *) NULL); } return d; }
void setinvmatrix(int **distmatrix,struct genome_struct *genomes, int num_genes,int num_genomes,distmem_t *distmem, int CIRCULAR) { int i, j; for (i=0 ; i<num_genomes ; i++) { distmatrix[i][i] = 0; for (j=i+1 ; j<num_genomes ; j++) { if (CIRCULAR) distmatrix[i][j] = distmatrix[j][i] = invdist_circular(genomes+i,genomes+j,num_genes,distmem); else distmatrix[i][j] = distmatrix[j][i] = invdist_noncircular(genomes+i,genomes+j,0,num_genes,distmem); } } return; }
double neighborj_SK_tree ( struct genome_struct *genomes, int num_genes, int num_genomes, distmem_t * distmem, int CIRCULAR, char *constTree ) { int i, j; double NJtreescore; int num_clusters; double **D, Dij; double *r; int *valid; double Sij, minSij; int mini, minj; char **branch; char *tmpbranch; int maxConstSize; D = ( double ** ) malloc ( num_genomes * sizeof ( double * ) ); if ( D == ( double ** ) NULL ) fprintf ( stderr, "ERROR: D NULL\n" ); for ( i = 0; i < num_genomes; i++ ) { D[i] = ( double * ) malloc ( num_genomes * sizeof ( double ) ); if ( D[i] == ( double * ) NULL ) fprintf ( stderr, "ERROR: D[i] NULL\n" ); } r = ( double * ) malloc ( num_genomes * sizeof ( double ) ); if ( r == ( double * ) NULL ) fprintf ( stderr, "ERROR: r NULL\n" ); valid = ( int * ) malloc ( num_genomes * sizeof ( int ) ); if ( valid == ( int * ) NULL ) fprintf ( stderr, "ERROR: valid NULL\n" ); branch = ( char ** ) malloc ( num_genomes * sizeof ( char * ) ); if ( branch == ( char ** ) NULL ) fprintf ( stderr, "ERROR: branch NULL\n" ); maxConstSize = ( ( int ) ceil ( log10 ( ( double ) num_genomes ) ) + 4 ) * num_genomes + 1; for ( i = 0; i < num_genomes; i++ ) { branch[i] = ( char * ) malloc ( maxConstSize * sizeof ( char ) ); if ( branch[i] == ( char * ) NULL ) fprintf ( stderr, "ERROR: branch[i] NULL\n" ); sprintf ( branch[i], "%d", i + 1 ); } tmpbranch = ( char * ) malloc ( maxConstSize * sizeof ( char ) ); if ( tmpbranch == ( char * ) NULL ) fprintf ( stderr, "ERROR: tmpbranch NULL\n" ); NJtreescore = 0; for ( i = 0; i < num_genomes; i++ ) valid[i] = TRUE; for ( i = 0; i < num_genomes; i++ ) { for ( j = i + 1; j < num_genomes; j++ ) { if ( CIRCULAR ) D[i][j] = ( double ) invdist_circular ( genomes + i, genomes + j, num_genes, distmem ); else D[i][j] = ( double ) invdist_noncircular ( genomes + i, genomes + j, 0, num_genes, distmem ); } } num_clusters = num_genomes; while ( num_clusters > 2 ) { for ( i = 0; i < num_genomes; i++ ) { if ( valid[i] ) { r[i] = 0.0; for ( j = 0; j < num_genomes; j++ ) if ( ( valid[j] ) && ( i != j ) ) { if ( i < j ) r[i] += D[i][j]; else r[i] += D[j][i]; } r[i] /= ( ( double ) num_clusters - 2.0 ); } } minSij = DBL_INF; mini = -1; minj = -1; for ( i = 0; i < num_genomes; i++ ) { if ( valid[i] ) { for ( j = i + 1; j < num_genomes; j++ ) { if ( valid[j] ) { Sij = D[i][j] - ( r[i] + r[j] ); #ifdef DEBUG fprintf ( outfile, "S[%3d][%3d]: %5.2f\n", i, j, Sij ); #endif if ( Sij < minSij ) { minSij = Sij; mini = i; minj = j; } } } } } if ( minSij == DBL_INF ) fprintf ( stderr, "ERROR: minSij Infinite\n" ); if ( ( mini == -1 ) || ( minj == -1 ) ) fprintf ( stderr, "ERROR: mini or minj not set\n" ); if ( ( valid[mini] == FALSE ) || ( valid[minj] == FALSE ) ) fprintf ( stderr, "ERROR: i or j cannot join\n" ); strcpy ( tmpbranch, branch[mini] ); sprintf ( branch[mini], "(%s,%s)", tmpbranch, branch[minj] ); valid[minj] = FALSE; Dij = D[mini][minj]; for ( j = 0; j < mini; j++ ) { if ( valid[j] ) { if ( minj < j ) D[j][mini] = 0.5 * ( D[j][mini] + D[minj][j] - Dij ); else D[j][mini] = 0.5 * ( D[j][mini] + D[j][minj] - Dij ); } } for ( j = mini + 1; j < num_genomes; j++ ) { if ( valid[j] ) { if ( minj < j ) D[mini][j] = 0.5 * ( D[mini][j] + D[minj][j] - Dij ); else D[mini][j] = 0.5 * ( D[mini][j] + D[j][minj] - Dij ); } } NJtreescore += Dij; num_clusters--; } /* Must add last edge */ mini = minj = -1; for ( i = 0; i < num_genomes; i++ ) if ( valid[i] ) { if ( mini < 0 ) mini = i; else minj = i; } if ( ( mini < 0 ) || ( minj < 0 ) || ( mini >= minj ) ) fprintf ( stderr, "ERROR: cannot join last two neighbors\n" ); NJtreescore += D[mini][minj]; sprintf ( constTree, "(%s,%s)", branch[mini], branch[minj] ); free ( tmpbranch ); for ( i = 0; i < num_genomes; i++ ) free ( branch[i] ); free ( branch ); free ( valid ); free ( r ); for ( i = 0; i < num_genomes; i++ ) free ( D[i] ); free ( D ); return NJtreescore; }
double neighborj_SK ( struct genome_struct *genomes, int num_genes, int num_genomes, distmem_t * distmem, int CIRCULAR, int verbose ) { int i, j; double NJtreescore; int num_clusters; double **D, Dij; double *r; int *valid; double Sij, minSij; int mini, minj; D = ( double ** ) malloc ( num_genomes * sizeof ( double * ) ); if ( D == ( double ** ) NULL ) fprintf ( stderr, "ERROR: D NULL\n" ); for ( i = 0; i < num_genomes; i++ ) { D[i] = ( double * ) malloc ( num_genomes * sizeof ( double ) ); if ( D[i] == ( double * ) NULL ) fprintf ( stderr, "ERROR: D[i] NULL\n" ); } r = ( double * ) malloc ( num_genomes * sizeof ( double ) ); if ( r == ( double * ) NULL ) fprintf ( stderr, "ERROR: r NULL\n" ); valid = ( int * ) malloc ( num_genomes * sizeof ( int ) ); if ( valid == ( int * ) NULL ) fprintf ( stderr, "ERROR: valid NULL\n" ); NJtreescore = 0.0; for ( i = 0; i < num_genomes; i++ ) valid[i] = TRUE; for ( i = 0; i < num_genomes; i++ ) { for ( j = i + 1; j < num_genomes; j++ ) { if ( CIRCULAR ) D[i][j] = ( double ) invdist_circular ( genomes + i, genomes + j, num_genes, distmem ); else D[i][j] = ( double ) invdist_noncircular ( genomes + i, genomes + j, 0, num_genes, distmem ); } } num_clusters = num_genomes; while ( num_clusters > 2 ) { for ( i = 0; i < num_genomes; i++ ) { if ( valid[i] ) { r[i] = 0.0; for ( j = 0; j < num_genomes; j++ ) if ( ( valid[j] ) && ( i != j ) ) { if ( i < j ) r[i] += D[i][j]; else r[i] += D[j][i]; } r[i] /= ( ( double ) num_clusters - 2.0 ); } } minSij = DBL_INF; mini = -1; minj = -1; for ( i = 0; i < num_genomes; i++ ) { if ( valid[i] ) { for ( j = i + 1; j < num_genomes; j++ ) { if ( valid[j] ) { Sij = D[i][j] - ( r[i] + r[j] ); #ifdef DEBUG fprintf ( outfile, "S[%3d][%3d]: %5.2f\n", i, j, Sij ); #endif if ( Sij < minSij ) { minSij = Sij; mini = i; minj = j; } } } } } if ( minSij == DBL_INF ) fprintf ( stderr, "ERROR: minSij Infinite\n" ); if ( ( mini == -1 ) || ( minj == -1 ) ) fprintf ( stderr, "ERROR: mini or minj not set\n" ); if ( ( valid[mini] == FALSE ) || ( valid[minj] == FALSE ) ) fprintf ( stderr, "ERROR: i or j cannot join\n" ); #ifdef VERYVERBOSE if ( verbose ) { fprintf ( outfile, "Studier-Keppler NJ:\t Step (%3d): ", num_genomes - num_clusters + 1 ); fprintf ( outfile, "Join %3d and %3d into %3d, edge weight= %5.2f\n", mini, minj, mini, D[mini][minj] ); } #endif valid[minj] = FALSE; Dij = D[mini][minj]; for ( j = 0; j < mini; j++ ) { if ( valid[j] ) { if ( minj < j ) D[j][mini] = 0.5 * ( D[j][mini] + D[minj][j] - Dij ); else D[j][mini] = 0.5 * ( D[j][mini] + D[j][minj] - Dij ); } } for ( j = mini + 1; j < num_genomes; j++ ) { if ( valid[j] ) { if ( minj < j ) D[mini][j] = 0.5 * ( D[mini][j] + D[minj][j] - Dij ); else D[mini][j] = 0.5 * ( D[mini][j] + D[j][minj] - Dij ); } } NJtreescore += Dij; num_clusters--; } /* Must add last edge */ mini = minj = -1; for ( i = 0; i < num_genomes; i++ ) if ( valid[i] ) { if ( mini < 0 ) mini = i; else minj = i; } if ( ( mini < 0 ) || ( minj < 0 ) || ( mini >= minj ) ) fprintf ( stderr, "ERROR: cannot join last two neighbors\n" ); #ifdef VERYVERBOSE if ( verbose ) { fprintf ( outfile, "Studier-Keppler NJ:\t Step (%3d): ", num_genomes - num_clusters + 1 ); fprintf ( outfile, "Join %3d and %3d into %3d, edge weight= %5.2f\n", mini, minj, mini, D[mini][minj] ); } #endif NJtreescore += D[mini][minj]; if ( verbose ) { fprintf ( outfile, "Studier-Keppler NJ\t Tree Score: %5.2f\n\n", NJtreescore ); fflush ( outfile ); } free ( valid ); free ( r ); for ( i = 0; i < num_genomes; i++ ) free ( D[i] ); free ( D ); return NJtreescore; }
double neighborj_SN ( struct genome_struct *genomes, int num_genes, int num_genomes, distmem_t * distmem, int CIRCULAR, int verbose ) { int i, j, k; double NJtreescore; int num_clusters; double **D; int *valid; double Dsum; double Sij, minSij; int mini, minj; D = ( double ** ) malloc ( num_genomes * sizeof ( double * ) ); if ( D == ( double ** ) NULL ) fprintf ( stderr, "ERROR: D NULL\n" ); for ( i = 0; i < num_genomes; i++ ) { D[i] = ( double * ) malloc ( num_genomes * sizeof ( double ) ); if ( D[i] == ( double * ) NULL ) fprintf ( stderr, "ERROR: D[i] NULL\n" ); } valid = ( int * ) malloc ( num_genomes * sizeof ( int ) ); if ( valid == ( int * ) NULL ) fprintf ( stderr, "ERROR: valid NULL\n" ); NJtreescore = 0.0; for ( i = 0; i < num_genomes; i++ ) valid[i] = TRUE; Dsum = 0.0; for ( i = 0; i < num_genomes; i++ ) { for ( j = i + 1; j < num_genomes; j++ ) { if ( CIRCULAR ) D[i][j] = ( double ) invdist_circular ( genomes + i, genomes + j, num_genes, distmem ); else D[i][j] = ( double ) invdist_noncircular ( genomes + i, genomes + j, 0, num_genes, distmem ); Dsum += D[i][j]; #ifdef DEBUG fprintf ( outfile, "SN D[%3d][%3d]: %5.2f (Dsum: %5.2f)\n", i, j, D[i][j], Dsum ); #endif } } num_clusters = num_genomes; while ( num_clusters > 2 ) { minSij = DBL_INF; mini = -1; minj = -1; for ( i = 0; i < num_genomes; i++ ) { if ( valid[i] ) { for ( j = i + 1; j < num_genomes; j++ ) { if ( valid[j] ) { Sij = 0.0; for ( k = 0; k < num_genomes; k++ ) { if ( ( k != i ) && ( k != j ) && valid[k] ) Sij += ( i < k ? D[i][k] : D[k][i] ) + ( j < k ? D[j][k] : D[k] [j] ); } Sij /= 2.0 * ( ( double ) num_clusters - 2.0 ); Sij += 0.5 * D[i][j]; Sij += ( 1.0 / ( ( double ) num_clusters - 2.0 ) ) * ( Dsum - D[i][j] ); #ifdef DEBUG fprintf ( outfile, "SN S[%3d][%3d]: %5.2f\n", i, j, Sij ); #endif if ( Sij < minSij ) { minSij = Sij; mini = i; minj = j; } } } } } if ( minSij == DBL_INF ) fprintf ( stderr, "ERROR: minSij Infinite\n" ); if ( ( mini == -1 ) || ( minj == -1 ) ) fprintf ( stderr, "ERROR: mini or minj not set\n" ); if ( ( valid[mini] == FALSE ) || ( valid[minj] == FALSE ) ) fprintf ( stderr, "ERROR: i or j cannot join\n" ); #ifdef VERYVERBOSE if ( verbose ) { fprintf ( outfile, "Saitou-Nei NJ:\t\t Step (%3d): ", num_genomes - num_clusters + 1 ); fprintf ( outfile, "Join %3d and %3d into %3d, edge weight= %5.2f\n", mini, minj, mini, D[mini][minj] ); } #endif valid[minj] = FALSE; for ( j = 0; j < mini; j++ ) { if ( valid[j] ) { if ( minj < j ) D[j][mini] = 0.5 * ( D[j][mini] + D[minj][j] ); else D[j][mini] = 0.5 * ( D[j][mini] + D[j][minj] ); } } for ( j = mini + 1; j < num_genomes; j++ ) { if ( valid[j] ) { if ( minj < j ) D[mini][j] = 0.5 * ( D[mini][j] + D[minj][j] ); else D[mini][j] = 0.5 * ( D[mini][j] + D[j][minj] ); } } NJtreescore += D[mini][minj]; Dsum -= D[mini][minj]; num_clusters--; } /* Must add last edge */ mini = minj = -1; for ( i = 0; i < num_genomes; i++ ) if ( valid[i] ) { if ( mini < 0 ) mini = i; else minj = i; } if ( ( mini < 0 ) || ( minj < 0 ) || ( mini >= minj ) ) fprintf ( stderr, "ERROR: cannot join last two neighbors\n" ); #ifdef VERYVERBOSE if ( verbose ) { fprintf ( outfile, "Saitou-Nei NJ:\t\t Step (%3d): ", num_genomes - num_clusters + 1 ); fprintf ( outfile, "Join %3d and %3d into %3d, edge weight= %5.2f\n", mini, minj, mini, D[mini][minj] ); } #endif NJtreescore += D[mini][minj]; if ( verbose ) { fprintf ( outfile, "Saitou-Nei NJ\t\t Tree Score: %5.2f\n\n", NJtreescore ); fflush ( outfile ); } free ( valid ); for ( i = 0; i < num_genomes; i++ ) free ( D[i] ); free ( D ); return NJtreescore; }
int neighborj_score ( struct genome_struct *genome_list, int num_genes, int num_genomes, distmem_t * distmem, int CIRCULAR, struct tNode *tpool, int *edgepool, struct genome_struct *labels, int initmethod, int COND, struct qNode *qpool, struct adj_struct *adj_list, struct adj_struct *adj_pool, int *stack, int *degree, int *otherEnd, intpair_t * neighbors, smalledge_t * smalledges, edge_t * edges, int *outcycle, int *pred1, int *pred2, int *picked, int *decode, int inittspsolver, triple_t * triple, int *incycle, int tspsolver, int distmethod, int thresh, int **weights, int **status, env_t * const_env, int *genes, int *condense_succ, int *condense_decode, int orig_num_genes, int correction, char *treeString ) { int i, j; int score; double **D; int *valid; char **branch; int maxConstSize; int count; D = ( double ** ) malloc ( num_genomes * sizeof ( double * ) ); if ( D == ( double ** ) NULL ) fprintf ( stderr, "ERROR: D NULL\n" ); for ( i = 0; i < num_genomes; i++ ) { D[i] = ( double * ) malloc ( num_genomes * sizeof ( double ) ); if ( D[i] == ( double * ) NULL ) fprintf ( stderr, "ERROR: D[i] NULL\n" ); } valid = ( int * ) malloc ( num_genomes * sizeof ( int ) ); if ( valid == ( int * ) NULL ) fprintf ( stderr, "ERROR: valid NULL\n" ); for ( i = 0; i < num_genomes; i++ ) valid[i] = TRUE; for ( i = 0; i < num_genomes; i++ ) { for ( j = i + 1; j < num_genomes; j++ ) { if ( CIRCULAR ) D[i][j] = ( double ) invdist_circular ( genome_list + i, genome_list + j, num_genes, distmem ); else D[i][j] = ( double ) invdist_noncircular ( genome_list + i, genome_list + j, 0, num_genes, distmem ); } } branch = ( char ** ) malloc ( num_genomes * sizeof ( char * ) ); if ( branch == ( char ** ) NULL ) fprintf ( stderr, "ERROR: branch NULL\n" ); maxConstSize = ( ( int ) ceil ( log10 ( ( double ) num_genomes ) ) + 4 ) * num_genomes + 1; for ( i = 0; i < num_genomes; i++ ) { branch[i] = ( char * ) malloc ( maxConstSize * sizeof ( char ) ); if ( branch[i] == ( char * ) NULL ) fprintf ( stderr, "ERROR: branch[i] NULL\n" ); sprintf ( branch[i], "%d", i + 1 ); } score = INT_INF; count = 0; neighborj_SK_trees ( genome_list, num_genes, num_genomes, distmem, CIRCULAR, tpool, edgepool, labels, initmethod, COND, qpool, adj_list, adj_pool, stack, degree, otherEnd, neighbors, smalledges, edges, outcycle, pred1, pred2, picked, decode, inittspsolver, triple, incycle, tspsolver, distmethod, thresh, weights, status, num_genomes, D, valid, branch, maxConstSize, &score, &count, const_env, genes, condense_succ, condense_decode, orig_num_genes, correction, treeString ); #ifdef MPBPA if ( MYPROC == 0 ) { #endif fprintf ( outfile, "Number of neighbor-joining trees evaluated: %12d\n\n", count ); fflush ( outfile ); #ifdef MPBPA } #endif for ( i = 0; i < num_genomes; i++ ) free ( branch[i] ); free ( branch ); free ( valid ); for ( i = 0; i < num_genomes; i++ ) free ( D[i] ); free ( D ); return ( score ); }
void do_fn_external(int num_genes, int num_chromosomes, int num_genomes, int circular, int unsigned_dist, int verbose, struct genome_struct *genome_list, char *ext_args) { int i, j; int **distmatrix; /* int dist_error; */ distmem_t *distmem; int aborted=0; //fprintf(outfile,"\nExternal function %s\n", ext_args); if (verbose && !unsigned_dist) { /* do_fn_distmatrix_v(num_genes, num_chromosomes, num_genomes, circular, unsigned_dist, genome_list); */ //fprintf(outfile,"verbose, signed distance. Code deleted.\n"); return; } //fprintf(outfile,"\nDistance Matrix:\n"); /* allocate space for matrix */ distmatrix = (int **) e_malloc((num_genomes)*sizeof(int *), "distmatrix"); for (i=0; i < num_genomes; i++) { distmatrix[i] = (int *) e_malloc((num_genomes)*sizeof(int), "distmatrix"); } /* allocate memory for distance computations */ distmem = (distmem_t *) e_malloc(sizeof(distmem_t), "distmem"); mcdist_allocmem(num_genes,num_chromosomes,distmem); /* compute the appropriate matrix */ if (unsigned_dist) { //fprintf(outfile,"Unsigned distance. Code deleted.\n"); aborted++; #if 0 set_unsigneddist_matrix(distmatrix, genome_list, num_genes, num_chromosomes, num_genomes, circular, distmem, &dist_error); if (dist_error) { //fprintf(outfile,"WARNING: These unsigned permutations are too complex;\n"); //fprintf(outfile,"some answers are approximated.\n"); } #endif /* 0 */ } else if (num_chromosomes == 0) { /* unichromosomal data */ #if 0 setinvmatrix(distmatrix,genome_list, num_genes,num_genomes, distmem, /* circular already converted to equiv linear problem */ FALSE); #endif /* 0 */ /* inline the code to demonstrate explicitly how distmem is used */ for (i=0 ; i<num_genomes ; i++) { distmatrix[i][i] = 0; for (j=i+1 ; j<num_genomes ; j++) { if (circular) distmatrix[i][j] = distmatrix[j][i] = invdist_circular(genome_list+i,genome_list+j, num_genes,distmem); else distmatrix[i][j] = distmatrix[j][i] = invdist_noncircular(genome_list+i,genome_list+j, 0,num_genes,distmem); } } } else { #if 0 /* multichromosomal data */ setmcdistmatrix(distmatrix,genome_list, num_genes,num_chromosomes,num_genomes, distmem); #endif /* 0 */ /* inline the code to demonstrate explicitly how distmem is used */ for (i=0 ; i<num_genomes ; i++) { distmatrix[i][i] = 0; for (j=i+1 ; j<num_genomes ; j++) { distmatrix[i][j] = distmatrix[j][i] = mcdist_noncircular(genome_list+i,genome_list+j, num_genes,num_chromosomes,distmem, (graphstats_t *)NULL); /* not verbose */ } } } if (!aborted) { /* display the matrix */ print_full_distmatrix(distmatrix,num_genomes,genome_list); } /* free the memory for distance computations */ mcdist_freemem(distmem); /* frees memory pointed to by fields of distmem */ free(distmem); /* frees the distmem structure itself */ /* free memory for the distance matrix */ for (i=num_genomes-1; i >=0 ; i--) free(distmatrix[i]); free(distmatrix); }