#' MD Distant Matrices
#'
#' Creates orthogonal matrices in the Stiefel manifold, which are distant to each other
#' by the MD index and optionally also distant to a given set of matrices.
#' 
#' @param p The dimension of the orthogonal matrices.
#' @param n The length of the returned matrix list.
#' @param mat_list A list of already existing orthogonal matrices.
#' @param bestof The number of candidates evaluated for each new matrix.
#' 
#' @return A list which contains the already given and the additionally created matrices.
#'
#' @details If a matrix list should be created from scratch, i.e. the parameter
#' \code{mat_list} was not provided, then the first orthogonal matrix 
#' of the returned list is randomly generated by \code{ICtest::rorth}.
#' If \code{n} is larger than one or if a matrix list was provided, 
#' then for each additional matrix \eqn{M_{k+1}} we consider the distance 
#' \eqn{\min(\textrm{MD}(M_1, M_{k+1}),\textrm{MD}(M_2, M_{k+1}),\dots, \textrm{MD}(M_k, M_{k+1}))}
#' to all previous list entries. This distance is evaluated for \code{bestof} 
#' randomly generated orthogonal candidate matrices from which the
#' furthest is selected.
#' 
#' 
#' @example examples/ex_MD_distant_matrices.R
#' 
#' @seealso ICtest::rorth
#' 
#' @importFrom ICtest rorth
#' @importFrom JADE MD
#' @export
MD_distant_matrices <- function(p, n=1, mat_list=list(), bestof=10){
  if(n <= length(mat_list)){
    return(mat_list)
  }
  for(i in (length(mat_list)+1):n){
    ## when no matrix is given in mat_list, the first matrix can be chosen
    # completely random, meaning as a result of rorth()
    if(i == 1){
      mat_list[[1]] <- ICtest::rorth(p)
    }else{
      largestMD <- 0
      best_cand <- matrix(0, p, p)
      for(j in seq_len(bestof)){
        mat_cand <- ICtest::rorth(p)
        res <- unlist(lapply(mat_list[1:(i-1)], function(x) MD(x, mat_cand)))
        if(min(res) > largestMD){
          best_cand <- mat_cand
          largestMD <- min(res)
        }
      }
      mat_list[[i]] <- best_cand
    }
  }
  return(mat_list)
}