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


#### distance of two vectors based on position difference
#    and based on a difference threshold

# used in agnes.cl()

gpd <- function(x, norm=0, thre){
	# wrapper for all versus all vec.pos.dist()
	#  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
	# norm:0: no norm, 1: scale on max., 2: norm on weight
	# thre: 0..1 fraction
	# result: distance values
	
	#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]]
	
	if(norm==1){		# norm on max.
		x <- apply(x, 2, adaptScale, minS=0, minT=0, maxT=1)
	}else if(norm==2){	# sum norm per column - a norm for the weight of each vector
		sumn <- apply(x, 2, function(x){ sum(x) })
		# normalization
		for(i in 1:nc){
			if(sumn[i]==0){		# sumn norm == 0 do not normalize own zero vector
				cat("\nsumn 0, column",i,nc.n[i])
			}else{
				x[,i] <- x[,i]/sumn[i]
			}
		}
	}
	
	# vector position distance
	tmp <- sum(seq((nc-1),1))	# number of combinations
	erg <- vector("numeric",tmp)
	txx <- range(x)
	txx <- (txx[2]-txx[1])*thre
	k <- 1
	for(i in 1:(nc-1)){
		for(j in (i+1):nc){
			erg[k] <- position.dist(x[,i], x[,j], thre=txx)
			names(erg)[k] <- paste(nc.n[i],nc.n[j],sep="-")
			k <- k+1
		}
	}
	return(erg)
}


# gpd(x=cbind(x1=c(2,3,0,0), x2=c(0,2,0,0), x3=c(3,3,0,0), x4=c(0,1,0,1)), norm=1, thre=0.01)
# a <- gpd(x=h.b5a.pad2, norm=1, thre=0.01)



position.dist <- function(x, y, thre){
	# distance of two vectors based on position difference
	# x,y: two vectors
	# thre: threshold for being a true difference
	xl <- length(x)
	yl <- length(y)
	if(xl!=yl){ stop("vector length different") }
	tmp <- vector("numeric",xl)
	out <- rep(0,xl)
	for(i in 1:xl){
		tmp[i] <- abs(x[i]-y[i])
	}
	out[tmp>=thre] <- 1
	dist <- sum(out)/xl
	return(dist)
}


# position.dist(x=c(2,3,0,0), y=c(0,2,0,0), thre=1)



