source: tags/arb-6.0/GDE/RAxML/newviewGenericSpecial.c

Last change on this file was 10409, checked in by aboeckma, 11 years ago

Updated raxml to current version

  • Property svn:executable set to *
File size: 212.3 KB
Line 
1/*  RAxML-VI-HPC (version 2.2) a program for sequential and parallel estimation of phylogenetic trees
2 *  Copyright August 2006 by Alexandros Stamatakis
3 *
4 *  Partially derived from
5 *  fastDNAml, a program for estimation of phylogenetic trees from sequences by Gary J. Olsen
6 *
7 *  and
8 *
9 *  Programs of the PHYLIP package by Joe Felsenstein.
10 *  This program is free software; you may redistribute it and/or modify its
11 *  under the terms of the GNU General Public License as published by the Free
12 *  Software Foundation; either version 2 of the License, or (at your option)
13 *  any later version.
14 *
15 *  This program is distributed in the hope that it will be useful, but
16 *  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 *  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 *  for more details.
19 *
20 *
21 *  For any other enquiries send an Email to Alexandros Stamatakis
22 *  Alexandros.Stamatakis@epfl.ch
23 *
24 *  When publishing work that is based on the results from RAxML-VI-HPC please cite:
25 *
26 *  Alexandros Stamatakis:"RAxML-VI-HPC: maximum likelihood-based phylogenetic analyses with thousands of taxa and mixed models".
27 *  Bioinformatics 2006; doi: 10.1093/bioinformatics/btl446
28 */
29
30#ifndef WIN32
31#include <unistd.h>
32#endif
33
34#include <math.h>
35#include <time.h>
36#include <stdlib.h>
37#include <stdio.h>
38#include <ctype.h>
39#include <string.h>
40#include <stdint.h>
41#include <limits.h>
42#include "axml.h"
43
44#ifdef __SIM_SSE3
45
46#include <stdint.h>
47#include <xmmintrin.h>
48#include <pmmintrin.h>
49
50const union __attribute__ ((aligned (BYTE_ALIGNMENT)))
51{
52       uint64_t i[2];
53       __m128d m;
54} absMask = {{0x7fffffffffffffffULL , 0x7fffffffffffffffULL }};
55
56
57
58
59#endif
60
61
62#ifdef _USE_PTHREADS
63#include <pthread.h>
64extern volatile int NumberOfThreads;
65extern pthread_mutex_t          mutex;
66#endif
67
68
69extern const unsigned int mask32[32];
70
71boolean isGap(unsigned int *x, int pos)
72{
73  return (x[pos / 32] & mask32[pos % 32]);
74}
75
76boolean noGap(unsigned int *x, int pos)
77{
78  return (!(x[pos / 32] & mask32[pos % 32]));
79}
80
81void makeP_Flex(double z1, double z2, double *rptr, double *EI,  double *EIGN, int numberOfCategories, double *left, double *right, const int numStates)
82{
83  int 
84    i,
85    j,
86    k;
87 
88  const int
89    rates = numStates - 1,
90    statesSquare = numStates * numStates;
91
92  double 
93    lz1[64],
94    lz2[64], 
95    d1[64], 
96    d2[64];
97
98  assert(numStates <= 64);
99     
100  for(i = 0; i < rates; i++)
101    {
102      lz1[i] = EIGN[i] * z1;
103      lz2[i] = EIGN[i] * z2;
104    }
105
106  for(i = 0; i < numberOfCategories; i++)
107    {
108      for(j = 0; j < rates; j++)
109        {
110          d1[j] = EXP (rptr[i] * lz1[j]);
111          d2[j] = EXP (rptr[i] * lz2[j]);
112        }
113
114      for(j = 0; j < numStates; j++)
115        {
116          left[statesSquare * i  + numStates * j] = 1.0;
117          right[statesSquare * i + numStates * j] = 1.0;
118
119          for(k = 1; k < numStates; k++)
120            {
121              left[statesSquare * i + numStates * j + k]  = d1[k-1] * EI[rates * j + (k-1)];
122              right[statesSquare * i + numStates * j + k] = d2[k-1] * EI[rates * j + (k-1)];
123            }
124        }
125    } 
126}
127
128static void makeP_FlexLG4(double z1, double z2, double *rptr, double *EI[4],  double *EIGN[4], int numberOfCategories, double *left, double *right, const int numStates)
129{
130  int 
131    i,
132    j,
133    k;
134 
135  const int
136    rates = numStates - 1,
137    statesSquare = numStates * numStates;
138
139  double   
140    d1[64], 
141    d2[64];
142
143  assert(numStates <= 64);
144       
145  for(i = 0; i < numberOfCategories; i++)
146    {
147      for(j = 0; j < rates; j++)
148        {
149          d1[j] = EXP (rptr[i] * EIGN[i][j] * z1);
150          d2[j] = EXP (rptr[i] * EIGN[i][j] * z2);
151        }
152
153      for(j = 0; j < numStates; j++)
154        {
155          left[statesSquare * i  + numStates * j] = 1.0;
156          right[statesSquare * i + numStates * j] = 1.0;
157
158          for(k = 1; k < numStates; k++)
159            {
160              left[statesSquare * i + numStates * j + k]  = d1[k-1] * EI[i][rates * j + (k-1)];
161              right[statesSquare * i + numStates * j + k] = d2[k-1] * EI[i][rates * j + (k-1)];
162            }
163        }
164    } 
165}
166
167
168
169
170
171
172static void newviewFlexCat(int tipCase, double *extEV,
173                           int *cptr,
174                           double *x1, double *x2, double *x3, double *tipVector,
175                           int *ex3, unsigned char *tipX1, unsigned char *tipX2,
176                           int n, double *left, double *right, int *wgt, int *scalerIncrement, const boolean useFastScaling, const int numStates)
177{
178  double
179    *le, *ri, *v, *vl, *vr,
180    ump_x1, ump_x2, x1px2;
181  int i, l, j, scale, addScale = 0;
182
183  const int 
184    statesSquare = numStates * numStates;
185
186  switch(tipCase)
187    {
188    case TIP_TIP:
189      {
190        for (i = 0; i < n; i++)
191          {
192            le = &left[cptr[i] * statesSquare];
193            ri = &right[cptr[i] * statesSquare];
194
195            vl = &(tipVector[numStates * tipX1[i]]);
196            vr = &(tipVector[numStates * tipX2[i]]);
197            v  = &x3[numStates * i];
198
199            for(l = 0; l < numStates; l++)
200              v[l] = 0.0;
201
202            for(l = 0; l < numStates; l++)
203              {
204                ump_x1 = 0.0;
205                ump_x2 = 0.0;
206
207                for(j = 0; j < numStates; j++)
208                  {
209                    ump_x1 += vl[j] * le[l * numStates + j];
210                    ump_x2 += vr[j] * ri[l * numStates + j];
211                  }
212
213                x1px2 = ump_x1 * ump_x2;
214
215                for(j = 0; j < numStates; j++)
216                  v[j] += x1px2 * extEV[l * numStates + j];
217              }     
218          }
219      }
220      break;
221    case TIP_INNER:
222      {
223        for (i = 0; i < n; i++)
224          {
225            le = &left[cptr[i] * statesSquare];
226            ri = &right[cptr[i] * statesSquare];
227
228            vl = &(tipVector[numStates * tipX1[i]]);
229            vr = &x2[numStates * i];
230            v  = &x3[numStates * i];
231
232            for(l = 0; l < numStates; l++)
233              v[l] = 0.0;
234
235            for(l = 0; l < numStates; l++)
236              {
237                ump_x1 = 0.0;
238                ump_x2 = 0.0;
239
240                for(j = 0; j < numStates; j++)
241                  {
242                    ump_x1 += vl[j] * le[l * numStates + j];
243                    ump_x2 += vr[j] * ri[l * numStates + j];
244                  }
245
246                x1px2 = ump_x1 * ump_x2;
247
248                for(j = 0; j < numStates; j++)
249                  v[j] += x1px2 * extEV[l * numStates + j];
250              }
251
252            scale = 1;
253            for(l = 0; scale && (l < numStates); l++)
254              scale = ((v[l] < minlikelihood) && (v[l] > minusminlikelihood));     
255
256            if(scale)
257              {
258                for(l = 0; l < numStates; l++)
259                  v[l] *= twotothe256;
260               
261                if(useFastScaling)
262                  addScale += wgt[i];
263                else
264                  ex3[i]  += 1;       
265              }
266          }
267      }
268      break;
269    case INNER_INNER:
270      for(i = 0; i < n; i++)
271        {
272          le = &left[cptr[i] * statesSquare];
273          ri = &right[cptr[i] * statesSquare];
274
275          vl = &x1[numStates * i];
276          vr = &x2[numStates * i];
277          v = &x3[numStates * i];
278
279          for(l = 0; l < numStates; l++)
280            v[l] = 0.0;
281
282          for(l = 0; l < numStates; l++)
283            {
284              ump_x1 = 0.0;
285              ump_x2 = 0.0;
286
287              for(j = 0; j < numStates; j++)
288                {
289                  ump_x1 += vl[j] * le[l * numStates + j];
290                  ump_x2 += vr[j] * ri[l * numStates + j];
291                }
292
293              x1px2 =  ump_x1 * ump_x2;
294
295              for(j = 0; j < numStates; j++)
296                v[j] += x1px2 * extEV[l * numStates + j];
297            }
298
299           scale = 1;
300           for(l = 0; scale && (l < numStates); l++)
301             scale = ((v[l] < minlikelihood) && (v[l] > minusminlikelihood));
302         
303           if(scale)
304             {
305               for(l = 0; l < numStates; l++)
306                 v[l] *= twotothe256;
307
308               if(useFastScaling)
309                 addScale += wgt[i];
310               else
311                 ex3[i]  += 1;       
312             }
313        }
314      break;
315    default:
316      assert(0);
317    }
318 
319  if(useFastScaling)
320    *scalerIncrement = addScale;
321
322}
323
324static void newviewFlexGamma(int tipCase,
325                             double *x1, double *x2, double *x3, double *extEV, double *tipVector,
326                             int *ex3, unsigned char *tipX1, unsigned char *tipX2,
327                             int n, double *left, double *right, int *wgt, int *scalerIncrement, const boolean useFastScaling, 
328                             const int numStates)
329{
330  double  *v;
331  double x1px2;
332  int  i, j, l, k, scale, addScale = 0;
333  double *vl, *vr, al, ar;
334
335  const int 
336    statesSquare = numStates * numStates,
337    gammaStates = 4 * numStates;
338
339  switch(tipCase)
340    {
341    case TIP_TIP:
342      {
343        for(i = 0; i < n; i++)
344          {
345            for(k = 0; k < 4; k++)
346              {
347                vl = &(tipVector[numStates * tipX1[i]]);
348                vr = &(tipVector[numStates * tipX2[i]]);
349                v =  &(x3[gammaStates * i + numStates * k]);
350
351                for(l = 0; l < numStates; l++)
352                  v[l] = 0;
353
354                for(l = 0; l < numStates; l++)
355                  {
356                    al = 0.0;
357                    ar = 0.0;
358                    for(j = 0; j < numStates; j++)
359                      {
360                        al += vl[j] * left[k * statesSquare + l * numStates + j];
361                        ar += vr[j] * right[k * statesSquare + l * numStates + j];
362                      }
363
364                    x1px2 = al * ar;
365                    for(j = 0; j < numStates; j++)
366                      v[j] += x1px2 * extEV[numStates * l + j];
367                  }
368              }     
369          }
370      }
371      break;
372    case TIP_INNER:
373      {
374        for (i = 0; i < n; i++)
375          {
376            for(k = 0; k < 4; k++)
377              {
378                vl = &(tipVector[numStates * tipX1[i]]);
379                vr = &(x2[gammaStates * i + numStates * k]);
380                v =  &(x3[gammaStates * i + numStates * k]);
381
382                for(l = 0; l < numStates; l++)
383                  v[l] = 0;
384
385                for(l = 0; l < numStates; l++)
386                  {
387                    al = 0.0;
388                    ar = 0.0;
389                    for(j = 0; j < numStates; j++)
390                      {
391                        al += vl[j] * left[k * statesSquare + l * numStates + j];
392                        ar += vr[j] * right[k * statesSquare + l * numStates + j];
393                      }
394
395                    x1px2 = al * ar;
396                    for(j = 0; j < numStates; j++)
397                      v[j] += x1px2 * extEV[numStates * l + j];
398                  }
399              }
400           
401            v = &x3[gammaStates * i];
402            scale = 1;
403            for(l = 0; scale && (l < gammaStates); l++)
404              scale = (ABS(v[l]) <  minlikelihood);
405
406            if(scale)
407              {
408                for(l = 0; l < gammaStates; l++)
409                  v[l] *= twotothe256;
410
411                if(useFastScaling)
412                  addScale += wgt[i];
413                else
414                  ex3[i]  += 1;       
415              }
416          }
417      }
418      break;
419    case INNER_INNER:
420      for (i = 0; i < n; i++)
421       {
422         for(k = 0; k < 4; k++)
423           {
424             vl = &(x1[gammaStates * i + numStates * k]);
425             vr = &(x2[gammaStates * i + numStates * k]);
426             v =  &(x3[gammaStates * i + numStates * k]);
427
428             for(l = 0; l < numStates; l++)
429               v[l] = 0;
430
431             for(l = 0; l < numStates; l++)
432               {
433                 al = 0.0;
434                 ar = 0.0;
435                 for(j = 0; j < numStates; j++)
436                   {
437                     al += vl[j] * left[k * statesSquare + l * numStates + j];
438                     ar += vr[j] * right[k * statesSquare + l * numStates + j];
439                   }
440
441                 x1px2 = al * ar;
442                 for(j = 0; j < numStates; j++)
443                   v[j] += x1px2 * extEV[numStates * l + j];
444               }
445           }
446         
447         v = &(x3[gammaStates * i]);
448         scale = 1;
449         for(l = 0; scale && (l < gammaStates); l++)
450           scale = ((ABS(v[l]) <  minlikelihood));
451
452         if (scale)
453           {
454             for(l = 0; l < gammaStates; l++)
455               v[l] *= twotothe256;
456
457             if(useFastScaling)
458               addScale += wgt[i];
459             else
460               ex3[i]  += 1;       
461           }
462       }
463      break;
464    default:
465      assert(0);
466    }
467
468  if(useFastScaling)
469    *scalerIncrement = addScale;
470
471}
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487static void makeP(double z1, double z2, double *rptr, double *EI,  double *EIGN, int numberOfCategories, double *left, double *right, int data, boolean saveMem, int maxCat)
488{
489  int i, j, k;
490
491  switch(data)
492    {
493    case BINARY_DATA:
494      {
495        double d1, d2;
496
497        for(i = 0; i < numberOfCategories; i++)
498          {
499            d1 = EXP(rptr[i] * EIGN[0] * z1);
500            d2 = EXP(rptr[i] * EIGN[0] * z2);
501           
502            for(j = 0; j < 2; j++)
503              {
504                left[i * 4 + j * 2] = 1.0;
505                right[i * 4 + j * 2] = 1.0;
506
507                left[i * 4 + j * 2 + 1]  = d1 * EI[j];
508                right[i * 4 + j * 2 + 1] = d2 * EI[j]; 
509              }
510          }
511      }
512      break;
513    case DNA_DATA:
514      {
515#ifdef __SIM_SSE3
516        double 
517          d1[4] __attribute__ ((aligned (BYTE_ALIGNMENT))), 
518          d2[4] __attribute__ ((aligned (BYTE_ALIGNMENT))),
519          ez1[3], 
520          ez2[3],
521          EI_16[16] __attribute__ ((aligned (BYTE_ALIGNMENT)));
522       
523                 
524        for(j = 0; j < 4; j++)
525          {
526            EI_16[j * 4] = 1.0;
527            for(k = 0; k < 3; k++)
528              EI_16[j * 4 + k + 1] = EI[3 * j + k];
529          }       
530
531        for(j = 0; j < 3; j++)
532          {
533            ez1[j] = EIGN[j] * z1;
534            ez2[j] = EIGN[j] * z2;
535          }
536
537
538        for(i = 0; i < numberOfCategories; i++)
539          {       
540            __m128d 
541              d1_0, d1_1,
542              d2_0, d2_1;
543 
544            d1[0] = 1.0;
545            d2[0] = 1.0;
546
547            for(j = 0; j < 3; j++)
548              {
549                d1[j+1] = EXP(rptr[i] * ez1[j]);
550                d2[j+1] = EXP(rptr[i] * ez2[j]);
551              }
552
553            d1_0 = _mm_load_pd(&d1[0]);
554            d1_1 = _mm_load_pd(&d1[2]);
555
556            d2_0 = _mm_load_pd(&d2[0]);
557            d2_1 = _mm_load_pd(&d2[2]);
558           
559
560            for(j = 0; j < 4; j++)
561              {       
562                double *ll = &left[i * 16 + j * 4];
563                double *rr = &right[i * 16 + j * 4];           
564
565                __m128d eev = _mm_load_pd(&EI_16[4 * j]);
566               
567                _mm_store_pd(&ll[0], _mm_mul_pd(d1_0, eev));
568                _mm_store_pd(&rr[0], _mm_mul_pd(d2_0, eev));
569               
570                eev = _mm_load_pd(&EI_16[4 * j + 2]);
571               
572                _mm_store_pd(&ll[2], _mm_mul_pd(d1_1, eev));
573                _mm_store_pd(&rr[2], _mm_mul_pd(d2_1, eev));
574
575               
576              }
577          }
578
579        if(saveMem)
580          {
581            i = maxCat;
582                   
583            {     
584              __m128d 
585                d1_0, d1_1,
586                d2_0, d2_1;
587             
588              d1[0] = 1.0;
589              d2[0] = 1.0;
590             
591              for(j = 0; j < 3; j++)
592                {
593                  d1[j+1] = EXP(ez1[j]);
594                  d2[j+1] = EXP(ez2[j]);
595                }           
596             
597              d1_0 = _mm_load_pd(&d1[0]);
598              d1_1 = _mm_load_pd(&d1[2]);
599             
600              d2_0 = _mm_load_pd(&d2[0]);
601              d2_1 = _mm_load_pd(&d2[2]);
602                     
603              for(j = 0; j < 4; j++)
604                {             
605                  double *ll = &left[i * 16 + j * 4];
606                  double *rr = &right[i * 16 + j * 4];         
607                 
608                  __m128d eev = _mm_load_pd(&EI_16[4 * j]);
609                 
610                  _mm_store_pd(&ll[0], _mm_mul_pd(d1_0, eev));
611                  _mm_store_pd(&rr[0], _mm_mul_pd(d2_0, eev));
612                 
613                  eev = _mm_load_pd(&EI_16[4 * j + 2]);
614                 
615                  _mm_store_pd(&ll[2], _mm_mul_pd(d1_1, eev));
616                  _mm_store_pd(&rr[2], _mm_mul_pd(d2_1, eev));
617                 
618                 
619                }
620            }
621          }
622     
623#else
624        double d1[3], d2[3];
625
626        for(i = 0; i < numberOfCategories; i++)
627          {
628            for(j = 0; j < 3; j++)
629              {
630                d1[j] = EXP(rptr[i] * EIGN[j] * z1);
631                d2[j] = EXP(rptr[i] * EIGN[j] * z2);
632              }
633
634            for(j = 0; j < 4; j++)
635              {
636                left[i * 16 + j * 4] = 1.0;
637                right[i * 16 + j * 4] = 1.0;
638
639                for(k = 0; k < 3; k++)
640                  {
641                    left[i * 16 + j * 4 + k + 1]  = d1[k] * EI[3 * j + k];
642                    right[i * 16 + j * 4 + k + 1] = d2[k] * EI[3 * j + k];
643                  }
644              }
645          }
646#endif
647      }
648      break;
649    case SECONDARY_DATA:
650      {
651        double lz1[15], lz2[15], d1[15], d2[15];
652
653        for(i = 0; i < 15; i++)
654          {
655            lz1[i] = EIGN[i] * z1;
656            lz2[i] = EIGN[i] * z2;
657          }
658
659        for(i = 0; i < numberOfCategories; i++)
660          {
661            for(j = 0; j < 15; j++)
662              {
663                d1[j] = EXP (rptr[i] * lz1[j]);
664                d2[j] = EXP (rptr[i] * lz2[j]);
665              }
666
667            for(j = 0; j < 16; j++)
668              {
669                left[256 * i  + 16 * j] = 1.0;
670                right[256 * i + 16 * j] = 1.0;
671
672                for(k = 1; k < 16; k++)
673                  {
674                    left[256 * i + 16 * j + k]  = d1[k-1] * EI[15 * j + (k-1)];
675                    right[256 * i + 16 * j + k] = d2[k-1] * EI[15 * j + (k-1)];
676                  }
677              }
678          }
679      }
680      break;
681    case SECONDARY_DATA_6:
682      {
683        double lz1[5], lz2[5], d1[5], d2[5];
684
685        for(i = 0; i < 5; i++)
686          {
687            lz1[i] = EIGN[i] * z1;
688            lz2[i] = EIGN[i] * z2;
689          }
690
691        for(i = 0; i < numberOfCategories; i++)
692          {
693            for(j = 0; j < 5; j++)
694              {
695                d1[j] = EXP (rptr[i] * lz1[j]);
696                d2[j] = EXP (rptr[i] * lz2[j]);
697              }
698
699            for(j = 0; j < 6; j++)
700              {
701                left[36 * i  + 6 * j] = 1.0;
702                right[36 * i + 6 * j] = 1.0;
703
704                for(k = 1; k < 6; k++)
705                  {
706                    left[36 * i + 6 * j + k]  = d1[k-1] * EI[5 * j + (k-1)];
707                    right[36 * i + 6 * j + k] = d2[k-1] * EI[5 * j + (k-1)];
708                  }
709              }
710          }
711      }
712      break;
713    case SECONDARY_DATA_7:
714      {
715        double lz1[6], lz2[6], d1[6], d2[6];
716
717        for(i = 0; i < 6; i++)
718          {
719            lz1[i] = EIGN[i] * z1;
720            lz2[i] = EIGN[i] * z2;
721          }
722
723        for(i = 0; i < numberOfCategories; i++)
724          {
725            for(j = 0; j < 6; j++)
726              {
727                d1[j] = EXP (rptr[i] * lz1[j]);
728                d2[j] = EXP (rptr[i] * lz2[j]);
729              }
730
731            for(j = 0; j < 7; j++)
732              {
733                left[49 * i  + 7 * j] = 1.0;
734                right[49 * i + 7 * j] = 1.0;
735
736                for(k = 1; k < 7; k++)
737                  {
738                    left[49 * i + 7 * j + k]  = d1[k-1] * EI[6 * j + (k-1)];
739                    right[49 * i + 7 * j + k] = d2[k-1] * EI[6 * j + (k-1)];
740                  }
741              }
742          }
743      }
744      break;
745    case AA_DATA:
746      {
747        double lz1[19], lz2[19], d1[19], d2[19];
748
749        for(i = 0; i < 19; i++)
750          {
751            lz1[i] = EIGN[i] * z1;
752            lz2[i] = EIGN[i] * z2;
753          }
754
755        for(i = 0; i < numberOfCategories; i++)
756          {
757            for(j = 0; j < 19; j++)
758              {
759                d1[j] = EXP (rptr[i] * lz1[j]);
760                d2[j] = EXP (rptr[i] * lz2[j]);
761              }
762
763            for(j = 0; j < 20; j++)
764              {
765                left[400 * i  + 20 * j] = 1.0;
766                right[400 * i + 20 * j] = 1.0;
767
768                for(k = 1; k < 20; k++)
769                  {
770                    left[400 * i + 20 * j + k]  = d1[k-1] * EI[19 * j + (k-1)];
771                    right[400 * i + 20 * j + k] = d2[k-1] * EI[19 * j + (k-1)];
772                  }
773              }
774          }
775
776        if(saveMem)
777        {
778          i = maxCat;
779
780          for(j = 0; j < 19; j++)
781          {
782            d1[j] = EXP (lz1[j]);
783            d2[j] = EXP (lz2[j]);
784          }
785
786          for(j = 0; j < 20; j++)
787          {
788            left[400 * i  + 20 * j] = 1.0;
789            right[400 * i + 20 * j] = 1.0;
790
791            for(k = 1; k < 20; k++)
792            {
793              left[400 * i + 20 * j + k]  = d1[k-1] * EI[19 * j + (k-1)];
794              right[400 * i + 20 * j + k] = d2[k-1] * EI[19 * j + (k-1)];
795            }
796          }
797        }     
798      }
799      break;
800    default:
801      assert(0);
802    }
803
804}
805
806
807
808
809#ifndef __SIM_SSE3
810
811static void newviewGTRCAT_BINARY( int tipCase,  double *EV,  int *cptr,
812                                  double *x1_start,  double *x2_start,  double *x3_start,  double *tipVector,
813                                  int *ex3, unsigned char *tipX1, unsigned char *tipX2,
814                                  int n,  double *left, double *right, int *wgt, int *scalerIncrement, const boolean useFastScaling)
815{
816  double
817    *le,
818    *ri,
819    *x1, *x2, *x3;
820  double
821    ump_x1, ump_x2, x1px2[2];
822  int i, j, k, scale, addScale = 0;
823
824  switch(tipCase)
825    {
826    case TIP_TIP:
827      {
828        for (i = 0; i < n; i++)
829          {
830            x1 = &(tipVector[2 * tipX1[i]]);
831            x2 = &(tipVector[2 * tipX2[i]]);
832            x3 = &x3_start[2 * i];         
833
834            le =  &left[cptr[i] * 4];
835            ri =  &right[cptr[i] * 4];
836
837            for(j = 0; j < 2; j++)
838              {
839                ump_x1 = 0.0;
840                ump_x2 = 0.0;
841                for(k = 0; k < 2; k++)
842                  {
843                    ump_x1 += x1[k] * le[j * 2 + k];
844                    ump_x2 += x2[k] * ri[j * 2 + k];
845                  }
846                x1px2[j] = ump_x1 * ump_x2;
847              }
848
849            for(j = 0; j < 2; j++)
850              x3[j] = 0.0;
851
852            for(j = 0; j < 2; j++)
853              for(k = 0; k < 2; k++)
854                x3[k] += x1px2[j] * EV[j * 2 + k];         
855          }
856      }
857      break;
858    case TIP_INNER:
859      {
860        for (i = 0; i < n; i++)
861          {
862            x1 = &(tipVector[2 * tipX1[i]]);
863            x2 = &x2_start[2 * i];
864            x3 = &x3_start[2 * i];
865           
866            le =  &left[cptr[i] * 4];
867            ri =  &right[cptr[i] * 4];
868
869            for(j = 0; j < 2; j++)
870              {
871                ump_x1 = 0.0;
872                ump_x2 = 0.0;
873                for(k = 0; k < 2; k++)
874                  {
875                    ump_x1 += x1[k] * le[j * 2 + k];
876                    ump_x2 += x2[k] * ri[j * 2 + k];
877                  }
878                x1px2[j] = ump_x1 * ump_x2;
879              }
880
881            for(j = 0; j < 2; j++)
882              x3[j] = 0.0;
883
884            for(j = 0; j < 2; j++)
885              for(k = 0; k < 2; k++)
886                x3[k] +=  x1px2[j] *  EV[2 * j + k];       
887
888            scale = 1;
889            for(j = 0; j < 2 && scale; j++)
890              scale = (x3[j] < minlikelihood && x3[j] > minusminlikelihood);
891
892            if(scale)
893              {
894                for(j = 0; j < 2; j++)
895                  x3[j] *= twotothe256;
896
897                if(useFastScaling)
898                  addScale += wgt[i];
899                else
900                  ex3[i]  += 1;       
901              }
902          }
903      }
904      break;
905    case INNER_INNER:
906      for (i = 0; i < n; i++)
907        {
908          x1 = &x1_start[2 * i];
909          x2 = &x2_start[2 * i];
910          x3 = &x3_start[2 * i];
911
912          le = &left[cptr[i] * 4];
913          ri = &right[cptr[i] * 4];
914
915          for(j = 0; j < 2; j++)
916            {
917              ump_x1 = 0.0;
918              ump_x2 = 0.0;
919              for(k = 0; k < 2; k++)
920                {
921                  ump_x1 += x1[k] * le[j * 2 + k];
922                  ump_x2 += x2[k] * ri[j * 2 + k];
923                }
924              x1px2[j] = ump_x1 * ump_x2;
925            }
926
927          for(j = 0; j < 2; j++)
928            x3[j] = 0.0;
929
930          for(j = 0; j < 2; j++)
931            for(k = 0; k < 2; k++)
932              x3[k] +=  x1px2[j] *  EV[2 * j + k];       
933
934          scale = 1;
935          for(j = 0; j < 2 && scale; j++)
936            scale = (x3[j] < minlikelihood && x3[j] > minusminlikelihood);
937
938          if(scale)
939            {
940              for(j = 0; j < 2; j++)
941                x3[j] *= twotothe256;
942
943              if(useFastScaling)
944                addScale += wgt[i];
945              else
946                ex3[i]  += 1;     
947            }
948        }
949      break;
950    default:
951      assert(0);
952    }
953
954  if(useFastScaling)
955    *scalerIncrement = addScale;
956
957}
958
959#else
960
961static void newviewGTRCAT_BINARY( int tipCase,  double *EV,  int *cptr,
962                                  double *x1_start,  double *x2_start,  double *x3_start,  double *tipVector,
963                                  int *ex3, unsigned char *tipX1, unsigned char *tipX2,
964                                  int n,  double *left, double *right, int *wgt, int *scalerIncrement, const boolean useFastScaling)
965{
966  double
967    *le,
968    *ri,
969    *x1, *x2, *x3;
970  int i, l, scale, addScale = 0;
971
972  switch(tipCase)
973    {
974    case TIP_TIP:
975      {
976        for(i = 0; i < n; i++)
977          {
978            x1 = &(tipVector[2 * tipX1[i]]);
979            x2 = &(tipVector[2 * tipX2[i]]);
980            x3 = &x3_start[2 * i];         
981
982            le =  &left[cptr[i] * 4];
983            ri =  &right[cptr[i] * 4];
984
985            _mm_store_pd(x3, _mm_setzero_pd());     
986                     
987            for(l = 0; l < 2; l++)
988              {                                                                                                                         
989                __m128d al = _mm_mul_pd(_mm_load_pd(x1), _mm_load_pd(&le[l * 2]));
990                __m128d ar = _mm_mul_pd(_mm_load_pd(x2), _mm_load_pd(&ri[l * 2]));
991               
992                al = _mm_hadd_pd(al, al);
993                ar = _mm_hadd_pd(ar, ar);
994               
995                al = _mm_mul_pd(al, ar);
996               
997                __m128d vv  = _mm_load_pd(x3);
998                __m128d EVV = _mm_load_pd(&EV[2 * l]);
999               
1000                vv = _mm_add_pd(vv, _mm_mul_pd(al, EVV));
1001               
1002                _mm_store_pd(x3, vv);                                                     
1003              }           
1004          }
1005      }
1006      break;
1007    case TIP_INNER:
1008      {
1009        for (i = 0; i < n; i++)
1010          {
1011            x1 = &(tipVector[2 * tipX1[i]]);
1012            x2 = &x2_start[2 * i];
1013            x3 = &x3_start[2 * i];
1014           
1015            le =  &left[cptr[i] * 4];
1016            ri =  &right[cptr[i] * 4];
1017
1018            _mm_store_pd(x3, _mm_setzero_pd());     
1019                     
1020            for(l = 0; l < 2; l++)
1021              {                                                                                                                         
1022                __m128d al = _mm_mul_pd(_mm_load_pd(x1), _mm_load_pd(&le[l * 2]));
1023                __m128d ar = _mm_mul_pd(_mm_load_pd(x2), _mm_load_pd(&ri[l * 2]));
1024               
1025                al = _mm_hadd_pd(al, al);
1026                ar = _mm_hadd_pd(ar, ar);
1027               
1028                al = _mm_mul_pd(al, ar);
1029               
1030                __m128d vv  = _mm_load_pd(x3);
1031                __m128d EVV = _mm_load_pd(&EV[2 * l]);
1032               
1033                vv = _mm_add_pd(vv, _mm_mul_pd(al, EVV));
1034               
1035                _mm_store_pd(x3, vv);                                                     
1036              } 
1037           
1038            __m128d minlikelihood_sse = _mm_set1_pd( minlikelihood );
1039         
1040            scale = 1;
1041           
1042            __m128d v1 = _mm_and_pd(_mm_load_pd(x3), absMask.m);
1043            v1 = _mm_cmplt_pd(v1,  minlikelihood_sse);
1044            if(_mm_movemask_pd( v1 ) != 3)
1045              scale = 0;                         
1046           
1047            if(scale)
1048              {
1049                __m128d twoto = _mm_set_pd(twotothe256, twotothe256);
1050               
1051                __m128d ex3v = _mm_load_pd(x3);           
1052                _mm_store_pd(x3, _mm_mul_pd(ex3v,twoto));                                                 
1053               
1054                if(useFastScaling)
1055                  addScale += wgt[i];
1056                else
1057                  ex3[i]  += 1;   
1058              }                   
1059          }
1060      }
1061      break;
1062    case INNER_INNER:
1063      for (i = 0; i < n; i++)
1064        {
1065          x1 = &x1_start[2 * i];
1066          x2 = &x2_start[2 * i];
1067          x3 = &x3_start[2 * i];
1068
1069          le = &left[cptr[i] * 4];
1070          ri = &right[cptr[i] * 4];
1071
1072          _mm_store_pd(x3, _mm_setzero_pd());       
1073         
1074          for(l = 0; l < 2; l++)
1075            {                                                                                                                           
1076              __m128d al = _mm_mul_pd(_mm_load_pd(x1), _mm_load_pd(&le[l * 2]));
1077              __m128d ar = _mm_mul_pd(_mm_load_pd(x2), _mm_load_pd(&ri[l * 2]));
1078             
1079              al = _mm_hadd_pd(al, al);
1080              ar = _mm_hadd_pd(ar, ar);
1081             
1082              al = _mm_mul_pd(al, ar);
1083             
1084              __m128d vv  = _mm_load_pd(x3);
1085              __m128d EVV = _mm_load_pd(&EV[2 * l]);
1086             
1087              vv = _mm_add_pd(vv, _mm_mul_pd(al, EVV));
1088             
1089              _mm_store_pd(x3, vv);                                                       
1090            }                             
1091
1092          __m128d minlikelihood_sse = _mm_set1_pd( minlikelihood );
1093         
1094          scale = 1;
1095                 
1096          __m128d v1 = _mm_and_pd(_mm_load_pd(x3), absMask.m);
1097          v1 = _mm_cmplt_pd(v1,  minlikelihood_sse);
1098          if(_mm_movemask_pd( v1 ) != 3)
1099            scale = 0;                   
1100         
1101          if(scale)
1102            {
1103              __m128d twoto = _mm_set_pd(twotothe256, twotothe256);
1104                   
1105              __m128d ex3v = _mm_load_pd(x3);             
1106              _mm_store_pd(x3, _mm_mul_pd(ex3v,twoto));                                           
1107             
1108              if(useFastScaling)
1109                addScale += wgt[i];
1110              else
1111                ex3[i]  += 1;     
1112           }             
1113        }
1114      break;
1115    default:
1116      assert(0);
1117    }
1118
1119  if(useFastScaling)
1120    *scalerIncrement = addScale;
1121
1122}
1123
1124
1125#endif
1126
1127#ifdef __SIM_SSE3
1128static void newviewGTRGAMMA_BINARY(int tipCase,
1129                                   double *x1_start, double *x2_start, double *x3_start,
1130                                   double *EV, double *tipVector,
1131                                   int *ex3, unsigned char *tipX1, unsigned char *tipX2,
1132                                   const int n, double *left, double *right, int *wgt, int *scalerIncrement, const boolean useFastScaling
1133                                   )
1134{
1135  double
1136    *x1, *x2, *x3;
1137 
1138  int i, k, l, scale, addScale = 0; 
1139
1140  switch(tipCase)
1141    {
1142    case TIP_TIP:
1143      for (i = 0; i < n; i++)
1144       {
1145         x1  = &(tipVector[2 * tipX1[i]]);
1146         x2  = &(tipVector[2 * tipX2[i]]);
1147         
1148         for(k = 0; k < 4; k++)
1149           {                       
1150             x3 = &(x3_start[8 * i + 2 * k]);       
1151                         
1152             _mm_store_pd(x3, _mm_setzero_pd());           
1153                     
1154             for(l = 0; l < 2; l++)
1155               {                                                                                                                                 
1156                 __m128d al = _mm_mul_pd(_mm_load_pd(x1), _mm_load_pd(&left[k * 4 + l * 2]));
1157                 __m128d ar = _mm_mul_pd(_mm_load_pd(x2), _mm_load_pd(&right[k * 4 + l * 2]));
1158                                       
1159                 al = _mm_hadd_pd(al, al);
1160                 ar = _mm_hadd_pd(ar, ar);
1161                   
1162                 al = _mm_mul_pd(al, ar);
1163                   
1164                 __m128d vv  = _mm_load_pd(x3);
1165                 __m128d EVV = _mm_load_pd(&EV[2 * l]);
1166                 
1167                 vv = _mm_add_pd(vv, _mm_mul_pd(al, EVV));
1168                 
1169                 _mm_store_pd(x3, vv);                                                   
1170               }                   
1171           }
1172       }
1173      break;
1174    case TIP_INNER:
1175      for (i = 0; i < n; i++)
1176       {
1177         x1  = &(tipVector[2 * tipX1[i]]);
1178         
1179         for(k = 0; k < 4; k++)
1180           {                 
1181             x2 = &(x2_start[8 * i + 2 * k]);
1182             x3 = &(x3_start[8 * i + 2 * k]);       
1183                         
1184             _mm_store_pd(x3, _mm_setzero_pd());           
1185                     
1186             for(l = 0; l < 2; l++)
1187               {                                                                                                                                 
1188                 __m128d al = _mm_mul_pd(_mm_load_pd(x1), _mm_load_pd(&left[k * 4 + l * 2]));
1189                 __m128d ar = _mm_mul_pd(_mm_load_pd(x2), _mm_load_pd(&right[k * 4 + l * 2]));
1190                                       
1191                 al = _mm_hadd_pd(al, al);
1192                 ar = _mm_hadd_pd(ar, ar);
1193                   
1194                 al = _mm_mul_pd(al, ar);
1195                   
1196                 __m128d vv  = _mm_load_pd(x3);
1197                 __m128d EVV = _mm_load_pd(&EV[2 * l]);
1198                 
1199                 vv = _mm_add_pd(vv, _mm_mul_pd(al, EVV));
1200                 
1201                 _mm_store_pd(x3, vv);                                                   
1202               }                   
1203           }
1204       
1205         x3 = &(x3_start[8 * i]);
1206         __m128d minlikelihood_sse = _mm_set1_pd( minlikelihood );
1207         
1208         scale = 1;
1209         for(l = 0; scale && (l < 8); l += 2)
1210           {
1211             __m128d vv = _mm_load_pd(&x3[l]);
1212             __m128d v1 = _mm_and_pd(vv, absMask.m);
1213             v1 = _mm_cmplt_pd(v1,  minlikelihood_sse);
1214             if(_mm_movemask_pd( v1 ) != 3)
1215               scale = 0;
1216           }                     
1217         
1218         if(scale)
1219           {
1220             __m128d twoto = _mm_set_pd(twotothe256, twotothe256);
1221             
1222             for(l = 0; l < 8; l+=2)
1223               {
1224                 __m128d ex3v = _mm_load_pd(&x3[l]);             
1225                 _mm_store_pd(&x3[l], _mm_mul_pd(ex3v,twoto)); 
1226               }                                 
1227             
1228             if(useFastScaling)
1229               addScale += wgt[i];
1230             else
1231               ex3[i]  += 1;     
1232           }     
1233       }     
1234      break;
1235    case INNER_INNER:
1236      for (i = 0; i < n; i++)
1237       {         
1238         for(k = 0; k < 4; k++)
1239           {         
1240             x1 = &(x1_start[8 * i + 2 * k]);
1241             x2 = &(x2_start[8 * i + 2 * k]);
1242             x3 = &(x3_start[8 * i + 2 * k]);       
1243                         
1244             _mm_store_pd(x3, _mm_setzero_pd());           
1245                     
1246             for(l = 0; l < 2; l++)
1247               {                                                                                                                                 
1248                 __m128d al = _mm_mul_pd(_mm_load_pd(x1), _mm_load_pd(&left[k * 4 + l * 2]));
1249                 __m128d ar = _mm_mul_pd(_mm_load_pd(x2), _mm_load_pd(&right[k * 4 + l * 2]));
1250                                       
1251                 al = _mm_hadd_pd(al, al);
1252                 ar = _mm_hadd_pd(ar, ar);
1253                   
1254                 al = _mm_mul_pd(al, ar);
1255                   
1256                 __m128d vv  = _mm_load_pd(x3);
1257                 __m128d EVV = _mm_load_pd(&EV[2 * l]);
1258                 
1259                 vv = _mm_add_pd(vv, _mm_mul_pd(al, EVV));
1260                 
1261                 _mm_store_pd(x3, vv);                                                   
1262               }                   
1263           }
1264       
1265         x3 = &(x3_start[8 * i]);
1266         __m128d minlikelihood_sse = _mm_set1_pd( minlikelihood );
1267         
1268         scale = 1;
1269         for(l = 0; scale && (l < 8); l += 2)
1270           {
1271             __m128d vv = _mm_load_pd(&x3[l]);
1272             __m128d v1 = _mm_and_pd(vv, absMask.m);
1273             v1 = _mm_cmplt_pd(v1,  minlikelihood_sse);
1274             if(_mm_movemask_pd( v1 ) != 3)
1275               scale = 0;
1276           }                     
1277         
1278         if(scale)
1279           {
1280             __m128d twoto = _mm_set_pd(twotothe256, twotothe256);
1281             
1282             for(l = 0; l < 8; l+=2)
1283               {
1284                 __m128d ex3v = _mm_load_pd(&x3[l]);             
1285                 _mm_store_pd(&x3[l], _mm_mul_pd(ex3v,twoto)); 
1286               }                                 
1287             
1288             if(useFastScaling)
1289               addScale += wgt[i];
1290             else
1291               ex3[i]  += 1;     
1292           }     
1293       }
1294      break;
1295
1296    default:
1297      assert(0);
1298    }
1299
1300  if(useFastScaling)
1301    *scalerIncrement = addScale;
1302
1303}
1304
1305#else
1306
1307static void newviewGTRGAMMA_BINARY(int tipCase,
1308                                   double *x1_start, double *x2_start, double *x3_start,
1309                                   double *EV, double *tipVector,
1310                                   int *ex3, unsigned char *tipX1, unsigned char *tipX2,
1311                                   const int n, double *left, double *right, int *wgt, int *scalerIncrement, const boolean useFastScaling
1312                                   )
1313{
1314  double
1315    *x1, *x2, *x3;
1316  double
1317    ump_x1,
1318    ump_x2,
1319    x1px2[4];
1320  int i, j, k, l, scale, addScale = 0;
1321
1322
1323  /* C-OPT figure out if we are at an inner node who has two tips/leaves
1324     as descendants TIP_TIP, a tip and another inner node as descendant
1325     TIP_INNER, or two inner nodes as descendants INNER_INNER */
1326
1327  switch(tipCase)
1328    {
1329    case TIP_TIP:
1330      {
1331        for (i = 0; i < n; i++)
1332          {
1333            x1 = &(tipVector[2 * tipX1[i]]);
1334            x2 = &(tipVector[2 * tipX2[i]]);
1335            x3 = &x3_start[i * 8];
1336
1337            for(j = 0; j < 8; j++)
1338              x3[j] = 0.0;
1339
1340            for (j = 0; j < 4; j++)
1341              {
1342                for (k = 0; k < 2; k++)
1343                  {
1344                    ump_x1 = 0.0;
1345                    ump_x2 = 0.0;
1346
1347                    for (l=0; l < 2; l++)
1348                      {
1349                        ump_x1 += x1[l] * left[ j*4 + k*2 + l];
1350                        ump_x2 += x2[l] * right[j*4 + k*2 + l];
1351                      }
1352
1353                    x1px2[k] = ump_x1 * ump_x2;
1354                  }
1355
1356                for(k = 0; k < 2; k++)
1357                  for (l = 0; l < 2; l++)
1358                    x3[j * 2 + l] +=  x1px2[k] * EV[2 * k + l];
1359
1360              }   
1361          }
1362      }
1363      break;
1364    case TIP_INNER:
1365      {
1366         for (i = 0; i < n; i++)
1367           {
1368             x1 = &(tipVector[2 * tipX1[i]]);
1369             x2 = &x2_start[i * 8];
1370             x3 = &x3_start[i * 8];
1371
1372             for(j = 0; j < 8; j++)
1373               x3[j] = 0.0;
1374
1375             for (j = 0; j < 4; j++)
1376               {
1377                 for (k = 0; k < 2; k++)
1378                   {
1379                     ump_x1 = 0.0;
1380                     ump_x2 = 0.0;
1381
1382                     for (l=0; l < 2; l++)
1383                       {
1384                         ump_x1 += x1[l] * left[ j*4 + k*2 + l];
1385                         ump_x2 += x2[j*2 + l] * right[j*4 + k*2 + l];
1386                       }
1387
1388                     x1px2[k] = ump_x1 * ump_x2;
1389                   }
1390
1391                 for(k = 0; k < 2; k++)
1392                   for (l = 0; l < 2; l++)
1393                     x3[j * 2 + l] +=  x1px2[k] * EV[2 * k + l];
1394
1395               }           
1396
1397             scale = 1;
1398             for(l = 0; scale && (l < 8); l++)
1399               scale = (ABS(x3[l]) <  minlikelihood);
1400
1401             if(scale)
1402               {
1403                 for (l=0; l < 8; l++)
1404                   x3[l] *= twotothe256;
1405                 
1406                 if(useFastScaling)
1407                   addScale += wgt[i];
1408                 else
1409                   ex3[i]  += 1;               
1410               }
1411
1412           }
1413      }
1414      break;
1415    case INNER_INNER:
1416
1417      /* C-OPT here we don't do any pre-computations
1418         This should be the most compute intensive loop of the three
1419         cases here. If we have one or two tips as descendants
1420         we can take a couple of shortcuts */
1421
1422
1423     for (i = 0; i < n; i++)
1424       {
1425         x1 = &x1_start[i * 8];
1426         x2 = &x2_start[i * 8];
1427         x3 = &x3_start[i * 8];
1428
1429         for(j = 0; j < 8; j++)
1430           x3[j] = 0.0;
1431
1432         for (j = 0; j < 4; j++)
1433           {
1434             for (k = 0; k < 2; k++)
1435               {
1436                 ump_x1 = 0.0;
1437                 ump_x2 = 0.0;
1438
1439                 for (l=0; l < 2; l++)
1440                   {
1441                     ump_x1 += x1[j*2 + l] * left[ j*4 + k*2 + l];
1442                     ump_x2 += x2[j*2 + l] * right[j*4 + k*2 + l];
1443                   }
1444
1445                 x1px2[k] = ump_x1 * ump_x2;
1446               }
1447
1448             for(k = 0; k < 2; k++)
1449               for (l = 0; l < 2; l++)
1450                 x3[j * 2 + l] +=  x1px2[k] * EV[2 * k + l];
1451
1452           }
1453         
1454         scale = 1;
1455         for(l = 0; scale && (l < 8); l++)
1456           scale = (ABS(x3[l]) <  minlikelihood);
1457
1458
1459         if(scale)
1460           {
1461             for (l=0; l<8; l++)
1462               x3[l] *= twotothe256;
1463
1464             if(useFastScaling)
1465               addScale += wgt[i];
1466             else
1467               ex3[i]  += 1;     
1468           }
1469       }
1470     break;
1471
1472    default:
1473      assert(0);
1474    }
1475
1476  if(useFastScaling)
1477    *scalerIncrement = addScale;
1478
1479}
1480
1481#endif
1482
1483
1484
1485#ifndef __SIM_SSE3
1486
1487static void newviewGTRCAT( int tipCase,  double *EV,  int *cptr,
1488                           double *x1_start,  double *x2_start,  double *x3_start,  double *tipVector,
1489                           int *ex3, unsigned char *tipX1, unsigned char *tipX2,
1490                           int n,  double *left, double *right, int *wgt, int *scalerIncrement, const boolean useFastScaling)
1491{
1492  double
1493    *le,
1494    *ri,
1495    *x1, *x2, *x3;
1496  double
1497    ump_x1, ump_x2, x1px2[4];
1498  int i, j, k, scale, addScale = 0;
1499
1500  switch(tipCase)
1501    {
1502    case TIP_TIP:
1503      {
1504        for (i = 0; i < n; i++)
1505          {
1506            x1 = &(tipVector[4 * tipX1[i]]);
1507            x2 = &(tipVector[4 * tipX2[i]]);
1508            x3 = &x3_start[4 * i];
1509
1510            le =  &left[cptr[i] * 16];
1511            ri =  &right[cptr[i] * 16];
1512
1513            for(j = 0; j < 4; j++)
1514              {
1515                ump_x1 = 0.0;
1516                ump_x2 = 0.0;
1517                for(k = 0; k < 4; k++)
1518                  {
1519                    ump_x1 += x1[k] * le[j * 4 + k];
1520                    ump_x2 += x2[k] * ri[j * 4 + k];
1521                  }
1522                x1px2[j] = ump_x1 * ump_x2;
1523              }
1524
1525            for(j = 0; j < 4; j++)
1526              x3[j] = 0.0;
1527
1528            for(j = 0; j < 4; j++)
1529              for(k = 0; k < 4; k++)
1530                x3[k] += x1px2[j] * EV[j * 4 + k];         
1531          }
1532      }
1533      break;
1534    case TIP_INNER:
1535      {
1536        for (i = 0; i < n; i++)
1537          {
1538            x1 = &(tipVector[4 * tipX1[i]]);
1539            x2 = &x2_start[4 * i];
1540            x3 = &x3_start[4 * i];
1541
1542            le =  &left[cptr[i] * 16];
1543            ri =  &right[cptr[i] * 16];
1544
1545            for(j = 0; j < 4; j++)
1546              {
1547                ump_x1 = 0.0;
1548                ump_x2 = 0.0;
1549                for(k = 0; k < 4; k++)
1550                  {
1551                    ump_x1 += x1[k] * le[j * 4 + k];
1552                    ump_x2 += x2[k] * ri[j * 4 + k];
1553                  }
1554                x1px2[j] = ump_x1 * ump_x2;
1555              }
1556
1557            for(j = 0; j < 4; j++)
1558              x3[j] = 0.0;
1559
1560            for(j = 0; j < 4; j++)
1561              for(k = 0; k < 4; k++)
1562                x3[k] +=  x1px2[j] *  EV[4 * j + k];       
1563
1564            scale = 1;
1565            for(j = 0; j < 4 && scale; j++)
1566              scale = (x3[j] < minlikelihood && x3[j] > minusminlikelihood);               
1567                   
1568            if(scale)
1569              {             
1570                for(j = 0; j < 4; j++)
1571                  x3[j] *= twotothe256;
1572               
1573                if(useFastScaling)
1574                  addScale += wgt[i];
1575                else
1576                  ex3[i]  += 1;         
1577              }     
1578          }
1579      }
1580      break;
1581    case INNER_INNER:
1582      for (i = 0; i < n; i++)
1583        {
1584          x1 = &x1_start[4 * i];
1585          x2 = &x2_start[4 * i];
1586          x3 = &x3_start[4 * i];
1587
1588          le = &left[cptr[i] * 16];
1589          ri = &right[cptr[i] * 16];
1590
1591          for(j = 0; j < 4; j++)
1592            {
1593              ump_x1 = 0.0;
1594              ump_x2 = 0.0;
1595              for(k = 0; k < 4; k++)
1596                {
1597                  ump_x1 += x1[k] * le[j * 4 + k];
1598                  ump_x2 += x2[k] * ri[j * 4 + k];
1599                }
1600              x1px2[j] = ump_x1 * ump_x2;
1601            }
1602
1603          for(j = 0; j < 4; j++)
1604            x3[j] = 0.0;
1605
1606          for(j = 0; j < 4; j++)
1607            for(k = 0; k < 4; k++)
1608              x3[k] +=  x1px2[j] *  EV[4 * j + k];
1609       
1610          scale = 1;
1611          for(j = 0; j < 4 && scale; j++)
1612            scale = (x3[j] < minlikelihood && x3[j] > minusminlikelihood);
1613
1614          if(scale)
1615            {               
1616              for(j = 0; j < 4; j++)
1617                x3[j] *= twotothe256;
1618             
1619              if(useFastScaling)
1620                addScale += wgt[i];
1621              else
1622                ex3[i]  += 1;           
1623            }     
1624        }
1625      break;
1626    default:
1627      assert(0);
1628    }
1629
1630  if(useFastScaling)
1631    *scalerIncrement = addScale;
1632
1633}
1634
1635#else
1636
1637
1638static void newviewGTRCAT_SAVE( int tipCase,  double *EV,  int *cptr,
1639                                double *x1_start, double *x2_start,  double *x3_start, double *tipVector,
1640                                int *ex3, unsigned char *tipX1, unsigned char *tipX2,
1641                                int n,  double *left, double *right, int *wgt, int *scalerIncrement, const boolean useFastScaling,
1642                                unsigned int *x1_gap, unsigned int *x2_gap, unsigned int *x3_gap,
1643                                double *x1_gapColumn, double *x2_gapColumn, double *x3_gapColumn, const int maxCats)
1644{
1645  double
1646    *le,
1647    *ri,
1648    *x1,
1649    *x2,
1650    *x3,
1651    *x1_ptr = x1_start,
1652    *x2_ptr = x2_start, 
1653    *x3_ptr = x3_start, 
1654    EV_t[16] __attribute__ ((aligned (BYTE_ALIGNMENT)));
1655
1656  int 
1657    i, 
1658    j, 
1659    scale, 
1660    scaleGap = 0,
1661    addScale = 0;
1662
1663  __m128d
1664    minlikelihood_sse = _mm_set1_pd( minlikelihood ),
1665    sc = _mm_set1_pd(twotothe256),
1666    EVV[8]; 
1667
1668  for(i = 0; i < 4; i++)
1669    for (j=0; j < 4; j++)
1670      EV_t[4 * j + i] = EV[4 * i + j];
1671
1672  for(i = 0; i < 8; i++)
1673    EVV[i] = _mm_load_pd(&EV_t[i * 2]);
1674
1675  {
1676    x1 = x1_gapColumn;       
1677    x2 = x2_gapColumn;
1678    x3 = x3_gapColumn;
1679
1680    le =  &left[maxCats * 16];           
1681    ri =  &right[maxCats * 16];                                                 
1682
1683    __m128d x1_0 = _mm_load_pd( &x1[0] );
1684    __m128d x1_2 = _mm_load_pd( &x1[2] );
1685
1686    __m128d left_k0_0 = _mm_load_pd( &le[0] );
1687    __m128d left_k0_2 = _mm_load_pd( &le[2] );
1688    __m128d left_k1_0 = _mm_load_pd( &le[4] );
1689    __m128d left_k1_2 = _mm_load_pd( &le[6] );
1690    __m128d left_k2_0 = _mm_load_pd( &le[8] );
1691    __m128d left_k2_2 = _mm_load_pd( &le[10] );
1692    __m128d left_k3_0 = _mm_load_pd( &le[12] );
1693    __m128d left_k3_2 = _mm_load_pd( &le[14] );
1694
1695    left_k0_0 = _mm_mul_pd(x1_0, left_k0_0);
1696    left_k0_2 = _mm_mul_pd(x1_2, left_k0_2);
1697
1698    left_k1_0 = _mm_mul_pd(x1_0, left_k1_0);
1699    left_k1_2 = _mm_mul_pd(x1_2, left_k1_2);
1700
1701    left_k0_0 = _mm_hadd_pd( left_k0_0, left_k0_2 );
1702    left_k1_0 = _mm_hadd_pd( left_k1_0, left_k1_2);
1703    left_k0_0 = _mm_hadd_pd( left_k0_0, left_k1_0);
1704
1705    left_k2_0 = _mm_mul_pd(x1_0, left_k2_0);
1706    left_k2_2 = _mm_mul_pd(x1_2, left_k2_2);
1707
1708    left_k3_0 = _mm_mul_pd(x1_0, left_k3_0);
1709    left_k3_2 = _mm_mul_pd(x1_2, left_k3_2);
1710
1711    left_k2_0 = _mm_hadd_pd( left_k2_0, left_k2_2);
1712    left_k3_0 = _mm_hadd_pd( left_k3_0, left_k3_2);
1713    left_k2_0 = _mm_hadd_pd( left_k2_0, left_k3_0);
1714
1715    __m128d x2_0 = _mm_load_pd( &x2[0] );
1716    __m128d x2_2 = _mm_load_pd( &x2[2] );
1717
1718    __m128d right_k0_0 = _mm_load_pd( &ri[0] );
1719    __m128d right_k0_2 = _mm_load_pd( &ri[2] );
1720    __m128d right_k1_0 = _mm_load_pd( &ri[4] );
1721    __m128d right_k1_2 = _mm_load_pd( &ri[6] );
1722    __m128d right_k2_0 = _mm_load_pd( &ri[8] );
1723    __m128d right_k2_2 = _mm_load_pd( &ri[10] );
1724    __m128d right_k3_0 = _mm_load_pd( &ri[12] );
1725    __m128d right_k3_2 = _mm_load_pd( &ri[14] );
1726
1727    right_k0_0 = _mm_mul_pd( x2_0, right_k0_0);
1728    right_k0_2 = _mm_mul_pd( x2_2, right_k0_2);
1729
1730    right_k1_0 = _mm_mul_pd( x2_0, right_k1_0);
1731    right_k1_2 = _mm_mul_pd( x2_2, right_k1_2);
1732
1733    right_k0_0 = _mm_hadd_pd( right_k0_0, right_k0_2);
1734    right_k1_0 = _mm_hadd_pd( right_k1_0, right_k1_2);
1735    right_k0_0 = _mm_hadd_pd( right_k0_0, right_k1_0);
1736
1737    right_k2_0 = _mm_mul_pd( x2_0, right_k2_0);
1738    right_k2_2 = _mm_mul_pd( x2_2, right_k2_2);
1739
1740    right_k3_0 = _mm_mul_pd( x2_0, right_k3_0);
1741    right_k3_2 = _mm_mul_pd( x2_2, right_k3_2);
1742
1743    right_k2_0 = _mm_hadd_pd( right_k2_0, right_k2_2);
1744    right_k3_0 = _mm_hadd_pd( right_k3_0, right_k3_2);
1745    right_k2_0 = _mm_hadd_pd( right_k2_0, right_k3_0);     
1746
1747    __m128d x1px2_k0 = _mm_mul_pd( left_k0_0, right_k0_0 );
1748    __m128d x1px2_k2 = _mm_mul_pd( left_k2_0, right_k2_0 );
1749
1750    __m128d EV_t_l0_k0 = EVV[0];
1751    __m128d EV_t_l0_k2 = EVV[1];
1752    __m128d EV_t_l1_k0 = EVV[2];
1753    __m128d EV_t_l1_k2 = EVV[3];
1754    __m128d EV_t_l2_k0 = EVV[4];
1755    __m128d EV_t_l2_k2 = EVV[5];
1756    __m128d EV_t_l3_k0 = EVV[6];
1757    __m128d EV_t_l3_k2 = EVV[7];
1758
1759    EV_t_l0_k0 = _mm_mul_pd( x1px2_k0, EV_t_l0_k0 );
1760    EV_t_l0_k2 = _mm_mul_pd( x1px2_k2, EV_t_l0_k2 );
1761    EV_t_l0_k0 = _mm_hadd_pd( EV_t_l0_k0, EV_t_l0_k2 );
1762
1763    EV_t_l1_k0 = _mm_mul_pd( x1px2_k0, EV_t_l1_k0 );
1764    EV_t_l1_k2 = _mm_mul_pd( x1px2_k2, EV_t_l1_k2 );
1765
1766    EV_t_l1_k0 = _mm_hadd_pd( EV_t_l1_k0, EV_t_l1_k2 );
1767    EV_t_l0_k0 = _mm_hadd_pd( EV_t_l0_k0, EV_t_l1_k0 );
1768
1769    EV_t_l2_k0 = _mm_mul_pd( x1px2_k0, EV_t_l2_k0 );
1770    EV_t_l2_k2 = _mm_mul_pd( x1px2_k2, EV_t_l2_k2 );
1771    EV_t_l2_k0 = _mm_hadd_pd( EV_t_l2_k0, EV_t_l2_k2 );
1772
1773    EV_t_l3_k0 = _mm_mul_pd( x1px2_k0, EV_t_l3_k0 );
1774    EV_t_l3_k2 = _mm_mul_pd( x1px2_k2, EV_t_l3_k2 );
1775    EV_t_l3_k0 = _mm_hadd_pd( EV_t_l3_k0, EV_t_l3_k2 );
1776
1777    EV_t_l2_k0 = _mm_hadd_pd( EV_t_l2_k0, EV_t_l3_k0 );                                   
1778   
1779    if(tipCase != TIP_TIP)
1780      {   
1781        scale = 1;
1782       
1783        __m128d v1 = _mm_and_pd(EV_t_l0_k0, absMask.m);
1784       
1785        v1 = _mm_cmplt_pd(v1,  minlikelihood_sse);
1786       
1787        if(_mm_movemask_pd( v1 ) != 3)
1788          scale = 0;
1789        else
1790          {
1791            v1 = _mm_and_pd(EV_t_l2_k0, absMask.m);
1792            v1 = _mm_cmplt_pd(v1,  minlikelihood_sse);
1793            if(_mm_movemask_pd( v1 ) != 3)
1794              scale = 0;
1795          }
1796
1797      if(scale)
1798        {                     
1799          _mm_store_pd(&x3[0], _mm_mul_pd(EV_t_l0_k0, sc));
1800          _mm_store_pd(&x3[2], _mm_mul_pd(EV_t_l2_k0, sc));                   
1801         
1802          scaleGap = TRUE;         
1803        }       
1804      else
1805        {
1806          _mm_store_pd(x3, EV_t_l0_k0);
1807          _mm_store_pd(&x3[2], EV_t_l2_k0);
1808        }
1809      }
1810    else
1811      {
1812        _mm_store_pd(x3, EV_t_l0_k0);
1813        _mm_store_pd(&x3[2], EV_t_l2_k0);
1814      }
1815  }
1816 
1817  switch(tipCase)
1818    {
1819    case TIP_TIP:     
1820      for (i = 0; i < n; i++)
1821      {
1822        if(noGap(x3_gap, i))
1823        {
1824          x1 = &(tipVector[4 * tipX1[i]]);
1825          x2 = &(tipVector[4 * tipX2[i]]);
1826
1827          x3 = x3_ptr;
1828
1829          if(isGap(x1_gap, i))
1830            le =  &left[maxCats * 16];
1831          else           
1832            le =  &left[cptr[i] * 16];   
1833
1834          if(isGap(x2_gap, i))
1835            ri =  &right[maxCats * 16];
1836          else           
1837            ri =  &right[cptr[i] * 16];
1838
1839          __m128d x1_0 = _mm_load_pd( &x1[0] );
1840          __m128d x1_2 = _mm_load_pd( &x1[2] );
1841
1842          __m128d left_k0_0 = _mm_load_pd( &le[0] );
1843          __m128d left_k0_2 = _mm_load_pd( &le[2] );
1844          __m128d left_k1_0 = _mm_load_pd( &le[4] );
1845          __m128d left_k1_2 = _mm_load_pd( &le[6] );
1846          __m128d left_k2_0 = _mm_load_pd( &le[8] );
1847          __m128d left_k2_2 = _mm_load_pd( &le[10] );
1848          __m128d left_k3_0 = _mm_load_pd( &le[12] );
1849          __m128d left_k3_2 = _mm_load_pd( &le[14] );
1850
1851          left_k0_0 = _mm_mul_pd(x1_0, left_k0_0);
1852          left_k0_2 = _mm_mul_pd(x1_2, left_k0_2);
1853
1854          left_k1_0 = _mm_mul_pd(x1_0, left_k1_0);
1855          left_k1_2 = _mm_mul_pd(x1_2, left_k1_2);
1856
1857          left_k0_0 = _mm_hadd_pd( left_k0_0, left_k0_2 );
1858          left_k1_0 = _mm_hadd_pd( left_k1_0, left_k1_2);
1859          left_k0_0 = _mm_hadd_pd( left_k0_0, left_k1_0);
1860
1861          left_k2_0 = _mm_mul_pd(x1_0, left_k2_0);
1862          left_k2_2 = _mm_mul_pd(x1_2, left_k2_2);
1863
1864          left_k3_0 = _mm_mul_pd(x1_0, left_k3_0);
1865          left_k3_2 = _mm_mul_pd(x1_2, left_k3_2);
1866
1867          left_k2_0 = _mm_hadd_pd( left_k2_0, left_k2_2);
1868          left_k3_0 = _mm_hadd_pd( left_k3_0, left_k3_2);
1869          left_k2_0 = _mm_hadd_pd( left_k2_0, left_k3_0);
1870
1871          __m128d x2_0 = _mm_load_pd( &x2[0] );
1872          __m128d x2_2 = _mm_load_pd( &x2[2] );
1873
1874          __m128d right_k0_0 = _mm_load_pd( &ri[0] );
1875          __m128d right_k0_2 = _mm_load_pd( &ri[2] );
1876          __m128d right_k1_0 = _mm_load_pd( &ri[4] );
1877          __m128d right_k1_2 = _mm_load_pd( &ri[6] );
1878          __m128d right_k2_0 = _mm_load_pd( &ri[8] );
1879          __m128d right_k2_2 = _mm_load_pd( &ri[10] );
1880          __m128d right_k3_0 = _mm_load_pd( &ri[12] );
1881          __m128d right_k3_2 = _mm_load_pd( &ri[14] );
1882
1883          right_k0_0 = _mm_mul_pd( x2_0, right_k0_0);
1884          right_k0_2 = _mm_mul_pd( x2_2, right_k0_2);
1885
1886          right_k1_0 = _mm_mul_pd( x2_0, right_k1_0);
1887          right_k1_2 = _mm_mul_pd( x2_2, right_k1_2);
1888
1889          right_k0_0 = _mm_hadd_pd( right_k0_0, right_k0_2);
1890          right_k1_0 = _mm_hadd_pd( right_k1_0, right_k1_2);
1891          right_k0_0 = _mm_hadd_pd( right_k0_0, right_k1_0);
1892
1893          right_k2_0 = _mm_mul_pd( x2_0, right_k2_0);
1894          right_k2_2 = _mm_mul_pd( x2_2, right_k2_2);
1895
1896          right_k3_0 = _mm_mul_pd( x2_0, right_k3_0);
1897          right_k3_2 = _mm_mul_pd( x2_2, right_k3_2);
1898
1899          right_k2_0 = _mm_hadd_pd( right_k2_0, right_k2_2);
1900          right_k3_0 = _mm_hadd_pd( right_k3_0, right_k3_2);
1901          right_k2_0 = _mm_hadd_pd( right_k2_0, right_k3_0);       
1902
1903          __m128d x1px2_k0 = _mm_mul_pd( left_k0_0, right_k0_0 );
1904          __m128d x1px2_k2 = _mm_mul_pd( left_k2_0, right_k2_0 );                 
1905
1906          __m128d EV_t_l0_k0 = EVV[0];
1907          __m128d EV_t_l0_k2 = EVV[1];
1908          __m128d EV_t_l1_k0 = EVV[2];
1909          __m128d EV_t_l1_k2 = EVV[3];
1910          __m128d EV_t_l2_k0 = EVV[4];
1911          __m128d EV_t_l2_k2 = EVV[5];
1912          __m128d EV_t_l3_k0 = EVV[6];
1913          __m128d EV_t_l3_k2 = EVV[7];
1914
1915          EV_t_l0_k0 = _mm_mul_pd( x1px2_k0, EV_t_l0_k0 );
1916          EV_t_l0_k2 = _mm_mul_pd( x1px2_k2, EV_t_l0_k2 );
1917          EV_t_l0_k0 = _mm_hadd_pd( EV_t_l0_k0, EV_t_l0_k2 );
1918
1919          EV_t_l1_k0 = _mm_mul_pd( x1px2_k0, EV_t_l1_k0 );
1920          EV_t_l1_k2 = _mm_mul_pd( x1px2_k2, EV_t_l1_k2 );
1921
1922          EV_t_l1_k0 = _mm_hadd_pd( EV_t_l1_k0, EV_t_l1_k2 );
1923          EV_t_l0_k0 = _mm_hadd_pd( EV_t_l0_k0, EV_t_l1_k0 );
1924
1925          EV_t_l2_k0 = _mm_mul_pd( x1px2_k0, EV_t_l2_k0 );
1926          EV_t_l2_k2 = _mm_mul_pd( x1px2_k2, EV_t_l2_k2 );
1927          EV_t_l2_k0 = _mm_hadd_pd( EV_t_l2_k0, EV_t_l2_k2 );
1928
1929          EV_t_l3_k0 = _mm_mul_pd( x1px2_k0, EV_t_l3_k0 );
1930          EV_t_l3_k2 = _mm_mul_pd( x1px2_k2, EV_t_l3_k2 );
1931          EV_t_l3_k0 = _mm_hadd_pd( EV_t_l3_k0, EV_t_l3_k2 );
1932
1933          EV_t_l2_k0 = _mm_hadd_pd( EV_t_l2_k0, EV_t_l3_k0 );   
1934
1935          _mm_store_pd(x3, EV_t_l0_k0);
1936          _mm_store_pd(&x3[2], EV_t_l2_k0);                                 
1937
1938          x3_ptr += 4;
1939        }
1940      }
1941      break;
1942    case TIP_INNER:     
1943      for (i = 0; i < n; i++)
1944      { 
1945        if(isGap(x3_gap, i))
1946        {
1947          if(scaleGap)
1948            {
1949              if(useFastScaling)
1950                addScale += wgt[i];
1951              else
1952                ex3[i] += 1;
1953            }           
1954        }
1955        else
1956        {             
1957          x1 = &(tipVector[4 * tipX1[i]]);
1958
1959          x2 = x2_ptr;
1960          x3 = x3_ptr;
1961
1962          if(isGap(x1_gap, i))
1963            le =  &left[maxCats * 16];
1964          else
1965            le =  &left[cptr[i] * 16];
1966
1967          if(isGap(x2_gap, i))
1968          {             
1969            ri =  &right[maxCats * 16];
1970            x2 = x2_gapColumn;
1971          }
1972          else
1973          {
1974            ri =  &right[cptr[i] * 16];
1975            x2 = x2_ptr;
1976            x2_ptr += 4;
1977          }                               
1978
1979          __m128d x1_0 = _mm_load_pd( &x1[0] );
1980          __m128d x1_2 = _mm_load_pd( &x1[2] );
1981
1982          __m128d left_k0_0 = _mm_load_pd( &le[0] );
1983          __m128d left_k0_2 = _mm_load_pd( &le[2] );
1984          __m128d left_k1_0 = _mm_load_pd( &le[4] );
1985          __m128d left_k1_2 = _mm_load_pd( &le[6] );
1986          __m128d left_k2_0 = _mm_load_pd( &le[8] );
1987          __m128d left_k2_2 = _mm_load_pd( &le[10] );
1988          __m128d left_k3_0 = _mm_load_pd( &le[12] );
1989          __m128d left_k3_2 = _mm_load_pd( &le[14] );
1990
1991          left_k0_0 = _mm_mul_pd(x1_0, left_k0_0);
1992          left_k0_2 = _mm_mul_pd(x1_2, left_k0_2);
1993
1994          left_k1_0 = _mm_mul_pd(x1_0, left_k1_0);
1995          left_k1_2 = _mm_mul_pd(x1_2, left_k1_2);
1996
1997          left_k0_0 = _mm_hadd_pd( left_k0_0, left_k0_2 );
1998          left_k1_0 = _mm_hadd_pd( left_k1_0, left_k1_2);
1999          left_k0_0 = _mm_hadd_pd( left_k0_0, left_k1_0);
2000
2001          left_k2_0 = _mm_mul_pd(x1_0, left_k2_0);
2002          left_k2_2 = _mm_mul_pd(x1_2, left_k2_2);
2003
2004          left_k3_0 = _mm_mul_pd(x1_0, left_k3_0);
2005          left_k3_2 = _mm_mul_pd(x1_2, left_k3_2);
2006
2007          left_k2_0 = _mm_hadd_pd( left_k2_0, left_k2_2);
2008          left_k3_0 = _mm_hadd_pd( left_k3_0, left_k3_2);
2009          left_k2_0 = _mm_hadd_pd( left_k2_0, left_k3_0);
2010
2011          __m128d x2_0 = _mm_load_pd( &x2[0] );
2012          __m128d x2_2 = _mm_load_pd( &x2[2] );
2013
2014          __m128d right_k0_0 = _mm_load_pd( &ri[0] );
2015          __m128d right_k0_2 = _mm_load_pd( &ri[2] );
2016          __m128d right_k1_0 = _mm_load_pd( &ri[4] );
2017          __m128d right_k1_2 = _mm_load_pd( &ri[6] );
2018          __m128d right_k2_0 = _mm_load_pd( &ri[8] );
2019          __m128d right_k2_2 = _mm_load_pd( &ri[10] );
2020          __m128d right_k3_0 = _mm_load_pd( &ri[12] );
2021          __m128d right_k3_2 = _mm_load_pd( &ri[14] );
2022
2023          right_k0_0 = _mm_mul_pd( x2_0, right_k0_0);
2024          right_k0_2 = _mm_mul_pd( x2_2, right_k0_2);
2025
2026          right_k1_0 = _mm_mul_pd( x2_0, right_k1_0);
2027          right_k1_2 = _mm_mul_pd( x2_2, right_k1_2);
2028
2029          right_k0_0 = _mm_hadd_pd( right_k0_0, right_k0_2);
2030          right_k1_0 = _mm_hadd_pd( right_k1_0, right_k1_2);
2031          right_k0_0 = _mm_hadd_pd( right_k0_0, right_k1_0);
2032
2033          right_k2_0 = _mm_mul_pd( x2_0, right_k2_0);
2034          right_k2_2 = _mm_mul_pd( x2_2, right_k2_2);
2035
2036          right_k3_0 = _mm_mul_pd( x2_0, right_k3_0);
2037          right_k3_2 = _mm_mul_pd( x2_2, right_k3_2);
2038
2039          right_k2_0 = _mm_hadd_pd( right_k2_0, right_k2_2);
2040          right_k3_0 = _mm_hadd_pd( right_k3_0, right_k3_2);
2041          right_k2_0 = _mm_hadd_pd( right_k2_0, right_k3_0);       
2042
2043          __m128d x1px2_k0 = _mm_mul_pd( left_k0_0, right_k0_0 );
2044          __m128d x1px2_k2 = _mm_mul_pd( left_k2_0, right_k2_0 );
2045
2046          __m128d EV_t_l0_k0 = EVV[0];
2047          __m128d EV_t_l0_k2 = EVV[1];
2048          __m128d EV_t_l1_k0 = EVV[2];
2049          __m128d EV_t_l1_k2 = EVV[3];
2050          __m128d EV_t_l2_k0 = EVV[4];
2051          __m128d EV_t_l2_k2 = EVV[5];
2052          __m128d EV_t_l3_k0 = EVV[6];
2053          __m128d EV_t_l3_k2 = EVV[7];
2054
2055
2056          EV_t_l0_k0 = _mm_mul_pd( x1px2_k0, EV_t_l0_k0 );
2057          EV_t_l0_k2 = _mm_mul_pd( x1px2_k2, EV_t_l0_k2 );
2058          EV_t_l0_k0 = _mm_hadd_pd( EV_t_l0_k0, EV_t_l0_k2 );
2059
2060          EV_t_l1_k0 = _mm_mul_pd( x1px2_k0, EV_t_l1_k0 );
2061          EV_t_l1_k2 = _mm_mul_pd( x1px2_k2, EV_t_l1_k2 );
2062
2063          EV_t_l1_k0 = _mm_hadd_pd( EV_t_l1_k0, EV_t_l1_k2 );
2064          EV_t_l0_k0 = _mm_hadd_pd( EV_t_l0_k0, EV_t_l1_k0 );
2065
2066          EV_t_l2_k0 = _mm_mul_pd( x1px2_k0, EV_t_l2_k0 );
2067          EV_t_l2_k2 = _mm_mul_pd( x1px2_k2, EV_t_l2_k2 );
2068          EV_t_l2_k0 = _mm_hadd_pd( EV_t_l2_k0, EV_t_l2_k2 );
2069
2070          EV_t_l3_k0 = _mm_mul_pd( x1px2_k0, EV_t_l3_k0 );
2071          EV_t_l3_k2 = _mm_mul_pd( x1px2_k2, EV_t_l3_k2 );
2072          EV_t_l3_k0 = _mm_hadd_pd( EV_t_l3_k0, EV_t_l3_k2 );
2073
2074          EV_t_l2_k0 = _mm_hadd_pd( EV_t_l2_k0, EV_t_l3_k0 );                                     
2075
2076          scale = 1;
2077
2078          __m128d v1 = _mm_and_pd(EV_t_l0_k0, absMask.m);
2079          v1 = _mm_cmplt_pd(v1,  minlikelihood_sse);
2080          if(_mm_movemask_pd( v1 ) != 3)
2081            scale = 0;
2082          else
2083          {
2084            v1 = _mm_and_pd(EV_t_l2_k0, absMask.m);
2085            v1 = _mm_cmplt_pd(v1,  minlikelihood_sse);
2086            if(_mm_movemask_pd( v1 ) != 3)
2087              scale = 0;
2088          }
2089
2090          if(scale)
2091          {                   
2092            _mm_store_pd(&x3[0], _mm_mul_pd(EV_t_l0_k0, sc));
2093            _mm_store_pd(&x3[2], _mm_mul_pd(EV_t_l2_k0, sc));                 
2094
2095            if(useFastScaling)
2096              addScale += wgt[i];
2097            else
2098              ex3[i] += 1;           
2099          }     
2100          else
2101          {
2102            _mm_store_pd(x3, EV_t_l0_k0);
2103            _mm_store_pd(&x3[2], EV_t_l2_k0);
2104          }
2105
2106          x3_ptr += 4;
2107        }
2108
2109      }
2110      break;
2111    case INNER_INNER:
2112      for (i = 0; i < n; i++)
2113        { 
2114          if(isGap(x3_gap, i))
2115            {
2116              if(scaleGap)
2117                {
2118                  if(useFastScaling)
2119                    addScale += wgt[i];
2120                  else
2121                    ex3[i] += 1;
2122                }
2123            }
2124          else
2125            {       
2126              x3 = x3_ptr;
2127             
2128              if(isGap(x1_gap, i))
2129                {
2130                  x1 = x1_gapColumn;
2131                  le =  &left[maxCats * 16];
2132                }
2133              else
2134                {
2135                  le =  &left[cptr[i] * 16];
2136                  x1 = x1_ptr;
2137                  x1_ptr += 4;
2138                }
2139
2140              if(isGap(x2_gap, i))     
2141                {
2142                  x2 = x2_gapColumn;
2143                  ri =  &right[maxCats * 16];       
2144                }
2145              else
2146                {
2147                  ri =  &right[cptr[i] * 16];
2148                  x2 = x2_ptr;
2149                  x2_ptr += 4;
2150                }                                 
2151
2152              __m128d x1_0 = _mm_load_pd( &x1[0] );
2153              __m128d x1_2 = _mm_load_pd( &x1[2] );
2154             
2155              __m128d left_k0_0 = _mm_load_pd( &le[0] );
2156              __m128d left_k0_2 = _mm_load_pd( &le[2] );
2157              __m128d left_k1_0 = _mm_load_pd( &le[4] );
2158              __m128d left_k1_2 = _mm_load_pd( &le[6] );
2159              __m128d left_k2_0 = _mm_load_pd( &le[8] );
2160              __m128d left_k2_2 = _mm_load_pd( &le[10] );
2161              __m128d left_k3_0 = _mm_load_pd( &le[12] );
2162              __m128d left_k3_2 = _mm_load_pd( &le[14] );
2163             
2164              left_k0_0 = _mm_mul_pd(x1_0, left_k0_0);
2165              left_k0_2 = _mm_mul_pd(x1_2, left_k0_2);
2166             
2167              left_k1_0 = _mm_mul_pd(x1_0, left_k1_0);
2168              left_k1_2 = _mm_mul_pd(x1_2, left_k1_2);
2169             
2170              left_k0_0 = _mm_hadd_pd( left_k0_0, left_k0_2 );
2171              left_k1_0 = _mm_hadd_pd( left_k1_0, left_k1_2);
2172              left_k0_0 = _mm_hadd_pd( left_k0_0, left_k1_0);
2173             
2174              left_k2_0 = _mm_mul_pd(x1_0, left_k2_0);
2175              left_k2_2 = _mm_mul_pd(x1_2, left_k2_2);
2176             
2177              left_k3_0 = _mm_mul_pd(x1_0, left_k3_0);
2178              left_k3_2 = _mm_mul_pd(x1_2, left_k3_2);
2179             
2180              left_k2_0 = _mm_hadd_pd( left_k2_0, left_k2_2);
2181              left_k3_0 = _mm_hadd_pd( left_k3_0, left_k3_2);
2182              left_k2_0 = _mm_hadd_pd( left_k2_0, left_k3_0);
2183             
2184              __m128d x2_0 = _mm_load_pd( &x2[0] );
2185              __m128d x2_2 = _mm_load_pd( &x2[2] );
2186             
2187              __m128d right_k0_0 = _mm_load_pd( &ri[0] );
2188              __m128d right_k0_2 = _mm_load_pd( &ri[2] );
2189              __m128d right_k1_0 = _mm_load_pd( &ri[4] );
2190              __m128d right_k1_2 = _mm_load_pd( &ri[6] );
2191              __m128d right_k2_0 = _mm_load_pd( &ri[8] );
2192              __m128d right_k2_2 = _mm_load_pd( &ri[10] );
2193              __m128d right_k3_0 = _mm_load_pd( &ri[12] );
2194              __m128d right_k3_2 = _mm_load_pd( &ri[14] );
2195             
2196              right_k0_0 = _mm_mul_pd( x2_0, right_k0_0);
2197              right_k0_2 = _mm_mul_pd( x2_2, right_k0_2);
2198             
2199              right_k1_0 = _mm_mul_pd( x2_0, right_k1_0);
2200              right_k1_2 = _mm_mul_pd( x2_2, right_k1_2);
2201             
2202              right_k0_0 = _mm_hadd_pd( right_k0_0, right_k0_2);
2203              right_k1_0 = _mm_hadd_pd( right_k1_0, right_k1_2);
2204              right_k0_0 = _mm_hadd_pd( right_k0_0, right_k1_0);
2205             
2206              right_k2_0 = _mm_mul_pd( x2_0, right_k2_0);
2207              right_k2_2 = _mm_mul_pd( x2_2, right_k2_2);
2208             
2209              right_k3_0 = _mm_mul_pd( x2_0, right_k3_0);
2210              right_k3_2 = _mm_mul_pd( x2_2, right_k3_2);
2211             
2212              right_k2_0 = _mm_hadd_pd( right_k2_0, right_k2_2);
2213              right_k3_0 = _mm_hadd_pd( right_k3_0, right_k3_2);
2214              right_k2_0 = _mm_hadd_pd( right_k2_0, right_k3_0);           
2215             
2216              __m128d x1px2_k0 = _mm_mul_pd( left_k0_0, right_k0_0 );
2217              __m128d x1px2_k2 = _mm_mul_pd( left_k2_0, right_k2_0 );
2218             
2219              __m128d EV_t_l0_k0 = EVV[0];
2220              __m128d EV_t_l0_k2 = EVV[1];
2221              __m128d EV_t_l1_k0 = EVV[2];
2222              __m128d EV_t_l1_k2 = EVV[3];
2223              __m128d EV_t_l2_k0 = EVV[4];
2224              __m128d EV_t_l2_k2 = EVV[5];
2225              __m128d EV_t_l3_k0 = EVV[6];
2226              __m128d EV_t_l3_k2 = EVV[7];
2227
2228              EV_t_l0_k0 = _mm_mul_pd( x1px2_k0, EV_t_l0_k0 );
2229              EV_t_l0_k2 = _mm_mul_pd( x1px2_k2, EV_t_l0_k2 );
2230              EV_t_l0_k0 = _mm_hadd_pd( EV_t_l0_k0, EV_t_l0_k2 );
2231             
2232              EV_t_l1_k0 = _mm_mul_pd( x1px2_k0, EV_t_l1_k0 );
2233              EV_t_l1_k2 = _mm_mul_pd( x1px2_k2, EV_t_l1_k2 );
2234             
2235              EV_t_l1_k0 = _mm_hadd_pd( EV_t_l1_k0, EV_t_l1_k2 );
2236              EV_t_l0_k0 = _mm_hadd_pd( EV_t_l0_k0, EV_t_l1_k0 );
2237             
2238              EV_t_l2_k0 = _mm_mul_pd( x1px2_k0, EV_t_l2_k0 );
2239              EV_t_l2_k2 = _mm_mul_pd( x1px2_k2, EV_t_l2_k2 );
2240              EV_t_l2_k0 = _mm_hadd_pd( EV_t_l2_k0, EV_t_l2_k2 );
2241             
2242              EV_t_l3_k0 = _mm_mul_pd( x1px2_k0, EV_t_l3_k0 );
2243              EV_t_l3_k2 = _mm_mul_pd( x1px2_k2, EV_t_l3_k2 );
2244              EV_t_l3_k0 = _mm_hadd_pd( EV_t_l3_k0, EV_t_l3_k2 );
2245             
2246              EV_t_l2_k0 = _mm_hadd_pd( EV_t_l2_k0, EV_t_l3_k0 );                                               
2247             
2248              scale = 1;
2249             
2250              __m128d v1 = _mm_and_pd(EV_t_l0_k0, absMask.m);
2251              v1 = _mm_cmplt_pd(v1,  minlikelihood_sse);
2252              if(_mm_movemask_pd( v1 ) != 3)
2253                scale = 0;
2254              else
2255                {
2256                  v1 = _mm_and_pd(EV_t_l2_k0, absMask.m);
2257                  v1 = _mm_cmplt_pd(v1,  minlikelihood_sse);
2258                  if(_mm_movemask_pd( v1 ) != 3)
2259                    scale = 0;
2260                }
2261
2262              if(scale)
2263                {                     
2264                  EV_t_l0_k0 = _mm_mul_pd(EV_t_l0_k0, sc);
2265                  EV_t_l2_k0 = _mm_mul_pd(EV_t_l2_k0, sc);                   
2266                 
2267                  if(useFastScaling)
2268                    addScale += wgt[i];
2269                  else
2270                    ex3[i] += 1;           
2271                }       
2272
2273              _mm_store_pd(&x3[0], EV_t_l0_k0);
2274              _mm_store_pd(&x3[2], EV_t_l2_k0);
2275             
2276              x3_ptr += 4;
2277            }
2278        }
2279      break;
2280    default:
2281      assert(0);
2282  }
2283
2284  if(useFastScaling)
2285    *scalerIncrement = addScale;
2286}
2287
2288
2289static void newviewGTRCAT( int tipCase,  double *EV,  int *cptr,
2290                           double *x1_start, double *x2_start,  double *x3_start, double *tipVector,
2291                           int *ex3, unsigned char *tipX1, unsigned char *tipX2,
2292                           int n,  double *left, double *right, int *wgt, int *scalerIncrement, const boolean useFastScaling)
2293{
2294  double
2295    *le,
2296    *ri,
2297    *x1,
2298    *x2, 
2299    *x3, 
2300    EV_t[16] __attribute__ ((aligned (BYTE_ALIGNMENT)));
2301   
2302  int 
2303    i, 
2304    j, 
2305    scale, 
2306    addScale = 0;
2307   
2308  __m128d
2309    minlikelihood_sse = _mm_set1_pd( minlikelihood ),
2310    sc = _mm_set1_pd(twotothe256),
2311    EVV[8]; 
2312 
2313  for(i = 0; i < 4; i++)
2314    for (j=0; j < 4; j++)
2315      EV_t[4 * j + i] = EV[4 * i + j];
2316 
2317  for(i = 0; i < 8; i++)
2318    EVV[i] = _mm_load_pd(&EV_t[i * 2]);
2319 
2320  switch(tipCase)
2321    {
2322    case TIP_TIP:     
2323      for (i = 0; i < n; i++)
2324        {       
2325          x1 = &(tipVector[4 * tipX1[i]]);
2326          x2 = &(tipVector[4 * tipX2[i]]);
2327         
2328          x3 = &x3_start[i * 4];
2329         
2330          le =  &left[cptr[i] * 16];
2331          ri =  &right[cptr[i] * 16];
2332         
2333          __m128d x1_0 = _mm_load_pd( &x1[0] );
2334          __m128d x1_2 = _mm_load_pd( &x1[2] );
2335         
2336          __m128d left_k0_0 = _mm_load_pd( &le[0] );
2337          __m128d left_k0_2 = _mm_load_pd( &le[2] );
2338          __m128d left_k1_0 = _mm_load_pd( &le[4] );
2339          __m128d left_k1_2 = _mm_load_pd( &le[6] );
2340          __m128d left_k2_0 = _mm_load_pd( &le[8] );
2341          __m128d left_k2_2 = _mm_load_pd( &le[10] );
2342          __m128d left_k3_0 = _mm_load_pd( &le[12] );
2343          __m128d left_k3_2 = _mm_load_pd( &le[14] );
2344         
2345          left_k0_0 = _mm_mul_pd(x1_0, left_k0_0);
2346          left_k0_2 = _mm_mul_pd(x1_2, left_k0_2);
2347         
2348          left_k1_0 = _mm_mul_pd(x1_0, left_k1_0);
2349          left_k1_2 = _mm_mul_pd(x1_2, left_k1_2);
2350         
2351          left_k0_0 = _mm_hadd_pd( left_k0_0, left_k0_2 );
2352          left_k1_0 = _mm_hadd_pd( left_k1_0, left_k1_2);
2353          left_k0_0 = _mm_hadd_pd( left_k0_0, left_k1_0);
2354         
2355          left_k2_0 = _mm_mul_pd(x1_0, left_k2_0);
2356          left_k2_2 = _mm_mul_pd(x1_2, left_k2_2);
2357         
2358          left_k3_0 = _mm_mul_pd(x1_0, left_k3_0);
2359          left_k3_2 = _mm_mul_pd(x1_2, left_k3_2);
2360         
2361          left_k2_0 = _mm_hadd_pd( left_k2_0, left_k2_2);
2362          left_k3_0 = _mm_hadd_pd( left_k3_0, left_k3_2);
2363          left_k2_0 = _mm_hadd_pd( left_k2_0, left_k3_0);
2364         
2365          __m128d x2_0 = _mm_load_pd( &x2[0] );
2366          __m128d x2_2 = _mm_load_pd( &x2[2] );
2367         
2368          __m128d right_k0_0 = _mm_load_pd( &ri[0] );
2369          __m128d right_k0_2 = _mm_load_pd( &ri[2] );
2370          __m128d right_k1_0 = _mm_load_pd( &ri[4] );
2371          __m128d right_k1_2 = _mm_load_pd( &ri[6] );
2372          __m128d right_k2_0 = _mm_load_pd( &ri[8] );
2373          __m128d right_k2_2 = _mm_load_pd( &ri[10] );
2374          __m128d right_k3_0 = _mm_load_pd( &ri[12] );
2375          __m128d right_k3_2 = _mm_load_pd( &ri[14] );
2376         
2377          right_k0_0 = _mm_mul_pd( x2_0, right_k0_0);
2378          right_k0_2 = _mm_mul_pd( x2_2, right_k0_2);
2379         
2380          right_k1_0 = _mm_mul_pd( x2_0, right_k1_0);
2381          right_k1_2 = _mm_mul_pd( x2_2, right_k1_2);
2382         
2383          right_k0_0 = _mm_hadd_pd( right_k0_0, right_k0_2);
2384          right_k1_0 = _mm_hadd_pd( right_k1_0, right_k1_2);
2385          right_k0_0 = _mm_hadd_pd( right_k0_0, right_k1_0);
2386         
2387          right_k2_0 = _mm_mul_pd( x2_0, right_k2_0);
2388          right_k2_2 = _mm_mul_pd( x2_2, right_k2_2);
2389         
2390          right_k3_0 = _mm_mul_pd( x2_0, right_k3_0);
2391          right_k3_2 = _mm_mul_pd( x2_2, right_k3_2);
2392         
2393          right_k2_0 = _mm_hadd_pd( right_k2_0, right_k2_2);
2394          right_k3_0 = _mm_hadd_pd( right_k3_0, right_k3_2);
2395          right_k2_0 = _mm_hadd_pd( right_k2_0, right_k3_0);       
2396         
2397          __m128d x1px2_k0 = _mm_mul_pd( left_k0_0, right_k0_0 );
2398          __m128d x1px2_k2 = _mm_mul_pd( left_k2_0, right_k2_0 );                 
2399
2400          __m128d EV_t_l0_k0 = EVV[0];
2401          __m128d EV_t_l0_k2 = EVV[1];
2402          __m128d EV_t_l1_k0 = EVV[2];
2403          __m128d EV_t_l1_k2 = EVV[3];
2404          __m128d EV_t_l2_k0 = EVV[4];
2405          __m128d EV_t_l2_k2 = EVV[5];
2406          __m128d EV_t_l3_k0 = EVV[6];
2407          __m128d EV_t_l3_k2 = EVV[7];
2408         
2409          EV_t_l0_k0 = _mm_mul_pd( x1px2_k0, EV_t_l0_k0 );
2410          EV_t_l0_k2 = _mm_mul_pd( x1px2_k2, EV_t_l0_k2 );
2411          EV_t_l0_k0 = _mm_hadd_pd( EV_t_l0_k0, EV_t_l0_k2 );
2412         
2413          EV_t_l1_k0 = _mm_mul_pd( x1px2_k0, EV_t_l1_k0 );
2414          EV_t_l1_k2 = _mm_mul_pd( x1px2_k2, EV_t_l1_k2 );
2415         
2416          EV_t_l1_k0 = _mm_hadd_pd( EV_t_l1_k0, EV_t_l1_k2 );
2417          EV_t_l0_k0 = _mm_hadd_pd( EV_t_l0_k0, EV_t_l1_k0 );
2418         
2419          EV_t_l2_k0 = _mm_mul_pd( x1px2_k0, EV_t_l2_k0 );
2420          EV_t_l2_k2 = _mm_mul_pd( x1px2_k2, EV_t_l2_k2 );
2421          EV_t_l2_k0 = _mm_hadd_pd( EV_t_l2_k0, EV_t_l2_k2 );
2422                 
2423          EV_t_l3_k0 = _mm_mul_pd( x1px2_k0, EV_t_l3_k0 );
2424          EV_t_l3_k2 = _mm_mul_pd( x1px2_k2, EV_t_l3_k2 );
2425          EV_t_l3_k0 = _mm_hadd_pd( EV_t_l3_k0, EV_t_l3_k2 );
2426         
2427          EV_t_l2_k0 = _mm_hadd_pd( EV_t_l2_k0, EV_t_l3_k0 );   
2428                 
2429          _mm_store_pd(x3, EV_t_l0_k0);
2430          _mm_store_pd(&x3[2], EV_t_l2_k0);                                 
2431        }
2432      break;
2433    case TIP_INNER:     
2434      for (i = 0; i < n; i++)
2435        {
2436          x1 = &(tipVector[4 * tipX1[i]]);
2437          x2 = &x2_start[4 * i];
2438          x3 = &x3_start[4 * i];
2439         
2440          le =  &left[cptr[i] * 16];
2441          ri =  &right[cptr[i] * 16];
2442
2443          __m128d x1_0 = _mm_load_pd( &x1[0] );
2444          __m128d x1_2 = _mm_load_pd( &x1[2] );
2445         
2446          __m128d left_k0_0 = _mm_load_pd( &le[0] );
2447          __m128d left_k0_2 = _mm_load_pd( &le[2] );
2448          __m128d left_k1_0 = _mm_load_pd( &le[4] );
2449          __m128d left_k1_2 = _mm_load_pd( &le[6] );
2450          __m128d left_k2_0 = _mm_load_pd( &le[8] );
2451          __m128d left_k2_2 = _mm_load_pd( &le[10] );
2452          __m128d left_k3_0 = _mm_load_pd( &le[12] );
2453          __m128d left_k3_2 = _mm_load_pd( &le[14] );
2454         
2455          left_k0_0 = _mm_mul_pd(x1_0, left_k0_0);
2456          left_k0_2 = _mm_mul_pd(x1_2, left_k0_2);
2457         
2458          left_k1_0 = _mm_mul_pd(x1_0, left_k1_0);
2459          left_k1_2 = _mm_mul_pd(x1_2, left_k1_2);
2460         
2461          left_k0_0 = _mm_hadd_pd( left_k0_0, left_k0_2 );
2462          left_k1_0 = _mm_hadd_pd( left_k1_0, left_k1_2);
2463          left_k0_0 = _mm_hadd_pd( left_k0_0, left_k1_0);
2464         
2465          left_k2_0 = _mm_mul_pd(x1_0, left_k2_0);
2466          left_k2_2 = _mm_mul_pd(x1_2, left_k2_2);
2467         
2468          left_k3_0 = _mm_mul_pd(x1_0, left_k3_0);
2469          left_k3_2 = _mm_mul_pd(x1_2, left_k3_2);
2470         
2471          left_k2_0 = _mm_hadd_pd( left_k2_0, left_k2_2);
2472          left_k3_0 = _mm_hadd_pd( left_k3_0, left_k3_2);
2473          left_k2_0 = _mm_hadd_pd( left_k2_0, left_k3_0);
2474         
2475          __m128d x2_0 = _mm_load_pd( &x2[0] );
2476          __m128d x2_2 = _mm_load_pd( &x2[2] );
2477         
2478          __m128d right_k0_0 = _mm_load_pd( &ri[0] );
2479          __m128d right_k0_2 = _mm_load_pd( &ri[2] );
2480          __m128d right_k1_0 = _mm_load_pd( &ri[4] );
2481          __m128d right_k1_2 = _mm_load_pd( &ri[6] );
2482          __m128d right_k2_0 = _mm_load_pd( &ri[8] );
2483          __m128d right_k2_2 = _mm_load_pd( &ri[10] );
2484          __m128d right_k3_0 = _mm_load_pd( &ri[12] );
2485          __m128d right_k3_2 = _mm_load_pd( &ri[14] );
2486         
2487          right_k0_0 = _mm_mul_pd( x2_0, right_k0_0);
2488          right_k0_2 = _mm_mul_pd( x2_2, right_k0_2);
2489         
2490          right_k1_0 = _mm_mul_pd( x2_0, right_k1_0);
2491          right_k1_2 = _mm_mul_pd( x2_2, right_k1_2);
2492         
2493          right_k0_0 = _mm_hadd_pd( right_k0_0, right_k0_2);
2494          right_k1_0 = _mm_hadd_pd( right_k1_0, right_k1_2);
2495          right_k0_0 = _mm_hadd_pd( right_k0_0, right_k1_0);
2496         
2497          right_k2_0 = _mm_mul_pd( x2_0, right_k2_0);
2498          right_k2_2 = _mm_mul_pd( x2_2, right_k2_2);
2499         
2500          right_k3_0 = _mm_mul_pd( x2_0, right_k3_0);
2501          right_k3_2 = _mm_mul_pd( x2_2, right_k3_2);
2502         
2503          right_k2_0 = _mm_hadd_pd( right_k2_0, right_k2_2);
2504          right_k3_0 = _mm_hadd_pd( right_k3_0, right_k3_2);
2505          right_k2_0 = _mm_hadd_pd( right_k2_0, right_k3_0);       
2506         
2507          __m128d x1px2_k0 = _mm_mul_pd( left_k0_0, right_k0_0 );
2508          __m128d x1px2_k2 = _mm_mul_pd( left_k2_0, right_k2_0 );
2509         
2510          __m128d EV_t_l0_k0 = EVV[0];
2511          __m128d EV_t_l0_k2 = EVV[1];
2512          __m128d EV_t_l1_k0 = EVV[2];
2513          __m128d EV_t_l1_k2 = EVV[3];
2514          __m128d EV_t_l2_k0 = EVV[4];
2515          __m128d EV_t_l2_k2 = EVV[5];
2516          __m128d EV_t_l3_k0 = EVV[6];
2517          __m128d EV_t_l3_k2 = EVV[7];
2518         
2519         
2520          EV_t_l0_k0 = _mm_mul_pd( x1px2_k0, EV_t_l0_k0 );
2521          EV_t_l0_k2 = _mm_mul_pd( x1px2_k2, EV_t_l0_k2 );
2522          EV_t_l0_k0 = _mm_hadd_pd( EV_t_l0_k0, EV_t_l0_k2 );
2523         
2524          EV_t_l1_k0 = _mm_mul_pd( x1px2_k0, EV_t_l1_k0 );
2525          EV_t_l1_k2 = _mm_mul_pd( x1px2_k2, EV_t_l1_k2 );
2526         
2527          EV_t_l1_k0 = _mm_hadd_pd( EV_t_l1_k0, EV_t_l1_k2 );
2528          EV_t_l0_k0 = _mm_hadd_pd( EV_t_l0_k0, EV_t_l1_k0 );
2529         
2530          EV_t_l2_k0 = _mm_mul_pd( x1px2_k0, EV_t_l2_k0 );
2531          EV_t_l2_k2 = _mm_mul_pd( x1px2_k2, EV_t_l2_k2 );
2532          EV_t_l2_k0 = _mm_hadd_pd( EV_t_l2_k0, EV_t_l2_k2 );
2533                 
2534          EV_t_l3_k0 = _mm_mul_pd( x1px2_k0, EV_t_l3_k0 );
2535          EV_t_l3_k2 = _mm_mul_pd( x1px2_k2, EV_t_l3_k2 );
2536          EV_t_l3_k0 = _mm_hadd_pd( EV_t_l3_k0, EV_t_l3_k2 );
2537         
2538          EV_t_l2_k0 = _mm_hadd_pd( EV_t_l2_k0, EV_t_l3_k0 );                                     
2539         
2540          scale = 1;
2541                                   
2542          __m128d v1 = _mm_and_pd(EV_t_l0_k0, absMask.m);
2543          v1 = _mm_cmplt_pd(v1,  minlikelihood_sse);
2544          if(_mm_movemask_pd( v1 ) != 3)
2545            scale = 0;
2546          else
2547            {
2548              v1 = _mm_and_pd(EV_t_l2_k0, absMask.m);
2549              v1 = _mm_cmplt_pd(v1,  minlikelihood_sse);
2550              if(_mm_movemask_pd( v1 ) != 3)
2551                scale = 0;
2552            }
2553                 
2554          if(scale)
2555            {                 
2556              _mm_store_pd(&x3[0], _mm_mul_pd(EV_t_l0_k0, sc));
2557              _mm_store_pd(&x3[2], _mm_mul_pd(EV_t_l2_k0, sc));               
2558             
2559              if(useFastScaling)
2560                addScale += wgt[i];
2561              else
2562                ex3[i]  += 1;
2563            }   
2564          else
2565            {
2566              _mm_store_pd(x3, EV_t_l0_k0);
2567              _mm_store_pd(&x3[2], EV_t_l2_k0);
2568            }
2569         
2570                 
2571        }
2572      break;
2573    case INNER_INNER:
2574      for (i = 0; i < n; i++)
2575        {
2576          x1 = &x1_start[4 * i];
2577          x2 = &x2_start[4 * i];
2578          x3 = &x3_start[4 * i];
2579         
2580          le =  &left[cptr[i] * 16];
2581          ri =  &right[cptr[i] * 16];
2582
2583          __m128d x1_0 = _mm_load_pd( &x1[0] );
2584          __m128d x1_2 = _mm_load_pd( &x1[2] );
2585         
2586          __m128d left_k0_0 = _mm_load_pd( &le[0] );
2587          __m128d left_k0_2 = _mm_load_pd( &le[2] );
2588          __m128d left_k1_0 = _mm_load_pd( &le[4] );
2589          __m128d left_k1_2 = _mm_load_pd( &le[6] );
2590          __m128d left_k2_0 = _mm_load_pd( &le[8] );
2591          __m128d left_k2_2 = _mm_load_pd( &le[10] );
2592          __m128d left_k3_0 = _mm_load_pd( &le[12] );
2593          __m128d left_k3_2 = _mm_load_pd( &le[14] );
2594         
2595          left_k0_0 = _mm_mul_pd(x1_0, left_k0_0);
2596          left_k0_2 = _mm_mul_pd(x1_2, left_k0_2);
2597         
2598          left_k1_0 = _mm_mul_pd(x1_0, left_k1_0);
2599          left_k1_2 = _mm_mul_pd(x1_2, left_k1_2);
2600         
2601          left_k0_0 = _mm_hadd_pd( left_k0_0, left_k0_2 );
2602          left_k1_0 = _mm_hadd_pd( left_k1_0, left_k1_2);
2603          left_k0_0 = _mm_hadd_pd( left_k0_0, left_k1_0);
2604         
2605          left_k2_0 = _mm_mul_pd(x1_0, left_k2_0);
2606          left_k2_2 = _mm_mul_pd(x1_2, left_k2_2);
2607         
2608          left_k3_0 = _mm_mul_pd(x1_0, left_k3_0);
2609          left_k3_2 = _mm_mul_pd(x1_2, left_k3_2);
2610         
2611          left_k2_0 = _mm_hadd_pd( left_k2_0, left_k2_2);
2612          left_k3_0 = _mm_hadd_pd( left_k3_0, left_k3_2);
2613          left_k2_0 = _mm_hadd_pd( left_k2_0, left_k3_0);
2614         
2615          __m128d x2_0 = _mm_load_pd( &x2[0] );
2616          __m128d x2_2 = _mm_load_pd( &x2[2] );
2617         
2618          __m128d right_k0_0 = _mm_load_pd( &ri[0] );
2619          __m128d right_k0_2 = _mm_load_pd( &ri[2] );
2620          __m128d right_k1_0 = _mm_load_pd( &ri[4] );
2621          __m128d right_k1_2 = _mm_load_pd( &ri[6] );
2622          __m128d right_k2_0 = _mm_load_pd( &ri[8] );
2623          __m128d right_k2_2 = _mm_load_pd( &ri[10] );
2624          __m128d right_k3_0 = _mm_load_pd( &ri[12] );
2625          __m128d right_k3_2 = _mm_load_pd( &ri[14] );
2626         
2627          right_k0_0 = _mm_mul_pd( x2_0, right_k0_0);
2628          right_k0_2 = _mm_mul_pd( x2_2, right_k0_2);
2629         
2630          right_k1_0 = _mm_mul_pd( x2_0, right_k1_0);
2631          right_k1_2 = _mm_mul_pd( x2_2, right_k1_2);
2632         
2633          right_k0_0 = _mm_hadd_pd( right_k0_0, right_k0_2);
2634          right_k1_0 = _mm_hadd_pd( right_k1_0, right_k1_2);
2635          right_k0_0 = _mm_hadd_pd( right_k0_0, right_k1_0);
2636         
2637          right_k2_0 = _mm_mul_pd( x2_0, right_k2_0);
2638          right_k2_2 = _mm_mul_pd( x2_2, right_k2_2);
2639         
2640          right_k3_0 = _mm_mul_pd( x2_0, right_k3_0);
2641          right_k3_2 = _mm_mul_pd( x2_2, right_k3_2);
2642         
2643          right_k2_0 = _mm_hadd_pd( right_k2_0, right_k2_2);
2644          right_k3_0 = _mm_hadd_pd( right_k3_0, right_k3_2);
2645          right_k2_0 = _mm_hadd_pd( right_k2_0, right_k3_0);       
2646         
2647          __m128d x1px2_k0 = _mm_mul_pd( left_k0_0, right_k0_0 );
2648          __m128d x1px2_k2 = _mm_mul_pd( left_k2_0, right_k2_0 );
2649         
2650          __m128d EV_t_l0_k0 = EVV[0];
2651          __m128d EV_t_l0_k2 = EVV[1];
2652          __m128d EV_t_l1_k0 = EVV[2];
2653          __m128d EV_t_l1_k2 = EVV[3];
2654          __m128d EV_t_l2_k0 = EVV[4];
2655          __m128d EV_t_l2_k2 = EVV[5];
2656          __m128d EV_t_l3_k0 = EVV[6];
2657          __m128d EV_t_l3_k2 = EVV[7];
2658         
2659         
2660          EV_t_l0_k0 = _mm_mul_pd( x1px2_k0, EV_t_l0_k0 );
2661          EV_t_l0_k2 = _mm_mul_pd( x1px2_k2, EV_t_l0_k2 );
2662          EV_t_l0_k0 = _mm_hadd_pd( EV_t_l0_k0, EV_t_l0_k2 );
2663         
2664          EV_t_l1_k0 = _mm_mul_pd( x1px2_k0, EV_t_l1_k0 );
2665          EV_t_l1_k2 = _mm_mul_pd( x1px2_k2, EV_t_l1_k2 );
2666         
2667          EV_t_l1_k0 = _mm_hadd_pd( EV_t_l1_k0, EV_t_l1_k2 );
2668          EV_t_l0_k0 = _mm_hadd_pd( EV_t_l0_k0, EV_t_l1_k0 );
2669         
2670          EV_t_l2_k0 = _mm_mul_pd( x1px2_k0, EV_t_l2_k0 );
2671          EV_t_l2_k2 = _mm_mul_pd( x1px2_k2, EV_t_l2_k2 );
2672          EV_t_l2_k0 = _mm_hadd_pd( EV_t_l2_k0, EV_t_l2_k2 );
2673                 
2674          EV_t_l3_k0 = _mm_mul_pd( x1px2_k0, EV_t_l3_k0 );
2675          EV_t_l3_k2 = _mm_mul_pd( x1px2_k2, EV_t_l3_k2 );
2676          EV_t_l3_k0 = _mm_hadd_pd( EV_t_l3_k0, EV_t_l3_k2 );
2677         
2678          EV_t_l2_k0 = _mm_hadd_pd( EV_t_l2_k0, EV_t_l3_k0 );                                           
2679
2680          scale = 1;
2681                 
2682          __m128d v1 = _mm_and_pd(EV_t_l0_k0, absMask.m);
2683          v1 = _mm_cmplt_pd(v1,  minlikelihood_sse);
2684          if(_mm_movemask_pd( v1 ) != 3)
2685            scale = 0;
2686          else
2687            {
2688              v1 = _mm_and_pd(EV_t_l2_k0, absMask.m);
2689              v1 = _mm_cmplt_pd(v1,  minlikelihood_sse);
2690              if(_mm_movemask_pd( v1 ) != 3)
2691                scale = 0;
2692            }
2693                 
2694          if(scale)
2695            {                 
2696              _mm_store_pd(&x3[0], _mm_mul_pd(EV_t_l0_k0, sc));
2697              _mm_store_pd(&x3[2], _mm_mul_pd(EV_t_l2_k0, sc));               
2698             
2699              if(useFastScaling)
2700                addScale += wgt[i];
2701              else
2702                ex3[i]  += 1;
2703            }   
2704          else
2705            {
2706              _mm_store_pd(x3, EV_t_l0_k0);
2707              _mm_store_pd(&x3[2], EV_t_l2_k0);
2708            }
2709                 
2710        }
2711      break;
2712    default:
2713      assert(0);
2714    }
2715
2716  if(useFastScaling)
2717    *scalerIncrement = addScale;
2718}
2719
2720
2721
2722#endif
2723
2724
2725
2726
2727
2728#ifdef __SIM_SSE3
2729
2730static void newviewGTRGAMMA(int tipCase,
2731                            double *x1_start, double *x2_start, double *x3_start,
2732                            double *EV, double *tipVector,
2733                            int *ex3, unsigned char *tipX1, unsigned char *tipX2,
2734                            const int n, double *left, double *right, int *wgt, int *scalerIncrement, const boolean useFastScaling
2735                            )
2736{
2737  int 
2738    i, 
2739    j, 
2740    k, 
2741    l,
2742    addScale = 0;
2743 
2744  double
2745    *x1,
2746    *x2,
2747    *x3,
2748    max,
2749    maxima[2] __attribute__ ((aligned (BYTE_ALIGNMENT))),       
2750    EV_t[16] __attribute__ ((aligned (BYTE_ALIGNMENT)));     
2751   
2752  __m128d 
2753    values[8],
2754    EVV[8]; 
2755
2756  for(k = 0; k < 4; k++)
2757    for (l=0; l < 4; l++)
2758      EV_t[4 * l + k] = EV[4 * k + l];
2759
2760  for(k = 0; k < 8; k++)
2761    EVV[k] = _mm_load_pd(&EV_t[k * 2]);
2762   
2763  switch(tipCase)
2764    {
2765    case TIP_TIP:
2766      {
2767        double *uX1, umpX1[256] __attribute__ ((aligned (BYTE_ALIGNMENT))), *uX2, umpX2[256] __attribute__ ((aligned (BYTE_ALIGNMENT)));
2768
2769
2770        for (i = 1; i < 16; i++)
2771          {
2772            __m128d x1_1 = _mm_load_pd(&(tipVector[i*4]));
2773            __m128d x1_2 = _mm_load_pd(&(tipVector[i*4 + 2]));     
2774
2775            for (j = 0; j < 4; j++)
2776              for (k = 0; k < 4; k++)
2777                {               
2778                  __m128d left1 = _mm_load_pd(&left[j*16 + k*4]);
2779                  __m128d left2 = _mm_load_pd(&left[j*16 + k*4 + 2]);
2780                 
2781                  __m128d acc = _mm_setzero_pd();
2782
2783                  acc = _mm_add_pd(acc, _mm_mul_pd(left1, x1_1));
2784                  acc = _mm_add_pd(acc, _mm_mul_pd(left2, x1_2));
2785                                 
2786                  acc = _mm_hadd_pd(acc, acc);
2787                  _mm_storel_pd(&umpX1[i*16 + j*4 + k], acc);
2788                }
2789         
2790            for (j = 0; j < 4; j++)
2791              for (k = 0; k < 4; k++)
2792                {
2793                  __m128d left1 = _mm_load_pd(&right[j*16 + k*4]);
2794                  __m128d left2 = _mm_load_pd(&right[j*16 + k*4 + 2]);
2795                 
2796                  __m128d acc = _mm_setzero_pd();
2797
2798                  acc = _mm_add_pd(acc, _mm_mul_pd(left1, x1_1));
2799                  acc = _mm_add_pd(acc, _mm_mul_pd(left2, x1_2));
2800                                 
2801                  acc = _mm_hadd_pd(acc, acc);
2802                  _mm_storel_pd(&umpX2[i*16 + j*4 + k], acc);
2803                 
2804                }
2805          }     
2806         
2807        for (i = 0; i < n; i++)
2808          {
2809            x3 = &x3_start[i * 16];
2810
2811           
2812            uX1 = &umpX1[16 * tipX1[i]];
2813            uX2 = &umpX2[16 * tipX2[i]];                           
2814           
2815            for (j = 0; j < 4; j++)
2816               {                                                                                   
2817                 __m128d uX1_k0_sse = _mm_load_pd( &uX1[j * 4] );
2818                 __m128d uX1_k2_sse = _mm_load_pd( &uX1[j * 4 + 2] );
2819                                                 
2820                   
2821                 __m128d uX2_k0_sse = _mm_load_pd( &uX2[j * 4] );
2822                 __m128d uX2_k2_sse = _mm_load_pd( &uX2[j * 4 + 2] );
2823                 
2824
2825               
2826                 /* multiply left * right */           
2827                 
2828                 __m128d x1px2_k0 = _mm_mul_pd( uX1_k0_sse, uX2_k0_sse );
2829                 __m128d x1px2_k2 = _mm_mul_pd( uX1_k2_sse, uX2_k2_sse );
2830                 
2831                 
2832                 
2833                 /* multiply with EV matrix (!?) */
2834               
2835                 
2836                 __m128d EV_t_l0_k0 = EVV[0];
2837                 __m128d EV_t_l0_k2 = EVV[1];
2838                 __m128d EV_t_l1_k0 = EVV[2];
2839                 __m128d EV_t_l1_k2 = EVV[3];
2840                 __m128d EV_t_l2_k0 = EVV[4];
2841                 __m128d EV_t_l2_k2 = EVV[5];
2842                 __m128d EV_t_l3_k0 = EVV[6]; 
2843                 __m128d EV_t_l3_k2 = EVV[7];
2844                 
2845                 EV_t_l0_k0 = _mm_mul_pd( x1px2_k0, EV_t_l0_k0 );
2846                 EV_t_l0_k2 = _mm_mul_pd( x1px2_k2, EV_t_l0_k2 );
2847                 EV_t_l0_k0 = _mm_hadd_pd( EV_t_l0_k0, EV_t_l0_k2 );
2848                 
2849                 EV_t_l1_k0 = _mm_mul_pd( x1px2_k0, EV_t_l1_k0 );
2850                 EV_t_l1_k2 = _mm_mul_pd( x1px2_k2, EV_t_l1_k2 );
2851                 
2852                 EV_t_l1_k0 = _mm_hadd_pd( EV_t_l1_k0, EV_t_l1_k2 );
2853                 EV_t_l0_k0 = _mm_hadd_pd( EV_t_l0_k0, EV_t_l1_k0 );
2854                 
2855                 EV_t_l2_k0 = _mm_mul_pd( x1px2_k0, EV_t_l2_k0 );
2856                 EV_t_l2_k2 = _mm_mul_pd( x1px2_k2, EV_t_l2_k2 );
2857                 EV_t_l2_k0 = _mm_hadd_pd( EV_t_l2_k0, EV_t_l2_k2 );
2858                 
2859                 EV_t_l3_k0 = _mm_mul_pd( x1px2_k0, EV_t_l3_k0 );
2860                 EV_t_l3_k2 = _mm_mul_pd( x1px2_k2, EV_t_l3_k2 );
2861                 EV_t_l3_k0 = _mm_hadd_pd( EV_t_l3_k0, EV_t_l3_k2 );
2862                 
2863                 EV_t_l2_k0 = _mm_hadd_pd( EV_t_l2_k0, EV_t_l3_k0 );
2864                 
2865                 _mm_store_pd( &x3[j * 4 + 0], EV_t_l0_k0 );
2866                 _mm_store_pd( &x3[j * 4 + 2], EV_t_l2_k0 );
2867               }
2868          }
2869      }
2870      break;
2871    case TIP_INNER:
2872      { 
2873        double *uX1, umpX1[256] __attribute__ ((aligned (BYTE_ALIGNMENT)));
2874
2875
2876        for (i = 1; i < 16; i++)
2877          {
2878            __m128d x1_1 = _mm_load_pd(&(tipVector[i*4]));
2879            __m128d x1_2 = _mm_load_pd(&(tipVector[i*4 + 2]));     
2880
2881            for (j = 0; j < 4; j++)
2882              for (k = 0; k < 4; k++)
2883                {               
2884                  __m128d left1 = _mm_load_pd(&left[j*16 + k*4]);
2885                  __m128d left2 = _mm_load_pd(&left[j*16 + k*4 + 2]);
2886                 
2887                  __m128d acc = _mm_setzero_pd();
2888
2889                  acc = _mm_add_pd(acc, _mm_mul_pd(left1, x1_1));
2890                  acc = _mm_add_pd(acc, _mm_mul_pd(left2, x1_2));
2891                                 
2892                  acc = _mm_hadd_pd(acc, acc);
2893                  _mm_storel_pd(&umpX1[i*16 + j*4 + k], acc);           
2894                }
2895          }
2896
2897         for (i = 0; i < n; i++)
2898           {
2899             __m128d maxv =_mm_setzero_pd();
2900             
2901             x2 = &x2_start[i * 16];
2902             x3 = &x3_start[i * 16];
2903
2904             uX1 = &umpX1[16 * tipX1[i]];           
2905
2906             for (j = 0; j < 4; j++)
2907               {
2908
2909                 
2910                 /* multiply/add right side */
2911                 
2912                 double *x2_p = &x2[j*4];
2913                 double *right_k0_p = &right[j*16];
2914                 double *right_k1_p = &right[j*16 + 1*4];
2915                 double *right_k2_p = &right[j*16 + 2*4];
2916                 double *right_k3_p = &right[j*16 + 3*4];
2917                 __m128d x2_0 = _mm_load_pd( &x2_p[0] );
2918                 __m128d x2_2 = _mm_load_pd( &x2_p[2] );
2919
2920                 __m128d right_k0_0 = _mm_load_pd( &right_k0_p[0] );
2921                 __m128d right_k0_2 = _mm_load_pd( &right_k0_p[2] );
2922                 __m128d right_k1_0 = _mm_load_pd( &right_k1_p[0] );
2923                 __m128d right_k1_2 = _mm_load_pd( &right_k1_p[2] );
2924                 __m128d right_k2_0 = _mm_load_pd( &right_k2_p[0] );
2925                 __m128d right_k2_2 = _mm_load_pd( &right_k2_p[2] );
2926                 __m128d right_k3_0 = _mm_load_pd( &right_k3_p[0] );
2927                 __m128d right_k3_2 = _mm_load_pd( &right_k3_p[2] );
2928
2929
2930
2931                 right_k0_0 = _mm_mul_pd( x2_0, right_k0_0);
2932                 right_k0_2 = _mm_mul_pd( x2_2, right_k0_2);
2933
2934                 right_k1_0 = _mm_mul_pd( x2_0, right_k1_0);
2935                 right_k1_2 = _mm_mul_pd( x2_2, right_k1_2);
2936
2937                 right_k0_0 = _mm_hadd_pd( right_k0_0, right_k0_2);
2938                 right_k1_0 = _mm_hadd_pd( right_k1_0, right_k1_2);
2939                 right_k0_0 = _mm_hadd_pd( right_k0_0, right_k1_0);
2940
2941
2942                 right_k2_0 = _mm_mul_pd( x2_0, right_k2_0);
2943                 right_k2_2 = _mm_mul_pd( x2_2, right_k2_2);
2944
2945
2946                 right_k3_0 = _mm_mul_pd( x2_0, right_k3_0);
2947                 right_k3_2 = _mm_mul_pd( x2_2, right_k3_2);
2948
2949                 right_k2_0 = _mm_hadd_pd( right_k2_0, right_k2_2);
2950                 right_k3_0 = _mm_hadd_pd( right_k3_0, right_k3_2);
2951                 right_k2_0 = _mm_hadd_pd( right_k2_0, right_k3_0);
2952
2953                 {
2954                 
2955                   /* load left side from tip vector */
2956                 
2957                   
2958                   __m128d uX1_k0_sse = _mm_load_pd( &uX1[j * 4] );
2959                   __m128d uX1_k2_sse = _mm_load_pd( &uX1[j * 4 + 2] );
2960                 
2961                 
2962                   
2963                   /* multiply left * right */
2964                 
2965                   
2966                   __m128d x1px2_k0 = _mm_mul_pd( uX1_k0_sse, right_k0_0 );
2967                   __m128d x1px2_k2 = _mm_mul_pd( uX1_k2_sse, right_k2_0 );
2968                   
2969                   
2970                   
2971                   /* multiply with EV matrix (!?) */           
2972
2973                   __m128d EV_t_l0_k0 = EVV[0];
2974                   __m128d EV_t_l0_k2 = EVV[1];
2975                   __m128d EV_t_l1_k0 = EVV[2];
2976                   __m128d EV_t_l1_k2 = EVV[3];
2977                   __m128d EV_t_l2_k0 = EVV[4];
2978                   __m128d EV_t_l2_k2 = EVV[5];
2979                   __m128d EV_t_l3_k0 = EVV[6]; 
2980                   __m128d EV_t_l3_k2 = EVV[7];
2981
2982                   
2983                   EV_t_l0_k0 = _mm_mul_pd( x1px2_k0, EV_t_l0_k0 );
2984                   EV_t_l0_k2 = _mm_mul_pd( x1px2_k2, EV_t_l0_k2 );
2985                   EV_t_l0_k0 = _mm_hadd_pd( EV_t_l0_k0, EV_t_l0_k2 );
2986                   
2987                   EV_t_l1_k0 = _mm_mul_pd( x1px2_k0, EV_t_l1_k0 );
2988                   EV_t_l1_k2 = _mm_mul_pd( x1px2_k2, EV_t_l1_k2 );
2989                   
2990                   EV_t_l1_k0 = _mm_hadd_pd( EV_t_l1_k0, EV_t_l1_k2 );
2991                   EV_t_l0_k0 = _mm_hadd_pd( EV_t_l0_k0, EV_t_l1_k0 );
2992                   
2993                   EV_t_l2_k0 = _mm_mul_pd( x1px2_k0, EV_t_l2_k0 );
2994                   EV_t_l2_k2 = _mm_mul_pd( x1px2_k2, EV_t_l2_k2 );
2995                   EV_t_l2_k0 = _mm_hadd_pd( EV_t_l2_k0, EV_t_l2_k2 );
2996                                   
2997                   EV_t_l3_k0 = _mm_mul_pd( x1px2_k0, EV_t_l3_k0 );
2998                   EV_t_l3_k2 = _mm_mul_pd( x1px2_k2, EV_t_l3_k2 );
2999                   EV_t_l3_k0 = _mm_hadd_pd( EV_t_l3_k0, EV_t_l3_k2 );
3000                   
3001                   EV_t_l2_k0 = _mm_hadd_pd( EV_t_l2_k0, EV_t_l3_k0 );
3002                   
3003                   values[j * 2]     = EV_t_l0_k0;
3004                   values[j * 2 + 1] = EV_t_l2_k0;                                 
3005                   
3006                   maxv = _mm_max_pd(maxv, _mm_and_pd(EV_t_l0_k0, absMask.m));
3007                   maxv = _mm_max_pd(maxv, _mm_and_pd(EV_t_l2_k0, absMask.m));             
3008                 }
3009               }
3010
3011             
3012             _mm_store_pd(maxima, maxv);
3013
3014             max = MAX(maxima[0], maxima[1]);
3015
3016             if(max < minlikelihood)
3017               {
3018                 __m128d sv = _mm_set1_pd(twotothe256);
3019                                                     
3020                 _mm_store_pd(&x3[0], _mm_mul_pd(values[0], sv));         
3021                 _mm_store_pd(&x3[2], _mm_mul_pd(values[1], sv));
3022                 _mm_store_pd(&x3[4], _mm_mul_pd(values[2], sv));
3023                 _mm_store_pd(&x3[6], _mm_mul_pd(values[3], sv));
3024                 _mm_store_pd(&x3[8], _mm_mul_pd(values[4], sv));         
3025                 _mm_store_pd(&x3[10], _mm_mul_pd(values[5], sv));
3026                 _mm_store_pd(&x3[12], _mm_mul_pd(values[6], sv));
3027                 _mm_store_pd(&x3[14], _mm_mul_pd(values[7], sv));           
3028                 
3029                 if(useFastScaling)
3030                   addScale += wgt[i];
3031                 else
3032                   ex3[i]  += 1;
3033               }
3034             else
3035               {
3036                 _mm_store_pd(&x3[0], values[0]);         
3037                 _mm_store_pd(&x3[2], values[1]);
3038                 _mm_store_pd(&x3[4], values[2]);
3039                 _mm_store_pd(&x3[6], values[3]);
3040                 _mm_store_pd(&x3[8], values[4]);         
3041                 _mm_store_pd(&x3[10], values[5]);
3042                 _mm_store_pd(&x3[12], values[6]);
3043                 _mm_store_pd(&x3[14], values[7]);
3044               }
3045           }
3046      }
3047      break;
3048    case INNER_INNER:     
3049     for (i = 0; i < n; i++)
3050       {
3051         __m128d maxv =_mm_setzero_pd();
3052         
3053
3054         x1 = &x1_start[i * 16];
3055         x2 = &x2_start[i * 16];
3056         x3 = &x3_start[i * 16];
3057         
3058         for (j = 0; j < 4; j++)
3059           {
3060             
3061             double *x1_p = &x1[j*4];
3062             double *left_k0_p = &left[j*16];
3063             double *left_k1_p = &left[j*16 + 1*4];
3064             double *left_k2_p = &left[j*16 + 2*4];
3065             double *left_k3_p = &left[j*16 + 3*4];
3066             
3067             __m128d x1_0 = _mm_load_pd( &x1_p[0] );
3068             __m128d x1_2 = _mm_load_pd( &x1_p[2] );
3069             
3070             __m128d left_k0_0 = _mm_load_pd( &left_k0_p[0] );
3071             __m128d left_k0_2 = _mm_load_pd( &left_k0_p[2] );
3072             __m128d left_k1_0 = _mm_load_pd( &left_k1_p[0] );
3073             __m128d left_k1_2 = _mm_load_pd( &left_k1_p[2] );
3074             __m128d left_k2_0 = _mm_load_pd( &left_k2_p[0] );
3075             __m128d left_k2_2 = _mm_load_pd( &left_k2_p[2] );
3076             __m128d left_k3_0 = _mm_load_pd( &left_k3_p[0] );
3077             __m128d left_k3_2 = _mm_load_pd( &left_k3_p[2] );
3078             
3079             left_k0_0 = _mm_mul_pd(x1_0, left_k0_0);
3080             left_k0_2 = _mm_mul_pd(x1_2, left_k0_2);
3081             
3082             left_k1_0 = _mm_mul_pd(x1_0, left_k1_0);
3083             left_k1_2 = _mm_mul_pd(x1_2, left_k1_2);
3084             
3085             left_k0_0 = _mm_hadd_pd( left_k0_0, left_k0_2 );
3086             left_k1_0 = _mm_hadd_pd( left_k1_0, left_k1_2);
3087             left_k0_0 = _mm_hadd_pd( left_k0_0, left_k1_0);
3088             
3089             left_k2_0 = _mm_mul_pd(x1_0, left_k2_0);
3090             left_k2_2 = _mm_mul_pd(x1_2, left_k2_2);
3091             
3092             left_k3_0 = _mm_mul_pd(x1_0, left_k3_0);
3093             left_k3_2 = _mm_mul_pd(x1_2, left_k3_2);
3094             
3095             left_k2_0 = _mm_hadd_pd( left_k2_0, left_k2_2);
3096             left_k3_0 = _mm_hadd_pd( left_k3_0, left_k3_2);
3097             left_k2_0 = _mm_hadd_pd( left_k2_0, left_k3_0);
3098             
3099             
3100             
3101             /* multiply/add right side */
3102             
3103             double *x2_p = &x2[j*4];
3104             double *right_k0_p = &right[j*16];
3105             double *right_k1_p = &right[j*16 + 1*4];
3106             double *right_k2_p = &right[j*16 + 2*4];
3107             double *right_k3_p = &right[j*16 + 3*4];
3108             __m128d x2_0 = _mm_load_pd( &x2_p[0] );
3109             __m128d x2_2 = _mm_load_pd( &x2_p[2] );
3110             
3111             __m128d right_k0_0 = _mm_load_pd( &right_k0_p[0] );
3112             __m128d right_k0_2 = _mm_load_pd( &right_k0_p[2] );
3113             __m128d right_k1_0 = _mm_load_pd( &right_k1_p[0] );
3114             __m128d right_k1_2 = _mm_load_pd( &right_k1_p[2] );
3115             __m128d right_k2_0 = _mm_load_pd( &right_k2_p[0] );
3116             __m128d right_k2_2 = _mm_load_pd( &right_k2_p[2] );
3117             __m128d right_k3_0 = _mm_load_pd( &right_k3_p[0] );
3118             __m128d right_k3_2 = _mm_load_pd( &right_k3_p[2] );
3119             
3120             right_k0_0 = _mm_mul_pd( x2_0, right_k0_0);
3121             right_k0_2 = _mm_mul_pd( x2_2, right_k0_2);
3122             
3123             right_k1_0 = _mm_mul_pd( x2_0, right_k1_0);
3124             right_k1_2 = _mm_mul_pd( x2_2, right_k1_2);
3125             
3126             right_k0_0 = _mm_hadd_pd( right_k0_0, right_k0_2);
3127             right_k1_0 = _mm_hadd_pd( right_k1_0, right_k1_2);
3128             right_k0_0 = _mm_hadd_pd( right_k0_0, right_k1_0);
3129             
3130             right_k2_0 = _mm_mul_pd( x2_0, right_k2_0);
3131             right_k2_2 = _mm_mul_pd( x2_2, right_k2_2);
3132             
3133             
3134             right_k3_0 = _mm_mul_pd( x2_0, right_k3_0);
3135             right_k3_2 = _mm_mul_pd( x2_2, right_k3_2);
3136             
3137             right_k2_0 = _mm_hadd_pd( right_k2_0, right_k2_2);
3138             right_k3_0 = _mm_hadd_pd( right_k3_0, right_k3_2);
3139             right_k2_0 = _mm_hadd_pd( right_k2_0, right_k3_0);   
3140
3141             
3142             /* multiply left * right */
3143           
3144
3145             __m128d x1px2_k0 = _mm_mul_pd( left_k0_0, right_k0_0 );
3146             __m128d x1px2_k2 = _mm_mul_pd( left_k2_0, right_k2_0 );
3147
3148
3149             
3150             /* multiply with EV matrix (!?) */           
3151
3152             __m128d EV_t_l0_k0 = EVV[0];
3153             __m128d EV_t_l0_k2 = EVV[1];
3154             __m128d EV_t_l1_k0 = EVV[2];
3155             __m128d EV_t_l1_k2 = EVV[3];
3156             __m128d EV_t_l2_k0 = EVV[4];
3157             __m128d EV_t_l2_k2 = EVV[5];
3158             __m128d EV_t_l3_k0 = EVV[6]; 
3159             __m128d EV_t_l3_k2 = EVV[7];
3160
3161
3162            EV_t_l0_k0 = _mm_mul_pd( x1px2_k0, EV_t_l0_k0 );
3163            EV_t_l0_k2 = _mm_mul_pd( x1px2_k2, EV_t_l0_k2 );
3164            EV_t_l0_k0 = _mm_hadd_pd( EV_t_l0_k0, EV_t_l0_k2 );
3165
3166            EV_t_l1_k0 = _mm_mul_pd( x1px2_k0, EV_t_l1_k0 );
3167            EV_t_l1_k2 = _mm_mul_pd( x1px2_k2, EV_t_l1_k2 );
3168
3169            EV_t_l1_k0 = _mm_hadd_pd( EV_t_l1_k0, EV_t_l1_k2 );
3170            EV_t_l0_k0 = _mm_hadd_pd( EV_t_l0_k0, EV_t_l1_k0 );
3171
3172            EV_t_l2_k0 = _mm_mul_pd( x1px2_k0, EV_t_l2_k0 );
3173            EV_t_l2_k2 = _mm_mul_pd( x1px2_k2, EV_t_l2_k2 );
3174            EV_t_l2_k0 = _mm_hadd_pd( EV_t_l2_k0, EV_t_l2_k2 );
3175
3176
3177            EV_t_l3_k0 = _mm_mul_pd( x1px2_k0, EV_t_l3_k0 );
3178            EV_t_l3_k2 = _mm_mul_pd( x1px2_k2, EV_t_l3_k2 );
3179            EV_t_l3_k0 = _mm_hadd_pd( EV_t_l3_k0, EV_t_l3_k2 );
3180
3181            EV_t_l2_k0 = _mm_hadd_pd( EV_t_l2_k0, EV_t_l3_k0 );
3182
3183           
3184            values[j * 2] = EV_t_l0_k0;
3185            values[j * 2 + 1] = EV_t_l2_k0;                         
3186
3187            maxv = _mm_max_pd(maxv, _mm_and_pd(EV_t_l0_k0, absMask.m));
3188            maxv = _mm_max_pd(maxv, _mm_and_pd(EV_t_l2_k0, absMask.m));
3189           }
3190                 
3191         
3192         _mm_store_pd(maxima, maxv);
3193         
3194         max = MAX(maxima[0], maxima[1]);
3195         
3196         if(max < minlikelihood)
3197           {
3198             __m128d sv = _mm_set1_pd(twotothe256);
3199                                                     
3200             _mm_store_pd(&x3[0], _mm_mul_pd(values[0], sv));     
3201             _mm_store_pd(&x3[2], _mm_mul_pd(values[1], sv));
3202             _mm_store_pd(&x3[4], _mm_mul_pd(values[2], sv));
3203             _mm_store_pd(&x3[6], _mm_mul_pd(values[3], sv));
3204             _mm_store_pd(&x3[8], _mm_mul_pd(values[4], sv));     
3205             _mm_store_pd(&x3[10], _mm_mul_pd(values[5], sv));
3206             _mm_store_pd(&x3[12], _mm_mul_pd(values[6], sv));
3207             _mm_store_pd(&x3[14], _mm_mul_pd(values[7], sv));       
3208             
3209             if(useFastScaling)
3210               addScale += wgt[i];
3211             else
3212               ex3[i]  += 1;
3213           }
3214         else
3215           {
3216             _mm_store_pd(&x3[0], values[0]);     
3217             _mm_store_pd(&x3[2], values[1]);
3218             _mm_store_pd(&x3[4], values[2]);
3219             _mm_store_pd(&x3[6], values[3]);
3220             _mm_store_pd(&x3[8], values[4]);     
3221             _mm_store_pd(&x3[10], values[5]);
3222             _mm_store_pd(&x3[12], values[6]);
3223             _mm_store_pd(&x3[14], values[7]);
3224           }     
3225       }
3226   
3227     break;
3228    default:
3229      assert(0);
3230    }
3231 
3232  if(useFastScaling)
3233    *scalerIncrement = addScale;
3234
3235}
3236
3237
3238
3239
3240static void newviewGTRGAMMA_GAPPED_SAVE(int tipCase,
3241                                        double *x1_start, double *x2_start, double *x3_start,
3242                                        double *EV, double *tipVector,
3243                                        int *ex3, unsigned char *tipX1, unsigned char *tipX2,
3244                                        const int n, double *left, double *right, int *wgt, int *scalerIncrement, const boolean useFastScaling,
3245                                        unsigned int *x1_gap, unsigned int *x2_gap, unsigned int *x3_gap, 
3246                                        double *x1_gapColumn, double *x2_gapColumn, double *x3_gapColumn)
3247{
3248  int     
3249    i, 
3250    j, 
3251    k, 
3252    l,
3253    addScale = 0, 
3254    scaleGap = 0;
3255 
3256  double
3257    *x1,
3258    *x2,
3259    *x3,
3260    *x1_ptr = x1_start,
3261    *x2_ptr = x2_start,       
3262    max,
3263    maxima[2] __attribute__ ((aligned (BYTE_ALIGNMENT))),       
3264    EV_t[16] __attribute__ ((aligned (BYTE_ALIGNMENT)));     
3265   
3266  __m128d 
3267    values[8],
3268    EVV[8]; 
3269
3270  for(k = 0; k < 4; k++)
3271    for (l=0; l < 4; l++)
3272      EV_t[4 * l + k] = EV[4 * k + l];
3273
3274  for(k = 0; k < 8; k++)
3275    EVV[k] = _mm_load_pd(&EV_t[k * 2]);     
3276 
3277 
3278
3279  switch(tipCase)
3280    {
3281    case TIP_TIP:
3282      {
3283        double *uX1, umpX1[256] __attribute__ ((aligned (BYTE_ALIGNMENT))), *uX2, umpX2[256] __attribute__ ((aligned (BYTE_ALIGNMENT)));
3284
3285
3286        for (i = 1; i < 16; i++)
3287          {         
3288            __m128d x1_1 = _mm_load_pd(&(tipVector[i*4]));
3289            __m128d x1_2 = _mm_load_pd(&(tipVector[i*4 + 2]));     
3290
3291            for (j = 0; j < 4; j++)
3292              for (k = 0; k < 4; k++)
3293                {                               
3294                  __m128d left1 = _mm_load_pd(&left[j*16 + k*4]);
3295                  __m128d left2 = _mm_load_pd(&left[j*16 + k*4 + 2]);
3296                 
3297                  __m128d acc = _mm_setzero_pd();
3298
3299                  acc = _mm_add_pd(acc, _mm_mul_pd(left1, x1_1));
3300                  acc = _mm_add_pd(acc, _mm_mul_pd(left2, x1_2));
3301                                 
3302                  acc = _mm_hadd_pd(acc, acc);
3303                  _mm_storel_pd(&umpX1[i*16 + j*4 + k], acc);
3304                }
3305         
3306            for (j = 0; j < 4; j++)
3307              for (k = 0; k < 4; k++)
3308                {
3309                  __m128d left1 = _mm_load_pd(&right[j*16 + k*4]);
3310                  __m128d left2 = _mm_load_pd(&right[j*16 + k*4 + 2]);
3311                 
3312                  __m128d acc = _mm_setzero_pd();
3313
3314                  acc = _mm_add_pd(acc, _mm_mul_pd(left1, x1_1));
3315                  acc = _mm_add_pd(acc, _mm_mul_pd(left2, x1_2));
3316                                 
3317                  acc = _mm_hadd_pd(acc, acc);
3318                  _mm_storel_pd(&umpX2[i*16 + j*4 + k], acc);
3319                 
3320                }
3321          }               
3322       
3323        uX1 = &umpX1[240];
3324        uX2 = &umpX2[240];                         
3325       
3326        for (j = 0; j < 4; j++)
3327          {                                                                               
3328            __m128d uX1_k0_sse = _mm_load_pd( &uX1[j * 4] );
3329            __m128d uX1_k2_sse = _mm_load_pd( &uX1[j * 4 + 2] );
3330                   
3331            __m128d uX2_k0_sse = _mm_load_pd( &uX2[j * 4] );
3332            __m128d uX2_k2_sse = _mm_load_pd( &uX2[j * 4 + 2] );
3333           
3334            __m128d x1px2_k0 = _mm_mul_pd( uX1_k0_sse, uX2_k0_sse );
3335            __m128d x1px2_k2 = _mm_mul_pd( uX1_k2_sse, uX2_k2_sse );                                               
3336           
3337            __m128d EV_t_l0_k0 = EVV[0];
3338            __m128d EV_t_l0_k2 = EVV[1];
3339            __m128d EV_t_l1_k0 = EVV[2];
3340            __m128d EV_t_l1_k2 = EVV[3];
3341            __m128d EV_t_l2_k0 = EVV[4];
3342            __m128d EV_t_l2_k2 = EVV[5];
3343            __m128d EV_t_l3_k0 = EVV[6]; 
3344            __m128d EV_t_l3_k2 = EVV[7];
3345           
3346            EV_t_l0_k0 = _mm_mul_pd( x1px2_k0, EV_t_l0_k0 );
3347            EV_t_l0_k2 = _mm_mul_pd( x1px2_k2, EV_t_l0_k2 );
3348            EV_t_l0_k0 = _mm_hadd_pd( EV_t_l0_k0, EV_t_l0_k2 );
3349           
3350            EV_t_l1_k0 = _mm_mul_pd( x1px2_k0, EV_t_l1_k0 );
3351            EV_t_l1_k2 = _mm_mul_pd( x1px2_k2, EV_t_l1_k2 );
3352           
3353            EV_t_l1_k0 = _mm_hadd_pd( EV_t_l1_k0, EV_t_l1_k2 );
3354            EV_t_l0_k0 = _mm_hadd_pd( EV_t_l0_k0, EV_t_l1_k0 );
3355           
3356            EV_t_l2_k0 = _mm_mul_pd( x1px2_k0, EV_t_l2_k0 );
3357            EV_t_l2_k2 = _mm_mul_pd( x1px2_k2, EV_t_l2_k2 );
3358            EV_t_l2_k0 = _mm_hadd_pd( EV_t_l2_k0, EV_t_l2_k2 );
3359           
3360            EV_t_l3_k0 = _mm_mul_pd( x1px2_k0, EV_t_l3_k0 );
3361            EV_t_l3_k2 = _mm_mul_pd( x1px2_k2, EV_t_l3_k2 );
3362            EV_t_l3_k0 = _mm_hadd_pd( EV_t_l3_k0, EV_t_l3_k2 );
3363           
3364            EV_t_l2_k0 = _mm_hadd_pd( EV_t_l2_k0, EV_t_l3_k0 );
3365                 
3366            _mm_store_pd( &x3_gapColumn[j * 4 + 0], EV_t_l0_k0 );
3367            _mm_store_pd( &x3_gapColumn[j * 4 + 2], EV_t_l2_k0 );         
3368          } 
3369       
3370       
3371        x3 = x3_start;
3372       
3373        for (i = 0; i < n; i++)
3374          {         
3375            if(!(x3_gap[i / 32] & mask32[i % 32]))           
3376              {
3377                uX1 = &umpX1[16 * tipX1[i]];
3378                uX2 = &umpX2[16 * tipX2[i]];                                   
3379               
3380                for (j = 0; j < 4; j++)
3381                  {                                                                               
3382                    __m128d uX1_k0_sse = _mm_load_pd( &uX1[j * 4] );
3383                    __m128d uX1_k2_sse = _mm_load_pd( &uX1[j * 4 + 2] );
3384                   
3385                   
3386                    __m128d uX2_k0_sse = _mm_load_pd( &uX2[j * 4] );
3387                    __m128d uX2_k2_sse = _mm_load_pd( &uX2[j * 4 + 2] );
3388                                                   
3389                    /* multiply left * right */           
3390                   
3391                    __m128d x1px2_k0 = _mm_mul_pd( uX1_k0_sse, uX2_k0_sse );
3392                    __m128d x1px2_k2 = _mm_mul_pd( uX1_k2_sse, uX2_k2_sse );
3393                   
3394                                   
3395                    /* multiply with EV matrix (!?) */             
3396                   
3397                    __m128d EV_t_l0_k0 = EVV[0];
3398                    __m128d EV_t_l0_k2 = EVV[1];
3399                    __m128d EV_t_l1_k0 = EVV[2];
3400                    __m128d EV_t_l1_k2 = EVV[3];
3401                    __m128d EV_t_l2_k0 = EVV[4];
3402                    __m128d EV_t_l2_k2 = EVV[5];
3403                    __m128d EV_t_l3_k0 = EVV[6]; 
3404                    __m128d EV_t_l3_k2 = EVV[7];
3405                   
3406                    EV_t_l0_k0 = _mm_mul_pd( x1px2_k0, EV_t_l0_k0 );
3407                    EV_t_l0_k2 = _mm_mul_pd( x1px2_k2, EV_t_l0_k2 );
3408                    EV_t_l0_k0 = _mm_hadd_pd( EV_t_l0_k0, EV_t_l0_k2 );
3409                   
3410                    EV_t_l1_k0 = _mm_mul_pd( x1px2_k0, EV_t_l1_k0 );
3411                    EV_t_l1_k2 = _mm_mul_pd( x1px2_k2, EV_t_l1_k2 );
3412                   
3413                    EV_t_l1_k0 = _mm_hadd_pd( EV_t_l1_k0, EV_t_l1_k2 );
3414                    EV_t_l0_k0 = _mm_hadd_pd( EV_t_l0_k0, EV_t_l1_k0 );
3415                   
3416                    EV_t_l2_k0 = _mm_mul_pd( x1px2_k0, EV_t_l2_k0 );
3417                    EV_t_l2_k2 = _mm_mul_pd( x1px2_k2, EV_t_l2_k2 );
3418                    EV_t_l2_k0 = _mm_hadd_pd( EV_t_l2_k0, EV_t_l2_k2 );
3419                   
3420                    EV_t_l3_k0 = _mm_mul_pd( x1px2_k0, EV_t_l3_k0 );
3421                    EV_t_l3_k2 = _mm_mul_pd( x1px2_k2, EV_t_l3_k2 );
3422                    EV_t_l3_k0 = _mm_hadd_pd( EV_t_l3_k0, EV_t_l3_k2 );
3423                   
3424                    EV_t_l2_k0 = _mm_hadd_pd( EV_t_l2_k0, EV_t_l3_k0 );
3425                   
3426                    _mm_store_pd( &x3[j * 4 + 0], EV_t_l0_k0 );
3427                    _mm_store_pd( &x3[j * 4 + 2], EV_t_l2_k0 );
3428                  }
3429               
3430                x3 += 16;
3431              }
3432          }
3433      }
3434      break;
3435    case TIP_INNER:
3436      { 
3437        double 
3438          *uX1, 
3439          umpX1[256] __attribute__ ((aligned (BYTE_ALIGNMENT)));                 
3440
3441        for (i = 1; i < 16; i++)
3442          {
3443            __m128d x1_1 = _mm_load_pd(&(tipVector[i*4]));
3444            __m128d x1_2 = _mm_load_pd(&(tipVector[i*4 + 2]));     
3445
3446            for (j = 0; j < 4; j++)
3447              for (k = 0; k < 4; k++)
3448                {               
3449                  __m128d left1 = _mm_load_pd(&left[j*16 + k*4]);
3450                  __m128d left2 = _mm_load_pd(&left[j*16 + k*4 + 2]);
3451                 
3452                  __m128d acc = _mm_setzero_pd();
3453
3454                  acc = _mm_add_pd(acc, _mm_mul_pd(left1, x1_1));
3455                  acc = _mm_add_pd(acc, _mm_mul_pd(left2, x1_2));
3456                                 
3457                  acc = _mm_hadd_pd(acc, acc);
3458                  _mm_storel_pd(&umpX1[i*16 + j*4 + k], acc);           
3459                }
3460          }
3461
3462        {
3463          __m128d maxv =_mm_setzero_pd();
3464         
3465          scaleGap = 0;
3466         
3467          x2 = x2_gapColumn;                     
3468          x3 = x3_gapColumn;
3469         
3470          uX1 = &umpX1[240];         
3471         
3472          for (j = 0; j < 4; j++)
3473            {                             
3474              double *x2_p = &x2[j*4];
3475              double *right_k0_p = &right[j*16];
3476              double *right_k1_p = &right[j*16 + 1*4];
3477              double *right_k2_p = &right[j*16 + 2*4];
3478              double *right_k3_p = &right[j*16 + 3*4];
3479              __m128d x2_0 = _mm_load_pd( &x2_p[0] );
3480              __m128d x2_2 = _mm_load_pd( &x2_p[2] );
3481             
3482              __m128d right_k0_0 = _mm_load_pd( &right_k0_p[0] );
3483              __m128d right_k0_2 = _mm_load_pd( &right_k0_p[2] );
3484              __m128d right_k1_0 = _mm_load_pd( &right_k1_p[0] );
3485              __m128d right_k1_2 = _mm_load_pd( &right_k1_p[2] );
3486              __m128d right_k2_0 = _mm_load_pd( &right_k2_p[0] );
3487              __m128d right_k2_2 = _mm_load_pd( &right_k2_p[2] );
3488              __m128d right_k3_0 = _mm_load_pd( &right_k3_p[0] );
3489              __m128d right_k3_2 = _mm_load_pd( &right_k3_p[2] );
3490                     
3491              right_k0_0 = _mm_mul_pd( x2_0, right_k0_0);
3492              right_k0_2 = _mm_mul_pd( x2_2, right_k0_2);
3493             
3494              right_k1_0 = _mm_mul_pd( x2_0, right_k1_0);
3495              right_k1_2 = _mm_mul_pd( x2_2, right_k1_2);
3496             
3497              right_k0_0 = _mm_hadd_pd( right_k0_0, right_k0_2);
3498              right_k1_0 = _mm_hadd_pd( right_k1_0, right_k1_2);
3499              right_k0_0 = _mm_hadd_pd( right_k0_0, right_k1_0);
3500                       
3501              right_k2_0 = _mm_mul_pd( x2_0, right_k2_0);
3502              right_k2_2 = _mm_mul_pd( x2_2, right_k2_2);
3503                       
3504              right_k3_0 = _mm_mul_pd( x2_0, right_k3_0);
3505              right_k3_2 = _mm_mul_pd( x2_2, right_k3_2);
3506             
3507              right_k2_0 = _mm_hadd_pd( right_k2_0, right_k2_2);
3508              right_k3_0 = _mm_hadd_pd( right_k3_0, right_k3_2);
3509              right_k2_0 = _mm_hadd_pd( right_k2_0, right_k3_0);
3510             
3511              __m128d uX1_k0_sse = _mm_load_pd( &uX1[j * 4] );
3512              __m128d uX1_k2_sse = _mm_load_pd( &uX1[j * 4 + 2] );
3513             
3514              __m128d x1px2_k0 = _mm_mul_pd( uX1_k0_sse, right_k0_0 );
3515              __m128d x1px2_k2 = _mm_mul_pd( uX1_k2_sse, right_k2_0 );
3516             
3517              __m128d EV_t_l0_k0 = EVV[0];
3518              __m128d EV_t_l0_k2 = EVV[1];
3519              __m128d EV_t_l1_k0 = EVV[2];
3520              __m128d EV_t_l1_k2 = EVV[3];
3521              __m128d EV_t_l2_k0 = EVV[4];
3522              __m128d EV_t_l2_k2 = EVV[5];
3523              __m128d EV_t_l3_k0 = EVV[6]; 
3524              __m128d EV_t_l3_k2 = EVV[7];
3525             
3526              EV_t_l0_k0 = _mm_mul_pd( x1px2_k0, EV_t_l0_k0 );
3527              EV_t_l0_k2 = _mm_mul_pd( x1px2_k2, EV_t_l0_k2 );
3528              EV_t_l0_k0 = _mm_hadd_pd( EV_t_l0_k0, EV_t_l0_k2 );
3529             
3530              EV_t_l1_k0 = _mm_mul_pd( x1px2_k0, EV_t_l1_k0 );
3531              EV_t_l1_k2 = _mm_mul_pd( x1px2_k2, EV_t_l1_k2 );
3532             
3533              EV_t_l1_k0 = _mm_hadd_pd( EV_t_l1_k0, EV_t_l1_k2 );
3534              EV_t_l0_k0 = _mm_hadd_pd( EV_t_l0_k0, EV_t_l1_k0 );
3535             
3536              EV_t_l2_k0 = _mm_mul_pd( x1px2_k0, EV_t_l2_k0 );
3537              EV_t_l2_k2 = _mm_mul_pd( x1px2_k2, EV_t_l2_k2 );
3538              EV_t_l2_k0 = _mm_hadd_pd( EV_t_l2_k0, EV_t_l2_k2 );
3539             
3540              EV_t_l3_k0 = _mm_mul_pd( x1px2_k0, EV_t_l3_k0 );
3541              EV_t_l3_k2 = _mm_mul_pd( x1px2_k2, EV_t_l3_k2 );
3542              EV_t_l3_k0 = _mm_hadd_pd( EV_t_l3_k0, EV_t_l3_k2 );
3543             
3544              EV_t_l2_k0 = _mm_hadd_pd( EV_t_l2_k0, EV_t_l3_k0 );
3545             
3546              values[j * 2]     = EV_t_l0_k0;
3547              values[j * 2 + 1] = EV_t_l2_k0;                             
3548             
3549              maxv = _mm_max_pd(maxv, _mm_and_pd(EV_t_l0_k0, absMask.m));
3550              maxv = _mm_max_pd(maxv, _mm_and_pd(EV_t_l2_k0, absMask.m));                                         
3551            }
3552
3553         
3554          _mm_store_pd(maxima, maxv);
3555                 
3556          max = MAX(maxima[0], maxima[1]);
3557         
3558          if(max < minlikelihood)
3559            {
3560              scaleGap = 1;
3561             
3562              __m128d sv = _mm_set1_pd(twotothe256);
3563             
3564              _mm_store_pd(&x3[0], _mm_mul_pd(values[0], sv));     
3565              _mm_store_pd(&x3[2], _mm_mul_pd(values[1], sv));
3566              _mm_store_pd(&x3[4], _mm_mul_pd(values[2], sv));
3567              _mm_store_pd(&x3[6], _mm_mul_pd(values[3], sv));
3568              _mm_store_pd(&x3[8], _mm_mul_pd(values[4], sv));     
3569              _mm_store_pd(&x3[10], _mm_mul_pd(values[5], sv));
3570              _mm_store_pd(&x3[12], _mm_mul_pd(values[6], sv));
3571              _mm_store_pd(&x3[14], _mm_mul_pd(values[7], sv));                     
3572            }
3573          else
3574            {
3575              _mm_store_pd(&x3[0], values[0]);     
3576              _mm_store_pd(&x3[2], values[1]);
3577              _mm_store_pd(&x3[4], values[2]);
3578              _mm_store_pd(&x3[6], values[3]);
3579              _mm_store_pd(&x3[8], values[4]);     
3580              _mm_store_pd(&x3[10], values[5]);
3581              _mm_store_pd(&x3[12], values[6]);
3582              _mm_store_pd(&x3[14], values[7]);
3583            }
3584        }                       
3585       
3586        x3 = x3_start;
3587
3588        for (i = 0; i < n; i++)
3589           {
3590             if((x3_gap[i / 32] & mask32[i % 32]))
3591               {               
3592                 if(scaleGap)
3593                   {
3594                     if(useFastScaling)
3595                       addScale += wgt[i];
3596                     else
3597                       ex3[i]  += 1;
3598                   }
3599               }
3600             else
3601               {                                 
3602                 __m128d maxv =_mm_setzero_pd();                 
3603                 
3604                 if(x2_gap[i / 32] & mask32[i % 32])
3605                   x2 = x2_gapColumn;
3606                 else
3607                   {
3608                     x2 = x2_ptr;
3609                     x2_ptr += 16;
3610                   }
3611                                                 
3612                 uX1 = &umpX1[16 * tipX1[i]];       
3613                 
3614                 
3615                 for (j = 0; j < 4; j++)
3616                   {                               
3617                     double *x2_p = &x2[j*4];
3618                     double *right_k0_p = &right[j*16];
3619                     double *right_k1_p = &right[j*16 + 1*4];
3620                     double *right_k2_p = &right[j*16 + 2*4];
3621                     double *right_k3_p = &right[j*16 + 3*4];
3622                     __m128d x2_0 = _mm_load_pd( &x2_p[0] );
3623                     __m128d x2_2 = _mm_load_pd( &x2_p[2] );
3624                     
3625                     __m128d right_k0_0 = _mm_load_pd( &right_k0_p[0] );
3626                     __m128d right_k0_2 = _mm_load_pd( &right_k0_p[2] );
3627                     __m128d right_k1_0 = _mm_load_pd( &right_k1_p[0] );
3628                     __m128d right_k1_2 = _mm_load_pd( &right_k1_p[2] );
3629                     __m128d right_k2_0 = _mm_load_pd( &right_k2_p[0] );
3630                     __m128d right_k2_2 = _mm_load_pd( &right_k2_p[2] );
3631                     __m128d right_k3_0 = _mm_load_pd( &right_k3_p[0] );
3632                     __m128d right_k3_2 = _mm_load_pd( &right_k3_p[2] );
3633                     
3634                                     
3635                     right_k0_0 = _mm_mul_pd( x2_0, right_k0_0);
3636                     right_k0_2 = _mm_mul_pd( x2_2, right_k0_2);
3637                     
3638                     right_k1_0 = _mm_mul_pd( x2_0, right_k1_0);
3639                     right_k1_2 = _mm_mul_pd( x2_2, right_k1_2);
3640                     
3641                     right_k0_0 = _mm_hadd_pd( right_k0_0, right_k0_2);
3642                     right_k1_0 = _mm_hadd_pd( right_k1_0, right_k1_2);
3643                     right_k0_0 = _mm_hadd_pd( right_k0_0, right_k1_0);
3644                     
3645                     
3646                     right_k2_0 = _mm_mul_pd( x2_0, right_k2_0);
3647                     right_k2_2 = _mm_mul_pd( x2_2, right_k2_2);
3648                     
3649                     
3650                     right_k3_0 = _mm_mul_pd( x2_0, right_k3_0);
3651                     right_k3_2 = _mm_mul_pd( x2_2, right_k3_2);
3652                     
3653                     right_k2_0 = _mm_hadd_pd( right_k2_0, right_k2_2);
3654                     right_k3_0 = _mm_hadd_pd( right_k3_0, right_k3_2);
3655                     right_k2_0 = _mm_hadd_pd( right_k2_0, right_k3_0);
3656                     
3657                     {
3658                       //
3659                       // load left side from tip vector
3660                       //
3661                       
3662                       __m128d uX1_k0_sse = _mm_load_pd( &uX1[j * 4] );
3663                       __m128d uX1_k2_sse = _mm_load_pd( &uX1[j * 4 + 2] );
3664                       
3665                       
3666                       //
3667                       // multiply left * right
3668                       //
3669                       
3670                       __m128d x1px2_k0 = _mm_mul_pd( uX1_k0_sse, right_k0_0 );
3671                       __m128d x1px2_k2 = _mm_mul_pd( uX1_k2_sse, right_k2_0 );
3672                       
3673                       
3674                       //
3675                       // multiply with EV matrix (!?)
3676                       //                                 
3677                       
3678                       __m128d EV_t_l0_k0 = EVV[0];
3679                       __m128d EV_t_l0_k2 = EVV[1];
3680                       __m128d EV_t_l1_k0 = EVV[2];
3681                       __m128d EV_t_l1_k2 = EVV[3];
3682                       __m128d EV_t_l2_k0 = EVV[4];
3683                       __m128d EV_t_l2_k2 = EVV[5];
3684                       __m128d EV_t_l3_k0 = EVV[6]; 
3685                       __m128d EV_t_l3_k2 = EVV[7];
3686                       
3687                       
3688                       EV_t_l0_k0 = _mm_mul_pd( x1px2_k0, EV_t_l0_k0 );
3689                       EV_t_l0_k2 = _mm_mul_pd( x1px2_k2, EV_t_l0_k2 );
3690                       EV_t_l0_k0 = _mm_hadd_pd( EV_t_l0_k0, EV_t_l0_k2 );
3691                       
3692                       EV_t_l1_k0 = _mm_mul_pd( x1px2_k0, EV_t_l1_k0 );
3693                       EV_t_l1_k2 = _mm_mul_pd( x1px2_k2, EV_t_l1_k2 );
3694                       
3695                       EV_t_l1_k0 = _mm_hadd_pd( EV_t_l1_k0, EV_t_l1_k2 );
3696                       EV_t_l0_k0 = _mm_hadd_pd( EV_t_l0_k0, EV_t_l1_k0 );
3697                       
3698                       EV_t_l2_k0 = _mm_mul_pd( x1px2_k0, EV_t_l2_k0 );
3699                       EV_t_l2_k2 = _mm_mul_pd( x1px2_k2, EV_t_l2_k2 );
3700                       EV_t_l2_k0 = _mm_hadd_pd( EV_t_l2_k0, EV_t_l2_k2 );
3701                       
3702                       EV_t_l3_k0 = _mm_mul_pd( x1px2_k0, EV_t_l3_k0 );
3703                       EV_t_l3_k2 = _mm_mul_pd( x1px2_k2, EV_t_l3_k2 );
3704                       EV_t_l3_k0 = _mm_hadd_pd( EV_t_l3_k0, EV_t_l3_k2 );
3705                       
3706                       EV_t_l2_k0 = _mm_hadd_pd( EV_t_l2_k0, EV_t_l3_k0 );
3707                       
3708                       values[j * 2]     = EV_t_l0_k0;
3709                       values[j * 2 + 1] = EV_t_l2_k0;                             
3710                           
3711                       maxv = _mm_max_pd(maxv, _mm_and_pd(EV_t_l0_k0, absMask.m));
3712                       maxv = _mm_max_pd(maxv, _mm_and_pd(EV_t_l2_k0, absMask.m));                 
3713                     }             
3714                   }
3715
3716             
3717                 _mm_store_pd(maxima, maxv);
3718                 
3719                 max = MAX(maxima[0], maxima[1]);
3720                 
3721                 if(max < minlikelihood)
3722                   {
3723                     __m128d sv = _mm_set1_pd(twotothe256);
3724                     
3725                     _mm_store_pd(&x3[0], _mm_mul_pd(values[0], sv));     
3726                     _mm_store_pd(&x3[2], _mm_mul_pd(values[1], sv));
3727                     _mm_store_pd(&x3[4], _mm_mul_pd(values[2], sv));
3728                     _mm_store_pd(&x3[6], _mm_mul_pd(values[3], sv));
3729                     _mm_store_pd(&x3[8], _mm_mul_pd(values[4], sv));     
3730                     _mm_store_pd(&x3[10], _mm_mul_pd(values[5], sv));
3731                     _mm_store_pd(&x3[12], _mm_mul_pd(values[6], sv));
3732                     _mm_store_pd(&x3[14], _mm_mul_pd(values[7], sv));       
3733                     
3734                     if(useFastScaling)
3735                       addScale += wgt[i];
3736                     else
3737                       ex3[i]  += 1;
3738                   }
3739                 else
3740                   {
3741                     _mm_store_pd(&x3[0], values[0]);     
3742                     _mm_store_pd(&x3[2], values[1]);
3743                     _mm_store_pd(&x3[4], values[2]);
3744                     _mm_store_pd(&x3[6], values[3]);
3745                     _mm_store_pd(&x3[8], values[4]);     
3746                     _mm_store_pd(&x3[10], values[5]);
3747                     _mm_store_pd(&x3[12], values[6]);
3748                     _mm_store_pd(&x3[14], values[7]);
3749                   }             
3750                 
3751                 x3 += 16;
3752               }
3753           }
3754      }
3755      break;
3756    case INNER_INNER:         
3757      {
3758        __m128d maxv =_mm_setzero_pd();
3759       
3760        scaleGap = 0;
3761       
3762        x1 = x1_gapColumn;                 
3763        x2 = x2_gapColumn;         
3764        x3 = x3_gapColumn;
3765       
3766        for (j = 0; j < 4; j++)
3767          {
3768           
3769            double *x1_p = &x1[j*4];
3770            double *left_k0_p = &left[j*16];
3771            double *left_k1_p = &left[j*16 + 1*4];
3772            double *left_k2_p = &left[j*16 + 2*4];
3773            double *left_k3_p = &left[j*16 + 3*4];
3774           
3775            __m128d x1_0 = _mm_load_pd( &x1_p[0] );
3776            __m128d x1_2 = _mm_load_pd( &x1_p[2] );
3777           
3778            __m128d left_k0_0 = _mm_load_pd( &left_k0_p[0] );
3779            __m128d left_k0_2 = _mm_load_pd( &left_k0_p[2] );
3780            __m128d left_k1_0 = _mm_load_pd( &left_k1_p[0] );
3781            __m128d left_k1_2 = _mm_load_pd( &left_k1_p[2] );
3782            __m128d left_k2_0 = _mm_load_pd( &left_k2_p[0] );
3783            __m128d left_k2_2 = _mm_load_pd( &left_k2_p[2] );
3784            __m128d left_k3_0 = _mm_load_pd( &left_k3_p[0] );
3785            __m128d left_k3_2 = _mm_load_pd( &left_k3_p[2] );
3786           
3787            left_k0_0 = _mm_mul_pd(x1_0, left_k0_0);
3788            left_k0_2 = _mm_mul_pd(x1_2, left_k0_2);
3789           
3790            left_k1_0 = _mm_mul_pd(x1_0, left_k1_0);
3791            left_k1_2 = _mm_mul_pd(x1_2, left_k1_2);
3792           
3793            left_k0_0 = _mm_hadd_pd( left_k0_0, left_k0_2 );
3794            left_k1_0 = _mm_hadd_pd( left_k1_0, left_k1_2);
3795            left_k0_0 = _mm_hadd_pd( left_k0_0, left_k1_0);
3796           
3797            left_k2_0 = _mm_mul_pd(x1_0, left_k2_0);
3798            left_k2_2 = _mm_mul_pd(x1_2, left_k2_2);
3799           
3800            left_k3_0 = _mm_mul_pd(x1_0, left_k3_0);
3801            left_k3_2 = _mm_mul_pd(x1_2, left_k3_2);
3802           
3803            left_k2_0 = _mm_hadd_pd( left_k2_0, left_k2_2);
3804            left_k3_0 = _mm_hadd_pd( left_k3_0, left_k3_2);
3805            left_k2_0 = _mm_hadd_pd( left_k2_0, left_k3_0);
3806           
3807           
3808            double *x2_p = &x2[j*4];
3809            double *right_k0_p = &right[j*16];
3810            double *right_k1_p = &right[j*16 + 1*4];
3811            double *right_k2_p = &right[j*16 + 2*4];
3812            double *right_k3_p = &right[j*16 + 3*4];
3813            __m128d x2_0 = _mm_load_pd( &x2_p[0] );
3814            __m128d x2_2 = _mm_load_pd( &x2_p[2] );
3815           
3816            __m128d right_k0_0 = _mm_load_pd( &right_k0_p[0] );
3817            __m128d right_k0_2 = _mm_load_pd( &right_k0_p[2] );
3818            __m128d right_k1_0 = _mm_load_pd( &right_k1_p[0] );
3819            __m128d right_k1_2 = _mm_load_pd( &right_k1_p[2] );
3820            __m128d right_k2_0 = _mm_load_pd( &right_k2_p[0] );
3821            __m128d right_k2_2 = _mm_load_pd( &right_k2_p[2] );
3822            __m128d right_k3_0 = _mm_load_pd( &right_k3_p[0] );
3823            __m128d right_k3_2 = _mm_load_pd( &right_k3_p[2] );
3824           
3825            right_k0_0 = _mm_mul_pd( x2_0, right_k0_0);
3826            right_k0_2 = _mm_mul_pd( x2_2, right_k0_2);
3827           
3828            right_k1_0 = _mm_mul_pd( x2_0, right_k1_0);
3829            right_k1_2 = _mm_mul_pd( x2_2, right_k1_2);
3830           
3831            right_k0_0 = _mm_hadd_pd( right_k0_0, right_k0_2);
3832            right_k1_0 = _mm_hadd_pd( right_k1_0, right_k1_2);
3833            right_k0_0 = _mm_hadd_pd( right_k0_0, right_k1_0);
3834           
3835            right_k2_0 = _mm_mul_pd( x2_0, right_k2_0);
3836            right_k2_2 = _mm_mul_pd( x2_2, right_k2_2);
3837                   
3838            right_k3_0 = _mm_mul_pd( x2_0, right_k3_0);
3839            right_k3_2 = _mm_mul_pd( x2_2, right_k3_2);
3840           
3841            right_k2_0 = _mm_hadd_pd( right_k2_0, right_k2_2);
3842            right_k3_0 = _mm_hadd_pd( right_k3_0, right_k3_2);
3843            right_k2_0 = _mm_hadd_pd( right_k2_0, right_k3_0);                                 
3844           
3845            __m128d x1px2_k0 = _mm_mul_pd( left_k0_0, right_k0_0 );
3846            __m128d x1px2_k2 = _mm_mul_pd( left_k2_0, right_k2_0 );                                       
3847           
3848            __m128d EV_t_l0_k0 = EVV[0];
3849            __m128d EV_t_l0_k2 = EVV[1];
3850            __m128d EV_t_l1_k0 = EVV[2];
3851            __m128d EV_t_l1_k2 = EVV[3];
3852            __m128d EV_t_l2_k0 = EVV[4];
3853            __m128d EV_t_l2_k2 = EVV[5];
3854            __m128d EV_t_l3_k0 = EVV[6]; 
3855            __m128d EV_t_l3_k2 = EVV[7];
3856           
3857            EV_t_l0_k0 = _mm_mul_pd( x1px2_k0, EV_t_l0_k0 );
3858            EV_t_l0_k2 = _mm_mul_pd( x1px2_k2, EV_t_l0_k2 );
3859            EV_t_l0_k0 = _mm_hadd_pd( EV_t_l0_k0, EV_t_l0_k2 );
3860           
3861            EV_t_l1_k0 = _mm_mul_pd( x1px2_k0, EV_t_l1_k0 );
3862            EV_t_l1_k2 = _mm_mul_pd( x1px2_k2, EV_t_l1_k2 );
3863           
3864            EV_t_l1_k0 = _mm_hadd_pd( EV_t_l1_k0, EV_t_l1_k2 );
3865            EV_t_l0_k0 = _mm_hadd_pd( EV_t_l0_k0, EV_t_l1_k0 );
3866           
3867            EV_t_l2_k0 = _mm_mul_pd( x1px2_k0, EV_t_l2_k0 );
3868            EV_t_l2_k2 = _mm_mul_pd( x1px2_k2, EV_t_l2_k2 );
3869            EV_t_l2_k0 = _mm_hadd_pd( EV_t_l2_k0, EV_t_l2_k2 );
3870           
3871            EV_t_l3_k0 = _mm_mul_pd( x1px2_k0, EV_t_l3_k0 );
3872            EV_t_l3_k2 = _mm_mul_pd( x1px2_k2, EV_t_l3_k2 );
3873            EV_t_l3_k0 = _mm_hadd_pd( EV_t_l3_k0, EV_t_l3_k2 );
3874           
3875            EV_t_l2_k0 = _mm_hadd_pd( EV_t_l2_k0, EV_t_l3_k0 );
3876           
3877           
3878            values[j * 2] = EV_t_l0_k0;
3879            values[j * 2 + 1] = EV_t_l2_k0;                         
3880           
3881            maxv = _mm_max_pd(maxv, _mm_and_pd(EV_t_l0_k0, absMask.m));
3882            maxv = _mm_max_pd(maxv, _mm_and_pd(EV_t_l2_k0, absMask.m));
3883          }
3884                     
3885        _mm_store_pd(maxima, maxv);
3886       
3887        max = MAX(maxima[0], maxima[1]);
3888       
3889        if(max < minlikelihood)
3890          {
3891            __m128d sv = _mm_set1_pd(twotothe256);
3892           
3893            scaleGap = 1;
3894           
3895            _mm_store_pd(&x3[0], _mm_mul_pd(values[0], sv));       
3896            _mm_store_pd(&x3[2], _mm_mul_pd(values[1], sv));
3897            _mm_store_pd(&x3[4], _mm_mul_pd(values[2], sv));
3898            _mm_store_pd(&x3[6], _mm_mul_pd(values[3], sv));
3899            _mm_store_pd(&x3[8], _mm_mul_pd(values[4], sv));       
3900            _mm_store_pd(&x3[10], _mm_mul_pd(values[5], sv));
3901            _mm_store_pd(&x3[12], _mm_mul_pd(values[6], sv));
3902            _mm_store_pd(&x3[14], _mm_mul_pd(values[7], sv));                   
3903          }
3904        else
3905          {
3906            _mm_store_pd(&x3[0], values[0]);       
3907            _mm_store_pd(&x3[2], values[1]);
3908            _mm_store_pd(&x3[4], values[2]);
3909            _mm_store_pd(&x3[6], values[3]);
3910            _mm_store_pd(&x3[8], values[4]);       
3911            _mm_store_pd(&x3[10], values[5]);
3912            _mm_store_pd(&x3[12], values[6]);
3913            _mm_store_pd(&x3[14], values[7]);
3914          }
3915      }
3916
3917     
3918      x3 = x3_start;
3919
3920     for (i = 0; i < n; i++)
3921       { 
3922         if(x3_gap[i / 32] & mask32[i % 32])
3923           {         
3924             if(scaleGap)
3925               {
3926                 if(useFastScaling)
3927                   addScale += wgt[i];
3928                 else
3929                   ex3[i]  += 1;               
3930               }
3931           }
3932         else
3933           {
3934             __m128d maxv =_mm_setzero_pd();               
3935             
3936             if(x1_gap[i / 32] & mask32[i % 32])
3937               x1 = x1_gapColumn;
3938             else
3939               {
3940                 x1 = x1_ptr;
3941                 x1_ptr += 16;
3942               }
3943             
3944             if(x2_gap[i / 32] & mask32[i % 32])
3945               x2 = x2_gapColumn;
3946             else
3947               {
3948                 x2 = x2_ptr;
3949                 x2_ptr += 16;
3950               }
3951             
3952             
3953             for (j = 0; j < 4; j++)
3954               {
3955                 
3956                 double *x1_p = &x1[j*4];
3957                 double *left_k0_p = &left[j*16];
3958                 double *left_k1_p = &left[j*16 + 1*4];
3959                 double *left_k2_p = &left[j*16 + 2*4];
3960                 double *left_k3_p = &left[j*16 + 3*4];
3961                 
3962                 __m128d x1_0 = _mm_load_pd( &x1_p[0] );
3963                 __m128d x1_2 = _mm_load_pd( &x1_p[2] );
3964                 
3965                 __m128d left_k0_0 = _mm_load_pd( &left_k0_p[0] );
3966                 __m128d left_k0_2 = _mm_load_pd( &left_k0_p[2] );
3967                 __m128d left_k1_0 = _mm_load_pd( &left_k1_p[0] );
3968                 __m128d left_k1_2 = _mm_load_pd( &left_k1_p[2] );
3969                 __m128d left_k2_0 = _mm_load_pd( &left_k2_p[0] );
3970                 __m128d left_k2_2 = _mm_load_pd( &left_k2_p[2] );
3971                 __m128d left_k3_0 = _mm_load_pd( &left_k3_p[0] );
3972                 __m128d left_k3_2 = _mm_load_pd( &left_k3_p[2] );
3973                 
3974                 left_k0_0 = _mm_mul_pd(x1_0, left_k0_0);
3975                 left_k0_2 = _mm_mul_pd(x1_2, left_k0_2);
3976                 
3977                 left_k1_0 = _mm_mul_pd(x1_0, left_k1_0);
3978                 left_k1_2 = _mm_mul_pd(x1_2, left_k1_2);
3979                 
3980                 left_k0_0 = _mm_hadd_pd( left_k0_0, left_k0_2 );
3981                 left_k1_0 = _mm_hadd_pd( left_k1_0, left_k1_2);
3982                 left_k0_0 = _mm_hadd_pd( left_k0_0, left_k1_0);
3983                 
3984                 left_k2_0 = _mm_mul_pd(x1_0, left_k2_0);
3985                 left_k2_2 = _mm_mul_pd(x1_2, left_k2_2);
3986                 
3987                 left_k3_0 = _mm_mul_pd(x1_0, left_k3_0);
3988                 left_k3_2 = _mm_mul_pd(x1_2, left_k3_2);
3989                 
3990                 left_k2_0 = _mm_hadd_pd( left_k2_0, left_k2_2);
3991                 left_k3_0 = _mm_hadd_pd( left_k3_0, left_k3_2);
3992                 left_k2_0 = _mm_hadd_pd( left_k2_0, left_k3_0);
3993                 
3994                 
3995                 //
3996                 // multiply/add right side
3997                 //
3998                 double *x2_p = &x2[j*4];
3999                 double *right_k0_p = &right[j*16];
4000                 double *right_k1_p = &right[j*16 + 1*4];
4001                 double *right_k2_p = &right[j*16 + 2*4];
4002                 double *right_k3_p = &right[j*16 + 3*4];
4003                 __m128d x2_0 = _mm_load_pd( &x2_p[0] );
4004                 __m128d x2_2 = _mm_load_pd( &x2_p[2] );
4005                 
4006                 __m128d right_k0_0 = _mm_load_pd( &right_k0_p[0] );
4007                 __m128d right_k0_2 = _mm_load_pd( &right_k0_p[2] );
4008                 __m128d right_k1_0 = _mm_load_pd( &right_k1_p[0] );
4009                 __m128d right_k1_2 = _mm_load_pd( &right_k1_p[2] );
4010                 __m128d right_k2_0 = _mm_load_pd( &right_k2_p[0] );
4011                 __m128d right_k2_2 = _mm_load_pd( &right_k2_p[2] );
4012                 __m128d right_k3_0 = _mm_load_pd( &right_k3_p[0] );
4013                 __m128d right_k3_2 = _mm_load_pd( &right_k3_p[2] );
4014                 
4015                 right_k0_0 = _mm_mul_pd( x2_0, right_k0_0);
4016                 right_k0_2 = _mm_mul_pd( x2_2, right_k0_2);
4017                 
4018                 right_k1_0 = _mm_mul_pd( x2_0, right_k1_0);
4019                 right_k1_2 = _mm_mul_pd( x2_2, right_k1_2);
4020                 
4021                 right_k0_0 = _mm_hadd_pd( right_k0_0, right_k0_2);
4022                 right_k1_0 = _mm_hadd_pd( right_k1_0, right_k1_2);
4023                 right_k0_0 = _mm_hadd_pd( right_k0_0, right_k1_0);
4024                 
4025                 right_k2_0 = _mm_mul_pd( x2_0, right_k2_0);
4026                 right_k2_2 = _mm_mul_pd( x2_2, right_k2_2);
4027                 
4028                 
4029                 right_k3_0 = _mm_mul_pd( x2_0, right_k3_0);
4030                 right_k3_2 = _mm_mul_pd( x2_2, right_k3_2);
4031                 
4032                 right_k2_0 = _mm_hadd_pd( right_k2_0, right_k2_2);
4033                 right_k3_0 = _mm_hadd_pd( right_k3_0, right_k3_2);
4034                 right_k2_0 = _mm_hadd_pd( right_k2_0, right_k3_0);       
4035                 
4036                 //
4037                 // multiply left * right
4038                 //
4039                 
4040                 __m128d x1px2_k0 = _mm_mul_pd( left_k0_0, right_k0_0 );
4041                 __m128d x1px2_k2 = _mm_mul_pd( left_k2_0, right_k2_0 );
4042                 
4043                 
4044                 //
4045                 // multiply with EV matrix (!?)
4046                 //         
4047                 
4048                 __m128d EV_t_l0_k0 = EVV[0];
4049                 __m128d EV_t_l0_k2 = EVV[1];
4050                 __m128d EV_t_l1_k0 = EVV[2];
4051                 __m128d EV_t_l1_k2 = EVV[3];
4052                 __m128d EV_t_l2_k0 = EVV[4];
4053                 __m128d EV_t_l2_k2 = EVV[5];
4054                 __m128d EV_t_l3_k0 = EVV[6]; 
4055                 __m128d EV_t_l3_k2 = EVV[7];
4056                 
4057                 
4058                 EV_t_l0_k0 = _mm_mul_pd( x1px2_k0, EV_t_l0_k0 );
4059                 EV_t_l0_k2 = _mm_mul_pd( x1px2_k2, EV_t_l0_k2 );
4060                 EV_t_l0_k0 = _mm_hadd_pd( EV_t_l0_k0, EV_t_l0_k2 );
4061                 
4062                 EV_t_l1_k0 = _mm_mul_pd( x1px2_k0, EV_t_l1_k0 );
4063                 EV_t_l1_k2 = _mm_mul_pd( x1px2_k2, EV_t_l1_k2 );
4064                 
4065                 EV_t_l1_k0 = _mm_hadd_pd( EV_t_l1_k0, EV_t_l1_k2 );
4066                 EV_t_l0_k0 = _mm_hadd_pd( EV_t_l0_k0, EV_t_l1_k0 );
4067                 
4068                 EV_t_l2_k0 = _mm_mul_pd( x1px2_k0, EV_t_l2_k0 );
4069                 EV_t_l2_k2 = _mm_mul_pd( x1px2_k2, EV_t_l2_k2 );
4070                 EV_t_l2_k0 = _mm_hadd_pd( EV_t_l2_k0, EV_t_l2_k2 );
4071                 
4072                 
4073                 EV_t_l3_k0 = _mm_mul_pd( x1px2_k0, EV_t_l3_k0 );
4074                 EV_t_l3_k2 = _mm_mul_pd( x1px2_k2, EV_t_l3_k2 );
4075                 EV_t_l3_k0 = _mm_hadd_pd( EV_t_l3_k0, EV_t_l3_k2 );
4076                 
4077                 EV_t_l2_k0 = _mm_hadd_pd( EV_t_l2_k0, EV_t_l3_k0 );
4078                 
4079                 
4080                 values[j * 2] = EV_t_l0_k0;
4081                 values[j * 2 + 1] = EV_t_l2_k0;                           
4082                 
4083                 maxv = _mm_max_pd(maxv, _mm_and_pd(EV_t_l0_k0, absMask.m));
4084                 maxv = _mm_max_pd(maxv, _mm_and_pd(EV_t_l2_k0, absMask.m));
4085               }
4086             
4087             
4088             _mm_store_pd(maxima, maxv);
4089             
4090             max = MAX(maxima[0], maxima[1]);
4091             
4092             if(max < minlikelihood)
4093               {
4094                 __m128d sv = _mm_set1_pd(twotothe256);
4095                 
4096                 _mm_store_pd(&x3[0], _mm_mul_pd(values[0], sv));         
4097                 _mm_store_pd(&x3[2], _mm_mul_pd(values[1], sv));
4098                 _mm_store_pd(&x3[4], _mm_mul_pd(values[2], sv));
4099                 _mm_store_pd(&x3[6], _mm_mul_pd(values[3], sv));
4100                 _mm_store_pd(&x3[8], _mm_mul_pd(values[4], sv));         
4101                 _mm_store_pd(&x3[10], _mm_mul_pd(values[5], sv));
4102                 _mm_store_pd(&x3[12], _mm_mul_pd(values[6], sv));
4103                 _mm_store_pd(&x3[14], _mm_mul_pd(values[7], sv));           
4104                 
4105                 if(useFastScaling)
4106                   addScale += wgt[i];
4107                 else
4108                   ex3[i]  += 1;
4109               }
4110             else
4111               {
4112                 _mm_store_pd(&x3[0], values[0]);         
4113                 _mm_store_pd(&x3[2], values[1]);
4114                 _mm_store_pd(&x3[4], values[2]);
4115                 _mm_store_pd(&x3[6], values[3]);
4116                 _mm_store_pd(&x3[8], values[4]);         
4117                 _mm_store_pd(&x3[10], values[5]);
4118                 _mm_store_pd(&x3[12], values[6]);
4119                 _mm_store_pd(&x3[14], values[7]);
4120               }         
4121
4122           
4123                 
4124             x3 += 16;
4125
4126           }
4127       }
4128     break;
4129    default:
4130      assert(0);
4131    }
4132 
4133  if(useFastScaling)
4134    *scalerIncrement = addScale;
4135}
4136
4137
4138
4139
4140#else
4141
4142
4143
4144
4145
4146static void newviewGTRGAMMA(int tipCase,
4147                            double *x1_start, double *x2_start, double *x3_start,
4148                            double *EV, double *tipVector,
4149                            int *ex3, unsigned char *tipX1, unsigned char *tipX2,
4150                            const int n, double *left, double *right, int *wgt, int *scalerIncrement, const boolean useFastScaling
4151                            )
4152{
4153  int i, j, k, l, scale, addScale = 0;
4154  double
4155    *x1,
4156    *x2,
4157    *x3,
4158    buf,
4159    ump_x1,
4160    ump_x2;
4161
4162
4163  double x1px2[4];
4164
4165 
4166 
4167
4168
4169  switch(tipCase)
4170    {
4171    case TIP_TIP:
4172      {
4173        double *uX1, umpX1[256], *uX2, umpX2[256];
4174
4175
4176        for(i = 1; i < 16; i++)
4177          {
4178            x1 = &(tipVector[i * 4]);
4179
4180            for(j=0; j<4; j++)
4181              for(k=0; k<4; k++)
4182                {
4183                  umpX1[i*16 + j*4 + k] = 0.0;
4184                  umpX2[i*16 + j*4 + k] = 0.0;
4185
4186                  for (l=0; l < 4; l++)
4187                    {
4188                      umpX1[i*16 + j*4 + k] += x1[l] * left[j*16 + k*4 + l];
4189                      umpX2[i*16 + j*4 + k] += x1[l] * right[j*16 + k*4 + l];
4190                    }
4191                }
4192          }
4193
4194       
4195
4196        for (i = 0; i < n; i++)
4197          {
4198            x3 = &x3_start[i * 16];
4199
4200            uX1 = &umpX1[16 * tipX1[i]];
4201            uX2 = &umpX2[16 * tipX2[i]];
4202
4203            for(j = 0; j < 16; j++)
4204              x3[j] = 0.0;
4205
4206            for (j = 0; j < 4; j++)
4207              for (k = 0; k < 4; k++)
4208                {
4209                  buf = uX1[j*4 + k] * uX2[j*4 + k];
4210
4211                  for (l=0; l<4; l++)
4212                    x3[j * 4 + l] +=  buf * EV[4 * k + l];
4213                }         
4214          }
4215      }
4216      break;
4217    case TIP_INNER:
4218      { 
4219        double *uX1, umpX1[256];
4220
4221
4222        for (i = 1; i < 16; i++)
4223          {
4224            x1 = &(tipVector[i*4]);
4225
4226            for (j = 0; j < 4; j++)
4227              for (k = 0; k < 4; k++)
4228                {
4229                  umpX1[i*16 + j*4 + k] = 0.0;
4230                  for (l=0; l < 4; l++)
4231                    umpX1[i*16 + j*4 + k] += x1[l] * left[j*16 + k*4 + l];
4232                }
4233          }
4234
4235
4236         for (i = 0; i < n; i++)
4237           {
4238             x2 = &x2_start[i * 16];
4239             x3 = &x3_start[i * 16];
4240
4241             uX1 = &umpX1[16 * tipX1[i]];
4242
4243             for(j = 0; j < 16; j++)
4244               x3[j] = 0.0;
4245
4246             for (j = 0; j < 4; j++)
4247               {
4248
4249
4250                 for (k = 0; k < 4; k++)
4251                   {
4252                     ump_x2 = 0.0;
4253
4254                     for (l=0; l<4; l++)
4255                       ump_x2 += x2[j*4 + l] * right[j* 16 + k*4 + l];
4256                     x1px2[k] = uX1[j * 4 + k] * ump_x2;
4257                   }
4258
4259                 for(k = 0; k < 4; k++)
4260                   for (l=0; l<4; l++)
4261                     x3[j * 4 + l] +=  x1px2[k] * EV[4 * k + l];
4262
4263
4264               }             
4265
4266             scale = 1;
4267             for(l = 0; scale && (l < 16); l++)
4268               scale = (ABS(x3[l]) <  minlikelihood);
4269
4270             if(scale)
4271               {
4272                 for (l=0; l<16; l++)
4273                   x3[l] *= twotothe256;
4274
4275                 if(useFastScaling)
4276                   addScale += wgt[i];
4277                 else
4278                   ex3[i]  += 1;                 
4279               }
4280
4281           }
4282      }
4283      break;
4284    case INNER_INNER:
4285     for (i = 0; i < n; i++)
4286       {
4287         x1 = &x1_start[i * 16];
4288         x2 = &x2_start[i * 16];
4289         x3 = &x3_start[i * 16];
4290
4291         for(j = 0; j < 16; j++)
4292           x3[j] = 0.0;
4293
4294         for (j = 0; j < 4; j++)
4295           {
4296             for (k = 0; k < 4; k++)
4297               {
4298                 ump_x1 = 0.0;
4299                 ump_x2 = 0.0;
4300
4301                 for (l=0; l<4; l++)
4302                   {
4303                     ump_x1 += x1[j*4 + l] * left[j*16 + k*4 +l];
4304                     ump_x2 += x2[j*4 + l] * right[j*16 + k*4 +l];
4305                   }
4306
4307
4308
4309
4310                 x1px2[k] = ump_x1 * ump_x2;
4311               }
4312
4313             for(k = 0; k < 4; k++)
4314               for (l=0; l<4; l++)
4315                 x3[j * 4 + l] +=  x1px2[k] * EV[4 * k + l];
4316           }     
4317
4318         scale = 1;
4319         for(l = 0; scale && (l < 16); l++)
4320           scale = (ABS(x3[l]) <  minlikelihood);
4321
4322         if(scale)
4323           {
4324             for (l=0; l<16; l++)
4325               x3[l] *= twotothe256;
4326
4327              if(useFastScaling)
4328                addScale += wgt[i];
4329              else
4330                ex3[i]  += 1;     
4331           }                           
4332       }
4333   
4334     break;
4335    default:
4336      assert(0);
4337    }
4338 
4339  if(useFastScaling)
4340    *scalerIncrement = addScale;
4341
4342}
4343
4344#endif
4345
4346
4347#ifdef __SIM_SSE3
4348static void newviewGTRCATPROT_SAVE(int tipCase, double *extEV,
4349    int *cptr,
4350    double *x1, double *x2, double *x3, double *tipVector,
4351    int *ex3, unsigned char *tipX1, unsigned char *tipX2,
4352    int n, double *left, double *right, int *wgt, int *scalerIncrement, const boolean useFastScaling,
4353    unsigned int *x1_gap, unsigned int *x2_gap, unsigned int *x3_gap,
4354    double *x1_gapColumn, double *x2_gapColumn, double *x3_gapColumn, const int maxCats)
4355{
4356  double
4357    *le, 
4358  *ri, 
4359  *v, 
4360  *vl, 
4361  *vr,
4362  *x1_ptr = x1,
4363  *x2_ptr = x2, 
4364  *x3_ptr = x3;
4365
4366  int 
4367    i, 
4368    l, 
4369    j, 
4370    scale, 
4371    scaleGap = 0,
4372    addScale = 0;
4373
4374  {
4375    vl = x1_gapColumn;       
4376    vr = x2_gapColumn;
4377    v = x3_gapColumn;
4378
4379    le = &left[maxCats * 400];
4380    ri = &right[maxCats * 400];   
4381
4382    for(l = 0; l < 20; l+=2)
4383      _mm_store_pd(&v[l], _mm_setzero_pd());                   
4384
4385    for(l = 0; l < 20; l++)
4386    {
4387      __m128d x1v = _mm_setzero_pd();
4388      __m128d x2v = _mm_setzero_pd();
4389      double 
4390        *ev = &extEV[l * 20],
4391        *lv = &le[l * 20],
4392        *rv = &ri[l * 20];
4393
4394
4395      for(j = 0; j < 20; j+=2)
4396      {
4397        x1v = _mm_add_pd(x1v, _mm_mul_pd(_mm_load_pd(&vl[j]), _mm_load_pd(&lv[j])));               
4398        x2v = _mm_add_pd(x2v, _mm_mul_pd(_mm_load_pd(&vr[j]), _mm_load_pd(&rv[j])));
4399      }
4400
4401      x1v = _mm_hadd_pd(x1v, x1v);
4402      x2v = _mm_hadd_pd(x2v, x2v);
4403
4404      x1v = _mm_mul_pd(x1v, x2v);
4405
4406      for(j = 0; j < 20; j+=2)
4407      {
4408        __m128d vv = _mm_load_pd(&v[j]);
4409        vv = _mm_add_pd(vv, _mm_mul_pd(x1v, _mm_load_pd(&ev[j])));
4410        _mm_store_pd(&v[j], vv);
4411      }                 
4412    }
4413
4414    if(tipCase != TIP_TIP)
4415    {       
4416      __m128d minlikelihood_sse = _mm_set1_pd( minlikelihood );
4417
4418      scale = 1;
4419      for(l = 0; scale && (l < 20); l += 2)
4420      {
4421        __m128d vv = _mm_load_pd(&v[l]);
4422        __m128d v1 = _mm_and_pd(vv, absMask.m);
4423        v1 = _mm_cmplt_pd(v1,  minlikelihood_sse);
4424        if(_mm_movemask_pd( v1 ) != 3)
4425          scale = 0;
4426      }                 
4427
4428      if(scale)
4429      {
4430        __m128d twoto = _mm_set_pd(twotothe256, twotothe256);
4431
4432        for(l = 0; l < 20; l+=2)
4433        {
4434          __m128d ex3v = _mm_load_pd(&v[l]);             
4435          _mm_store_pd(&v[l], _mm_mul_pd(ex3v,twoto)); 
4436        }                                 
4437
4438        scaleGap = TRUE;           
4439      }
4440    }
4441  }
4442
4443  switch(tipCase)
4444  {
4445    case TIP_TIP:
4446      {
4447        for (i = 0; i < n; i++)
4448        {
4449          if(noGap(x3_gap, i))
4450          {             
4451            vl = &(tipVector[20 * tipX1[i]]);
4452            vr = &(tipVector[20 * tipX2[i]]);
4453            v  = x3_ptr;
4454
4455            if(isGap(x1_gap, i))
4456              le =  &left[maxCats * 400];
4457            else                 
4458              le =  &left[cptr[i] * 400];         
4459
4460            if(isGap(x2_gap, i))
4461              ri =  &right[maxCats * 400];
4462            else                 
4463              ri =  &right[cptr[i] * 400];
4464
4465            for(l = 0; l < 20; l+=2)
4466              _mm_store_pd(&v[l], _mm_setzero_pd());                   
4467
4468            for(l = 0; l < 20; l++)
4469            {
4470              __m128d x1v = _mm_setzero_pd();
4471              __m128d x2v = _mm_setzero_pd();   
4472              double 
4473                *ev = &extEV[l * 20],
4474                *lv = &le[l * 20],
4475                *rv = &ri[l * 20];
4476
4477              for(j = 0; j < 20; j+=2)
4478              {
4479                x1v = _mm_add_pd(x1v, _mm_mul_pd(_mm_load_pd(&vl[j]), _mm_load_pd(&lv[j])));               
4480                x2v = _mm_add_pd(x2v, _mm_mul_pd(_mm_load_pd(&vr[j]), _mm_load_pd(&rv[j])));
4481              }
4482
4483              x1v = _mm_hadd_pd(x1v, x1v);
4484              x2v = _mm_hadd_pd(x2v, x2v);
4485
4486              x1v = _mm_mul_pd(x1v, x2v);
4487
4488              for(j = 0; j < 20; j+=2)
4489              {
4490                __m128d vv = _mm_load_pd(&v[j]);
4491                vv = _mm_add_pd(vv, _mm_mul_pd(x1v, _mm_load_pd(&ev[j])));
4492                _mm_store_pd(&v[j], vv);
4493              }           
4494            }
4495
4496            x3_ptr += 20;
4497
4498          }   
4499        }
4500      }
4501      break;
4502    case TIP_INNER:
4503      {
4504        for (i = 0; i < n; i++)
4505        {
4506          if(isGap(x3_gap, i))
4507          {
4508            if(scaleGap)
4509              {
4510                if(useFastScaling)
4511                  addScale += wgt[i];
4512                else
4513                  ex3[i] += 1;
4514              }             
4515          }
4516          else
4517          {     
4518            vl = &(tipVector[20 * tipX1[i]]);
4519
4520            vr = x2_ptr;
4521            v = x3_ptr;
4522
4523            if(isGap(x1_gap, i))
4524              le =  &left[maxCats * 400];
4525            else
4526              le =  &left[cptr[i] * 400];
4527
4528            if(isGap(x2_gap, i))
4529            {           
4530              ri =  &right[maxCats * 400];
4531              vr = x2_gapColumn;
4532            }
4533            else
4534            {
4535              ri =  &right[cptr[i] * 400];
4536              vr = x2_ptr;
4537              x2_ptr += 20;
4538            }                                             
4539
4540            for(l = 0; l < 20; l+=2)
4541              _mm_store_pd(&v[l], _mm_setzero_pd());                               
4542
4543            for(l = 0; l < 20; l++)
4544            {
4545              __m128d x1v = _mm_setzero_pd();
4546              __m128d x2v = _mm_setzero_pd();   
4547              double 
4548                *ev = &extEV[l * 20],
4549                *lv = &le[l * 20],
4550                *rv = &ri[l * 20];
4551
4552              for(j = 0; j < 20; j+=2)
4553              {
4554                x1v = _mm_add_pd(x1v, _mm_mul_pd(_mm_load_pd(&vl[j]), _mm_load_pd(&lv[j])));               
4555                x2v = _mm_add_pd(x2v, _mm_mul_pd(_mm_load_pd(&vr[j]), _mm_load_pd(&rv[j])));
4556              }
4557
4558              x1v = _mm_hadd_pd(x1v, x1v);
4559              x2v = _mm_hadd_pd(x2v, x2v);
4560
4561              x1v = _mm_mul_pd(x1v, x2v);
4562
4563              for(j = 0; j < 20; j+=2)
4564              {
4565                __m128d vv = _mm_load_pd(&v[j]);
4566                vv = _mm_add_pd(vv, _mm_mul_pd(x1v, _mm_load_pd(&ev[j])));
4567                _mm_store_pd(&v[j], vv);
4568              }             
4569            }
4570
4571            {       
4572              __m128d minlikelihood_sse = _mm_set1_pd( minlikelihood );
4573
4574              scale = 1;
4575              for(l = 0; scale && (l < 20); l += 2)
4576              {
4577                __m128d vv = _mm_load_pd(&v[l]);
4578                __m128d v1 = _mm_and_pd(vv, absMask.m);
4579                v1 = _mm_cmplt_pd(v1,  minlikelihood_sse);
4580                if(_mm_movemask_pd( v1 ) != 3)
4581                  scale = 0;
4582              }           
4583            }
4584
4585
4586            if(scale)
4587              {
4588                __m128d twoto = _mm_set_pd(twotothe256, twotothe256);
4589               
4590                for(l = 0; l < 20; l+=2)
4591                  {
4592                    __m128d ex3v = _mm_load_pd(&v[l]);
4593                    _mm_store_pd(&v[l], _mm_mul_pd(ex3v,twoto));                   
4594                  }
4595               
4596                if(useFastScaling)
4597                  addScale += wgt[i];
4598                else
4599                  ex3[i] += 1;             
4600              }
4601           
4602 
4603            x3_ptr += 20;
4604          }
4605        }
4606      }
4607      break;
4608    case INNER_INNER:
4609      for(i = 0; i < n; i++)
4610      { 
4611        if(isGap(x3_gap, i))
4612        {
4613          if(scaleGap)
4614            {
4615              if(useFastScaling)
4616                addScale += wgt[i];
4617              else
4618                ex3[i] += 1;
4619            }           
4620        }
4621        else
4622        {                   
4623          v = x3_ptr;
4624
4625          if(isGap(x1_gap, i))
4626          {
4627            vl = x1_gapColumn;
4628            le =  &left[maxCats * 400];
4629          }
4630          else
4631          {
4632            le =  &left[cptr[i] * 400];
4633            vl = x1_ptr;
4634            x1_ptr += 20;
4635          }
4636
4637          if(isGap(x2_gap, i)) 
4638          {
4639            vr = x2_gapColumn;
4640            ri =  &right[maxCats * 400];           
4641          }
4642          else
4643          {
4644            ri =  &right[cptr[i] * 400];
4645            vr = x2_ptr;
4646            x2_ptr += 20;
4647          }                               
4648
4649          for(l = 0; l < 20; l+=2)
4650            _mm_store_pd(&v[l], _mm_setzero_pd());                     
4651
4652          for(l = 0; l < 20; l++)
4653          {
4654            __m128d x1v = _mm_setzero_pd();
4655            __m128d x2v = _mm_setzero_pd();
4656            double 
4657              *ev = &extEV[l * 20],
4658              *lv = &le[l * 20],
4659              *rv = &ri[l * 20];
4660
4661            for(j = 0; j < 20; j+=2)
4662            {
4663              x1v = _mm_add_pd(x1v, _mm_mul_pd(_mm_load_pd(&vl[j]), _mm_load_pd(&lv[j])));                 
4664              x2v = _mm_add_pd(x2v, _mm_mul_pd(_mm_load_pd(&vr[j]), _mm_load_pd(&rv[j])));
4665            }
4666
4667            x1v = _mm_hadd_pd(x1v, x1v);
4668            x2v = _mm_hadd_pd(x2v, x2v);
4669
4670            x1v = _mm_mul_pd(x1v, x2v);
4671
4672            for(j = 0; j < 20; j+=2)
4673            {
4674              __m128d vv = _mm_load_pd(&v[j]);
4675              vv = _mm_add_pd(vv, _mm_mul_pd(x1v, _mm_load_pd(&ev[j])));
4676              _mm_store_pd(&v[j], vv);
4677            }               
4678
4679          }
4680
4681          {         
4682            __m128d minlikelihood_sse = _mm_set1_pd( minlikelihood );
4683
4684            scale = 1;
4685            for(l = 0; scale && (l < 20); l += 2)
4686            {
4687              __m128d vv = _mm_load_pd(&v[l]);
4688              __m128d v1 = _mm_and_pd(vv, absMask.m);
4689              v1 = _mm_cmplt_pd(v1,  minlikelihood_sse);
4690              if(_mm_movemask_pd( v1 ) != 3)
4691                scale = 0;
4692            }             
4693          }
4694
4695          if(scale)
4696          {
4697            __m128d twoto = _mm_set_pd(twotothe256, twotothe256);
4698
4699            for(l = 0; l < 20; l+=2)
4700            {
4701              __m128d ex3v = _mm_load_pd(&v[l]);                 
4702              _mm_store_pd(&v[l], _mm_mul_pd(ex3v,twoto));     
4703            }                             
4704           
4705            if(useFastScaling)
4706              addScale += wgt[i];
4707            else
4708              ex3[i] += 1;         
4709          }
4710          x3_ptr += 20;
4711        }
4712      }
4713      break;
4714    default:
4715      assert(0);
4716  }
4717 
4718
4719  if(useFastScaling)
4720    *scalerIncrement = addScale;
4721}
4722
4723
4724#endif
4725
4726static void newviewGTRCATPROT(int tipCase, double *extEV,
4727                              int *cptr,
4728                              double *x1, double *x2, double *x3, double *tipVector,
4729                              int *ex3, unsigned char *tipX1, unsigned char *tipX2,
4730                              int n, double *left, double *right, int *wgt, int *scalerIncrement, const boolean useFastScaling)
4731{
4732  double
4733    *le, *ri, *v, *vl, *vr;
4734#ifndef __SIM_SSE3
4735  double
4736    ump_x1, ump_x2, x1px2;
4737#endif
4738  int i, l, j, scale, addScale = 0;
4739
4740  switch(tipCase)
4741    {
4742    case TIP_TIP:
4743      {
4744        for (i = 0; i < n; i++)
4745          {
4746            le = &left[cptr[i] * 400];
4747            ri = &right[cptr[i] * 400];
4748
4749            vl = &(tipVector[20 * tipX1[i]]);
4750            vr = &(tipVector[20 * tipX2[i]]);
4751            v  = &x3[20 * i];
4752#ifdef __SIM_SSE3
4753            for(l = 0; l < 20; l+=2)
4754              _mm_store_pd(&v[l], _mm_setzero_pd());                   
4755#else
4756            for(l = 0; l < 20; l++)
4757              v[l] = 0.0;
4758#endif
4759
4760            for(l = 0; l < 20; l++)
4761              {
4762#ifdef __SIM_SSE3
4763                __m128d x1v = _mm_setzero_pd();
4764                __m128d x2v = _mm_setzero_pd(); 
4765                double 
4766                  *ev = &extEV[l * 20],
4767                  *lv = &le[l * 20],
4768                  *rv = &ri[l * 20];
4769
4770                for(j = 0; j < 20; j+=2)
4771                  {
4772                    x1v = _mm_add_pd(x1v, _mm_mul_pd(_mm_load_pd(&vl[j]), _mm_load_pd(&lv[j])));                   
4773                    x2v = _mm_add_pd(x2v, _mm_mul_pd(_mm_load_pd(&vr[j]), _mm_load_pd(&rv[j])));
4774                  }
4775
4776                x1v = _mm_hadd_pd(x1v, x1v);
4777                x2v = _mm_hadd_pd(x2v, x2v);
4778
4779                x1v = _mm_mul_pd(x1v, x2v);
4780               
4781                for(j = 0; j < 20; j+=2)
4782                  {
4783                    __m128d vv = _mm_load_pd(&v[j]);
4784                    vv = _mm_add_pd(vv, _mm_mul_pd(x1v, _mm_load_pd(&ev[j])));
4785                    _mm_store_pd(&v[j], vv);
4786                  }                 
4787#else
4788                ump_x1 = 0.0;
4789                ump_x2 = 0.0;
4790
4791                for(j = 0; j < 20; j++)
4792                  {
4793                    ump_x1 += vl[j] * le[l * 20 + j];
4794                    ump_x2 += vr[j] * ri[l * 20 + j];
4795                  }
4796
4797                x1px2 = ump_x1 * ump_x2;
4798
4799                for(j = 0; j < 20; j++)
4800                  v[j] += x1px2 * extEV[l * 20 + j];
4801#endif
4802              }   
4803          }
4804      }
4805      break;
4806    case TIP_INNER:
4807      {
4808        for (i = 0; i < n; i++)
4809          {
4810            le = &left[cptr[i] * 400];
4811            ri = &right[cptr[i] * 400];
4812
4813            vl = &(tipVector[20 * tipX1[i]]);
4814            vr = &x2[20 * i];
4815            v  = &x3[20 * i];
4816
4817#ifdef __SIM_SSE3
4818            for(l = 0; l < 20; l+=2)
4819              _mm_store_pd(&v[l], _mm_setzero_pd());                   
4820#else
4821            for(l = 0; l < 20; l++)
4822              v[l] = 0.0;
4823#endif
4824           
4825
4826            for(l = 0; l < 20; l++)
4827              {
4828#ifdef __SIM_SSE3
4829
4830                __m128d x1v = _mm_setzero_pd();
4831                __m128d x2v = _mm_setzero_pd(); 
4832                double 
4833                  *ev = &extEV[l * 20],
4834                  *lv = &le[l * 20],
4835                  *rv = &ri[l * 20];
4836
4837                for(j = 0; j < 20; j+=2)
4838                  {
4839                    x1v = _mm_add_pd(x1v, _mm_mul_pd(_mm_load_pd(&vl[j]), _mm_load_pd(&lv[j])));                   
4840                    x2v = _mm_add_pd(x2v, _mm_mul_pd(_mm_load_pd(&vr[j]), _mm_load_pd(&rv[j])));
4841                  }
4842
4843                x1v = _mm_hadd_pd(x1v, x1v);
4844                x2v = _mm_hadd_pd(x2v, x2v);
4845
4846                x1v = _mm_mul_pd(x1v, x2v);
4847               
4848                for(j = 0; j < 20; j+=2)
4849                  {
4850                    __m128d vv = _mm_load_pd(&v[j]);
4851                    vv = _mm_add_pd(vv, _mm_mul_pd(x1v, _mm_load_pd(&ev[j])));
4852                    _mm_store_pd(&v[j], vv);
4853                  }                 
4854#else
4855                ump_x1 = 0.0;
4856                ump_x2 = 0.0;
4857
4858                for(j = 0; j < 20; j++)
4859                  {
4860                    ump_x1 += vl[j] * le[l * 20 + j];
4861                    ump_x2 += vr[j] * ri[l * 20 + j];
4862                  }
4863
4864                x1px2 = ump_x1 * ump_x2;
4865
4866                for(j = 0; j < 20; j++)
4867                  v[j] += x1px2 * extEV[l * 20 + j];
4868#endif
4869              }
4870#ifdef __SIM_SSE3
4871            {       
4872              __m128d minlikelihood_sse = _mm_set1_pd( minlikelihood );
4873             
4874              scale = 1;
4875              for(l = 0; scale && (l < 20); l += 2)
4876                {
4877                  __m128d vv = _mm_load_pd(&v[l]);
4878                  __m128d v1 = _mm_and_pd(vv, absMask.m);
4879                  v1 = _mm_cmplt_pd(v1,  minlikelihood_sse);
4880                  if(_mm_movemask_pd( v1 ) != 3)
4881                    scale = 0;
4882                }                 
4883            }
4884#else
4885            scale = 1;
4886            for(l = 0; scale && (l < 20); l++)
4887              scale = ((v[l] < minlikelihood) && (v[l] > minusminlikelihood));     
4888#endif
4889
4890            if(scale)
4891              {
4892#ifdef __SIM_SSE3
4893                __m128d twoto = _mm_set_pd(twotothe256, twotothe256);
4894
4895                for(l = 0; l < 20; l+=2)
4896                  {
4897                    __m128d ex3v = _mm_load_pd(&v[l]);
4898                    _mm_store_pd(&v[l], _mm_mul_pd(ex3v,twoto));                   
4899                  }
4900#else
4901                for(l = 0; l < 20; l++)
4902                  v[l] *= twotothe256;
4903#endif
4904
4905                if(useFastScaling)
4906                  addScale += wgt[i];
4907                else
4908                  ex3[i]  += 1;       
4909              }
4910          }
4911      }
4912      break;
4913    case INNER_INNER:
4914      for(i = 0; i < n; i++)
4915        {
4916          le = &left[cptr[i] * 400];
4917          ri = &right[cptr[i] * 400];
4918
4919          vl = &x1[20 * i];
4920          vr = &x2[20 * i];
4921          v = &x3[20 * i];
4922
4923#ifdef __SIM_SSE3
4924            for(l = 0; l < 20; l+=2)
4925              _mm_store_pd(&v[l], _mm_setzero_pd());                   
4926#else
4927            for(l = 0; l < 20; l++)
4928              v[l] = 0.0;
4929#endif
4930         
4931          for(l = 0; l < 20; l++)
4932            {
4933#ifdef __SIM_SSE3
4934                __m128d x1v = _mm_setzero_pd();
4935                __m128d x2v = _mm_setzero_pd();
4936                double 
4937                  *ev = &extEV[l * 20],
4938                  *lv = &le[l * 20],
4939                  *rv = &ri[l * 20];
4940
4941
4942                for(j = 0; j < 20; j+=2)
4943                  {
4944                    x1v = _mm_add_pd(x1v, _mm_mul_pd(_mm_load_pd(&vl[j]), _mm_load_pd(&lv[j])));                   
4945                    x2v = _mm_add_pd(x2v, _mm_mul_pd(_mm_load_pd(&vr[j]), _mm_load_pd(&rv[j])));
4946                  }
4947
4948                x1v = _mm_hadd_pd(x1v, x1v);
4949                x2v = _mm_hadd_pd(x2v, x2v);
4950
4951                x1v = _mm_mul_pd(x1v, x2v);
4952               
4953                for(j = 0; j < 20; j+=2)
4954                  {
4955                    __m128d vv = _mm_load_pd(&v[j]);
4956                    vv = _mm_add_pd(vv, _mm_mul_pd(x1v, _mm_load_pd(&ev[j])));
4957                    _mm_store_pd(&v[j], vv);
4958                  }                 
4959#else
4960              ump_x1 = 0.0;
4961              ump_x2 = 0.0;
4962
4963              for(j = 0; j < 20; j++)
4964                {
4965                  ump_x1 += vl[j] * le[l * 20 + j];
4966                  ump_x2 += vr[j] * ri[l * 20 + j];
4967                }
4968
4969              x1px2 =  ump_x1 * ump_x2;
4970
4971              for(j = 0; j < 20; j++)
4972                v[j] += x1px2 * extEV[l * 20 + j];
4973#endif
4974            }
4975#ifdef __SIM_SSE3
4976            {       
4977              __m128d minlikelihood_sse = _mm_set1_pd( minlikelihood );
4978             
4979              scale = 1;
4980              for(l = 0; scale && (l < 20); l += 2)
4981                {
4982                  __m128d vv = _mm_load_pd(&v[l]);
4983                  __m128d v1 = _mm_and_pd(vv, absMask.m);
4984                  v1 = _mm_cmplt_pd(v1,  minlikelihood_sse);
4985                  if(_mm_movemask_pd( v1 ) != 3)
4986                    scale = 0;
4987                }                 
4988            }
4989#else
4990           scale = 1;
4991           for(l = 0; scale && (l < 20); l++)
4992             scale = ((v[l] < minlikelihood) && (v[l] > minusminlikelihood));
4993#endif     
4994
4995           if(scale)
4996             {
4997#ifdef __SIM_SSE3
4998               __m128d twoto = _mm_set_pd(twotothe256, twotothe256);
4999               
5000               for(l = 0; l < 20; l+=2)
5001                 {
5002                   __m128d ex3v = _mm_load_pd(&v[l]);             
5003                   _mm_store_pd(&v[l], _mm_mul_pd(ex3v,twoto)); 
5004                 }                               
5005#else
5006               for(l = 0; l < 20; l++)
5007                 v[l] *= twotothe256;
5008#endif
5009
5010               if(useFastScaling)
5011                 addScale += wgt[i];
5012               else
5013                 ex3[i]  += 1;       
5014             }
5015        }
5016      break;
5017    default:
5018      assert(0);
5019    }
5020 
5021  if(useFastScaling)
5022    *scalerIncrement = addScale;
5023
5024}
5025
5026
5027
5028
5029
5030
5031static void newviewGTRCATSECONDARY(int tipCase, double *extEV,
5032                                   int *cptr,
5033                                   double *x1, double *x2, double *x3, double *tipVector,
5034                                   int *ex3, unsigned char *tipX1, unsigned char *tipX2,
5035                                   int n, double *left, double *right, int *wgt, int *scalerIncrement, const boolean useFastScaling)
5036{
5037  double
5038    *le, *ri, *v, *vl, *vr;
5039  double
5040    ump_x1, ump_x2, x1px2;
5041  int i, l, j, scale, addScale = 0;
5042
5043  switch(tipCase)
5044    {
5045    case TIP_TIP:
5046      {
5047        for (i = 0; i < n; i++)
5048          {
5049            le = &left[cptr[i] * 256];
5050            ri = &right[cptr[i] * 256];
5051
5052            vl = &(tipVector[16 * tipX1[i]]);
5053            vr = &(tipVector[16 * tipX2[i]]);
5054            v  = &x3[16 * i];
5055
5056            for(l = 0; l < 16; l++)
5057              v[l] = 0.0;
5058
5059            for(l = 0; l < 16; l++)
5060              {
5061                ump_x1 = 0.0;
5062                ump_x2 = 0.0;
5063
5064                for(j = 0; j < 16; j++)
5065                  {
5066                    ump_x1 += vl[j] * le[l * 16 + j];
5067                    ump_x2 += vr[j] * ri[l * 16 + j];
5068                  }
5069
5070                x1px2 = ump_x1 * ump_x2;
5071
5072                for(j = 0; j < 16; j++)
5073                  v[j] += x1px2 * extEV[l * 16 + j];
5074              }     
5075          }
5076      }
5077      break;
5078    case TIP_INNER:
5079      {
5080        for (i = 0; i < n; i++)
5081          {
5082            le = &left[cptr[i] * 256];
5083            ri = &right[cptr[i] * 256];
5084
5085            vl = &(tipVector[16 * tipX1[i]]);
5086            vr = &x2[16 * i];
5087            v  = &x3[16 * i];
5088
5089            for(l = 0; l < 16; l++)
5090              v[l] = 0.0;
5091
5092            for(l = 0; l < 16; l++)
5093              {
5094                ump_x1 = 0.0;
5095                ump_x2 = 0.0;
5096
5097                for(j = 0; j < 16; j++)
5098                  {
5099                    ump_x1 += vl[j] * le[l * 16 + j];
5100                    ump_x2 += vr[j] * ri[l * 16 + j];
5101                  }
5102
5103                x1px2 = ump_x1 * ump_x2;
5104
5105                for(j = 0; j < 16; j++)
5106                  v[j] += x1px2 * extEV[l * 16 + j];
5107              }
5108
5109            scale = 1;
5110            for(l = 0; scale && (l < 16); l++)
5111              scale = ((v[l] < minlikelihood) && (v[l] > minusminlikelihood));     
5112
5113            if(scale)
5114              {
5115                for(l = 0; l < 16; l++)
5116                  v[l] *= twotothe256;
5117               
5118                if(useFastScaling)
5119                  addScale += wgt[i];
5120                else
5121                  ex3[i]  += 1;       
5122              }
5123          }
5124      }
5125      break;
5126    case INNER_INNER:
5127      for(i = 0; i < n; i++)
5128        {
5129          le = &left[cptr[i] * 256];
5130          ri = &right[cptr[i] * 256];
5131
5132          vl = &x1[16 * i];
5133          vr = &x2[16 * i];
5134          v = &x3[16 * i];
5135
5136          for(l = 0; l < 16; l++)
5137            v[l] = 0.0;
5138
5139          for(l = 0; l < 16; l++)
5140            {
5141              ump_x1 = 0.0;
5142              ump_x2 = 0.0;
5143
5144              for(j = 0; j < 16; j++)
5145                {
5146                  ump_x1 += vl[j] * le[l * 16 + j];
5147                  ump_x2 += vr[j] * ri[l * 16 + j];
5148                }
5149
5150              x1px2 =  ump_x1 * ump_x2;
5151
5152              for(j = 0; j < 16; j++)
5153                v[j] += x1px2 * extEV[l * 16 + j];
5154            }
5155
5156           scale = 1;
5157           for(l = 0; scale && (l < 16); l++)
5158             scale = ((v[l] < minlikelihood) && (v[l] > minusminlikelihood));
5159         
5160           if(scale)
5161             {
5162               for(l = 0; l < 16; l++)
5163                 v[l] *= twotothe256;
5164
5165               if(useFastScaling)
5166                 addScale += wgt[i];
5167               else
5168                 ex3[i]  += 1;       
5169             }
5170        }
5171      break;
5172    default:
5173      assert(0);
5174    }
5175
5176  if(useFastScaling)
5177    *scalerIncrement = addScale;
5178
5179}
5180
5181
5182
5183static void newviewGTRCATSECONDARY_6(int tipCase, double *extEV,
5184                                   int *cptr,
5185                                   double *x1, double *x2, double *x3, double *tipVector,
5186                                   int *ex3, unsigned char *tipX1, unsigned char *tipX2,
5187                                   int n, double *left, double *right, int *wgt, int *scalerIncrement, const boolean useFastScaling)
5188{
5189  double
5190    *le, *ri, *v, *vl, *vr;
5191  double
5192    ump_x1, ump_x2, x1px2;
5193  int i, l, j, scale, addScale = 0;
5194
5195  switch(tipCase)
5196    {
5197    case TIP_TIP:
5198      {
5199        for (i = 0; i < n; i++)
5200          {
5201            le = &left[cptr[i] * 36];
5202            ri = &right[cptr[i] * 36];
5203
5204            vl = &(tipVector[6 * tipX1[i]]);
5205            vr = &(tipVector[6 * tipX2[i]]);
5206            v  = &x3[6 * i];
5207
5208            for(l = 0; l < 6; l++)
5209              v[l] = 0.0;
5210
5211            for(l = 0; l < 6; l++)
5212              {
5213                ump_x1 = 0.0;
5214                ump_x2 = 0.0;
5215
5216                for(j = 0; j < 6; j++)
5217                  {
5218                    ump_x1 += vl[j] * le[l * 6 + j];
5219                    ump_x2 += vr[j] * ri[l * 6 + j];
5220                  }
5221
5222                x1px2 = ump_x1 * ump_x2;
5223
5224                for(j = 0; j < 6; j++)
5225                  v[j] += x1px2 * extEV[l * 6 + j];
5226              }     
5227          }
5228      }
5229      break;
5230    case TIP_INNER:
5231      {
5232        for (i = 0; i < n; i++)
5233          {
5234            le = &left[cptr[i] * 36];
5235            ri = &right[cptr[i] * 36];
5236
5237            vl = &(tipVector[6 * tipX1[i]]);
5238            vr = &x2[6 * i];
5239            v  = &x3[6 * i];
5240
5241            for(l = 0; l < 6; l++)
5242              v[l] = 0.0;
5243
5244            for(l = 0; l < 6; l++)
5245              {
5246                ump_x1 = 0.0;
5247                ump_x2 = 0.0;
5248
5249                for(j = 0; j < 6; j++)
5250                  {
5251                    ump_x1 += vl[j] * le[l * 6 + j];
5252                    ump_x2 += vr[j] * ri[l * 6 + j];
5253                  }
5254
5255                x1px2 = ump_x1 * ump_x2;
5256
5257                for(j = 0; j < 6; j++)
5258                  v[j] += x1px2 * extEV[l * 6 + j];
5259              }
5260
5261            scale = 1;
5262            for(l = 0; scale && (l < 6); l++)
5263              scale = ((v[l] < minlikelihood) && (v[l] > minusminlikelihood));     
5264
5265            if(scale)
5266              {
5267                for(l = 0; l < 6; l++)
5268                  v[l] *= twotothe256;
5269
5270                if(useFastScaling)
5271                  addScale += wgt[i];
5272                else
5273                  ex3[i]  += 1;       
5274              }
5275          }
5276      }
5277      break;
5278    case INNER_INNER:
5279      for(i = 0; i < n; i++)
5280        {
5281          le = &left[cptr[i] * 36];
5282          ri = &right[cptr[i] * 36];
5283
5284          vl = &x1[6 * i];
5285          vr = &x2[6 * i];
5286          v = &x3[6 * i];
5287
5288          for(l = 0; l < 6; l++)
5289            v[l] = 0.0;
5290
5291          for(l = 0; l < 6; l++)
5292            {
5293              ump_x1 = 0.0;
5294              ump_x2 = 0.0;
5295
5296              for(j = 0; j < 6; j++)
5297                {
5298                  ump_x1 += vl[j] * le[l * 6 + j];
5299                  ump_x2 += vr[j] * ri[l * 6 + j];
5300                }
5301
5302              x1px2 =  ump_x1 * ump_x2;
5303
5304              for(j = 0; j < 6; j++)
5305                v[j] += x1px2 * extEV[l * 6 + j];
5306            }
5307
5308           scale = 1;
5309           for(l = 0; scale && (l < 6); l++)
5310             scale = ((v[l] < minlikelihood) && (v[l] > minusminlikelihood));     
5311
5312           if(scale)
5313             {
5314               for(l = 0; l < 6; l++)
5315                 v[l] *= twotothe256;
5316               
5317               if(useFastScaling)
5318                 addScale += wgt[i];
5319               else
5320                 ex3[i]  += 1;
5321             }
5322        }
5323      break;
5324    default:
5325      assert(0);
5326    }
5327
5328  if(useFastScaling)
5329    *scalerIncrement = addScale;
5330
5331}
5332
5333static void newviewGTRCATSECONDARY_7(int tipCase, double *extEV,
5334                                     int *cptr,
5335                                     double *x1, double *x2, double *x3, double *tipVector,
5336                                     int *ex3, unsigned char *tipX1, unsigned char *tipX2,
5337                                     int n, double *left, double *right, int *wgt, int *scalerIncrement, const boolean useFastScaling)
5338{
5339  double
5340    *le, *ri, *v, *vl, *vr;
5341  double
5342    ump_x1, ump_x2, x1px2;
5343  int i, l, j, scale, addScale = 0;
5344
5345  switch(tipCase)
5346    {
5347    case TIP_TIP:
5348      {
5349        for (i = 0; i < n; i++)
5350          {
5351            le = &left[cptr[i] * 49];
5352            ri = &right[cptr[i] * 49];
5353
5354            vl = &(tipVector[7 * tipX1[i]]);
5355            vr = &(tipVector[7 * tipX2[i]]);
5356            v  = &x3[7 * i];
5357
5358            for(l = 0; l < 7; l++)
5359              v[l] = 0.0;
5360
5361            for(l = 0; l < 7; l++)
5362              {
5363                ump_x1 = 0.0;
5364                ump_x2 = 0.0;
5365
5366                for(j = 0; j < 7; j++)
5367                  {
5368                    ump_x1 += vl[j] * le[l * 7 + j];
5369                    ump_x2 += vr[j] * ri[l * 7 + j];
5370                  }
5371
5372                x1px2 = ump_x1 * ump_x2;
5373
5374                for(j = 0; j < 7; j++)
5375                  v[j] += x1px2 * extEV[l * 7 + j];
5376              }     
5377          }
5378      }
5379      break;
5380    case TIP_INNER:
5381      {
5382        for (i = 0; i < n; i++)
5383          {
5384            le = &left[cptr[i] * 49];
5385            ri = &right[cptr[i] * 49];
5386
5387            vl = &(tipVector[7 * tipX1[i]]);
5388            vr = &x2[7 * i];
5389            v  = &x3[7 * i];
5390
5391            for(l = 0; l < 7; l++)
5392              v[l] = 0.0;
5393
5394            for(l = 0; l < 7; l++)
5395              {
5396                ump_x1 = 0.0;
5397                ump_x2 = 0.0;
5398
5399                for(j = 0; j < 7; j++)
5400                  {
5401                    ump_x1 += vl[j] * le[l * 7 + j];
5402                    ump_x2 += vr[j] * ri[l * 7 + j];
5403                  }
5404
5405                x1px2 = ump_x1 * ump_x2;
5406
5407                for(j = 0; j < 7; j++)
5408                  v[j] += x1px2 * extEV[l * 7 + j];
5409              }
5410
5411            scale = 1;
5412            for(l = 0; scale && (l < 7); l++)
5413              scale = ((v[l] < minlikelihood) && (v[l] > minusminlikelihood));     
5414
5415            if(scale)
5416              {
5417                for(l = 0; l < 7; l++)
5418                  v[l] *= twotothe256;
5419
5420                if(useFastScaling)
5421                 addScale += wgt[i];
5422                else
5423                  ex3[i]  += 1;                     
5424              }
5425          }
5426      }
5427      break;
5428    case INNER_INNER:
5429      for(i = 0; i < n; i++)
5430        {
5431          le = &left[cptr[i] * 49];
5432          ri = &right[cptr[i] * 49];
5433
5434          vl = &x1[7 * i];
5435          vr = &x2[7 * i];
5436          v = &x3[7 * i];
5437
5438          for(l = 0; l < 7; l++)
5439            v[l] = 0.0;
5440
5441          for(l = 0; l < 7; l++)
5442            {
5443              ump_x1 = 0.0;
5444              ump_x2 = 0.0;
5445
5446              for(j = 0; j < 7; j++)
5447                {
5448                  ump_x1 += vl[j] * le[l * 7 + j];
5449                  ump_x2 += vr[j] * ri[l * 7 + j];
5450                }
5451
5452              x1px2 =  ump_x1 * ump_x2;
5453
5454              for(j = 0; j < 7; j++)
5455                v[j] += x1px2 * extEV[l * 7 + j];
5456            }
5457
5458           scale = 1;
5459           for(l = 0; scale && (l < 7); l++)
5460             scale = ((v[l] < minlikelihood) && (v[l] > minusminlikelihood));     
5461
5462           if(scale)
5463             {
5464               for(l = 0; l < 7; l++)
5465                 v[l] *= twotothe256;
5466
5467               if(useFastScaling)
5468                 addScale += wgt[i];
5469               else
5470                 ex3[i]  += 1;       
5471             }
5472        }
5473      break;
5474    default:
5475      assert(0);
5476    }
5477
5478  if(useFastScaling)
5479    *scalerIncrement = addScale;
5480
5481}
5482
5483
5484
5485static void newviewGTRGAMMAPROT(int tipCase,
5486                                double *x1, double *x2, double *x3, double *extEV, double *tipVector,
5487                                int *ex3, unsigned char *tipX1, unsigned char *tipX2,
5488                                int n, double *left, double *right, int *wgt, int *scalerIncrement, const boolean useFastScaling)
5489{
5490  double  *uX1, *uX2, *v;
5491  double x1px2;
5492  int  i, j, l, k, scale, addScale = 0;
5493  double *vl, *vr;
5494#ifndef __SIM_SSE3
5495  double al, ar;
5496#endif
5497
5498
5499
5500  switch(tipCase)
5501    {
5502    case TIP_TIP:
5503      {
5504        double umpX1[1840], umpX2[1840];
5505
5506        for(i = 0; i < 23; i++)
5507          {
5508            v = &(tipVector[20 * i]);
5509
5510            for(k = 0; k < 80; k++)
5511              {
5512#ifdef __SIM_SSE3
5513                double *ll =  &left[k * 20];
5514                double *rr =  &right[k * 20];
5515               
5516                __m128d umpX1v = _mm_setzero_pd();
5517                __m128d umpX2v = _mm_setzero_pd();
5518
5519                for(l = 0; l < 20; l+=2)
5520                  {
5521                    __m128d vv = _mm_load_pd(&v[l]);
5522                    umpX1v = _mm_add_pd(umpX1v, _mm_mul_pd(vv, _mm_load_pd(&ll[l])));
5523                    umpX2v = _mm_add_pd(umpX2v, _mm_mul_pd(vv, _mm_load_pd(&rr[l])));                                   
5524                  }
5525               
5526                umpX1v = _mm_hadd_pd(umpX1v, umpX1v);
5527                umpX2v = _mm_hadd_pd(umpX2v, umpX2v);
5528               
5529                _mm_storel_pd(&umpX1[80 * i + k], umpX1v);
5530                _mm_storel_pd(&umpX2[80 * i + k], umpX2v);
5531#else
5532                umpX1[80 * i + k] = 0.0;
5533                umpX2[80 * i + k] = 0.0;
5534
5535                for(l = 0; l < 20; l++)
5536                  {
5537                    umpX1[80 * i + k] +=  v[l] *  left[k * 20 + l];
5538                    umpX2[80 * i + k] +=  v[l] * right[k * 20 + l];
5539                  }
5540#endif
5541              }
5542          }
5543
5544        for(i = 0; i < n; i++)
5545          {
5546            uX1 = &umpX1[80 * tipX1[i]];
5547            uX2 = &umpX2[80 * tipX2[i]];
5548
5549            for(j = 0; j < 4; j++)
5550              {
5551                v = &x3[i * 80 + j * 20];
5552
5553#ifdef __SIM_SSE3
5554                __m128d zero =  _mm_setzero_pd();
5555                for(k = 0; k < 20; k+=2)                                   
5556                  _mm_store_pd(&v[k], zero);
5557
5558                for(k = 0; k < 20; k++)
5559                  { 
5560                    double *eev = &extEV[k * 20];
5561                    x1px2 = uX1[j * 20 + k] * uX2[j * 20 + k];
5562                    __m128d x1px2v = _mm_set1_pd(x1px2);
5563
5564                    for(l = 0; l < 20; l+=2)
5565                      {
5566                        __m128d vv = _mm_load_pd(&v[l]);
5567                        __m128d ee = _mm_load_pd(&eev[l]);
5568
5569                        vv = _mm_add_pd(vv, _mm_mul_pd(x1px2v,ee));
5570                       
5571                        _mm_store_pd(&v[l], vv);
5572                      }
5573                  }
5574
5575#else
5576
5577                for(k = 0; k < 20; k++)
5578                  v[k] = 0.0;
5579
5580                for(k = 0; k < 20; k++)
5581                  {               
5582                    x1px2 = uX1[j * 20 + k] * uX2[j * 20 + k];
5583                   
5584                    for(l = 0; l < 20; l++)                                                     
5585                      v[l] += x1px2 * extEV[20 * k + l];                     
5586                  }
5587#endif
5588              }   
5589          }
5590      }
5591      break;
5592    case TIP_INNER:
5593      {
5594        double umpX1[1840], ump_x2[20];
5595
5596
5597        for(i = 0; i < 23; i++)
5598          {
5599            v = &(tipVector[20 * i]);
5600
5601            for(k = 0; k < 80; k++)
5602              {
5603#ifdef __SIM_SSE3
5604                double *ll =  &left[k * 20];
5605                               
5606                __m128d umpX1v = _mm_setzero_pd();
5607               
5608                for(l = 0; l < 20; l+=2)
5609                  {
5610                    __m128d vv = _mm_load_pd(&v[l]);
5611                    umpX1v = _mm_add_pd(umpX1v, _mm_mul_pd(vv, _mm_load_pd(&ll[l])));                                                   
5612                  }
5613               
5614                umpX1v = _mm_hadd_pd(umpX1v, umpX1v);                           
5615                _mm_storel_pd(&umpX1[80 * i + k], umpX1v);             
5616#else       
5617                umpX1[80 * i + k] = 0.0;
5618
5619                for(l = 0; l < 20; l++)
5620                  umpX1[80 * i + k] +=  v[l] * left[k * 20 + l];
5621#endif
5622
5623              }
5624          }
5625
5626        for (i = 0; i < n; i++)
5627          {
5628            uX1 = &umpX1[80 * tipX1[i]];
5629
5630            for(k = 0; k < 4; k++)
5631              {
5632                v = &(x2[80 * i + k * 20]);
5633#ifdef __SIM_SSE3             
5634                for(l = 0; l < 20; l++)
5635                  {               
5636                    double *r =  &right[k * 400 + l * 20];
5637                    __m128d ump_x2v = _mm_setzero_pd();     
5638                   
5639                    for(j = 0; j < 20; j+= 2)
5640                      {
5641                        __m128d vv = _mm_load_pd(&v[j]);
5642                        __m128d rr = _mm_load_pd(&r[j]);
5643                        ump_x2v = _mm_add_pd(ump_x2v, _mm_mul_pd(vv, rr));
5644                      }
5645                     
5646                    ump_x2v = _mm_hadd_pd(ump_x2v, ump_x2v);
5647                   
5648                    _mm_storel_pd(&ump_x2[l], ump_x2v);                             
5649                  }
5650
5651                v = &(x3[80 * i + 20 * k]);
5652
5653                __m128d zero =  _mm_setzero_pd();
5654                for(l = 0; l < 20; l+=2)                                   
5655                  _mm_store_pd(&v[l], zero);
5656                 
5657                for(l = 0; l < 20; l++)
5658                  {
5659                    double *eev = &extEV[l * 20];
5660                    x1px2 = uX1[k * 20 + l]  * ump_x2[l];
5661                    __m128d x1px2v = _mm_set1_pd(x1px2);
5662                 
5663                    for(j = 0; j < 20; j+=2)
5664                      {
5665                        __m128d vv = _mm_load_pd(&v[j]);
5666                        __m128d ee = _mm_load_pd(&eev[j]);
5667                       
5668                        vv = _mm_add_pd(vv, _mm_mul_pd(x1px2v,ee));
5669                       
5670                        _mm_store_pd(&v[j], vv);
5671                      }                             
5672                  }                     
5673#else
5674                for(l = 0; l < 20; l++)
5675                  {
5676                    ump_x2[l] = 0.0;
5677
5678                    for(j = 0; j < 20; j++)
5679                      ump_x2[l] += v[j] * right[k * 400 + l * 20 + j];
5680                  }
5681
5682                v = &(x3[80 * i + 20 * k]);
5683
5684                for(l = 0; l < 20; l++)
5685                  v[l] = 0;
5686
5687                for(l = 0; l < 20; l++)
5688                  {
5689                    x1px2 = uX1[k * 20 + l]  * ump_x2[l];
5690                    for(j = 0; j < 20; j++)
5691                      v[j] += x1px2 * extEV[l * 20  + j];
5692                  }
5693#endif
5694              }
5695           
5696#ifdef __SIM_SSE3
5697            { 
5698              v = &(x3[80 * i]);
5699              __m128d minlikelihood_sse = _mm_set1_pd( minlikelihood );
5700             
5701              scale = 1;
5702              for(l = 0; scale && (l < 80); l += 2)
5703                {
5704                  __m128d vv = _mm_load_pd(&v[l]);
5705                  __m128d v1 = _mm_and_pd(vv, absMask.m);
5706                  v1 = _mm_cmplt_pd(v1,  minlikelihood_sse);
5707                  if(_mm_movemask_pd( v1 ) != 3)
5708                    scale = 0;
5709                }                 
5710            }
5711#else
5712            v = &x3[80 * i];
5713            scale = 1;
5714            for(l = 0; scale && (l < 80); l++)
5715              scale = (ABS(v[l]) <  minlikelihood);
5716#endif
5717
5718            if (scale)
5719              {
5720#ifdef __SIM_SSE3
5721               __m128d twoto = _mm_set_pd(twotothe256, twotothe256);
5722               
5723               for(l = 0; l < 80; l+=2)
5724                 {
5725                   __m128d ex3v = _mm_load_pd(&v[l]);             
5726                   _mm_store_pd(&v[l], _mm_mul_pd(ex3v,twoto)); 
5727                 }                               
5728#else
5729                for(l = 0; l < 80; l++)
5730                  v[l] *= twotothe256;
5731#endif
5732
5733                if(useFastScaling)
5734                  addScale += wgt[i];
5735                else
5736                  ex3[i]  += 1;       
5737              }
5738          }
5739      }
5740      break;
5741    case INNER_INNER:
5742      for (i = 0; i < n; i++)
5743       {
5744         for(k = 0; k < 4; k++)
5745           {
5746             vl = &(x1[80 * i + 20 * k]);
5747             vr = &(x2[80 * i + 20 * k]);
5748             v =  &(x3[80 * i + 20 * k]);
5749
5750#ifdef __SIM_SSE3
5751             __m128d zero =  _mm_setzero_pd();
5752             for(l = 0; l < 20; l+=2)                               
5753               _mm_store_pd(&v[l], zero);
5754#else
5755             for(l = 0; l < 20; l++)
5756               v[l] = 0;
5757#endif
5758
5759             for(l = 0; l < 20; l++)
5760               {                 
5761#ifdef __SIM_SSE3
5762                 {
5763                   __m128d al = _mm_setzero_pd();
5764                   __m128d ar = _mm_setzero_pd();
5765
5766                   double *ll   = &left[k * 400 + l * 20];
5767                   double *rr   = &right[k * 400 + l * 20];
5768                   double *EVEV = &extEV[20 * l];
5769                   
5770                   for(j = 0; j < 20; j+=2)
5771                     {
5772                       __m128d lv  = _mm_load_pd(&ll[j]);
5773                       __m128d rv  = _mm_load_pd(&rr[j]);
5774                       __m128d vll = _mm_load_pd(&vl[j]);
5775                       __m128d vrr = _mm_load_pd(&vr[j]);
5776                       
5777                       al = _mm_add_pd(al, _mm_mul_pd(vll, lv));
5778                       ar = _mm_add_pd(ar, _mm_mul_pd(vrr, rv));
5779                     }                   
5780                       
5781                   al = _mm_hadd_pd(al, al);
5782                   ar = _mm_hadd_pd(ar, ar);
5783                   
5784                   al = _mm_mul_pd(al, ar);
5785
5786                   for(j = 0; j < 20; j+=2)
5787                     {
5788                       __m128d vv  = _mm_load_pd(&v[j]);
5789                       __m128d EVV = _mm_load_pd(&EVEV[j]);
5790
5791                       vv = _mm_add_pd(vv, _mm_mul_pd(al, EVV));
5792
5793                       _mm_store_pd(&v[j], vv);
5794                     }                                           
5795                 }               
5796#else
5797                 al = 0.0;
5798                 ar = 0.0;
5799
5800                 for(j = 0; j < 20; j++)
5801                   {
5802                     al += vl[j] * left[k * 400 + l * 20 + j];
5803                     ar += vr[j] * right[k * 400 + l * 20 + j];
5804                   }
5805
5806                 x1px2 = al * ar;
5807
5808                 for(j = 0; j < 20; j++)
5809                   v[j] += x1px2 * extEV[20 * l + j];
5810#endif
5811               }
5812           }
5813         
5814
5815#ifdef __SIM_SSE3
5816         { 
5817           v = &(x3[80 * i]);
5818           __m128d minlikelihood_sse = _mm_set1_pd( minlikelihood );
5819           
5820           scale = 1;
5821           for(l = 0; scale && (l < 80); l += 2)
5822             {
5823               __m128d vv = _mm_load_pd(&v[l]);
5824               __m128d v1 = _mm_and_pd(vv, absMask.m);
5825               v1 = _mm_cmplt_pd(v1,  minlikelihood_sse);
5826               if(_mm_movemask_pd( v1 ) != 3)
5827                 scale = 0;
5828             }           
5829         }
5830#else
5831         v = &(x3[80 * i]);
5832         scale = 1;
5833         for(l = 0; scale && (l < 80); l++)
5834           scale = ((ABS(v[l]) <  minlikelihood));
5835#endif
5836
5837         if (scale)
5838           {
5839#ifdef __SIM_SSE3
5840               __m128d twoto = _mm_set_pd(twotothe256, twotothe256);
5841               
5842               for(l = 0; l < 80; l+=2)
5843                 {
5844                   __m128d ex3v = _mm_load_pd(&v[l]);             
5845                   _mm_store_pd(&v[l], _mm_mul_pd(ex3v,twoto)); 
5846                 }                               
5847#else       
5848             for(l = 0; l < 80; l++)
5849               v[l] *= twotothe256;
5850#endif
5851
5852             if(useFastScaling)
5853               addScale += wgt[i];
5854             else
5855               ex3[i]  += 1;     
5856           }
5857       }
5858      break;
5859    default:
5860      assert(0);
5861    }
5862
5863  if(useFastScaling)
5864    *scalerIncrement = addScale;
5865
5866}
5867
5868static void newviewGTRGAMMAPROT_LG4(int tipCase,
5869                                    double *x1, double *x2, double *x3, double *extEV[4], double *tipVector[4],
5870                                    int *ex3, unsigned char *tipX1, unsigned char *tipX2,
5871                                    int n, double *left, double *right, int *wgt, int *scalerIncrement, const boolean useFastScaling)
5872{
5873  double  *uX1, *uX2, *v;
5874  double x1px2;
5875  int  i, j, l, k, scale, addScale = 0;
5876  double *vl, *vr;
5877#ifndef __SIM_SSE3
5878  double al, ar;
5879#endif
5880
5881
5882
5883  switch(tipCase)
5884    {
5885    case TIP_TIP:
5886      {
5887        double umpX1[1840], umpX2[1840];
5888
5889        for(i = 0; i < 23; i++)
5890          {
5891           
5892
5893            for(k = 0; k < 80; k++)
5894              {
5895               
5896                v = &(tipVector[k / 20][20 * i]);
5897#ifdef __SIM_SSE3
5898                double *ll =  &left[k * 20];
5899                double *rr =  &right[k * 20];
5900               
5901                __m128d umpX1v = _mm_setzero_pd();
5902                __m128d umpX2v = _mm_setzero_pd();
5903
5904                for(l = 0; l < 20; l+=2)
5905                  {
5906                    __m128d vv = _mm_load_pd(&v[l]);
5907                    umpX1v = _mm_add_pd(umpX1v, _mm_mul_pd(vv, _mm_load_pd(&ll[l])));
5908                    umpX2v = _mm_add_pd(umpX2v, _mm_mul_pd(vv, _mm_load_pd(&rr[l])));                                   
5909                  }
5910               
5911                umpX1v = _mm_hadd_pd(umpX1v, umpX1v);
5912                umpX2v = _mm_hadd_pd(umpX2v, umpX2v);
5913               
5914                _mm_storel_pd(&umpX1[80 * i + k], umpX1v);
5915                _mm_storel_pd(&umpX2[80 * i + k], umpX2v);
5916#else
5917                umpX1[80 * i + k] = 0.0;
5918                umpX2[80 * i + k] = 0.0;
5919
5920                for(l = 0; l < 20; l++)
5921                  {
5922                    umpX1[80 * i + k] +=  v[l] *  left[k * 20 + l];
5923                    umpX2[80 * i + k] +=  v[l] * right[k * 20 + l];
5924                  }
5925#endif
5926              }
5927          }
5928
5929        for(i = 0; i < n; i++)
5930          {
5931            uX1 = &umpX1[80 * tipX1[i]];
5932            uX2 = &umpX2[80 * tipX2[i]];
5933
5934            for(j = 0; j < 4; j++)
5935              {
5936                v = &x3[i * 80 + j * 20];
5937
5938#ifdef __SIM_SSE3
5939                __m128d zero =  _mm_setzero_pd();
5940                for(k = 0; k < 20; k+=2)                                   
5941                  _mm_store_pd(&v[k], zero);
5942
5943                for(k = 0; k < 20; k++)
5944                  { 
5945                    double *eev = &extEV[j][k * 20];
5946                    x1px2 = uX1[j * 20 + k] * uX2[j * 20 + k];
5947                    __m128d x1px2v = _mm_set1_pd(x1px2);
5948
5949                    for(l = 0; l < 20; l+=2)
5950                      {
5951                        __m128d vv = _mm_load_pd(&v[l]);
5952                        __m128d ee = _mm_load_pd(&eev[l]);
5953
5954                        vv = _mm_add_pd(vv, _mm_mul_pd(x1px2v,ee));
5955                       
5956                        _mm_store_pd(&v[l], vv);
5957                      }
5958                  }
5959
5960#else
5961
5962                for(k = 0; k < 20; k++)
5963                  v[k] = 0.0;
5964
5965                for(k = 0; k < 20; k++)
5966                  {               
5967                    x1px2 = uX1[j * 20 + k] * uX2[j * 20 + k];
5968                   
5969                    for(l = 0; l < 20; l++)                                                     
5970                      v[l] += x1px2 * extEV[j][20 * k + l];                 
5971                  }
5972#endif
5973              }   
5974          }
5975      }
5976      break;
5977    case TIP_INNER:
5978      {
5979        double umpX1[1840], ump_x2[20];
5980
5981
5982        for(i = 0; i < 23; i++)
5983          {
5984           
5985
5986            for(k = 0; k < 80; k++)
5987              { 
5988                v = &(tipVector[k / 20][20 * i]);
5989#ifdef __SIM_SSE3
5990                double *ll =  &left[k * 20];
5991                               
5992                __m128d umpX1v = _mm_setzero_pd();
5993               
5994                for(l = 0; l < 20; l+=2)
5995                  {
5996                    __m128d vv = _mm_load_pd(&v[l]);
5997                    umpX1v = _mm_add_pd(umpX1v, _mm_mul_pd(vv, _mm_load_pd(&ll[l])));                                                   
5998                  }
5999               
6000                umpX1v = _mm_hadd_pd(umpX1v, umpX1v);                           
6001                _mm_storel_pd(&umpX1[80 * i + k], umpX1v);             
6002#else       
6003                umpX1[80 * i + k] = 0.0;
6004
6005                for(l = 0; l < 20; l++)
6006                  umpX1[80 * i + k] +=  v[l] * left[k * 20 + l];
6007#endif
6008
6009              }
6010          }
6011
6012        for (i = 0; i < n; i++)
6013          {
6014            uX1 = &umpX1[80 * tipX1[i]];
6015
6016            for(k = 0; k < 4; k++)
6017              {
6018                v = &(x2[80 * i + k * 20]);
6019#ifdef __SIM_SSE3             
6020                for(l = 0; l < 20; l++)
6021                  {               
6022                    double *r =  &right[k * 400 + l * 20];
6023                    __m128d ump_x2v = _mm_setzero_pd();     
6024                   
6025                    for(j = 0; j < 20; j+= 2)
6026                      {
6027                        __m128d vv = _mm_load_pd(&v[j]);
6028                        __m128d rr = _mm_load_pd(&r[j]);
6029                        ump_x2v = _mm_add_pd(ump_x2v, _mm_mul_pd(vv, rr));
6030                      }
6031                     
6032                    ump_x2v = _mm_hadd_pd(ump_x2v, ump_x2v);
6033                   
6034                    _mm_storel_pd(&ump_x2[l], ump_x2v);                             
6035                  }
6036
6037                v = &(x3[80 * i + 20 * k]);
6038
6039                __m128d zero =  _mm_setzero_pd();
6040                for(l = 0; l < 20; l+=2)                                   
6041                  _mm_store_pd(&v[l], zero);
6042                 
6043                for(l = 0; l < 20; l++)
6044                  {
6045                    double *eev = &extEV[k][l * 20];
6046                    x1px2 = uX1[k * 20 + l]  * ump_x2[l];
6047                    __m128d x1px2v = _mm_set1_pd(x1px2);
6048                 
6049                    for(j = 0; j < 20; j+=2)
6050                      {
6051                        __m128d vv = _mm_load_pd(&v[j]);
6052                        __m128d ee = _mm_load_pd(&eev[j]);
6053                       
6054                        vv = _mm_add_pd(vv, _mm_mul_pd(x1px2v,ee));
6055                       
6056                        _mm_store_pd(&v[j], vv);
6057                      }                             
6058                  }                     
6059#else
6060                for(l = 0; l < 20; l++)
6061                  {
6062                    ump_x2[l] = 0.0;
6063
6064                    for(j = 0; j < 20; j++)
6065                      ump_x2[l] += v[j] * right[k * 400 + l * 20 + j];
6066                  }
6067
6068                v = &(x3[80 * i + 20 * k]);
6069
6070                for(l = 0; l < 20; l++)
6071                  v[l] = 0;
6072
6073                for(l = 0; l < 20; l++)
6074                  {
6075                    x1px2 = uX1[k * 20 + l]  * ump_x2[l];
6076                    for(j = 0; j < 20; j++)
6077                      v[j] += x1px2 * extEV[k][l * 20  + j];
6078                  }
6079#endif
6080              }
6081           
6082#ifdef __SIM_SSE3
6083            { 
6084              v = &(x3[80 * i]);
6085              __m128d minlikelihood_sse = _mm_set1_pd( minlikelihood );
6086             
6087              scale = 1;
6088              for(l = 0; scale && (l < 80); l += 2)
6089                {
6090                  __m128d vv = _mm_load_pd(&v[l]);
6091                  __m128d v1 = _mm_and_pd(vv, absMask.m);
6092                  v1 = _mm_cmplt_pd(v1,  minlikelihood_sse);
6093                  if(_mm_movemask_pd( v1 ) != 3)
6094                    scale = 0;
6095                }                 
6096            }
6097#else
6098            v = &x3[80 * i];
6099            scale = 1;
6100            for(l = 0; scale && (l < 80); l++)
6101              scale = (ABS(v[l]) <  minlikelihood);
6102#endif
6103
6104            if (scale)
6105              {
6106#ifdef __SIM_SSE3
6107               __m128d twoto = _mm_set_pd(twotothe256, twotothe256);
6108               
6109               for(l = 0; l < 80; l+=2)
6110                 {
6111                   __m128d ex3v = _mm_load_pd(&v[l]);             
6112                   _mm_store_pd(&v[l], _mm_mul_pd(ex3v,twoto)); 
6113                 }                               
6114#else
6115                for(l = 0; l < 80; l++)
6116                  v[l] *= twotothe256;
6117#endif
6118
6119                if(useFastScaling)
6120                  addScale += wgt[i];
6121                else
6122                  ex3[i]  += 1;       
6123              }
6124          }
6125      }
6126      break;
6127    case INNER_INNER:
6128      for (i = 0; i < n; i++)
6129       {
6130         for(k = 0; k < 4; k++)
6131           {
6132             vl = &(x1[80 * i + 20 * k]);
6133             vr = &(x2[80 * i + 20 * k]);
6134             v =  &(x3[80 * i + 20 * k]);
6135
6136#ifdef __SIM_SSE3
6137             __m128d zero =  _mm_setzero_pd();
6138             for(l = 0; l < 20; l+=2)                               
6139               _mm_store_pd(&v[l], zero);
6140#else
6141             for(l = 0; l < 20; l++)
6142               v[l] = 0;
6143#endif
6144
6145             for(l = 0; l < 20; l++)
6146               {                 
6147#ifdef __SIM_SSE3
6148                 {
6149                   __m128d al = _mm_setzero_pd();
6150                   __m128d ar = _mm_setzero_pd();
6151
6152                   double *ll   = &left[k * 400 + l * 20];
6153                   double *rr   = &right[k * 400 + l * 20];
6154                   double *EVEV = &extEV[k][20 * l];
6155                   
6156                   for(j = 0; j < 20; j+=2)
6157                     {
6158                       __m128d lv  = _mm_load_pd(&ll[j]);
6159                       __m128d rv  = _mm_load_pd(&rr[j]);
6160                       __m128d vll = _mm_load_pd(&vl[j]);
6161                       __m128d vrr = _mm_load_pd(&vr[j]);
6162                       
6163                       al = _mm_add_pd(al, _mm_mul_pd(vll, lv));
6164                       ar = _mm_add_pd(ar, _mm_mul_pd(vrr, rv));
6165                     }                   
6166                       
6167                   al = _mm_hadd_pd(al, al);
6168                   ar = _mm_hadd_pd(ar, ar);
6169                   
6170                   al = _mm_mul_pd(al, ar);
6171
6172                   for(j = 0; j < 20; j+=2)
6173                     {
6174                       __m128d vv  = _mm_load_pd(&v[j]);
6175                       __m128d EVV = _mm_load_pd(&EVEV[j]);
6176
6177                       vv = _mm_add_pd(vv, _mm_mul_pd(al, EVV));
6178
6179                       _mm_store_pd(&v[j], vv);
6180                     }                                           
6181                 }               
6182#else
6183                 al = 0.0;
6184                 ar = 0.0;
6185
6186                 for(j = 0; j < 20; j++)
6187                   {
6188                     al += vl[j] * left[k * 400 + l * 20 + j];
6189                     ar += vr[j] * right[k * 400 + l * 20 + j];
6190                   }
6191
6192                 x1px2 = al * ar;
6193
6194                 for(j = 0; j < 20; j++)
6195                   v[j] += x1px2 * extEV[k][20 * l + j];
6196#endif
6197               }
6198           }
6199         
6200
6201#ifdef __SIM_SSE3
6202         { 
6203           v = &(x3[80 * i]);
6204           __m128d minlikelihood_sse = _mm_set1_pd( minlikelihood );
6205           
6206           scale = 1;
6207           for(l = 0; scale && (l < 80); l += 2)
6208             {
6209               __m128d vv = _mm_load_pd(&v[l]);
6210               __m128d v1 = _mm_and_pd(vv, absMask.m);
6211               v1 = _mm_cmplt_pd(v1,  minlikelihood_sse);
6212               if(_mm_movemask_pd( v1 ) != 3)
6213                 scale = 0;
6214             }           
6215         }
6216#else
6217         v = &(x3[80 * i]);
6218         scale = 1;
6219         for(l = 0; scale && (l < 80); l++)
6220           scale = ((ABS(v[l]) <  minlikelihood));
6221#endif
6222
6223         if (scale)
6224           {
6225#ifdef __SIM_SSE3
6226               __m128d twoto = _mm_set_pd(twotothe256, twotothe256);
6227               
6228               for(l = 0; l < 80; l+=2)
6229                 {
6230                   __m128d ex3v = _mm_load_pd(&v[l]);             
6231                   _mm_store_pd(&v[l], _mm_mul_pd(ex3v,twoto)); 
6232                 }                               
6233#else       
6234             for(l = 0; l < 80; l++)
6235               v[l] *= twotothe256;
6236#endif
6237
6238             if(useFastScaling)
6239               addScale += wgt[i];
6240             else
6241               ex3[i]  += 1;     
6242           }
6243       }
6244      break;
6245    default:
6246      assert(0);
6247    }
6248
6249  if(useFastScaling)
6250    *scalerIncrement = addScale;
6251
6252}
6253
6254
6255#ifdef __SIM_SSE3
6256
6257
6258static void newviewGTRGAMMAPROT_GAPPED_SAVE(int tipCase,
6259    double *x1, double *x2, double *x3, double *extEV, double *tipVector,
6260    int *ex3, unsigned char *tipX1, unsigned char *tipX2,
6261    int n, double *left, double *right, int *wgt, int *scalerIncrement, const boolean useFastScaling,
6262    unsigned int *x1_gap, unsigned int *x2_gap, unsigned int *x3_gap, 
6263    double *x1_gapColumn, double *x2_gapColumn, double *x3_gapColumn
6264    )
6265{
6266  double  *uX1, *uX2, *v;
6267  double x1px2;
6268  int  i, j, l, k, scale, addScale = 0,   
6269       gapScaling = 0;
6270  double 
6271    *vl, *vr, *x1v, *x2v,
6272    *x1_ptr = x1,
6273    *x2_ptr = x2,
6274    *x3_ptr = x3;
6275
6276
6277
6278  switch(tipCase)
6279  {
6280    case TIP_TIP:
6281      {
6282        double umpX1[1840], umpX2[1840];
6283
6284        for(i = 0; i < 23; i++)
6285        {
6286          v = &(tipVector[20 * i]);
6287
6288          for(k = 0; k < 80; k++)
6289          {
6290            double *ll =  &left[k * 20];
6291            double *rr =  &right[k * 20];
6292
6293            __m128d umpX1v = _mm_setzero_pd();
6294            __m128d umpX2v = _mm_setzero_pd();
6295
6296            for(l = 0; l < 20; l+=2)
6297            {
6298              __m128d vv = _mm_load_pd(&v[l]);
6299              umpX1v = _mm_add_pd(umpX1v, _mm_mul_pd(vv, _mm_load_pd(&ll[l])));
6300              umpX2v = _mm_add_pd(umpX2v, _mm_mul_pd(vv, _mm_load_pd(&rr[l])));                                 
6301            }
6302
6303            umpX1v = _mm_hadd_pd(umpX1v, umpX1v);
6304            umpX2v = _mm_hadd_pd(umpX2v, umpX2v);
6305
6306            _mm_storel_pd(&umpX1[80 * i + k], umpX1v);
6307            _mm_storel_pd(&umpX2[80 * i + k], umpX2v);
6308          }
6309        }
6310
6311        {
6312          uX1 = &umpX1[1760];
6313          uX2 = &umpX2[1760];
6314
6315          for(j = 0; j < 4; j++)
6316          {
6317            v = &x3_gapColumn[j * 20];
6318
6319            __m128d zero =  _mm_setzero_pd();
6320            for(k = 0; k < 20; k+=2)                               
6321              _mm_store_pd(&v[k], zero);
6322
6323            for(k = 0; k < 20; k++)
6324            { 
6325              double *eev = &extEV[k * 20];
6326              x1px2 = uX1[j * 20 + k] * uX2[j * 20 + k];
6327              __m128d x1px2v = _mm_set1_pd(x1px2);
6328
6329              for(l = 0; l < 20; l+=2)
6330              {
6331                __m128d vv = _mm_load_pd(&v[l]);
6332                __m128d ee = _mm_load_pd(&eev[l]);
6333
6334                vv = _mm_add_pd(vv, _mm_mul_pd(x1px2v,ee));
6335
6336                _mm_store_pd(&v[l], vv);
6337              }
6338            }
6339          }       
6340        }       
6341
6342        for(i = 0; i < n; i++)
6343        {
6344          if(!(x3_gap[i / 32] & mask32[i % 32]))
6345          {
6346            uX1 = &umpX1[80 * tipX1[i]];
6347            uX2 = &umpX2[80 * tipX2[i]];
6348
6349            for(j = 0; j < 4; j++)
6350            {
6351              v = &x3_ptr[j * 20];
6352
6353
6354              __m128d zero =  _mm_setzero_pd();
6355              for(k = 0; k < 20; k+=2)                             
6356                _mm_store_pd(&v[k], zero);
6357
6358              for(k = 0; k < 20; k++)
6359              { 
6360                double *eev = &extEV[k * 20];
6361                x1px2 = uX1[j * 20 + k] * uX2[j * 20 + k];
6362                __m128d x1px2v = _mm_set1_pd(x1px2);
6363
6364                for(l = 0; l < 20; l+=2)
6365                {
6366                  __m128d vv = _mm_load_pd(&v[l]);
6367                  __m128d ee = _mm_load_pd(&eev[l]);
6368
6369                  vv = _mm_add_pd(vv, _mm_mul_pd(x1px2v,ee));
6370
6371                  _mm_store_pd(&v[l], vv);
6372                }
6373              }
6374            }     
6375            x3_ptr += 80;
6376          }
6377        }
6378      }
6379      break;
6380    case TIP_INNER:
6381      {
6382        double umpX1[1840], ump_x2[20];
6383
6384
6385        for(i = 0; i < 23; i++)
6386        {
6387          v = &(tipVector[20 * i]);
6388
6389          for(k = 0; k < 80; k++)
6390          {
6391            double *ll =  &left[k * 20];
6392
6393            __m128d umpX1v = _mm_setzero_pd();
6394
6395            for(l = 0; l < 20; l+=2)
6396            {
6397              __m128d vv = _mm_load_pd(&v[l]);
6398              umpX1v = _mm_add_pd(umpX1v, _mm_mul_pd(vv, _mm_load_pd(&ll[l])));                                                 
6399            }
6400
6401            umpX1v = _mm_hadd_pd(umpX1v, umpX1v);                               
6402            _mm_storel_pd(&umpX1[80 * i + k], umpX1v);         
6403
6404          }
6405        }
6406
6407        {
6408          uX1 = &umpX1[1760];
6409
6410          for(k = 0; k < 4; k++)
6411          {
6412            v = &(x2_gapColumn[k * 20]);
6413
6414            for(l = 0; l < 20; l++)
6415            {             
6416              double *r =  &right[k * 400 + l * 20];
6417              __m128d ump_x2v = _mm_setzero_pd();           
6418
6419              for(j = 0; j < 20; j+= 2)
6420              {
6421                __m128d vv = _mm_load_pd(&v[j]);
6422                __m128d rr = _mm_load_pd(&r[j]);
6423                ump_x2v = _mm_add_pd(ump_x2v, _mm_mul_pd(vv, rr));
6424              }
6425
6426              ump_x2v = _mm_hadd_pd(ump_x2v, ump_x2v);
6427
6428              _mm_storel_pd(&ump_x2[l], ump_x2v);                                   
6429            }
6430
6431            v = &(x3_gapColumn[20 * k]);
6432
6433            __m128d zero =  _mm_setzero_pd();
6434            for(l = 0; l < 20; l+=2)                               
6435              _mm_store_pd(&v[l], zero);
6436
6437            for(l = 0; l < 20; l++)
6438            {
6439              double *eev = &extEV[l * 20];
6440              x1px2 = uX1[k * 20 + l]  * ump_x2[l];
6441              __m128d x1px2v = _mm_set1_pd(x1px2);
6442
6443              for(j = 0; j < 20; j+=2)
6444              {
6445                __m128d vv = _mm_load_pd(&v[j]);
6446                __m128d ee = _mm_load_pd(&eev[j]);
6447
6448                vv = _mm_add_pd(vv, _mm_mul_pd(x1px2v,ee));
6449
6450                _mm_store_pd(&v[j], vv);
6451              }                             
6452            }                   
6453
6454          }
6455
6456          { 
6457            v = x3_gapColumn;
6458            __m128d minlikelihood_sse = _mm_set1_pd( minlikelihood );
6459
6460            scale = 1;
6461            for(l = 0; scale && (l < 80); l += 2)
6462            {
6463              __m128d vv = _mm_load_pd(&v[l]);
6464              __m128d v1 = _mm_and_pd(vv, absMask.m);
6465              v1 = _mm_cmplt_pd(v1,  minlikelihood_sse);
6466              if(_mm_movemask_pd( v1 ) != 3)
6467                scale = 0;
6468            }             
6469          }
6470
6471
6472          if (scale)
6473          {
6474            gapScaling = 1;
6475            __m128d twoto = _mm_set_pd(twotothe256, twotothe256);
6476
6477            for(l = 0; l < 80; l+=2)
6478            {
6479              __m128d ex3v = _mm_load_pd(&v[l]);                 
6480              _mm_store_pd(&v[l], _mm_mul_pd(ex3v,twoto));     
6481            }                                                         
6482          }
6483        }
6484
6485        for (i = 0; i < n; i++)
6486        {           
6487          if((x3_gap[i / 32] & mask32[i % 32]))
6488          {           
6489            if(gapScaling)
6490            {
6491              if(useFastScaling)
6492                addScale += wgt[i];
6493              else
6494                ex3[i]  += 1;
6495            }
6496          }
6497          else
6498          {
6499            uX1 = &umpX1[80 * tipX1[i]];
6500
6501            if(x2_gap[i / 32] & mask32[i % 32])
6502              x2v = x2_gapColumn;
6503            else
6504            {
6505              x2v = x2_ptr;
6506              x2_ptr += 80;
6507            }
6508
6509            for(k = 0; k < 4; k++)
6510            {
6511              v = &(x2v[k * 20]);
6512
6513              for(l = 0; l < 20; l++)
6514              {           
6515                double *r =  &right[k * 400 + l * 20];
6516                __m128d ump_x2v = _mm_setzero_pd();         
6517
6518                for(j = 0; j < 20; j+= 2)
6519                {
6520                  __m128d vv = _mm_load_pd(&v[j]);
6521                  __m128d rr = _mm_load_pd(&r[j]);
6522                  ump_x2v = _mm_add_pd(ump_x2v, _mm_mul_pd(vv, rr));
6523                }
6524
6525                ump_x2v = _mm_hadd_pd(ump_x2v, ump_x2v);
6526
6527                _mm_storel_pd(&ump_x2[l], ump_x2v);                                 
6528              }
6529
6530              v = &x3_ptr[20 * k];
6531
6532              __m128d zero =  _mm_setzero_pd();
6533              for(l = 0; l < 20; l+=2)                             
6534                _mm_store_pd(&v[l], zero);
6535
6536              for(l = 0; l < 20; l++)
6537              {
6538                double *eev = &extEV[l * 20];
6539                x1px2 = uX1[k * 20 + l]  * ump_x2[l];
6540                __m128d x1px2v = _mm_set1_pd(x1px2);
6541
6542                for(j = 0; j < 20; j+=2)
6543                {
6544                  __m128d vv = _mm_load_pd(&v[j]);
6545                  __m128d ee = _mm_load_pd(&eev[j]);
6546
6547                  vv = _mm_add_pd(vv, _mm_mul_pd(x1px2v,ee));
6548
6549                  _mm_store_pd(&v[j], vv);
6550                }                                   
6551              }                 
6552
6553            }
6554
6555
6556            { 
6557              v = x3_ptr;
6558              __m128d minlikelihood_sse = _mm_set1_pd( minlikelihood );
6559
6560              scale = 1;
6561              for(l = 0; scale && (l < 80); l += 2)
6562              {
6563                __m128d vv = _mm_load_pd(&v[l]);
6564                __m128d v1 = _mm_and_pd(vv, absMask.m);
6565                v1 = _mm_cmplt_pd(v1,  minlikelihood_sse);
6566                if(_mm_movemask_pd( v1 ) != 3)
6567                  scale = 0;
6568              }           
6569            }
6570
6571
6572            if (scale)
6573            {
6574              __m128d twoto = _mm_set_pd(twotothe256, twotothe256);
6575
6576              for(l = 0; l < 80; l+=2)
6577              {
6578                __m128d ex3v = _mm_load_pd(&v[l]);               
6579                _mm_store_pd(&v[l], _mm_mul_pd(ex3v,twoto));   
6580              }                           
6581
6582              if(useFastScaling)
6583                addScale += wgt[i];
6584              else
6585                ex3[i]  += 1;         
6586            }
6587
6588            x3_ptr += 80;
6589          }
6590        }
6591      }
6592      break;
6593    case INNER_INNER:
6594      {
6595        for(k = 0; k < 4; k++)
6596        {
6597          vl = &(x1_gapColumn[20 * k]);
6598          vr = &(x2_gapColumn[20 * k]);
6599          v =  &(x3_gapColumn[20 * k]);
6600
6601          __m128d zero =  _mm_setzero_pd();
6602          for(l = 0; l < 20; l+=2)                                 
6603            _mm_store_pd(&v[l], zero);
6604
6605          for(l = 0; l < 20; l++)
6606          {             
6607            {
6608              __m128d al = _mm_setzero_pd();
6609              __m128d ar = _mm_setzero_pd();
6610
6611              double *ll   = &left[k * 400 + l * 20];
6612              double *rr   = &right[k * 400 + l * 20];
6613              double *EVEV = &extEV[20 * l];
6614
6615              for(j = 0; j < 20; j+=2)
6616              {
6617                __m128d lv  = _mm_load_pd(&ll[j]);
6618                __m128d rv  = _mm_load_pd(&rr[j]);
6619                __m128d vll = _mm_load_pd(&vl[j]);
6620                __m128d vrr = _mm_load_pd(&vr[j]);
6621
6622                al = _mm_add_pd(al, _mm_mul_pd(vll, lv));
6623                ar = _mm_add_pd(ar, _mm_mul_pd(vrr, rv));
6624              }                 
6625
6626              al = _mm_hadd_pd(al, al);
6627              ar = _mm_hadd_pd(ar, ar);
6628
6629              al = _mm_mul_pd(al, ar);
6630
6631              for(j = 0; j < 20; j+=2)
6632              {
6633                __m128d vv  = _mm_load_pd(&v[j]);
6634                __m128d EVV = _mm_load_pd(&EVEV[j]);
6635
6636                vv = _mm_add_pd(vv, _mm_mul_pd(al, EVV));
6637
6638                _mm_store_pd(&v[j], vv);
6639              }                                           
6640            }           
6641
6642          }
6643        }
6644
6645
6646        { 
6647          v = x3_gapColumn;
6648          __m128d minlikelihood_sse = _mm_set1_pd( minlikelihood );
6649
6650          scale = 1;
6651          for(l = 0; scale && (l < 80); l += 2)
6652          {
6653            __m128d vv = _mm_load_pd(&v[l]);
6654            __m128d v1 = _mm_and_pd(vv, absMask.m);
6655            v1 = _mm_cmplt_pd(v1,  minlikelihood_sse);
6656            if(_mm_movemask_pd( v1 ) != 3)
6657              scale = 0;
6658          }               
6659        }
6660
6661        if (scale)
6662        {
6663          gapScaling = 1;
6664          __m128d twoto = _mm_set_pd(twotothe256, twotothe256);
6665
6666          for(l = 0; l < 80; l+=2)
6667          {
6668            __m128d ex3v = _mm_load_pd(&v[l]);           
6669            _mm_store_pd(&v[l], _mm_mul_pd(ex3v,twoto));       
6670          }                               
6671
6672
6673        }
6674      }
6675
6676      for (i = 0; i < n; i++)
6677      {
6678        if(x3_gap[i / 32] & mask32[i % 32])
6679        {           
6680          if(gapScaling)
6681          {
6682            if(useFastScaling)
6683              addScale += wgt[i];
6684            else
6685              ex3[i]  += 1;           
6686          }
6687        }
6688        else
6689        {
6690          if(x1_gap[i / 32] & mask32[i % 32])
6691            x1v = x1_gapColumn;
6692          else
6693          {
6694            x1v = x1_ptr;
6695            x1_ptr += 80;
6696          }
6697
6698          if(x2_gap[i / 32] & mask32[i % 32])
6699            x2v = x2_gapColumn;
6700          else
6701          {
6702            x2v = x2_ptr;
6703            x2_ptr += 80;
6704          }
6705
6706          for(k = 0; k < 4; k++)
6707          {
6708            vl = &(x1v[20 * k]);
6709            vr = &(x2v[20 * k]);
6710            v =  &x3_ptr[20 * k];
6711
6712            __m128d zero =  _mm_setzero_pd();
6713            for(l = 0; l < 20; l+=2)                               
6714              _mm_store_pd(&v[l], zero);
6715
6716            for(l = 0; l < 20; l++)
6717            {           
6718              {
6719                __m128d al = _mm_setzero_pd();
6720                __m128d ar = _mm_setzero_pd();
6721
6722                double *ll   = &left[k * 400 + l * 20];
6723                double *rr   = &right[k * 400 + l * 20];
6724                double *EVEV = &extEV[20 * l];
6725
6726                for(j = 0; j < 20; j+=2)
6727                {
6728                  __m128d lv  = _mm_load_pd(&ll[j]);
6729                  __m128d rv  = _mm_load_pd(&rr[j]);
6730                  __m128d vll = _mm_load_pd(&vl[j]);
6731                  __m128d vrr = _mm_load_pd(&vr[j]);
6732
6733                  al = _mm_add_pd(al, _mm_mul_pd(vll, lv));
6734                  ar = _mm_add_pd(ar, _mm_mul_pd(vrr, rv));
6735                }               
6736
6737                al = _mm_hadd_pd(al, al);
6738                ar = _mm_hadd_pd(ar, ar);
6739
6740                al = _mm_mul_pd(al, ar);
6741
6742                for(j = 0; j < 20; j+=2)
6743                {
6744                  __m128d vv  = _mm_load_pd(&v[j]);
6745                  __m128d EVV = _mm_load_pd(&EVEV[j]);
6746
6747                  vv = _mm_add_pd(vv, _mm_mul_pd(al, EVV));
6748
6749                  _mm_store_pd(&v[j], vv);
6750                }                                                 
6751              }         
6752
6753            }
6754          }
6755
6756
6757
6758          { 
6759            v = x3_ptr;
6760            __m128d minlikelihood_sse = _mm_set1_pd( minlikelihood );
6761
6762            scale = 1;
6763            for(l = 0; scale && (l < 80); l += 2)
6764            {
6765              __m128d vv = _mm_load_pd(&v[l]);
6766              __m128d v1 = _mm_and_pd(vv, absMask.m);
6767              v1 = _mm_cmplt_pd(v1,  minlikelihood_sse);
6768              if(_mm_movemask_pd( v1 ) != 3)
6769                scale = 0;
6770            }             
6771          }
6772
6773
6774          if (scale)
6775          {
6776            __m128d twoto = _mm_set_pd(twotothe256, twotothe256);
6777
6778            for(l = 0; l < 80; l+=2)
6779            {
6780              __m128d ex3v = _mm_load_pd(&v[l]);                 
6781              _mm_store_pd(&v[l], _mm_mul_pd(ex3v,twoto));     
6782            }                             
6783
6784            if(useFastScaling)
6785              addScale += wgt[i];
6786            else
6787              ex3[i]  += 1;       
6788          }
6789          x3_ptr += 80;
6790        }
6791      }
6792      break;
6793    default:
6794      assert(0);
6795  }
6796
6797  if(useFastScaling)
6798    *scalerIncrement = addScale;
6799
6800}
6801
6802#else
6803
6804
6805
6806#endif
6807
6808
6809
6810
6811
6812
6813
6814static void newviewGTRGAMMASECONDARY(int tipCase,
6815                                     double *x1, double *x2, double *x3, double *extEV, double *tipVector,
6816                                     int *ex3, unsigned char *tipX1, unsigned char *tipX2,
6817                                     int n, double *left, double *right, int *wgt, int *scalerIncrement, const boolean useFastScaling)
6818{
6819  double  *v;
6820  double x1px2;
6821  int  i, j, l, k, scale, addScale = 0;
6822  double *vl, *vr, al, ar;
6823
6824  switch(tipCase)
6825    {
6826    case TIP_TIP:
6827      {
6828        for(i = 0; i < n; i++)
6829          {
6830            for(k = 0; k < 4; k++)
6831              {
6832                vl = &(tipVector[16 * tipX1[i]]);
6833                vr = &(tipVector[16 * tipX2[i]]);
6834                v =  &(x3[64 * i + 16 * k]);
6835
6836                for(l = 0; l < 16; l++)
6837                  v[l] = 0;
6838
6839                for(l = 0; l < 16; l++)
6840                  {
6841                    al = 0.0;
6842                    ar = 0.0;
6843                    for(j = 0; j < 16; j++)
6844                      {
6845                        al += vl[j] * left[k * 256 + l * 16 + j];
6846                        ar += vr[j] * right[k * 256 + l * 16 + j];
6847                      }
6848
6849                    x1px2 = al * ar;
6850                    for(j = 0; j < 16; j++)
6851                      v[j] += x1px2 * extEV[16 * l + j];
6852                  }
6853              }     
6854          }
6855      }
6856      break;
6857    case TIP_INNER:
6858      {
6859        for (i = 0; i < n; i++)
6860          {
6861            for(k = 0; k < 4; k++)
6862              {
6863                vl = &(tipVector[16 * tipX1[i]]);
6864                vr = &(x2[64 * i + 16 * k]);
6865                v =  &(x3[64 * i + 16 * k]);
6866
6867                for(l = 0; l < 16; l++)
6868                  v[l] = 0;
6869
6870                for(l = 0; l < 16; l++)
6871                  {
6872                    al = 0.0;
6873                    ar = 0.0;
6874                    for(j = 0; j < 16; j++)
6875                      {
6876                        al += vl[j] * left[k * 256 + l * 16 + j];
6877                        ar += vr[j] * right[k * 256 + l * 16 + j];
6878                      }
6879
6880                    x1px2 = al * ar;
6881                    for(j = 0; j < 16; j++)
6882                      v[j] += x1px2 * extEV[16 * l + j];
6883                  }
6884              }
6885           
6886            v = &x3[64 * i];
6887            scale = 1;
6888            for(l = 0; scale && (l < 64); l++)
6889              scale = (ABS(v[l]) <  minlikelihood);
6890
6891            if (scale)
6892              {
6893                for(l = 0; l < 64; l++)
6894                  v[l] *= twotothe256;
6895
6896                if(useFastScaling)
6897                  addScale += wgt[i];
6898                else
6899                  ex3[i]  += 1;       
6900              }
6901          }
6902      }
6903      break;
6904    case INNER_INNER:
6905      for (i = 0; i < n; i++)
6906       {
6907         for(k = 0; k < 4; k++)
6908           {
6909             vl = &(x1[64 * i + 16 * k]);
6910             vr = &(x2[64 * i + 16 * k]);
6911             v =  &(x3[64 * i + 16 * k]);
6912
6913             for(l = 0; l < 16; l++)
6914               v[l] = 0;
6915
6916             for(l = 0; l < 16; l++)
6917               {
6918                 al = 0.0;
6919                 ar = 0.0;
6920                 for(j = 0; j < 16; j++)
6921                   {
6922                     al += vl[j] * left[k * 256 + l * 16 + j];
6923                     ar += vr[j] * right[k * 256 + l * 16 + j];
6924                   }
6925
6926                 x1px2 = al * ar;
6927                 for(j = 0; j < 16; j++)
6928                   v[j] += x1px2 * extEV[16 * l + j];
6929               }
6930           }
6931         
6932         v = &(x3[64 * i]);
6933         scale = 1;
6934         for(l = 0; scale && (l < 64); l++)
6935           scale = ((ABS(v[l]) <  minlikelihood));
6936
6937         if (scale)
6938           {
6939             for(l = 0; l < 64; l++)
6940               v[l] *= twotothe256;
6941
6942             if(useFastScaling)
6943               addScale += wgt[i];
6944             else
6945               ex3[i]  += 1;       
6946           }
6947       }
6948      break;
6949    default:
6950      assert(0);
6951    }
6952
6953  if(useFastScaling)
6954    *scalerIncrement = addScale;
6955
6956}
6957
6958
6959
6960static void newviewGTRGAMMASECONDARY_6(int tipCase,
6961                                       double *x1, double *x2, double *x3, double *extEV, double *tipVector,
6962                                       int *ex3, unsigned char *tipX1, unsigned char *tipX2,
6963                                       int n, double *left, double *right, int *wgt, int *scalerIncrement, const boolean useFastScaling)
6964{
6965  double  *v;
6966  double x1px2;
6967  int  i, j, l, k, scale, addScale = 0;
6968  double *vl, *vr, al, ar;
6969
6970  switch(tipCase)
6971    {
6972    case TIP_TIP:
6973      {
6974        for(i = 0; i < n; i++)
6975          {
6976            for(k = 0; k < 4; k++)
6977              {
6978                vl = &(tipVector[6 * tipX1[i]]);
6979                vr = &(tipVector[6 * tipX2[i]]);
6980                v =  &(x3[24 * i + 6 * k]);
6981
6982                for(l = 0; l < 6; l++)
6983                  v[l] = 0;
6984
6985                for(l = 0; l < 6; l++)
6986                  {
6987                    al = 0.0;
6988                    ar = 0.0;
6989                    for(j = 0; j < 6; j++)
6990                      {
6991                        al += vl[j] * left[k * 36 + l * 6 + j];
6992                        ar += vr[j] * right[k * 36 + l * 6 + j];
6993                      }
6994
6995                    x1px2 = al * ar;
6996                    for(j = 0; j < 6; j++)
6997                      v[j] += x1px2 * extEV[6 * l + j];
6998                  }
6999              }   
7000          }
7001      }
7002      break;
7003    case TIP_INNER:
7004      {
7005        for (i = 0; i < n; i++)
7006          {
7007            for(k = 0; k < 4; k++)
7008              {
7009                vl = &(tipVector[6 * tipX1[i]]);
7010                vr = &(x2[24 * i + 6 * k]);
7011                v =  &(x3[24 * i + 6 * k]);
7012
7013                for(l = 0; l < 6; l++)
7014                  v[l] = 0;
7015
7016                for(l = 0; l < 6; l++)
7017                  {
7018                    al = 0.0;
7019                    ar = 0.0;
7020                    for(j = 0; j < 6; j++)
7021                      {
7022                        al += vl[j] * left[k * 36 + l * 6 + j];
7023                        ar += vr[j] * right[k * 36 + l * 6 + j];
7024                      }
7025
7026                    x1px2 = al * ar;
7027                    for(j = 0; j < 6; j++)
7028                      v[j] += x1px2 * extEV[6 * l + j];
7029                  }
7030              }
7031           
7032            v = &x3[24 * i];
7033            scale = 1;
7034            for(l = 0; scale && (l < 24); l++)
7035              scale = (ABS(v[l]) <  minlikelihood);
7036
7037            if(scale)
7038              {
7039                for(l = 0; l < 24; l++)
7040                  v[l] *= twotothe256;
7041
7042                if(useFastScaling)
7043                  addScale += wgt[i];
7044                else
7045                  ex3[i]  += 1;         
7046              }
7047          }
7048      }
7049      break;
7050    case INNER_INNER:
7051      for (i = 0; i < n; i++)
7052       {
7053         for(k = 0; k < 4; k++)
7054           {
7055             vl = &(x1[24 * i + 6 * k]);
7056             vr = &(x2[24 * i + 6 * k]);
7057             v =  &(x3[24 * i + 6 * k]);
7058
7059             for(l = 0; l < 6; l++)
7060               v[l] = 0;
7061
7062             for(l = 0; l < 6; l++)
7063               {
7064                 al = 0.0;
7065                 ar = 0.0;
7066                 for(j = 0; j < 6; j++)
7067                   {
7068                     al += vl[j] * left[k * 36 + l * 6 + j];
7069                     ar += vr[j] * right[k * 36 + l * 6 + j];
7070                   }
7071
7072                 x1px2 = al * ar;
7073                 for(j = 0; j < 6; j++)
7074                   v[j] += x1px2 * extEV[6 * l + j];
7075               }
7076           }
7077         
7078         v = &(x3[24 * i]);
7079         scale = 1;
7080         for(l = 0; scale && (l < 24); l++)
7081           scale = ((ABS(v[l]) <  minlikelihood));
7082
7083         if (scale)
7084           {
7085             for(l = 0; l < 24; l++)
7086               v[l] *= twotothe256;
7087
7088             if(useFastScaling)
7089               addScale += wgt[i];
7090             else
7091               ex3[i]  += 1;       
7092           }
7093       }
7094      break;
7095    default:
7096      assert(0);
7097    }
7098
7099  if(useFastScaling)
7100    *scalerIncrement = addScale;
7101
7102}
7103
7104
7105static void newviewGTRGAMMASECONDARY_7(int tipCase,
7106                                       double *x1, double *x2, double *x3, double *extEV, double *tipVector,
7107                                       int *ex3, unsigned char *tipX1, unsigned char *tipX2,
7108                                       int n, double *left, double *right, int *wgt, int *scalerIncrement, const boolean useFastScaling)
7109{
7110  double  *v;
7111  double x1px2;
7112  int  i, j, l, k, scale, addScale = 0;
7113  double *vl, *vr, al, ar;
7114
7115  switch(tipCase)
7116    {
7117    case TIP_TIP:
7118      {
7119        for(i = 0; i < n; i++)
7120          {
7121            for(k = 0; k < 4; k++)
7122              {
7123                vl = &(tipVector[7 * tipX1[i]]);
7124                vr = &(tipVector[7 * tipX2[i]]);
7125                v =  &(x3[28 * i + 7 * k]);
7126
7127                for(l = 0; l < 7; l++)
7128                  v[l] = 0;
7129
7130                for(l = 0; l < 7; l++)
7131                  {
7132                    al = 0.0;
7133                    ar = 0.0;
7134                    for(j = 0; j < 7; j++)
7135                      {
7136                        al += vl[j] * left[k * 49 + l * 7 + j];
7137                        ar += vr[j] * right[k * 49 + l * 7 + j];
7138                      }
7139
7140                    x1px2 = al * ar;
7141                    for(j = 0; j < 7; j++)
7142                      v[j] += x1px2 * extEV[7 * l + j];
7143                  }
7144              }   
7145          }
7146      }
7147      break;
7148    case TIP_INNER:
7149      {
7150        for (i = 0; i < n; i++)
7151          {
7152            for(k = 0; k < 4; k++)
7153              {
7154                vl = &(tipVector[7 * tipX1[i]]);
7155                vr = &(x2[28 * i + 7 * k]);
7156                v =  &(x3[28 * i + 7 * k]);
7157
7158                for(l = 0; l < 7; l++)
7159                  v[l] = 0;
7160
7161                for(l = 0; l < 7; l++)
7162                  {
7163                    al = 0.0;
7164                    ar = 0.0;
7165                    for(j = 0; j < 7; j++)
7166                      {
7167                        al += vl[j] * left[k * 49 + l * 7 + j];
7168                        ar += vr[j] * right[k * 49 + l * 7 + j];
7169                      }
7170
7171                    x1px2 = al * ar;
7172                    for(j = 0; j < 7; j++)
7173                      v[j] += x1px2 * extEV[7 * l + j];
7174                  }
7175              }
7176           
7177            v = &x3[28 * i];
7178            scale = 1;
7179            for(l = 0; scale && (l < 28); l++)
7180              scale = (ABS(v[l]) <  minlikelihood);
7181
7182            if (scale)
7183              {
7184                for(l = 0; l < 28; l++)
7185                  v[l] *= twotothe256;
7186
7187                if(useFastScaling)
7188                  addScale += wgt[i];
7189                else
7190                  ex3[i]  += 1;       
7191              }
7192          }
7193      }
7194      break;
7195    case INNER_INNER:
7196      for (i = 0; i < n; i++)
7197       {
7198         for(k = 0; k < 4; k++)
7199           {
7200             vl = &(x1[28 * i + 7 * k]);
7201             vr = &(x2[28 * i + 7 * k]);
7202             v =  &(x3[28 * i + 7 * k]);
7203
7204             for(l = 0; l < 7; l++)
7205               v[l] = 0;
7206
7207             for(l = 0; l < 7; l++)
7208               {
7209                 al = 0.0;
7210                 ar = 0.0;
7211                 for(j = 0; j < 7; j++)
7212                   {
7213                     al += vl[j] * left[k * 49 + l * 7 + j];
7214                     ar += vr[j] * right[k * 49 + l * 7 + j];
7215                   }
7216
7217                 x1px2 = al * ar;
7218                 for(j = 0; j < 7; j++)
7219                   v[j] += x1px2 * extEV[7 * l + j];
7220               }
7221           }
7222         
7223         v = &(x3[28 * i]);
7224         scale = 1;
7225         for(l = 0; scale && (l < 28); l++)
7226           scale = ((ABS(v[l]) <  minlikelihood));
7227
7228         if (scale)
7229           {
7230             for(l = 0; l < 28; l++)
7231               v[l] *= twotothe256;
7232
7233             if(useFastScaling)
7234               addScale += wgt[i];
7235             else
7236               ex3[i]  += 1;       
7237           }
7238       }
7239      break;
7240    default:
7241      assert(0);
7242    }
7243
7244  if(useFastScaling)
7245    *scalerIncrement = addScale;
7246}
7247
7248
7249
7250
7251
7252
7253
7254void computeTraversalInfo(nodeptr p, traversalInfo *ti, int *counter, int maxTips, int numBranches)
7255{
7256  if(isTip(p->number, maxTips))
7257    return;
7258
7259  {
7260    int i;
7261    nodeptr q = p->next->back;
7262    nodeptr r = p->next->next->back;
7263
7264    if(isTip(r->number, maxTips) && isTip(q->number, maxTips))
7265      {
7266        while (! p->x)
7267         {
7268           if (! p->x)
7269             getxnode(p);
7270         }
7271
7272        ti[*counter].tipCase = TIP_TIP;
7273        ti[*counter].pNumber = p->number;
7274        ti[*counter].qNumber = q->number;
7275        ti[*counter].rNumber = r->number;
7276
7277        for(i = 0; i < numBranches; i++)
7278          {
7279            double z;
7280            z = q->z[i];
7281         
7282            z = (z > zmin) ? log(z) : log(zmin);
7283            ti[*counter].qz[i] = z;
7284
7285            z = r->z[i];
7286            z = (z > zmin) ? log(z) : log(zmin);
7287            ti[*counter].rz[i] = z;
7288          }
7289        *counter = *counter + 1;
7290      }
7291    else
7292      {
7293        if(isTip(r->number, maxTips) || isTip(q->number, maxTips))
7294          {
7295            nodeptr tmp;
7296
7297            if(isTip(r->number, maxTips))
7298              {
7299                tmp = r;
7300                r = q;
7301                q = tmp;
7302              }
7303
7304            while ((! p->x) || (! r->x))
7305              {
7306                if (! r->x)
7307                  computeTraversalInfo(r, ti, counter, maxTips, numBranches);
7308                if (! p->x)
7309                  getxnode(p);
7310              }
7311
7312            ti[*counter].tipCase = TIP_INNER;
7313            ti[*counter].pNumber = p->number;
7314            ti[*counter].qNumber = q->number;
7315            ti[*counter].rNumber = r->number;
7316
7317            for(i = 0; i < numBranches; i++)
7318              {
7319                double z;
7320                z = q->z[i];
7321                       
7322                z = (z > zmin) ? log(z) : log(zmin);
7323                ti[*counter].qz[i] = z;
7324
7325                z = r->z[i];
7326                z = (z > zmin) ? log(z) : log(zmin);
7327                ti[*counter].rz[i] = z;
7328              }
7329
7330            *counter = *counter + 1;
7331          }
7332        else
7333          {
7334
7335            while ((! p->x) || (! q->x) || (! r->x))
7336              {
7337                if (! q->x)
7338                  computeTraversalInfo(q, ti, counter, maxTips, numBranches);
7339                if (! r->x)
7340                  computeTraversalInfo(r, ti, counter, maxTips, numBranches);
7341                if (! p->x)
7342                  getxnode(p);
7343              }
7344
7345            ti[*counter].tipCase = INNER_INNER;
7346            ti[*counter].pNumber = p->number;
7347            ti[*counter].qNumber = q->number;
7348            ti[*counter].rNumber = r->number;
7349
7350            for(i = 0; i < numBranches; i++)
7351              {
7352                double z;
7353                z = q->z[i];   
7354
7355                z = (z > zmin) ? log(z) : log(zmin);
7356                ti[*counter].qz[i] = z;
7357
7358                z = r->z[i];
7359                z = (z > zmin) ? log(z) : log(zmin);
7360                ti[*counter].rz[i] = z;
7361              }
7362
7363            *counter = *counter + 1;
7364          }
7365      }
7366  }
7367
7368 
7369
7370}
7371
7372
7373
7374
7375
7376void newviewIterative (tree *tr)
7377{
7378  traversalInfo
7379    *ti   = tr->td[0].ti;
7380 
7381  int 
7382    i, 
7383    model;
7384
7385
7386
7387  for(i = 1; i < tr->td[0].count; i++)
7388    {
7389      traversalInfo
7390        *tInfo = &ti[i];
7391
7392      for(model = 0; model < tr->NumberOfModels; model++)
7393        {                 
7394          if(tr->executeModel[model])
7395            {         
7396              double
7397                *x1_start = (double*)NULL,
7398                *x2_start = (double*)NULL,
7399                *x3_start = tr->partitionData[model].xVector[tInfo->pNumber - tr->mxtips - 1],
7400                *left     = (double*)NULL,
7401                *right    = (double*)NULL,
7402                *x1_gapColumn = (double*)NULL,
7403                *x2_gapColumn = (double*)NULL,
7404                *x3_gapColumn = (double*)NULL,         
7405                qz, 
7406                rz;
7407             
7408              unsigned int
7409                *x1_gap = (unsigned int*)NULL,
7410                *x2_gap = (unsigned int*)NULL,
7411                *x3_gap = (unsigned int*)NULL;
7412                     
7413              int               
7414                scalerIncrement = 0,
7415                *wgt = (int*)NULL,             
7416                *ex3 = (int*)NULL;
7417             
7418              unsigned char
7419                *tipX1 = (unsigned char *)NULL,
7420                *tipX2 = (unsigned char *)NULL;
7421                     
7422              size_t
7423                gapOffset = 0,
7424                rateHet,
7425                states = (size_t)tr->partitionData[model].states,
7426                width = tr->partitionData[model].width,
7427                availableLength =  tr->partitionData[model].xSpaceVector[(tInfo->pNumber - tr->mxtips - 1)],                           
7428                requiredLength;
7429               
7430              if(tr->rateHetModel == CAT)
7431                rateHet = 1;
7432              else
7433                rateHet = 4;
7434
7435              if(tr->saveMemory)
7436                { 
7437                  size_t
7438                    j,
7439                    setBits = 0;
7440                 
7441                  x1_gap = &(tr->partitionData[model].gapVector[tInfo->qNumber * tr->partitionData[model].gapVectorLength]);
7442                  x2_gap = &(tr->partitionData[model].gapVector[tInfo->rNumber * tr->partitionData[model].gapVectorLength]);
7443                  x3_gap = &(tr->partitionData[model].gapVector[tInfo->pNumber * tr->partitionData[model].gapVectorLength]);
7444
7445                  gapOffset = states * (size_t)getUndetermined(tr->partitionData[model].dataType);
7446                                         
7447                  availableLength = tr->partitionData[model].xSpaceVector[(tInfo->pNumber - tr->mxtips - 1)];
7448                   
7449                   for(j = 0; j < (size_t)tr->partitionData[model].gapVectorLength; j++)
7450                     {
7451                       x3_gap[j] = x1_gap[j] & x2_gap[j];
7452                       setBits += (size_t)(precomputed16_bitcount(x3_gap[j]));
7453                     }
7454                   
7455                   requiredLength = (width - setBits)  * rateHet * states * sizeof(double);     
7456                }
7457              else
7458                requiredLength  =  width * rateHet * states * sizeof(double);
7459
7460              if(requiredLength != availableLength)
7461                {                 
7462                  if(x3_start)
7463                    rax_free(x3_start);
7464                 
7465                  x3_start = (double*)rax_malloc(requiredLength);               
7466                 
7467                  tr->partitionData[model].xVector[tInfo->pNumber - tr->mxtips - 1] = x3_start;
7468                 
7469                  tr->partitionData[model].xSpaceVector[(tInfo->pNumber - tr->mxtips - 1)] = requiredLength;             
7470                }
7471             
7472
7473              if(tr->useFastScaling)           
7474                wgt   =  tr->partitionData[model].wgt; 
7475              else
7476                {
7477                  size_t
7478                    availableExpLength = tr->partitionData[model].expSpaceVector[(tInfo->pNumber - tr->mxtips - 1)],
7479                    requiredExpLength  = width * sizeof(int);
7480                 
7481                  ex3 = tr->partitionData[model].expVector[tInfo->pNumber - tr->mxtips - 1];
7482                 
7483                  if(requiredExpLength != availableExpLength)
7484                    {
7485                      if(ex3)
7486                        rax_free(ex3);
7487                 
7488                      ex3 = (int*)rax_malloc(requiredExpLength);                 
7489                 
7490                      tr->partitionData[model].expVector[tInfo->pNumber - tr->mxtips - 1] = ex3;
7491                 
7492                      tr->partitionData[model].expSpaceVector[(tInfo->pNumber - tr->mxtips - 1)] = requiredExpLength;
7493                    }
7494                }
7495
7496              switch(tInfo->tipCase)
7497                {
7498                case TIP_TIP:             
7499                  tipX1    = tr->partitionData[model].yVector[tInfo->qNumber];
7500                  tipX2    = tr->partitionData[model].yVector[tInfo->rNumber];                                           
7501                 
7502                  if(tr->saveMemory)
7503                    {
7504                      assert(gapOffset > 0);
7505
7506                      x1_gapColumn   = &(tr->partitionData[model].tipVector[gapOffset]);
7507                      x2_gapColumn   = &(tr->partitionData[model].tipVector[gapOffset]);
7508                      x3_gapColumn   = &tr->partitionData[model].gapColumn[(tInfo->pNumber - tr->mxtips - 1) * states * rateHet];
7509                    }
7510                 
7511                  if(!tr->useFastScaling)
7512                    {
7513                      size_t
7514                        k;                                   
7515
7516                      for(k = 0; k < width; k++)
7517                        ex3[k] = 0;
7518                    }
7519                  break;
7520                case TIP_INNER:         
7521                  tipX1    =  tr->partitionData[model].yVector[tInfo->qNumber];         
7522                  x2_start       = tr->partitionData[model].xVector[tInfo->rNumber - tr->mxtips - 1];
7523                                 
7524                  if(tr->saveMemory)
7525                    {
7526                      assert(gapOffset > 0);
7527                     
7528                      x1_gapColumn   = &(tr->partitionData[model].tipVector[gapOffset]);
7529                      x2_gapColumn   = &tr->partitionData[model].gapColumn[(tInfo->rNumber - tr->mxtips - 1) * states * rateHet];
7530                      x3_gapColumn   = &tr->partitionData[model].gapColumn[(tInfo->pNumber - tr->mxtips - 1) * states * rateHet];
7531                    }           
7532                 
7533                  if(!tr->useFastScaling)
7534                    {
7535                      size_t 
7536                        k;
7537                      int
7538                        *ex2;
7539                     
7540                      ex2      = tr->partitionData[model].expVector[tInfo->rNumber - tr->mxtips - 1];               
7541                     
7542                      for(k = 0; k < width; k++)
7543                        ex3[k] = ex2[k];
7544                    }
7545                  break;
7546                case INNER_INNER:                                                   
7547                  x1_start       = tr->partitionData[model].xVector[tInfo->qNumber - tr->mxtips - 1];
7548                  x2_start       = tr->partitionData[model].xVector[tInfo->rNumber - tr->mxtips - 1];
7549                     
7550                  if(tr->saveMemory)
7551                    {                 
7552                      x1_gapColumn   = &tr->partitionData[model].gapColumn[(tInfo->qNumber - tr->mxtips - 1) * states * rateHet];
7553                      x2_gapColumn   = &tr->partitionData[model].gapColumn[(tInfo->rNumber - tr->mxtips - 1) * states * rateHet];
7554                      x3_gapColumn   = &tr->partitionData[model].gapColumn[(tInfo->pNumber - tr->mxtips - 1) * states * rateHet];
7555                    }
7556                 
7557                  if(!tr->useFastScaling)
7558                    {
7559                      size_t
7560                        k;
7561                     
7562                      int
7563                        *ex1,
7564                        *ex2;
7565
7566                      ex1      = tr->partitionData[model].expVector[tInfo->qNumber - tr->mxtips - 1];
7567                      ex2      = tr->partitionData[model].expVector[tInfo->rNumber - tr->mxtips - 1];                 
7568                     
7569                      for(k = 0; k < width; k++)
7570                        ex3[k] = ex1[k] + ex2[k];
7571                    }             
7572                  break;
7573                default:
7574                  assert(0);
7575                }
7576                       
7577              left  = tr->partitionData[model].left;
7578              right = tr->partitionData[model].right;
7579             
7580              if(tr->multiBranch)
7581                {
7582                  qz = tInfo->qz[model];
7583                  rz = tInfo->rz[model];
7584                }
7585              else
7586                {
7587                  qz = tInfo->qz[0];
7588                  rz = tInfo->rz[0];
7589                }
7590                             
7591              switch(tr->partitionData[model].dataType)
7592                {
7593                case BINARY_DATA:
7594                  switch(tr->rateHetModel)
7595                    {
7596                    case CAT:
7597                      {                 
7598                        makeP(qz, rz, tr->partitionData[model].perSiteRates,   tr->partitionData[model].EI,
7599                              tr->partitionData[model].EIGN, tr->partitionData[model].numberOfCategories,
7600                              left, right, BINARY_DATA, tr->saveMemory, tr->maxCategories);
7601
7602                        newviewGTRCAT_BINARY(tInfo->tipCase,  tr->partitionData[model].EV, tr->partitionData[model].rateCategory,
7603                                             x1_start, x2_start, x3_start, tr->partitionData[model].tipVector,
7604                                             ex3, tipX1, tipX2,
7605                                             width, left, right, wgt, &scalerIncrement, tr->useFastScaling
7606                                             );         
7607                      }
7608                      break;
7609                    case GAMMA:
7610                    case GAMMA_I:
7611                      {
7612                        makeP(qz, rz, tr->partitionData[model].gammaRates,
7613                              tr->partitionData[model].EI, tr->partitionData[model].EIGN,
7614                              4, left, right, BINARY_DATA, tr->saveMemory, tr->maxCategories);
7615
7616                        newviewGTRGAMMA_BINARY(tInfo->tipCase,
7617                                               x1_start, x2_start, x3_start, tr->partitionData[model].EV, tr->partitionData[model].tipVector,
7618                                               ex3, tipX1, tipX2,
7619                                               width, left, right, wgt, &scalerIncrement, tr->useFastScaling);
7620                      }
7621                      break;
7622                    default:
7623                      assert(0);
7624                    }
7625                  break;
7626                case DNA_DATA:           
7627                  switch(tr->rateHetModel)
7628                    {
7629                    case CAT:
7630                     
7631                        {                         
7632                          makeP(qz, rz, tr->partitionData[model].perSiteRates,   tr->partitionData[model].EI,
7633                                tr->partitionData[model].EIGN, tr->partitionData[model].numberOfCategories,
7634                                left, right, DNA_DATA, tr->saveMemory, tr->maxCategories);
7635
7636#if (defined(__SIM_SSE3) || defined(__AVX))
7637                          if(tr->saveMemory)
7638                            {                                         
7639#ifdef __AVX
7640                              newviewGTRCAT_AVX_GAPPED_SAVE(tInfo->tipCase,  tr->partitionData[model].EV, tr->partitionData[model].rateCategory,
7641                                                             x1_start, x2_start, x3_start, tr->partitionData[model].tipVector,
7642                                                             ex3, tipX1, tipX2,
7643                                                             width, left, right, wgt, &scalerIncrement, tr->useFastScaling, x1_gap, x2_gap, x3_gap,
7644                                                             x1_gapColumn, x2_gapColumn, x3_gapColumn, tr->maxCategories);
7645#else
7646                              newviewGTRCAT_SAVE(tInfo->tipCase,  tr->partitionData[model].EV, tr->partitionData[model].rateCategory,
7647                                                 x1_start, x2_start, x3_start, tr->partitionData[model].tipVector,
7648                                                 ex3, tipX1, tipX2,
7649                                                 width, left, right, wgt, &scalerIncrement, tr->useFastScaling, x1_gap, x2_gap, x3_gap,
7650                                                 x1_gapColumn, x2_gapColumn, x3_gapColumn, tr->maxCategories);
7651#endif
7652                            }
7653                          else
7654#endif
7655                            {
7656#ifdef __AVX
7657                              newviewGTRCAT_AVX(tInfo->tipCase,  tr->partitionData[model].EV, tr->partitionData[model].rateCategory,
7658                                                x1_start, x2_start, x3_start, tr->partitionData[model].tipVector,
7659                                                ex3, tipX1, tipX2,
7660                                                width, left, right, wgt, &scalerIncrement, tr->useFastScaling);
7661#else
7662                              newviewGTRCAT(tInfo->tipCase,  tr->partitionData[model].EV, tr->partitionData[model].rateCategory,
7663                                            x1_start, x2_start, x3_start, tr->partitionData[model].tipVector,
7664                                            ex3, tipX1, tipX2,
7665                                            width, left, right, wgt, &scalerIncrement, tr->useFastScaling);
7666#endif
7667                            }
7668                        }
7669                      break;
7670                    case GAMMA:
7671                    case GAMMA_I:
7672                     
7673                        {                       
7674                          makeP(qz, rz, tr->partitionData[model].gammaRates,
7675                                tr->partitionData[model].EI, tr->partitionData[model].EIGN,
7676                                4, left, right, DNA_DATA, tr->saveMemory, tr->maxCategories);
7677                 
7678
7679#if (defined(__SIM_SSE3) || defined(__AVX))
7680                          if(tr->saveMemory)
7681                            {
7682#ifdef __AVX                                         
7683                              newviewGTRGAMMA_AVX_GAPPED_SAVE(tInfo->tipCase,
7684                                                              x1_start, x2_start, x3_start, tr->partitionData[model].EV, tr->partitionData[model].tipVector,
7685                                                              ex3, tipX1, tipX2,
7686                                                              width, left, right, wgt, &scalerIncrement, tr->useFastScaling,
7687                                                              x1_gap, x2_gap, x3_gap, 
7688                                                              x1_gapColumn, x2_gapColumn, x3_gapColumn); 
7689                             
7690#else
7691                              newviewGTRGAMMA_GAPPED_SAVE(tInfo->tipCase,
7692                                                          x1_start, x2_start, x3_start, tr->partitionData[model].EV, tr->partitionData[model].tipVector,
7693                                                          ex3, tipX1, tipX2,
7694                                                          width, left, right, wgt, &scalerIncrement, tr->useFastScaling,
7695                                                          x1_gap, x2_gap, x3_gap, 
7696                                                          x1_gapColumn, x2_gapColumn, x3_gapColumn);
7697
7698#endif
7699                           
7700                            }
7701                          else
7702#endif
7703                            {                       
7704#ifdef __AVX
7705                                newviewGTRGAMMA_AVX(tInfo->tipCase,
7706                                                    x1_start, x2_start, x3_start, tr->partitionData[model].EV, tr->partitionData[model].tipVector,
7707                                                    ex3, tipX1, tipX2,
7708                                                    width, left, right, wgt, &scalerIncrement, tr->useFastScaling);
7709#else
7710                                newviewGTRGAMMA(tInfo->tipCase,
7711                                                x1_start, x2_start, x3_start, tr->partitionData[model].EV, tr->partitionData[model].tipVector,
7712                                                ex3, tipX1, tipX2,
7713                                                width, left, right, wgt, &scalerIncrement, tr->useFastScaling);
7714#endif
7715                            }
7716                        }
7717                      break;
7718                    default:
7719                      assert(0);
7720                      }
7721                  break;
7722                case AA_DATA:
7723                  switch(tr->rateHetModel)
7724                    {
7725                    case CAT:
7726                     
7727                        {
7728                          makeP(qz, rz, tr->partitionData[model].perSiteRates,
7729                                tr->partitionData[model].EI,
7730                                tr->partitionData[model].EIGN,
7731                                tr->partitionData[model].numberOfCategories, left, right, AA_DATA, tr->saveMemory, tr->maxCategories);
7732
7733#if  (defined(__SIM_SSE3) || defined(__AVX))
7734                          if(tr->saveMemory)
7735#ifdef __AVX
7736                            newviewGTRCATPROT_AVX_GAPPED_SAVE(tInfo->tipCase,  tr->partitionData[model].EV, tr->partitionData[model].rateCategory,
7737                                                              x1_start, x2_start, x3_start, tr->partitionData[model].tipVector,
7738                                                              ex3, tipX1, tipX2, width, left, right, wgt, &scalerIncrement, tr->useFastScaling, x1_gap, x2_gap, x3_gap,
7739                                                              x1_gapColumn, x2_gapColumn, x3_gapColumn, tr->maxCategories);
7740#else
7741                            newviewGTRCATPROT_SAVE(tInfo->tipCase,  tr->partitionData[model].EV, tr->partitionData[model].rateCategory,
7742                                                   x1_start, x2_start, x3_start, tr->partitionData[model].tipVector,
7743                                                   ex3, tipX1, tipX2, width, left, right, wgt, &scalerIncrement, tr->useFastScaling, x1_gap, x2_gap, x3_gap,
7744                                                   x1_gapColumn, x2_gapColumn, x3_gapColumn, tr->maxCategories);
7745#endif
7746                          else
7747#endif
7748                            {
7749#ifdef __AVX
7750                              newviewGTRCATPROT_AVX(tInfo->tipCase,  tr->partitionData[model].EV, tr->partitionData[model].rateCategory,
7751                                                    x1_start, x2_start, x3_start, tr->partitionData[model].tipVector,
7752                                                    ex3, tipX1, tipX2, width, left, right, wgt, &scalerIncrement, tr->useFastScaling);
7753#else                     
7754                              newviewGTRCATPROT(tInfo->tipCase,  tr->partitionData[model].EV, tr->partitionData[model].rateCategory,
7755                                                x1_start, x2_start, x3_start, tr->partitionData[model].tipVector,
7756                                                ex3, tipX1, tipX2, width, left, right, wgt, &scalerIncrement, tr->useFastScaling);                     
7757#endif
7758                            }
7759                        }
7760                      break;
7761                    case GAMMA:
7762                    case GAMMA_I:
7763                      if(tr->partitionData[model].protModels == LG4 || tr->partitionData[model].protModels == LG4X)
7764                        {                                       
7765                          makeP_FlexLG4(qz, rz, tr->partitionData[model].gammaRates,
7766                                        tr->partitionData[model].EI_LG4,
7767                                        tr->partitionData[model].EIGN_LG4,
7768                                        4, left, right, 20);
7769#ifdef __AVX
7770                          newviewGTRGAMMAPROT_AVX_LG4(tInfo->tipCase,
7771                                                      x1_start, x2_start, x3_start,
7772                                                      tr->partitionData[model].EV_LG4,
7773                                                      tr->partitionData[model].tipVector_LG4,
7774                                                      ex3, tipX1, tipX2,
7775                                                      width, left, right, wgt, &scalerIncrement, tr->useFastScaling);
7776#else
7777                          newviewGTRGAMMAPROT_LG4(tInfo->tipCase,
7778                                                  x1_start, x2_start, x3_start,
7779                                                  tr->partitionData[model].EV_LG4,
7780                                                  tr->partitionData[model].tipVector_LG4,
7781                                                  ex3, tipX1, tipX2,
7782                                                  width, left, right, 
7783                                                  wgt, &scalerIncrement, tr->useFastScaling);                       
7784#endif
7785                        }                     
7786                      else
7787                        {                       
7788                          makeP(qz, rz, tr->partitionData[model].gammaRates,
7789                                tr->partitionData[model].EI,
7790                                tr->partitionData[model].EIGN,
7791                                4, left, right, AA_DATA, tr->saveMemory, tr->maxCategories);
7792#if (defined(__SIM_SSE3) || defined(__AVX))
7793                          if(tr->saveMemory)
7794#ifdef __AVX
7795                            newviewGTRGAMMAPROT_AVX_GAPPED_SAVE(tInfo->tipCase,
7796                                                                x1_start, x2_start, x3_start,
7797                                                                tr->partitionData[model].EV,
7798                                                                tr->partitionData[model].tipVector,
7799                                                                ex3, tipX1, tipX2,
7800                                                                width, left, right, wgt, &scalerIncrement, tr->useFastScaling,
7801                                                                x1_gap, x2_gap, x3_gap,
7802                                                                x1_gapColumn, x2_gapColumn, x3_gapColumn);
7803#else
7804                            newviewGTRGAMMAPROT_GAPPED_SAVE(tInfo->tipCase,
7805                                                            x1_start, x2_start, x3_start,
7806                                                            tr->partitionData[model].EV,
7807                                                            tr->partitionData[model].tipVector,
7808                                                            ex3, tipX1, tipX2,
7809                                                            width, left, right, wgt, &scalerIncrement, tr->useFastScaling,
7810                                                            x1_gap, x2_gap, x3_gap,
7811                                                            x1_gapColumn, x2_gapColumn, x3_gapColumn);
7812#endif
7813                          else
7814#endif
7815                            {
7816                             
7817#ifdef __AVX
7818                              newviewGTRGAMMAPROT_AVX(tInfo->tipCase,
7819                                                      x1_start, x2_start, x3_start,
7820                                                      tr->partitionData[model].EV,
7821                                                      tr->partitionData[model].tipVector,
7822                                                      ex3, tipX1, tipX2,
7823                                                      width, left, right, wgt, &scalerIncrement, tr->useFastScaling);
7824#else
7825                                newviewGTRGAMMAPROT(tInfo->tipCase,
7826                                                    x1_start, x2_start, x3_start,
7827                                                    tr->partitionData[model].EV,
7828                                                    tr->partitionData[model].tipVector,
7829                                                    ex3, tipX1, tipX2,
7830                                                    width, left, right, wgt, &scalerIncrement, tr->useFastScaling);
7831#endif
7832                            }                   
7833                        }
7834                      break;
7835                    default:
7836                      assert(0);
7837                    }
7838                  break;
7839                case SECONDARY_DATA_6:           
7840                  switch(tr->rateHetModel)
7841                    {
7842                    case CAT:
7843                      {
7844                        makeP(qz, rz, tr->partitionData[model].perSiteRates,
7845                              tr->partitionData[model].EI,
7846                              tr->partitionData[model].EIGN,
7847                              tr->partitionData[model].numberOfCategories, left, right, SECONDARY_DATA_6, tr->saveMemory, tr->maxCategories);
7848
7849                        newviewGTRCATSECONDARY_6(tInfo->tipCase,  tr->partitionData[model].EV, tr->partitionData[model].rateCategory,
7850                                                 x1_start, x2_start, x3_start, tr->partitionData[model].tipVector,
7851                                                 ex3, tipX1, tipX2, width, left, right, wgt, &scalerIncrement, tr->useFastScaling);
7852                      }
7853                      break;
7854                    case GAMMA:
7855                    case GAMMA_I:
7856                      {
7857                        makeP(qz, rz, tr->partitionData[model].gammaRates,
7858                              tr->partitionData[model].EI,
7859                              tr->partitionData[model].EIGN,
7860                              4, left, right, SECONDARY_DATA_6, tr->saveMemory, tr->maxCategories);
7861
7862                        newviewGTRGAMMASECONDARY_6(tInfo->tipCase,
7863                                                   x1_start, x2_start, x3_start,
7864                                                   tr->partitionData[model].EV,
7865                                                   tr->partitionData[model].tipVector,
7866                                                   ex3, tipX1, tipX2,
7867                                                   width, left, right, wgt, &scalerIncrement, tr->useFastScaling);
7868                      }
7869                      break;
7870                    default:
7871                      assert(0);
7872                    }
7873                  break;
7874                case SECONDARY_DATA_7:
7875                  switch(tr->rateHetModel)
7876                    {
7877                    case CAT:
7878                      {
7879                        makeP(qz, rz, tr->partitionData[model].perSiteRates,
7880                              tr->partitionData[model].EI,
7881                              tr->partitionData[model].EIGN,
7882                              tr->partitionData[model].numberOfCategories, left, right, SECONDARY_DATA_7, tr->saveMemory, tr->maxCategories);
7883
7884                        newviewGTRCATSECONDARY_7(tInfo->tipCase,  tr->partitionData[model].EV, tr->partitionData[model].rateCategory,
7885                                                 x1_start, x2_start, x3_start, tr->partitionData[model].tipVector,
7886                                                 ex3, tipX1, tipX2, width, left, right, wgt, &scalerIncrement, tr->useFastScaling);
7887                      }
7888                      break;
7889                    case GAMMA:
7890                    case GAMMA_I:
7891                      {
7892                        makeP(qz, rz, tr->partitionData[model].gammaRates,
7893                              tr->partitionData[model].EI,
7894                              tr->partitionData[model].EIGN,
7895                              4, left, right, SECONDARY_DATA_7, tr->saveMemory, tr->maxCategories);
7896
7897                        newviewGTRGAMMASECONDARY_7(tInfo->tipCase,
7898                                                   x1_start, x2_start, x3_start,
7899                                                   tr->partitionData[model].EV,
7900                                                   tr->partitionData[model].tipVector,
7901                                                   ex3, tipX1, tipX2,
7902                                                   width, left, right, wgt, &scalerIncrement, tr->useFastScaling);
7903                      }
7904                      break;
7905                    default:
7906                      assert(0);
7907                    }
7908                  break;
7909                case SECONDARY_DATA:
7910                 switch(tr->rateHetModel)
7911                    {
7912                    case CAT:
7913                      {
7914                        makeP(qz, rz, tr->partitionData[model].perSiteRates,
7915                              tr->partitionData[model].EI,
7916                              tr->partitionData[model].EIGN,
7917                              tr->partitionData[model].numberOfCategories, left, right, SECONDARY_DATA, tr->saveMemory, tr->maxCategories);
7918
7919                        newviewGTRCATSECONDARY(tInfo->tipCase,  tr->partitionData[model].EV, tr->partitionData[model].rateCategory,
7920                                               x1_start, x2_start, x3_start, tr->partitionData[model].tipVector,
7921                                               ex3, tipX1, tipX2, width, left, right, wgt, &scalerIncrement, tr->useFastScaling);
7922                      }
7923                      break;
7924                    case GAMMA:
7925                    case GAMMA_I:
7926                      {
7927                        makeP(qz, rz, tr->partitionData[model].gammaRates,
7928                              tr->partitionData[model].EI,
7929                              tr->partitionData[model].EIGN,
7930                              4, left, right, SECONDARY_DATA, tr->saveMemory, tr->maxCategories);
7931
7932                        newviewGTRGAMMASECONDARY(tInfo->tipCase,
7933                                                 x1_start, x2_start, x3_start,
7934                                                 tr->partitionData[model].EV,
7935                                                 tr->partitionData[model].tipVector,
7936                                                 ex3, tipX1, tipX2,
7937                                                 width, left, right, wgt, &scalerIncrement, tr->useFastScaling);               
7938                      }
7939                      break;
7940                    default:
7941                      assert(0);
7942                    }
7943                  break;
7944                case GENERIC_32:
7945                  switch(tr->rateHetModel)
7946                    {
7947                    case CAT:
7948                      {
7949                        makeP_Flex(qz, rz, tr->partitionData[model].perSiteRates,
7950                                   tr->partitionData[model].EI,
7951                                   tr->partitionData[model].EIGN,
7952                                   tr->partitionData[model].numberOfCategories, left, right, states);
7953                       
7954                        newviewFlexCat(tInfo->tipCase,  tr->partitionData[model].EV, tr->partitionData[model].rateCategory,
7955                                       x1_start, x2_start, x3_start, tr->partitionData[model].tipVector,
7956                                       ex3, tipX1, tipX2, width, left, right, wgt, &scalerIncrement, tr->useFastScaling, states);
7957                      }
7958                      break;
7959                    case GAMMA:
7960                    case GAMMA_I:
7961                      {
7962                        makeP_Flex(qz, rz, tr->partitionData[model].gammaRates,
7963                                   tr->partitionData[model].EI,
7964                                   tr->partitionData[model].EIGN,
7965                                   4, left, right, states);
7966
7967                        newviewFlexGamma(tInfo->tipCase,
7968                                         x1_start, x2_start, x3_start,
7969                                         tr->partitionData[model].EV,
7970                                         tr->partitionData[model].tipVector,
7971                                         ex3, tipX1, tipX2,
7972                                         width, left, right, wgt, &scalerIncrement, tr->useFastScaling, states);               
7973                      }
7974                      break;
7975                    default:
7976                      assert(0);
7977                    }
7978                  break;
7979                case GENERIC_64:
7980                  break;
7981                default:
7982                  assert(0);
7983                }
7984              if(tr->useFastScaling)
7985                {
7986
7987                  tr->partitionData[model].globalScaler[tInfo->pNumber] = 
7988                    tr->partitionData[model].globalScaler[tInfo->qNumber] + 
7989                    tr->partitionData[model].globalScaler[tInfo->rNumber] +
7990                    (unsigned int)scalerIncrement;
7991                  assert(tr->partitionData[model].globalScaler[tInfo->pNumber] < INT_MAX);
7992                }
7993            }
7994
7995        }
7996#ifdef _DEBUG_MULTI_EPA
7997          printf("\n");
7998#endif   
7999       
8000    }
8001 
8002}
8003
8004
8005
8006
8007
8008void newviewGeneric (tree *tr, nodeptr p)
8009{ 
8010  if(isTip(p->number, tr->mxtips))
8011    return;
8012
8013  tr->td[0].count = 1;
8014  computeTraversalInfo(p, &(tr->td[0].ti[0]), &(tr->td[0].count), tr->mxtips, tr->numBranches);
8015   
8016  if(tr->td[0].count > 1)
8017    {
8018#ifdef _USE_PTHREADS
8019      masterBarrier(THREAD_NEWVIEW, tr);
8020#else
8021      newviewIterative(tr);
8022#endif
8023    }
8024}
8025
8026
8027
8028
8029void newviewGenericMasked(tree *tr, nodeptr p)
8030{
8031  if(isTip(p->number, tr->mxtips))
8032    return;
8033
8034  {
8035    int i;
8036
8037    for(i = 0; i < tr->NumberOfModels; i++)
8038      {
8039        if(tr->partitionConverged[i])
8040          tr->executeModel[i] = FALSE;
8041        else
8042          tr->executeModel[i] = TRUE;
8043      }
8044   
8045   
8046      {
8047        tr->td[0].count = 1;
8048        computeTraversalInfo(p, &(tr->td[0].ti[0]), &(tr->td[0].count), tr->mxtips, tr->numBranches);
8049
8050        if(tr->td[0].count > 1)
8051          {
8052#ifdef _USE_PTHREADS
8053            masterBarrier(THREAD_NEWVIEW_MASKED, tr);
8054#else
8055            newviewIterative(tr);
8056#endif
8057          }
8058      }
8059
8060    for(i = 0; i < tr->NumberOfModels; i++)
8061      tr->executeModel[i] = TRUE;
8062  }
8063}
8064
8065
8066#ifdef  _USE_PTHREADS
8067
8068void newviewMultiGrain(tree *tr,  double *x1, double *x2, double *x3, int *_ex1, int *_ex2, int *_ex3, unsigned char *_tipX1, unsigned char *_tipX2, 
8069                       int tipCase, double *_pz, double *_qz, int insertion)
8070{
8071  int   
8072    scalerIncrement = 0,   
8073    model,         
8074    columnCounter = 0,
8075    offsetCounter = 0;
8076
8077  setPartitionMask(tr, insertion, tr->executeModel);
8078
8079
8080#ifdef _DEBUG_MULTI_EPA
8081  if(tr->threadID == THREAD_TO_DEBUG)
8082    printf("NV %s: ", tr->nameList[tr->inserts[insertion]]);
8083#endif
8084
8085  for(model = 0; model < tr->NumberOfModels; model++)
8086    {
8087      int
8088        width = tr->partitionData[model].upper - tr->partitionData[model].lower;
8089     
8090#ifdef _DEBUG_MULTI_EPA
8091  if(tr->threadID == THREAD_TO_DEBUG)
8092    printf("%d", tr->executeModel[model]);
8093#endif   
8094
8095      if(tr->executeModel[model])
8096        {
8097          double
8098            *x1_start = (double*)NULL,
8099            *x2_start = (double*)NULL,
8100            *x3_start = (double*)NULL,
8101            *left     = tr->partitionData[model].left,
8102            *right    = tr->partitionData[model].right,
8103            pz, qz;
8104         
8105          int
8106            *wgt          = &tr->contiguousWgt[columnCounter],
8107            *rateCategory = &tr->contiguousRateCategory[columnCounter],
8108            *ex1 = (int*)NULL,
8109            *ex2 = (int*)NULL,
8110            *ex3 = (int*)NULL;
8111           
8112         
8113          unsigned char
8114            *tipX1 = (unsigned char *)NULL,
8115            *tipX2 = (unsigned char *)NULL;     
8116         
8117          switch(tipCase)
8118            {
8119            case TIP_TIP:   
8120              tipX1 =    &_tipX1[columnCounter];
8121              tipX2 =    &_tipX2[columnCounter];
8122              ex3   =    &_ex3[columnCounter];
8123              x3_start = &x3[offsetCounter];
8124             
8125              if(!tr->useFastScaling)
8126                {
8127                  int k;             
8128                 
8129                  for(k = 0; k < width; k++)
8130                    ex3[k] = 0;
8131                }
8132              break;
8133            case TIP_INNER:
8134              tipX1 =    &_tipX1[columnCounter];
8135             
8136              ex2   =    &_ex2[columnCounter];
8137              x2_start = &x2[offsetCounter];
8138             
8139              ex3   =    &_ex3[columnCounter];
8140              x3_start = &x3[offsetCounter];
8141             
8142              if(!tr->useFastScaling)
8143                {
8144                  int k;             
8145                 
8146                  for(k = 0; k < width; k++)
8147                    ex3[k] = ex2[k];
8148                }
8149              break;
8150            case INNER_INNER:
8151              ex1   =    &_ex1[columnCounter];
8152              x1_start = &x1[offsetCounter];
8153             
8154              ex2   =    &_ex2[columnCounter];
8155              x2_start = &x2[offsetCounter];
8156             
8157              ex3   =    &_ex3[columnCounter];
8158              x3_start = &x3[offsetCounter];
8159             
8160              if(!tr->useFastScaling)
8161                {
8162                  int k;             
8163                 
8164                  for(k = 0; k < width; k++)
8165                    ex3[k] = ex1[k] + ex2[k];
8166                }
8167              break;
8168            default:
8169              assert(0);
8170            }   
8171         
8172          if(tr->multiBranch)
8173            {
8174              pz = _pz[model];
8175              pz = (pz > zmin) ? log(pz) : log(zmin);
8176             
8177              qz = _qz[model];
8178              qz = (qz > zmin) ? log(qz) : log(zmin);
8179            }
8180          else
8181            {     
8182              pz = _pz[0];
8183              pz = (pz > zmin) ? log(pz) : log(zmin);
8184             
8185              qz = _qz[0];
8186              qz = (qz > zmin) ? log(qz) : log(zmin);
8187            }
8188         
8189     
8190
8191          switch(tr->partitionData[model].dataType)
8192            {
8193            case BINARY_DATA:
8194              switch(tr->rateHetModel)
8195                {
8196                case CAT:             
8197                  makeP(pz, qz, tr->partitionData[model].perSiteRates,   tr->partitionData[model].EI,
8198                        tr->partitionData[model].EIGN, tr->partitionData[model].numberOfCategories,
8199                        left, right, BINARY_DATA, tr->saveMemory, tr->maxCategories);
8200                 
8201                  newviewGTRCAT_BINARY(tipCase,  tr->partitionData[model].EV, rateCategory,
8202                                       x1_start, x2_start, x3_start, tr->partitionData[model].tipVector,
8203                                       ex3, tipX1, tipX2,
8204                                       width, left, right, wgt, &scalerIncrement, tr->useFastScaling
8205                                       );                     
8206                  break;
8207                case GAMMA:
8208                case GAMMA_I:                   
8209                  makeP(pz, qz, tr->partitionData[model].gammaRates,
8210                        tr->partitionData[model].EI, tr->partitionData[model].EIGN,
8211                        4, left, right, BINARY_DATA, tr->saveMemory, tr->maxCategories);
8212                 
8213                  newviewGTRGAMMA_BINARY(tipCase,
8214                                         x1_start, x2_start, x3_start, tr->partitionData[model].EV, tr->partitionData[model].tipVector,
8215                                         ex3, tipX1, tipX2,
8216                                         width, left, right, wgt, &scalerIncrement, tr->useFastScaling);                     
8217                  break;
8218                default:
8219                  assert(0);
8220                }
8221              break;
8222            case DNA_DATA:
8223              switch(tr->rateHetModel)
8224                {
8225                case CAT:                               
8226                  makeP(pz, qz, tr->partitionData[model].perSiteRates,   tr->partitionData[model].EI,
8227                        tr->partitionData[model].EIGN, tr->partitionData[model].numberOfCategories,
8228                        left, right, DNA_DATA, tr->saveMemory, tr->maxCategories);
8229                 
8230#ifdef __AVX
8231                  newviewGTRCAT_AVX(tipCase,  tr->partitionData[model].EV, tr->partitionData[model].rateCategory,
8232                                    x1_start, x2_start, x3_start, tr->partitionData[model].tipVector,
8233                                    ex3, tipX1, tipX2,
8234                                    width, left, right, wgt, &scalerIncrement, tr->useFastScaling); 
8235#else
8236                 
8237                  newviewGTRCAT(tipCase,  tr->partitionData[model].EV, rateCategory,
8238                                x1_start, x2_start, x3_start, tr->partitionData[model].tipVector,
8239                                ex3, tipX1, tipX2,
8240                                width, left, right, wgt, &scalerIncrement, tr->useFastScaling
8241                                );
8242#endif
8243                 
8244                  break;
8245                case GAMMA:
8246                case GAMMA_I:                   
8247                  makeP(pz, qz, tr->partitionData[model].gammaRates,
8248                        tr->partitionData[model].EI, tr->partitionData[model].EIGN,
8249                        4, left, right, DNA_DATA, tr->saveMemory, tr->maxCategories);
8250                 
8251#ifdef __AVX
8252                  newviewGTRGAMMA_AVX(tipCase,
8253                                      x1_start, x2_start, x3_start, tr->partitionData[model].EV, tr->partitionData[model].tipVector,
8254                                      ex3, tipX1, tipX2,
8255                                      width, left, right, wgt, &scalerIncrement, tr->useFastScaling);
8256#else
8257                  newviewGTRGAMMA(tipCase,
8258                                  x1_start, x2_start, x3_start, tr->partitionData[model].EV, tr->partitionData[model].tipVector,
8259                                  ex3, tipX1, tipX2,
8260                                  width, left, right, wgt, &scalerIncrement, tr->useFastScaling);                                   
8261#endif
8262                  break;
8263                default:
8264                  assert(0);
8265                }
8266              break;
8267            case AA_DATA:
8268              switch(tr->rateHetModel)
8269                {
8270                case CAT:             
8271                  makeP(pz, qz, tr->partitionData[model].perSiteRates,
8272                        tr->partitionData[model].EI,
8273                        tr->partitionData[model].EIGN,
8274                        tr->partitionData[model].numberOfCategories, left, right, AA_DATA, tr->saveMemory, tr->maxCategories);
8275#ifdef __AVX
8276                  newviewGTRCATPROT_AVX(tipCase,  tr->partitionData[model].EV, tr->partitionData[model].rateCategory,
8277                                        x1_start, x2_start, x3_start, tr->partitionData[model].tipVector,
8278                                        ex3, tipX1, tipX2, width, left, right, wgt, &scalerIncrement, tr->useFastScaling);
8279#else                 
8280                  newviewGTRCATPROT(tipCase,  tr->partitionData[model].EV, rateCategory,
8281                                    x1_start, x2_start, x3_start, tr->partitionData[model].tipVector,
8282                                    ex3, tipX1, tipX2, width, left, right, wgt, &scalerIncrement, tr->useFastScaling);               
8283#endif
8284                  break;
8285                case GAMMA:
8286                case GAMMA_I:         
8287                  makeP(pz, qz, tr->partitionData[model].gammaRates,
8288                        tr->partitionData[model].EI,
8289                        tr->partitionData[model].EIGN,
8290                        4, left, right, AA_DATA, tr->saveMemory, tr->maxCategories);
8291#ifdef __AVX
8292                  newviewGTRGAMMAPROT_AVX(tipCase,
8293                                          x1_start, x2_start, x3_start,
8294                                          tr->partitionData[model].EV,
8295                                          tr->partitionData[model].tipVector,
8296                                          ex3, tipX1, tipX2,
8297                                          width, left, right, wgt, &scalerIncrement, tr->useFastScaling);
8298#else         
8299                  newviewGTRGAMMAPROT(tipCase,
8300                                      x1_start, x2_start, x3_start,
8301                                      tr->partitionData[model].EV,
8302                                      tr->partitionData[model].tipVector,
8303                                      ex3, tipX1, tipX2,
8304                                      width, left, right, wgt, &scalerIncrement, tr->useFastScaling);
8305#endif
8306                 
8307                  break;
8308                default:
8309                  assert(0);
8310                }
8311              break;
8312            case SECONDARY_DATA:
8313              switch(tr->rateHetModel)
8314                {
8315                case CAT:             
8316                  makeP(pz, qz, tr->partitionData[model].perSiteRates,
8317                        tr->partitionData[model].EI,
8318                        tr->partitionData[model].EIGN,
8319                        tr->partitionData[model].numberOfCategories, left, right, SECONDARY_DATA, tr->saveMemory, tr->maxCategories);
8320                 
8321                  newviewGTRCATSECONDARY(tipCase,  tr->partitionData[model].EV, rateCategory,
8322                                         x1_start, x2_start, x3_start, tr->partitionData[model].tipVector,
8323                                         ex3, tipX1, tipX2, width, left, right, wgt, &scalerIncrement, tr->useFastScaling);
8324                 
8325                  break;
8326                case GAMMA:
8327                case GAMMA_I:         
8328                  makeP(pz, qz, tr->partitionData[model].gammaRates,
8329                        tr->partitionData[model].EI,
8330                        tr->partitionData[model].EIGN,
8331                        4, left, right, SECONDARY_DATA, tr->saveMemory, tr->maxCategories);
8332                 
8333                  newviewGTRGAMMASECONDARY(tipCase,
8334                                           x1_start, x2_start, x3_start,
8335                                           tr->partitionData[model].EV,
8336                                           tr->partitionData[model].tipVector,
8337                                           ex3, tipX1, tipX2,
8338                                           width, left, right, wgt, &scalerIncrement, tr->useFastScaling);
8339                 
8340                  break;
8341                default:
8342                  assert(0);
8343                }
8344              break;
8345            case SECONDARY_DATA_6:
8346              switch(tr->rateHetModel)
8347                {
8348                case CAT:                     
8349                  makeP(pz, qz, tr->partitionData[model].perSiteRates,
8350                        tr->partitionData[model].EI,
8351                        tr->partitionData[model].EIGN,
8352                        tr->partitionData[model].numberOfCategories, left, right, SECONDARY_DATA_6, tr->saveMemory, tr->maxCategories);
8353                 
8354                  newviewGTRCATSECONDARY_6(tipCase,  tr->partitionData[model].EV, rateCategory,
8355                                           x1_start, x2_start, x3_start, tr->partitionData[model].tipVector,
8356                                           ex3, tipX1, tipX2, width, left, right, wgt, &scalerIncrement, tr->useFastScaling);       
8357                  break;
8358                case GAMMA:
8359                case GAMMA_I:                 
8360                  makeP(pz, qz, tr->partitionData[model].gammaRates,
8361                        tr->partitionData[model].EI,
8362                        tr->partitionData[model].EIGN,
8363                        4, left, right, SECONDARY_DATA_6, tr->saveMemory, tr->maxCategories);
8364                 
8365                  newviewGTRGAMMASECONDARY_6(tipCase,
8366                                             x1_start, x2_start, x3_start,
8367                                             tr->partitionData[model].EV,
8368                                             tr->partitionData[model].tipVector,
8369                                             ex3, tipX1, tipX2,
8370                                             width, left, right, wgt, &scalerIncrement, tr->useFastScaling);       
8371                  break;
8372                default:
8373                  assert(0);
8374                }
8375              break;
8376            case SECONDARY_DATA_7:
8377              switch(tr->rateHetModel)
8378                {
8379                case CAT:                     
8380                  makeP(pz, qz, tr->partitionData[model].perSiteRates,
8381                        tr->partitionData[model].EI,
8382                        tr->partitionData[model].EIGN,
8383                        tr->partitionData[model].numberOfCategories, left, right, SECONDARY_DATA_7, tr->saveMemory, tr->maxCategories);
8384                 
8385                  newviewGTRCATSECONDARY_7(tipCase,  tr->partitionData[model].EV, rateCategory,
8386                                           x1_start, x2_start, x3_start, tr->partitionData[model].tipVector,
8387                                           ex3, tipX1, tipX2, width, left, right, wgt, &scalerIncrement, tr->useFastScaling);         
8388                  break;
8389                case GAMMA:
8390                case GAMMA_I:         
8391                  makeP(pz, qz, tr->partitionData[model].gammaRates,
8392                        tr->partitionData[model].EI,
8393                        tr->partitionData[model].EIGN,
8394                        4, left, right, SECONDARY_DATA_7, tr->saveMemory, tr->maxCategories);
8395                 
8396                  newviewGTRGAMMASECONDARY_7(tipCase,
8397                                             x1_start, x2_start, x3_start,
8398                                             tr->partitionData[model].EV,
8399                                             tr->partitionData[model].tipVector,
8400                                             ex3, tipX1, tipX2,
8401                                             width, left, right, wgt, &scalerIncrement, tr->useFastScaling);         
8402                  break;
8403                default:
8404                  assert(0);
8405                }
8406              break;
8407            default:
8408              assert(0);
8409            }
8410        }
8411
8412      columnCounter += width;
8413      offsetCounter += width * tr->partitionData[model].states * tr->discreteRateCategories;   
8414    }
8415
8416#ifdef _DEBUG_MULTI_EPA
8417  if(tr->threadID == THREAD_TO_DEBUG)
8418    printf("\n");
8419#endif
8420
8421  resetPartitionMask(tr, tr->executeModel);
8422}
8423
8424
8425
8426void newviewClassify(tree *tr, branchInfo *b, double *z, int insertion)
8427{
8428  int 
8429    leftNumber = b->epa->leftNodeNumber,
8430    rightNumber = b->epa->rightNodeNumber,
8431    tipCase = -1,
8432    *ex1 = (int*)NULL,
8433    *ex2 = (int*)NULL,
8434    *ex3 = tr->temporaryScaling;
8435
8436  double
8437    *x1_start = (double*)NULL,
8438    *x2_start = (double*)NULL,
8439    *x3_start = tr->temporaryVector;
8440
8441  unsigned char
8442    *tipX1 = (unsigned char*)NULL,
8443    *tipX2 = (unsigned char*)NULL;
8444 
8445  if (isTip(leftNumber, tr->mxtips) && isTip(rightNumber, tr->mxtips))
8446    {     
8447      tipCase = TIP_TIP;
8448     
8449      tipX1 = tr->contiguousTips[leftNumber];
8450      tipX2 = tr->contiguousTips[rightNumber];
8451    }
8452  else
8453    {
8454      if (isTip(leftNumber, tr->mxtips))
8455        {             
8456          tipCase = TIP_INNER;
8457         
8458          tipX1 = tr->contiguousTips[leftNumber];
8459
8460          x2_start = b->epa->right;
8461          ex2      = b->epa->rightScaling;               
8462        }
8463      else
8464        {
8465          if(isTip(rightNumber, tr->mxtips))
8466            {             
8467              tipCase = TIP_INNER;
8468             
8469              tipX1 = tr->contiguousTips[rightNumber];
8470             
8471              x2_start = b->epa->left;
8472              ex2      = b->epa->leftScaling;           
8473            }
8474          else
8475            {
8476              tipCase = INNER_INNER;
8477             
8478              x1_start = b->epa->left;
8479              ex1      = b->epa->leftScaling;
8480             
8481              x2_start = b->epa->right;
8482              ex2      = b->epa->rightScaling;             
8483            }
8484        }
8485    }
8486   
8487  newviewMultiGrain(tr,  x1_start, x2_start, x3_start, ex1, ex2, ex3, tipX1, tipX2, 
8488                    tipCase, z, z, insertion);
8489
8490}
8491
8492
8493
8494
8495
8496
8497
8498
8499#endif
8500
8501
Note: See TracBrowser for help on using the repository browser.