#################################################
# Matrix calculations
#################################################

#' Calculate the normalized weights for each node and add them to the tree
#'
#' This function will take a defined model and corresponding set of
#' comboFrames and add normalized and weighted values to the tree
#'
#' @param tree the tree representing the model to calculate
#' @param comboFrames a list of dataframes with comparative values corresponding
#' to the tree
#' @export
calculateHDMWeights <- function(tree, comboFrames) {

  tree$norm <- 1
  tree$weight <- 1
  tree$inconsistency <- 1

  tree$Do(function(node) {
    parent <- node$parent
    #build the comparison frames into a matrix
    matrixColumns <- lapply(1:length(parent$children), function(i){
      parent$children[[i]]$name
    })
    populatedMatrixAB <- matrix.buildFromComboFrames(matrixColumns,comboFrames[[node$name]])

    node$norm <-  normalizeValueForNode(node, populatedMatrixAB)
    node$weight <-  finalizeWeightsForNode(node)
    node$inconsistency <- inconsistency.calculate(populatedMatrixAB)
  }, filterFun = isNotRoot)

  tree
}

#' Calculate weight for requested node
#'
#' Designed to be used recursively in the tree, this function will return
#' the normalized value for a node.
#'
#' @param currentNode the node to operate on
#' @param populatedMatrix the populated matrix of comboFrames
normalizeValueForNode <- function(currentNode, populatedMatrix) {
  calculatedMatrix <- matrix.calculate(populatedMatrix)
  #return(calculatedMatrix[[currentNode$name,2]])
  return(round(calculatedMatrix[[currentNode$name,2]], 4)) #round to 4 digits
}

#' Calculate the weighted value for each node
#'
#' As the final step in the calculation return the finalized weight of each node.
#'
#' @param node the node to operate on
finalizeWeightsForNode <- function(node) {
  parent.norm <- node$parent$norm
  weight <- node$norm * parent.norm
  return(round(weight, 4)) #round to 4 digits
}

#' Given a set of names and dataframes with evaluation data,
#' build out the first matrix to operate on
#'
#' This is only used internally as the first and second step in the calculation
#'
#' @param names the names of the elements being compared in a pairwise manner
#' @param comboFrames the frames to transform into a matrix
matrix.buildFromComboFrames <- function(names,comboFrames) {
  A <- matrix(,
              nrow = length(names),
              ncol = length(names),
              dimnames = list(names,names))
  diag(A) <- 1
  for(df in comboFrames) {
    A[colnames(df)[1],colnames(df)[2]] <- df[[1,1]]
    A[colnames(df)[2],colnames(df)[1]] <- df[[1,2]]
  }
  B <- t(A) / A
  diag(B) <- 1
  B
}

#' Calculate inconsistency
#'
#' Helps determine how reliable this expert is
#'
#' @param B the matrix after it's gone through the first 2 steps of the calculation
inconsistency.calculate <- function(B){
  B.norm <- sweep(B,2,colSums(B),`/`)
  nMeans <- rowMeans(B.norm)
  nSd <- apply(B.norm,1,sd)
  nVar <- apply(B.norm,1,var)
  inconsistency <- sqrt(sum(nVar) * .25)

  print("---Inconsistency")
  print(inconsistency)

  return(round(inconsistency, 4)) #round to 4 digits
}

#' Pass in a list of experts and their final results, get back the disagreement
#'
#' First get the standard deviation across the values for each expert
#' Second get the mean across the experts
#'
#' @rdname disagreement.calculate
#'
#' @param expertsFinalResults a matrix with the experts and the weights at the bottom
#' of the tree
#' @export
calculateExpertDisagreement <- function(expertsFinalResults) {
  stepOne <- apply(expertsFinalResults,1,sd)
  stepTwo <- mean(stepOne)
  print("Step 2")
  print(round(stepTwo,4))
  return(round(stepTwo,4)) #round to 4 digits
}

#' Given a populated matrix, divide the comparisons against
#' each other to get relative weights
#'
#' This is only used internally as the final part of the calculation. The first
#' 2 steps are used to them get the normalized value for the nodes
#'
#' @param B the matrix to operate on
matrix.calculate <- function(B) {
  #divide col1 by col2, col2 by col3, etc to create Matrix C
  C <- matrix(ncol = ncol(B)-1, nrow = nrow(B))
  for(c in 1:ncol(C)) {
    C[,c] <- B[,c] / B[,c+1]
  }
  cMeans <- colMeans(C)

  #final calculation
  matrix.final <- matrix(ncol = 2, nrow = nrow(B), dimnames = list(rev(colnames(B)), list("Raw","Normalized")))
  #matrix.final[nrow(matrix.final),1] <- 1
  matrix.final[1,1] <- 1
  cMeans.reverse <- rev(cMeans)
  for(c in 2:nrow(matrix.final)) {
    matrix.final[c, 1] <- matrix.final[c-1,1] * cMeans.reverse[c-1]
  }

  matrix.final.raw.sum <- sum(matrix.final[,1])
  matrix.final[,2] <- matrix.final[,1] / matrix.final.raw.sum

  should.be.one <- sum(matrix.final[,2])

  matrix.final
}


library(tidyverse)
library(Seurat)

fn = "data/H1_day0_scranNorm_adtbatchNorm_dist_clustered_PCA.rds"
h1 = readRDS(fn)

fn.new = "data/H1_day0_scranNorm_adtbatchNorm_dist_clustered_TSNE.rds"

for(p in c(seq(10, 170, by = 40))) {
  cat(p, " ")
  h1 = RunTSNE(h1, reduction.use = "protpca", reduction.name = paste0("tsne_p",p),
               dims.use = 1:7, seed.use = 0, perplexity=p)
  saveRDS(h1, fn.new)
}


library(ggplot2)

techData <- read.csv("~//Desktop//eds.csv")

'Attach data frame for easy references'
attach(techData)

'Creating dummy variable for vulnerabilities'
techData$hasVuln <- as.factor(techData$vulnerabilities > 0)

'Date columns needs to be converted from factor to date type'
str(techData)
techData$startDate <- as.Date(techData$intialcommitdate, format = "%m/%d/%Y")
techData$endDate <- as.Date(techData$recentdate, format = "%m/%d/%Y")

'Messy plot of lines of code of projects'
ggplot(techData, aes(x = startDate,y = sqrt(cocomo), color = hasVuln)) +
  geom_line() +
  geom_point() +
  scale_x_date() +
  xlab("") +
  ylab("Lines of Code") +
  ggtitle("Lines of Code of Projects Over Time")

detach(techData)

'Data for correlation between total devs and bug count with no outliers'
MoPeopleMoProblems <- subset(techData, bugcount >= 0 & bugcount < 2000 & totaldevs < 5000)
cor(MoPeopleMoProblems$bugcount, MoPeopleMoProblems$totaldevs)
attach(MoPeopleMoProblems)

'Linear model'
fit <- lm(bugcount~totaldevs, MoPeopleMoProblems)

'Scatter plot with with regression line and confidence bands'
ggplot(MoPeopleMoProblems, aes(x = totaldevs,y = bugcount)) +
  geom_point() +
  geom_smooth(method = 'lm', se = TRUE) +
  xlab("Number of Developers") +
  ylab("Bugs") +
  ggtitle("Mo' People = Mo' Problems")


prod2 <- outer(0:9, 0:9)
frdet <- table(outer(prod2, prod2, FUN = "-"))
plot(frdet, xlab = "det", ylab = "freq", col = "blue")


pdf_file<-"pdf/lorenzcurves_barcharts_05.pdf"
cairo_pdf(bg="grey98", pdf_file,width=12,height=9)

par(omi=c(0.5,0.5,1.1,0.5),mai=c(0,2,0,0.5),family="Lato Light",las=1)
library(fBasics)
library(gdata)

# Read data and prepare chart

myDataFile<-"myData/income_five_classes.xlsx"
myData<-read.xls(myDataFile,head=T,skip=1,dec=".",encoding="latin1")
layout(matrix(c(1,2),ncol=1),heights=c(80,20))

# Create chart

par(mai=c(0,1.75,1,0))
bp1<-barplot(as.matrix(myData),ylim=c(0,6),width=c(0.5),axes=F,horiz=T,col=c("grey",seqPalette(5,"OrRd")[2:5]),border=par("bg"),names.arg=gsub("."," ",names(myData),fixed=T),cex.names=1.55)

# Other elements

mtext(seq(0,100,by=20),at=seq(0,100,by=20),1,line=0,cex=1.15)
arrows(0,-0.03,0,7.30,lwd=1.5,length=0,xpd=T,col="grey")
text(100-(myData[5,]/2),bp1,cex=1.1,labels=paste(round(myData[5,],digits=0),"%",sep=" "),col="white",family="Lato Black",xpd=T)

# Create chart

par(mai=c(0.55,1.75,0,0))
bp2<-barplot(as.matrix(rep(20,5)),ylim=c(0,0.5),width=c(0.20),horiz=T,col=seqPalette(5,"Greys"),border=par("bg"),names.arg=c("Uniform distribution"),axes=F,cex.names=1.25)

# Other elements

arrows(0,-0.01,0,0.35,lwd=1.5,length=0,xpd=T,col="grey")
text(c(10,30,50,70,90),bp2,labels=c("20 %","20 %","20 %","20 %","20 %"),col=c("black","black","white","white","white"),xpd=T)

# Titling

title(main="Income Distribution over five Classes in different Countries",line=3,adj=0,cex.main=2.25,family="Lato Black",outer=T)
myBreak<-strsplit( strwrap("In Mexico the richest 10% of income recipients held over 45% of the overall income in 2000, in the USA
                           it was 29%, in Germany 24. Compared to 1984 the share did increase.",width=110),"\n")
for(i in seq(along=myBreak))
{
mtext(myBreak[[i]],line=(1.8-i)*1.5,adj=0,side=3,cex=1.25,outer=T)
}
mtext("Source: World Income Inequality Database V2.Oc 2008",side=1,adj=1,cex=0.95,font=3,outer=T)
dev.off()


# Parameters
## SAD
S_POOL   <- c(20L, 200L)
N_SIM    <- c(2000L, 20000L)
SAD_COEF <- c(list(cv_abund = 0.1), list(cv_abund = 0.5), list(cv_abund = 1))

## initial dispersion
SIGMA    <- c(0.05, 10)

## movement dispersion
MOVEMENT_SD <- 0
DRIFT    <- 0.001

## sampling
QUADRAT_AREA <- 0.01 # in a grid of 100
N_QUADRATS <- 100L

## subsampling
# SUBSAMPLING_RATIO <- c(.1, .5, 1)

parameter_table <- expand.grid(
   S_POOL = S_POOL, N_SIM = N_SIM, SAD_COEF = SAD_COEF,
   SIGMA = SIGMA,
   MOVEMENT_SD = MOVEMENT_SD, DRIFT = DRIFT,
   QUADRAT_AREA = QUADRAT_AREA, N_QUADRATS = N_QUADRATS
)