# TODO: Add comment
# 
# Author: E.Korsching 04-2024
###############################################################################


# former dvs()


nedl2 <- function(x){
	# computes the normalized Euclidean distance between all columns in a matrix,
	#  therfore same length and position exactness is mandatory for column vectors
	#  normalization is done with L2 norm (calculation per columns)
	#  NA values are not allowed, respectively line wise removed
	#  result range from 0 (min. different) to 2 (max. different)
	# x: data.frame/matrix (min. two columns), minimal rows: 2
	# result: distance value
	
	#ini
	if(is.vector(x)){ stop("Matrix or data frame expected") }
	if(sum(is.na(x))>0){
		tmp <- rowSums(apply(a,2,is.na))
		tmp2 <- tmp==0
		tmp3 <- sum(tmp>0)
		x <- x[tmp2,]
		warning("NA values, rows removed:",tmp3)
	}
	nr <- nrow(x)
	nc <- ncol(x)
	if(nr<2){ stop("Minimal column length is 2") }
	nc.n <- dimnames(x)[[2]]
	
	# L2 norm per column
	l2n <- apply(x, 2, function(x){ sqrt(sum(x^2)) })
	# normalization
	for(i in 1:nc){
		if(l2n[i]==0){		# L2 norm == 0 do not normalize own zero vector
			cat("\nL2 0, column",i,nc.n[i])
		}else{
			x[,i] <- x[,i]/l2n[i]
		}
	}
	# Euclidean distance
	tmp <- sum(seq((nc-1),1))
	#cat("\ncombinations",tmp)
	erg <- vector("numeric",tmp)
	k <- 1
	for(i in 1:(nc-1)){
		for(j in (i+1):nc){
			erg[k] <- sqrt(sum((x[,i]-x[,j])^2))
			names(erg)[k] <- paste(nc.n[i],nc.n[j],sep="-")
			k <- k+1
		}
	}
	return(erg)
}


#a <- nedl2(x=data.frame(
#				a=c(1,2,1,3,2,3),
#				b=c(2,3,2,4,3,4),
#				c=c(1,1,1,1,1,1),
#				d=c(1,1,1,1,1,1),
#				e=c(2,2,2,2,2,2)
#				))

# a-b	0.12
# a-c	0.38
# a-d	0.38
# a-e	0.38
# b-c	0.26
# b-d	0.26
# b-e	0.26
# c-d	0
# c-e	0
# d-e	0




nedl2.test.case <- function(samples, min=-200, max=200, mix=F){
	# sample some use cases and look on the
	# distribution / the range of the result values
	# samples: number of samples
	cc <- NULL
	if(mix){
		for(i in 1:samples){
			a <- runif(50, min, max)
			b <- runif(50, min, max)
			c <- runif(50, 0, max)
			d <- runif(50, 0, max)
			e <- runif(50, min, 0)
			f <- runif(50, min, 0)
			aa <- cbind(a,b,c,d,e,f)
			bb <- dvs(aa)
			cc <- c(cc,bb)
		}
	}else{
		for(i in 1:samples){
			a <- runif(50, min, max)
			b <- runif(50, min, max)
			c <- runif(50, min, max)
			d <- runif(50, min, max)
			e <- runif(50, min, max)
			f <- runif(50, min, max)
			aa <- cbind(a,b,c,d,e,f)
			bb <- dvs(aa)
			cc <- c(cc,bb)
		}
	}
	tmp <- mean(cc)
	tmp1 <- median(cc)
	cat("\nrange",range(cc)," mean",tmp," median",tmp1,"\n")
	hist(cc)
	abline(v=tmp, lty=2, col="red")
	abline(v=tmp1, lty=2, col="blue")
	return()
}


#pdf(file=paste(getwd(),"/tech_tests/test-nedl2",".",format(Sys.time(), "%Y%m%d%H%M"),".pdf", sep=""),
#		width=11, height=7, onefile=T, title="test-nedl2", pointsize=12)
#par(mfrow=c(2,2))
#nedl2.test.case(samples=10000, min=-200, max=200, mix=F)		# range 0.92 1.75  mean 1.41  median 1.41
#mtext("samples=10000, min=-200, max=200, mix=F",side=3)
#nedl2.test.case(samples=10000, min=-200, max=0, mix=F)		# range 0.44 0.99  mean 0.70  median 0.70
#mtext("samples=10000, min=-200, max=0, mix=F",side=3)
#nedl2.test.case(samples=10000, min=0, max=200, mix=F)			# range 0.43 0.98  mean 0.70  median 0.70
#mtext("samples=10000, min=0, max=200, mix=F",side=3)
#
#nedl2.test.case(samples=10000, min=-200, max=200, mix=T)		# range 0.46 1.94  mean 1.43  median 1.44
#mtext("samples=10000, min=-200, max=200, mix=T",side=3)
#par(mfrow=c(1,1))
#dev.off()



