double
dotwcalc(double *lambda, int m, double *ptw, double *pzn, double *pzvar, int minm) 
{
  double nv, mv, tzn, tm ; 
  double *evals ;
  double y, top, bot, zn, tw, ystat ;
  double tail, lsum ;

  if (m<minm) { 
   *pzn = *pzvar = *ptw = -1 ;
   return -1.0 ;
  }
  lsum = asum(lambda, m) ;
  if (lsum<=0.0) {  
   *pzn = *pzvar = *ptw = -1 ;
   return -1.0 ;
  }

  tzn = *pzn ;
  tm  = (double) m ;

  y = (double) m  / lsum ;
  ystat = lambda[0] * y * tzn ;

  if (tzn>0.0) {  
   tw = twnorm(ystat, tm, tzn) ;
   *pzn = tzn ;
   *ptw = tw ;  
   tail = twtail(tw) ;
   return tail ;
  }
   ZALLOC(evals, m, double) ;
   vst(evals, lambda, y, m) ;
   top = (double) (m*(m+2)) ;
   bot = asum2(evals, m) - (double) m ;
   zn = top/bot ;  // see appendix to eigenpaper  NJP
   y = evals[0]*zn ;
   tw = twnorm(y, tm, zn) ;
   *pzn = zn ;
   *ptw = tw ;  
   tail = twtail(tw) ;
   free(evals) ;
   return tail ;
}
double twnorm(double lam, double p, double n) 
// Ref Johnstone (2001) 
{ 
	 double mu, phi , y1, y2  ; 

         if (n<0.0) return -10.0 ;
         if (p<0.0) return -10.0 ;

         if (n<p) return twnorm(lam, n, p) ;
// not very important refinement as twnorm symmetric in p, n-1  NJP

	 y1 = sqrt(n-1) + sqrt(p) ; 
	 mu = y1*y1 ;
	 y2 = (1.0/sqrt(n-1)) + 1.0/sqrt(p) ;  
         phi = y1*pow(y2,1.0/3.0) ;
	 return (lam-mu)/phi ;
}
Esempio n. 3
0
double doeig2(double *vals, int m, double *pzn, double *ptw) 
{
  static int ncall = 0 ;
  double y, tw, tail ;
  double zn, top, bot ;
  double *evals ;
 
  ++ncall ;
  ZALLOC(evals, m, double) ;
  copyarr(vals, evals, m) ;
  y = (double) m / asum(evals, m) ;
  vst(evals, evals, y, m) ;      
  top = (double) (m*(m+2)) ;
  bot = asum2(evals, m) - (double) m ;
  zn = top/bot ;
  y = evals[0]*zn ;
  tw = twnorm(y, (double) m, zn) ;
  tail = twtail(tw) ;
  free(evals) ;
  *pzn = zn ;
  *ptw = tw ;  
  return tail ;
}