# TODO: Add comment
# 
# Author: E.Korsching 15.12.2011, 2021
###############################################################################



enumeration.search.dep.boots.GOnly.extf90.distribution <- function(x, gRef, gTest, method="pearson", globalSsqINI=1000, sampleCOR=0, ssqflag=1){
	# R: original data set and group size			-->> small version only for ssq values - no order etc.
	# IMPORTANT: initial globalSsqINI must be greater than all results in the permutation process
	# Fortran dll: all other work: enumeration of all permutations of original grouping
	#   do the same for all compositions (combinations) ,
	#   for each: calculate best ssq for each pair of groups -- also sampling on cor table possible --
	# input: x - dataframe - table of raw data, col names: variables, row names: patients, genes, etc.
	#   gRef: index of group B, gTest: index of group A,
	#   method: pearson, spearman or euclidean  as proximity measure,  sampleCOR: 1: cor matrix will be sampled before use
	# output: matrix of results: ssqPG all ssq of enumeration of all groupings,  ssqBest: best ssq of enumeration of all permutations
	#   of original grouping,  indexB: index of best test order in the original grouping
	# (!) doing a full enumeration -> check if appropriate
	
	# const
	dynpath <- "../searchdep11dist/Release_Intel64/searchdep11dist.so"		# relative to wd
	# check also: libifport.so.5 etc. in /usr/lib
	#ini
	if(!(method %in% c("euclidean","pearson"))){ cat("\n wrong similarity method "); return() }
	if(method=="pearson"){ meth <- 1 } else { meth <- 2 }
	
	nr <- length(gTest)
	nc <- length(gRef)
	nrs <- choose(nr+nc,nc)		# combinations
	cat("\n combinations of groups: ",nrs)
	fact <- factorial(nr)
	cat("\n permutations of test set: ",fact)
	
	ssqPG <- matrix(0,nrs,1)		# allocation, ssq  only
	
	#filter and order x
	y <- x[,c(gTest,gRef),drop=F]		####
	
	cat("\n\n input (x): \n\n")
	cat(names(x))		#print(x)
	cat("\n\n and ordered input (y): \n\n")
	cat(names(y))		#print(y)
	cat("\n\n col 1 bis ",nr,": Test, col ",nr+1," bis ",nr+nc,": Ref \n")
	
	y <- as.matrix(y)		####
	nry <- dim(y)[1]
	ncy <- dim(y)[2]
	cat("\n nr y: ",nry," -  nc y: ",ncy,"\n\n")
	
	#Fortran definition
	mode(y) <- 'single'
	mode(nry) <- 'integer'
	mode(ncy) <- 'integer'
	mode(nr) <- 'integer'
	mode(nc) <- 'integer'
	mode(nrs) <- 'integer'
	mode(meth) <- 'integer'
	mode(sampleCOR) <- 'integer'
	mode(fact) <- 'integer'
	mode(ssqPG) <- 'single'
	mode(globalSsqINI) <- 'single'
	mode(ssqflag) <- 'integer'					#flag: '1': ssq in x, '2': ssq in y
	
	#Fortran call
	dyn.load(dynpath)
	f.back <- .Fortran("workflow",
				x=y,
				nrx=nry,
				ncx=ncy,
				nr=nr,
				nc=nc,
				nrs=nrs,
				meth=meth,
				sampleCOR=sampleCOR,
				fact=fact,
				ssqPG=ssqPG,
				globalSsqINI=globalSsqINI,
				ssqflag=ssqflag
		)
	dyn.unload(dynpath)
	
	#check if globalSsqINI value was in all cases greater than the real global ssq values
	cat("\n Max ssqPG = ",max(f.back$ssqPG)," if equal '",globalSsqINI,"' check the results and adjust the 'globalSsqINI' value.\n")
	
	return(f.back$ssqPG)
}

#aa50 <- enumeration.search.dep.boots.GOnly.extf90.distribution(He589.c, gRef=c(1,5,3,2), gTest=c(4,6,7,8,9,10), method="cor", globalSsqINI=1000, sampleCOR=0, ssqflag=1)
#aa51 <- enumeration.search.dep.boots.GOnly.extf90.distribution(He589.c, gRef=c(1,5,3,2), gTest=c(4,6,7,8,9,10), method="cor", globalSsqINI=1000, sampleCOR=1, ssqflag=1)

#compare old algo
#aa51 <- enumeration.search.dep.boots.GOnly.extf90(He589.c, gRef=c(1,5,3,2), gTest=c(4,6,7,8,9,10), method="cor")

#factorial(11)		#39916800
#factorial(10)		#3628800
#factorial(9)			#362880
#factorial(8)			#40320
#choose(16,5)			#4368
#choose(16,6)			#8008
#choose(16,7)			#11440
#choose(16,8)			#12870


