library(fpca)
library(tidyverse)

# Set working directory.
#setwd("~/.../BPM")

df_bpm <- read.csv("df_bpm.csv")
df_bpm <- df_bpm %>%
  select(-season)

# Candidate models for fitting:
M.set <- c(5, 10, 15, 20)
r.set <- c(3, 4, 5)

#Fit candidate models by fpca.mle:
s0 <- Sys.time()
result_bpm <- fpca.mle(as.data.frame(df_bpm), M.set, r.set)
s1 <- Sys.time() - s0
s1
#Time difference of 33.65598 mins
#save(result_bpm, file = "result_bpm.RData")
#load("result_bpm.RData")

#Model selection result, selected with the smallest CV score among all converged models:
M <- result_bpm$selected_model[1]
r <- result_bpm$selected_model[2]

# Look at the CV scores and convergence for each model:
result_bpm$cv_scores
result_bpm$converge
# Rescaled grid:
grids.new <- result_bpm$grid
# Estimated eigenvalues:
evalest <- result_bpm$eigenvalues
evalest

# Estimated error variance:
sig2est <- result_bpm$error_var

# Estimated eigenfunctions:
eigenfest <- result_bpm$eigenfunctions

va <- evalest[1] * eigenfest[1,] * eigenfest[1,] + 
  evalest[2] * eigenfest[2,] * eigenfest[2,] + 
  evalest[3] * eigenfest[3,] * eigenfest[3,] + 
  evalest[4] * eigenfest[4,] * eigenfest[4,] 
plot(grids.new, sqrt(va))

#Estimated mean curve:
muest <- result_bpm$fitted_mean

# If we wanted to exclude players with only one measurement:
#more_than_one <- df_bpm %>% 
#  count(player_link) %>%
#  filter(n > 1) %>%
#  select(player_link) 

df_bpm1 <- df_bpm #%>% 
  #filter(player_link %in% more_than_one$player_link) 

L1 <- min(as.numeric(df_bpm1$age)) # Range of the time.             
L2 <- max(as.numeric(df_bpm1$age))

df_bpm2 <- df_bpm1 %>% 
  mutate(temp = (age - L1) / (L2 - L1)) %>%
  mutate(temp = ifelse(temp < 0.00001, 0.00001, temp)) %>%
  mutate(temp = ifelse(temp > 0.99999, 0.99999, temp)) %>%
  select(player_link, bpm, temp) %>%
  rename(age = temp)

player_names_bpm <- as.character(unique(df_bpm2$player_link))
#save(player_names_bpm, file = "player_names_bpm.RData")
#load("player_names_bpm.RData")

fpcs <- fpca.score(as.matrix(df_bpm2), grids.new, muest, evalest, eigenfest, sig2est, r)
pred <- fpca.pred(fpcs, muest, eigenfest) 
# Save table (fpcs will be used with FAA and FADA):
#write.table(fpcs, file = "fpcs.txt", col.names = FALSE, row.names = FALSE)
#fpcs <- read.table("Predictions/Files_from_diff_places/fpcs.txt")

# ----

# 3. FAA and FADA:
library(Anthropometry)
X <- fpcs
numArch <- 10 
numRep <- 20
set.seed(2018)
s0 <- Sys.time()
lass_bpm <- stepArchetypesRawData(data = X, numArch = 1:numArch, numRep = numRep, verbose = FALSE)
s1 <- Sys.time() - s0
s1
#Time difference of 11.32573 mins
screeplot(lass_bpm)
#save(lass_bpm, file = "lass_bpm.RData")
#load("lass.RData")

numArchoid <- 5 # Number of archetypoids according to the screeplot.
# With numArchoid <- 4, we obtain: 
#"Ron Boone_boonero01", "Eddie Jones_jonesed02", "Tremaine Fowlkes_fowlktr01" and "Greg Butler_butlegr01"     
s0 <- Sys.time()
res_ada_bpm <- archetypoids(numArchoid, data = X, step = FALSE, 
                           ArchObj = lass_bpm, nearest = "cand_ns", sequ = TRUE)
s1 <- Sys.time() - s0
s1
#Time difference of 36.74753 mins
#save(res_ada_bpm, file = "res_ada_bpm.RData")
#load("res_ada_bpm.RData")

str(res_ada_bpm)
# Archetypoids:
cases <- player_names_bpm[res_ada_bpm$cases]
cases
#[1] "Devin Gray_grayde01"      "Darryl Dawkins_dawkida01" "Diamond Stone_stonedi01"  "Eddy Curry_curryed01"    
#[5] "LeBron James_jamesle01"
df_bpm1 %>%
  filter(player_link %in% cases) %>%
  group_by(player_link) %>%
  summarise(mean_bpm = mean(bpm)) %>%
  arrange(desc(mean_bpm))
#LeBron James_jamesle01      9.21
#Darryl Dawkins_dawkida01   -2.52
#Eddy Curry_curryed01       -6.50
#Devin Gray_grayde01        -8.40
#Diamond Stone_stonedi01    -24.1

#mean(df_bpm1[df_bpm1$player_link == cases[5], "bpm"])

# Alphas:
alphas <- res_ada_bpm$alphas
dimnames(alphas) <- list(player_names_bpm[res_ada_bpm$cases], player_names_bpm) 
names(which(alphas[5,] > 0.95)) # > 0.9

# SET OF SIMILAR PLAYERS:
player <- "Joel Embiid_embiijo01"
alphas[, grep(player, colnames(alphas))]
#Devin Gray_grayde01 Darryl Dawkins_dawkida01  Diamond Stone_stonedi01     Eddy Curry_curryed01 
#                 0.2286803                0.1563753                0.0000000                0.1283133 
#LeBron James_jamesle01 
#             0.4866382
source(".../Code_and_data_v1/do_similar_players.R")
do_similar_players(player, alphas, numArchoid, FALSE)
