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 "models.h" |
---|
14 | |
---|
15 | |
---|
16 | ////////////////////////////////////////////////////////////// |
---|
17 | ////////////////////////////////////////////////////////////// |
---|
18 | |
---|
19 | /* Handle any number of states (>1) */ |
---|
20 | void PMat_JC69(phydbl l, int pos, phydbl *Pij, t_mod *mod) |
---|
21 | { |
---|
22 | int ns; |
---|
23 | int i,j; |
---|
24 | |
---|
25 | ns = mod->ns; |
---|
26 | |
---|
27 | |
---|
28 | For(i,ns) Pij[pos+ ns*i+i] = 1. - ((ns - 1.)/ns)*(1. - EXP(-ns*l/(ns - 1.))); |
---|
29 | For(i,ns-1) |
---|
30 | for(j=i+1;j<ns;j++) |
---|
31 | { |
---|
32 | Pij[pos+ ns*i+j] = (1./ns)*(1. - EXP(-ns*l/(ns - 1.))); |
---|
33 | if(Pij[pos+ns*i+j] < SMALL_PIJ) Pij[pos+ns*i+j] = SMALL_PIJ; |
---|
34 | Pij[pos+ ns*j+i] = Pij[pos+ ns*i+j]; |
---|
35 | } |
---|
36 | } |
---|
37 | |
---|
38 | |
---|
39 | ////////////////////////////////////////////////////////////// |
---|
40 | ////////////////////////////////////////////////////////////// |
---|
41 | |
---|
42 | void PMat_K80(phydbl l, phydbl kappa, int pos, phydbl *Pij) |
---|
43 | { |
---|
44 | phydbl Ts,Tv,e1,e2,aux; |
---|
45 | int i,j; |
---|
46 | /*0 => A*/ |
---|
47 | /*1 => C*/ |
---|
48 | /*2 => G*/ |
---|
49 | /*3 => T*/ |
---|
50 | |
---|
51 | /* Ts -> transition*/ |
---|
52 | /* Tv -> transversion*/ |
---|
53 | |
---|
54 | |
---|
55 | aux = -2*l/(kappa+2); |
---|
56 | e1 = (phydbl)EXP(aux *2); |
---|
57 | |
---|
58 | e2 = (phydbl)EXP(aux *(kappa+1)); |
---|
59 | Tv = .25*(1-e1); |
---|
60 | Ts = .25*(1+e1-2*e2); |
---|
61 | |
---|
62 | Pij[pos+ 4*0+0] = Pij[pos+ 4*1+1] = |
---|
63 | Pij[pos+ 4*2+2] = Pij[pos+ 4*3+3] = 1.-Ts-2.*Tv; |
---|
64 | |
---|
65 | Pij[pos+ 4*0+1] = Pij[pos+ 4*1+0] = Tv; |
---|
66 | Pij[pos+ 4*0+2] = Pij[pos+ 4*2+0] = Ts; |
---|
67 | Pij[pos+ 4*0+3] = Pij[pos+ 4*3+0] = Tv; |
---|
68 | |
---|
69 | Pij[pos+ 4*1+2] = Pij[pos+ 4*2+1] = Tv; |
---|
70 | Pij[pos+ 4*1+3] = Pij[pos+ 4*3+1] = Ts; |
---|
71 | |
---|
72 | Pij[pos+ 4*2+3] = Pij[pos+ 4*3+2] = Tv; |
---|
73 | |
---|
74 | For(i,4) For(j,4) |
---|
75 | if(Pij[pos + 4*i+j] < SMALL_PIJ) Pij[pos + 4*i+j] = SMALL_PIJ; |
---|
76 | |
---|
77 | } |
---|
78 | |
---|
79 | ////////////////////////////////////////////////////////////// |
---|
80 | ////////////////////////////////////////////////////////////// |
---|
81 | |
---|
82 | |
---|
83 | |
---|
84 | void PMat_TN93(phydbl l, t_mod *mod, int pos, phydbl *Pij) |
---|
85 | { |
---|
86 | int i,j; |
---|
87 | phydbl e1,e2,e3; |
---|
88 | phydbl a1t,a2t,bt; |
---|
89 | phydbl A,C,G,T,R,Y; |
---|
90 | phydbl kappa1,kappa2; |
---|
91 | |
---|
92 | A = mod->e_frq->pi->v[0]; C = mod->e_frq->pi->v[1]; G = mod->e_frq->pi->v[2]; T = mod->e_frq->pi->v[3]; |
---|
93 | R = A+G; Y = T+C; |
---|
94 | |
---|
95 | if(mod->kappa->v < .0) mod->kappa->v = 1.0e-5; |
---|
96 | |
---|
97 | if((mod->whichmodel != F84) && (mod->whichmodel != TN93)) mod->lambda->v = 1.; |
---|
98 | else if(mod->whichmodel == F84) |
---|
99 | { |
---|
100 | mod->lambda->v = Get_Lambda_F84(mod->e_frq->pi->v,&mod->kappa->v); |
---|
101 | } |
---|
102 | |
---|
103 | kappa2 = mod->kappa->v*2./(1.+mod->lambda->v); |
---|
104 | kappa1 = kappa2 * mod->lambda->v; |
---|
105 | |
---|
106 | |
---|
107 | bt = l/(2.*(A*G*kappa1+C*T*kappa2+R*Y)); |
---|
108 | |
---|
109 | a1t = kappa1; |
---|
110 | a2t = kappa2; |
---|
111 | a1t*=bt; a2t*=bt; |
---|
112 | |
---|
113 | e1 = (phydbl)EXP(-a1t*R-bt*Y); |
---|
114 | e2 = (phydbl)EXP(-a2t*Y-bt*R); |
---|
115 | e3 = (phydbl)EXP(-bt); |
---|
116 | |
---|
117 | |
---|
118 | /*A->A*/Pij[pos + 4*0+0] = A+Y*A/R*e3+G/R*e1; |
---|
119 | /*A->C*/Pij[pos + 4*0+1] = C*(1-e3); |
---|
120 | /*A->G*/Pij[pos + 4*0+2] = G+Y*G/R*e3-G/R*e1; |
---|
121 | /*A->T*/Pij[pos + 4*0+3] = T*(1-e3); |
---|
122 | |
---|
123 | /*C->A*/Pij[pos + 4*1+0] = A*(1-e3); |
---|
124 | /*C->C*/Pij[pos + 4*1+1] = C+R*C/Y*e3+T/Y*e2; |
---|
125 | /*C->G*/Pij[pos + 4*1+2] = G*(1-e3); |
---|
126 | /*C->T*/Pij[pos + 4*1+3] = T+R*T/Y*e3-T/Y*e2; |
---|
127 | |
---|
128 | /*G->A*/Pij[pos + 4*2+0] = A+Y*A/R*e3-A/R*e1; |
---|
129 | /*G->C*/Pij[pos + 4*2+1] = C*(1-e3); |
---|
130 | /*G->G*/Pij[pos + 4*2+2] = G+Y*G/R*e3+A/R*e1; |
---|
131 | /*G->T*/Pij[pos + 4*2+3] = T*(1-e3); |
---|
132 | |
---|
133 | /*T->A*/Pij[pos + 4*3+0] = A*(1-e3); |
---|
134 | /*T->C*/Pij[pos + 4*3+1] = C+R*C/Y*e3-C/Y*e2; |
---|
135 | /*T->G*/Pij[pos + 4*3+2] = G*(1-e3); |
---|
136 | /*T->T*/Pij[pos + 4*3+3] = T+R*T/Y*e3+C/Y*e2; |
---|
137 | |
---|
138 | For(i,4) For(j,4) |
---|
139 | if(Pij[pos + 4*i+j] < SMALL_PIJ) Pij[pos + 4*i+j] = SMALL_PIJ; |
---|
140 | |
---|
141 | /* /\*A->A*\/(*Pij)[0][0] = A+Y*A/R*e3+G/R*e1; */ |
---|
142 | /* /\*A->C*\/(*Pij)[0][1] = C*(1-e3); */ |
---|
143 | /* /\*A->G*\/(*Pij)[0][2] = G+Y*G/R*e3-G/R*e1; */ |
---|
144 | /* /\*A->T*\/(*Pij)[0][3] = T*(1-e3); */ |
---|
145 | |
---|
146 | /* /\*C->A*\/(*Pij)[1][0] = A*(1-e3); */ |
---|
147 | /* /\*C->C*\/(*Pij)[1][1] = C+R*C/Y*e3+T/Y*e2; */ |
---|
148 | /* /\*C->G*\/(*Pij)[1][2] = G*(1-e3); */ |
---|
149 | /* /\*C->T*\/(*Pij)[1][3] = T+R*T/Y*e3-T/Y*e2; */ |
---|
150 | |
---|
151 | /* /\*G->A*\/(*Pij)[2][0] = A+Y*A/R*e3-A/R*e1; */ |
---|
152 | /* /\*G->C*\/(*Pij)[2][1] = C*(1-e3); */ |
---|
153 | /* /\*G->G*\/(*Pij)[2][2] = G+Y*G/R*e3+A/R*e1; */ |
---|
154 | /* /\*G->T*\/(*Pij)[2][3] = T*(1-e3); */ |
---|
155 | |
---|
156 | /* /\*T->A*\/(*Pij)[3][0] = A*(1-e3); */ |
---|
157 | /* /\*T->C*\/(*Pij)[3][1] = C+R*C/Y*e3-C/Y*e2; */ |
---|
158 | /* /\*T->G*\/(*Pij)[3][2] = G*(1-e3); */ |
---|
159 | /* /\*T->T*\/(*Pij)[3][3] = T+R*T/Y*e3+C/Y*e2; */ |
---|
160 | |
---|
161 | /* For(i,4) For(j,4) */ |
---|
162 | /* if((*Pij)[i][j] < SMALL) (*Pij)[i][j] = SMALL; */ |
---|
163 | |
---|
164 | } |
---|
165 | |
---|
166 | ////////////////////////////////////////////////////////////// |
---|
167 | ////////////////////////////////////////////////////////////// |
---|
168 | |
---|
169 | |
---|
170 | phydbl Get_Lambda_F84(phydbl *pi, phydbl *kappa) |
---|
171 | { |
---|
172 | phydbl A,C,G,T,R,Y,lambda; |
---|
173 | int kappa_has_changed; |
---|
174 | |
---|
175 | A = pi[0]; C = pi[1]; G = pi[2]; T = pi[3]; |
---|
176 | R = A+G; Y = T+C; |
---|
177 | |
---|
178 | if(*kappa < .0) *kappa = 1.0e-5; |
---|
179 | |
---|
180 | kappa_has_changed = NO; |
---|
181 | |
---|
182 | do |
---|
183 | { |
---|
184 | lambda = (Y+(R-Y)/(2.*(*kappa)))/(R-(R-Y)/(2.*(*kappa))); |
---|
185 | |
---|
186 | if(lambda < .0) |
---|
187 | { |
---|
188 | *kappa += *kappa/10.; |
---|
189 | kappa_has_changed = YES; |
---|
190 | } |
---|
191 | }while(lambda < .0); |
---|
192 | |
---|
193 | if(kappa_has_changed) |
---|
194 | { |
---|
195 | PhyML_Printf("\n. WARNING: This transition/transversion ratio\n"); |
---|
196 | PhyML_Printf(" is impossible with these base frequencies!\n"); |
---|
197 | PhyML_Printf(" The ratio is now set to %.3f\n",*kappa); |
---|
198 | } |
---|
199 | |
---|
200 | return lambda; |
---|
201 | } |
---|
202 | |
---|
203 | |
---|
204 | ////////////////////////////////////////////////////////////// |
---|
205 | ////////////////////////////////////////////////////////////// |
---|
206 | |
---|
207 | |
---|
208 | |
---|
209 | /********************************************************************/ |
---|
210 | /* void PMat_Empirical(phydbl l, t_mod *mod, phydbl ***Pij) */ |
---|
211 | /* */ |
---|
212 | /* Computes the substitution probability matrix */ |
---|
213 | /* from the initial substitution rate matrix and frequency vector */ |
---|
214 | /* and one specific branch length */ |
---|
215 | /* */ |
---|
216 | /* input : l , branch length */ |
---|
217 | /* input : mod , choosen model parameters, qmat and pi */ |
---|
218 | /* ouput : Pij , substitution probability matrix */ |
---|
219 | /* */ |
---|
220 | /* matrix P(l) is computed as follows : */ |
---|
221 | /* P(l) = EXP(Q*t) , where : */ |
---|
222 | /* */ |
---|
223 | /* Q = substitution rate matrix = Vr*D*inverse(Vr) , where : */ |
---|
224 | /* */ |
---|
225 | /* Vr = right eigenvector matrix for Q */ |
---|
226 | /* D = diagonal matrix of eigenvalues for Q */ |
---|
227 | /* */ |
---|
228 | /* t = time interval = l / mr , where : */ |
---|
229 | /* */ |
---|
230 | /* mr = mean rate = branch length/time interval */ |
---|
231 | /* = sum(i)(pi[i]*p(i->j)) , where : */ |
---|
232 | /* */ |
---|
233 | /* pi = state frequency vector */ |
---|
234 | /* p(i->j) = subst. probability from i to a different state */ |
---|
235 | /* = -Q[ii] , as sum(j)(Q[ij]) +Q[ii] =0 */ |
---|
236 | /* */ |
---|
237 | /* the Taylor development of EXP(Q*t) gives : */ |
---|
238 | /* P(l) = Vr*EXP(D*t) *inverse(Vr) */ |
---|
239 | /* = Vr*POW(EXP(D/mr),l)*inverse(Vr) */ |
---|
240 | /* */ |
---|
241 | /* for performance we compute only once the following matrixes : */ |
---|
242 | /* Vr, inverse(Vr), EXP(D/mr) */ |
---|
243 | /* thus each time we compute P(l) we only have to : */ |
---|
244 | /* make 20 times the operation POW() */ |
---|
245 | /* make 2 20x20 matrix multiplications , that is : */ |
---|
246 | /* 16000 = 2x20x20x20 times the operation * */ |
---|
247 | /* 16000 = 2x20x20x20 times the operation + */ |
---|
248 | /* which can be reduced to (the central matrix being diagonal) : */ |
---|
249 | /* 8400 = 20x20 + 20x20x20 times the operation * */ |
---|
250 | /* 8000 = 20x20x20 times the operation + */ |
---|
251 | /********************************************************************/ |
---|
252 | |
---|
253 | void PMat_Empirical(phydbl l, t_mod *mod, int pos, phydbl *Pij) |
---|
254 | { |
---|
255 | int n = mod->ns; |
---|
256 | int i, j, k; |
---|
257 | phydbl *U,*V,*R; |
---|
258 | phydbl *expt; |
---|
259 | phydbl *uexpt; |
---|
260 | |
---|
261 | expt = mod->eigen->e_val_im; |
---|
262 | uexpt = mod->eigen->r_e_vect_im; |
---|
263 | U = mod->eigen->r_e_vect; |
---|
264 | V = mod->eigen->l_e_vect; |
---|
265 | R = mod->eigen->e_val; /* exponential of the eigen value matrix */ |
---|
266 | |
---|
267 | For(i,n) For(k,n) Pij[pos+mod->ns*i+k] = .0; |
---|
268 | |
---|
269 | /* compute POW(EXP(D/mr),l) into mat_eDmrl */ |
---|
270 | For(k,n) expt[k] = (phydbl)POW(R[k],l); |
---|
271 | |
---|
272 | /* multiply Vr*POW(EXP(D/mr),l)*Vi into Pij */ |
---|
273 | For (i,n) For (k,n) uexpt[i*n+k] = U[i*n+k] * expt[k]; |
---|
274 | |
---|
275 | For (i,n) |
---|
276 | { |
---|
277 | For (j,n) |
---|
278 | { |
---|
279 | For(k,n) |
---|
280 | { |
---|
281 | Pij[pos+mod->ns*i+j] += (uexpt[i*n+k] * V[k*n+j]); |
---|
282 | } |
---|
283 | /* if(Pij[pos+mod->ns*i+j] < SMALL) Pij[pos+mod->ns*i+j] = SMALL; */ |
---|
284 | if(Pij[pos+mod->ns*i+j] < SMALL_PIJ) Pij[pos+mod->ns*i+j] = SMALL_PIJ; |
---|
285 | } |
---|
286 | |
---|
287 | #ifndef PHYML |
---|
288 | phydbl sum; |
---|
289 | sum = .0; |
---|
290 | For (j,n) sum += Pij[pos+mod->ns*i+j]; |
---|
291 | if((sum > 1.+.0001) || (sum < 1.-.0001)) |
---|
292 | { |
---|
293 | PhyML_Printf("\n"); |
---|
294 | PhyML_Printf("\n. Q\n"); |
---|
295 | For(i,n) { For(j,n) PhyML_Printf("%7.3f ",mod->eigen->q[i*n+j]); PhyML_Printf("\n"); } |
---|
296 | PhyML_Printf("\n. U\n"); |
---|
297 | For(i,n) { For(j,n) PhyML_Printf("%7.3f ",U[i*n+j]); PhyML_Printf("\n"); } |
---|
298 | PhyML_Printf("\n"); |
---|
299 | PhyML_Printf("\n. V\n"); |
---|
300 | For(i,n) { For(j,n) PhyML_Printf("%7.3f ",V[i*n+j]); PhyML_Printf("\n"); } |
---|
301 | PhyML_Printf("\n"); |
---|
302 | PhyML_Printf("\n. Eigen\n"); |
---|
303 | For(i,n) PhyML_Printf("%E ",expt[i]); |
---|
304 | PhyML_Printf("\n"); |
---|
305 | PhyML_Printf("\n. Pij\n"); |
---|
306 | For(i,n) { For (j,n) PhyML_Printf("%f ",Pij[pos+mod->ns*i+j]); PhyML_Printf("\n"); } |
---|
307 | PhyML_Printf("\n. sum = %f",sum); |
---|
308 | if(mod->m4mod) |
---|
309 | { |
---|
310 | int i; |
---|
311 | PhyML_Printf("\n. mod->m4mod->alpha = %f",mod->m4mod->alpha); |
---|
312 | PhyML_Printf("\n. mod->m4mod->delta = %f",mod->m4mod->delta); |
---|
313 | For(i,mod->m4mod->n_h) |
---|
314 | { |
---|
315 | PhyML_Printf("\n. mod->m4mod->multipl[%d] = %f",i,mod->m4mod->multipl[i]); |
---|
316 | } |
---|
317 | } |
---|
318 | PhyML_Printf("\n. l=%f",l); |
---|
319 | PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); |
---|
320 | Warn_And_Exit(""); |
---|
321 | } |
---|
322 | #endif |
---|
323 | } |
---|
324 | } |
---|
325 | |
---|
326 | ////////////////////////////////////////////////////////////// |
---|
327 | ////////////////////////////////////////////////////////////// |
---|
328 | |
---|
329 | |
---|
330 | void PMat_Gamma(phydbl l, t_mod *mod, int pos, phydbl *Pij) |
---|
331 | { |
---|
332 | int n; |
---|
333 | int i, j, k; |
---|
334 | phydbl *U,*V,*R; |
---|
335 | phydbl *expt; |
---|
336 | phydbl *uexpt; |
---|
337 | phydbl shape; |
---|
338 | |
---|
339 | |
---|
340 | n = mod->ns; |
---|
341 | expt = mod->eigen->e_val_im; |
---|
342 | uexpt = mod->eigen->r_e_vect_im; |
---|
343 | U = mod->eigen->r_e_vect; |
---|
344 | V = mod->eigen->l_e_vect; |
---|
345 | R = mod->eigen->e_val; /* exponential of the eigen value matrix */ |
---|
346 | |
---|
347 | if(mod->ras->n_catg == 1) shape = 1.E+4; |
---|
348 | else shape = mod->ras->alpha->v; |
---|
349 | |
---|
350 | |
---|
351 | For(i,n) For(k,n) Pij[pos+mod->ns*i+k] = .0; |
---|
352 | |
---|
353 | if(shape < 1.E-10) |
---|
354 | { |
---|
355 | PhyML_Printf("\n== Err in file %s at line %d\n\n",__FILE__,__LINE__); |
---|
356 | Warn_And_Exit(""); |
---|
357 | } |
---|
358 | |
---|
359 | /* Formula 13.42, page 220 of Felsenstein's book ``Inferring Phylogenies'' */ |
---|
360 | For(k,n) expt[k] = POW(shape/(shape-LOG(R[k])*l),shape); |
---|
361 | |
---|
362 | /* multiply Vr*expt*Vi into Pij */ |
---|
363 | For(i,n) For(k,n) uexpt[i*n+k] = U[i*n+k] * expt[k]; |
---|
364 | |
---|
365 | For (i,n) |
---|
366 | { |
---|
367 | For (j,n) |
---|
368 | { |
---|
369 | For(k,n) |
---|
370 | { |
---|
371 | Pij[pos+mod->ns*i+j] += (uexpt[i*n+k] * V[k*n+j]); |
---|
372 | } |
---|
373 | if(Pij[pos+mod->ns*i+j] < SMALL_PIJ) Pij[pos+mod->ns*i+j] = SMALL_PIJ; |
---|
374 | } |
---|
375 | |
---|
376 | #ifdef DEBUG |
---|
377 | phydbl sum; |
---|
378 | sum = .0; |
---|
379 | For (j,n) sum += Pij[pos+mod->ns*i+j]; |
---|
380 | if((sum > 1.+.0001) || (sum < 1.-.0001)) |
---|
381 | { |
---|
382 | PhyML_Printf("\n"); |
---|
383 | PhyML_Printf("\n. Q\n"); |
---|
384 | For(i,n) { For(j,n) PhyML_Printf("%7.3f ",mod->eigen->q[i*n+j]); PhyML_Printf("\n"); } |
---|
385 | PhyML_Printf("\n. U\n"); |
---|
386 | For(i,n) { For(j,n) PhyML_Printf("%7.3f ",U[i*n+j]); PhyML_Printf("\n"); } |
---|
387 | PhyML_Printf("\n"); |
---|
388 | PhyML_Printf("\n. V\n"); |
---|
389 | For(i,n) { For(j,n) PhyML_Printf("%7.3f ",V[i*n+j]); PhyML_Printf("\n"); } |
---|
390 | PhyML_Printf("\n"); |
---|
391 | PhyML_Printf("\n. Eigen\n"); |
---|
392 | For(i,n) PhyML_Printf("%E ",expt[i]); |
---|
393 | PhyML_Printf("\n"); |
---|
394 | PhyML_Printf("\n. Pij\n"); |
---|
395 | For(i,n) { For (j,n) PhyML_Printf("%f ",Pij[pos+mod->ns*i+j]); PhyML_Printf("\n"); } |
---|
396 | PhyML_Printf("\n. sum = %f",sum); |
---|
397 | if(mod->m4mod) |
---|
398 | { |
---|
399 | int i; |
---|
400 | PhyML_Printf("\n. mod->m4mod->ras->alpha = %f",mod->m4mod->alpha); |
---|
401 | PhyML_Printf("\n. mod->m4mod->delta = %f",mod->m4mod->delta); |
---|
402 | For(i,mod->m4mod->n_h) |
---|
403 | { |
---|
404 | PhyML_Printf("\n. mod->m4mod->multipl[%d] = %f",i,mod->m4mod->multipl[i]); |
---|
405 | } |
---|
406 | } |
---|
407 | PhyML_Printf("\n. l=%f",l); |
---|
408 | PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); |
---|
409 | Warn_And_Exit(""); |
---|
410 | } |
---|
411 | #endif |
---|
412 | } |
---|
413 | } |
---|
414 | |
---|
415 | ////////////////////////////////////////////////////////////// |
---|
416 | ////////////////////////////////////////////////////////////// |
---|
417 | |
---|
418 | |
---|
419 | void PMat_Zero_Br_Len(t_mod *mod, int pos, phydbl *Pij) |
---|
420 | { |
---|
421 | int n = mod->ns; |
---|
422 | int i, j; |
---|
423 | |
---|
424 | For (i,n) For (j,n) Pij[pos+mod->ns*i+j] = .0; |
---|
425 | For (i,n) Pij[pos+mod->ns*i+i] = 1.0; |
---|
426 | |
---|
427 | } |
---|
428 | |
---|
429 | ////////////////////////////////////////////////////////////// |
---|
430 | ////////////////////////////////////////////////////////////// |
---|
431 | |
---|
432 | |
---|
433 | void PMat(phydbl l, t_mod *mod, int pos, phydbl *Pij) |
---|
434 | { |
---|
435 | /* Warning: l is never the og of branch length here */ |
---|
436 | if(l < 0.0) |
---|
437 | { |
---|
438 | PMat_Zero_Br_Len(mod,pos,Pij); |
---|
439 | } |
---|
440 | else |
---|
441 | { |
---|
442 | switch(mod->io->datatype) |
---|
443 | { |
---|
444 | case NT : |
---|
445 | { |
---|
446 | if(mod->use_m4mod) |
---|
447 | { |
---|
448 | PMat_Empirical(l,mod,pos,Pij); |
---|
449 | } |
---|
450 | else |
---|
451 | { |
---|
452 | if((mod->whichmodel == JC69) || |
---|
453 | (mod->whichmodel == K80)) |
---|
454 | { |
---|
455 | /* PMat_JC69(l,pos,Pij,mod); */ |
---|
456 | PMat_K80(l,mod->kappa->v,pos,Pij); |
---|
457 | } |
---|
458 | else |
---|
459 | { |
---|
460 | if( |
---|
461 | (mod->whichmodel == F81) || |
---|
462 | (mod->whichmodel == HKY85) || |
---|
463 | (mod->whichmodel == F84) || |
---|
464 | (mod->whichmodel == TN93)) |
---|
465 | { |
---|
466 | PMat_TN93(l,mod,pos,Pij); |
---|
467 | } |
---|
468 | else |
---|
469 | { |
---|
470 | PMat_Empirical(l,mod,pos,Pij); |
---|
471 | } |
---|
472 | } |
---|
473 | break; |
---|
474 | } |
---|
475 | case AA : |
---|
476 | { |
---|
477 | PMat_Empirical(l,mod,pos,Pij); |
---|
478 | break; |
---|
479 | } |
---|
480 | default: |
---|
481 | { |
---|
482 | PMat_JC69(l,pos,Pij,mod); |
---|
483 | break; |
---|
484 | /* PhyML_Printf("\n. Not implemented yet.\n"); */ |
---|
485 | /* PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); */ |
---|
486 | /* Warn_And_Exit(""); */ |
---|
487 | /* break; */ |
---|
488 | } |
---|
489 | } |
---|
490 | } |
---|
491 | } |
---|
492 | } |
---|
493 | |
---|
494 | ////////////////////////////////////////////////////////////// |
---|
495 | ////////////////////////////////////////////////////////////// |
---|
496 | |
---|
497 | |
---|
498 | int GetDaa (phydbl *daa, phydbl *pi, char *file_name) |
---|
499 | { |
---|
500 | /* Get the amino acid distance (or substitution rate) matrix |
---|
501 | (grantham, dayhoff, jones, etc). |
---|
502 | */ |
---|
503 | FILE * fdaa; |
---|
504 | int i,j, naa; |
---|
505 | phydbl dmax,dmin; |
---|
506 | phydbl sum; |
---|
507 | double val; |
---|
508 | |
---|
509 | naa = 20; |
---|
510 | dmax = .0; |
---|
511 | dmin = 1.E+40; |
---|
512 | |
---|
513 | fdaa = (FILE *)Openfile(file_name,0); |
---|
514 | |
---|
515 | for(i=0; i<naa; i++) |
---|
516 | for(j=0; j<i; j++) |
---|
517 | { |
---|
518 | /* if(fscanf(fdaa, "%lf", &daa[i*naa+j])) Exit("\n. err aaRatefile"); */ |
---|
519 | if(fscanf(fdaa, "%lf", &val)) Exit("\n. err aaRatefile"); |
---|
520 | daa[i*naa+j] = (phydbl)val; |
---|
521 | daa[j*naa+i]=daa[i*naa+j]; |
---|
522 | if (dmax<daa[i*naa+j]) dmax=daa[i*naa+j]; |
---|
523 | if (dmin>daa[i*naa+j]) dmin=daa[i*naa+j]; |
---|
524 | } |
---|
525 | |
---|
526 | For(i,naa) |
---|
527 | { |
---|
528 | /* if(fscanf(fdaa,"%lf",&pi[i])!=1) Exit("\n. err aaRatefile"); */ |
---|
529 | if(fscanf(fdaa,"%lf",&val)!=1) Exit("\n. err aaRatefile"); |
---|
530 | pi[i] = (phydbl)val; |
---|
531 | } |
---|
532 | sum = 0.0; |
---|
533 | For(i, naa) sum += pi[i]; |
---|
534 | if (FABS(1-sum)>1e-4) { |
---|
535 | PhyML_Printf("\nSum of freq. = %.6f != 1 in aaRateFile\n",sum); |
---|
536 | exit(-1); |
---|
537 | } |
---|
538 | |
---|
539 | fclose (fdaa); |
---|
540 | |
---|
541 | return (0); |
---|
542 | } |
---|
543 | |
---|
544 | ////////////////////////////////////////////////////////////// |
---|
545 | ////////////////////////////////////////////////////////////// |
---|
546 | |
---|
547 | |
---|
548 | void Update_Qmat_Generic(phydbl *rr, phydbl *pi, int ns, phydbl *qmat) |
---|
549 | { |
---|
550 | int i,j; |
---|
551 | phydbl sum,mr; |
---|
552 | |
---|
553 | For(i,ns*ns) qmat[i] = .0; |
---|
554 | |
---|
555 | if(rr[(int)(ns*(ns-1)/2)-1] < 0.00001) |
---|
556 | { |
---|
557 | PhyML_Printf("\n== rr[%d]=%f",(int)(ns*(ns-1)/2)-1,rr[(int)(ns*(ns-1)/2)-1]); |
---|
558 | PhyML_Printf("\n== Err in file %s at line %d\n\n",__FILE__,__LINE__); |
---|
559 | Warn_And_Exit(""); |
---|
560 | } |
---|
561 | |
---|
562 | /* PhyML_Printf("\n"); */ |
---|
563 | /* For(i,(int)(ns*(ns-1)/2)) */ |
---|
564 | /* { */ |
---|
565 | /* PhyML_Printf("\n> rr %d = %f",i,rr[i]); */ |
---|
566 | /* } */ |
---|
567 | |
---|
568 | For(i,(int)(ns*(ns-1)/2)) |
---|
569 | { |
---|
570 | rr[i] /= rr[(int)(ns*(ns-1)/2)-1]; |
---|
571 | } |
---|
572 | |
---|
573 | /* Fill the non-diagonal parts */ |
---|
574 | For(i,ns) |
---|
575 | { |
---|
576 | for(j=i+1;j<ns;j++) |
---|
577 | { |
---|
578 | qmat[i*ns+j] = rr[MIN(i,j) * ns + MAX(i,j) - |
---|
579 | (MIN(i,j)+1+(int)POW(MIN(i,j)+1,2))/2]; |
---|
580 | qmat[j*ns+i] = qmat[i*ns+j]; |
---|
581 | } |
---|
582 | } |
---|
583 | |
---|
584 | |
---|
585 | /* Multiply by pi */ |
---|
586 | For(i,ns) |
---|
587 | { |
---|
588 | For(j,ns) |
---|
589 | { |
---|
590 | qmat[i*ns+j] *= pi[j]; |
---|
591 | } |
---|
592 | } |
---|
593 | |
---|
594 | /* Compute diagonal elements */ |
---|
595 | mr = .0; |
---|
596 | For(i,ns) |
---|
597 | { |
---|
598 | sum = .0; |
---|
599 | For(j,ns) {sum += qmat[i*ns+j];} |
---|
600 | qmat[i*ns+i] = -sum; |
---|
601 | mr += sum * pi[i]; |
---|
602 | } |
---|
603 | |
---|
604 | /* For(i,ns) For(j,ns) qmat[i*ns+j] /= mr; */ |
---|
605 | } |
---|
606 | |
---|
607 | ////////////////////////////////////////////////////////////// |
---|
608 | ////////////////////////////////////////////////////////////// |
---|
609 | |
---|
610 | |
---|
611 | void Update_Qmat_GTR(phydbl *rr, phydbl *rr_val, int *rr_num, phydbl *pi, phydbl *qmat) |
---|
612 | { |
---|
613 | int i; |
---|
614 | phydbl mr; |
---|
615 | |
---|
616 | For(i,6) rr[i] = rr_val[rr_num[i]]; |
---|
617 | For(i,6) |
---|
618 | if(rr[i] < 0.0) |
---|
619 | { |
---|
620 | PhyML_Printf("\n. rr%d: %f",i,rr[i]); |
---|
621 | PhyML_Printf("\n. Err. in file %s at line %d\n\n",__FILE__,__LINE__); |
---|
622 | Exit(""); |
---|
623 | } |
---|
624 | |
---|
625 | |
---|
626 | For(i,6) rr[i] /= rr[5]; |
---|
627 | |
---|
628 | qmat[0*4+1] = (rr[0]*pi[1]); |
---|
629 | qmat[0*4+2] = (rr[1]*pi[2]); |
---|
630 | qmat[0*4+3] = (rr[2]*pi[3]); |
---|
631 | |
---|
632 | qmat[1*4+0] = (rr[0]*pi[0]); |
---|
633 | qmat[1*4+2] = (rr[3]*pi[2]); |
---|
634 | qmat[1*4+3] = (rr[4]*pi[3]); |
---|
635 | |
---|
636 | qmat[2*4+0] = (rr[1]*pi[0]); |
---|
637 | qmat[2*4+1] = (rr[3]*pi[1]); |
---|
638 | qmat[2*4+3] = (rr[5]*pi[3]); |
---|
639 | |
---|
640 | qmat[3*4+0] = (rr[2]*pi[0]); |
---|
641 | qmat[3*4+1] = (rr[4]*pi[1]); |
---|
642 | qmat[3*4+2] = (rr[5]*pi[2]); |
---|
643 | |
---|
644 | qmat[0*4+0] = -(rr[0]*pi[1]+rr[1]*pi[2]+rr[2]*pi[3]); |
---|
645 | qmat[1*4+1] = -(rr[0]*pi[0]+rr[3]*pi[2]+rr[4]*pi[3]); |
---|
646 | qmat[2*4+2] = -(rr[1]*pi[0]+rr[3]*pi[1]+rr[5]*pi[3]); |
---|
647 | qmat[3*4+3] = -(rr[2]*pi[0]+rr[4]*pi[1]+rr[5]*pi[2]); |
---|
648 | |
---|
649 | /* compute diagonal terms of Q and mean rate mr = l/t */ |
---|
650 | mr = .0; |
---|
651 | For (i,4) mr += pi[i] * (-qmat[i*4+i]); |
---|
652 | For(i,16) qmat[i] /= mr; |
---|
653 | |
---|
654 | /* int j; */ |
---|
655 | /* printf("\n"); */ |
---|
656 | /* printf("\n. rr -- "); */ |
---|
657 | /* For(i,5) printf(" %15f ",rr[i]); */ |
---|
658 | /* printf("\n"); */ |
---|
659 | /* For(i,4) */ |
---|
660 | /* { */ |
---|
661 | /* printf("\n. [%15f] \t ",pi[i]); */ |
---|
662 | /* For(j,4) */ |
---|
663 | /* { */ |
---|
664 | /* printf(" %15f ",qmat[i*4+j]); */ |
---|
665 | /* } */ |
---|
666 | /* } */ |
---|
667 | } |
---|
668 | |
---|
669 | ////////////////////////////////////////////////////////////// |
---|
670 | ////////////////////////////////////////////////////////////// |
---|
671 | |
---|
672 | |
---|
673 | void Update_Qmat_HKY(phydbl kappa, phydbl *pi, phydbl *qmat) |
---|
674 | { |
---|
675 | int i; |
---|
676 | phydbl mr; |
---|
677 | |
---|
678 | /* A -> C */ qmat[0*4+1] = (phydbl)(pi[1]); |
---|
679 | /* A -> G */ qmat[0*4+2] = (phydbl)(kappa*pi[2]); |
---|
680 | /* A -> T */ qmat[0*4+3] = (phydbl)(pi[3]); |
---|
681 | |
---|
682 | /* C -> A */ qmat[1*4+0] = (phydbl)(pi[0]); |
---|
683 | /* C -> G */ qmat[1*4+2] = (phydbl)(pi[2]); |
---|
684 | /* C -> T */ qmat[1*4+3] = (phydbl)(kappa*pi[3]); |
---|
685 | |
---|
686 | /* G -> A */ qmat[2*4+0] = (phydbl)(kappa*pi[0]); |
---|
687 | /* G -> C */ qmat[2*4+1] = (phydbl)(pi[1]); |
---|
688 | /* G -> T */ qmat[2*4+3] = (phydbl)(pi[3]); |
---|
689 | |
---|
690 | /* T -> A */ qmat[3*4+0] = (phydbl)(pi[0]); |
---|
691 | /* T -> C */ qmat[3*4+1] = (phydbl)(kappa*pi[1]); |
---|
692 | /* T -> G */ qmat[3*4+2] = (phydbl)(pi[2]); |
---|
693 | |
---|
694 | qmat[0*4+0] = (phydbl)(-(qmat[0*4+1]+qmat[0*4+2]+qmat[0*4+3])); |
---|
695 | qmat[1*4+1] = (phydbl)(-(qmat[1*4+0]+qmat[1*4+2]+qmat[1*4+3])); |
---|
696 | qmat[2*4+2] = (phydbl)(-(qmat[2*4+0]+qmat[2*4+1]+qmat[2*4+3])); |
---|
697 | qmat[3*4+3] = (phydbl)(-(qmat[3*4+0]+qmat[3*4+1]+qmat[3*4+2])); |
---|
698 | |
---|
699 | /* compute diagonal terms of Q and mean rate mr = l/t */ |
---|
700 | mr = .0; |
---|
701 | For (i,4) mr += pi[i] * (-qmat[i*4+i]); |
---|
702 | For(i,16) qmat[i] /= mr; |
---|
703 | } |
---|
704 | |
---|
705 | ////////////////////////////////////////////////////////////// |
---|
706 | ////////////////////////////////////////////////////////////// |
---|
707 | |
---|
708 | |
---|
709 | void Translate_Custom_Mod_String(t_mod *mod) |
---|
710 | { |
---|
711 | int i,j; |
---|
712 | |
---|
713 | For(i,6) mod->r_mat->n_rr_per_cat->v[i] = 0; |
---|
714 | |
---|
715 | mod->r_mat->n_diff_rr = 0; |
---|
716 | |
---|
717 | For(i,6) |
---|
718 | { |
---|
719 | For(j,i) |
---|
720 | { |
---|
721 | if((mod->custom_mod_string->s[i] == mod->custom_mod_string->s[j])) |
---|
722 | { |
---|
723 | break; |
---|
724 | } |
---|
725 | } |
---|
726 | |
---|
727 | if(i == j) |
---|
728 | { |
---|
729 | mod->r_mat->rr_num->v[i] = mod->r_mat->n_diff_rr; |
---|
730 | mod->r_mat->n_diff_rr++; |
---|
731 | } |
---|
732 | else |
---|
733 | { |
---|
734 | mod->r_mat->rr_num->v[i] = mod->r_mat->rr_num->v[j]; |
---|
735 | } |
---|
736 | |
---|
737 | mod->r_mat->n_rr_per_cat->v[mod->r_mat->rr_num->v[j]]++; |
---|
738 | } |
---|
739 | |
---|
740 | /* PhyML_Printf("\n"); */ |
---|
741 | /* For(i,6) PhyML_Printf("%d ",mod->rr_param_num[i]); */ |
---|
742 | /* For(i,mod->n_diff_rr_param) PhyML_Printf("\n. Class %d size %d",i+1,mod->r_mat->n_rr_param_per_cat[i]); */ |
---|
743 | } |
---|
744 | |
---|
745 | ////////////////////////////////////////////////////////////// |
---|
746 | ////////////////////////////////////////////////////////////// |
---|
747 | |
---|
748 | // Update rate across sites distribution settings. |
---|
749 | |
---|
750 | void Update_RAS(t_mod *mod) |
---|
751 | { |
---|
752 | phydbl sum; |
---|
753 | int i; |
---|
754 | |
---|
755 | if(mod->ras->free_mixt_rates == NO) DiscreteGamma(mod->ras->gamma_r_proba->v, |
---|
756 | mod->ras->gamma_rr->v, |
---|
757 | mod->ras->alpha->v, |
---|
758 | mod->ras->alpha->v, |
---|
759 | mod->ras->n_catg, |
---|
760 | mod->ras->gamma_median); |
---|
761 | else |
---|
762 | { |
---|
763 | |
---|
764 | #if (!defined PHYML) |
---|
765 | |
---|
766 | Qksort(mod->ras->gamma_r_proba_unscaled->v,NULL,0,mod->ras->n_catg-1); // Unscaled class frequencies sorted in increasing order |
---|
767 | |
---|
768 | // Update class frequencies |
---|
769 | For(i,mod->ras->n_catg) |
---|
770 | { |
---|
771 | if(!i) |
---|
772 | mod->ras->gamma_r_proba->v[i] = |
---|
773 | mod->ras->gamma_r_proba_unscaled->v[i] / (mod->ras->gamma_r_proba_unscaled->v[mod->ras->n_catg-1]); |
---|
774 | else |
---|
775 | mod->ras->gamma_r_proba->v[i] = |
---|
776 | (mod->ras->gamma_r_proba_unscaled->v[i] - mod->ras->gamma_r_proba_unscaled->v[i-1]) / |
---|
777 | (mod->ras->gamma_r_proba_unscaled->v[mod->ras->n_catg-1]) ; |
---|
778 | } |
---|
779 | |
---|
780 | #else |
---|
781 | |
---|
782 | sum = 0.0; |
---|
783 | For(i,mod->ras->n_catg) sum += mod->ras->gamma_r_proba_unscaled->v[i]; |
---|
784 | For(i,mod->ras->n_catg) mod->ras->gamma_r_proba->v[i] = mod->ras->gamma_r_proba_unscaled->v[i] / sum; |
---|
785 | |
---|
786 | |
---|
787 | #endif |
---|
788 | |
---|
789 | do |
---|
790 | { |
---|
791 | sum = .0; |
---|
792 | For(i,mod->ras->n_catg) |
---|
793 | { |
---|
794 | if(mod->ras->gamma_r_proba->v[i] < 0.01) mod->ras->gamma_r_proba->v[i]=0.01; |
---|
795 | if(mod->ras->gamma_r_proba->v[i] > 0.99) mod->ras->gamma_r_proba->v[i]=0.99; |
---|
796 | sum += mod->ras->gamma_r_proba->v[i]; |
---|
797 | } |
---|
798 | For(i,mod->ras->n_catg) mod->ras->gamma_r_proba->v[i]/=sum; |
---|
799 | } |
---|
800 | while((sum > 1.01) || (sum < 0.99)); |
---|
801 | |
---|
802 | |
---|
803 | // Update class rates |
---|
804 | sum = .0; |
---|
805 | For(i,mod->ras->n_catg) sum += mod->ras->gamma_r_proba->v[i] * mod->ras->gamma_rr_unscaled->v[i]; |
---|
806 | |
---|
807 | if(mod->ras->normalise_rr == YES) |
---|
808 | For(i,mod->ras->n_catg) |
---|
809 | mod->ras->gamma_rr->v[i] = mod->ras->gamma_rr_unscaled->v[i]/sum; |
---|
810 | else |
---|
811 | For(i,mod->ras->n_catg) |
---|
812 | mod->ras->gamma_rr->v[i] = mod->ras->gamma_rr_unscaled->v[i] * mod->ras->free_rate_mr->v; |
---|
813 | |
---|
814 | /* printf("\n"); */ |
---|
815 | /* For(i,mod->ras->n_catg) */ |
---|
816 | /* printf("\nx %12f %12f xx %12f %12f", */ |
---|
817 | /* mod->ras->gamma_r_proba->v[i], */ |
---|
818 | /* mod->ras->gamma_rr->v[i], */ |
---|
819 | /* mod->ras->gamma_r_proba_unscaled->v[i], */ |
---|
820 | /* mod->ras->gamma_rr_unscaled->v[i]); */ |
---|
821 | } |
---|
822 | |
---|
823 | } |
---|
824 | |
---|
825 | ////////////////////////////////////////////////////////////// |
---|
826 | ////////////////////////////////////////////////////////////// |
---|
827 | |
---|
828 | void Update_Efrq(t_mod *mod) |
---|
829 | { |
---|
830 | phydbl sum; |
---|
831 | int i; |
---|
832 | |
---|
833 | if((mod->io->datatype == NT) && (mod->s_opt->opt_state_freq)) |
---|
834 | { |
---|
835 | sum = .0; |
---|
836 | For(i,mod->ns) sum += FABS(mod->e_frq->pi_unscaled->v[i]); |
---|
837 | For(i,mod->ns) mod->e_frq->pi->v[i] = FABS(mod->e_frq->pi_unscaled->v[i])/sum; |
---|
838 | |
---|
839 | do |
---|
840 | { |
---|
841 | sum = .0; |
---|
842 | For(i,mod->ns) |
---|
843 | { |
---|
844 | if(mod->e_frq->pi->v[i] < 0.01) mod->e_frq->pi->v[i]=0.01; |
---|
845 | if(mod->e_frq->pi->v[i] > 0.99) mod->e_frq->pi->v[i]=0.99; |
---|
846 | sum += mod->e_frq->pi->v[i]; |
---|
847 | } |
---|
848 | For(i,mod->ns) mod->e_frq->pi->v[i]/=sum; |
---|
849 | } |
---|
850 | while((sum > 1.01) || (sum < 0.99)); |
---|
851 | } |
---|
852 | |
---|
853 | |
---|
854 | |
---|
855 | } |
---|
856 | |
---|
857 | ////////////////////////////////////////////////////////////// |
---|
858 | ////////////////////////////////////////////////////////////// |
---|
859 | |
---|
860 | void Set_Model_Parameters(t_mod *mod) |
---|
861 | { |
---|
862 | Update_RAS(mod); |
---|
863 | Update_Efrq(mod); |
---|
864 | Update_Eigen(mod); |
---|
865 | } |
---|
866 | |
---|
867 | ////////////////////////////////////////////////////////////// |
---|
868 | ////////////////////////////////////////////////////////////// |
---|
869 | |
---|
870 | void Update_Eigen(t_mod *mod) |
---|
871 | { |
---|
872 | int result, n_iter; |
---|
873 | phydbl scalar; |
---|
874 | int i; |
---|
875 | |
---|
876 | |
---|
877 | if(mod->is_mixt_mod) |
---|
878 | { |
---|
879 | MIXT_Update_Eigen(mod); |
---|
880 | return; |
---|
881 | } |
---|
882 | |
---|
883 | if(mod->update_eigen) |
---|
884 | { |
---|
885 | if(mod->use_m4mod == NO) |
---|
886 | { |
---|
887 | if(mod->io->datatype == NT) |
---|
888 | { |
---|
889 | if(mod->whichmodel == GTR) |
---|
890 | Update_Qmat_GTR(mod->r_mat->rr->v, mod->r_mat->rr_val->v, mod->r_mat->rr_num->v, mod->e_frq->pi->v, mod->r_mat->qmat->v); |
---|
891 | else if(mod->whichmodel == CUSTOM) |
---|
892 | Update_Qmat_GTR(mod->r_mat->rr->v, mod->r_mat->rr_val->v, mod->r_mat->rr_num->v, mod->e_frq->pi->v, mod->r_mat->qmat->v); |
---|
893 | else if(mod->whichmodel == HKY85) |
---|
894 | Update_Qmat_HKY(mod->kappa->v, mod->e_frq->pi->v, mod->r_mat->qmat->v); |
---|
895 | else /* Any other nucleotide-based t_mod */ |
---|
896 | Update_Qmat_HKY(mod->kappa->v, mod->e_frq->pi->v, mod->r_mat->qmat->v); |
---|
897 | } |
---|
898 | } |
---|
899 | else |
---|
900 | { |
---|
901 | M4_Update_Qmat(mod->m4mod,mod); |
---|
902 | } |
---|
903 | |
---|
904 | scalar = 1.0; |
---|
905 | n_iter = 0; |
---|
906 | result = 0; |
---|
907 | |
---|
908 | For(i,mod->ns*mod->ns) mod->r_mat->qmat_buff->v[i] = mod->r_mat->qmat->v[i]; |
---|
909 | |
---|
910 | /* compute eigenvectors/values */ |
---|
911 | /* if(!EigenRealGeneral(mod->eigen->size,mod->r_mat->qmat,mod->eigen->e_val, */ |
---|
912 | /* mod->eigen->e_val_im, mod->eigen->r_e_vect, */ |
---|
913 | /* mod->eigen->space_int,mod->eigen->space)) */ |
---|
914 | |
---|
915 | if(!Eigen(1,mod->r_mat->qmat_buff->v,mod->eigen->size,mod->eigen->e_val, |
---|
916 | mod->eigen->e_val_im,mod->eigen->r_e_vect, |
---|
917 | mod->eigen->r_e_vect_im,mod->eigen->space)) |
---|
918 | { |
---|
919 | /* compute inverse(Vr) into Vi */ |
---|
920 | For (i,mod->ns*mod->ns) mod->eigen->l_e_vect[i] = mod->eigen->r_e_vect[i]; |
---|
921 | while(!Matinv(mod->eigen->l_e_vect, mod->eigen->size, mod->eigen->size,YES)) |
---|
922 | { |
---|
923 | PhyML_Printf("\n. Trying Q<-Q*scalar and then Root<-Root/scalar to fix this...\n"); |
---|
924 | scalar += scalar / 3.; |
---|
925 | For(i,mod->eigen->size*mod->eigen->size) mod->r_mat->qmat_buff->v[i] = mod->r_mat->qmat->v[i]; |
---|
926 | For(i,mod->eigen->size*mod->eigen->size) mod->r_mat->qmat_buff->v[i] *= scalar; |
---|
927 | result = Eigen(1,mod->r_mat->qmat_buff->v,mod->eigen->size,mod->eigen->e_val, |
---|
928 | mod->eigen->e_val_im,mod->eigen->r_e_vect, |
---|
929 | mod->eigen->r_e_vect_im,mod->eigen->space); |
---|
930 | if (result == -1) |
---|
931 | Exit("\n. Eigenvalues/vectors computation did not converge: computation cancelled\n"); |
---|
932 | else if (result == 1) |
---|
933 | Exit("\n. Complex eigenvalues/vectors: computation cancelled\n"); |
---|
934 | |
---|
935 | For (i,mod->eigen->size*mod->eigen->size) mod->eigen->l_e_vect[i] = mod->eigen->r_e_vect[i]; |
---|
936 | n_iter++; |
---|
937 | if(n_iter > 100) Exit("\n. Cannot work out eigen vectors\n"); |
---|
938 | }; |
---|
939 | For(i,mod->eigen->size) mod->eigen->e_val[i] /= scalar; |
---|
940 | |
---|
941 | /* compute the diagonal terms of EXP(D) */ |
---|
942 | For(i,mod->ns) mod->eigen->e_val[i] = (phydbl)EXP(mod->eigen->e_val[i]); |
---|
943 | |
---|
944 | |
---|
945 | /* int j; */ |
---|
946 | /* double *U,*V,*R; */ |
---|
947 | /* double *expt; */ |
---|
948 | /* double *uexpt; */ |
---|
949 | /* int n; */ |
---|
950 | |
---|
951 | /* expt = mod->eigen->e_val_im; */ |
---|
952 | /* uexpt = mod->eigen->r_e_vect_im; */ |
---|
953 | /* U = mod->eigen->r_e_vect; */ |
---|
954 | /* V = mod->eigen->l_e_vect; */ |
---|
955 | /* R = mod->eigen->e_val; /\* exponential of the eigen value matrix *\/ */ |
---|
956 | /* n = mod->ns; */ |
---|
957 | |
---|
958 | /* PhyML_Printf("\n"); */ |
---|
959 | /* PhyML_Printf("\n. Q\n"); */ |
---|
960 | /* For(i,n) { For(j,n) PhyML_Printf("%7.3f ",mod->eigen->q[i*n+j]); PhyML_Printf("\n"); } */ |
---|
961 | /* PhyML_Printf("\n. U\n"); */ |
---|
962 | /* For(i,n) { For(j,n) PhyML_Printf("%7.3f ",U[i*n+j]); PhyML_Printf("\n"); } */ |
---|
963 | /* PhyML_Printf("\n"); */ |
---|
964 | /* PhyML_Printf("\n. V\n"); */ |
---|
965 | /* For(i,n) { For(j,n) PhyML_Printf("%7.3f ",V[i*n+j]); PhyML_Printf("\n"); } */ |
---|
966 | /* PhyML_Printf("\n"); */ |
---|
967 | /* PhyML_Printf("\n. Eigen\n"); */ |
---|
968 | /* For(i,n) PhyML_Printf("%E ",mod->eigen->e_val[i]); */ |
---|
969 | /* PhyML_Printf("\n"); */ |
---|
970 | |
---|
971 | /* Exit("\n"); */ |
---|
972 | |
---|
973 | } |
---|
974 | else |
---|
975 | { |
---|
976 | PhyML_Printf("\n. Eigenvalues/vectors computation does not converge : computation cancelled"); |
---|
977 | Warn_And_Exit("\n"); |
---|
978 | } |
---|
979 | } |
---|
980 | |
---|
981 | } |
---|
982 | |
---|
983 | ////////////////////////////////////////////////////////////// |
---|
984 | ////////////////////////////////////////////////////////////// |
---|
985 | |
---|
986 | |
---|
987 | void Switch_From_M4mod_To_Mod(t_mod *mod) |
---|
988 | { |
---|
989 | int i; |
---|
990 | |
---|
991 | mod->use_m4mod = 0; |
---|
992 | mod->ns = mod->m4mod->n_o; |
---|
993 | For(i,mod->ns) mod->e_frq->pi->v[i] = mod->m4mod->o_fq[i]; |
---|
994 | mod->eigen->size = mod->ns; |
---|
995 | Switch_Eigen(YES,mod); |
---|
996 | } |
---|
997 | |
---|
998 | ////////////////////////////////////////////////////////////// |
---|
999 | ////////////////////////////////////////////////////////////// |
---|
1000 | |
---|
1001 | |
---|
1002 | void Switch_From_Mod_To_M4mod(t_mod *mod) |
---|
1003 | { |
---|
1004 | int i; |
---|
1005 | mod->use_m4mod = 1; |
---|
1006 | mod->ns = mod->m4mod->n_o * mod->m4mod->n_h; |
---|
1007 | For(i,mod->ns) mod->e_frq->pi->v[i] = mod->m4mod->o_fq[i%mod->m4mod->n_o] * mod->m4mod->h_fq[i/mod->m4mod->n_o]; |
---|
1008 | mod->eigen->size = mod->ns; |
---|
1009 | Switch_Eigen(YES,mod); |
---|
1010 | } |
---|
1011 | |
---|
1012 | ////////////////////////////////////////////////////////////// |
---|
1013 | ////////////////////////////////////////////////////////////// |
---|
1014 | |
---|
1015 | |
---|
1016 | phydbl General_Dist(phydbl *F, t_mod *mod, eigen *eigen_struct) |
---|
1017 | { |
---|
1018 | phydbl *pi,*mod_pi; |
---|
1019 | int i,j,k; |
---|
1020 | phydbl dist; |
---|
1021 | phydbl sum; |
---|
1022 | phydbl sum_ev; |
---|
1023 | phydbl *F_phydbl; |
---|
1024 | |
---|
1025 | |
---|
1026 | /* TO DO : call eigen decomposition function for all nt models */ |
---|
1027 | |
---|
1028 | F_phydbl = (phydbl *)mCalloc(eigen_struct->size*eigen_struct->size,sizeof(phydbl)); |
---|
1029 | pi = (phydbl *)mCalloc(eigen_struct->size,sizeof(phydbl)); |
---|
1030 | mod_pi = (phydbl *)mCalloc(eigen_struct->size,sizeof(phydbl)); |
---|
1031 | |
---|
1032 | For(i,mod->ns) mod_pi[i] = mod->e_frq->pi->v[i]; |
---|
1033 | |
---|
1034 | sum = .0; |
---|
1035 | For(i,eigen_struct->size) |
---|
1036 | { |
---|
1037 | For(j,eigen_struct->size) |
---|
1038 | { |
---|
1039 | pi[i] += (F[eigen_struct->size*i+j] + F[eigen_struct->size*j+i])/2.; |
---|
1040 | sum += F[eigen_struct->size*i+j]; |
---|
1041 | } |
---|
1042 | } |
---|
1043 | |
---|
1044 | Make_Symmetric(&F,eigen_struct->size); |
---|
1045 | Divide_Mat_By_Vect(&F,mod->e_frq->pi->v,eigen_struct->size); |
---|
1046 | |
---|
1047 | /* Eigen decomposition of pi^{-1} x F */ |
---|
1048 | For(i,eigen_struct->size) For(j,eigen_struct->size) F_phydbl[eigen_struct->size*i+j] = F[eigen_struct->size*i+j]; |
---|
1049 | |
---|
1050 | if(Eigen(1,F_phydbl,mod->eigen->size,mod->eigen->e_val, |
---|
1051 | mod->eigen->e_val_im,mod->eigen->r_e_vect, |
---|
1052 | mod->eigen->r_e_vect_im,mod->eigen->space)) |
---|
1053 | { |
---|
1054 | For(i,mod->ns) mod->e_frq->pi->v[i] = mod_pi[i]; |
---|
1055 | Update_Qmat_GTR(mod->r_mat->rr->v, mod->r_mat->rr_val->v, mod->r_mat->rr_num->v, mod->e_frq->pi->v, mod->r_mat->qmat->v); |
---|
1056 | Free(pi); |
---|
1057 | Free(mod_pi); |
---|
1058 | return -1.; |
---|
1059 | } |
---|
1060 | |
---|
1061 | /* Get the left eigen vector of pi^{-1} x F */ |
---|
1062 | For(i,eigen_struct->size*eigen_struct->size) eigen_struct->l_e_vect[i] = eigen_struct->r_e_vect[i]; |
---|
1063 | if(!Matinv(eigen_struct->l_e_vect,eigen_struct->size,eigen_struct->size,YES)<0) |
---|
1064 | { |
---|
1065 | For(i,mod->ns) mod->e_frq->pi->v[i] = mod_pi[i]; |
---|
1066 | Update_Qmat_GTR(mod->r_mat->rr->v, mod->r_mat->rr_val->v, mod->r_mat->rr_num->v, mod->e_frq->pi->v, mod->r_mat->qmat->v); |
---|
1067 | Free(pi); |
---|
1068 | Free(mod_pi); |
---|
1069 | return -1.; |
---|
1070 | } |
---|
1071 | |
---|
1072 | /* LOG of eigen values */ |
---|
1073 | For(i,eigen_struct->size) |
---|
1074 | { |
---|
1075 | /* if(eigen_struct->e_val[i] < 0.0) eigen_struct->e_val[i] = 0.0001; */ |
---|
1076 | eigen_struct->e_val[i] = (phydbl)LOG(eigen_struct->e_val[i]); |
---|
1077 | } |
---|
1078 | |
---|
1079 | /* Matrix multiplications LOG(pi^{-1} x F) */ |
---|
1080 | For(i,eigen_struct->size) For(j,eigen_struct->size) |
---|
1081 | eigen_struct->r_e_vect[eigen_struct->size*i+j] = |
---|
1082 | eigen_struct->r_e_vect[eigen_struct->size*i+j] * |
---|
1083 | eigen_struct->e_val[j]; |
---|
1084 | For(i,eigen_struct->size) For(j,eigen_struct->size) F[eigen_struct->size*i+j] = .0; |
---|
1085 | For(i,eigen_struct->size) For(j,eigen_struct->size) For(k,eigen_struct->size) |
---|
1086 | F[eigen_struct->size*i+j] += eigen_struct->r_e_vect[eigen_struct->size*i+k] * eigen_struct->l_e_vect[eigen_struct->size*k+j]; |
---|
1087 | |
---|
1088 | |
---|
1089 | /* Trace */ |
---|
1090 | dist = .0; |
---|
1091 | For(i,eigen_struct->size) dist+=F[eigen_struct->size*i+i]; |
---|
1092 | |
---|
1093 | sum_ev = .0; |
---|
1094 | For(i,mod->ns) sum_ev += mod->eigen->e_val[i]; |
---|
1095 | |
---|
1096 | /* dist /= sum_ev; */ |
---|
1097 | dist /= -4.; |
---|
1098 | |
---|
1099 | |
---|
1100 | /* For(i,mod->ns) mod->e_frq->pi->v[i] = mod_pi[i]; */ |
---|
1101 | /* Update_Qmat_GTR(mod); */ |
---|
1102 | Free(pi); |
---|
1103 | Free(mod_pi); |
---|
1104 | Free(F_phydbl); |
---|
1105 | |
---|
1106 | if(isnan(dist)) return -1.; |
---|
1107 | return dist; |
---|
1108 | } |
---|
1109 | |
---|
1110 | ////////////////////////////////////////////////////////////// |
---|
1111 | ////////////////////////////////////////////////////////////// |
---|
1112 | |
---|
1113 | phydbl GTR_Dist(phydbl *F, phydbl alpha, eigen *eigen_struct) |
---|
1114 | { |
---|
1115 | phydbl *pi; |
---|
1116 | int i,j,k; |
---|
1117 | phydbl dist; |
---|
1118 | phydbl sum; |
---|
1119 | phydbl *F_phydbl; |
---|
1120 | |
---|
1121 | pi = (phydbl *)mCalloc(eigen_struct->size,sizeof(phydbl)); |
---|
1122 | F_phydbl = (phydbl *)mCalloc(eigen_struct->size*eigen_struct->size,sizeof(phydbl)); |
---|
1123 | |
---|
1124 | /* /\* Waddell and Steel's example *\/ */ |
---|
1125 | /* F[4*0+0] = 1415./4898.; F[4*0+1] = 8./4898.; F[4*0+2] = 55./4898.; F[4*0+3] = 2./4898.; */ |
---|
1126 | /* F[4*1+0] = 4./4898.; F[4*1+1] = 1371./4898.; F[4*1+2] = 1./4898.; F[4*1+3] = 144./4898.; */ |
---|
1127 | /* F[4*2+0] = 73./4898.; F[4*2+1] = 0./4898.; F[4*2+2] = 578./4898.; F[4*2+3] = 0./4898.; */ |
---|
1128 | /* F[4*3+0] = 3./4898.; F[4*3+1] = 117./4898.; F[4*3+2] = 1./4898.; F[4*3+3] = 1126./4898.; */ |
---|
1129 | |
---|
1130 | |
---|
1131 | For(i,eigen_struct->size) |
---|
1132 | { |
---|
1133 | For(j,eigen_struct->size) |
---|
1134 | { |
---|
1135 | pi[i] += (F[eigen_struct->size*i+j] + F[eigen_struct->size*j+i])/2.; |
---|
1136 | sum += F[eigen_struct->size*i+j]; |
---|
1137 | } |
---|
1138 | } |
---|
1139 | |
---|
1140 | /* /\* Jukes and Cantor correction *\/ */ |
---|
1141 | /* sum = .0; */ |
---|
1142 | /* For(i,eigen_struct->size) sum += F[eigen_struct->size*i+i]; */ |
---|
1143 | /* sum = 1.-sum; */ |
---|
1144 | /* For(i,eigen_struct->size*eigen_struct->size) F[i] = sum/12.; */ |
---|
1145 | /* For(i,eigen_struct->size) F[eigen_struct->size*i+i] = (1.-sum)/4.; */ |
---|
1146 | /* For(i,eigen_struct->size) pi[i] = 1./(phydbl)eigen_struct->size; */ |
---|
1147 | |
---|
1148 | |
---|
1149 | Make_Symmetric(&F,eigen_struct->size); |
---|
1150 | Divide_Mat_By_Vect(&F,pi,eigen_struct->size); |
---|
1151 | |
---|
1152 | |
---|
1153 | /* Eigen decomposition of pi^{-1} x F */ |
---|
1154 | For(i,eigen_struct->size) For(j,eigen_struct->size) F_phydbl[eigen_struct->size*i+j] = F[eigen_struct->size*i+j]; |
---|
1155 | if(Eigen(1,F_phydbl,eigen_struct->size,eigen_struct->e_val, |
---|
1156 | eigen_struct->e_val_im,eigen_struct->r_e_vect, |
---|
1157 | eigen_struct->r_e_vect_im,eigen_struct->space)) |
---|
1158 | { |
---|
1159 | Free(pi); |
---|
1160 | return -1.; |
---|
1161 | } |
---|
1162 | |
---|
1163 | /* Get the left eigen vector of pi^{-1} x F */ |
---|
1164 | For(i,eigen_struct->size*eigen_struct->size) eigen_struct->l_e_vect[i] = eigen_struct->r_e_vect[i]; |
---|
1165 | if(!Matinv(eigen_struct->l_e_vect,eigen_struct->size,eigen_struct->size,YES)<0) {Free(pi); return -1.;} |
---|
1166 | |
---|
1167 | /* Equation (3) + inverse of the moment generating function for the gamma distribution (see Waddell & Steel, 1997) */ |
---|
1168 | For(i,eigen_struct->size) |
---|
1169 | { |
---|
1170 | if(eigen_struct->e_val[i] < 0.0) |
---|
1171 | { |
---|
1172 | eigen_struct->e_val[i] = 0.0001; |
---|
1173 | } |
---|
1174 | if(alpha < .0) |
---|
1175 | eigen_struct->e_val[i] = (phydbl)LOG(eigen_struct->e_val[i]); |
---|
1176 | else |
---|
1177 | eigen_struct->e_val[i] = alpha * (1. - (phydbl)POW(eigen_struct->e_val[i],-1./alpha)); |
---|
1178 | } |
---|
1179 | |
---|
1180 | /* Matrix multiplications pi x LOG(pi^{-1} x F) */ |
---|
1181 | For(i,eigen_struct->size) For(j,eigen_struct->size) |
---|
1182 | eigen_struct->r_e_vect[eigen_struct->size*i+j] = |
---|
1183 | eigen_struct->r_e_vect[eigen_struct->size*i+j] * eigen_struct->e_val[j]; |
---|
1184 | For(i,eigen_struct->size) For(j,eigen_struct->size) F[eigen_struct->size*i+j] = .0; |
---|
1185 | For(i,eigen_struct->size) For(j,eigen_struct->size) For(k,eigen_struct->size) |
---|
1186 | F[eigen_struct->size*i+j] += eigen_struct->r_e_vect[eigen_struct->size*i+k] * eigen_struct->l_e_vect[eigen_struct->size*k+j]; |
---|
1187 | For(i,eigen_struct->size) For(j,eigen_struct->size) F[eigen_struct->size*i+j] *= pi[i]; |
---|
1188 | |
---|
1189 | /* Trace */ |
---|
1190 | dist = .0; |
---|
1191 | For(i,eigen_struct->size) dist-=F[eigen_struct->size*i+i]; |
---|
1192 | |
---|
1193 | /* PhyML_Printf("\nDIST = %f\n",dist); Exit("\n"); */ |
---|
1194 | |
---|
1195 | Free(pi); |
---|
1196 | Free(F_phydbl); |
---|
1197 | |
---|
1198 | if(isnan(dist)) return -1.; |
---|
1199 | return dist; |
---|
1200 | } |
---|
1201 | |
---|
1202 | |
---|