#' Find unique values of a vector or unique rows of a matrix and their location
#'
#' @param x a vector or a matrix
#' @param sort = 1 to sort the result
#'
#' @return
#'  A list of \cr
#'  \code{value} The unique values \cr
#'  \code{loc} The list of length \code{length(value)} containing
#'  the locations of the original elements.
#'
#' @examples
#' ( temp <- Unique( c(1,2,1,5,6,3,5,4,6) ) )
#' sum( unlist(lapply(temp$loc,length)) )
#' ( temp <- Unique( c(1,2,1,5,6,3,5,4,6), sort=1 ) )
#'
#' ( temp2 <- Unique( rbind(demomat(5,4),demomat(3,4)) ) )
#' ( temp2 <- Unique( rbind(demomat(5,4),demomat(3,4)), sort=1, decreasing=1 ) )
#'
#' @export
#'

Unique <- function( x, sort=0, decreasing=0 ){
 # returns a set of unique values of x and their locations
 # Shin-ichi Mayekawa
 # 20230902cot
 # sort: 20230903
 # factor added: 20230909
 #
 
 if( !is.vector(x) && !is.matrix(x) && !is.factor(x) ){
  cat("\nerror1(Unique) cannot handle arrays.\n")
  stop()
 }
 
 xu=unique(x)
 
 if( is.vector(x) || is.factor(x) ){
  
  lenu=length(xu)
  loc=vector( mode="list", length=lenu )
  for( i in 1:lenu ){
   loc[[i]]=which( x == xu[i] )
  }
  names(loc)=xu
  
  if( sort ){
   od=order(xu, decreasing=decreasing)
   xu=xu[od]
   loc=loc[od]
  }
  
 }
 else{
  
  lenu=nrow(xu)
  loc=vector( mode="list", length=lenu )
  for( i in 1:lenu ){
   loc[[i]]=which( apply( x, 1, function(y){all(y==xu[i,])} ) )
   names(loc[[i]])=NULL
  }
  
  if( sort ){
   nc=ncol(xu)
   code=paste("od=order(", paste("xu[,",1:nc,"]", sep="", collapse=",")
              , ", decreasing=decreasing)", sep="")
   eval(parse(text=code))
   Print(code)
   xu=xu[od,]
   loc=loc[od]
  }
  
 }
 
 return( list( value=xu, loc=loc ) )
 
 
} # end of Unique


