Next version of JABA
[jabaws.git] / binaries / src / mafft / core / SAalignmm.c
1 #include "mltaln.h"
2 #include "dp.h"
3
4 #define DEBUG 0
5
6 static void match_calc( float *match, float **cpmx1, float **cpmx2, int i1, int lgth2, float **floatwork, int **intwork, int initialize )
7 {
8         int j, k, l;
9         float scarr[26];
10         float **cpmxpd = floatwork;
11         int **cpmxpdn = intwork;
12         int count = 0;
13
14         if( initialize )
15         {
16                 for( j=0; j<lgth2; j++ )
17                 {
18                         count = 0;
19                         for( l=0; l<26; l++ )
20                         {
21                                 if( cpmx2[l][j] )
22                                 {
23                                         cpmxpd[count][j] = cpmx2[l][j];
24                                         cpmxpdn[count][j] = l;
25                                         count++;
26                                 }
27                         }
28                         cpmxpdn[count][j] = -1;
29                 }
30         }
31
32         for( l=0; l<26; l++ )
33         {
34                 scarr[l] = 0.0;
35                 for( k=0; k<26; k++ )
36                         scarr[l] += n_dis[k][l] * cpmx1[k][i1];
37         }
38         for( j=0; j<lgth2; j++ )
39         {
40                 match[j] = 0;
41                 for( k=0; cpmxpdn[k][j] > -1;  k++ )
42                         match[j] += scarr[cpmxpdn[k][j]] * cpmxpd[k][j];
43         } 
44 }
45
46 static float Atracking( float *lasthorizontalw, float *lastverticalw, 
47                                                 char **seq1, char **seq2, 
48                         char **mseq1, char **mseq2, 
49                         float **cpmx1, float **cpmx2, 
50                         int **ijp, int icyc, int jcyc )
51 {
52         int i, j, k, l, iin, jin, ifi, jfi, lgth1, lgth2;
53         char gap[] = "-";
54         float wm;
55         lgth1 = strlen( seq1[0] );
56         lgth2 = strlen( seq2[0] );
57
58 #if DEBUG
59         for( i=0; i<lgth1; i++ ) 
60         {
61                 fprintf( stderr, "lastverticalw[%d] = %f\n", i, lastverticalw[i] );
62         }
63 #endif
64  
65         if( outgap == 1 )
66                 ;
67         else
68         {
69                 wm = lastverticalw[0];
70                 for( i=0; i<lgth1; i++ )
71                 {
72                         if( lastverticalw[i] >= wm )
73                         {
74                                 wm = lastverticalw[i];
75                                 iin = i; jin = lgth2-1;
76                                 ijp[lgth1][lgth2] = +( lgth1 - i );
77                         }
78                 }
79                 for( j=0; j<lgth2; j++ )
80                 {
81                         if( lasthorizontalw[j] >= wm )
82                         {
83                                 wm = lasthorizontalw[j];
84                                 iin = lgth1-1; jin = j;
85                                 ijp[lgth1][lgth2] = -( lgth2 - j );
86                         }
87                 }
88         }
89
90     for( i=0; i<lgth1+1; i++ ) 
91     {
92         ijp[i][0] = i + 1;
93     }
94     for( j=0; j<lgth2+1; j++ ) 
95     {
96         ijp[0][j] = -( j + 1 );
97     }
98
99         for( i=0; i<icyc; i++ )
100         {
101                 mseq1[i] += lgth1+lgth2;
102                 *mseq1[i] = 0;
103         }
104         for( j=0; j<jcyc; j++ )
105         {
106                 mseq2[j] += lgth1+lgth2;
107                 *mseq2[j] = 0;
108         }
109         iin = lgth1; jin = lgth2;
110         for( k=0; k<=lgth1+lgth2; k++ ) 
111         {
112                 if( ijp[iin][jin] < 0 ) 
113                 {
114                         ifi = iin-1; jfi = jin+ijp[iin][jin];
115                 }
116                 else if( ijp[iin][jin] > 0 )
117                 {
118                         ifi = iin-ijp[iin][jin]; jfi = jin-1;
119                 }
120                 else
121                 {
122                         ifi = iin-1; jfi = jin-1;
123                 }
124                 l = iin - ifi;
125                 while( --l ) 
126                 {
127                         for( i=0; i<icyc; i++ )
128                                 *--mseq1[i] = seq1[i][ifi+l];
129                         for( j=0; j<jcyc; j++ ) 
130                                 *--mseq2[j] = *gap;
131                         k++;
132                 }
133                 l= jin - jfi;
134                 while( --l )
135                 {
136                         for( i=0; i<icyc; i++ ) 
137                                 *--mseq1[i] = *gap;
138                         for( j=0; j<jcyc; j++ ) 
139                                 *--mseq2[j] = seq2[j][jfi+l];
140                         k++;
141                 }
142                 if( iin <= 0 || jin <= 0 ) break;
143                 for( i=0; i<icyc; i++ ) 
144                         *--mseq1[i] = seq1[i][ifi];
145                 for( j=0; j<jcyc; j++ ) 
146                         *--mseq2[j] = seq2[j][jfi];
147                 k++;
148                 iin = ifi; jin = jfi;
149         }
150         return( 0.0 );
151 }
152
153
154 float Aalign( char **seq1, char **seq2, double *eff1, double *eff2, int icyc, int jcyc, int alloclen )
155 /* score no keisan no sai motokaraaru gap no atukai ni mondai ga aru */
156 {
157         register int i, j;
158         int lasti;                      /* outgap == 0 -> lgth1, outgap == 1 -> lgth1+1 */
159         int lgth1, lgth2;
160         int resultlen;
161         float wm = 0.0;   /* int ?????? */
162         float g;
163         float x;
164         static float mi, *m;
165         static int **ijp;
166         static int mpi, *mp;
167         static float *currentw;
168         static float *previousw;
169         static float *match;
170         static float *initverticalw;    /* kufuu sureba iranai */
171         static float *lastverticalw;    /* kufuu sureba iranai */
172         static char **mseq1;
173         static char **mseq2;
174         static char **mseq;
175         static float **cpmx1;
176         static float **cpmx2;
177         static int **intwork;
178         static float **floatwork;
179         static int orlgth1 = 0, orlgth2 = 0;
180
181 #if DEBUG
182         fprintf( stderr, "eff in SA+++align\n" );
183         for( i=0; i<icyc; i++ ) fprintf( stderr, "eff1[%d] = %f\n", i, eff1[i] );
184 #endif
185         if( orlgth1 == 0 )
186         {
187                 mseq1 = AllocateCharMtx( njob, 1 ); 
188                 mseq2 = AllocateCharMtx( njob, 1 ); /* by J. Thompson */
189         }
190
191         lgth1 = strlen( seq1[0] );
192         lgth2 = strlen( seq2[0] );
193
194         if( lgth1 > orlgth1 || lgth2 > orlgth2 )
195         {
196                 int ll1, ll2;
197
198                 if( orlgth1 > 0 && orlgth2 > 0 )
199                 {
200                         FreeFloatVec( currentw );
201                         FreeFloatVec( previousw );
202                         FreeFloatVec( match );
203                         FreeFloatVec( initverticalw );
204                         FreeFloatVec( lastverticalw );
205
206                         FreeFloatVec( m );
207                         FreeIntVec( mp );
208
209                         FreeCharMtx( mseq );
210
211                         FreeFloatMtx( cpmx1 );
212                         FreeFloatMtx( cpmx2 );
213
214                         FreeFloatMtx( floatwork );
215                         FreeIntMtx( intwork );
216                 }
217
218                 ll1 = MAX( (int)(1.1*lgth1), orlgth1 ) + 100;
219                 ll2 = MAX( (int)(1.1*lgth2), orlgth2 ) + 100;
220
221                 fprintf( stderr, "\ntrying to allocate (%d+%d)xn matrices ... ", ll1, ll2 );
222
223                 currentw = AllocateFloatVec( ll2+2 );
224                 previousw = AllocateFloatVec( ll2+2 );
225                 match = AllocateFloatVec( ll2+2 );
226
227                 initverticalw = AllocateFloatVec( ll1+2 );
228                 lastverticalw = AllocateFloatVec( ll1+2 );
229
230                 m = AllocateFloatVec( ll2+2 );
231                 mp = AllocateIntVec( ll2+2 );
232
233                 mseq = AllocateCharMtx( njob, ll1+ll2 );
234
235                 cpmx1 = AllocateFloatMtx( 26, ll1+2 );
236                 cpmx2 = AllocateFloatMtx( 26, ll2+2 );
237
238                 floatwork = AllocateFloatMtx( 26, MAX( ll1, ll2 )+2 ); 
239                 intwork = AllocateIntMtx( 26, MAX( ll1, ll2 )+2 ); 
240
241                 fprintf( stderr, "succeeded\n" );
242
243                 orlgth1 = ll1;
244                 orlgth2 = ll2;
245         }
246
247         for( i=0; i<icyc; i++ ) mseq1[i] = mseq[i];
248         for( j=0; j<jcyc; j++ ) mseq2[j] = mseq[icyc+j];
249
250
251         if( orlgth1 > commonAlloc1 || orlgth2 > commonAlloc2 )
252         {
253                 int ll1, ll2;
254
255                 if( commonAlloc1 && commonAlloc2 )
256                 {
257                         FreeIntMtx( commonIP );
258                 }
259
260                 ll1 = MAX( orlgth1, commonAlloc1 );
261                 ll2 = MAX( orlgth2, commonAlloc2 );
262
263                 fprintf( stderr, "\n\ntrying to allocate %dx%d matrices ... ", ll1+1, ll2+1 );
264
265                 commonIP = AllocateIntMtx( ll1+10, ll2+10 );
266
267                 fprintf( stderr, "succeeded\n\n" );
268
269                 commonAlloc1 = ll1;
270                 commonAlloc2 = ll2;
271         }
272         ijp = commonIP;
273
274         cpmx_calc( seq1, cpmx1, eff1, strlen( seq1[0] ), icyc );
275         cpmx_calc( seq2, cpmx2, eff2, strlen( seq2[0] ), jcyc );
276
277         match_calc( initverticalw, cpmx2, cpmx1, 0, lgth1, floatwork, intwork, 1 );
278         match_calc( currentw, cpmx1, cpmx2, 0, lgth2, floatwork, intwork, 1 );
279
280         if( outgap == 1 )
281         {
282                 for( i=1; i<lgth1+1; i++ )
283                 {
284                         initverticalw[i] += penalty * 0.5;
285                 }
286                 for( j=1; j<lgth2+1; j++ )
287                 {
288                         currentw[j] += penalty * 0.5;
289                 }
290         }
291
292         for( j=0; j<lgth2+1; ++j ) 
293         {
294                 m[j] = currentw[j-1] + penalty * 0.5; mp[j] = 0;
295         }
296
297         lastverticalw[0] = currentw[lgth2-1];
298
299         if( outgap ) lasti = lgth1+1; else lasti = lgth1;
300
301         for( i=1; i<lasti; i++ )
302         {
303
304                 floatncpy( previousw, currentw, lgth2+1 );
305                 previousw[0] = initverticalw[i-1];
306
307                 match_calc( currentw, cpmx1, cpmx2, i, lgth2, floatwork, intwork, 0 );
308                 currentw[0] = initverticalw[i];
309
310                 mi = previousw[0] + penalty * 0.5; mpi = 0;
311                 for( j=1; j<lgth2+1; j++ )
312                 {
313                         wm = previousw[j-1];
314                         ijp[i][j] = 0;
315
316                         g = penalty * 0.5;
317                         x = mi + g;
318                         if( x > wm )
319                         {
320                                 wm = x;
321                                 ijp[i][j] = -( j - mpi );
322                         }
323                         g = penalty * 0.5;
324                         x = previousw[j-1] + g;
325                         if( mi <= x )
326                         {
327                                 mi = x;
328                                 mpi = j-1;
329                         }
330
331                         g = penalty * 0.5;
332                         x = m[j] + g;
333                         if( x > wm )
334                         {
335                                 wm = x;
336                                 ijp[i][j] = +( i - mp[j] );
337                         }
338                         g = penalty * 0.5;
339                         x = previousw[j-1] + g;
340                         if( m[j] <= x )
341                         {
342                                 m[j] = x;
343                                 mp[j] = i-1;
344                         }
345                         currentw[j] += wm;
346                 }
347                 lastverticalw[i] = currentw[lgth2-1];
348         }
349         /*
350         fprintf( stderr, "\n" );
351         for( i=0; i<icyc; i++ ) fprintf( stderr,"%s\n", seq1[i] );
352         fprintf( stderr, "#####\n" );
353         for( j=0; j<jcyc; j++ ) fprintf( stderr,"%s\n", seq2[j] );
354         fprintf( stderr, "====>" );
355         for( i=0; i<icyc; i++ ) strcpy( mseq1[i], seq1[i] );
356         for( j=0; j<jcyc; j++ ) strcpy( mseq2[j], seq2[j] );
357         */
358         Atracking( currentw, lastverticalw, seq1, seq2, mseq1, mseq2, cpmx1, cpmx2, ijp, icyc, jcyc );
359
360         resultlen = strlen( mseq1[0] );
361         if( alloclen < resultlen || resultlen > N )
362         {
363                 fprintf( stderr, "alloclen=%d, resultlen=%d, N=%d\n", alloclen, resultlen, N );
364                 ErrorExit( "LENGTH OVER!\n" );
365         }
366
367         for( i=0; i<icyc; i++ ) strcpy( seq1[i], mseq1[i] );
368         for( j=0; j<jcyc; j++ ) strcpy( seq2[j], mseq2[j] );
369         /*
370         fprintf( stderr, "\n" );
371         for( i=0; i<icyc; i++ ) fprintf( stderr, "%s\n", mseq1[i] );
372         fprintf( stderr, "#####\n" );
373         for( j=0; j<jcyc; j++ ) fprintf( stderr, "%s\n", mseq2[j] );
374         */
375         return( wm );
376 }