# optimize by choosing point with highest cdf difference
ud_local_dmax <- function(n, dim, dmax=1, T=1000){
  ind <- 0 # number of total runs in inner loop
  x <- matrix(runif(dim*n), ncol = dim)
  #x <- maximin(n,dim)
  du <- seq(from = .Machine$double.eps , to = dmax*sqrt(dim), length.out = 1000) 
  ksprog <- rep(NA, T) # progress of maximum k-s distance
  
  for(j in 1:T){
    distance1 <- dist(x)
    ecdf1 <- ecdf(distance1)
    ecdf2 <- ecdf(du)
    dist_diff <- abs(ecdf1(distance1) - ecdf2(distance1))
    dist_max_loc <- which.max(dist_diff) #find where is the max_diff
    ppair <- loc_search(n, dist_max_loc)
    ksold <- ks.test(distance1, du)$statistic
    ksprog[j] <- ksold
    coin <- sample(c(1,2),1)
    xold <- x[ppair[coin],]
    xres <- x[-ppair[coin],]
    s_area <- search_area(xold, xres)
    if(s_area$upper[1] != s_area$lower[1] & s_area$lower[2] != s_area$upper[2])
    {x[ppair[coin],] <- optim(par = xold, fn = local_ks_propose, xres = xres, 
                              method = "L-BFGS-B", lower =as.vector(s_area$lower), 
                              upper = as.vector(s_area$upper), 
                              control = list(fnscale = 1))$par}
    
  }
  return(list(x=x, ksopt=ksold, ksprog = ksprog))
}

# optimize by choosing point randomly
ud_local_rd <- function(n, dim, dmax=1, T=1000){
  x <- matrix(runif(dim*n), ncol = dim)
  #x <- maximin(n,dim)
  du <- seq(from = .Machine$double.eps , to = dmax*sqrt(dim), length.out = 1000) 
  ksprog <- rep(NA, T) # progress of maximum k-s distance
  
  for(j in 1:T){
    distance1 <- dist(x)
    #ksold <- ks.test(distance1, du)$statistic
    ksold <- myks(distance1, du)
    ksprog[j] <- ksold
    coin <- sample(1:n,1)
    xold <- x[coin,]
    xres <- x[-coin,]
    s_area <- search_area(xold, xres)
    if(s_area$upper[1] != s_area$lower[1] & s_area$lower[2] != s_area$upper[2])
    {x[coin,] <- optim(par = xold, fn = local_ks_propose, xres = xres, method = "L-BFGS-B", lower =as.vector(s_area$lower), upper = as.vector(s_area$upper))$par}
    
  }
  return(list(x=x, ksopt=ksold, ksprog = ksprog))
}

# function to find max_dist_difference point pair in a n*n distance matrix
loc_search <- function(n, dist_max_loc){
  sum <- 0
  col_elem_num <- (n-1):1
  for(j in 1:(n-1)){
    sum <- col_elem_num[j] + sum
    if(sum >= dist_max_loc){
      return(c(n-(sum-dist_max_loc), j))
    }
  }
}

# function to define search area of a certain point
search_area <- function(x, xres){
  x <- as.vector(x)
  d <- length(x)
  l <- rep(0, d)
  u <- rep(0, d)
  for(i in 1:d){
    dd <- xres[,i] - x[i]
    if(sum(dd<0)!=0){
      l[i] <- min(dd[dd<0])}
    if(sum(dd>0)!=0){
      u[i] <- max(dd[dd>0])}
  }
  eps <- sqrt(.Machine$double.eps)
  lower <- x + l +eps
  upper <- x + u -eps
  if(length(lower < 0) != 0){
    lower[lower<0] <- rep(0, sum(lower < 0))}
  if(length(upper > 1) != 0){
    upper[upper>1] <- rep(1, sum(upper > 1))}
  return(list(lower = lower, upper = upper))
}
# test 'search_area'
# test <- rbind(matrix(runif(8*2), ncol = 2))
# search_area(test[1,], test[-1,])

# target function to be minimized
local_ks_propose <- function(x, xres){
  xm <- rbind(x,xres)
  dim <- ncol(xres)
  t_cdf <- seq(from = .Machine$double.eps , to = sqrt(dim), length.out = 1000) 
  #ksdist <- ks.test(as.vector(dist(xm)), t_cdf)$statistic
  ksdist <- myks(as.vector(dist(xm)), t_cdf)
  return(ksdist)
}


myks <- function(distance1, du){
  ecdf1 <- ecdf(distance1)
  ecdf2 <- ecdf(du)
  dist_diff <- abs(ecdf1(distance1) - ecdf2(distance1))
  return(max(dist_diff))
}
# test myks
# x <- matrix(runif(18), ncol = 2)
# myks(dist(x), du)
# ks.test(dist(x), du)$statistic
out <- ud_local_rd(8,2)
out
## $x
##            [,1]       [,2]
## [1,] 0.14906188 0.50200003
## [2,] 0.01993249 0.24313339
## [3,] 0.31789812 0.39999905
## [4,] 0.73044670 0.91149441
## [5,] 0.28386704 0.03133594
## [6,] 0.08371642 0.03133594
## [7,] 0.73044670 0.91149441
## [8,] 0.01993248 0.10994367
## 
## $ksopt
## [1] 0.228
## 
## $ksprog
##    [1] 0.3824286 0.3824286 0.3824286 0.3824286 0.3824286 0.3732857
##    [7] 0.3732857 0.3732857 0.3732857 0.3148571 0.3111429 0.3111429
##   [13] 0.3111429 0.3111429 0.3111429 0.3111429 0.3111429 0.3111429
##   [19] 0.3111429 0.3111429 0.2437143 0.2437143 0.2437143 0.2437143
##   [25] 0.2437143 0.2437143 0.2437143 0.2280000 0.2280000 0.2280000
##   [31] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##   [37] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##   [43] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##   [49] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##   [55] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##   [61] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##   [67] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##   [73] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##   [79] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##   [85] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##   [91] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##   [97] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [103] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [109] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [115] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [121] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [127] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [133] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [139] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [145] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [151] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [157] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [163] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [169] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [175] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [181] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [187] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [193] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [199] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [205] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [211] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [217] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [223] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [229] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [235] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [241] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [247] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [253] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [259] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [265] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [271] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [277] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [283] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [289] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [295] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [301] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [307] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [313] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [319] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [325] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [331] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [337] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [343] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [349] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [355] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [361] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [367] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [373] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [379] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [385] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [391] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [397] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [403] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [409] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [415] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [421] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [427] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [433] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [439] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [445] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [451] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [457] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [463] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [469] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [475] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [481] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [487] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [493] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [499] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [505] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [511] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [517] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [523] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [529] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [535] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [541] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [547] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [553] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [559] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [565] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [571] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [577] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [583] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [589] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [595] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [601] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [607] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [613] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [619] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [625] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [631] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [637] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [643] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [649] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [655] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [661] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [667] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [673] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [679] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [685] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [691] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [697] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [703] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [709] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [715] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [721] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [727] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [733] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [739] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [745] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [751] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [757] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [763] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [769] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [775] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [781] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [787] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [793] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [799] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [805] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [811] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [817] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [823] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [829] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [835] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [841] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [847] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [853] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [859] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [865] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [871] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [877] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [883] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [889] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [895] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [901] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [907] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [913] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [919] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [925] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [931] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [937] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [943] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [949] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [955] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [961] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [967] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [973] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [979] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [985] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [991] 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000 0.2280000
##  [997] 0.2280000 0.2280000 0.2280000 0.2280000
x <- out$x
plot(x)

    n=8
    dim = 2
    distance1 <- dist(x)
    #ksold <- ks.test(distance1, du)$statistic
    du <- seq(from = .Machine$double.eps , to = sqrt(dim), length.out = 1000) 
    ksold <- myks(distance1, du)
    coin <- sample(1:n,1)
    xold <- x[coin,]
    xres <- x[-coin,]
    s_area <- search_area(xold, xres)
    if(s_area$upper[1] != s_area$lower[1] & s_area$lower[2] != s_area$upper[2])
    {x[coin,] <- optim(par = xold, fn = local_ks_propose, xres = xres, method = "L-BFGS-B", lower =as.vector(s_area$lower), upper = as.vector(s_area$upper))$par}
    s_area
## $lower
## [1] 0.01993249 0.03133595
## 
## $upper
## [1] 0.7304467 0.9114944
    xold
## [1] 0.1490619 0.5020000
    x[coin,]
## [1] 0.1490619 0.5020000