static double evaluatePartialGTRCATPROT(int i, double ki, int counter,  traversalInfo *ti, double qz,
					int w, double *EIGN, double *EI, double *EV,
					double *tipVector, unsigned char **yVector, 
					int branchReference, int mxtips)
{
  double lz, term;       
  double  d[20];
  double   *x1, *x2; 
  int scale = 0, k, l;
  double *lVector = (double *)rax_malloc_aligned(sizeof(double) * 20 * mxtips);

  traversalInfo *trav = &ti[0];

  assert(isTip(trav->pNumber, mxtips));
     
  x1 = &(tipVector[20 *  yVector[trav->pNumber][i]]);   

  for(k = 1; k < counter; k++)                
    computeVectorGTRCATPROT(lVector, &scale, ki, i, ti[k].qz[branchReference], ti[k].rz[branchReference], 
			    &ti[k], EIGN, EI, EV, 
			    tipVector, yVector, mxtips);       
   
  x2 = &lVector[20 * (trav->qNumber - mxtips)];

       

  assert(0 <=  (trav->qNumber - mxtips) && (trav->qNumber - mxtips) < mxtips);  
  
  if(qz < zmin) 
    lz = zmin;
  lz  = log(qz); 
  lz *= ki;
  
  d[0] = 1.0;
  for(l = 1; l < 20; l++)
    d[l] = EXP (EIGN[l-1] * lz);

  term = 0.0;
  
  for(l = 0; l < 20; l++)
    term += x1[l] * x2[l] * d[l];   

  term = LOG(FABS(term)) + (scale * LOG(minlikelihood));   

  term = term * w;

  rax_free(lVector);
  

  return  term;
}
static double evaluatePartialGTRCATPROT(int i, double ki, int counter,  traversalInfo *ti, double qz,
                                        int w, double *EIGN, double *EI, double *EV,
                                        double *tipVector, unsigned char **yVector,
                                        int branchReference, int mxtips)
{
    double lz, term;
    double  d[20];
    double   *x1, *x2;
    int scale = 0, k, l;
    double
    *lVector = (double *)malloc_aligned(sizeof(double) * 20 * mxtips),
     myEI[400]  __attribute__ ((aligned (BYTE_ALIGNMENT)));

    traversalInfo *trav = &ti[0];



    for(k = 0; k < 20; k++)
    {
        for(l = 0; l < 20; l++)
            myEI[k * 20 + l] = EI[k * 20 + l];
    }

    assert(isTip(trav->pNumber, mxtips));

    x1 = &(tipVector[20 *  yVector[trav->pNumber][i]]);

    for(k = 1; k < counter; k++)
    {
        double
        qz = ti[k].qz[branchReference],
        rz = ti[k].rz[branchReference];

        qz = (qz > zmin) ? log(qz) : log(zmin);
        rz = (rz > zmin) ? log(rz) : log(zmin);

        computeVectorGTRCATPROT(lVector, &scale, ki, i, qz, rz,
                                &ti[k], EIGN, myEI, EV,
                                tipVector, yVector, mxtips);
    }

    x2 = &lVector[20 * (trav->qNumber - mxtips)];



    assert(0 <=  (trav->qNumber - mxtips) && (trav->qNumber - mxtips) < mxtips);

    if(qz < zmin)
        lz = zmin;
    lz  = log(qz);
    lz *= ki;

    d[0] = 1.0;
    for(l = 1; l < 20; l++)
        d[l] = EXP (EIGN[l] * lz);

    term = 0.0;

    for(l = 0; l < 20; l++)
        term += x1[l] * x2[l] * d[l];

    term = LOG(FABS(term)) + (scale * LOG(minlikelihood));

    term = term * w;

    free(lVector);


    return  term;
}