`pp.est` <-
function(y, x, pcuts = c(1e-3, 1e-4, 1e-5, 1e-6), K=10000, 
  skip.extreme=TRUE, trace=0)
{
  r1=1
  r2=0.5*ncol(x)-1
   
  if(!is.vector(y)){ stop("y must be a vector\n") }
  if(!is.matrix(x)){ stop("x must be a matrix\n") }
  if(length(y) != ncol(x)){ stop("dimensions of x and y do not match\n")}
  p = length(y)
  if(p%%2!=0){ stop("there are must be even number of observations\n") }
  p2 = p/2
  if(r2>=p2){ stop("r2 must be smaller than p2\n") }

  ux = unique(as.vector(x))
  if(length(ux) != 2){
    stop("x must have two unique values\n")
  }
  if(any(sort(ux) != 0:1)){
    stop("x can only be 0 or 1\n")
  }
  
  mm = numeric(p)
  mm[which(y>median(y))] = 1

  pd = matrix(1, nrow=r2-r1+1, ncol=K)
  dims = c(r1, r2, K, p, round(runif(1, -10000,-2)))
  Z = .C("p_r_est", as.double(y), as.integer(mm), pd = as.double(pd),
     as.integer(dims), PACKAGE="permuteP")
  pd = matrix(Z[["pd"]], byrow=TRUE, nrow=r2-r1+1, ncol=K)
  
  pp = matrix(1, nrow=length(pcuts), ncol=r2)
  for(i in 1:length(pcuts)){
    pcut = pcuts[i]
    pp[i,r1:r2]=apply(pd,1,function(v){length(which(v<=pcut))/length(v)})
  }
  # rm(pd)
  
  ww1  = which(pp>0, arr.ind=TRUE)
  if(length(ww1) == 0){
    rmax = r2
  }else{
    rmax = max(ww1[,2])
  }
  
  dims = c(nrow(x), p, rmax, length(pcuts))
  pers = numeric(length(pcuts))
  
  for(i in 1:length(pcuts)){
    if(pp[i,r1] < 0.99){
      wstr = sprintf("p-value cutoff %.2e is too small", pcuts[i])
      wstr = paste(wstr, "to obtain a reliable estimation\n")
      warning(wstr)
      if(skip.extreme){ return(pers) }
    }
  }
  
  ## the first column is the proportion when distance is 0
  if(nrow(pp)==1){
    pp = c(1, pp[,1:rmax])
  }else{
    pp = cbind(rep(1, nrow(pp)), pp[,1:rmax])
  }
  
  Z = .C("p_p_est", as.integer(t(x)), as.double(pcuts),
     as.double(t(pp)), as.integer(dims), as.integer(trace), 
     pers=as.double(pers), PACKAGE="permuteP")
  
  Z[["pers"]]
}
