Example #1
0
double dbb(int x, int n, double mu, double disp, int logp) {
	double y = mu * disp;
	double p = lbeta(x + y, n - x - y + disp) - lbeta(y, disp - y) + lgamma(n+1) - lgamma(x+1) -lgamma(n-x+1);
	if(! logp)
		p = exp(p);
	return p;
}
Example #2
0
double intrinsic_glm_shrinkage(SEXP hyperparams, int pmodel, double W, int Laplace ) {
  double a, b, s, r, v, theta, n, p, u, shrinkage;

  a = REAL(getListElement(hyperparams, "alpha"))[0];
  b = REAL(getListElement(hyperparams, "beta"))[0];
  s = REAL(getListElement(hyperparams, "s"))[0];
  r = REAL(getListElement(hyperparams, "r"))[0];
  n = REAL(getListElement(hyperparams, "n"))[0];

  p = (double) pmodel;
  v = (n + p + 1.0)/(p + 1);
  theta = (n + p + 1.0)/n;

  shrinkage = 1.0;
  if (p >= 1.0) {
     u = exp(-log(v)
             + lbeta((a + p) / 2.0 + 1.0, b / 2.0)
             + log(HyperTwo(b/2.0, r, (a +b+p)/2.0 + 1.0, (s+W)/(2.0*v), 1.0-theta))
             - lbeta((a+p) / 2.0, b/2.0)
             - log(HyperTwo(b/2.0, r, (a + p+ b)/2.0, (s+W)/(2.0*v), 1.0 - theta)));
    shrinkage = 1.0 - u;
  }

  return(shrinkage);
}
Example #3
0
double intrinsic_glm_logmarg(SEXP hyperparams, int pmodel, double W,
		       double loglik_mle, double logdet_Iintercept, int Laplace ) {
  double a, b, s, r, v, theta,n, logmarglik, p;

  a = REAL(getListElement(hyperparams, "alpha"))[0];
  b = REAL(getListElement(hyperparams, "beta"))[0];
  s = REAL(getListElement(hyperparams, "s"))[0];
  r = REAL(getListElement(hyperparams, "r"))[0];
  n = REAL(getListElement(hyperparams, "n"))[0];

  p = (double) pmodel;

  v = (n + p + 1.0)/(p + 1);
  theta = (n + p + 1.0)/n;

  logmarglik =   loglik_mle + M_LN_SQRT_2PI - 0.5* logdet_Iintercept;
  if (p >= 1.0) {
    logmarglik +=   lbeta((a + p) / 2.0, b / 2.0)
      + log(HyperTwo(b/2.0, r, (a + b + p)/2.0, (s+W)/(2.0*v), 1.0 - theta))
      -.5*p*log(v) -.5*W/v
      - lbeta(a / 2.0, b / 2.0)
      - log(HyperTwo(b/2.0, r, (a + b)/2.0, s/(2.0*v), 1.0 - theta));
  }

  return(logmarglik);
}
Example #4
0
double dbeta(double x, double a, double b, int give_log)
{
    double lval;

#ifdef IEEE_754
    /* NaNs propagated correctly */
    if (ISNAN(x) || ISNAN(a) || ISNAN(b)) return x + a + b;
#endif

    if (a <= 0 || b <= 0) ML_ERR_return_NAN;
    if (x < 0 || x > 1) return(R_D__0);
    if (x == 0) {
	if(a > 1) return(R_D__0);
	if(a < 1) return(ML_POSINF);
	/* a == 1 : */ return(R_D_val(b));
    }
    if (x == 1) {
	if(b > 1) return(R_D__0);
	if(b < 1) return(ML_POSINF);
	/* b == 1 : */ return(R_D_val(a));
    }
    if (a <= 2 || b <= 2)
	lval = (a-1)*log(x) + (b-1)*log1p(-x) - lbeta(a, b);
    else
	lval = log(a+b-1) + dbinom_raw(a-1, a+b-2, x, 1-x, TRUE);

    return R_D_exp(lval);
}
Example #5
0
double betaprime_glm_logmarg(SEXP hyperparams, int pmodel, double W,
		       double loglik_mle, double logdet_Iintercept, int Laplace ) {
  double a, n, p, logmarglik;

  a = REAL(getListElement(hyperparams, "alpha"))[0];
  n = REAL(getListElement(hyperparams, "n"))[0];
  p = (double) pmodel;

  logmarglik =   loglik_mle + M_LN_SQRT_2PI - 0.5* logdet_Iintercept;
  if (p >= 1.0) {
    logmarglik +=   lbeta((a + p) / 2.0, (n - p - 1.5) / 2.0)
      + loghyperg1F1((a + p)/2.0, (a + n - 1.5)/2.0, -W/2.0, Laplace)
      - lbeta(a / 2.0, (n - p - 1.5)/ 2.0)
      - loghyperg1F1(a/2.0, (a + n - p - 1.5)/2.0, 0.0, Laplace);
  }

  return(logmarglik);
}
double bprob(double p, double a, double b) 
{
   double q, yl ;
   q = 1.0 - p ;
   yl = (a-1) * log(p) + (b-1) * log (q) ;
   if (!finite(yl)) fatalx("bad bprob\n") ;
   yl -= lbeta(a, b) ;
   if (!finite(yl)) fatalx("bad bprob\n") ;
   return yl ;
}
Example #7
0
static double lbeta_negint(int a, double b)
{
    double r;
    if (b == (int)b && 1 - a - b > 0) {
        r = lbeta(1 - a - b, b);
        return r;
    }
    else {
	mtherr("lbeta", OVERFLOW);
        return CEPHES_INFINITY;
    }
}
Example #8
0
double beta(double a, double b)
{
#ifdef NOMORE_FOR_THREADS
    static double xmin, xmax = 0;/*-> typically = 171.61447887 for IEEE */
    static double lnsml = 0;/*-> typically = -708.3964185 */

    if (xmax == 0) {
	    gammalims(&xmin, &xmax);
	    lnsml = log(d1mach(1));
    }
#else
/* For IEEE double precision DBL_EPSILON = 2^-52 = 2.220446049250313e-16 :
 *   xmin, xmax : see ./gammalims.c
 *   lnsml = log(DBL_MIN) = log(2 ^ -1022) = -1022 * log(2)
*/
# define xmin  -170.5674972726612
# define xmax   171.61447887182298
# define lnsml -708.39641853226412
#endif


#ifdef IEEE_754
    /* NaNs propagated correctly */
    if(ISNAN(a) || ISNAN(b)) return a + b;
#endif

    if (a < 0 || b < 0)
	ML_ERR_return_NAN
    else if (a == 0 || b == 0)
	return ML_POSINF;
    else if (!R_FINITE(a) || !R_FINITE(b))
	return 0;

    if (a + b < xmax) {/* ~= 171.61 for IEEE */
//	return gammafn(a) * gammafn(b) / gammafn(a+b);
	/* All the terms are positive, and all can be large for large
	   or small arguments.  They are never much less than one.
	   gammafn(x) can still overflow for x ~ 1e-308, 
	   but the result would too. 
	*/
	return (1 / gammafn(a+b)) * gammafn(a) * gammafn(b);
    } else {
	double val = lbeta(a, b);
	if (val < lnsml) {
	    /* a and/or b so big that beta underflows */
	    ML_ERROR(ME_UNDERFLOW, "beta");
	    /* return ML_UNDERFLOW; pointless giving incorrect value */
	}
	return exp(val);
    }
}
Example #9
0
double shrinkage_chg(double a, double b, double Q, int laplace) {

  double shrinkage;
  /* Beta(a/2,(b+2)/2) 1F1(a/2,(b+2)/2,(s+Q)/2 /
     Beta(a/2,b/2) 1F1(a/2,b/2,(s+Q)/2
  */		       
  /* shrinkage = exp( lbeta(a/2.0, (b+2.0)/2.0) +
		   log(hyperg1F1(a/2.0, b/2.0 + 1.0, Q/2.0)) -
		   lbeta(a/2.0, (b)/2.0) -
		   log(hyperg1F1(a/2.0, b/2.0, Q/2.0)));
   */
   //    Rprintf("shrinkage_chg:  %lf\n", shrinkage);
    shrinkage = exp( lbeta(a/2.0, b/2.0 + 1.0) +
		     loghyperg1F1(a/2.0, b/2.0 + 1.0,  Q/2.0, laplace) -
		     lbeta(a/2.0, b/2.0) -
		     loghyperg1F1(a/2.0, b/2.0,  Q/2.0, laplace));	

    //Rprintf("Laplace shrinkage_chg:  %lf\n", shrinkage);
  if (shrinkage > 1.0)  shrinkage = 1.0;
  else if (shrinkage < 0.0) shrinkage = 0.0;
  
  return (shrinkage);
}
Example #10
0
double CCH_glm_logmarg(SEXP hyperparams, int pmodel, double W,
		       double loglik_mle, double logdet_Iintercept, int Laplace ) {
  double a, b, s, logmarglik, p;

  a = REAL(getListElement(hyperparams, "alpha"))[0];
  b = REAL(getListElement(hyperparams, "beta"))[0];
  s = REAL(getListElement(hyperparams, "s"))[0];
  //  n = INTEGER(getListElement(hyperparams, "n"))[0];
  //  p = INTEGER(getListElement(hyperparams, "p"))[0];
  // Rprintf("a = %lf\n", a);
  // Rprintf("b = %lf\n", b);
  p = (double) pmodel;

  logmarglik =   loglik_mle + M_LN_SQRT_2PI - 0.5* logdet_Iintercept;
  if (p >= 1.0) {
    logmarglik +=   lbeta((a + p) / 2.0, b / 2.0)
                  + loghyperg1F1((a + p)/2.0, (a + b + p)/2.0, -(s+W)/2.0, Laplace)
                  - lbeta(a / 2.0, b / 2.0)
                  - loghyperg1F1(a/2.0, (a + b)/2.0, - s/2.0, Laplace);
  }

  return(logmarglik);
}
Example #11
0
double tCCH_glm_shrinkage(SEXP hyperparams, int pmodel, double W, int Laplace ) {
  double a, b, s, r, v, theta, p, shrinkage;

  a = REAL(getListElement(hyperparams, "alpha"))[0];
  b = REAL(getListElement(hyperparams, "beta"))[0];
  s = REAL(getListElement(hyperparams, "s"))[0];
  r = REAL(getListElement(hyperparams, "r"))[0];
  v = REAL(getListElement(hyperparams, "v"))[0];
  theta =  REAL(getListElement(hyperparams, "theta"))[0];

  p = (double) pmodel;

  shrinkage = 1.0;
  if (p >= 1.0) {
   shrinkage -=  exp( -log(v)
    + lbeta((a + p) / 2.0 + 1.0, b / 2.0)
    + log(HyperTwo(b/2.0, r, (a +b+p)/2.0 + 1.0, (s+W)/(2.0*v), 1.0-theta))
    - lbeta((a+p) / 2.0, b/2.0)
    - log(HyperTwo(b/2.0, r, (a + p+ b)/2.0, (s+W)/(2.0*v), 1.0 - theta)));
  }

  return(shrinkage);
}
Example #12
0
double dbeta(double x, double a, double b, int give_log)
{
#ifdef IEEE_754
    /* NaNs propagated correctly */
    if (ISNAN(x) || ISNAN(a) || ISNAN(b)) return x + a + b;
#endif

    if (a < 0 || b < 0) ML_ERR_return_NAN;
    if (x < 0 || x > 1) return(R_D__0);

    // limit cases for (a,b), leading to point masses
    if(a == 0 || b == 0 || !R_FINITE(a) || !R_FINITE(b)) {
	if(a == 0 && b == 0) { // point mass 1/2 at each of {0,1} :
	    if (x == 0 || x == 1) return(ML_POSINF); /* else */ return(R_D__0);
	}
	if (a == 0 || a/b == 0) { // point mass 1 at 0
	    if (x == 0) return(ML_POSINF); /* else */ return(R_D__0);
	}
	if (b == 0 || b/a == 0) { // point mass 1 at 1
	    if (x == 1) return(ML_POSINF); /* else */ return(R_D__0);
	}
	// else, remaining case:  a = b = Inf : point mass 1 at 1/2
	if (x == 0.5) return(ML_POSINF); /* else */ return(R_D__0);
    }

    if (x == 0) {
	if(a > 1) return(R_D__0);
	if(a < 1) return(ML_POSINF);
	/* a == 1 : */ return(R_D_val(b));
    }
    if (x == 1) {
	if(b > 1) return(R_D__0);
	if(b < 1) return(ML_POSINF);
	/* b == 1 : */ return(R_D_val(a));
    }

    double lval;
    if (a <= 2 || b <= 2)
	lval = (a-1)*log(x) + (b-1)*log1p(-x) - lbeta(a, b);
    else
	lval = log(a+b-1) + dbinom_raw(a-1, a+b-2, x, 1-x, TRUE);

    return R_D_exp(lval);
}
Example #13
0
File: cutil.c Project: cran/growth
void F77_CALL(flbeta)(double *a,double *b,double *y){
  *y=lbeta(*a, *b);}
Example #14
0
double BetaLogPdf::f(double alpha, double beta, double x)
{
    return (alpha - 1) * fastlog(x) + (beta - 1) * fastlog(1 - x) - lbeta(alpha, beta);
}
Example #15
0
double attribute_hidden lfastchoose(double n, double k)
{
    return -log(n + 1.) - lbeta(n - k + 1., k + 1.);
}
Example #16
0
void inbeder(double* x_in, double* p_in, double* q_in, double* der)
{

  double lbet, pa, pa1, pb, pb1, pab, pab1, err=1e-12;
  double p, q, x;
  int minappx=3, maxappx=200, n=0;

  // falls x>p/(p+q)
  if (*x_in>*p_in/(*p_in+*q_in))
  {
	  x=1-*x_in;
	  p=*q_in;
	  q=*p_in;
  }
  else
  {
	  x=*x_in;
	  p=*p_in;
	  q=*q_in;
  }
  
  // Compute Log Beta, digamma, and trigamma functions
  
  lbet=lbeta(p,q);
  pa=digamma(p);
  pa1=trigamma(p);
  pb=digamma(q);
  pb1=trigamma(q);
  pab=digamma(p+q);
  pab1=trigamma(p+q);


  double omx=1-x;
  double logx=log(x);
  double logomx=log(omx);

  // Compute derivatives of K(x,p,q)=x^p(1-x)^(q-1)/[p beta(p,q)

  double *c;
  double c0, d;
  c=Calloc(3,double);
  c[0]=p*logx+(q-1)*logomx-lbet-log(p);
  c0=exp(c[0]);
  if (*x_in>*p_in/(*p_in+*q_in))
  {
	 c[1]=logomx-pb+pab;
  	c[2]=c[1]*c[1]-pb1+pab1;
  }
  else
  {
  	c[1]=logx-1/p-pa+pab;
 	 c[2]=c[1]*c[1]+1/p/p-pa1+pab1;
  }
  

  int del=1, i=0;
  double *an, *bn, *an1, *an2, *bn1, *bn2, *dr;
  an=Calloc(3,double);
  bn=Calloc(3,double);
  an1=Calloc(3,double);
  bn1=Calloc(3,double);
  an2=Calloc(3,double);
  bn2=Calloc(3,double);
  dr=Calloc(3,double);
  double *dan, *dbn, *der_old, *d1;
  dan=Calloc(3,double);
  dbn=Calloc(3,double);
  der_old=Calloc(3,double);
  d1=Calloc(3,double);

  double Rn=0, pr=0;

  an1[0]=1;
  an2[0]=1;
  bn1[0]=1;
  bn2[0]=0;
  der_old[0]=0;
  for(i=1;i<3;i++)
  {
	  an1[i]=0;
	  an2[i]=0;
	  bn1[i]=0;
	  bn2[i]=0;
	  der_old[i]=0;
  }

	
  while(del==1)
  {
	  n++;
	  if(n==1)
	  {
		  if (*x_in>*p_in/(*p_in+*q_in))
		  {
			  incompleBeta_an1_bn1_q(&x, p, q, an, bn);
		  }
		  else
		  {
			  incompleBeta_an1_bn1_p(&x, p, q, an, bn);

		  }
	  }
	  else
	  {
		  if (*x_in>*p_in/(*p_in+*q_in))
		  {
			  incompleBeta_an_bn_q(&x, p, q, n, an, bn);
		  }
		  else
		  {
			  incompleBeta_an_bn_p(&x, p, q, n, an, bn);
		  }
	  }
	  

	  // Use forward recurrance relations to compute An, Bn, and their derivatives
	  
	  dan[0]=an[0]*an2[0]+bn[0]*an1[0];
	  dbn[0]=an[0]*bn2[0]+bn[0]*bn1[0];
	  dan[1]=an[1]*an2[0]+an[0]*an2[1]+bn[1]*an1[0]+bn[0]*an1[1];
	  dbn[1]=an[1]*bn2[0]+an[0]*bn2[1]+bn[1]*bn1[0]+bn[0]*bn1[1];
	  dan[2]=an[2]*an2[0]+2*an[1]*an2[1]+an[0]*an2[2]+bn[2]*an1[0]+2*bn[1]*an1[1]+bn[0]*an1[2];
	  dbn[2]=an[2]*bn2[0]+2*an[1]*bn2[1]+an[0]*bn2[2]+bn[2]*bn1[0]+2*bn[1]*bn1[1]+bn[0]*bn1[2];
	  
	  
	  // Scale derivatives to prevent overflow
	  
	  Rn=dan[0];
	  if(fabs(dbn[0])>fabs(dan[0]))
	  {
	    Rn=dbn[0];
	  }
	  for(i=0;i<3;i++)
	  {
	      an1[i]=an1[i]/Rn;
	      bn1[i]=bn1[i]/Rn;
	  }
	  dan[1]=dan[1]/Rn;
	  dan[2]=dan[2]/Rn;
	  dbn[1]=dbn[1]/Rn;
	  dbn[2]=dbn[2]/Rn;
	  if(fabs(dbn[0])>fabs(dan[0]))
	  {
	    dan[0]=dan[0]/dbn[0];
	    dbn[0]=1;
	  }
	  else
	  {
	    dbn[0]=dbn[0]/dan[0];
	    dan[0]=1;
	  }
	  
	  // Compute components of derivatives of the nth approximant
	  
	  dr[0]=dan[0]/dbn[0];
	  Rn=dr[0];
	  dr[1]=(dan[1]-Rn*dbn[1])/dbn[0];
	  dr[2]=(-2*dan[1]*dbn[1]+2*Rn*dbn[1]*dbn[1])/dbn[0]/dbn[0]+(dan[2]-Rn*dbn[2])/dbn[0];
	  
	  // Save terms corresponding to approximants n-1 and n-2
	  
	  for(i=0;i<3;i++)
	  {
	    an2[i]=an1[i];
	    an1[i]=dan[i];
	    bn2[i]=bn1[i];
	    bn1[i]=dbn[i];
	  }
	  
	  //  Compute nth approximants
	  pr=0;
	  if(dr[0]>0)
	  {
	    pr=exp(c[0]+log(dr[0]));
	  }
	  der[0]=pr;
	  der[1]=pr*c[1]+c0*dr[1];
	  der[2]=pr*c[2]+2*c0*c[1]*dr[1]+c0*dr[2];
	  
	  
	  // Check for convergence, check for maximum and minimum iterations.
	  
	  for(i=0;i<3;i++)
	  {
	    d1[i]=MAX(err,fabs(der[i]));
	    d1[i]=fabs(der_old[i]-der[i])/d1[i];
	    der_old[i]=der[i];
	  }
	  d=MAX(MAX(d1[0],d1[1]),d1[2]);
	  
	  if(n< minappx)
	  {
	    d=1;
	  }
	  if(n>= maxappx)
	  {
	    d=0;
	  }
	  del=0;
	  if(d> err)
	  {
	    del=1;
	  }
	  
	  
  }
 
  	// Adjust results if I(x,p,q) = 1- I(1-x,q,p) was used
	  
	  if (*x_in>*p_in/(*p_in+*q_in))
	  {
		der[0]=1-der[0];
		der[1]=-der[1];
		der[2]=-der[2];
	  }

  Free(c);
  Free(an);
  Free(bn);
  Free(dan);
  Free(dbn);
  Free(dr);
  Free(an1);
  Free(an2);
  Free(bn1);
  Free(bn2);
  Free(d1);
  Free(der_old);
  
}
Example #17
0
//function to calculate l[P'(D|M)] for a given distribution of bases
double lPDM_mod_fn(int *z, int ind, double pstar)
{	
	/*'z' is a pointer to a vector of length 5, where the
		first 4 elements correspond to each base (with the consensus
		as the fourth element z[3]). The final element is 
		S-z[3]=sum(z[0:2])
	'ind' denotes which model (from 0:9) is to be calculated
	'pstar' is the overall mutation rate*/
	
	double lPDM = 0.0;
/*	switch(ind)*/
/*	{*/
/*		//Null p1=p2=p3=p3*/
/*		case 0 :lPDM=z[4]*log(pstar/3.0)+z[3]*log(1.0-pstar);*/
/*			break;*/
/*		//Alt that one free pi is different: e.g. p1!=p2=p3 etc. but mutation rate constrained to p**/
/*		case 1 :lPDM=-(z[1]+z[2])*log(2.0)+lfactorial(z[0])+lfactorial(z[1]+z[2])-lfactorial(z[4]+1)+z[4]*log(pstar)+z[3]*log(1.0-pstar);*/
/*			break;*/
/*		case 2 :lPDM=-(z[0]+z[2])*log(2.0)+lfactorial(z[1])+lfactorial(z[0]+z[2])-lfactorial(z[4]+1)+z[4]*log(pstar)+z[3]*log(1.0-pstar);*/
/*			break;*/
/*		case 3 :lPDM=-(z[0]+z[1])*log(2.0)+lfactorial(z[2])+lfactorial(z[0]+z[1])-lfactorial(z[4]+1)+z[4]*log(pstar)+z[3]*log(1.0-pstar);*/
/*			break;*/
/*		//Alt that all pis are different but mutation rate constrained to p**/
/*		case 4 :lPDM=log(2.0)+lfactorial(z[0])+lfactorial(z[1])+lfactorial(z[2])-lfactorial(z[4]+2)+z[4]*log(pstar)+z[3]*log(1.0-pstar);*/
/*			break;*/
/*		//Alt that pis are uniform but not constrained to sum to p**/
/*		case 5 :lPDM=-z[4]*log(3.0)+lfactorial(z[4])+lfactorial(z[3])-lfactorial(z[3]+z[4]+1);*/
/*			break;*/
/*		//Alt that one free pi is different: e.g. p1!=p2=p3 etc.*/
/*		case 6 :lPDM=-(z[1]+z[2])*log(2.0)+lfactorial(z[1]+z[2])+lfactorial(z[0])+lfactorial(z[3])-log(z[4]+1)-lfactorial(z[4]+z[3]+1);*/
/*			break;*/
/*		case 7 :lPDM=-(z[0]+z[2])*log(2.0)+lfactorial(z[0]+z[2])+lfactorial(z[1])+lfactorial(z[3])-log(z[4]+1)-lfactorial(z[4]+z[3]+1);*/
/*			break;*/
/*		case 8 :lPDM=-(z[0]+z[1])*log(2.0)+lfactorial(z[0]+z[1])+lfactorial(z[2])+lfactorial(z[3])-log(z[4]+1)-lfactorial(z[4]+z[3]+1);*/
/*			break;*/
/*		//Alt that all pis are different*/
/*		case 9 :lPDM=log(2.0)+lfactorial(z[0])+lfactorial(z[1])+lfactorial(z[2])+lfactorial(z[3])-log(z[4]+2)-log(z[4]+1)-lfactorial(z[4]+z[3]+1);*/
/*			break;*/
/*	}*/
	int i;
	double z1[5];
	for(i=0;i<5;i++) z1[i]=(double) z[i];
	switch(ind)
	{
		//Null p1=p2=p3=p/3 where p<=p*
		case 0 :lPDM=-z1[4]*log(3.0)-log(pstar)+pbeta(pstar,z1[4]+1,z1[3]+1,1,1)+lbeta(z1[4]+1,z1[3]+1);
			break;
		//Alt that one free pi is different: e.g. p1!=p2=p3 etc. but mutation rate constrained to be <= p*
		case 1 :lPDM=-(z[1]+z[2])*log(2.0)+lfactorial(z[0])+lfactorial(z[1]+z[2])-lfactorial(z[4]+1)-log(pstar)+pbeta(pstar,z1[4]+1,z1[3]+1,1,1)+lbeta(z1[4]+1,z1[3]+1);
			break;
		case 2 :lPDM=-(z[0]+z[2])*log(2.0)+lfactorial(z[1])+lfactorial(z[0]+z[2])-lfactorial(z[4]+1)-log(pstar)+pbeta(pstar,z1[4]+1,z1[3]+1,1,1)+lbeta(z1[4]+1,z1[3]+1);
			break;
		case 3 :lPDM=-(z[0]+z[1])*log(2.0)+lfactorial(z[2])+lfactorial(z[0]+z[1])-lfactorial(z[4]+1)-log(pstar)+pbeta(pstar,z1[4]+1,z1[3]+1,1,1)+lbeta(z1[4]+1,z1[3]+1);
			break;
		//Alt that all pis are different but mutation rate constrained to be <= p*
		case 4 :lPDM=log(2.0)+lfactorial(z[0])+lfactorial(z[1])+lfactorial(z[2])-lfactorial(z[4]+2)-log(pstar)+pbeta(pstar,z1[4]+1,z1[3]+1,1,1)+lbeta(z1[4]+1,z1[3]+1);
			break;
		//Alt p1=p2=p3=p/3 where p>p*
		case 5 :lPDM=-z1[4]*log(3.0)-log(1.0-pstar)+pbeta(pstar,z1[4]+1,z1[3]+1,0,1)+lbeta(z1[4]+1,z1[3]+1);
			break;
		//Alt that one free pi is different: e.g. p1!=p2=p3 etc. but mutation rate constrained to be > p*
		case 6 :lPDM=-(z[1]+z[2])*log(2.0)+lfactorial(z[0])+lfactorial(z[1]+z[2])-lfactorial(z[4]+1)-log(1.0-pstar)+pbeta(pstar,z1[4]+1,z1[3]+1,0,1)+lbeta(z1[4]+1,z1[3]+1);
			break;
		case 7 :lPDM=-(z[0]+z[2])*log(2.0)+lfactorial(z[1])+lfactorial(z[0]+z[2])-lfactorial(z[4]+1)-log(1.0-pstar)+pbeta(pstar,z1[4]+1,z1[3]+1,0,1)+lbeta(z1[4]+1,z1[3]+1);
			break;
		case 8 :lPDM=-(z[0]+z[1])*log(2.0)+lfactorial(z[2])+lfactorial(z[0]+z[1])-lfactorial(z[4]+1)-log(1.0-pstar)+pbeta(pstar,z1[4]+1,z1[3]+1,0,1)+lbeta(z1[4]+1,z1[3]+1);
			break;
		//Alt that all pis are different but mutation rate constrained to be > p*
		case 9 :lPDM=log(2.0)+lfactorial(z[0])+lfactorial(z[1])+lfactorial(z[2])-lfactorial(z[4]+2)-log(1.0-pstar)+pbeta(pstar,z1[4]+1,z1[3]+1,0,1)+lbeta(z1[4]+1,z1[3]+1);
			break;
	}
	return lPDM;
}
Example #18
0
double qbeta(double alpha, double p, double q, int lower_tail, int log_p)
{
    int swap_tail, i_pb, i_inn;
    double a, adj, logbeta, g, h, pp, p_, prev, qq, r, s, t, tx, w, y, yprev;
    double acu;
    volatile double xinbta;

    /* test for admissibility of parameters */

    if (isnan(p) || isnan(q) || isnan(alpha)){
        return p + q + alpha;
    }

    if(p < 0. || q < 0.){
      report_error("shape parameters for qbeta must be > 0.");
    }

    R_Q_P01_boundaries(alpha, 0, 1);

    p_ = R_DT_qIv(alpha);/* lower_tail prob (in any case) */

    if(log_p && (p_ == 0. || p_ == 1.))
        return p_; /* better than NaN or infinite loop;
                      FIXME: suboptimal, since -Inf < alpha ! */

    /* initialize */
    logbeta = lbeta(p, q);

    /* change tail if necessary;  afterwards   0 < a <= 1/2      */
    if (p_ <= 0.5) {
        a = p_; pp = p; qq = q; swap_tail = 0;
    } else { /* change tail, swap  p <-> q :*/
        a = (!lower_tail && !log_p)? alpha : 1 - p_;
        pp = q; qq = p; swap_tail = 1;
    }

    /* calculate the initial approximation */

    /* y := {fast approximation of} qnorm(1 - a) :*/
    r = sqrt(-2 * log(a));
    y = r - (const1 + const2 * r) / (1. + (const3 + const4 * r) * r);
    if (pp > 1 && qq > 1) {
        r = (y * y - 3.) / 6.;
        s = 1. / (pp + pp - 1.);
        t = 1. / (qq + qq - 1.);
        h = 2. / (s + t);
        w = y * sqrt(h + r) / h - (t - s) * (r + 5. / 6. - 2. / (3. * h));
        xinbta = pp / (pp + qq * exp(w + w));
    } else {
        r = qq + qq;
        t = 1. / (9. * qq);
        t = r * pow(1. - t + y * sqrt(t), 3.0);
        if (t <= 0.)
            xinbta = 1. - exp((log1p(-a)+ log(qq) + logbeta) / qq);
        else {
            t = (4. * pp + r - 2.) / t;
            if (t <= 1.)
                xinbta = exp((log(a * pp) + logbeta) / pp);
            else
                xinbta = 1. - 2. / (t + 1.);
        }
    }

    /* solve for x by a modified newton-raphson method, */
    /* using the function pbeta_raw */

    r = 1 - pp;
    t = 1 - qq;
    yprev = 0.;
    adj = 1;
    /* Sometimes the approximation is negative! */
    if (xinbta < lower)
        xinbta = 0.5;
    else if (xinbta > upper)
        xinbta = 0.5;

    /* Desired accuracy should depend on  (a,p)
     * This is from Remark .. on AS 109, adapted.
     * However, it's not clear if this is "optimal" for IEEE double prec.

     * acu = std::max<double>(acu_min, pow(10., -25. - 5./(pp * pp) - 1./(a * a)));

     * NEW: 'acu' accuracy NOT for squared adjustment, but simple;
     * ---- i.e.,  "new acu" = sqrt(old acu)

    */
    acu = std::max<double>(acu_min, pow(10., -13 - 2.5/(pp * pp) - 0.5/(a * a)));
    tx = prev = 0.;     /* keep -Wall happy */

    for (i_pb=0; i_pb < 1000; i_pb++) {
        y = pbeta_raw(xinbta, pp, qq, /*lower_tail = */ true, false);
        if(!std::isfinite(y)){
          report_error("algorithm blew up ni qbeta");
        }

        y = (y - a) *
            exp(logbeta + r * log(xinbta) + t * log1p(-xinbta));
        if (y * yprev <= 0.)
            prev = std::max<double>(fabs(adj),fpu);
        g = 1;
        for (i_inn=0; i_inn < 1000;i_inn++) {
            adj = g * y;
            if (fabs(adj) < prev) {
                tx = xinbta - adj; /* trial new x */
                if (tx >= 0. && tx <= 1) {
                    if (prev <= acu)    goto L_converged;
                    if (fabs(y) <= acu) goto L_converged;
                    if (tx != 0. && tx != 1)
                        break;
                }
            }
            g /= 3;
        }
        if (fabs(tx - xinbta) < 1e-15*xinbta) goto L_converged;
        xinbta = tx;
        yprev = y;
    }
    /*-- NOT converged: Iteration count --*/
    report_error("algorithm did not converge in qbeta");

L_converged:
    return swap_tail ? 1 - xinbta : xinbta;
}
Example #19
0
/***** ***************************************************************************************** *****/
void
RJMCMCcombine(int* accept,           double* log_AR,
              int* K,                double* w,             double* logw,           double* mu,    
              double* Q,             double* Li,            double* Sigma,          double* log_dets,  
              int* order,            int* rank,             int* r,                 int* mixN,         int** rInv,
              double* u,             double* P,             double* log_dens_u,                  
              double* dwork,         int* iwork,            int* err,
              const double* y,          const int* p,                     const int* n,
              const int* Kmax,          const double* logK,               const double* log_lambda,  const int* priorK,
              const double* logPsplit,  const double* logPcombine,        const double* delta,  
              const double* c,          const double* log_c,              const double* xi,          const double* D_Li,               const double* log_dets_D,
              const double* zeta,       const double* log_Wishart_const,  const double* gammaInv,    const double* log_sqrt_detXiInv,  
              const int* priormuQ,      const double* pars_dens_u,
              void (*ld_u)(double* log_dens_u,  const double* u,  const double* pars_dens_u,  const int* p))
{
  const char *fname = "NMix::RJMCMCcombine";

  *err = 0;
  *accept = 0;
  *log_AR = R_NegInf;

  /*** Array of two zeros to be passed to ldMVN as log_dets to compute only -1/2(x-mu)'Sigma^{-1}(x-mu) ***/
  static const double ZERO_ZERO[2] = {0.0, 0.0};

  /***  Some variables ***/
  static int i0, i1, k, LTp, p_p, ldwork_logJacLambdaVSigma;
  static int jstar, jremove, j1, j2;
  static int rInvPrev;
  static int rankstar;

  static double sqrt_u1_ratio, one_u1, log_u1, log_one_u1, log_u1_one_minus_u1_min32, one_minus_u2sq, erand;
  static double log_Jacob, log_Palloc, log_LikelihoodRatio, log_PriorRatio, log_ProposalRatio;
  static double log_phi1, log_phi2, log_phistar, Prob_r1, Prob_r2, log_Prob_r1, log_Prob_r2, max_log_Prob_r12, sum_Prob_r12;
  static double mu1_vstar, mu2_vstar, mustar_vstar;

  /*** Some pointers ***/
  static double *w1, *w2, *logw1, *logw2, *mu1, *mu2, *Sigma1, *Sigma2, *Li1, *Li2, *Q1, *Q2, *log_dets1, *log_dets2;
  static int *mixN1, *mixN2, *rInv1, *rInv2;
  static int **rrInv1, **rrInv2;

  static double *wOldP, *logwOldP, *muOldP, *SigmaOldP, *LiOldP, *QOldP, *log_detsOldP;
  static double *Listar;
  static int *mixNOldP;  
  static int **rrInvOldP;
  static const double *muNewP, *SigmaNewP, *QNewP;

  static const double *mu1P, *mu2P;
  static const double *yP;
  static int *rInv1P, *rInv2P, *rInvP;
  static int *rP;

  /*** Declaration for dwork ***/
  static double *mustar, *Sigmastar, *Lambdastar, *Vstar, *Lstar, *Qstar;
  static double *SigmaTemp, *Lambda1, *Lambda2, *V1, *V2, *Lambda_dspev, *V_dspev, *dwork_misc;
  static double *dlambdaV_dSigma, *P_im, *VPinv_re, *VPinv_im, *sqrt_Plambda_re, *sqrt_Plambda_im, *VP_re, *VP_im;

  static double *mustarP, *LambdastarP, *LstarP, *Lambda1P, *Lambda2P, *VstarP, *VP_reP;

  /*** Declaration for iwork ***/
  static int *iwork_misc;

  static int complexP[1];

  /*** Declaration for auxiliary variables ***/
  static double *u1, *u2, *u3;
  static double *u2P, *u3P;

  /*** Declaration for other mixture related variables ***/
  static double wstar[1];                       /** weight of the new combined component                                                         **/
  static double logwstar[1];                    /** log(weight) of the new combined component                                                    **/
  static double log_detsstar[2];                /** Like log_dets, related to the new combined component                                         **/ 
  static double logJ_part3[1];                  /** the third part of the log-Jacobian                                                           **/
  //static double log_dlambdaV_dSigma[1];         /** logarithm of |d(Lambdastar,Vstar)/d(Sigmastar)|                                              **/
  static double logL12[2];                      /** logL12[0] = sum_{i=0}^{mixN1} log(phi(y_i | mu_{r_i}, Sigma_{r_i})) + sum_{i=0}^{mixN2}...   **/
                                                /** logL12[1] = sum_{i=0}^{mixN1} log(P(r = r_i | w, K)) + sum_{i=0}^{mixN2} ...                 **/
                                                /** for observations allocated to the combined components, state before reallocation             **/
  static double logLstar[2];                    /** the same as above, state after reallocation                                                  **/
  static double log_prior_mu1[1];               /** logarithm of the prior of mu1 (first splitted component)                                     **/
  static double log_prior_mu2[1];               /** logarithm of the prior of mu2 (second splitted component)                                    **/
  static double log_prior_mustar[1];            /** logarithm of the prior of mu(star) (splitted component)                                      **/
  static double log_prior_Q1[1];                /** logarithm of the prior of Q1 = Sigma1^{-1} (first splitted component)                        **/
  static double log_prior_Q2[1];                /** logarithm of the prior of Q2 = Sigma2^{-1} (first splitted component)                        **/
  static double log_prior_Qstar[1];             /** logarithm of the prior of Q(star) = Sigma(star)^{-1} (splitted component)                    **/
  static int mixNstar[1];                       /** numbers of allocated observations in the new combined component                              **/

  if (*K == 1) return;

  LTp = (*p * (*p + 1))/2;
  p_p = *p * *p;
  ldwork_logJacLambdaVSigma = *p * LTp + (4 + 2 * *p) * *p;

  /*** Components of dwork ***/
  mustar          = dwork;                       /** mean vector of the new combined component                                                  **/
  Sigmastar       = mustar + *p;                 /** covariance matrix of the new combined component                                            **/
  Lambdastar      = Sigmastar + LTp;             /** eigenvalues of the new combined component                                                  **/
  Vstar           = Lambdastar + *p;             /** eigenvectors of the new combined component                                                 **/
  Lstar           = Vstar + p_p;                 /** Cholesky decomposition of Sigmastar                                                        **/
  Qstar           = Lstar + LTp;                 /** inversion of Sigmastar                                                                     **/
  SigmaTemp       = Qstar + LTp;                 /** Sigma1 and Sigma2 passed to dspev which overwrites it during the decomposition             **/
  Lambda1         = Sigmastar + LTp;             /** eigenvalues of the first component to be combined                                          **/
  Lambda2         = Lambda1 + *p;                /** eigenvalues of the second component to be combined                                         **/  
  V1              = Lambda2 + *p;                /** eigenvectors of the first component to be combined                                         **/
  V2              = V1 + p_p;                    /** eigenvectors of the second component to be combined                                        **/
  Lambda_dspev    = V2 + p_p;                    /** space to store lambda's computed by dspev (in ascending order)                             **/
  V_dspev         = Lambda_dspev + *p;           /** space to store V computed by dspev                                                         **/
  dwork_misc      = V_dspev + p_p;               /** working array for LAPACK dspev (needs 3*p)                                                 **/
         				         /**                   Dist::ldMVN1, Dist::ldMVN2 (needs p)                                     **/
                                                 /**                   NMix::RJMCMC_logJacLambdaVSigma (needs: see above)                       **/
                                                 /**                   AK_LAPACK::sqrtGE (needs p*p)                                            **/
                                                 /**                   AK_LAPACK::correctMatGE (needs p*p)                                      **/
                                                 /**                   NMix::orderComp (needs at most Kmax)                                     **/
  dlambdaV_dSigma = dwork_misc + ldwork_logJacLambdaVSigma + *Kmax;  
  P_im            = dlambdaV_dSigma + LTp * LTp; /** needed by AK_LAPACK::sqrt_GE                                                               **/
  VPinv_re        = P_im + p_p;                  /** needed by AK_LAPACK::sqrt_GE                                                               **/
  VPinv_im        = VPinv_re + p_p;              /** needed by AK_LAPACK::sqrt_GE                                                               **/
  sqrt_Plambda_re = VPinv_im + p_p;              /** needed by AK_LAPACK::sqrt_GE                                                               **/
  sqrt_Plambda_im = sqrt_Plambda_re + *p;        /** needed by AK_LAPACK::sqrt_GE                                                               **/
  VP_re           = sqrt_Plambda_im + *p;        /** needed by AK_LAPACK::sqrt_GE                                                               **/
  VP_im           = VP_re + p_p;                 /** needed by AK_LAPACK::sqrt_GE                                                               **/
  // next       = VP_im + p_p;

  /*** Components of iwork ***/
  iwork_misc = iwork;                   /** working array for NMix::RJMCMC_logJacLambdaVSigma (needs p)                   **/
                                        /**                   Rand::RotationMatrix (needs p)                              **/
                                        /**                   AK_LAPACK::sqrtGE (needs p)                                 **/
                                        /**                   AK_LAPACK::correctMatGE (needs p)                           **/
  // next   = iwork_misc + *p;

  /***** Pointers for auxiliary vector u *****/
  /***** =============================== *****/
  u1 = u;
  u2 = u1 + 1;
  u3 = u2 + *p;
  

  /***** Choose the components to be splitted *****/
  /***** ==================================== *****/

  // TEMPORAR? For p > 1, a pair is sampled from all pairs,
  //           for p = 1, a pair of "adjacent components" is sampled
  if (*p > 1){

    // ===== Code for the situation when a pair is sampled from all pairs ===== //
    Rand::SamplePair(&j1, &j2, K);       // generates a pair (j1, j2) where j1 < j2
  }

  else{
    // ===== Code for the situation when j1 is sampled from K-1 components with the "smallest" mean  ===== //
    // ===== and j2 is the adjacent component with just a "higher" mean                              ===== //
    // ===== For a definition of ordering see NMix::orderComp function                               ===== //
    rankstar = (int)(floor(unif_rand() * (*K - 1)));  
    if (rankstar == *K - 1) jstar = *K - 2;                     // this row is needed with pobability 0 (unif_rand() would have to return 1)
    j1 = order[rankstar];
    j2 = order[rankstar + 1];
  }

  // ===== Code for the situation similar to the Matlab code of I. Papageorgiou ===== //
  //j1 = (int)(floor(unif_rand() * (*K - 1)));      // This way is used in the Matlab code of I. Papageorgiou,
  //if (j1 == *K - 1) j1 = *K - 2;                  // i.e., j1 is sampled from Unif(0,...,K-2)
  //j2      = *K - 1;                               // I have no idea why in this way...  

  /*** Pointers to chosen components ***/
  w1        = w  + j1;
  w2        = w1 + (j2 - j1);
  logw1     = logw  + j1;
  logw2     = logw1 + (j2 - j1);
  mu1       = mu + j1 * *p;
  mu2       = mu1 + (j2 - j1) * *p;
  Sigma1    = Sigma  + j1 * LTp;
  Sigma2    = Sigma1 + (j2 - j1) * LTp;
  Li1       = Li  + j1 * LTp;
  Li2       = Li1 + (j2 - j1) * LTp;
  Q1        = Q  + j1 * LTp;
  Q2        = Q1 + (j2 - j1) * LTp;
  log_dets1 = log_dets  + j1 * 2;
  log_dets2 = log_dets1 + (j2 - j1) * 2;
  rrInv1    = rInv + j1;
  rrInv2    = rrInv1 + (j2 - j1);
  rInv1     = *rrInv1;
  rInv2     = *rrInv2;
  mixN1     = mixN  + j1;
  mixN2     = mixN1 + (j2 - j1);

  /*** Pointers to the old places where a new component will be written (if accepted)                                         ***/
  /*** jstar   = index of the place where a new component will be written on the place of one of old components (if accepted) ***/
  /*** jremove = index of the place where an old component will be removed (and the rest will be shifted forward)             ***/
  /*** I will ensure jstar < jremove                                                                                          ***/
  if (j1 < j2){                   
    jstar   = j1;              // combined component will be placed on place with a lower index if combine move accepted
    jremove = j2;              // component with a higher index will be removed if combine move accepted

    wOldP        = w1;         // places where a new component will be written
    logwOldP     = logw1;
    muOldP       = mu1;
    SigmaOldP    = Sigma1;
    LiOldP       = Li1;
    QOldP        = Q1;
    log_detsOldP = log_dets1;
    rrInvOldP    = rrInv1;
    mixNOldP     = mixN1;  
  }
  else{
    jstar   = j2;
    jremove = j1;

    wOldP        = w2;         // places where a new component will be written
    logwOldP     = logw2;
    muOldP       = mu2;
    SigmaOldP    = Sigma2;
    LiOldP       = Li2;
    QOldP        = Q2;
    log_detsOldP = log_dets2;
    rrInvOldP    = rrInv2;
    mixNOldP     = mixN2;  
  }


  /***** Compute proposed weight, mean, variance and log-Jacobian of the RJ (split) move *****/
  /***** =============================================================================== *****/

  /***** Proposed weight *****/
  *wstar = *w1 + *w2;
  *logwstar = AK_Basic::log_AK(wstar[0]);
  *u1 = *w1 / *wstar;
  one_u1 = 1 - *u1;

  /***** Log-Jacobian, part 1                                                          *****/
  /***** Jacobian = dtheta/dtheta^*, that is corresponds to the reversal split move    *****/
  log_Jacob = *logwstar;

  /***** Code for UNIVARIATE mixtures *****/
  if (*p == 1){          /*** UNIVARIATE mixture             ***/               

    /***** Check inequality condition which is satisfied by the reversal split move *****/
    /***** This will ensure that u2 is positive                                     *****/
    // ===== The following code is needed only when (j1, j2) is sampled from a set of all pairs and hence there is no guarantee ===== //
    // ===== that mu1 <= mu2                                                                                                    ===== //
    //if (*mu1 > *mu2){             // switch labels j1, j2 such that mu1 < mu2 to get correctly u1, u2 and u3
    //  AK_Basic::switchValues(&j1, &j2);
    //  *u1    = one_u1;
    //  one_u1 = 1 - *u1;
    //  AK_Basic::switchPointers(&w1,        &w2);
    //  AK_Basic::switchPointers(&logw1,     &logw2);
    //  AK_Basic::switchPointers(&mu1,       &mu2);
    //  AK_Basic::switchPointers(&Sigma1,    &Sigma2);
    //  AK_Basic::switchPointers(&Li1,       &Li2);
    //  AK_Basic::switchPointers(&Q1,        &Q2);
    //  AK_Basic::switchPointers(&log_dets1, &log_dets2);
    //  AK_Basic::switchPointers(&rInv1,     &rInv2);
    //  AK_Basic::switchPointers(&mixN1,     &mixN2);
    //}

    /***** Values derived from the auxiliary number u1 corresponding to the reversal split move *****/
    sqrt_u1_ratio             = sqrt(*u1 / (1 - *u1));
    log_u1                    = AK_Basic::log_AK(*u1);
    log_one_u1                = AK_Basic::log_AK(1 - *u1);
    log_u1_one_minus_u1_min32 = -1.5 * (log_u1+ log_one_u1);

    /***** Proposed mean:   mustar = u1 * mu1 + (1 - u1) * mu2 *****/
    *mustar = *u1 * *mu1 + one_u1 * *mu2;

    /***** Proposed variance *****/
    *Sigmastar = *u1 * (*mu1 * *mu1 + *Sigma1) + one_u1 * (*mu2 * *mu2 + *Sigma2) - *mustar * *mustar;
    if (*Sigmastar <= 0) return;
    
    /***** Cholesky decomposition of the proposed variance (standard deviation) *****/
    *Lstar = sqrt(*Sigmastar);

    /***** Inverted proposed variance *****/
    *Qstar = 1 / *Sigmastar;

    /***** Auxiliary numbers u2 and u3 correspoding to the reversal split move *****/
    *u2 = ((*mustar - *mu1) / *Lstar) * sqrt_u1_ratio;
    one_minus_u2sq = 1 - *u2 * *u2;

    *u3 = (*u1 * *Sigma1) / (one_minus_u2sq * *Sigmastar);

    /***** Log-Jacobian, part 2 *****/
    log_Jacob += AK_Basic::log_AK(one_minus_u2sq * *Sigmastar * *Lstar) + log_u1_one_minus_u1_min32;

    /***** log|d(Lambdastar,Vstar)/d(Sigmastar)|*****/             // NOT NEEDED AS IT IS ZERO,  moreover, 25/01/2008:  included in logJ_part3
    //*log_dlambdaV_dSigma = 0.0;

    /***** Log-Jacobian, part 3 *****/                             // NOT NEEDED AS IT IS ZERO
    //*logJ_part3 = 0.0;    
    //log_Jacob += *logJ_part3;

    /***** log-dets for the proposed variance *****/
    log_detsstar[0] = -AK_Basic::log_AK(*Lstar);        /** log_detsstar[0] = -log(Lstar) = log|Sigmastar|^{-1/2}  **/
    log_detsstar[1] = log_dets1[1];                        /** log_detsstar[1] = -p * log(sqrt(2*pi))                 **/
  }

  else{                  /*** MULTIVARIATE mixture                                      ***/

    /***** Values derived from the auxiliary number u1 corresponding to the reversal split move *****/
    sqrt_u1_ratio             = sqrt(*u1 / (1 - *u1));
    log_u1                    = AK_Basic::log_AK(*u1);
    log_one_u1                = AK_Basic::log_AK(1 - *u1);
    log_u1_one_minus_u1_min32 = -1.5 * (log_u1+ log_one_u1);

    /***** Spectral decomposition of Sigma1 *****/
    AK_Basic::copyArray(SigmaTemp, Sigma1, LTp);
    F77_CALL(dspev)("V", "L", p, SigmaTemp, Lambda_dspev, V_dspev, p, dwork_misc, err);    /** eigen values in ascending order  **/
    if (*err){
      warning("%s: Spectral decomposition of Sigma[%d] failed.\n", fname, j1);    
      return;
    }
    //AK_LAPACK::spevAsc2spevDesc(Lambda1, V1, Lambda_dspev, V_dspev, p);                  /** eigen values in descending order **/
    // 05/02/2008:  CHANGE - eigenvalues are assumed to be in ASCENDING order
    AK_LAPACK::correctMatGE(V1, dwork_misc, iwork_misc, err, p);                           /** be sure that det(V1) = 1 and not -1 **/
    if (*err){
      warning("%s: Correction of V[%d] failed.\n", fname, j1);    
      return;
    }

    /***** Spectral decomposition of Sigma2 *****/
    AK_Basic::copyArray(SigmaTemp, Sigma2, LTp);
    F77_CALL(dspev)("V", "L", p, SigmaTemp, Lambda_dspev, V_dspev, p, dwork_misc, err);    /** eigen values in ascending order  **/
    if (*err){
      warning("%s: Spectral decomposition of Sigma[%d] failed.\n", fname, j2);    
      return;
    }
    //AK_LAPACK::spevAsc2spevDesc(Lambda2, V2, Lambda_dspev, V_dspev, p);                    /** eigen values in descending order **/
    // 05/02/2008:  CHANGE - eigenvalues are assumed to be in ASCENDING order
    AK_LAPACK::correctMatGE(V2, dwork_misc, iwork_misc, err, p);                             /** be sure that det(V2) = 1 and not -1 **/
    if (*err){
      warning("%s: Correction of V[%d] failed.\n", fname, j2);    
      return;
    }

    /***** Rotation matrix which corresponds to the reversible split move, P = (V1 %*% t(V2))^{1/2} *****/
    F77_CALL(dgemm)("N", "T", p, p, p, &AK_Basic::_ONE_DOUBLE, V1, p, V2, p, &AK_Basic::_ZERO_DOUBLE, P, p);       /*** P = V1 %*% t(V2) ***/
    AK_LAPACK::sqrtGE(P, P_im, VPinv_re, VPinv_im, complexP, sqrt_Plambda_re, sqrt_Plambda_im, VP_re, VP_im, dwork_misc, iwork_misc, err, p);
    if (*err){
      warning("%s: Computation of the square root of the rotation matrix failed.\n", fname);    
      return;
    }

    /***** Proposed eigenvectors:   Vstar = (1/2) * (t(P) %*% V1 + P %*% V2) *****/
    F77_CALL(dgemm)("T", "N", p, p, p, &AK_Basic::_ONE_DOUBLE, P, p, V1, p, &AK_Basic::_ZERO_DOUBLE, VP_re, p);       /*** VP_re = t(P) %*% V1  ***/
    F77_CALL(dgemm)("N", "N", p, p, p, &AK_Basic::_ONE_DOUBLE, P, p, V2, p, &AK_Basic::_ZERO_DOUBLE, Vstar, p);       /*** Vstar = P %*% V2     ***/

    /***** Proposed mean:  mustar = u1*mu1 + (1 - u1)*mu2                                          *****/
    /***** Finalize computation of Vstar (sum t(P) %*% V1 and P %*% V2 and multiply it by 0.5)     *****/
    mu1P    = mu1;
    mu2P    = mu2;
    mustarP = mustar;

    VstarP = Vstar;
    VP_reP = VP_re;

    for (i1 = 0; i1 < *p; i1++){
      *mustarP = *u1 * *mu1P + one_u1 * *mu2P;
      mu1P++;
      mu2P++;
      mustarP++;

      for (i0 = 0; i0 < *p; i0++){
        *VstarP += *VP_reP;
        *VstarP *= 0.5;
        VstarP++;
        VP_reP++;
      }
    }

    /***** Proposed eigenvalues                                                                                                *****/    
    /***** Auxiliary numbers u2 and u3 correspoding to the reversal split move                                                 *****/
    /***** Log-Jacobian, part 2                                                                                                *****/
    /***** Check also the adjacency condition from the reversal split move -> u2[p-1] must be positive                         *****/
    /****** -> if not satisfied, take abs(u2[p-1]) -> this should be equivalent to labelswitching which is then not necessary  *****/
    LambdastarP = Lambdastar;
    u2P         = u2;
    u3P         = u3;

    Lambda1P    = Lambda1;
    Lambda2P    = Lambda2;
    VstarP      = Vstar;

    for (i1 = 0; i1 < *p; i1++){
      mu1_vstar    = 0.0;
      mu2_vstar    = 0.0;
      mustar_vstar = 0.0;

      mu1P    = mu1;
      mu2P    = mu2;
      mustarP = mustar;
      
      for (i0 = 0; i0 < *p; i0++){
        mu1_vstar    += *mu1P * *VstarP;
        mu2_vstar    += *mu2P * *VstarP;
        mustar_vstar += *mustarP * *VstarP;
   
        mu1P++;
        mu2P++;
        mustarP++;
        VstarP++;
      }

      *LambdastarP = *u1 * (mu1_vstar * mu1_vstar + *Lambda1P) + one_u1 * (mu2_vstar * mu2_vstar + *Lambda2P) - mustar_vstar * mustar_vstar;
      if (*LambdastarP <= 0){
        return;
      }

      *u2P = ((mustar_vstar - mu1_vstar) / sqrt(*LambdastarP)) * sqrt_u1_ratio;
      if (i1 == *p - 1 && *u2P <= 0) *u2P *= (-1);
      one_minus_u2sq = 1 - *u2P * *u2P;
      *u3P = (*u1 * *Lambda1P) / (one_minus_u2sq * *LambdastarP);
      log_Jacob += 1.5 * AK_Basic::log_AK(*LambdastarP) + AK_Basic::log_AK(one_minus_u2sq);

      LambdastarP++;
      Lambda1P++;
      Lambda2P++;
      u2P++;
      u3P++;
    }
    log_Jacob += *p * log_u1_one_minus_u1_min32;

    /***** Proposed variance *****/
    AK_LAPACK::spevSY2SP(Sigmastar, Lambdastar, Vstar, p);

    /***** Cholesky decomposition of the proposed variance *****/
    AK_Basic::copyArray(Lstar, Sigmastar, LTp);
    F77_CALL(dpptrf)("L", p, Lstar, err);
    if (*err){ 
      warning("%s: Cholesky decomposition of proposed Sigmastar failed.\n", fname);    
      return;
    }

    /***** Inverted proposed variance *****/
    AK_Basic::copyArray(Qstar, Lstar, LTp);
    F77_CALL(dpptri)("L", p, Qstar, err);
    if (*err){
      warning("%s: Inversion of proposed Sigmastar failed.\n", fname);    
      return;
    }

    /***** log-dets for the proposed variance *****/
    log_detsstar[0] = 0.0;
    LstarP = Lstar;
    for (i0 = *p; i0 > 0; i0--){                       /** log_detsstar[0] = -sum(log(Lstar[i,i])) **/
      log_detsstar[0] -= AK_Basic::log_AK(*LstarP);
      LstarP += i0;
    }
    log_detsstar[1] = log_dets1[1];                    /** log_detsstar[1] = -p * log(sqrt(2*pi)) **/

    /***** log|d(Lambdastar,Vstar)/d(Sigmastar)|*****/        // 25/01/2008:  this part included in NMix::RJMCMC_logJac_part3
    //NMix::RJMCMC_logJacLambdaVSigma(log_dlambdaV_dSigma, dlambdaV_dSigma, dwork_misc, iwork_misc, err,
    //                                Lambdastar, Vstar, Sigmastar, p, &AK_Basic::_ZERO_INT);
    //if (*err){ 
    //  warning("%s: RJMCMC_logJacLambdaVSigma failed.\n", fname);    
    //  return;
    //}

    /***** Log-Jacobian, part 3                                *****/
    NMix::RJMCMC_logJac_part3(logJ_part3, Lambdastar, Vstar, P, p);
    log_Jacob += *logJ_part3;
  }                      /*** end of the code for a MULTIVARIATE mixture ***/

  /***** Log-density of the auxiliary vector *****/
  /***** =================================== *****/
  ld_u(log_dens_u, u, pars_dens_u, p);


  /***** Propose new allocations              *****/
  /***** Compute logarithm of reversal Palloc *****/
  /***** ==================================== *****/
  log_Palloc  = 0.0;                 /** to compute sum[i: r[i]=j1] log P(r[i]=j1|...) + sum[i: r[i]=j2] log P(r[i]=j2|...)    **/
  logL12[0]   = 0.0;                 /** to sum up log_phi for observations in the original two components                     **/
  logLstar[0] = 0.0;                 /** to sum up log_phi for observations belonging to the new combined component            **/

  *mixNstar = *mixN1 + *mixN2;

  /*** Loop for component j1 ***/
  yP            = y;                          /** all observations **/
  rInv1P        = rInv1;
  rInvPrev      = 0;
  for (i0 = 0; i0 < *mixN1; i0++){
    yP            += (*rInv1P - rInvPrev) * *p;

    /*** log(phi(y | mu1, Sigma1)), log(phi(y | mu2, Sigma2)), log(phi(y | mustar, Sigmastar)) ***/  
    Dist::ldMVN1(&log_phi1,    dwork_misc, yP, mu1,    Li1,   log_dets1,    p);
    Dist::ldMVN1(&log_phi2,    dwork_misc, yP, mu2,    Li2,   log_dets2,    p);
    Dist::ldMVN2(&log_phistar, dwork_misc, yP, mustar, Lstar, log_detsstar, p);

    /*** Probabilities of the full conditional of r (to compute log_Palloc of the reversal split move) ***/
    log_Prob_r1  = log_phi1 + *logw1;
    log_Prob_r2  = log_phi2 + *logw2;    
    max_log_Prob_r12 = (log_Prob_r1 > log_Prob_r2 ? log_Prob_r1 : log_Prob_r2);
    log_Prob_r1 -= max_log_Prob_r12;
    log_Prob_r2 -= max_log_Prob_r12;
    Prob_r1 = AK_Basic::exp_AK(log_Prob_r1);
    Prob_r2 = AK_Basic::exp_AK(log_Prob_r2);
    sum_Prob_r12 = Prob_r1 + Prob_r2;

    log_Palloc  += log_Prob_r1 - AK_Basic::log_AK(sum_Prob_r12);
    logL12[0]   += log_phi1;
    logLstar[0] += log_phistar;

    rInvPrev = *rInv1P;
    rInv1P++;
  }

  /*** Loop for component j2 ***/
  yP            = y;                          /** all observations **/
  rInv2P        = rInv2;
  rInvPrev      = 0;
  for (i0 = 0; i0 < *mixN2; i0++){
    yP            += (*rInv2P - rInvPrev) * *p;

    /*** log(phi(y | mu1, Sigma1)), log(phi(y | mu2, Sigma2)), log(phi(y | mustar, Sigmastar)) ***/  
    Dist::ldMVN1(&log_phi1,    dwork_misc, yP, mu1,    Li1,   log_dets1,    p);
    Dist::ldMVN1(&log_phi2,    dwork_misc, yP, mu2,    Li2,   log_dets2,    p);
    Dist::ldMVN2(&log_phistar, dwork_misc, yP, mustar, Lstar, log_detsstar, p);

    /*** Probabilities of the full conditional of r (to compute log_Palloc of the reversal split move) ***/
    log_Prob_r1  = log_phi1 + *logw1;
    log_Prob_r2  = log_phi2 + *logw2;    
    max_log_Prob_r12 = (log_Prob_r1 > log_Prob_r2 ? log_Prob_r1 : log_Prob_r2);
    log_Prob_r1 -= max_log_Prob_r12;
    log_Prob_r2 -= max_log_Prob_r12;
    Prob_r1 = AK_Basic::exp_AK(log_Prob_r1);
    Prob_r2 = AK_Basic::exp_AK(log_Prob_r2);
    sum_Prob_r12 = Prob_r1 + Prob_r2;

    log_Palloc  += log_Prob_r2 - AK_Basic::log_AK(sum_Prob_r12);
    logL12[0]   += log_phi2;
    logLstar[0] += log_phistar;

    rInvPrev = *rInv2P;
    rInv2P++;
  }

  logL12[1]   = *mixN1 * *logw1 + *mixN2 * *logw2;
  logLstar[1] = *mixNstar * *logwstar;


  /***** Logarithm of the likelihood ratio (of the reversal split move) *****/
  /***** ============================================================== *****/
  log_LikelihoodRatio = logL12[0] + logL12[1] - logLstar[0] - logLstar[1];


  /***** Logarithm of the prior ratio (of the reversal split move) *****/
  /***** ========================================================= *****/  

  /***** log-ratio of priors on mixture weights *****/
  log_PriorRatio = (*delta - 1) * (*logw1 + *logw2 - *logwstar) - lbeta(*delta, *K * *delta);
  
  /***** log-ratio of priors on K (+ factor comming from the equivalent ways that the components can produce the same likelihood) *****/
  switch (*priorK){
  case NMix::K_FIXED:
  case NMix::K_UNIF:      /*** K * (p(K)/p(K-1)) = K ***/
    log_PriorRatio += logK[*K - 1];
    break;
  case NMix::K_TPOISS:    /*** K * (p(K)/p(K-1)) = K * (lambda/K) = lambda ***/
    log_PriorRatio += *log_lambda;
    break;
  }

  /***** log-ratio of priors on mixture means *****/
  switch (*priormuQ){
  case NMix::MUQ_NC:
    Dist::ldMVN1(log_prior_mu1, dwork_misc, mu1, xi + j1 * *p, Li1, ZERO_ZERO, p);
    *log_prior_mu1 *= c[j1];
    *log_prior_mu1 += log_dets1[0] + log_dets1[1] + (*p * log_c[j1]) / 2;

    Dist::ldMVN1(log_prior_mu2, dwork_misc, mu2, xi + j2 * *p, Li2, ZERO_ZERO, p);
    *log_prior_mu2 *= c[j2];
    *log_prior_mu2 += log_dets2[0] + log_dets2[1] + (*p * log_c[j2]) / 2;

    Dist::ldMVN2(log_prior_mustar, dwork_misc, mustar, xi + jstar * *p, Lstar, ZERO_ZERO, p);
    *log_prior_mustar *= c[jstar];
    *log_prior_mustar += log_detsstar[0] + log_detsstar[1] + (*p * log_c[jstar]) / 2;
    break;

  case NMix::MUQ_IC:
    Dist::ldMVN1(log_prior_mu1,    dwork_misc, mu1,    xi + j1 * *p,    D_Li + j1 * LTp,    log_dets_D + j1 * 2,    p);
    Dist::ldMVN1(log_prior_mu2,    dwork_misc, mu2,    xi + j2 * *p,    D_Li + j2 * LTp,    log_dets_D + j2 * 2,    p);
    Dist::ldMVN1(log_prior_mustar, dwork_misc, mustar, xi + jstar * *p, D_Li + jstar * LTp, log_dets_D + jstar * 2, p);
    break;
  }
  log_PriorRatio += *log_prior_mu1 + *log_prior_mu2 - *log_prior_mustar;

  /***** log-ratio of priors on mixture (inverse) variances *****/
  Dist::ldWishart_diagS(log_prior_Q1,    Q1,    log_dets1,    log_Wishart_const, zeta, gammaInv, log_sqrt_detXiInv, p);
  Dist::ldWishart_diagS(log_prior_Q2,    Q2,    log_dets2,    log_Wishart_const, zeta, gammaInv, log_sqrt_detXiInv, p);
  Dist::ldWishart_diagS(log_prior_Qstar, Qstar, log_detsstar, log_Wishart_const, zeta, gammaInv, log_sqrt_detXiInv, p);
  log_PriorRatio += *log_prior_Q1 + *log_prior_Q2 - *log_prior_Qstar;


  /***** Logarithm of the proposal ratio (of the reversal split move) *****/
  /***** ============================================================ *****/
  log_ProposalRatio = logPcombine[*K - 1] - logPsplit[*K - 2] - log_Palloc - *log_dens_u;


  /***** Accept/reject *****/
  /***** ============= *****/
  *log_AR = -(log_LikelihoodRatio + log_PriorRatio + log_ProposalRatio + log_Jacob);
  if (*log_AR >= 0) *accept = 1;
  else{                           /** decide by sampling from the exponential distribution **/
    erand = exp_rand();
    *accept = (erand > -(*log_AR) ? 1 : 0);
  }


  /***** Update mixture values if proposal accepted *****/
  /***** ========================================== *****/
  // Remember that jstar < jremove (irrespective of values j1 and j2)
  //
  if (*accept){

    /*** r: loop for component j1 ***/
    rP            = r;                           /** all observations               **/
    rInv1P        = rInv1;                       /** observations from component j1 **/
    rInvPrev      = 0;
    for (i0 = 0; i0 < *mixN1; i0++){
      rP  += (*rInv1P - rInvPrev);
      *rP = jstar;

      rInvPrev = *rInv1P;
      rInv1P++;
    }

    /*** r: loop for component j2 ***/
    rP            = r;                           /** all observations               **/
    rInv2P        = rInv2;                       /** observations from component j2 **/
    rInvPrev      = 0;
    for (i0 = 0; i0 < *mixN2; i0++){
      rP  += (*rInv2P - rInvPrev);
      *rP = jstar;

      rInvPrev = *rInv2P;
      rInv2P++;
    }

    /*** w: weights ***/
    *wOldP = *wstar;
    wOldP += (jremove - jstar);           /** jump to the point from which everything must be shifted **/

    /*** logw: log-weights ***/
    *logwOldP = *logwstar;
    logwOldP += (jremove - jstar);        /** jump to the point from which everything must be shifted **/
    
    /*** mu:     means                                                                                           ***/
    /*** Q:      inverse variances                                                                               ***/
    /*** Sigma:  variances                                                                                       ***/
    /*** Li:     Cholesky decomposition of inverse variances, must be computed                                    ***/
    muNewP    = mustar;
    QNewP     = Qstar;
    SigmaNewP = Sigmastar;

    Listar    = LiOldP;
    for (i1 = 0; i1 < *p; i1++){
      *muOldP = *muNewP;
      muOldP++;
      muNewP++;

      for (i0 = i1; i0 < *p; i0++){
        *QOldP  = *QNewP;
        *LiOldP = *QNewP;     /* preparing to calculate Cholesky decomposition */
        QOldP++;
        LiOldP++;
        QNewP++;

        *SigmaOldP = *SigmaNewP;
        SigmaOldP++;
        SigmaNewP++;
      }
    }

    F77_CALL(dpptrf)("L", p, Listar, err);
    if (*err){ 
      error("%s: Cholesky decomposition of proposed Q(star) failed.\n", fname);     // this should never happen
    }

    muOldP    += *p * (jremove - jstar - 1);       /** jump to the point from which everything must be shifted **/
    QOldP     += LTp * (jremove - jstar - 1);      /** jump to the point from which everything must be shifted **/    
    SigmaOldP += LTp * (jremove - jstar - 1);      /** jump to the point from which everything must be shifted **/    
    LiOldP    += LTp * (jremove - jstar - 1);      /** jump to the point from which everything must be shifted **/    

    /*** log_dets ***/
    log_detsOldP[0] = log_detsstar[0];
    log_detsOldP++;
    log_detsOldP += 2 * (jremove - jstar - 1);     /** jump to the point from which everything must be shifted **/        

    /*** mixN ***/
    *mixNOldP = *mixNstar;
    mixNOldP += (jremove - jstar);                 /** jump to the point from which everything must be shifted **/

    /*** rInv ***/
    rInvP = *rrInvOldP;
    rP    = r;
    for (i0 = 0; i0 < *n; i0++){
      if (*rP == jstar){
        *rInvP = i0;
        rInvP++;
      }
      rP++;
    }
    rrInvOldP += (jremove - jstar);                /** jump to the point from which everything must be shifted **/

    /*** Shift forward components after the removed one ***/
    for (k = jremove; k < *K-1; k++){
      *wOldP = *(wOldP + 1);
      wOldP++;

      *logwOldP = *(logwOldP + 1);
      logwOldP++;
 
      for (i1 = 0; i1 < *p; i1++){
        *muOldP = *(muOldP + *p);
        muOldP++;

        for (i0 = i1; i0 < *p; i0++){
          *QOldP = *(QOldP + LTp);
          QOldP++;

          *SigmaOldP = *(SigmaOldP + LTp);
          SigmaOldP++;

          *LiOldP = *(LiOldP + LTp);
          LiOldP++;
        }
      }

      log_detsOldP[0] = log_detsOldP[2];
      log_detsOldP += 2;

      *mixNOldP = *(mixNOldP + 1);
      AK_Basic::copyArray(*rrInvOldP, *(rrInvOldP + 1), *mixNOldP);
      mixNOldP++;
      rrInvOldP++;
    }

    /*** K ***/
    *K -= 1;

    /*** order, rank ***/
    NMix::orderComp(order, rank, dwork_misc, &AK_Basic::_ZERO_INT, K, mu, p);   
  }                /*** end of if (*accept) ***/

  return;
}
Example #20
0
double F77_SUB(lbetaf)(double *a, double *b)
{
	return lbeta(*a, *b);
}
Example #21
0
// Returns both qbeta() and its "mirror" 1-qbeta(). Useful notably when qbeta() ~= 1
attribute_hidden void
qbeta_raw(double alpha, double p, double q, int lower_tail, int log_p,
	  int swap_01, // {TRUE, NA, FALSE}: if NA, algorithm decides swap_tail
	  double log_q_cut, /* if == Inf: return log(qbeta(..));
			       otherwise, if finite: the bound for
			       switching to log(x)-scale; see use_log_x */
	  int n_N,  // number of "unconstrained" Newton steps before switching to constrained
	  double *qb) // = qb[0:1] = { qbeta(), 1 - qbeta() }
{
    Rboolean
	swap_choose = (swap_01 == MLOGICAL_NA),
	swap_tail,
	log_, give_log_q = (log_q_cut == ML_POSINF),
	use_log_x = give_log_q, // or u < log_q_cut  below
	warned = FALSE, add_N_step = TRUE;
    int i_pb, i_inn;
    double a, la, logbeta, g, h, pp, p_, qq, r, s, t, w, y = -1.;
    volatile double u, xinbta;

    // Assuming p >= 0, q >= 0  here ...

    // Deal with boundary cases here:
    if(alpha == R_DT_0) {
#define return_q_0						\
	if(give_log_q) { qb[0] = ML_NEGINF; qb[1] = 0; }	\
	else {           qb[0] = 0;         qb[1] = 1; }	\
	return

	return_q_0;
    }
    if(alpha == R_DT_1) {
#define return_q_1						\
	if(give_log_q) { qb[0] = 0; qb[1] = ML_NEGINF; }	\
	else {           qb[0] = 1; qb[1] = 0;         }	\
	return

	return_q_1;
    }

    // check alpha {*before* transformation which may all accuracy}:
    if((log_p && alpha > 0) ||
       (!log_p && (alpha < 0 || alpha > 1))) { // alpha is outside
	R_ifDEBUG_printf("qbeta(alpha=%g, %g, %g, .., log_p=%d): %s%s\n",
			 alpha, p,q, log_p, "alpha not in ",
			 log_p ? "[-Inf, 0]" : "[0,1]");
	// ML_ERR_return_NAN :
	ML_ERROR(ME_DOMAIN, "");
	qb[0] = qb[1] = ML_NAN; return;
    }

    //  p==0, q==0, p = Inf, q = Inf  <==> treat as one- or two-point mass
    if(p == 0 || q == 0 || !R_FINITE(p) || !R_FINITE(q)) {
	// We know 0 < T(alpha) < 1 : pbeta() is constant and trivial in {0, 1/2, 1}
	R_ifDEBUG_printf(
	    "qbeta(%g, %g, %g, lower_t=%d, log_p=%d): (p,q)-boundary: trivial\n",
	    alpha, p,q, lower_tail, log_p);
	if(p == 0 && q == 0) { // point mass 1/2 at each of {0,1} :
	    if(alpha < R_D_half) { return_q_0; }
	    if(alpha > R_D_half) { return_q_1; }
	    // else:  alpha == "1/2"
#define return_q_half					\
	    if(give_log_q) qb[0] = qb[1] = -M_LN2;	\
	    else	   qb[0] = qb[1] = 0.5;		\
	    return

	    return_q_half;
	} else if (p == 0 || p/q == 0) { // point mass 1 at 0 - "flipped around"
	    return_q_0;
	} else if (q == 0 || q/p == 0) { // point mass 1 at 0 - "flipped around"
	    return_q_1;
	}
	// else:  p = q = Inf : point mass 1 at 1/2
	return_q_half;
    }

    /* initialize */
    p_ = R_DT_qIv(alpha);/* lower_tail prob (in any case) */
    // Conceptually,  0 < p_ < 1  (but can be 0 or 1 because of cancellation!)
    logbeta = lbeta(p, q);

    swap_tail = (swap_choose) ? (p_ > 0.5) : swap_01;
    // change tail; default (swap_01 = NA): afterwards 0 < a <= 1/2
    if(swap_tail) { /* change tail, swap  p <-> q :*/
	a = R_DT_CIv(alpha); // = 1 - p_ < 1/2
	/* la := log(a), but without numerical cancellation: */
	la = R_DT_Clog(alpha);
	pp = q; qq = p;
    }
    else {
	a = p_;
	la = R_DT_log(alpha);
	pp = p; qq = q;
    }

    /* calculate the initial approximation */

    /* Desired accuracy for Newton iterations (below) should depend on  (a,p)
     * This is from Remark .. on AS 109, adapted.
     * However, it's not clear if this is "optimal" for IEEE double prec.

     * acu = fmax2(acu_min, pow(10., -25. - 5./(pp * pp) - 1./(a * a)));

     * NEW: 'acu' accuracy NOT for squared adjustment, but simple;
     * ---- i.e.,  "new acu" = sqrt(old acu)
    */
    double acu = fmax2(acu_min, pow(10., -13. - 2.5/(pp * pp) - 0.5/(a * a)));
    // try to catch  "extreme left tail" early
    double tx, u0 = (la + log(pp) + logbeta) / pp; // = log(x_0)
    static const double
	log_eps_c = M_LN2 * (1. - DBL_MANT_DIG);// = log(DBL_EPSILON) = -36.04..
    r = pp*(1.-qq)/(pp+1.);

    t = 0.2;
    // FIXME: Factor 0.2 is a bit arbitrary;  '1' is clearly much too much.

    R_ifDEBUG_printf(
	"qbeta(%g, %g, %g, lower_t=%d, log_p=%d):%s\n"
	"  swap_tail=%d, la=%g, u0=%g (bnd: %g (%g)) ",
	alpha, p,q, lower_tail, log_p,
	(log_p && (p_ == 0. || p_ == 1.)) ? (p_==0.?" p_=0":" p_=1") : "",
	swap_tail, la, u0,
	(t*log_eps_c - log(fabs(pp*(1.-qq)*(2.-qq)/(2.*(pp+2.)))))/2.,
	 t*log_eps_c - log(fabs(r))
	);

    if(M_LN2 * DBL_MIN_EXP < u0 && // cannot allow exp(u0) = 0 ==> exp(u1) = exp(u0) = 0
       u0 < -0.01 && // (must: u0 < 0, but too close to 0 <==> x = exp(u0) = 0.99..)
       // qq <= 2 && // <--- "arbitrary"
       // u0 <  t*log_eps_c - log(fabs(r)) &&
       u0 < (t*log_eps_c - log(fabs(pp*(1.-qq)*(2.-qq)/(2.*(pp+2.)))))/2.)
    {
// TODO: maybe jump here from below, when initial u "fails" ?
// L_tail_u:
	// MM's one-step correction (cheaper than 1 Newton!)
	r = r*exp(u0);// = r*x0
	if(r > -1.) {
	    u = u0 - log1p(r)/pp;
	    R_ifDEBUG_printf("u1-u0=%9.3g --> choosing u = u1\n", u-u0);
	} else {
	    u = u0;
	    R_ifDEBUG_printf("cannot cheaply improve u0\n");
	}
	tx = xinbta = exp(u);
	use_log_x = TRUE; // or (u < log_q_cut)  ??
	goto L_Newton;
    }

    // y := y_\alpha in AS 64 := Hastings(1955) approximation of qnorm(1 - a) :
    r = sqrt(-2 * la);
    y = r - (const1 + const2 * r) / (1. + (const3 + const4 * r) * r);

    if (pp > 1 && qq > 1) { // use  Carter(1947), see AS 109, remark '5.'
	r = (y * y - 3.) / 6.;
	s = 1. / (pp + pp - 1.);
	t = 1. / (qq + qq - 1.);
	h = 2. / (s + t);
	w = y * sqrt(h + r) / h - (t - s) * (r + 5. / 6. - 2. / (3. * h));
	R_ifDEBUG_printf("p,q > 1 => w=%g", w);
	if(w > 300) { // exp(w+w) is huge or overflows
	    t = w+w + log(qq) - log(pp); // = argument of log1pexp(.)
	    u = // log(xinbta) = - log1p(qq/pp * exp(w+w)) = -log(1 + exp(t))
		(t <= 18) ? -log1p(exp(t)) : -t - exp(-t);
	    xinbta = exp(u);
	} else {
	    xinbta = pp / (pp + qq * exp(w + w));
	    u = // log(xinbta)
		- log1p(qq/pp * exp(w+w));
	}
    } else { // use the original AS 64 proposal, Scheffé-Tukey (1944) and Wilson-Hilferty
	r = qq + qq;
	/* A slightly more stable version of  t := \chi^2_{alpha} of AS 64
	 * t = 1. / (9. * qq); t = r * R_pow_di(1. - t + y * sqrt(t), 3);  */
	t = 1. / (3. * sqrt(qq));
	t = r * R_pow_di(1. + t*(-t + y), 3);// = \chi^2_{alpha} of AS 64
	s = 4. * pp + r - 2.;// 4p + 2q - 2 = numerator of new t = (...) / chi^2
	R_ifDEBUG_printf("min(p,q) <= 1: t=%g", t);
	if (t == 0 || (t < 0. && s >= t)) { // cannot use chisq approx
	    // x0 = 1 - { (1-a)*q*B(p,q) } ^{1/q}    {AS 65}
	    // xinbta = 1. - exp((log(1-a)+ log(qq) + logbeta) / qq);
	    double l1ma;/* := log(1-a), directly from alpha (as 'la' above):
			 * FIXME: not worth it? log1p(-a) always the same ?? */
	    if(swap_tail)
		l1ma = R_DT_log(alpha);
	    else
		l1ma = R_DT_Clog(alpha);
	    R_ifDEBUG_printf(" t <= 0 : log1p(-a)=%.15g, better l1ma=%.15g\n", log1p(-a), l1ma);
	    double xx = (l1ma + log(qq) + logbeta) / qq;
	    if(xx <= 0.) {
		xinbta = -expm1(xx);
		u = R_Log1_Exp (xx);// =  log(xinbta) = log(1 - exp(...A...))
	    } else { // xx > 0 ==> 1 - e^xx < 0 .. is nonsense
		R_ifDEBUG_printf(" xx=%g > 0: xinbta:= 1-e^xx < 0\n", xx);
		xinbta = 0; u = ML_NEGINF; /// FIXME can do better?
	    }
	} else {
	    t = s / t;
	    R_ifDEBUG_printf(" t > 0 or s < t < 0:  new t = %g ( > 1 ?)\n", t);
	    if (t <= 1.) { // cannot use chisq, either
		u = (la + log(pp) + logbeta) / pp;
		xinbta = exp(u);
	    } else { // (1+x0)/(1-x0) = t,  solved for x0 :
		xinbta = 1. - 2. / (t + 1.);
		u = log1p(-2. / (t + 1.));
	    }
	}
    }

    // Problem: If initial u is completely wrong, we make a wrong decision here
    if(swap_choose &&
       (( swap_tail && u >= -exp(  log_q_cut)) || // ==> "swap back"
	(!swap_tail && u >= -exp(4*log_q_cut) && pp / qq < 1000.))) { // ==> "swap now" (much less easily)
	// "revert swap" -- and use_log_x
	swap_tail = !swap_tail;
	R_ifDEBUG_printf(" u = %g (e^u = xinbta = %.16g) ==> ", u, xinbta);
	if(swap_tail) {
	    a = R_DT_CIv(alpha); // needed ?
	    la = R_DT_Clog(alpha);
	    pp = q; qq = p;
	}
	else {
	    a = p_;
	    la = R_DT_log(alpha);
	    pp = p; qq = q;
	}
	R_ifDEBUG_printf("\"%s\"; la = %g\n",
			 (swap_tail ? "swap now" : "swap back"), la);
	// we could redo computations above, but this should be stable
	u = R_Log1_Exp(u);
	xinbta = exp(u);

/* Careful: "swap now"  should not fail if
   1) the above initial xinbta is "completely wrong"
   2) The correction step can go outside (u_n > 0 ==>  e^u > 1 is illegal)
   e.g., for
	qbeta(0.2066, 0.143891, 0.05)
*/
    }

    if(!use_log_x)
	use_log_x = (u < log_q_cut);//(per default) <==> xinbta = e^u < 4.54e-5
    Rboolean
	bad_u = !R_FINITE(u),
	bad_init = bad_u || xinbta > p_hi;

    R_ifDEBUG_printf(" -> u = %g, e^u = xinbta = %.16g, (Newton acu=%g%s)\n",
	     u, xinbta, acu,
	     (bad_u ? ", ** bad u **" :
	      (use_log_x ? ", on u = log(x) scale" : "")));

    double u_n = 1.; // -Wall
    tx = xinbta; // keeping "original initial x" (for now)

    if(bad_u || u < log_q_cut) { /* e.g.
		    qbeta(0.21, .001, 0.05)
		    try "left border" quickly, i.e.,
		    try at smallest positive number: */
	w = pbeta_raw(DBL_very_MIN, pp, qq, TRUE, log_p);
	if(w > (log_p ? la : a)) {
	    R_ifDEBUG_printf(" quantile is left of smallest positive number; \"convergence\"\n");
	    if(log_p || fabs(w - a) < fabs(0 - a)) { // DBL_very_MIN is better than 0
		tx   = DBL_very_MIN;
		u_n  = DBL_log_v_MIN;// = log(DBL_very_MIN)
	    } else {
		tx   = 0.;
		u_n  = ML_NEGINF;
	    }
	    use_log_x = log_p; add_N_step = FALSE; goto L_return;
	}
	else {
	    R_ifDEBUG_printf(" pbeta(smallest pos.) = %g <= %g  --> continuing\n",
		     w, (log_p ? la : a));
	    if(u  < DBL_log_v_MIN) {
		u = DBL_log_v_MIN;// = log(DBL_very_MIN)
		xinbta = DBL_very_MIN;
	    }
	}
    }


    /* Sometimes the approximation is negative (and == 0 is also not "ok") */
    if (bad_init && !(use_log_x && tx > 0)) {
	if(u == ML_NEGINF) {
	    R_ifDEBUG_printf("  u = -Inf;");
	    u = M_LN2 * DBL_MIN_EXP;
	    xinbta = DBL_MIN;
	} else {
	    R_ifDEBUG_printf(" bad_init: u=%g, xinbta=%g;", u,xinbta);
	    xinbta = (xinbta > 1.1) // i.e. "way off"
		? 0.5 // otherwise, keep the respective boundary:
		: ((xinbta < p_lo) ? exp(u) : p_hi);
	    if(bad_u)
		u = log(xinbta);
	    // otherwise: not changing "potentially better" u than the above
	}
	R_ifDEBUG_printf(" -> (partly)new u=%g, xinbta=%g\n", u,xinbta);
    }

L_Newton:
    /* --------------------------------------------------------------------

     * Solve for x by a modified Newton-Raphson method, using pbeta_raw()
     */
    r = 1 - pp;
    t = 1 - qq;
    double wprev = 0., prev = 1., adj = 1.; // -Wall

    if(use_log_x) { // find  log(xinbta) -- work in  u := log(x) scale
	// if(bad_init && tx > 0) xinbta = tx;// may have been better

	for (i_pb=0; i_pb < 1000; i_pb++) {
	    // using log_p == TRUE  unconditionally here
	    // FIXME: if exp(u) = xinbta underflows to 0, like different formula pbeta_log(u, *)
	    y = pbeta_raw(xinbta, pp, qq, /*lower_tail = */ TRUE, TRUE);

	    /* w := Newton step size for   L(u) = log F(e^u)  =!= 0;   u := log(x)
	     *   =  (L(.) - la) / L'(.);  L'(u)= (F'(e^u) * e^u ) / F(e^u)
	     *   =  (L(.) - la)*F(.) / {F'(e^u) * e^u } =
	     *   =  (L(.) - la) * e^L(.) * e^{-log F'(e^u) - u}
	     *   =  ( y   - la) * e^{ y - u -log F'(e^u)}
		and  -log F'(x)= -log f(x) =  + logbeta + (1-p) log(x) + (1-q) log(1-x)
			       = logbeta + (1-p) u + (1-q) log(1-e^u)
	     */
	    w = (y == ML_NEGINF) // y = -Inf  well possible: we are on log scale!
		? 0. : (y - la) * exp(y - u + logbeta + r * u + t * R_Log1_Exp(u));
	    if(!R_FINITE(w))
		break;
	    if (i_pb >= n_N && w * wprev <= 0.)
		prev = fmax2(fabs(adj),fpu);
	    R_ifDEBUG_printf("N(i=%2d): u=%#20.16g, pb(e^u)=%#12.6g, w=%#15.9g, %s prev=%11g,",
			     i_pb, u, y, w, (w * wprev <= 0.) ? "new" : "old", prev);
	    g = 1;
	    for (i_inn=0; i_inn < 1000; i_inn++) {
		adj = g * w;
		// take full Newton steps at the beginning; only then safe guard:
		if (i_pb < n_N || fabs(adj) < prev) {
		    u_n = u - adj; // u_{n+1} = u_n - g*w
		    if (u_n <= 0.) { // <==> 0 <  xinbta := e^u  <= 1
			if (prev <= acu || fabs(w) <= acu) {
			    /* R_ifDEBUG_printf(" -adj=%g, %s <= acu  ==> convergence\n", */
			    /*	 -adj, (prev <= acu) ? "prev" : "|w|"); */
			    R_ifDEBUG_printf(" it{in}=%d, -adj=%g, %s <= acu  ==> convergence\n",
					     i_inn, -adj, (prev <= acu) ? "prev" : "|w|");
			    goto L_converged;
			}
			// if (u_n != ML_NEGINF && u_n != 1)
			break;
		    }
		}
		g /= 3;
	    }
	    // (cancellation in (u_n -u) => may differ from adj:
	    double D = fmin2(fabs(adj), fabs(u_n - u));
	    /* R_ifDEBUG_printf(" delta(u)=%g\n", u_n - u); */
	    R_ifDEBUG_printf(" it{in}=%d, delta(u)=%9.3g, D/|.|=%.3g\n",
			     i_inn, u_n - u, D/fabs(u_n + u));
	    if (D <= 4e-16 * fabs(u_n + u))
		goto L_converged;
	    u = u_n;
	    xinbta = exp(u);
	    wprev = w;
	} // for(i )

    } else

    for (i_pb=0; i_pb < 1000; i_pb++) {
	y = pbeta_raw(xinbta, pp, qq, /*lower_tail = */ TRUE, log_p);
	// delta{y} :   d_y = y - (log_p ? la : a);
#ifdef IEEE_754
	if(!R_FINITE(y) && !(log_p && y == ML_NEGINF))// y = -Inf  is ok if(log_p)
#else
	if (errno)
#endif
	{ // ML_ERR_return_NAN :
	    ML_ERROR(ME_DOMAIN, "");
	    qb[0] = qb[1] = ML_NAN; return;
	}


	/* w := Newton step size  (F(.) - a) / F'(.)  or,
	 * --   log: (lF - la) / (F' / F) = exp(lF) * (lF - la) / F'
	 */
	w = log_p
	    ? (y - la) * exp(y + logbeta + r * log(xinbta) + t * log1p(-xinbta))
	    : (y - a)  * exp(    logbeta + r * log(xinbta) + t * log1p(-xinbta));
	if (i_pb >= n_N && w * wprev <= 0.)
	    prev = fmax2(fabs(adj),fpu);
	R_ifDEBUG_printf("N(i=%2d): x0=%#17.15g, pb(x0)=%#17.15g, w=%#17.15g, %s prev=%g,",
			 i_pb, xinbta, y, w, (w * wprev <= 0.) ? "new" : "old", prev);
	g = 1;
	for (i_inn=0; i_inn < 1000;i_inn++) {
	    adj = g * w;
	    // take full Newton steps at the beginning; only then safe guard:
	    if (i_pb < n_N || fabs(adj) < prev) {
		tx = xinbta - adj; // x_{n+1} = x_n - g*w
		if (0. <= tx && tx <= 1.) {
		    if (prev <= acu || fabs(w) <= acu) {
			R_ifDEBUG_printf(" it{in}=%d, delta(x)=%g, %s <= acu  ==> convergence\n",
					 i_inn, -adj, (prev <= acu) ? "prev" : "|w|");
			goto L_converged;
		    }
		    if (tx != 0. && tx != 1)
			break;
		}
	    }
	    g /= 3;
	}
	R_ifDEBUG_printf(" it{in}=%d, delta(x)=%g\n", i_inn, tx - xinbta);
	if (fabs(tx - xinbta) <= 4e-16 * (tx + xinbta)) // "<=" : (.) == 0
	    goto L_converged;
	xinbta = tx;
	if(tx == 0) // "we have lost"
	    break;
	wprev = w;
    }

    /*-- NOT converged: Iteration count --*/
    warned = TRUE;
    ML_ERROR(ME_PRECISION, "qbeta");

L_converged:
    log_ = log_p || use_log_x; // only for printing
    R_ifDEBUG_printf(" %s: Final delta(y) = %g%s\n",
	     warned ? "_NO_ convergence" : "converged",
	     y - (log_ ? la : a), (log_ ? " (log_)" : ""));
    if((log_ && y == ML_NEGINF) || (!log_ && y == 0)) {
	// stuck at left, try if smallest positive number is "better"
	w = pbeta_raw(DBL_very_MIN, pp, qq, TRUE, log_);
	if(log_ || fabs(w - a) <= fabs(y - a)) {
	    tx  = DBL_very_MIN;
	    u_n = DBL_log_v_MIN;// = log(DBL_very_MIN)
	}
	add_N_step = FALSE; // not trying to do better anymore
    }
    else if(!warned && (log_ ? fabs(y - la) > 3 : fabs(y - a) > 1e-4)) {
	if(!(log_ && y == ML_NEGINF &&
	    // e.g. qbeta(-1e-10, .2, .03, log=TRUE) cannot get accurate ==> do NOT warn
	     pbeta_raw(DBL_1__eps, // = 1 - eps
		       pp, qq, TRUE, TRUE) > la + 2))
	    MATHLIB_WARNING2( // low accuracy for more platform independent output:
    "qbeta(a, *) =: x0 with |pbeta(x0,*%s) - alpha| = %.5g is not accurate",
	    (log_ ? ", log_" : ""), fabs(y - (log_ ? la : a)));
    }
L_return:
    if(give_log_q) { // ==> use_log_x , too
	if(!use_log_x) // (see if claim above is true)
	    MATHLIB_WARNING(
		"qbeta() L_return, u_n=%g;  give_log_q=TRUE but use_log_x=FALSE -- please report!",
		u_n);
	double r = R_Log1_Exp(u_n);
	if(swap_tail) {
	    qb[0] = r;	 qb[1] = u_n;
	} else {
	    qb[0] = u_n; qb[1] = r;
	}
    } else {
	if(use_log_x) {
	    if(add_N_step) {
		/* add one last Newton step on original x scale, e.g., for
		   qbeta(2^-98, 0.125, 2^-96) */
		xinbta = exp(u_n);
		y = pbeta_raw(xinbta, pp, qq, /*lower_tail = */ TRUE, log_p);
		w = log_p
		    ? (y - la) * exp(y + logbeta + r * log(xinbta) + t * log1p(-xinbta))
		    : (y - a)  * exp(    logbeta + r * log(xinbta) + t * log1p(-xinbta));
		tx = xinbta - w;
		R_ifDEBUG_printf(
		    "Final Newton correction(non-log scale): xinbta=%.16g, y=%g, w=%g. => new tx=%.16g\n",
		    xinbta, y, w, tx);
	    } else {
		if(swap_tail) {
		    qb[0] = -expm1(u_n); qb[1] =  exp  (u_n);
		} else {
		    qb[0] =  exp  (u_n); qb[1] = -expm1(u_n);
		}
		return;
	    }
	}
	if(swap_tail) {
	    qb[0] = 1 - tx;	qb[1] = tx;
	} else {
	    qb[0] = tx;	qb[1] = 1 - tx;
	}
    }
    return;
}
Example #22
0
/***** ***************************************************************************************** *****/
void
RJMCMCdeath(int* accept,              double* log_AR,
            int* K,                   double* w,                        double* logw,                double* mu,    
            double* Q,                double* Li,                       double* Sigma,               double* log_dets,  
            int* order,               int* rank,                        int* mixN,
            int* jempty,              int* err,
            const int* p,             const int* n,
            const int* Kmax,          const double* logK,               const double* log_lambda,    const int* priorK,
            const double* logPbirth,  const double* logPdeath,          const double* delta)
{
  //const char *fname = "NMix::RJMCMCdeath";

  *err = 0;
  *accept = 0;

  /*** Some variables ***/
  static int j, i1, i0, jstar, LTp;
  static int Nempty;
  static double one_wstar, log_one_wstar, erand;

  /*** Some pointers ***/
  static double *wstar, *logwstar;

  static int *mixNP, *jemptyP;
  static double *wP, *logwP, *muP, *QP, *LiP, *SigmaP, *log_detsP;
  static const double *muPnext, *QPnext, *LiPnext, *SigmaPnext;

  if (*K == 1){
    *log_AR = R_NegInf;
    return;
  }

  LTp = (*p * (*p + 1))/2;

  /***** Compute the number of empty components and store their indeces *****/
  /***** ============================================================== *****/
  Nempty  = 0;
  jemptyP = jempty;
  mixNP   = mixN;
  for (j = 0; j < *K; j++){
    if (*mixNP == 0){
      Nempty++;
      *jemptyP = j;
      jemptyP++;
    }
    mixNP++;
  }

  /***** Directly reject the death move if there are no empty components *****/
  /***** =============================================================== *****/
  if (Nempty == 0){
    *log_AR = R_NegInf;
    return;
  }

  /***** Choose at random one of empty components *****/
  /***** ======================================== *****/
  j = (int)(floor(unif_rand() * Nempty));
  if (j == Nempty) j = Nempty - 1;              // this row is needed with theoretical probability 0 (in cases when unif_rand() returns 1)
  jstar = jempty[j];

  /***** Log-acceptance ratio *****/
  /***** ==================== *****/
  wstar         = w + jstar;
  logwstar      = logw + jstar;
  one_wstar     = 1 - *wstar;
  log_one_wstar = AK_Basic::log_AK(one_wstar);

//  *log_AR = -(logPdeath[*K - 1] - logPbirth[*K - 2] - AK_Basic::log_AK((double)(Nempty)) + lbeta(1, *K - 1) - lbeta(*delta, (*K - 1) * *delta)
//	      + (*delta - 1) * *logwstar + (*n + (*K - 1) * (*delta - 1) + 1) * log_one_wstar);    // this is according to the original paper Richardson and Green (1997)
  *log_AR = -(logPdeath[*K - 1] - logPbirth[*K - 2] - AK_Basic::log_AK((double)(Nempty)) + lbeta(1, *K - 1) - lbeta(*delta, (*K - 1) * *delta)
	      + (*delta - 1) * *logwstar + (*n + (*K - 1) * (*delta - 1)) * log_one_wstar);        // this is according to Corrigendum in JRSS, B (1998), p. 661

  /***** log-ratio of priors on K (+ factor comming from the equivalent ways that the components can produce the same likelihood) *****/
  switch (*priorK){
  case NMix::K_FIXED:
  case NMix::K_UNIF:      /*** K * (p(K)/p(K-1)) = K ***/
    *log_AR -= logK[*K - 1];
    break;
  case NMix::K_TPOISS:    /*** K * (p(K)/p(K-1)) = K * (lambda/K) = lambda ***/
    *log_AR -= *log_lambda;
    break;
  }


  /***** Accept/reject *****/
  /***** ============= *****/
  if (*log_AR >= 0) *accept = 1;
  else{                           /** decide by sampling from the exponential distribution **/
    erand = exp_rand();
    *accept = (erand > -(*log_AR) ? 1 : 0);
  }


  /***** Update mixture values if proposal accepted *****/
  /***** ========================================== *****/
  if (*accept){

    /***** Adjustment of the weights and their shift, new log-weights *****/
    wP    = w;
    logwP = logw;
    j     = 0;
    while (j < jstar){
      *logwP -= log_one_wstar;
      *wP     = AK_Basic::exp_AK(*logwP);
      wP++;
      logwP++;
      j++;
    }
    while (j < *K - 1){
      *logwP = *(logwP + 1) - log_one_wstar;
      *wP    = AK_Basic::exp_AK(*logwP);
      wP++;
      logwP++;
      j++;
    }

    /***** Mixture means, inverse variances, their Cholesky decompositions, variances, log_dets -> must be shifted *****/
    /***** mixN -> must be shifted                                                                                 *****/
    mixNP     = mixN + jstar;
    muP       = mu + jstar * *p;
    QP        = Q + jstar * LTp;
    LiP       = Li + jstar * LTp;
    SigmaP    = Sigma + jstar * LTp;  
    log_detsP = log_dets + jstar * 2;

    muPnext    = muP + *p;
    QPnext     = QP + LTp;
    LiPnext    = LiP + LTp;
    SigmaPnext = SigmaP + LTp;

    for (j = jstar; j < *K - 1; j++){
      *mixNP     = *(mixNP + 1);
      mixNP++;

      *log_detsP = *(log_detsP + 2);
      log_detsP += 2;

      for (i1 = 0; i1 < *p; i1++){
        *muP = *muPnext;
        muP++;
        muPnext++;

        for (i0 = i1; i0 < *p; i0++){
          *QP = *QPnext;
          QP++;
          QPnext++;

          *LiP = *LiPnext;
          LiP++;
          LiPnext++;

          *SigmaP = *SigmaPnext;
          SigmaP++;
          SigmaPnext++;
        }
      }      
    }

    /***** order, rank *****/
    NMix::orderComp_remove(order, rank, &jstar, K);

    /***** K *****/
    *K -= 1;
  }

  return;
}
Example #23
0
double lfastchoose(double n, double k)
{
    return -log(n + 1.) - lbeta(n - k + 1., k + 1.);
}