1 | /* |
---|
2 | |
---|
3 | PHYML : a program that computes maximum likelihood phylogenies from |
---|
4 | DNA or AA homologous sequences |
---|
5 | |
---|
6 | Copyright (C) Stephane Guindon. Oct 2003 onward |
---|
7 | |
---|
8 | All parts of the source except where indicated are distributed under |
---|
9 | the GNU public licence. See http://www.opensource.org for details. |
---|
10 | |
---|
11 | */ |
---|
12 | |
---|
13 | #include "simu.h" |
---|
14 | |
---|
15 | |
---|
16 | ////////////////////////////////////////////////////////////// |
---|
17 | ////////////////////////////////////////////////////////////// |
---|
18 | |
---|
19 | void Simu_Loop(t_tree *mixt_tree) |
---|
20 | { |
---|
21 | phydbl lk_old; |
---|
22 | int *orig_catg; |
---|
23 | int n; |
---|
24 | t_tree *tree,**tree_list; |
---|
25 | |
---|
26 | |
---|
27 | if((mixt_tree->mod->s_opt->print) && |
---|
28 | (!mixt_tree->io->quiet)) PhyML_Printf("\n\n. Refining the tree...\n"); |
---|
29 | |
---|
30 | /*! Get the number of classes in each mixture */ |
---|
31 | orig_catg = MIXT_Get_Number_Of_Classes_In_All_Mixtures(mixt_tree); |
---|
32 | |
---|
33 | |
---|
34 | /*! Set the number of rate classes to (at most) 2. |
---|
35 | ! Propagate this to every mixture tree in the analysis |
---|
36 | */ |
---|
37 | tree = mixt_tree; |
---|
38 | n = 0; |
---|
39 | do |
---|
40 | { |
---|
41 | tree->mod->ras->n_catg = MIN(2,orig_catg[n]); |
---|
42 | if(tree->mod->ras->invar == YES) tree->mod->ras->n_catg--; |
---|
43 | tree = tree->next_mixt; |
---|
44 | n++; |
---|
45 | } |
---|
46 | while(tree); |
---|
47 | |
---|
48 | /*! Make sure the number of trees in each mixture is at most 2 |
---|
49 | */ |
---|
50 | tree_list = MIXT_Record_All_Mixtures(mixt_tree); |
---|
51 | MIXT_Break_All_Mixtures(orig_catg,mixt_tree); |
---|
52 | |
---|
53 | |
---|
54 | Set_Both_Sides(YES,mixt_tree); |
---|
55 | Lk(NULL,mixt_tree); |
---|
56 | |
---|
57 | |
---|
58 | mixt_tree->best_pars = 1E+8; |
---|
59 | mixt_tree->mod->s_opt->spr_pars = NO; |
---|
60 | mixt_tree->mod->s_opt->quickdirty = NO; |
---|
61 | mixt_tree->best_lnL = mixt_tree->c_lnL; |
---|
62 | mixt_tree->mod->s_opt->max_delta_lnL_spr = 0.; |
---|
63 | mixt_tree->mod->s_opt->br_len_in_spr = 1; |
---|
64 | mixt_tree->mod->s_opt->max_depth_path = 2*mixt_tree->n_otu-3; |
---|
65 | mixt_tree->mod->s_opt->spr_lnL = NO; |
---|
66 | |
---|
67 | |
---|
68 | /*! Optimize branch lengths and substitution model parameters |
---|
69 | */ |
---|
70 | Optimiz_All_Free_Param(mixt_tree,(mixt_tree->io->quiet)?(0):(mixt_tree->mod->s_opt->print)); |
---|
71 | |
---|
72 | |
---|
73 | /*! Rough SPR search |
---|
74 | */ |
---|
75 | do |
---|
76 | { |
---|
77 | lk_old = mixt_tree->c_lnL; |
---|
78 | Speed_Spr(mixt_tree,1); |
---|
79 | if((mixt_tree->n_improvements < 20) || |
---|
80 | (mixt_tree->max_spr_depth < 5) || |
---|
81 | (FABS(lk_old-mixt_tree->c_lnL) < 1.)) break; |
---|
82 | } |
---|
83 | while(1); |
---|
84 | |
---|
85 | |
---|
86 | Set_Both_Sides(YES,mixt_tree); |
---|
87 | Lk(NULL,mixt_tree); |
---|
88 | |
---|
89 | /*! Go back to the original data structure, with potentially more |
---|
90 | ! than 2 trees per mixture |
---|
91 | */ |
---|
92 | MIXT_Reconnect_All_Mixtures(tree_list,mixt_tree); |
---|
93 | Free(tree_list); |
---|
94 | |
---|
95 | /*! Set the number of rate classes to their original values |
---|
96 | */ |
---|
97 | tree = mixt_tree; |
---|
98 | n = 0; |
---|
99 | do |
---|
100 | { |
---|
101 | tree->mod->ras->n_catg = orig_catg[n]; |
---|
102 | if(tree->mod->ras->invar == YES) tree->mod->ras->n_catg--; |
---|
103 | tree = tree->next_mixt; |
---|
104 | n++; |
---|
105 | } |
---|
106 | while(tree); |
---|
107 | |
---|
108 | Free(orig_catg); |
---|
109 | |
---|
110 | |
---|
111 | |
---|
112 | /*! Only the first two trees for each mixture have been modified so |
---|
113 | ! far -> need to update the other trees by copying the modified trees |
---|
114 | ! onto them. |
---|
115 | */ |
---|
116 | tree = mixt_tree; |
---|
117 | do |
---|
118 | { |
---|
119 | if(tree != mixt_tree) Copy_Tree(mixt_tree,tree); |
---|
120 | tree = tree->next; |
---|
121 | } |
---|
122 | while(tree); |
---|
123 | |
---|
124 | if((mixt_tree->mod->s_opt->print) && (!mixt_tree->io->quiet)) |
---|
125 | { |
---|
126 | PhyML_Printf("\n\n. End of refining stage...\n. The log-likelihood might now decrease and then increase again...\n"); |
---|
127 | PhyML_Printf("\n\n. Maximizing likelihood (using NNI moves)...\n"); |
---|
128 | } |
---|
129 | |
---|
130 | |
---|
131 | Set_Both_Sides(YES,mixt_tree); |
---|
132 | Lk(NULL,mixt_tree); |
---|
133 | mixt_tree->best_lnL = mixt_tree->c_lnL; |
---|
134 | |
---|
135 | int n_tot_moves = 0; |
---|
136 | do |
---|
137 | { |
---|
138 | lk_old = mixt_tree->c_lnL; |
---|
139 | Optimiz_All_Free_Param(mixt_tree,(mixt_tree->io->quiet)?(0):(mixt_tree->mod->s_opt->print)); |
---|
140 | n_tot_moves = Simu(mixt_tree,10); |
---|
141 | if(!n_tot_moves) break; |
---|
142 | } |
---|
143 | while(mixt_tree->c_lnL > lk_old + mixt_tree->mod->s_opt->min_diff_lk_local); |
---|
144 | |
---|
145 | do |
---|
146 | { |
---|
147 | Round_Optimize(mixt_tree,mixt_tree->data,ROUND_MAX); |
---|
148 | if(!Check_NNI_Five_Branches(mixt_tree)) break; |
---|
149 | }while(1); |
---|
150 | /*****************************/ |
---|
151 | |
---|
152 | if((mixt_tree->mod->s_opt->print) && |
---|
153 | (!mixt_tree->io->quiet)) PhyML_Printf("\n"); |
---|
154 | } |
---|
155 | |
---|
156 | ////////////////////////////////////////////////////////////// |
---|
157 | ////////////////////////////////////////////////////////////// |
---|
158 | |
---|
159 | int Simu(t_tree *tree, int n_step_max) |
---|
160 | { |
---|
161 | phydbl old_loglk,n_iter,lambda; |
---|
162 | int i,n_neg,n_tested,n_without_swap,n_tot_swap,step,it_lim_without_swap; |
---|
163 | t_edge **sorted_b,**tested_b; |
---|
164 | |
---|
165 | sorted_b = (t_edge **)mCalloc(tree->n_otu-3,sizeof(t_edge *)); |
---|
166 | tested_b = (t_edge **)mCalloc(tree->n_otu-3,sizeof(t_edge *)); |
---|
167 | |
---|
168 | old_loglk = UNLIKELY; |
---|
169 | tree->c_lnL = UNLIKELY; |
---|
170 | n_iter = 1.0; |
---|
171 | /* it_lim_without_swap = (tree->mod->ras->invar)?(5):(2); */ |
---|
172 | it_lim_without_swap = (tree->mod->ras->invar)?(1):(1); |
---|
173 | n_tested = 0; |
---|
174 | n_without_swap = 0; |
---|
175 | step = 0; |
---|
176 | lambda = .75; |
---|
177 | n_tot_swap = 0; |
---|
178 | |
---|
179 | Update_Dirs(tree); |
---|
180 | |
---|
181 | if(tree->lock_topo) |
---|
182 | { |
---|
183 | PhyML_Printf("\n. The tree topology is locked."); |
---|
184 | PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); |
---|
185 | Warn_And_Exit(""); |
---|
186 | } |
---|
187 | |
---|
188 | do |
---|
189 | { |
---|
190 | ++step; |
---|
191 | |
---|
192 | if(n_tested || step == 1) MIXT_Set_Alias_Subpatt(YES,tree); |
---|
193 | old_loglk = tree->c_lnL; |
---|
194 | Set_Both_Sides(YES,tree); |
---|
195 | Lk(NULL,tree); |
---|
196 | MIXT_Set_Alias_Subpatt(NO,tree); |
---|
197 | |
---|
198 | if(tree->c_lnL < old_loglk) |
---|
199 | { |
---|
200 | if((tree->mod->s_opt->print) && (!tree->io->quiet)) PhyML_Printf("\n\n. Moving backward\n"); |
---|
201 | if(!Mov_Backward_Topo_Bl(tree,old_loglk,tested_b,n_tested)) |
---|
202 | Exit("\n== Err. mov_back failed\n"); |
---|
203 | if(!tree->n_swap) n_neg = 0; |
---|
204 | |
---|
205 | /* For(i,2*tree->n_otu-3) tree->a_edges[i]->l_old->v = tree->a_edges[i]->l->v; */ |
---|
206 | Record_Br_Len(tree); |
---|
207 | Set_Both_Sides(YES,tree); |
---|
208 | Lk(NULL,tree); |
---|
209 | } |
---|
210 | |
---|
211 | if(step > n_step_max) break; |
---|
212 | |
---|
213 | if(tree->io->print_trace) |
---|
214 | { |
---|
215 | char *s = Write_Tree(tree,NO); |
---|
216 | PhyML_Fprintf(tree->io->fp_out_trace,"[%f]%s\n",tree->c_lnL,s); fflush(tree->io->fp_out_trace); |
---|
217 | if(tree->io->print_site_lnl) Print_Site_Lk(tree,tree->io->fp_out_lk); fflush(tree->io->fp_out_lk); |
---|
218 | Free(s); |
---|
219 | } |
---|
220 | |
---|
221 | if((tree->mod->s_opt->print) && (!tree->io->quiet)) Print_Lk(tree,"[Topology ]"); |
---|
222 | |
---|
223 | |
---|
224 | /* if(((tree->c_lnL > old_loglk) && (FABS(old_loglk-tree->c_lnL) < tree->mod->s_opt->min_diff_lk_local)) || (n_without_swap > it_lim_without_swap)) break; */ |
---|
225 | if((FABS(old_loglk-tree->c_lnL) < tree->mod->s_opt->min_diff_lk_global) || (n_without_swap > it_lim_without_swap)) break; |
---|
226 | |
---|
227 | Fill_Dir_Table(tree); |
---|
228 | Fix_All(tree); |
---|
229 | n_neg = 0; |
---|
230 | For(i,2*tree->n_otu-3) |
---|
231 | if((!tree->a_edges[i]->left->tax) && |
---|
232 | (!tree->a_edges[i]->rght->tax)) |
---|
233 | NNI(tree,tree->a_edges[i],0); |
---|
234 | |
---|
235 | |
---|
236 | |
---|
237 | Select_Edges_To_Swap(tree,sorted_b,&n_neg); |
---|
238 | Sort_Edges_NNI_Score(tree,sorted_b,n_neg); |
---|
239 | Optimiz_Ext_Br(tree); |
---|
240 | Update_Bl(tree,lambda); |
---|
241 | |
---|
242 | n_tested = 0; |
---|
243 | For(i,(int)CEIL((phydbl)n_neg*(lambda))) |
---|
244 | tested_b[n_tested++] = sorted_b[i]; |
---|
245 | |
---|
246 | |
---|
247 | Make_N_Swap(tree,tested_b,0,n_tested); |
---|
248 | |
---|
249 | if((tree->mod->s_opt->print) && (!tree->io->quiet)) PhyML_Printf("[# nnis=%3d]",n_tested); |
---|
250 | |
---|
251 | n_tot_swap += n_tested; |
---|
252 | |
---|
253 | if(n_tested > 0) n_without_swap = 0; |
---|
254 | else n_without_swap++; |
---|
255 | |
---|
256 | n_iter+=1.0; |
---|
257 | } |
---|
258 | while(1); |
---|
259 | |
---|
260 | /* Round_Optimize(tree,tree->data); */ |
---|
261 | |
---|
262 | Free(sorted_b); |
---|
263 | Free(tested_b); |
---|
264 | |
---|
265 | return n_tot_swap; |
---|
266 | } |
---|
267 | |
---|
268 | ////////////////////////////////////////////////////////////// |
---|
269 | ////////////////////////////////////////////////////////////// |
---|
270 | |
---|
271 | |
---|
272 | void Simu_Pars(t_tree *tree, int n_step_max) |
---|
273 | { |
---|
274 | phydbl old_pars,n_iter,lambda; |
---|
275 | int i,n_neg,n_tested,n_without_swap,n_tot_swap,step; |
---|
276 | t_edge **sorted_b,**tested_b; |
---|
277 | int each; |
---|
278 | |
---|
279 | sorted_b = (t_edge **)mCalloc(tree->n_otu-3,sizeof(t_edge *)); |
---|
280 | tested_b = (t_edge **)mCalloc(tree->n_otu-3,sizeof(t_edge *)); |
---|
281 | |
---|
282 | old_pars = 0; |
---|
283 | tree->c_pars = 0; |
---|
284 | n_iter = 1.0; |
---|
285 | n_tested = 0; |
---|
286 | n_without_swap = 0; |
---|
287 | step = 0; |
---|
288 | each = 4; |
---|
289 | lambda = .75; |
---|
290 | n_tot_swap = 0; |
---|
291 | |
---|
292 | Update_Dirs(tree); |
---|
293 | |
---|
294 | if((tree->mod->s_opt->print) && (!tree->io->quiet)) PhyML_Printf("\n\n. Starting simultaneous NNI moves (parsimony criterion)...\n"); |
---|
295 | |
---|
296 | do |
---|
297 | { |
---|
298 | ++step; |
---|
299 | |
---|
300 | if(step > n_step_max) break; |
---|
301 | |
---|
302 | each--; |
---|
303 | |
---|
304 | Set_Both_Sides(YES,tree); |
---|
305 | Pars(NULL,tree); |
---|
306 | |
---|
307 | if((tree->mod->s_opt->print) && (!tree->io->quiet)) |
---|
308 | { |
---|
309 | Print_Pars(tree); |
---|
310 | if(step > 1) (n_tested > 1)?(printf("[%4d NNIs]",n_tested)):(printf("[%4d NNI ]",n_tested)); |
---|
311 | } |
---|
312 | |
---|
313 | |
---|
314 | if(FABS(old_pars - tree->c_pars) < SMALL) break; |
---|
315 | |
---|
316 | if((tree->c_pars > old_pars) && (step > 1)) |
---|
317 | { |
---|
318 | if((tree->mod->s_opt->print) && (!tree->io->quiet)) |
---|
319 | PhyML_Printf("\n\n. Moving backward (topoLlogy) \n"); |
---|
320 | if(!Mov_Backward_Topo_Pars(tree,old_pars,tested_b,n_tested)) |
---|
321 | Exit("\n. Err: mov_back failed\n"); |
---|
322 | if(!tree->n_swap) n_neg = 0; |
---|
323 | |
---|
324 | |
---|
325 | Set_Both_Sides(YES,tree); |
---|
326 | Pars(NULL,tree); |
---|
327 | } |
---|
328 | else |
---|
329 | { |
---|
330 | |
---|
331 | old_pars = tree->c_pars; |
---|
332 | Fill_Dir_Table(tree); |
---|
333 | |
---|
334 | n_neg = 0; |
---|
335 | For(i,2*tree->n_otu-3) |
---|
336 | if((!tree->a_edges[i]->left->tax) && |
---|
337 | (!tree->a_edges[i]->rght->tax)) |
---|
338 | NNI_Pars(tree,tree->a_edges[i],NO); |
---|
339 | |
---|
340 | Select_Edges_To_Swap(tree,sorted_b,&n_neg); |
---|
341 | Sort_Edges_NNI_Score(tree,sorted_b,n_neg); |
---|
342 | |
---|
343 | n_tested = 0; |
---|
344 | For(i,(int)CEIL((phydbl)n_neg*(lambda))) |
---|
345 | tested_b[n_tested++] = sorted_b[i]; |
---|
346 | |
---|
347 | Make_N_Swap(tree,tested_b,0,n_tested); |
---|
348 | |
---|
349 | n_tot_swap += n_tested; |
---|
350 | |
---|
351 | if(n_tested > 0) n_without_swap = 0; |
---|
352 | else n_without_swap++; |
---|
353 | } |
---|
354 | n_iter+=1.0; |
---|
355 | } |
---|
356 | while(1); |
---|
357 | |
---|
358 | Free(sorted_b); |
---|
359 | Free(tested_b); |
---|
360 | } |
---|
361 | |
---|
362 | ////////////////////////////////////////////////////////////// |
---|
363 | ////////////////////////////////////////////////////////////// |
---|
364 | |
---|
365 | |
---|
366 | void Select_Edges_To_Swap(t_tree *tree, t_edge **sorted_b, int *n_neg) |
---|
367 | { |
---|
368 | int i; |
---|
369 | t_edge *b; |
---|
370 | phydbl best_score; |
---|
371 | |
---|
372 | *n_neg = 0; |
---|
373 | |
---|
374 | For(i,2*tree->n_otu-3) |
---|
375 | { |
---|
376 | b = tree->a_edges[i]; |
---|
377 | best_score = b->nni->score; |
---|
378 | |
---|
379 | if((!b->left->tax) && (!b->rght->tax) && (b->nni->score < -tree->mod->s_opt->min_diff_lk_move)) |
---|
380 | { |
---|
381 | Check_NNI_Scores_Around(b->left,b->rght,b,&best_score,tree); |
---|
382 | Check_NNI_Scores_Around(b->rght,b->left,b,&best_score,tree); |
---|
383 | if(best_score < b->nni->score) continue; |
---|
384 | sorted_b[*n_neg] = b; |
---|
385 | (*n_neg)++; |
---|
386 | } |
---|
387 | } |
---|
388 | } |
---|
389 | |
---|
390 | ////////////////////////////////////////////////////////////// |
---|
391 | ////////////////////////////////////////////////////////////// |
---|
392 | |
---|
393 | |
---|
394 | void Update_Bl(t_tree *tree, phydbl fact) |
---|
395 | { |
---|
396 | int i; |
---|
397 | t_edge *b,*orig; |
---|
398 | |
---|
399 | For(i,2*tree->n_otu-3) |
---|
400 | { |
---|
401 | b = tree->a_edges[i]; |
---|
402 | /* b->l->v = b->l_old->v + (b->nni->l0 - b->l_old->v)*fact; */ |
---|
403 | |
---|
404 | orig = b; |
---|
405 | do |
---|
406 | { |
---|
407 | b->l->v = b->l_old->v + (b->nni->l0 - b->l_old->v)*fact; |
---|
408 | if(b->next) b = b->next; |
---|
409 | else b = b->next; |
---|
410 | } |
---|
411 | while(b); |
---|
412 | b = orig; |
---|
413 | |
---|
414 | } |
---|
415 | } |
---|
416 | |
---|
417 | ////////////////////////////////////////////////////////////// |
---|
418 | ////////////////////////////////////////////////////////////// |
---|
419 | |
---|
420 | |
---|
421 | void Make_N_Swap(t_tree *tree,t_edge **b, int beg, int end) |
---|
422 | { |
---|
423 | int i; |
---|
424 | int dim; |
---|
425 | t_edge *orig; |
---|
426 | |
---|
427 | dim = 2*tree->n_otu-2; |
---|
428 | |
---|
429 | /* PhyML_Printf("\n. Beg Actually performing swaps\n"); */ |
---|
430 | tree->n_swap = 0; |
---|
431 | for(i=beg;i<end;i++) |
---|
432 | { |
---|
433 | /* we use t_dir here to take into account previous modifications of the topology */ |
---|
434 | /* printf("\n. Swap on edge %d [%d %d %d %d]",b[i]->num, */ |
---|
435 | /* b[i]->nni->swap_node_v2->v[tree->t_dir[b[i]->nni->swap_node_v2->num*dim+b[i]->nni->swap_node_v1->num]]->num, */ |
---|
436 | /* b[i]->nni->swap_node_v2->num, */ |
---|
437 | /* b[i]->nni->swap_node_v3->num, */ |
---|
438 | /* b[i]->nni->swap_node_v3->v[tree->t_dir[b[i]->nni->swap_node_v3->num*dim+b[i]->nni->swap_node_v4->num]]->num); */ |
---|
439 | |
---|
440 | Swap(b[i]->nni->swap_node_v2->v[tree->t_dir[b[i]->nni->swap_node_v2->num*dim+b[i]->nni->swap_node_v1->num]], |
---|
441 | b[i]->nni->swap_node_v2, |
---|
442 | b[i]->nni->swap_node_v3, |
---|
443 | b[i]->nni->swap_node_v3->v[tree->t_dir[b[i]->nni->swap_node_v3->num*dim+b[i]->nni->swap_node_v4->num]], |
---|
444 | tree); |
---|
445 | |
---|
446 | if(!Check_Topo_Constraints(tree,tree->io->cstr_tree)) |
---|
447 | { |
---|
448 | /* Undo this swap as it violates one of the topological constraints |
---|
449 | defined in the input constraint tree |
---|
450 | */ |
---|
451 | Swap(b[i]->nni->swap_node_v2->v[tree->t_dir[b[i]->nni->swap_node_v2->num*dim+b[i]->nni->swap_node_v1->num]], |
---|
452 | b[i]->nni->swap_node_v2, |
---|
453 | b[i]->nni->swap_node_v3, |
---|
454 | b[i]->nni->swap_node_v3->v[tree->t_dir[b[i]->nni->swap_node_v3->num*dim+b[i]->nni->swap_node_v4->num]], |
---|
455 | tree); |
---|
456 | } |
---|
457 | |
---|
458 | if(tree->n_root) |
---|
459 | { |
---|
460 | tree->n_root->v[2] = tree->e_root->left; |
---|
461 | tree->n_root->v[1] = tree->e_root->rght; |
---|
462 | } |
---|
463 | |
---|
464 | orig = b[i]; |
---|
465 | do |
---|
466 | { |
---|
467 | b[i]->l->v = b[i]->nni->best_l; |
---|
468 | if(b[i]->next) b[i] = b[i]->next; |
---|
469 | else b[i] = b[i]->next; |
---|
470 | } |
---|
471 | while(b[i]); |
---|
472 | b[i] = orig; |
---|
473 | |
---|
474 | tree->n_swap++; |
---|
475 | } |
---|
476 | |
---|
477 | |
---|
478 | /* PhyML_Printf("\n. End Actually performing swaps\n"); */ |
---|
479 | |
---|
480 | } |
---|
481 | |
---|
482 | ////////////////////////////////////////////////////////////// |
---|
483 | ////////////////////////////////////////////////////////////// |
---|
484 | |
---|
485 | |
---|
486 | int Make_Best_Swap(t_tree *tree) |
---|
487 | { |
---|
488 | int i,j,return_value; |
---|
489 | t_edge *b,**sorted_b; |
---|
490 | int dim; |
---|
491 | t_edge *orig; |
---|
492 | |
---|
493 | dim = 2*tree->n_otu-2; |
---|
494 | |
---|
495 | sorted_b = (t_edge **)mCalloc(tree->n_otu-3,sizeof(t_edge *)); |
---|
496 | |
---|
497 | j=0; |
---|
498 | For(i,2*tree->n_otu-3) if((!tree->a_edges[i]->left->tax) && |
---|
499 | (!tree->a_edges[i]->rght->tax)) |
---|
500 | sorted_b[j++] = tree->a_edges[i]; |
---|
501 | |
---|
502 | Sort_Edges_NNI_Score(tree,sorted_b,tree->n_otu-3); |
---|
503 | |
---|
504 | if(sorted_b[0]->nni->score < -0.0) |
---|
505 | { |
---|
506 | b = sorted_b[0]; |
---|
507 | return_value = 1; |
---|
508 | |
---|
509 | Swap(b->nni->swap_node_v2->v[tree->t_dir[b->nni->swap_node_v2->num*dim+b->nni->swap_node_v1->num]], |
---|
510 | b->nni->swap_node_v2, |
---|
511 | b->nni->swap_node_v3, |
---|
512 | b->nni->swap_node_v3->v[tree->t_dir[b->nni->swap_node_v3->num*dim+b->nni->swap_node_v4->num]], |
---|
513 | tree); |
---|
514 | |
---|
515 | if(!Check_Topo_Constraints(tree,tree->io->cstr_tree)) |
---|
516 | { |
---|
517 | /* Undo this swap as it violates one of the topological constraints |
---|
518 | defined in the input constraint tree |
---|
519 | */ |
---|
520 | Swap(b->nni->swap_node_v2->v[tree->t_dir[b->nni->swap_node_v2->num*dim+b->nni->swap_node_v1->num]], |
---|
521 | b->nni->swap_node_v2, |
---|
522 | b->nni->swap_node_v3, |
---|
523 | b->nni->swap_node_v3->v[tree->t_dir[b->nni->swap_node_v3->num*dim+b->nni->swap_node_v4->num]], |
---|
524 | tree); |
---|
525 | } |
---|
526 | |
---|
527 | /* b->l->v = b->nni->best_l; */ |
---|
528 | |
---|
529 | orig = b; |
---|
530 | do |
---|
531 | { |
---|
532 | b->l->v = b->nni->best_l; |
---|
533 | if(b->next) b = b->next; |
---|
534 | else b = b->next; |
---|
535 | } |
---|
536 | while(b); |
---|
537 | b = orig; |
---|
538 | |
---|
539 | |
---|
540 | /* (b->nni->best_conf == 1)? */ |
---|
541 | /* (Swap(b->left->v[b->l_v2],b->left,b->rght,b->rght->v[b->r_v1],tree)): */ |
---|
542 | /* (Swap(b->left->v[b->l_v2],b->left,b->rght,b->rght->v[b->r_v2],tree)); */ |
---|
543 | |
---|
544 | /* b->l->v = */ |
---|
545 | /* (b->nni->best_conf == 1)? */ |
---|
546 | /* (b->nni->l1): */ |
---|
547 | /* (b->nni->l2); */ |
---|
548 | |
---|
549 | |
---|
550 | } |
---|
551 | else return_value = 0; |
---|
552 | |
---|
553 | Free(sorted_b); |
---|
554 | |
---|
555 | return return_value; |
---|
556 | } |
---|
557 | |
---|
558 | ////////////////////////////////////////////////////////////// |
---|
559 | ////////////////////////////////////////////////////////////// |
---|
560 | |
---|
561 | |
---|
562 | int Mov_Backward_Topo_Bl(t_tree *tree, phydbl lk_old, t_edge **tested_b, int n_tested) |
---|
563 | { |
---|
564 | phydbl **l_init; |
---|
565 | int i,j,step,beg,end; |
---|
566 | t_edge *b,*orig; |
---|
567 | |
---|
568 | l_init = (phydbl **)mCalloc(2*tree->n_otu-3,sizeof(phydbl *)); |
---|
569 | |
---|
570 | For(i,2*tree->n_otu-3) l_init[i] = MIXT_Get_Lengths_Of_This_Edge(tree->a_edges[i],tree); |
---|
571 | |
---|
572 | step = 2; |
---|
573 | do |
---|
574 | { |
---|
575 | For(i,2*tree->n_otu-3) |
---|
576 | { |
---|
577 | b = tree->a_edges[i]; |
---|
578 | |
---|
579 | /* b->l->v = b->l_old->v + (1./step) * (l_init[i] - b->l_old->v); */ |
---|
580 | |
---|
581 | j = 0; |
---|
582 | orig = b; |
---|
583 | do |
---|
584 | { |
---|
585 | b->l->v = b->l_old->v + (1./step) * (l_init[i][j] - b->l_old->v); |
---|
586 | if(b->next) b = b->next; |
---|
587 | else b = b->next; |
---|
588 | j++; |
---|
589 | } |
---|
590 | while(b); |
---|
591 | b = orig; |
---|
592 | } |
---|
593 | |
---|
594 | beg = (int)FLOOR((phydbl)n_tested/(step-1)); |
---|
595 | end = 0; |
---|
596 | Unswap_N_Branch(tree,tested_b,beg,end); |
---|
597 | beg = 0; |
---|
598 | end = (int)FLOOR((phydbl)n_tested/step); |
---|
599 | Swap_N_Branch(tree,tested_b,beg,end); |
---|
600 | |
---|
601 | if(!end) tree->n_swap = 0; |
---|
602 | |
---|
603 | Set_Both_Sides(NO,tree); |
---|
604 | Lk(NULL,tree); |
---|
605 | |
---|
606 | step++; |
---|
607 | |
---|
608 | }while((tree->c_lnL < lk_old) && (step < 1000)); |
---|
609 | |
---|
610 | |
---|
611 | if(step == 1000) |
---|
612 | { |
---|
613 | if(tree->n_swap) Exit("\n== Err. in Mov_Backward_Topo_Bl (n_swap > 0)\n"); |
---|
614 | |
---|
615 | For(i,2*tree->n_otu-3) |
---|
616 | { |
---|
617 | b = tree->a_edges[i]; |
---|
618 | |
---|
619 | orig = b; |
---|
620 | do |
---|
621 | { |
---|
622 | b->l->v = b->l_old->v; |
---|
623 | if(b->next) b = b->next; |
---|
624 | else b = b->next; |
---|
625 | } |
---|
626 | while(b); |
---|
627 | b = orig; |
---|
628 | } |
---|
629 | |
---|
630 | |
---|
631 | Set_Both_Sides(NO,tree); |
---|
632 | Lk(NULL,tree); |
---|
633 | } |
---|
634 | |
---|
635 | For(i,2*tree->n_otu-3) Free(l_init[i]); |
---|
636 | Free(l_init); |
---|
637 | |
---|
638 | tree->n_swap = 0; |
---|
639 | For(i,2*tree->n_otu-3) |
---|
640 | { |
---|
641 | if(tree->a_edges[i]->nni->score < 0.0) tree->n_swap++; |
---|
642 | tree->a_edges[i]->nni->score = +1.0; |
---|
643 | } |
---|
644 | |
---|
645 | |
---|
646 | if(tree->c_lnL > lk_old) return 1; |
---|
647 | else if((tree->c_lnL > lk_old-tree->mod->s_opt->min_diff_lk_local) && |
---|
648 | (tree->c_lnL < lk_old+tree->mod->s_opt->min_diff_lk_local)) return -1; |
---|
649 | else return 0; |
---|
650 | } |
---|
651 | |
---|
652 | ////////////////////////////////////////////////////////////// |
---|
653 | ////////////////////////////////////////////////////////////// |
---|
654 | |
---|
655 | |
---|
656 | int Mov_Backward_Topo_Pars(t_tree *tree, int pars_old, t_edge **tested_b, int n_tested) |
---|
657 | { |
---|
658 | int i,step,beg,end; |
---|
659 | |
---|
660 | step = 2; |
---|
661 | do |
---|
662 | { |
---|
663 | beg = (int)FLOOR((phydbl)n_tested/(step-1)); |
---|
664 | end = 0; |
---|
665 | Unswap_N_Branch(tree,tested_b,beg,end); |
---|
666 | beg = 0; |
---|
667 | end = (int)FLOOR((phydbl)n_tested/step); |
---|
668 | Swap_N_Branch(tree,tested_b,beg,end); |
---|
669 | |
---|
670 | if(!end) tree->n_swap = 0; |
---|
671 | |
---|
672 | Set_Both_Sides(NO,tree); |
---|
673 | Pars(NULL,tree); |
---|
674 | |
---|
675 | step++; |
---|
676 | |
---|
677 | }while((tree->c_pars > pars_old) && (step < 1000)); |
---|
678 | |
---|
679 | |
---|
680 | if(step == 1000) |
---|
681 | { |
---|
682 | if(tree->n_swap) Exit("\n. Err. in Mov_Backward_Topo_Bl (n_swap > 0)\n"); |
---|
683 | |
---|
684 | Set_Both_Sides(NO,tree); |
---|
685 | Pars(NULL,tree); |
---|
686 | } |
---|
687 | |
---|
688 | tree->n_swap = 0; |
---|
689 | For(i,2*tree->n_otu-3) |
---|
690 | { |
---|
691 | if(tree->a_edges[i]->nni->score < 0.0) tree->n_swap++; |
---|
692 | tree->a_edges[i]->nni->score = +1.0; |
---|
693 | } |
---|
694 | |
---|
695 | |
---|
696 | if(tree->c_pars < pars_old) return 1; |
---|
697 | else if(tree->c_pars == pars_old) return -1; |
---|
698 | else return 0; |
---|
699 | } |
---|
700 | |
---|
701 | ////////////////////////////////////////////////////////////// |
---|
702 | ////////////////////////////////////////////////////////////// |
---|
703 | |
---|
704 | |
---|
705 | void Unswap_N_Branch(t_tree *tree, t_edge **b, int beg, int end) |
---|
706 | { |
---|
707 | int i; |
---|
708 | int dim; |
---|
709 | t_edge *orig; |
---|
710 | |
---|
711 | dim = 2*tree->n_otu-2; |
---|
712 | |
---|
713 | if(end>beg) |
---|
714 | { |
---|
715 | for(i=beg;i<end;i++) |
---|
716 | { |
---|
717 | |
---|
718 | /* PhyML_Printf("MOV BACK UNSWAP Edge %d Swap nodes %d(%d) %d %d %d(%d)\n", */ |
---|
719 | /* b[i]->num, */ |
---|
720 | /* b[i]->nni->swap_node_v2->v[tree->t_dir[b[i]->nni->swap_node_v2->num][b[i]->nni->swap_node_v1->num]]->num, */ |
---|
721 | /* b[i]->nni->swap_node_v4->num, */ |
---|
722 | /* b[i]->nni->swap_node_v2->num, */ |
---|
723 | /* b[i]->nni->swap_node_v3->num, */ |
---|
724 | /* b[i]->nni->swap_node_v3->v[tree->t_dir[b[i]->nni->swap_node_v3->num][b[i]->nni->swap_node_v4->num]]->num, */ |
---|
725 | /* b[i]->nni->swap_node_v1->num */ |
---|
726 | /* ); */ |
---|
727 | |
---|
728 | Swap(b[i]->nni->swap_node_v2->v[tree->t_dir[b[i]->nni->swap_node_v2->num*dim+b[i]->nni->swap_node_v1->num]], |
---|
729 | b[i]->nni->swap_node_v2, |
---|
730 | b[i]->nni->swap_node_v3, |
---|
731 | b[i]->nni->swap_node_v3->v[tree->t_dir[b[i]->nni->swap_node_v3->num*dim+b[i]->nni->swap_node_v4->num]], |
---|
732 | tree); |
---|
733 | |
---|
734 | if(!Check_Topo_Constraints(tree,tree->io->cstr_tree)) |
---|
735 | { |
---|
736 | /* Undo this swap as it violates one of the topological constraints |
---|
737 | defined in the input constraint tree |
---|
738 | */ |
---|
739 | Swap(b[i]->nni->swap_node_v2->v[tree->t_dir[b[i]->nni->swap_node_v2->num*dim+b[i]->nni->swap_node_v1->num]], |
---|
740 | b[i]->nni->swap_node_v2, |
---|
741 | b[i]->nni->swap_node_v3, |
---|
742 | b[i]->nni->swap_node_v3->v[tree->t_dir[b[i]->nni->swap_node_v3->num*dim+b[i]->nni->swap_node_v4->num]], |
---|
743 | tree); |
---|
744 | } |
---|
745 | |
---|
746 | |
---|
747 | /* (b[i]->nni->best_conf == 1)? */ |
---|
748 | /* (Swap(b[i]->left->v[b[i]->l_v2],b[i]->left,b[i]->rght,b[i]->rght->v[b[i]->r_v1],tree)): */ |
---|
749 | /* (Swap(b[i]->left->v[b[i]->l_v2],b[i]->left,b[i]->rght,b[i]->rght->v[b[i]->r_v2],tree)); */ |
---|
750 | |
---|
751 | /* b[i]->l->v = b[i]->l_old->v; */ |
---|
752 | |
---|
753 | |
---|
754 | orig = b[i]; |
---|
755 | do |
---|
756 | { |
---|
757 | b[i]->l->v = b[i]->l_old->v; |
---|
758 | if(b[i]->next) b[i] = b[i]->next; |
---|
759 | else b[i] = b[i]->next; |
---|
760 | } |
---|
761 | while(b[i]); |
---|
762 | b[i] = orig; |
---|
763 | |
---|
764 | } |
---|
765 | } |
---|
766 | else |
---|
767 | { |
---|
768 | for(i=beg-1;i>=end;i--) |
---|
769 | { |
---|
770 | Swap(b[i]->nni->swap_node_v2->v[tree->t_dir[b[i]->nni->swap_node_v2->num*dim+b[i]->nni->swap_node_v1->num]], |
---|
771 | b[i]->nni->swap_node_v2, |
---|
772 | b[i]->nni->swap_node_v3, |
---|
773 | b[i]->nni->swap_node_v3->v[tree->t_dir[b[i]->nni->swap_node_v3->num*dim+b[i]->nni->swap_node_v4->num]], |
---|
774 | tree); |
---|
775 | |
---|
776 | if(!Check_Topo_Constraints(tree,tree->io->cstr_tree)) |
---|
777 | { |
---|
778 | /* Undo this swap as it violates one of the topological constraints |
---|
779 | defined in the input constraint tree |
---|
780 | */ |
---|
781 | Swap(b[i]->nni->swap_node_v2->v[tree->t_dir[b[i]->nni->swap_node_v2->num*dim+b[i]->nni->swap_node_v1->num]], |
---|
782 | b[i]->nni->swap_node_v2, |
---|
783 | b[i]->nni->swap_node_v3, |
---|
784 | b[i]->nni->swap_node_v3->v[tree->t_dir[b[i]->nni->swap_node_v3->num*dim+b[i]->nni->swap_node_v4->num]], |
---|
785 | tree); |
---|
786 | } |
---|
787 | |
---|
788 | |
---|
789 | /* b[i]->l->v = b[i]->l_old->v; */ |
---|
790 | |
---|
791 | orig = b[i]; |
---|
792 | do |
---|
793 | { |
---|
794 | b[i]->l->v = b[i]->l_old->v; |
---|
795 | if(b[i]->next) b[i] = b[i]->next; |
---|
796 | else b[i] = b[i]->next; |
---|
797 | } |
---|
798 | while(b[i]); |
---|
799 | b[i] = orig; |
---|
800 | |
---|
801 | } |
---|
802 | } |
---|
803 | } |
---|
804 | |
---|
805 | ////////////////////////////////////////////////////////////// |
---|
806 | ////////////////////////////////////////////////////////////// |
---|
807 | |
---|
808 | |
---|
809 | void Swap_N_Branch(t_tree *tree,t_edge **b, int beg, int end) |
---|
810 | { |
---|
811 | int i; |
---|
812 | int dim; |
---|
813 | t_edge *orig; |
---|
814 | |
---|
815 | dim = 2*tree->n_otu-2; |
---|
816 | |
---|
817 | if(end>beg) |
---|
818 | { |
---|
819 | for(i=beg;i<end;i++) |
---|
820 | { |
---|
821 | Swap(b[i]->nni->swap_node_v2->v[tree->t_dir[b[i]->nni->swap_node_v2->num*dim+b[i]->nni->swap_node_v1->num]], |
---|
822 | b[i]->nni->swap_node_v2, |
---|
823 | b[i]->nni->swap_node_v3, |
---|
824 | b[i]->nni->swap_node_v3->v[tree->t_dir[b[i]->nni->swap_node_v3->num*dim+b[i]->nni->swap_node_v4->num]], |
---|
825 | tree); |
---|
826 | |
---|
827 | if(!Check_Topo_Constraints(tree,tree->io->cstr_tree)) |
---|
828 | { |
---|
829 | /* Undo this swap as it violates one of the topological constraints |
---|
830 | defined in the input constraint tree |
---|
831 | */ |
---|
832 | Swap(b[i]->nni->swap_node_v2->v[tree->t_dir[b[i]->nni->swap_node_v2->num*dim+b[i]->nni->swap_node_v1->num]], |
---|
833 | b[i]->nni->swap_node_v2, |
---|
834 | b[i]->nni->swap_node_v3, |
---|
835 | b[i]->nni->swap_node_v3->v[tree->t_dir[b[i]->nni->swap_node_v3->num*dim+b[i]->nni->swap_node_v4->num]], |
---|
836 | tree); |
---|
837 | } |
---|
838 | |
---|
839 | /* b[i]->l->v = b[i]->nni->best_l; */ |
---|
840 | |
---|
841 | orig = b[i]; |
---|
842 | do |
---|
843 | { |
---|
844 | b[i]->l->v = b[i]->nni->best_l; |
---|
845 | if(b[i]->next) b[i] = b[i]->next; |
---|
846 | else b[i] = b[i]->next; |
---|
847 | } |
---|
848 | while(b[i]); |
---|
849 | b[i] = orig; |
---|
850 | |
---|
851 | } |
---|
852 | } |
---|
853 | else |
---|
854 | { |
---|
855 | for(i=beg-1;i>=end;i--) |
---|
856 | { |
---|
857 | Swap(b[i]->nni->swap_node_v2->v[tree->t_dir[b[i]->nni->swap_node_v2->num*dim+b[i]->nni->swap_node_v1->num]], |
---|
858 | b[i]->nni->swap_node_v2, |
---|
859 | b[i]->nni->swap_node_v3, |
---|
860 | b[i]->nni->swap_node_v3->v[tree->t_dir[b[i]->nni->swap_node_v3->num*dim+b[i]->nni->swap_node_v4->num]], |
---|
861 | tree); |
---|
862 | |
---|
863 | if(!Check_Topo_Constraints(tree,tree->io->cstr_tree)) |
---|
864 | { |
---|
865 | /* Undo this swap as it violates one of the topological constraints |
---|
866 | defined in the input constraint tree |
---|
867 | */ |
---|
868 | Swap(b[i]->nni->swap_node_v2->v[tree->t_dir[b[i]->nni->swap_node_v2->num*dim+b[i]->nni->swap_node_v1->num]], |
---|
869 | b[i]->nni->swap_node_v2, |
---|
870 | b[i]->nni->swap_node_v3, |
---|
871 | b[i]->nni->swap_node_v3->v[tree->t_dir[b[i]->nni->swap_node_v3->num*dim+b[i]->nni->swap_node_v4->num]], |
---|
872 | tree); |
---|
873 | } |
---|
874 | |
---|
875 | /* b[i]->l->v = b[i]->nni->best_l; */ |
---|
876 | |
---|
877 | orig = b[i]; |
---|
878 | do |
---|
879 | { |
---|
880 | b[i]->l->v = b[i]->nni->best_l; |
---|
881 | if(b[i]->next) b[i] = b[i]->next; |
---|
882 | else b[i] = b[i]->next; |
---|
883 | } |
---|
884 | while(b[i]); |
---|
885 | b[i] = orig; |
---|
886 | |
---|
887 | } |
---|
888 | } |
---|
889 | } |
---|
890 | |
---|
891 | ////////////////////////////////////////////////////////////// |
---|
892 | ////////////////////////////////////////////////////////////// |
---|
893 | |
---|
894 | |
---|
895 | void Check_NNI_Scores_Around(t_node *a, t_node *d, t_edge *b, phydbl *best_score, t_tree *tree) |
---|
896 | { |
---|
897 | |
---|
898 | int i; |
---|
899 | For(i,3) |
---|
900 | { |
---|
901 | if((d->v[i] != a) && (!d->v[i]->tax)) |
---|
902 | { |
---|
903 | if((d->b[i]->nni->score > *best_score-1.E-10) && |
---|
904 | (d->b[i]->nni->score < *best_score+1.E-10)) /* ties */ |
---|
905 | { |
---|
906 | d->b[i]->nni->score = *best_score+1.; |
---|
907 | } |
---|
908 | |
---|
909 | if(d->b[i]->nni->score < *best_score) |
---|
910 | { |
---|
911 | *best_score = d->b[i]->nni->score; |
---|
912 | } |
---|
913 | } |
---|
914 | } |
---|
915 | } |
---|
916 | |
---|
917 | ////////////////////////////////////////////////////////////// |
---|
918 | ////////////////////////////////////////////////////////////// |
---|
919 | |
---|
920 | ////////////////////////////////////////////////////////////// |
---|
921 | ////////////////////////////////////////////////////////////// |
---|
922 | |
---|
923 | ////////////////////////////////////////////////////////////// |
---|
924 | ////////////////////////////////////////////////////////////// |
---|
925 | |
---|
926 | ////////////////////////////////////////////////////////////// |
---|
927 | ////////////////////////////////////////////////////////////// |
---|
928 | |
---|
929 | ////////////////////////////////////////////////////////////// |
---|
930 | ////////////////////////////////////////////////////////////// |
---|
931 | |
---|
932 | ////////////////////////////////////////////////////////////// |
---|
933 | ////////////////////////////////////////////////////////////// |
---|
934 | |
---|
935 | ////////////////////////////////////////////////////////////// |
---|
936 | ////////////////////////////////////////////////////////////// |
---|
937 | |
---|
938 | ////////////////////////////////////////////////////////////// |
---|
939 | ////////////////////////////////////////////////////////////// |
---|
940 | |
---|
941 | ////////////////////////////////////////////////////////////// |
---|
942 | ////////////////////////////////////////////////////////////// |
---|
943 | |
---|
944 | ////////////////////////////////////////////////////////////// |
---|
945 | ////////////////////////////////////////////////////////////// |
---|
946 | |
---|
947 | ////////////////////////////////////////////////////////////// |
---|
948 | ////////////////////////////////////////////////////////////// |
---|
949 | |
---|