Next version of JABA
[jabaws.git] / binaries / src / mafft / core / nj.c
1 #include "mltaln.h"
2 #define DEBUG 0
3
4
5 void topolcpy( int s1[], int s2[], int *mpt1, int *mpt2 )
6 {
7     int i;
8
9     *mpt1 = *mpt2;
10     for( i=0; i<*mpt2; i++ )
11     {
12         s1[i] = s2[i];
13     }
14 }
15
16 void topolcat( int s1[], int s2[], int *mpt1, int *mpt2 )
17 {
18     int i;
19
20     for( i=*mpt1; i<*mpt1+*mpt2; i++ )
21     {
22         s1[i] = s2[i-*mpt1];
23     }
24     *mpt1 += *mpt2;
25 }
26    
27 void topolsort( int m, int s[] )
28 {
29     int i, j, im;
30     int sm;
31
32     for( j=0; j<m-1; j++ )
33     {
34         sm = s[j]; im = j;
35         for( i=j+1; i<m; i++ )
36         {
37             if( s[i] < sm )
38             {
39                 sm = s[i];
40                 im = i;
41             }
42         }
43         s[im] = s[j]; s[j] = sm;
44     }
45 }
46
47 void topolswap( int s1[], int s2[], int *mpt1, int *mpt2 )
48 {
49     int i;
50     int im;
51     int b;
52     b = *mpt1; *mpt1 = *mpt2; *mpt2 = b;
53     im = MAX(*mpt1,*mpt2);
54     for( i=0; i<im; i++ )
55     {
56         b = s1[i]; s1[i] = s2[i]; s2[i] = b;
57     /*
58     printf( "s1[%d]=%d\ns2[%d]=%d\n", i, s1[i], i, s2[i] );
59     */
60     }
61 }
62
63 void reduc( double **mtx, int nseq, int im, int jm )
64 {
65     int i;
66     for( i=0; i<nseq; i++ )
67     {
68         if(    i==im || i==jm
69             || mtx[MIN(i,im)][MAX(i,im)] == 9999.9
70             || mtx[MIN(i,jm)][MAX(i,jm)] == 9999.9
71           ) continue;
72         mtx[MIN(i,im)][MAX(i,im)]
73         = 0.5 * ( mtx[MIN(i,im)][MAX(i,im)] + mtx[MIN(i,jm)][MAX(i,jm)]
74                   - mtx[MIN(im,jm)][MAX(im,jm)] );
75         mtx[MIN(i,jm)][MAX(i,jm)] = 9999.9;
76     }
77     mtx[MIN(im,jm)][MAX(im,jm)] = 9999.9;
78 }
79
80
81 void  nj( int nseq, double **omtx, int ***topol, double **dis )
82 {
83     int i, j, l, n, m;
84     int count;
85     double r[M];
86     double t;
87     double s, sm;
88     double totallen = 0.0;
89     int im=0, jm=0;
90     double len1, len2;
91 #if 1
92         static char **par = NULL;
93         static double **mtx = NULL;
94         static int **mem = NULL;
95         if( par == NULL )
96         {
97                 par = AllocateCharMtx( njob, njob );
98                 mtx = AllocateDoubleMtx( njob, njob );
99                 mem = AllocateIntMtx( njob, 2 );
100         }
101 #else
102     char par[njob][njob];
103         double mtx[njob][njob];
104         int mem[njob][2];
105 #endif
106         for( i=0; i<nseq; i++ ) for( j=0; j<nseq; j++ ) mtx[i][j] = omtx[i][j];
107     for( i=0; i<nseq; i++ ) for( j=0; j<nseq; j++ ) par[i][j] = 0;
108     for( i=0; i<nseq; i++ ) par[i][i] = 1;
109 //      for( i=0; i<nseq; i++ ) for( j=0; j<2; j++ ) for( l=0; l<nseq+1; l++ ) topol[i][j][l] = -1;
110         for( i=0; i<nseq; i++ ) for( j=0; j<2; j++ ) for( l=0; l<nseq; l++ ) topol[i][j][l] = -1;
111     for( n=nseq, m=0; n>2; n--, m=nseq-n )
112     {
113         t = 0.0;
114         for( i=0; i<nseq-1; i++ ) for( j=0; j<nseq; j++ ) if( mtx[i][j] < 9999.9 )
115             t += mtx[i][j];
116         for( i=0; i<nseq; i++ )
117         {
118             r[i] = 0.0;
119             for( l=0; l<nseq; l++ ) 
120                 if( ( l != i ) && ( mtx[MIN(i,l)][MAX(i,l)] < 9999.9 ) )
121                     r[i] += mtx[MIN(i,l)][MAX(i,l)];
122         }
123         sm = 9999.9;
124         for( i=0; i<nseq-1; i++ ) for( j=i+1; j<nseq; j++ ) if( mtx[i][j] < 9999.9)
125         {
126             s = ( ( 2.0 * t - r[i] - r[j] + (n-2.0)*mtx[i][j] ) ) / ( 2.0*(n-2.0) );
127             if ( s < sm )
128             {
129                 sm = s;
130                 im = i; jm = j;
131             }
132         }
133         len1 = ( (n-2)*mtx[im][jm] + r[im] - r[jm] ) / (2*(n-2));
134         len2 = ( (n-2)*mtx[im][jm] - r[im] + r[jm] ) / (2*(n-2));
135
136 #if DEBUG
137         fprintf( stderr, "STEP-%3d  %3d: L = %5.5f\n", m+1, im+1, len1 );
138         fprintf( stderr, "          %3d: L = %5.5f\n",      jm+1, len2 );
139 #endif
140
141         totallen += len1;
142         totallen += len2;
143
144         dis[m][0] = len1;
145         dis[m][1] = len2;
146
147         for( l=0, count=0; l<nseq; l++ )
148             if( par[im][l] > 0 )
149             {
150                 topol[m][0][count] = l;
151                 count++;
152             }
153         mem[m][0] = count;
154         for( l=0, count=0; l<nseq; l++ )
155             if( par[jm][l] > 0 )
156             {
157                 topol[m][1][count] = l;
158                 count++;
159             }
160         mem[m][1] = count;
161         for( l=0; l<nseq; l++ )
162             par[im][l] += ( par[jm][l] > 0 );
163         if( n > 3 ) reduc( mtx, nseq, im, jm );
164     }
165     for( i=0; i<nseq; i++ )
166         if( i!=im && i!=jm && mtx[MIN(i,im)][MAX(i,im)]<9999.9 )
167             break;
168     len2 = ( mtx[MIN(i,im)][MAX(i,im)] - r[im] + r[i] ) / 2;
169
170 /*
171     printf("          %3d: L = %5.5f\n", i+1, len2 );
172 */
173     totallen += len2;
174
175     dis[m][0] = len2;
176     dis[m][1] = 0.0;
177     for( l=0, count=0; l<nseq; l++ )
178         if( par[i][l] > 0 )
179         {
180             topol[m][0][count] = l;
181             count++;
182         }
183     mem[m][0] = count;
184     /*
185     printf( " total length == %f\n", totallen );
186     */
187
188     topolcpy( topol[nseq-2][1], topol[nseq-3][0], mem[nseq-2]+1, mem[nseq-3] );
189     topolcat( topol[nseq-2][1], topol[nseq-3][1], mem[nseq-2]+1, mem[nseq-3]+1 );
190     topolsort( mem[nseq-2][1], topol[nseq-2][1] );
191         
192         if( topol[nseq-2][0][0] > topol[nseq-2][1][0] )
193                 topolswap( topol[nseq-2][0], topol[nseq-2][1], mem[nseq-2], mem[nseq-2]+1 );
194
195 }