-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmed_util.c
209 lines (189 loc) · 6.38 KB
/
med_util.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
/* $Id: med_util.c,v 1.8 2001/12/19 22:41:47 acs Exp $
Written by Adam Siepel, Spring 2001
Copyright 2001, Adam Siepel */
/* Miscellaneous utility functions used by reversal median code */
#include "med_util.h"
#include "invdist.h"
#include "simpleio.h"
#include <math.h>
/* 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 ) );
}
/* Allocates space for and returns a new permutation equal to the
specified one. */
int *
newperm ( int *perm, int ngenes )
{
int i;
int *newperm = calloc ( ngenes, sizeof ( int ) );
for ( i = 0; i < ngenes; i++ )
newperm[i] = perm[i];
return newperm;
}
/* Copies one permutation to another (space must already be allocated
for the new one). Use like strcpy. */
void
permcopy ( int *dest, int *source, int sz )
{
int i;
for ( i = 0; i < sz; i++ )
dest[i] = source[i];
}
/* Compares two permutations (use like strcmp) */
int
permcmp ( int *perm1, int *perm2, int n )
{
int i;
for ( i = 0; i < n; i++ )
if ( perm1[i] != perm2[i] )
return 1;
return 0;
}
/* Creates and returns a distmem_t structure for use in calculating
pairwise inversion distances */
distmem_t *
new_distmem ( int ngenes )
{
distmem_t *distmem = ( distmem_t * ) malloc ( sizeof ( distmem_t ) );
/* below snipped from GRAPPA */
distmem->hammingArr =
( int * ) malloc ( ( ngenes + 1 ) * 2 * sizeof ( int ) );
if ( distmem->hammingArr == ( int * ) NULL )
fprintf ( stderr, "ERROR: hammingArr NULL\n" );
distmem->perm1 = ( int * ) malloc ( ( 2 * ngenes + 2 ) * sizeof ( int ) );
if ( distmem->perm1 == ( int * ) NULL )
fprintf ( stderr, "ERROR: perm1 NULL\n" );
distmem->perm2 = ( int * ) malloc ( ( 2 * ngenes + 2 ) * sizeof ( int ) );
if ( distmem->perm2 == ( int * ) NULL )
fprintf ( stderr, "ERROR: perm2 NULL\n" );
distmem->perm = ( int * ) malloc ( ( 2 * ngenes + 2 ) * sizeof ( int ) );
if ( distmem->perm == ( int * ) NULL )
fprintf ( stderr, "ERROR: perm NULL\n" );
distmem->done = ( int * ) malloc ( ( 2 * ngenes + 2 ) * sizeof ( int ) );
if ( distmem->done == ( int * ) NULL )
fprintf ( stderr, "ERROR: done NULL\n" );
distmem->greyEdges =
( int * ) malloc ( ( 2 * ngenes + 2 ) * sizeof ( int ) );
if ( distmem->greyEdges == ( int * ) NULL )
fprintf ( stderr, "ERROR: greyEdges NULL\n" );
distmem->stack = ( int * ) malloc ( ( 2 * ngenes + 2 ) * sizeof ( int ) );
if ( distmem->stack == ( int * ) NULL )
fprintf ( stderr, "ERROR: stack NULL\n" );
distmem->oriented =
( int * ) malloc ( ( 2 * ngenes + 2 ) * sizeof ( int ) );
if ( distmem->oriented == ( int * ) NULL )
fprintf ( stderr, "ERROR: oriented NULL\n" );
distmem->cc = ( int * ) malloc ( ( 2 * ngenes + 2 ) * sizeof ( int ) );
if ( distmem->cc == ( int * ) NULL )
fprintf ( stderr, "ERROR: cc NULL\n" );
distmem->labeled =
( int * ) malloc ( ( 2 * ngenes + 2 ) * sizeof ( int ) );
if ( distmem->labeled == ( int * ) NULL )
fprintf ( stderr, "ERROR: labeled NULL\n" );
distmem->components = ( component_t * )
malloc ( ( 2 * ngenes + 2 ) * sizeof ( component_t ) );
if ( distmem->components == ( component_t * ) NULL )
fprintf ( stderr, "ERROR: components NULL\n" );
distmem->uf = UFalloc ( 2 * ngenes + 2 );
return distmem;
}
/* Frees all memory associated with the specified distmem_t structure
(including that allocated for the structure itself) */
void
free_distmem ( distmem_t * distmem )
{
free ( distmem->hammingArr );
free ( distmem->perm1 );
free ( distmem->perm2 );
free ( distmem->perm );
free ( distmem->done );
free ( distmem->greyEdges );
free ( distmem->stack );
free ( distmem->oriented );
free ( distmem->cc );
free ( distmem->labeled );
free ( distmem->components );
free ( distmem->uf );
free ( distmem );
}
/* "Condenses" three genomes by reducing to single genes all sequences
of three or more genes present in all three genomes (considering
reverse complements to be equal). Return value indicates whether
condensing occurred (1->condensing, 0->no condensing). */
int
condense ( struct genome_struct **old_gens, int old_ngenes,
struct genome_struct **new_gens, int new_ngenes )
{
int retval = 0;
return retval;
}
/* Finds the "circular identity" of the specified permutation,
which we define as the equivalent permutation that begins with the
gene "+1".*/
void
find_circular_identity ( int *perm, int *id, int ngenes )
{
int i, j;
int sign = 1;
for ( i = 0; i < ngenes; i++ )
{
if ( perm[i] == 1 )
break;
else if ( perm[i] == -1 )
{
sign = -1;
break;
}
}
if ( i == ngenes )
{
fprintf ( stderr,
"FATAL ERROR: permutation has no element labeled '1'.\n" );
exit ( 1 );
}
if ( sign == 1 )
{
for ( j = 0; j < ngenes; j++ )
{
id[j] = perm[i];
if ( ++i == ngenes )
i = 0;
}
}
else
{ /* sign == -1 */
for ( j = 0; j < ngenes; j++ )
{
id[j] = -perm[i];
if ( --i < 0 )
i = ngenes - 1;
}
}
}
/* Copies a permutation, simultaneously representing the effect of the
specified reversal */
void
copy_with_reversal ( int *dest, int *src, int n, Reversal * rev )
{
int i, mid;
for ( i = 0; i < rev->start; i++ )
dest[i] = src[i];
mid = ceil ( ( rev->stop - rev->start ) / 2.0 );
for ( i = 0; i < mid; i++ )
{
dest[rev->start + i] = -1 * src[rev->stop - 1 - i];
dest[rev->stop - 1 - i] = -1 * src[rev->start + i];
}
for ( i = rev->stop; i < n; i++ )
dest[i] = src[i];
}