##### Chapter 8: Association Rules -------------------
# 장바구니 분석의 결과는 연관 규칙의 모음이다.
  # 연관 규칙 : 아이템 집합 사이에 관계에 존재하는 패턴
    # LHS : 규칙을 실행하기 위해 만족돼야 하는 조건
    # RHS : 그 조건을 만족했을 때 기대하는 결과
# 연관 규칙은 예측이 아니라, 대규모 DB에서 자율적인 지식의 발견을 위해 사용된다.
# 연관 구칙 학습자는 자율적이기 때문에, 알고리즘이 훈련될 필요가 없다.
  # 즉 데이터가 사전에 레이블될 필요가 없다.
  # 하지만 학습자에 대해 사용자가 직접 확인하는 것 외에는 규칙 학습자의 성능을 측정할 방법이 없다.

# 연관 규칙 학습을 위한 a priori 알고리즘 (아 프리오리, 선험적인)
  # 쇼핑몰에 물건 100개만 있어도 2^100개의 아이템 집합을 평가해야 함
  # 좀 더 똑똑한 학습 알고리즘은 아이템 집합을 전부 평가하지 않는다.
    # 대신 잠재적인 아이템 조합이 실제로 드물게 발견된다는 사실을 이용한다.
  # 아프리오리 알고리즘은 빈번한 아이템집합의 속성에 대해 단순한 사전적 믿음을 이용한다.리
    # 통계 척도인, 아이템 집합의 흥미도를 이용한다.
      # 이는 어떻게 측정할까? 또 학습될 규칙의 수를 줄이기 위해 아프리오리 속성과 어떻게 결합되는가?
# 장단점
  # 장점
    # 대규모 거래 데이터에 대해 작업 가능
    # 이해하기 쉬운 규칙 생성
    # 데이터 마이닝과 DB에서 예상치 못한 지식 발굴 가능
  # 단점
    # 작은 데이터셋에서는 유용하지 않음
    # 진정한 통찰과 상식을 분리하기 위한 노력이 필요
    # 랜덤 패턴에서 비논리적인 결론을 도출하기 쉽다.
# 규칙 흥미 측정 : 지지도와 신뢰도
  # 지지도와 신뢰도를 사용해, 보고되는 규칙의 갯수를 제한할 수 있다.
    # 확실하거나 상식적인 규칙만 식별될 떄까지 제한하는 것도 가능하다.
  # support(X) = count(X) / N  <- (아이템 집합 X 를 포함하는 거래 건수 / 데이터베이스의 거래 건수)
  # confidence(X -> Y) = support(X,Y)/support(X) (X와 Y를 모두 포함하는 아이템집합의 지지도/X만포함지지도)
    # 신뢰도는 아이템 또는 아이템집합 X의 존재가, 아이템 또는 아이템집합 Y의 존재를 유발하는 거래의 비율
    # confidence(X -> Y) != confidence(Y -> X)
# a priori 원칙을 이용한 규칙 집합의 구축
  # 빈번한 아이템집합의 모든 부분집합 또한 빈번해야 한다.
  # a priori algorithm은 이 논리를 사용해, 실제 평가하기 전에 잠재적인 연관 규칙을 제외시킨다.
  # 규칙을 생성하는 절차
    # 1. 최소 지지도 임계치를 만족하는 모든 아이템 집합을 식별한다.
    # 2. 이 아이템 집합에서 최소 신리도 임계치를 만족하는 아이템 집합으로 규칙을 생성한다.

## Example: Identifying Frequently-Purchased Groceries ----
## Step 2: Exploring and preparing the data ----

# load the grocery data into a sparse matrix
# 거래 데이터는 좀 더 자유로운 형태로 저장되어 있다.
  # 각 레코드는 고정된 개수의 특징 대신, 한 개부터 여러 개까지 쉼표로 분리된 임의의 개수의 아이템목록으로 이루어짐.
install.packages("arules")
library(arules)
getwd()
setwd("D:/R_LAB/MlwR/Chapter 08")
# 그냥 read.csv로 읽으면 나중에 문제가 생긴다
  # 첫 번째 줄이 네 개의 값을 가졌기 때문에 R은 생성해야 할 네 변수를 생성했다. -> 더 많이 사면 잘린다
  # 거래를 특정 아이템으로 채우는 위치 집합이 아닌,
  # 각 특정 아이템을 포함하거나 포함하지 않는 장바구니로 취급하는 데이터셋이 필요하다.
# 거래 데이터를 위한 희소 행렬(sparse matrix)생성
  # 희소 행렬은 의미있는 셀에 비해 0이 너무 많기 떄문에, 전체 행렬을 통째로 저장하는 것은 비효율적이다.(170만개)
  # 희소 행렬 구조를 만들기 위해 arules 패키지를 사용하자.
groceries <- read.transactions("groceries.csv", sep = ",")
summary(groceries)# 0이 아닌 값 2.6%
# look at the first five transactions
  # 희소 행렬의 내용을 보려면 inspect 함수를 벡터 연산과 결합해 사용.
inspect(groceries[1:5])

# examine the frequency of items
itemFrequency(groceries[, 1:3])

# plot the frequency of items(아이템 빈도 그래프)
itemFrequencyPlot(groceries, support = 0.1) # 최소 10% 지지도 갖는 8개 아이템
itemFrequencyPlot(groceries, topN = 20) # 지지도 가장 높은 20개

# a visualization of the sparse matrix for the first five transactions
  # 5행 169열의 행렬. 5건의 거래와 169개의 가능한 아이템을 나타낸다.
image(groceries[1:5])

# visualization of a random sample of 100 transactions
image(sample(groceries, 100)) # 거래 100건에 대한 희소 행렬 시각화

## Step 3: Training a model on the data ----
library(arules)

# default settings result in zero rules learned
# 실행하는 것 자체는 간단하지만, 합리적인 개수와 연관 규칙을 생성하는 지지도, 신뢰도 찾기는 시행착오 필요
  # 파라미터의 수준이 너무 높은 경우
    # 규칙을 찾지 못하거나 너무 포괄적인 규칙만을 찾음(숟가락 옆에 젓가락 놓아봐야 다 안다)
  # 파라미터의 수준이 너무 낮은 경우
    # 규칙이 너무 많아져서 통제 힘듦, 혹은 메모리 부족
arules::apriori(groceries, parameter = # minlen은 요구되는 최소 규칙 아이템
                  list(support = 0.1, confidence = 0.8, minlen = 1))우 # default setting -> nothing learned

# set better support and confidence levels to learn more rules
# 최소 지지도 임계치를 다루는 방법
  # ex)한달 동안 하루 2번 구입되면 60회, 9835회 중 60회는 0.006
# 최소 신뢰도 임계치를 다루는 방법(일단 0.25로 시작)
  # 너무 낮으면 규칙 너무 많아짐, 너무 높으면 뻔한 규칙
groceryrules <- apriori(groceries, parameter = list(support =
                          0.006, confidence = 0.25, minlen = 2))
groceryrules # 규칙 463

## Step 4: Evaluating model performance ----
# summary of grocery association rules
summary(groceryrules)
# 대부분 또는 모든 규칙이 최소 임계치 바로 근처에서 지지도와 신뢰도를 갖는다면
  # 기준을 너무 높게 설정했다는 것을 의미 -> 재조정 필요
  # lift(X -> Y) = confidence(X ->Y)/support(Y)
    # 향상도는 어떤 아이템(집합) X가 구매됐다는 것을 안다면, 다른 아이템(집합)Y가 어떤 확률로 구매될 것인가를
    # Y의 일반적인 구매 확률과 비교해 측정한다.
    # 아이템 순서가 중요한 신뢰도와는 달리, 향상도는 순서가 달라도 동일하다.

# look at the first three rules
inspect(groceryrules[1:3])
# 논리적으로 potted plant -> whole milk는 말이 안되지만, 데이터는 이 규칙이 믿을만 하다고 말하고 있다.
# 일반적인 방법은, 연관 규칙을 받아 다음 세 가지 범주로 규칙을 나누는 것이다.
  # 실행 가능한
  # 사소한(기저귀 -> 분유)
  # 설명하기 어려운(연관성 불명확. 단순히 데이터에 있는 랜덤 패턴일 수도 있다.)
# 충분한 시간이 있다면 숨겨진 보석 규칙을 위해 모든 규칙을 평가할 수 있다.
  # 하지만 분석가는 규칙이 어떤지까지는 잘 모를 수도 있다.
  # 가장 흥미로운 결과가 상단에 표시되도록, 학습된 규칙을 정렬하고 공유하자.

## Step 5: Improving model performance ----

# sorting grocery rules by lift
  # sort()함수로 by 파라미터에 lift를 넣어서, lift가 가장 높은 순서대로 5개를 출력시켰다.
inspect(sort(groceryrules, by = "lift")[1:5])

# finding subsets of rules containing any berry items
# subset()함수는 거래, 아이템, 규칙의 부분집합을 찾는 방법을 제공한다.
berryrules <- subset(groceryrules, items %in% "berries") # 베리가 들어간 규칙만 부분집합으로 뽑음
inspect(berryrules) # 규칙 출력. lift 높은 두 규칙은 실행 가능해 보인다.
# subset() 사용법
  # items %in% 쓰면 좌측, 우측 모두 포함되기만 하면 뽑는다.
    # 좌측에만 해당되게 하려면 item 대신 lhs, 우측은 rhs
  # 연산자 %in%은 아이템 중 최소 하나가 정의된 목록에서 발견돼야만 한다.
    # 두 개 하고 싶으면 %in% c("berries", "yogurt")로 넣자.
  # %ain%으로 완전 매칭(베리, 요거트 둘 다 있는 규칙만 찾기)
  # %pin%으로 부분 매칭(%pin% fruit로 그냥 과일이랑 열대 과일 같이 찾기)
  # 부분집합은 support, confidence, lift로 제약 가능
  # 매칭 조건은 %, |, !같은 표준 R 논리 연산자와 결합 가능

# writing the rules to a CSV file
write(groceryrules, file = "groceryrules.csv",
      sep = ",", quote = TRUE, row.names = FALSE)

# converting the rule set to a data frame
groceryrules_df <- as(groceryrules, "data.frame")
str(groceryrules_df)


\name{generate_simulated_data_from_estimated_model}
\alias{generate_simulated_data_from_estimated_model}
%- Also NEED an '\alias' for EACH other topic documented here.
\title{
 Generating simulated data from a fitted model
}
\description{
  This function generates simulated networks from a fitted model and performs estimations on these simulated networks with the same setting used in the original estimation. Each simulated network is generated using parameters of the fitted model, while keeping other aspects of the growth process as faithfully as possible to the original observed network.
}
\usage{
generate_simulated_data_from_estimated_model(net_object, net_stat, result, M = 5)
}
%- maybe also 'usage' for other objects documented here.
\arguments{
  \item{net_object}{
    an object of class \code{PAFit_net} that contains the original network.
  }
  \item{net_stat}{
    An object of class \code{PAFit_data} which contains summarized statistics of the original network. This object is created by the function \code{\link{get_statistics}}.
  }
   \item{result}{
    An object of class \code{Full_PAFit_result} which contains the fitted model obtained by applying the function \code{\link{joint_estimate}}.
  }
\item{M}{integer. The number of simulated networks. Default value is \code{5}.}
}

\value{
  Outputs a \code{Simulated_Data_From_Fitted_Model} object, which is a list containing the following fields:
  \itemize{
    \item \code{graph_list}: a list containing \code{M} simulated graphs.

    \item \code{stats_list}: a list containing \code{M} objects of class \code{PAFit_data}, which are the results of applying \code{\link{get_statistics}} on the simulated graphs.
    \item \code{result_list}: a list containing \code{M} objects of class \code{Full_PAFit_result}, which are the results of applying \code{\link{joint_estimate}} on the simulated graphs.
}
}

\author{
  Thong Pham \email{thongphamthe@gmail.com}
}
\references{
  1. Pham, T., Sheridan, P. & Shimodaira, H. (2015). PAFit: A Statistical Method for Measuring Preferential Attachment in Temporal Complex Networks. PLoS ONE 10(9): e0137796. (\doi{10.1371/journal.pone.0137796}).

  2. Pham, T., Sheridan, P. & Shimodaira, H. (2016). Joint Estimation of Preferential Attachment and Node Fitness in Growing Complex Networks. Scientific Reports 6, Article number: 32558. (\doi{10.1038/srep32558}).

 3. Pham, T., Sheridan, P. & Shimodaira, H. (2020). PAFit: An R Package for the Non-Parametric Estimation of Preferential Attachment and Node Fitness in Temporal Complex Networks. Journal of Statistical Software 92 (3). (\doi{10.18637/jss.v092.i03}).

4. Inoue, M., Pham, T. & Shimodaira, H. (2020). Joint Estimation of Non-parametric Transitivity and Preferential Attachment Functions in Scientific Co-authorship Networks. Journal of Informetrics 14(3). (\doi{10.1016/j.joi.2020.101042}).
}
\seealso{
 \code{\link{get_statistics}}, \code{\link{joint_estimate}}, \code{\link{plot_contribution}}
}

\examples{
\dontrun{

  library("PAFit")
  net_object     <- generate_net(N = 500, m = 10, s = 10, alpha = 0.5)
  net_stat       <- get_statistics(net_object)
  result         <- joint_estimate(net_object, net_stat)
  simulated_data <- generate_simulated_data_from_estimated_model(net_object, net_stat, result)
  plot_contribution(simulated_data, result, which_plot = "PA")
  plot_contribution(simulated_data, result, which_plot = "fit")
  }
}

\concept{preferential attachment}
\concept{attachment function}
\concept{fitness}


## Function to do Wright-Fisher simulation with selection and a finite sample size
# using priors on Ne, s, and initial allele frequency
# Sample at two time points

# i is a dummy argument so that it can be used with sapply and parSapply
# f1min: the minimum for the initial allele frequency uniform prior
# f1max:
# smin: the minimum for the selection coefficient uniform prior
# smax:
# c1: the size of the first sample (in # chromosomes)
# c2: the size of the second sample (in # chromosomes)
# gen: the number of generations
# ne: a vector of possible Ne values. Simulation picks one to use.
# h: dominance effect

wfs <- function(i, f1min=0, f1max=1, smin=-1, smax=1, c1=58, c2=48, gen=20, ne=100, h=0.5){
	# choose parameters for this simulation
	f1 <- runif(1, min=f1min, max=f1max) # starting allele frequency
	s <- runif(1, min=smin, max=smax) # selection coefficient
	if(length(ne)>1) thisne <- round(sample(ne, 1)) # ne has to be integer for binomial sampling
	if(length(ne)==1) thisne <- round(ne)

#	print(paste(f1, s, thisne))

	p <- f1 # current allele frequency
	waa <- 1+s # relative fitness of genotype AA
	wab <- 1+s*h
	wbb <- 1
	for(i in 1:gen){
		x <- (waa*p^2 + wab*p*(1-p))/(waa*p^2 + wab*2*p*(1-p) + wbb*(1-p)^2) # probability of sampling allele A, given selection
		p <- rbinom(1,thisne,x)/thisne
#		print(paste(x,p))
	}
	f2 <- p

	f1samp <- rbinom(1,c1,f1)/c1 # first sample allele frequency
	f2samp <- rbinom(1,c2,f2)/c2 # second sample allele frequency

	# return values
	out <- c(ne=thisne, f1=f1, s=s, gen=gen, f2=f2, f1samp=f1samp, f2samp=f2samp)
	return(out)
}


#Analyses for Tutorial 05: Discrete PCMs

## 1: Read data, tree, and prune/match one to the other
library(geiger) #also loads ape
library(phytools)

#Here is a large time-dated molecular phylogeny (a chronogram):
tree<-read.tree("TutorialData/tree.64.tre",tree.names=T)
plot(tree, show.tip.label = FALSE)
mydata<-read.csv('TutorialData/DiscreteData.csv', row.names=1, header=TRUE)
mydata[1:10,]

#Match data with tree
data.pruned<-treedata(phy=tree,data = mydata, warnings=FALSE)
tree<-data.pruned$phy
mydata<-data.pruned$data

#Plot data on tree
plot.phylo(tree,show.tip.label = F)
tiplabels(pie = to.matrix(mydata[,1],sort(unique(mydata[,1]))),piecol=c("red", "black"),cex=.3, offset=0)
tiplabels(pie = to.matrix(mydata[,3],sort(unique(mydata[,1]))),piecol=c("green", "orange"),cex=.3, offset=.2)

#####1: Single trait analysis: transition rate comparison
library(corHMM)
   #Set up initial rate matrices
rmat.er<-rate.mat.maker(rate.cat=1, hrm=FALSE, ntraits=1, nstates=2, model="ER")  #equal transition rates
rmat.ard<-rate.mat.maker(rate.cat=1, hrm=FALSE, ntraits=1, nstates=2, model="ARD") #unequal transition rates
rmat.er   #all rates the same
rmat.ard  #all rates different
   #Set up data
trt1<-cbind(row.names(mydata),mydata[,1])
trt2<-cbind(row.names(mydata),mydata[,3])
trt3<-cbind(row.names(mydata),mydata[,5])

#Fit models: TRAIT 1
plot.phylo(tree,show.tip.label = F)
tiplabels(pie = to.matrix(mydata[,1],sort(unique(mydata[,1]))),piecol=c("red", "black"),cex=.3, offset=0)
res1.er<-corHMM(tree,trt1,rate.cat=1,rate.mat=rmat.er,node.states="marginal")
res1.er
res1.ard<-corHMM(tree,trt1,rate.cat=1,rate.mat=rmat.ard,node.states="marginal")
   #compare models: logL and AIC
res1.er$loglik
res1.ard$loglik  #identical in this case: no need for formal LRT
res1.er$AICc
res1.ard$AICc    #Choose simpler model (lower AICc b/c fewer parameters and same logL)
res1.er$solution  #rate transition parameters

#Fit models: TRAIT 2
plot.phylo(tree,show.tip.label = F)
tiplabels(pie = to.matrix(mydata[,3],sort(unique(mydata[,3]))),piecol=c("red", "black"),cex=.3, offset=0)
res2.er<-corHMM(tree,trt2,rate.cat=1,rate.mat=rmat.er,node.states="marginal")
res2.ard<-corHMM(tree,trt2,rate.cat=1,rate.mat=rmat.ard,node.states="marginal")
#compare models: logL and AIC
res2.er$loglik
res2.ard$loglik  #identical in this case: no need for formal LRT
res2.er$AICc
res2.ard$AICc    #Choose simpler model (lower AICc b/c fewer parameters and same logL)
res2.er$solution  #rate transition parameters

#Fit models: TRAIT 3
plot.phylo(tree,show.tip.label = F)
tiplabels(pie = to.matrix(mydata[,5],sort(unique(mydata[,5]))),piecol=c("red", "black"),cex=.3, offset=0)
res3.er<-corHMM(tree,trt3,rate.cat=1,rate.mat=rmat.er,node.states="marginal")
res3.ard<-corHMM(tree,trt3,rate.cat=1,rate.mat=rmat.ard,node.states="marginal")
#compare models: logL and AIC
res3.er$loglik
res3.ard$loglik
LRT<- -2*(res3.er$loglik - res3.ard$loglik)  #LRT test
LRT
1-pchisq( LRT,df = 1)  #probability of LRT
res3.er$AICc
res3.ard$AICc    #ARD preferred
res3.ard$solution  #rate transition parameters
   #transition from

#####2: Two trait analysis: Trait association
#Compare dependent (correlated) change model (ARD) with independent change model (ER)  #See Pagel 1994
trtset12<-cbind(row.names(mydata),mydata[,1:2])
trtset34<-cbind(row.names(mydata),mydata[,3:4])

#Traits 1&2
plot.phylo(tree,show.tip.label = F)
tiplabels(pie = to.matrix(mydata[,1],sort(unique(mydata[,1]))),piecol=c("red", "black"),cex=.3, offset=0)
tiplabels(pie = to.matrix(mydata[,2],sort(unique(mydata[,2]))),piecol=c("green", "orange"),cex=.3, offset=0.2)
disc.res12.er<-corDISC(tree,trtset12,ntraits=2,model="ER",node.states="marginal")
disc.res12.ard<-corDISC(tree,trtset12,ntraits=2,model="ARD",node.states="marginal")
disc.res12.er$loglik
disc.res12.ard$loglik
LRT<- -2*(disc.res12.er$loglik - disc.res12.ard$loglik)  #LRT test
1-pchisq( LRT,df = 4)  #probability of LRT
disc.res12.er$AIC
disc.res12.ard$AIC   #STRONG SUPPORT for correlated (dependent) evolution
   #Implemented in phytools
tr1<-mydata[,1]; names(tr1)<-row.names(mydata)
tr2<-mydata[,2]; names(tr2)<-row.names(mydata)
disc.res12.b<-fitPagel(tree,x=tr1,y=tr2)
disc.res12.b
  #NOTE: LOOK AT PHYLOGENY AND DATA HERE!  WE have strong support for correlated evolution, but both traits are co-distributed and clustered
    #essentially, 1 evolutionary shift could explain the pattern: the 'BiSSE' problem (need ancestral state estimation: next week)
 ##### ALWAYS PLOT YOUR DATA! DON'T JUST RUN STATISTICS (statistical anlaysis alone here leads to mis-interpretation)

#Traits 3&4
plot.phylo(tree,show.tip.label = F)
tiplabels(pie = to.matrix(mydata[,3],sort(unique(mydata[,3]))),piecol=c("red", "black"),cex=.3, offset=0)
tiplabels(pie = to.matrix(mydata[,4],sort(unique(mydata[,4]))),piecol=c("green", "orange"),cex=.3, offset=0.2)
disc.res34.er<-corDISC(tree,trtset34,ntraits=2,model="ER",node.states="marginal")
disc.res34.ard<-corDISC(tree,trtset34,ntraits=2,model="ARD",node.states="marginal")
disc.res34.er$loglik
disc.res34.ard$loglik
disc.res34.er$AIC
disc.res34.ard$AIC # VERY STRONG SUPPORT FOR CORRELATED EVOLUTION

#####3: Two trait analysis: Order to transitions matters (changes in trait 2 DEPEND on values of trait 1: Maddison 1990)
  #Must define the two models for comparison
plot.phylo(tree,show.tip.label = F)
tiplabels(pie = to.matrix(mydata[,3],sort(unique(mydata[,3]))),piecol=c("red", "black"),cex=.3, offset=0)
tiplabels(pie = to.matrix(mydata[,4],sort(unique(mydata[,4]))),piecol=c("green", "orange"),cex=.3, offset=0.2)
eq.rat<-rate.mat.maker(rate.cat=1, hrm=FALSE, ntraits=2, nstates=2, model="ER")
eq.rat
dir.rat<-eq.rat; dir.rat[1,2]<-2; dir.rat[3,4]<-3  #e.g., q12<>q34: see Table in Pagel 1994
dir.rat
  #NOTE: which values are allowed to differ dependently depends upon the directional hypothesis under investigation!

disc.res34.er<-corDISC(tree,trtset34,ntraits=2,model="ER",node.states="marginal")
disc.res34.dir<-corDISC(tree,trtset34,ntraits=2,model="ER",rate.mat=dir.rat,node.states="marginal") #run with directional hypothesis
disc.res34.er$loglik
disc.res34.dir$loglik
disc.res34.er$AIC
disc.res34.dir$AIC # # VERY STRONG SUPPORT FOR DIRECTIONAL DEPENDENT EVOLUTION


##Set Working Directory
setwd("C:/Users/GitHubRepository/scwrp-rsu-slr-model")

##Set Desired Output Directory
OutputDirectory="C:/Users/GitHubRepository/scwrp-rsu-slr-model/model output/"
  #This directory is set as a variable that will be used below to output the model data
  #Suggested output directory is a subdirectory of the working directory
  #Output directory path must end with a forward slash "/"

##############################################################################
#Part 1
##Import csv with input data for all sites in the region
input <- read.csv(file="SLR_Model_Inputs.csv", head=TRUE, sep=",")

##Create input variables for model
#Time points for baseline and SLR projections
t0 <- 2016
t1 <- 2050
t2 <- 2100

##Relative SLR (mm/yr)
SL2050 <-input$SLR_2050_mmyr*(t1-t0)
SL2100 <-input$SLR_2100_mmyr*(t2-t0)

##Accretion: inputs from Lit Review (mm/yr)
Acr2050 <- input$Accretion_mmyr*(t1-t0)
Acr2100 <- input$Accretion_mmyr*(t2-t0)

##Change in Elevation (m)
Elev2050 <- Acr2050*0.001 #convert accretion to m
Elev2100 <- Acr2100*0.001

##Change in Water level: inputs from rSLR and Mouth Dynamics Modeling
#Mouth Dynamics contribution (m)
MD2050 <- input$MD_WL_2050
MD2100 <- input$MD_WL_2100

#Change in Water level (m)
WL2050 <-(SL2050*0.001)+(MD2050) #SLR contribution (m)
WL2100 <-(SL2100*0.001)+(MD2100)

#Intermediate outputs for elevation and water level
output <-cbind(input, Elev2050, Elev2100, WL2050, WL2100)
  #Appends elevation and water level calculations per site to input data

##Hypsometric curves
Hyps <- read.csv(file="Hypsometry.csv", head=TRUE, sep=",")
  #Import long-format csv containing hypsometrtic curves (standardized to Z*) for all sites in the region

###Z breaks, by archetype
zbreaks <- read.csv(file="Zbreaks_Archetypes.csv", head=TRUE, sep=",")

##############################################################################
#Part 2
#Create list of sites from input/intermediate output
Sites=output$Site_Name
Sites = levels(Sites)

for (i in 1:length(Sites)){

  #SITE Inputs
  Site = subset(Hyps, Name==Sites[i]) #extracts site hypsometry data
  PC = subset(output, Site_Name==Sites[i], select=Perch.Correction) #site perch correction
  z.bin.max.pc = Site$z.bin.max - (PC[1,1]*1.25) #adjusts Z* (elevation) to correct for perched systems
  Site = cbind.data.frame(Site, z.bin.max.pc) #appends adjusted Z* (elevation)
  Site_archetype = subset(output, Site_Name==Sites[i], select=ArchetypeCode) #Site-specific archetype classification

  ##Archetype-specific Z* breaks
  z.subtidal=subset(zbreaks, Arch_Code==Site_archetype[1,1], select="Subtidal")
  z.mudflat=subset(zbreaks, Arch_Code==Site_archetype[1,1], select="Intertidal.Mudflat")
  z.low=subset(zbreaks, Arch_Code==Site_archetype[1,1], select="Low.Marsh")
  z.mid=subset(zbreaks, Arch_Code==Site_archetype[1,1], select="Mid.Marsh")
  z.high=subset(zbreaks, Arch_Code==Site_archetype[1,1], select="High.Marsh")
  z.trans=subset(zbreaks, Arch_Code==Site_archetype[1,1], select="Transition")
  z.stop=subset(zbreaks, Arch_Code==Site_archetype[1,1], select="Stop")

  #Calculate current area
  subtidal=with(Site, sum(Site[z.bin.max.pc<z.mudflat[1,1], "area.km2"]))
  shallowsubtidal=with(Site, sum(Site[z.bin.max.pc>=z.subtidal[1,1] & z.bin.max.pc<z.mudflat[1,1], "area.km2"]))
  mudflat=with(Site, sum(Site[z.bin.max.pc>=z.mudflat[1,1] & z.bin.max.pc<z.low[1,1], "area.km2"]))
  low=with(Site, sum(Site[z.bin.max.pc>=z.low[1,1] & z.bin.max.pc<z.mid[1,1], "area.km2"]))
  mid=with(Site, sum(Site[z.bin.max.pc>=z.mid[1,1] & z.bin.max.pc<z.high[1,1], "area.km2"]))
  high=with(Site, sum(Site[z.bin.max.pc>=z.high[1,1] & z.bin.max.pc<z.trans[1,1], "area.km2"]))
  trans=with(Site, sum(Site[z.bin.max.pc>=z.trans[1,1] & z.bin.max.pc<z.stop[1,1], "area.km2"]))

  ##Site-specific Change in Z* breaks = CHANGE IN WATER LEVEL
  #convert m to z* = 1.25
  WL2050=subset(output, Site_Name==Sites[i], select=WL2050)
  WL2100=subset(output, Site_Name==Sites[i], select=WL2100)

  z.shallowsubtidal.2050=z.subtidal+((SL2050*0.001)*1.25)
  z.mudflat.2050=z.mudflat+(WL2050*1.25)
  z.low.2050=z.low+(WL2050*1.25)
  z.mid.2050=z.mid+(WL2050*1.25)
  z.high.2050=z.high+(WL2050*1.25)
  z.trans.2050=z.trans+(WL2050*1.25)
  z.stop.2050=z.stop+(WL2050*1.25)

  z.shallowsubtidal.2100=z.subtidal+((SL2100*0.001)*1.25)
  z.mudflat.2100=z.mudflat+(WL2100*1.25)
  z.low.2100=z.low+(WL2100*1.25)
  z.mid.2100=z.mid+(WL2100*1.25)
  z.high.2100=z.high+(WL2100*1.25)
  z.trans.2100=z.trans+(WL2100*1.25)
  z.stop.2100=z.stop+(WL2100*1.25)

  ##Site-specific Change in Z* bin max = CHANGE IN ELEVATION (m)
  Elev2050=subset(output, Site_Name==Sites[i], select=Elev2050)
  Elev2100=subset(output, Site_Name==Sites[i], select=Elev2100)

  ##Apply accretion to all marsh zones
  z.bins.2050=(Site$z.bin.max.pc+(Elev2050[1,1]*1.25))
  z.bins.2100=(Site$z.bin.max.pc+(Elev2100[1,1]*1.25))

  ##Site-specific output: future hypsometry
  Hyps_future=cbind(Site,z.bins.2050,z.bins.2100)
  #Set output directory to "SCWRP RSU SLR Model Output" folder
  dirname = paste(OutputDirectory, Sites[i],"/",sep="")
  filename = paste(dirname, Sites[i],"_hypsometry.csv",sep="")
  dir.create(file.path(dirname),recursive=TRUE)
  #write.csv(Hyps_future, file=filename) #option to write hypsometry data

  #Caluculate 2050 area
  subtidal_2050=with(Hyps_future, sum(Hyps_future[z.bins.2050<z.mudflat.2050[1,1], "area.km2"]))
  #shallowsubtidal_2050=with(Hyps_future, sum(Hyps_future[z.bins.2050>=z.shallowsubtidal.2050[1,1] & z.bins.2050<z.mudflat.2050[1,1], "area.km2"]))
  mudflat_2050=with(Hyps_future, sum(Hyps_future[z.bins.2050>=z.mudflat.2050[1,1] & z.bins.2050<z.low.2050[1,1], "area.km2"]))
  low_2050=with(Hyps_future, sum(Hyps_future[z.bins.2050>=z.low.2050[1,1] & z.bins.2050<z.mid.2050[1,1], "area.km2"]))
  mid_2050=with(Hyps_future, sum(Hyps_future[z.bins.2050>=z.mid.2050[1,1] & z.bins.2050<z.high.2050[1,1], "area.km2"]))
  high_2050=with(Hyps_future, sum(Hyps_future[z.bins.2050>=z.high.2050[1,1] & z.bins.2050<z.trans.2050[1,1], "area.km2"]))
  trans_2050=with(Hyps_future, sum(Hyps_future[z.bins.2050>=z.trans.2050[1,1] & z.bins.2050<z.stop.2050[1,1], "area.km2"]))

  #Calculate 2100 area
  subtidal_2100=with(Hyps_future, sum(Hyps_future[z.bins.2100<z.mudflat.2100[1,1], "area.km2"]))
  #shallowsubtidal_2100=with(Hyps_future, sum(Hyps_future[z.bins.2100>=z.shallowsubtidal.2100[1,1] & z.bins.2100<z.mudflat.2100[1,1], "area.km2"]))
  mudflat_2100=with(Hyps_future, sum(Hyps_future[z.bins.2100>=z.mudflat.2100[1,1] & z.bins.2100<z.low.2100[1,1], "area.km2"]))
  low_2100=with(Hyps_future, sum(Hyps_future[z.bins.2100>=z.low.2100[1,1] & z.bins.2100<z.mid.2100[1,1], "area.km2"]))
  mid_2100=with(Hyps_future, sum(Hyps_future[z.bins.2100>=z.mid.2100[1,1] & z.bins.2100<z.high.2100[1,1], "area.km2"]))
  high_2100=with(Hyps_future, sum(Hyps_future[z.bins.2100>=z.high.2100[1,1] & z.bins.2100<z.trans.2100[1,1], "area.km2"]))
  trans_2100=with(Hyps_future, sum(Hyps_future[z.bins.2100>=z.trans.2100[1,1] & z.bins.2100<z.stop.2100[1,1], "area.km2"]))

  #Create and export Site-specific output:  habitat area for current, 2050, 2100
  #Aggregate marsh zones to NWI Classes: Sudtidal water, estuarine unvegetated wetland, estuarine vegetated wetland
  Area_output_NWI= cbind.data.frame(Habitat=c("Subtidal Water","Estuarine Unvegetated Wetland","Estuarine Vegetated Wetland"),
                                Current=c(rbind(subtidal, mudflat, sum(low, mid, high))),
                                SLR2050=c(rbind(subtidal_2050, mudflat_2050, sum(low_2050, mid_2050, high_2050))),
                                SLR2100=c(rbind(subtidal_2100, mudflat_2100, sum(low_2100, mid_2100, high_2100))))

  filename2 = paste(dirname, Sites[i],"_area_NWIclasses.csv",sep="")
  write.csv(Area_output_NWI, file=filename2)
}


x <- as.double(readline(prompt = "Enter x:"))
m <- as.double(readline(prompt = "Enter mean:"))
s <- as.double(readline(prompt = "Enter sigma:"))

# compute f(x)
first_part = 1 / (s * sqrt(2 * pi))
power_part = - (x - m) ^ 2 / 2 * s ^ 2

f_x = first_part * exp(power_part)

print('f(x) is')
print(f_x)


\name{PAFit_oneshot}
\alias{PAFit_oneshot}
%- Also NEED an '\alias' for EACH other topic documented here.
\title{
 Estimating the nonparametric preferential attachment function from one single snapshot.
}
\description{
  This function estimates the attachment function \eqn{A_k} from one snapshot.
}
\usage{

PAFit_oneshot(net_object,
              M    = 10,
              S    = 5,
              loop = 5,
              G    = 1000)
}
%- maybe also 'usage' for other objects documented here.
\arguments{
 \item{net_object}{
    an object of class \code{PAFit_net} that contains the network. Any time-step information, if available, will be ignored.
  }
   \item{M}{
  Integer. Number of simulated networks in each iteration. Default is \code{10}.
  }
  \item{S}{
  Integer. Number of iterations inside each loop. Default is \code{5}.
  }
  \item{loop}{
  Integer. Number of loops of the whole process. Default is \code{5}.
  }
    \item{G}{
  Integer. Number of bins for the PA function. Default is \code{1000}.
  }
}

\value{
   Outputs a \code{PAFit_result} object.
}

\author{
  Thong Pham \email{thongphamthe@gmail.com}
}
\references{
1. Pham, T., Sheridan, P. & Shimodaira, H. (2021). Non-parametric estimation of the preferential attachment function from one network snapshot. Journal of Complex Networks 9(5): cnab024. (\doi{10.1093/comnet/cnab024}).

%  2. Pham, T., Sheridan, P. & Shimodaira, H. (2016). Joint Estimation of Preferential Attachment and Node Fitness in Growing Complex Networks. Scientific Reports 6, Article number: 32558. doi:10.1038/srep32558   (\url{http://www.nature.com/articles/srep32558}).

% 3. Pham, T., Sheridan, P. & Shimodaira, H. (2020). PAFit: An R Package for the Non-Parametric Estimation of Preferential Attachment and Node Fitness in Temporal Complex Networks. Journal of Statistical Software 92 (3), doi:10.18637/jss.v092.i03. (\url{http://dx.doi.org/10.18637/jss.v092.i03})
}
%\seealso{
%  See \code{\link{get_statistics}} for how to create summerized statistics needed in this function.

%  See \code{\link{Jeong}}, \code{\link{Newman}} and \code{\link{only_A_estimate}} for functions to estimate the attachment function in isolation.

%    See \code{\link{only_F_estimate}} for a function to estimate node fitnesses in isolation.
%}

\examples{
\dontrun{
  library("PAFit")
  net_1    <- generate_BA(N = 10000, alpha = 1) # true attachment exponent = 1.0
  result_1 <- PAFit_oneshot(net_1)
  print(result_1)

  net_2    <- generate_BA(N = 10000, alpha = 0.5) # true attachment exponent = 0.5
  result_2 <- PAFit_oneshot(net_2)
  print(result_2)
  }
}

\concept{preferential attachment}
\concept{attachment function}


# MIT License
# Copyright (c) 2020 Abhinav Prakash, Vijay Panchang, Yu Ding, and Lewis Ntaimo

# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:

# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.

# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

source("function.r")
inputfile = "assunpink.csv"
outputfile = "Results/assunpink_constrained_MCMC_"
outputplot = "Assunpink Creek"
data_col = 3
year_col = 1
ReferenceYear = 2018
ReturnPeriod = 100
burn_in = 500
CSVFile = read.csv(file = inputfile, header = T)
Data = CSVFile[,data_col]
Year = CSVFile[,year_col]
time_index = time.index(Year,ReferenceYear)
parameters = draw.MCMC.samples(Data,time_index,InitialValues = c(50,1,20,0.8),LocationInterceptPrior = c(0,200),LocationSlopePrior = c(-5,5),ScalePrior = c(0,50),ShapePrior = c(-1,1),ProposalWidth = c(1,.1,1,0.05),n_samples=10000)
parameters = parameters[-c(1:burn_in),]
mu_post = parameters[,1]
muslope_post = parameters[,2]
scale_post = parameters[,3]
shape_post = parameters[,4]
ret_post=rep(-1,length(mu_post))
for (i in 1:length(mu_post)){
  ret_post[i] = calc.nstat.ret.event(mu_post[i],muslope_post[i],scale_post[i],shape_post[i],n = ReturnPeriod,baseyear = ReferenceYear, analysisyear = ReferenceYear, epsilon = 1)
}

bw = c(1.5,0.02,0.5,0.050,25)

### Expected and MAP Values of the parameters and the return event
d_mu = density(mu_post, bw = bw[1])
d_muslope = density(muslope_post, bw = bw[2])
d_scale = density(scale_post, bw= bw[3])
d_shape = density(shape_post, bw = bw[4])
d_retEvent = density(ret_post, bw = bw[5])

mu_exp = mean(mu_post)
mu_map = d_mu$x[which.max(d_mu$y)]
muslope_exp = mean(muslope_post)
muslope_map = d_muslope$x[which.max(d_muslope$y)]
scale_exp = mean(scale_post)
scale_map = d_scale$x[which.max(d_scale$y)]
shape_exp =mean(shape_post)
shape_map = d_shape$x[which.max(d_shape$y)]
retEvent_exp = mean(ret_post)
retEvent_map = d_retEvent$x[which.max(d_retEvent$y)]
NLLH_exp = likelihood.val(Data,time_index,mu_exp,muslope_exp,scale_exp,shape_exp)
NLLH_map = likelihood.val(Data,time_index,mu_map,muslope_map,scale_map,shape_map)
cat("Expected Values of the Parameters:",'\n')
cat("Location Intercept:", mu_exp, '\n')
cat("Location Slope:", muslope_exp, '\n')
cat("Scale:",scale_exp, '\n')
cat("Shape:", shape_exp, '\n')
cat("100 year Return Event:", retEvent_exp, '\n')
cat("NLLH:", NLLH_exp, '\n')
cat('\n',"MAP values of the Parameters:",'\n')
cat("Location Intercept:", mu_map, '\n')
cat("Location Slope:", muslope_map, '\n')
cat("Scale:",scale_map, '\n')
cat("Shape:", shape_map, '\n')
cat("100 year Return Event:", retEvent_map, '\n')
cat("NLLH:", NLLH_map, '\n')


## example conditional logistic regression using Stan
## David C Muller

library(survival)
library(rstan)

set.seed(77834)

## use the infertility data from the survival package
datlist <- list(N=nrow(infert),
                n_grp=max(infert[, "stratum"]),
                n_coef=2,
                x=infert[,c("spontaneous", "induced")],
                y=infert[, "case"],
                grp=infert[, "stratum"])

## fit using default parameters
clogit_stan <- stan("clogit.stan", data=datlist)
clogit_stan

## fit using survival::clogit for comparison
clogit_survival <- clogit(case ~ spontaneous + induced + strata(stratum),
                          data=infert)
summary(clogit_survival)


#########################################################################################################
# Empirical Size simulation Codes of New Combined Threshold Unit Root Test introduced in
#
# "Threshold Unit Root Tests with Smooth Transitions: A Monte Carlo Study"
#
# written by
#
# Dr. Mehmet ÖZCAN
# mehmetozcan@kmu.edu.tr
#
# *NOTES*
# 1)  Caner & Hansen (2001) Threshold Unit Root test and Threshold Effect test
#     programs are taken from Hansen's web page http://www.ssc.wisc.edu/~bhansen/ .
#     However, unit root test program are adjusted to test unit root null hypothesis
#     without any deterministic component.
#
# 2)  There are two indicator which come from Caner & Hansen (2001)'s codes. Caner &
#     Hansen investigate different type of threshol variable type and different trimming
#     intervals. In this study, lagged difference threshold variable and [0.15, 0.85]
#     trimming interval are used for all simulation experiments and empirical application.
#
#     thresh    Type of threshold variable
#  		  1 for long difference,   z(t-1)=y(t-1)-y(t-(m-1))
#  		  2 for lagged difference, z(t-1)=y(t-m)-y(t-m-1)
#  		  3 for lagged level,      z(t-1)=y(t-m)
#     trim      Trimming Range (normalized threshold, lambda)
#  		  1 for [.15,.85]
#  	 	  2 for [.10,.90]
#  		  3 for [.05,.95]
#
#    Other important imputs:
#     rep       Monte-Carlo replication
#     p         Autoregressive Lag Order
#     mmin      Minimal Delay Order for testing
#     mmax      Maximal Delay Order for testing
#     m		    Delay Order (fixed) for estimation. Set to 0 for m to be estimated by maximizing Wald RT statistics.
#
# 3) Results are printed to the screen.
#
# 4) All steps of simulation process are explained below. Please check them before run the codes.
#
# *Instructions*
#
# 1) First, please install required R packcages stated below.
# 2) You could simulate different parameter settings. Please check "simulation settings" part blow.
# 3) This codes includes critical values for T=100 and T=200.
# 4) Run all codes
#
#
#########################################################################################################
# Required Packcages
library(nloptr)
#########################################################################################################
# Required Functions
#########################################################################################################

# Size DGP
CHSizeDGP <- function(n,a){
    n <- n+1
    et<- as.matrix(rnorm(n))
    et<- et-mean(et)

    dyt <- matrix(0,n,1)
    for(i in 2:n) dyt[i] <- (a*dyt[i-1])+et[i]

    yo <- matrix(0,n,1)
    for(i in 2:n) yo[i]<-yo[i-1]+dyt[i]
    yo<-as.matrix(yo[2:n])
}

# Starting value estimation for LNV(1998) Models (A, B & C) #
startLNV<-function(dta){
tt<-length(dta)
tr<-as.matrix(c(1:tt))
cc<-as.matrix(rep(1,tt))

tauGs<-c()
for(kk in 1:tt){ tauGs[kk]<-(kk/tt) }
gamaGs<-seq(1,10,1)

SSRA<-matrix(0,length(tauGs),length(gamaGs))
SSRB<-matrix(0,length(tauGs),length(gamaGs))
SSRC<-matrix(0,length(tauGs),length(gamaGs))

for(vk in 1:3){
for(vi in 1:(length(gamaGs))){
for(vj in 1:(length(tauGs))){
st<-as.matrix((1/(1+exp(-(gamaGs[vi])*((tr)-(tauGs[vj]*tt))))))
if(vk==1){X<-as.matrix(cbind(cc,st))}
if(vk==2){X<-as.matrix(cbind(cc,tr,st))}
if(vk==3){X<-as.matrix(cbind(cc,tr,st,(tr*st)))}
XX<-(MASS:::ginv(t(X)%*%X, tol=1e-25))
betas<-XX%*%(t(X)%*%dta)
Yhat<-t((t(betas)%*%t(X)))
ehat<-(dta-Yhat)
if(vk==1){SSRA[vj,vi]<-sum((ehat)^2)}
if(vk==2){SSRB[vj,vi]<-sum((ehat)^2)}
if(vk==3){SSRC[vj,vi]<-sum((ehat)^2)}
}
}
}

for(vs in 1:3){
if(vs==1){posA<-which(SSRA == min(SSRA), arr.ind = TRUE);
st<-as.matrix((1/(1+exp(-(gamaGs[posA[2]])*((tr)-(tauGs[posA[1]]*tt))))));
X<-as.matrix(cbind(cc,st))}
if(vs==2){posB<-which(SSRB == min(SSRB), arr.ind = TRUE);
st<-as.matrix((1/(1+exp(-(gamaGs[posB[2]])*((tr)-(tauGs[posB[1]]*tt))))));
X<-as.matrix(cbind(cc,tr,st))}
if(vs==3){posC<-which(SSRC == min(SSRC), arr.ind = TRUE);
st<-as.matrix((1/(1+exp(-(gamaGs[posC[2]])*((tr)-(tauGs[posC[1]]*tt))))));
X<-as.matrix(cbind(cc,tr,st,(tr*st)))}

XX<-(MASS:::ginv(t(X)%*%X, tol=1e-25))

if(vs==1){betasA<-XX%*%(t(X)%*%dta);
betasA<-rbind(betasA,gamaGs[posA[2]],tauGs[posA[1]])}
if(vs==2){betasB<-XX%*%(t(X)%*%dta);
betasB<-rbind(betasB,gamaGs[posB[2]],tauGs[posB[1]])}
if(vs==3){betasC<-XX%*%(t(X)%*%dta);
betasC<-rbind(betasC,gamaGs[posC[2]],tauGs[posC[1]])}
}
list(betasA=betasA, betasB=betasB, betasC=betasC)
}

# LNV(1998) Models (A, B & C) Estimation with Sequential Quadratic Programing
estLNV<-function(yt, X, b0a, b0b, b0c){
tt<-length(yt)
stabA<-function(b){sum((yt-(b[1]*X[,1]+b[2]*(1/(1+exp(-(b[3])*((X[,2])-b[4]*tt))))))^2)}
stabB<-function(b){sum((yt-(b[1]*X[,1]+b[2]*X[,2]+b[3]*(1/(1+exp(-(b[4])*((X[,2])-b[5]*tt))))))^2)}
stabC<-function(b){sum((yt-(b[1]*X[,1]+b[2]*X[,2]+b[3]*(1/(1+exp(-(b[5])*((X[,2])-b[6]*tt))))+
b[4]*(X[,2])*(1/(1+exp(-(b[5])*((X[,2])-b[6]*tt))))))^2)}

lba<-c(-Inf,-Inf,0,0)
uba<-c(Inf,Inf,Inf,1)

lbb<-c(-Inf,-Inf,-Inf,0,0)
ubb<-c(Inf,Inf,Inf,Inf,1)

lbc<-c(-Inf,-Inf,-Inf,-Inf,0,0)
ubc<-c(Inf,Inf,Inf,Inf,Inf,1)

SA<-nloptr:::slsqp(b0a,fn=stabA,lower=lba,upper=uba, control=list(xtol_rel=1e-25))
SB<-nloptr:::slsqp(b0b,fn=stabB,lower=lbb,upper=ubb, control=list(xtol_rel=1e-25))
SC<-nloptr:::slsqp(b0c,fn=stabC,lower=lbc,upper=ubc, control=list(xtol_rel=1e-25))

staba<-function(b){(b[1]*X[,1]+b[2]*(1/(1+exp(-(b[3])*((X[,2])-b[4]*tt)))))}
yhatA<-staba(SA$par)

stabb<-function(b){b[1]*X[,1]+b[2]*X[,2]+b[3]*(1/(1+exp(-(b[4])*((X[,2])-b[5]*tt))))}
yhatB<-stabb(SB$par)

stabc<-function(b){(b[1]*X[,1]+b[2]*X[,2]+b[3]*(1/(1+exp(-(b[5])*((X[,2])-b[6]*tt))))+
b[4]*(X[,2])*(1/(1+exp(-(b[5])*((X[,2])-b[6]*tt)))))}
yhatC<-stabc(SC$par)

list(ehat=as.matrix(cbind((yt-yhatA),(yt-yhatB),(yt-yhatC))), yhat=as.matrix(cbind(yhatA,yhatB,yhatC)),BetaA=as.matrix(SA$par),BetaB=as.matrix(SB$par),BetaC=as.matrix(SC$par))
}

# Caner & Hansen (2001) Estimator
tur_est2 <- function(dat,p,mmin,mmax,m,constant,trend){
  t <- nrow(dat)
  n <- t - 1 - p
  mn <- mmax-mmin+1
  ms <- as.matrix(seq(mmin,mn,1))
  dy <- as.matrix(dat[2:t]-dat[1:(t-1)])
  y <- as.matrix(dy[(1+p):(t-1)])
  if(constant==1) x <- matrix(1,n,1)
  if (trend==1) x <- cbind(x,as.matrix(seq(1,n,1)))
  if(constant==1){x <- cbind(x,dat[(1+p):(t-1)],dy[p:(t-2)])}else{
  x <- cbind(dat[(1+p):(t-1)],dy[p:(t-2)])}
  if(p>1) for (ki in 2:p) x <- cbind(x,dy[(p+1-ki):(t-1-ki)])

  if (sum(coef)==0){
      xi_ns <- as.matrix(seq(1,p,1)+1+constant+trend)
        }else{
      idex <- colSums(as.matrix(coef%*%matrix(1,1,p))==(matrix(1,nrow(coef),1)%*%seq(1,p,1)))
      xi_ns <- seq(1,p,1)
      xi_ns <- as.matrix(xi_ns[idex==0]+1+constant+trend)
    }

  if (trend==0){
        if(constant==0){
	        if (sum(coef)==0){
            xi_s <- rbind(1)
                }else{xi_s <- rbind(1,(coef+1))
            }
        }
    }
  if (trend==0){
    if(constant==1){
	if (sum(coef)==0){
      xi_s <- rbind(1,2)
    }else{
      xi_s <- rbind(1,2,(coef+2))
    }
  }
  }
  if (trend==1){
    if(constant==1){
	if (sum(coef)==0){
      xi_s <- rbind(1,2,3)
    }else{
      xi_s <- rbind(1,2,3,(coef+3))
    }
  }
  }

  xs <- as.matrix(x[,xi_s])
  xns <- as.matrix(x[,xi_ns])

  if (thresh==1){
      qs <- dat[(1+p):(t-1)]-dat[(1+p-mmin):(t-1-mmin)]
      qs <- as.matrix(qs)
      if(p>1){
	  for (mi in (mmin+1):mmax){
          qs <- cbind(qs,(dat[(1+p):(t-1)]-dat[(1+p-mi):(t-1-mi)]))
      }
	  }
  }
  if (thresh==2){
      qs <- dat[(1+p-mmin+1):(t-1-mmin+1)]-dat[(1+p-mmin):(t-1-mmin)]
      qs <- as.matrix(qs)
      if(p>1){
	  for (mi in (mmin+1):mmax){
          qs <- cbind(qs,(dat[(1+p-mi+1):(t-1-mi+1)]-dat[(1+p-mi):(t-1-mi)]))
      }
	  }
  }
  if (thresh==3){
      qs <- dat[(1+p-mmin+1):(t-mmin)]
      qs <- as.matrix(qs)
      if(p>1){
	  for (mi in (mmin+1):mmax){
          qs <- cbind(qs,(dat[(1+p-mi+1):(t-mi)]))
      }
	  }
  }
  kx    <- ncol(x)
  ks    <- nrow(coef)+1+constant+trend
  xx    <- solve(t(x)%*%x, tol=1e-25)
  bols  <- xx%*%(t(x)%*%y)
  eols  <- y - x%*%bols
  sols  <- t(eols)%*%eols
  wwss  <- matrix(0,mn,1)
  smins <- matrix(0,mn,1)
  lams  <- matrix(0,mn,1)
  ws    <- matrix(0,mn,1)
  r1    <- matrix(0,mn,1)
  r2    <- matrix(0,mn,1)
  t1    <- matrix(0,mn,1)
  t2    <- matrix(0,mn,1)
  rur <- rbind(1,(ks+1))+trend+constant
  indx <- 1:(n)
  pi1 <-.2-.05*trim
  pi2 <-.8+.05*trim
  for (mi in 1:mn){
    q <- qs[,mi]
    qq <- unique(q)
    qq <- as.matrix(sort(qq))
    qq <- as.matrix(qq[(floor(n*pi1)+1):(ceiling(n*pi2)-1)])
    qn <- nrow(qq)
    s  <- matrix(0,qn,1)
    wws<- matrix(0,qn,1)
    for (qi in 1:qn){
      d1      <- as.matrix((q<qq[qi]))
      d2      <- 1-d1
      xz      <- cbind((xs*(d1%*%matrix(1,1,ncol(xs)))),(xs*(d2%*%matrix(1,1,ncol(xs)))),xns)
      xxi     <- solve(t(xz)%*%xz, tol=1e-25)
      bthresh <- xxi%*%(t(xz)%*%y)
      e       <- y-xz%*%bthresh
      s[qi]   <- t(e)%*%e
      v       <- xxi*as.vector((t(e)%*%e)/(n-kx-ks))
      vd      <- diag(v)
      ts      <- as.matrix(bthresh[rur]/sqrt(vd[rur]))
      wws[qi] <- t(ts)%*%ts
    }
    qi         <- which.max(wws)
    lam        <- qq[qi]
    smin       <- s[qi]
    wwsmax     <- wws[qi]
    ws[mi]     <- (n-kx-ks)*(sols-smin)/smin
    smins[mi]  <- smin
    lams[mi]   <- lam
    wwss[mi]   <- wwsmax
    d1         <- as.matrix((q<lam))
    d2         <- 1-d1
    xz         <- cbind((xs*(d1%*%matrix(1,1,ncol(xs)))),(xs*(d2%*%matrix(1,1,ncol(xs)))),xns)
    mmi        <- solve(t(xz)%*%xz, tol=1e-25)
    bthresh    <- mmi%*%(t(xz)%*%y)
    e          <- y - xz%*%bthresh
    v          <- mmi*as.vector((t(e)%*%e)/(n-kx-ks))
    vd         <- diag(v)
    ts         <- as.matrix(bthresh[rur]/sqrt(vd[rur]))
    r1[mi]     <- t(ts^2)%*%(ts<0)
    r2[mi]     <- t(ts)%*%ts
    t1[mi]     <- -ts[1]
    t2[mi]     <- -ts[2]
  }
  if (m != 0) {mi <- m-mmin+1}else{mi<- which.max(wwss)}
  mhat     <- ms[mi]
  w        <- ws[mi]
  lam      <- lams[mi]
  q        <- qs[,mi]
  d1       <- as.matrix((q<lam))
  d2       <- 1-d1
  xz       <- cbind((xs*(d1%*%matrix(1,1,ncol(xs)))),(xs*(d2%*%matrix(1,1,ncol(xs)))),xns)
  mmi      <- solve(t(xz)%*%xz, tol=1e-25)
  bthresh  <- mmi%*%(t(xz)%*%y)
  e        <- y - xz%*%bthresh
  ee       <- t(e)%*%e
  v        <- mmi*as.vector((ee)/(n-kx-ks))
  vd       <- diag(v)
  v1       <- vd[1:ks]
  v2       <- vd[(ks+1):(2*ks)]
  b1       <- bthresh[1:ks]
  b2       <- bthresh[(ks+1):(2*ks)]
  ts       <- as.matrix(((b1-b2)^2)/(v1+v2))
  bs_s     <- cbind(b1,sqrt(v1),matrix(0,ks,1),b2,sqrt(v2))
  bs_ns    <- cbind(bthresh[(1+2*ks):(kx+ks)],sqrt(vd[(1+2*ks):(kx+ks)]))
  ar01     <-bthresh[(2+constant+trend):(ks)]
  ar02     <-bthresh[(2+constant+trend+ks):(ks*2)]
  leng     <-sum(x[,ncol(x)]>lam)
list(mhat=mhat,lam=lam,e=e,bs_s=bs_s,ar01=ar01,ar02=ar02,b1=b1,b2=b2,r1=r1,r2=r2,t1=t1,t2=t2,ts=ts,ws=ws,w=w,
wws=wws, wwss=wwss,leng=leng,vd=vd)
}

###########################################################
# Caner & Hansen (2001) TAR Model Estimation Settings #####
thresh   <- 2
trim     <- 1
p        <- 1
m        <- 0
mmin     <- 1
mmax     <- p
coef     <- matrix(c(1:p),p,1)
###########################################################
# Simulation Settings #####################################
rep      <- 10000
n        <- 100
alpha    <- 0.8
tr       <-as.matrix(c(1:n))
cc       <-as.matrix(rep(1,n))
###########################################################
# 5% Criticals T=100 ######################################
 R1A <- 21.15948
 R2A <- 21.27445
 R1B <- 27.69705
 R2B <- 27.77254
 R1C <- 30.93129
 R2C <- 30.95712
# 5% Criticals T=200 ######################################
# R1A <- 20.82907
# R2A <- 21.07073
# R1B <- 26.67934
# R2B <- 26.80033
# R1C <- 29.65022
# R2C <- 29.69269
###########################################################
# Simulation Process
ptm <- proc.time()
set.seed(012345)
RTDist <- matrix(0,rep,6)

for(i in 1:rep){
yt   <- as.matrix(CHSizeDGP(n,alpha))
LNV  <- startLNV(yt)
b0a  <- LNV$betasA
b0b  <- LNV$betasB
b0c  <- LNV$betasC
X    <- as.matrix(cbind(cc,tr))
ELNV <- estLNV(yt, X, b0a, b0b,b0c)
D    <- as.matrix(ELNV$ehat)

tarA <- tur_est2(as.matrix(D[,1]),p,mmin,mmax,m,0,0);
tarB <- tur_est2(as.matrix(D[,2]),p,mmin,mmax,m,0,0);
tarC <- tur_est2(as.matrix(D[,3]),p,mmin,mmax,m,0,0);

RTDist[i,1] <- sum(tarA$r1[tarA$mhat]>R1A)
RTDist[i,2] <- sum(tarB$r1[tarB$mhat]>R1B)
RTDist[i,3] <- sum(tarC$r1[tarC$mhat]>R1C)
RTDist[i,4] <- sum(tarA$r2[tarA$mhat]>R2A)
RTDist[i,5] <- sum(tarB$r2[tarB$mhat]>R2B)
RTDist[i,6] <- sum(tarC$r2[tarC$mhat]>R2C)
}
rA <- rbind((sum(RTDist[,1])*100)/rep,(sum(RTDist[,4])*100)/rep)
rB <- rbind((sum(RTDist[,2])*100)/rep,(sum(RTDist[,5])*100)/rep)
rC <- rbind((sum(RTDist[,3])*100)/rep,(sum(RTDist[,6])*100)/rep)
CC  <- cbind(rA,rB,rC)
proc.time() - ptm
print(CC)

printres <- function(CC){
cat ("\n")
cat ("Empirical Size Values for Selected Sample Size & Alpha"                             , "\n")
cat ("\n")
cat ("Number of Observations (T):", n                                                     , "\n")
cat ("                     Alpha:", alpha                                                 , "\n")
cat ("               Replication:", rep                                                   , "\n")
cat ("              Nominal Size:", "%5"                                                  , "\n")
cat ("\n")
cat ("Model A"                                                                            , "\n")
cat ("   ","R1t", "   R2t"                                                                , "\n")
cat ("   ", CC[1,1]," ",CC[2,1]                                                           , "\n")
cat ("\n")
cat ("Model B"                                                                            , "\n")
cat ("   ","R1t", "   R2t"                                                                , "\n")
cat ("   ", CC[1,2]," ",CC[2,2]                                                           , "\n")
cat ("\n")
cat ("Model C"                                                                            , "\n")
cat ("   ","R1t", "   R2t"                                                                , "\n")
cat ("   ", CC[1,3]," ",CC[2,3]                                                           , "\n")
cat ("\n")
}

printres(CC)
# END #


#================================================================
library(truncnorm)
#===============================================================
#Auxiliary functions used during the simulations
#===============================================================
#Function that calculates euclidean distances. It receives two
#matrices of x and y coordinates as parameters.
euclid = function(m1, m2=m1)
{
  sqrt(outer(m1[,1], m2[,1],"-")^2 + outer(m1[,2], m2[,2],"-")^2)
}
#===============================================================
#Function that takes samples from a vector of probabilities
#Given a vector prob of length y, it samples values from 1 to y, the
#probability of value i (i <=y ) being sampled is prob[i].
sampleProb = function(prob, n=1, replace=FALSE)
{
  prob[is.na(prob)] = 0
  positiveProbs = sum(prob!=0)
  if (positiveProbs == 1)
    return(which(prob!=0))
  else if(positiveProbs > 1)
    return(sample(1:length(prob), size = n, replace=replace, prob=prob))
  else return(NA)
}
#===============================================================
#Function that runs a simulation of a mating system with information
#filtering during mate choice.
#It simulates one mating season of a population with 1:1 sex ratio
#The function returns a list containing three data.frames, if a
#filename is given, all data is also registered in three csv files.
simScramble = function(N=100, w = 1, zmean=4, zsd=1, radius=0.10,
                       B=2, filename=NA, append=TRUE, seed=NA,
                       choice=1, zmin=1, zmax=Inf, autocorr = FALSE)
{

  #if a random seed is given, it is used
  if(!is.na(seed))
    set.seed(seed)

  #a trick to facilitate indexing
  xy = c("x","y")

  #creating the data.frames for males and females
  females = data.frame(wid=seed, id=1:N, x=runif(N, min=0, max=w),
                       y=runif(N, min=0, max=w))
  males = data.frame(wid=seed, id=1:N, x=runif(N, min=0, max=w), y=runif(N, min=0, max=w), ms=0)

  zmatrix = NA
  difs = NA

  #creating data.frame for males
  zmean = as.numeric(zmean);zsd = as.numeric(zsd);
  zmin = as.numeric(zmin);zmax = as.numeric(zmax);

  #if there is spatial autocorrelation of traits
  if (autocorr)
  {
    MdistOrigin = euclid(cbind(males$x,males$y), matrix(c(0,0), nrow = 1, ncol=2))
    MmeanZ = (MdistOrigin/(sqrt(2)*w)*zmean)+1
    males$trait = rtruncnorm(N, a=MmeanZ/4, b=zmax, mean = MmeanZ, sd=zsd)
  }
  else
  {
    males$trait=rtruncnorm(n = N, a = zmin, b = zmax, mean=zmean, sd=zsd)
  }

  if(choice==1)#directional choice
  {
    #male trait matrix
    zbase = matrix(males$trait, nrow=N, ncol=N, byrow=TRUE)
    zmatrix = zbase^B

  }
  else #assortative choice
  {
    #then females also have a trait value(from the same distribution)

    if(autocorr)
    {
      FdistOrigin = euclid(cbind(females$x,females$y), matrix(c(0,0), nrow = 1, ncol=2))
      FmeanZ = (FdistOrigin/(sqrt(2)*w)*zmean)+1
      females$trait=rtruncnorm(n = N, a = FmeanZ/4, b = zmax, mean=FmeanZ, sd=zsd)
    }
    else
    {
      females$trait=rtruncnorm(n = N, a = zmin, b = zmax, mean=zmean, sd=zsd)
    }

    #calculates all pairwise differences
    difs = outer(females$trait, males$trait, "-")

    #divides by female trait
    fzmatrix = matrix(females$trait, nrow=N, ncol=N, byrow=TRUE)
    difs = difs/fzmatrix
    difs = abs(difs)

    zbase = difs
    zmatrix = exp(-B*(difs))
  }

  #In all the matrices, females are lines, males are columns
  #distance matrix
  smatrix = euclid(females[,xy], males[,xy])

  #adjacency matrix of neighborhood (males available)
  #females are connected to males within r distance
  nmatrix = ifelse(smatrix<=radius, 1, 0)

  #also, by default females are connected to the closest male
  nmatrix[cbind(1:N, apply(smatrix, 1, which.min))] = 1

  #choice matrix
  cmatrix = nmatrix * zmatrix

  #choosing the males
  chosenMales = apply(cmatrix, 1, sampleProb, replace=FALSE)

  #data.frame that registers the copulations
  groups = data.frame(wid=seed, female = females$id, male = chosenMales)

  #adding mating success to the males
  males$ms=0
  tms = tabulate(chosenMales, nbins = N)#table of mating success
  males$ms = tms

  #If there is a filename, files must be written
  #Columns are separated by ";" and "," is used as decimal separator
  if(!(is.na(filename)))
  {
    write.table(x = females, file = paste(filename, "Females.csv", sep=""),
                append = append, sep = ";", dec=",", row.names = FALSE, col.names = !append)
    write.table(x = males, file = paste(filename, "Males.csv", sep=""),
                append = append, sep = ";", dec=",", row.names = FALSE, col.names = !append)
    write.table(x = groups, file = paste(filename, "Groups.csv", sep=""),
                append = append, sep = ";", dec=",", row.names = FALSE, col.names = !append)
  }

  invisible(list(females=females, males=males,groups=groups))

}
#====================================================================


# Conditional Latent Growth Structural Equation Model Power Analysis

# Raymond Viviano
# rayviviano@gmail.com
# February 12th, 2020

# TODO: Vary models by small, medium, and large residual variance

suppressPackageStartupMessages(library(lavaan))
suppressPackageStartupMessages(library(mnormt))
suppressPackageStartupMessages(library(ggplot2))
suppressPackageStartupMessages(library(RColorBrewer))

options(warn=-1)

################### CHANGE MODEL AND SCRIPT PARAMETERS HERE ####################

intercept_mean_control <- 0 # Doesn't currently do anything.
intercept_mean_mci     <- 0

slope_mean_control <- 0
max_slope_mean_mci <- 1

intercept_variance <- 1
max_slope_variance <- 1

intercept_slope_covariance <- .2

residual_variances <- .5

intercept_age_coef_unstd    <-  .2
intercept_edu_coef_unstd    <- -.2
intercept_sex_coef_unstd    <-  .1
intercept_accult_coef_unstd <-  .1

slope_age_coef_unstd    <-  .2
slope_edu_coef_unstd    <- -.2
slope_sex_coef_unstd    <-  .1
slope_accult_coef_unstd <-  .1

nsimulations = 5000

##################### END USE DEFINED PARAMETERS SECTION  ######################

# Set Base Model, i.e., componenets that do not vary between models
growth_model_base <- "i =~ 1*y1 + 1*y2 + 1*y3\ns =~ 0*y1 + 1*y2 + 2*y3\n"
growth_model_base <- paste0(growth_model_base, "i ~~ ", intercept_variance, "*i\n")

# Age, edu, sex, and acculturation path coefficients
age_edu_terms <- paste0("i ~ ", intercept_age_coef_unstd, "*age\n")
age_edu_terms <- paste0(age_edu_terms, "s ~ ", slope_age_coef_unstd, "*age\n")
age_edu_terms <- paste0(age_edu_terms, "i ~ ", intercept_edu_coef_unstd, "*edu\n")
age_edu_terms <- paste0(age_edu_terms, "s ~ ", slope_edu_coef_unstd, "*edu\n")
age_edu_terms <- paste0(age_edu_terms, "i ~ ", intercept_sex_coef_unstd, "*sex\n")
age_edu_terms <- paste0(age_edu_terms, "s ~ ", slope_sex_coef_unstd, "*sex\n")
age_edu_terms <- paste0(age_edu_terms, "i ~ ", intercept_accult_coef_unstd, "*acculturation\n")
age_edu_terms <- paste0(age_edu_terms, "s ~ ", slope_accult_coef_unstd, "*acculturation\n")

# Set slope variance/covariance and residual variance for Ys
for(i in c(max_slope_variance/2, max_slope_variance)){
    # Vary slope variance between .1 and .5
    eval(parse(text=paste0('lgm_svar', i, ' <-paste0(growth_model_base, ',
                           '"s ~~ ', i, '*s +', intercept_slope_covariance,
                           '*i\n")')))

    # Set residual variances to .5
    eval(parse(text=paste0('lgm_svar', i, ' <-paste0(lgm_svar', i,
                           ', "\ny1 ~~ ', residual_variances,'*y1\ny2 ~~ ',
                           residual_variances,'*y2\n",', '"y3 ~~ ',
                           residual_variances,'*y3\n")')))

    # Add age and edu covariates
    eval(parse(text=paste0('lgm_svar', i, ' <- paste0(lgm_svar', i,
                           ', "\n", age_edu_terms)')))
}

# Set mean slope for MCI group
for(i in c(max_slope_variance/2, max_slope_variance)){
    for(j in seq(0, max_slope_mean_mci, by=max_slope_mean_mci/10)){
        # Add path coefficients between mci and slope (vary slope means
        # for the mci group across simulations)
        eval(parse(text=paste0('lgm_svar', i, '_mci_slp_mean', j,
                               ' <- paste0(lgm_svar', i,
                               ', "\ni~0*1\ns~', j, '*1\n")')))
    }
}

# Test Model - Correctly Specified
m1 <- "
i =~ 1*y1 + 1*y2 + 1*y3
s =~ 0*y1 + 1*y2 + 2*y3
i ~~ i + s
s ~~ s
i ~ mci + age + edu + sex + acculturation
s ~ mci + age + edu + sex + acculturation
"

# Test Model - Misspecification 1 - Only MCI
m2 <- "
i =~ 1*y1 + 1*y2 + 1*y3
s =~ 0*y1 + 1*y2 + 2*y3
i ~~ i + s
s ~~ s
i ~ mci
s ~ mci
"

# Test Model - Misspecification 2 - Add test site and language
m3 <- "
i =~ 1*y1 + 1*y2 + 1*y3
s =~ 0*y1 + 1*y2 + 2*y3
i ~~ i + s
s ~~ s
i ~ mci + age + edu + sex + site + acculturation + language
s ~ mci + age + edu + sex + site + acculturation + language
"

# Create dataframes to store simulation results
sim_df_m1 <- data.frame(matrix(ncol = 5, nrow = 0))
sim_df_m2 <- data.frame(matrix(ncol = 5, nrow = 0))
sim_df_m3 <- data.frame(matrix(ncol = 5, nrow = 0))
colnames(sim_df_m1) <- c('mciSlopeMean', 's_mci', 'svar', 'r05', 'r05p05')
colnames(sim_df_m2) <- c('mciSlopeMean', 's_mci', 'svar', 'r05', 'r05p05')
colnames(sim_df_m3) <- c('mciSlopeMean', 's_mci', 'svar', 'r05', 'r05p05')

# Run the simulations
for(i in c(max_slope_variance/2, max_slope_variance)){
    for(j in seq(0, max_slope_mean_mci, by=max_slope_mean_mci/10)){
        cat(i,j,'\n')
        eval(parse(text=paste0('lgm_con <- lgm_svar', i, '_mci_slp_mean', j*0.0)))
        eval(parse(text=paste0('lgm_mci <- lgm_svar', i, '_mci_slp_mean', j)))

        rmsea05_count  <- 0
        r05_path05 <- 0
        mci_slope_path <- 0

        for(k in 1:nsimulations){
            # Simulate 100 MCI and 100 Control Observations
            df_con <- lavaan::simulateData(model=lgm_con, model.type="growth",
                                           sample.nobs=100)

            df_mci <- lavaan::simulateData(model=lgm_mci, model.type="growth",
                                           sample.nobs=100)

            # Add MCI columns to both data frames
            df_con[,"mci"] <- 0
            df_mci[,"mci"] <- 1

            # Combine Control and MCI datasets
            df <- rbind(df_con, df_mci)

            # Test the correctly specified and misspecified models
            m1_fit <- growth(m1, data=df, missing='fiml')
            # m2_fit <- growth(m2, data=df, missing='fiml')
            # m3_fit <- growth(m3, data=df, missing='fiml')

            # Get RMSEA, s~mci estimate, and s~mci pvalue - Model 1
            smci_est <- as.double(parameterEstimates(m1_fit, standardized = FALSE)[15,'est'])
            pval <- as.double(parameterEstimates(m1_fit, standardized = FALSE)[15,'pvalue'])
            rmsea <- as.double(fitMeasures(m1_fit, c('rmsea'))[1])

            mci_slope_path <- mci_slope_path + smci_est

            if(rmsea <= .05){
                rmsea05_count <- rmsea05_count + 1
                if(pval <= .05){
                    r05_path05 <- r05_path05 + 1
                }
            }
        }

        rmsea05_prop <- rmsea05_count/nsimulations
        r05_path05_prop <- r05_path05/nsimulations
        mci_slope_path_avg <- mci_slope_path/nsimulations

        temp_df <- data.frame(j, mci_slope_path_avg, i, rmsea05_prop, r05_path05_prop)
        colnames(temp_df) <- c('mciSlopeMean', 's_mci', 'svar', 'r05', 'r05p05')

        sim_df_m1 <- rbind(sim_df_m1, temp_df)

    }
}

# Sort data
sim_df_m1 <- sim_df_m1[order(sim_df_m1$mciSlopeMean, sim_df_m1$s_mci),]

print(sim_df_m1)

save(sim_df_m1, file="./sim_df_m1.Rda")


a = 0
b = 1
for(i in seq(1, 20)) {
  cat(i, b, '\n')
  c = a + b
  a = b
  b = c
}


 DGGESX Example Program Results

 Matrix A
             1          2          3          4
 1      3.9000    12.5000   -34.5000    -0.5000
 2      4.3000    21.5000   -47.5000     7.5000
 3      4.3000    21.5000   -43.5000     3.5000
 4      4.4000    26.0000   -46.0000     6.0000

 Matrix B
             1          2          3          4
 1      1.0000     2.0000    -3.0000     1.0000
 2      1.0000     3.0000    -5.0000     4.0000
 3      1.0000     3.0000    -4.0000     3.0000
 4      1.0000     3.0000    -4.0000     4.0000

 Number of eigenvalues for which SELCTG is true =    2
 (dimension of deflating subspaces)

 Selected generalized eigenvalues
    1     (  2.000,  0.000)
    2     (  4.000,  0.000)

 Reciprocals of left and right projection norms onto
 the deflating subspaces for the selected eigenvalues
 RCONDE(1) =  1.9E-01, RCONDE(2) =  1.8E-02

 Reciprocal condition numbers for the left and right
 deflating subspaces
 RCONDV(1) =  5.4E-02, RCONDV(2) =  9.0E-02

 Approximate asymptotic error bound for selected eigenvalues    =  1.1E-13
 Approximate asymptotic error bound for the deflating subspaces =  2.4E-13


#' Fitting bivariate/multivariate MGL and MGL-EV copula regression models.
#'
#' @description \code{MGL.reg} is used to fit bivariate MGL and MGL-EV copula regression models for two continuous variables.
#' @param U two-dimensional matrix with values in \eqn{[0,1]}.
#' @param X design matrix
#' @param copula 'MGL', 'MGL180', "MGL-EV", "MGL-EV180", "Gumbel", "MGB2".
#' @param initpar Initial values for the parameters to be optimized over.
#' @param hessian Logical. Should a numerically differentiated Hessian matrix be returned?
#' @param ... additional arguments, see \code{\link[stats]{optim}} for more details.
#' @importFrom stats qbeta
#' @importFrom stats optim
#' @return A list containing the following components:
#' * loglike: the value of the estimated maximum of the loglikelihood function.
#' * copula: the name of the fitted copula. "MGL180" and "MGL-EV180" denote the survival MGL and MGL-EV copula respectively.
#' * estimates: the point at which the maximum value of the loglikelihood is obtained.
#' * se: the standard errors of the estimators.
#' * AIC, BIC: the goodness fit of the regression models.
#' * hessian: the hessian at the estimated maximum of the loglikelihood (if requested).
#' @details
#' The estimation method is performed via \code{\link[stats]{optim}} function. Y1 and Y2 are both continuous variables.
#'
#' copula: "MGL180" and "MGLEV180" denote the survival MGL and survival MGL-EV copula respectively.
#' * For "Gumbel" regression model, the copula parameter \deqn{\delta_i = \exp(X_i^T\beta) + 1,} where \eqn{{X}_{i}=(1,x_{i1}...,x_{ik})} denotes the vector of covariates and \eqn{\beta} is the vector of coefficients to be estimated in the copula regression.
#' * For "MGL", "MGL180", "MGL-EV", "MGL-EV180" regression model, the copula parameter \deqn{\delta_i = \exp(X_i^T\beta).}
#' * For "MGB2", the copula parameter \deqn{\q_i = \exp(X_i^T\beta)} and \eqn{(p_1,p_2)} remain to be constant.
#' * Note that the regression modelling can be extended to the high-dimensional case when copula is "MGL180" and "MGL".
#'
#' @examples
#' # 10-dimensional regression models
#' set.seed(111)
#' d <- 10
#' n <- 1000 # sample size
#' beta.true <- c(-0.6, 0.5, 0.2) # true regression coefficients
#' x1 <- rnorm(n, 0, 1)
#' x2 <- rnorm(n, 0, 1)
#' X <- model.matrix(~ x1 + x2) # design matrix
#' delta.sim <- as.vector(exp(X%*%beta.true)) # true copula parameters
#' Usim <- matrix(0, nrow = n, ncol = d)
#' for (i in 1:n){
#'   Usim[i, ] <- rcMGL.multi(n = 1, d = d, pars = delta.sim[i])
#' }
#' m.MGLMGA <- MGL.reg(U = Usim, copula = "MGL",
#'                        X = X, method = "Nelder-Mead",
#'                        initpar = c(-0.32, 0.001, 0.001)
#' )
#' m.MGLMGA
#'
#' @export
#'
#'
MGL.reg <- function(U, X, copula = c(
                      "MGL", "MGL180", "MGL-EV",
                      "MGL-EV180",
                      "Gumbel", "MGB2"),
                    hessian = TRUE, initpar, ...) {
  dcMGL.reg <- function(U, param) {
    dim <- length(U)
    a <- 1 / param[1]
    q <- qbeta(1 - U, shape1 = 0.5, shape2 = a) / (1 - qbeta(1 - U, shape1 = 0.5, shape2 = a))
    logdc <- (dim - 1) * lgamma(a) + lgamma(a + dim / 2) - dim * lgamma(a + 0.5) + (a + 0.5) * sum(log(q + 1)) - (a + dim / 2) * log(sum(q) + 1)
    out <- exp(logdc)
    return(out)
  }

  dcMGL180.reg <- function(U, param) {
    dcMGL.reg(1 - U, param = param)
  }

  dcMGLEV180.reg <- function(U, param) {
    u1 <- U[1]
    u2 <- U[2]
    as.numeric(dcMGLEV180.bivar(u1, u2, param = param[1]))
  }

  dcMGLEV.reg <- function(U, param) {
    u1 <- U[1]
    u2 <- U[2]
    as.numeric(dcMGLEV.bivar(u1, u2, param = param[1]))
  }

  dgumcop.reg <- function(U, param) {
    as.numeric(fCopulae::devCopula(u = U[1], v = U[2], type = "gumbel", param = param[1])) # Bivariate Extreme
  }

  if (copula == "MGL") {
    dcop <- dcMGL.reg
  } else if (copula == "MGL180") {
    dcop <- dcMGL180.reg
  } else if (copula == "MGL-EV") {
    dcop <- dcMGLEV.reg
  } else if (copula == "MGL-EV180") {
    dcop <- dcMGLEV180.reg
  } else if (copula == "Gumbel") {
    dcop <- dgumcop.reg
  }

  copLogL <- function(pars, X) {
    ll <- 0

    if (copula == "Gumbel") {
      delta <- exp(X %*% pars) + 1
      for (i in seq_len(nrow(X))) {ll[i] <- dcop(U[i, ], param = as.vector(delta[i]))}
    } else if (copula == "MGB2"){
      p1 <- exp(pars[ncol(X) + 1])
      p2 <- exp(pars[ncol(X) + 2])
      q <- exp(X%*%pars[1:(ncol(X))])
      for (i in seq_len(nrow(X))) {ll[i] <- dcMGB2.bivar(u1 = U[i,1], u2 = U[i,2], pars1 = p1, pars2 = p2, pars3 = q[i])}
    } else {
      delta <- exp(X %*% pars)
      for (i in seq_len(nrow(X))) {ll[i] <- dcop(U[i, ], param = as.vector(delta[i]))}
    }
    res <- -sum((log(ll)))
    return(res)
  }

  resopt <- optim(
    par = initpar,
    fn = copLogL,
    X = X,
    hessian = hessian, ...
  )

  if (hessian == TRUE){
  out <- list(
          loglike = -resopt$value,
          copula = list(name = copula),
          estimates = resopt$par,
          se = sqrt(diag(solve(resopt$hessian))),
          hessian = -resopt$hessian,
          AIC = 2 * length(resopt$par) + 2 * resopt$value,
          BIC = log(nrow(U)) * length(resopt$par) + 2 * resopt$value)
  } else {
    out <- list(
      loglike = -resopt$value,
      copula = list(name = copula),
      estimates = resopt$par,
      AIC = 2 * length(resopt$par) + 2 * resopt$value,
      BIC = log(nrow(U)) * length(resopt$par) + 2 * resopt$value)
  }
  out

}


#' @title calcActualDisp
#'
#' @description Estimate actual loaded displacement (\code{actualDisplacement})
#' (m^3) using a vessel's actual draft.
#'
#' @param Cb Maximum block coefficient (vector of numericals, dimensionless) (see \code{\link{calcCb}})
#' @param Cbw Waterline block coefficient (vector of numericals, dimensionless) (see \code{\link{calcCbw}})
#' @param actualDraft Actual draft (vector of numericals, m)
#' @param maxDraft Maximum summer load line draft (vector of numericals, m)
#' @param maxDisplacement Maximum ship displacement (vector of numericals, m^3)
#'
#' @details
#' Loaded displacement is estimated using actual draft. Actual draft is
#' typically obtained from sources such as AIS messages or ship records.
#' Uses Riddlesworth method (MAN, 2011).
#'
#' @return \code{actualDisplacement} (vector of numericals, m^3)
#'
#' @references
#' \href{https://www.man-es.com/marine/products/propeller-aft-ship}{MAN Energy
#'  Solutions. 2011. "Basic Principles of Propulsion." pg. 9.}
#'
#' @seealso \code{\link{calcCb}}, \code{\link{calcCbw}}
#'
#' @examples
#' calcActualDisp(c(0.82,0.66), c(0.81,0.65), c(12.5,11.1), c(13.6,11.5), c(80097,52382))
#' calcActualDisp(0.82, 0.81, 12.5, 13.6, 80097)
#'
#' @export

calcActualDisp <- function(Cb, Cbw, actualDraft, maxDraft, maxDisplacement){

  actualDisplacement<- ((pmin(0.99,
                      Cb
  ))/Cbw)*(actualDraft/maxDraft)*maxDisplacement
  return(actualDisplacement)

}


## this script produces a bifurcation diagramm for the 3-species food chain

rm(list=ls())

if (!"EMD" %in% installed.packages()) install.packages("EMD")
library(EMD)

# bifurcation data
bdd <- data.frame(
  q = numeric(),
  b1.min = numeric(),
  b1.max = numeric(),
  b2.min = numeric(),
  b2.max = numeric(),
  b3.min = numeric(),
  b3.max = numeric()
  )

nutrient<-seq(0,10,0.1)
for (j in 1:5)
{
for (i in 1:length(nutrient))
{
  out2 <-read.table(paste("../../Simulations/Nutrients/timeseries_",i,"_",j,".out",sep=""),header=T)

  ### searching mins and maxs
  ## b1min
  ifelse(
    extrema(out2$B0P0)$nextreme<2,
    b1.min <- rep(min(out2$B0P0),25), # if no extrema have been found, take the minimum value 25 times (note: minima are in this case identical to the fixed point value!)
    b1.min <- out2$B0P0[extrema(out2$B0P0)$minindex[1:25]] # otherwise, take the first 25 minima that have been found
  )
  ## b1max
  ifelse(
    extrema(out2$B0P0)$nextreme<2,
    b1.max <- rep(min(out2$B0P0),25),
    b1.max <- out2$B0P0[extrema(out2$B0P0)$maxindex[1:25]]
  )
  ## b2min
  ifelse(
    extrema(out2$B1P0)$nextreme<2,
    b2.min <- rep(min(out2$B1P0),25),
    b2.min <- out2$B1P0[extrema(out2$B1P0)$minindex[1:25]]
  )
  ## b2max
  ifelse(
    extrema(out2$B1P0)$nextreme<2,
    b2.max <- rep(min(out2$B1P0),25),
    b2.max <- out2$B1P0[extrema(out2$B1P0)$maxindex[1:25]]
  )
  ## b3min
  ifelse(
    extrema(out2$B2P0)$nextreme<2,
    b3.min <- rep(min(out2$B2P0),25),
    b3.min <- out2$B2P0[extrema(out2$B2P0)$minindex[1:25]]
  )
  ## b3max
  ifelse(
    extrema(out2$B2P0)$nextreme<2,
    b3.max <- rep(min(out2$B2P0),25),
    b3.max <- out2$B2P0[extrema(out2$B2P0)$maxindex[1:25]]
  )
  bddx <- data.frame(
    q = rep(nutrient[i],25),
    b1.min = b1.min,
    b1.max = b1.max,
    b2.min = b2.min,
    b2.max = b2.max,
    b3.min = b3.min,
    b3.max = b3.max
    )
  bdd <- rbind(bdd,bddx)
  print(i)

}
}

write.table(bdd,"Nutrient.txt", sep=",", row.names = F)


#' @rdname geom_boxplot
#' @param coef Length of the whiskers as multiple of IQR. Defaults to 1.5.
#' @inheritParams stat_identity
#' @section Computed variables:
#' `stat_boxplot()` provides the following variables, some of which depend on the orientation:
#' \describe{
#'   \item{width}{width of boxplot}
#'   \item{ymin *or* xmin}{lower whisker = smallest observation greater than or equal to lower hinge - 1.5 * IQR}
#'   \item{lower *or* xlower}{lower hinge, 25% quantile}
#'   \item{notchlower}{lower edge of notch = median - 1.58 * IQR / sqrt(n)}
#'   \item{middle *or* xmiddle}{median, 50% quantile}
#'   \item{notchupper}{upper edge of notch = median + 1.58 * IQR / sqrt(n)}
#'   \item{upper *or* xupper}{upper hinge, 75% quantile}
#'   \item{ymax *or* xmax}{upper whisker = largest observation less than or equal to upper hinge + 1.5 * IQR}
#' }
#' @export
stat_boxplot <- function(mapping = NULL, data = NULL,
                         geom = "boxplot", position = "dodge2",
                         ...,
                         coef = 1.5,
                         na.rm = FALSE,
                         orientation = NA,
                         show.legend = NA,
                         inherit.aes = TRUE) {
  layer(
    data = data,
    mapping = mapping,
    stat = StatBoxplot,
    geom = geom,
    position = position,
    show.legend = show.legend,
    inherit.aes = inherit.aes,
    params = list2(
      na.rm = na.rm,
      orientation = orientation,
      coef = coef,
      ...
    )
  )
}

#' @rdname ggplot2-ggproto
#' @format NULL
#' @usage NULL
#' @export
StatBoxplot <- ggproto("StatBoxplot", Stat,
  required_aes = c("y|x"),
  non_missing_aes = "weight",
  setup_data = function(self, data, params) {
    data <- flip_data(data, params$flipped_aes)
    data$x <- data$x %||% 0
    data <- remove_missing(
      data,
      na.rm = params$na.rm,
      vars = "x",
      name = "stat_boxplot"
    )
    flip_data(data, params$flipped_aes)
  },

  setup_params = function(self, data, params) {
    params$flipped_aes <- has_flipped_aes(data, params, main_is_orthogonal = TRUE,
                                          group_has_equal = TRUE,
                                          main_is_optional = TRUE)
    data <- flip_data(data, params$flipped_aes)

    has_x <- !(is.null(data$x) && is.null(params$x))
    has_y <- !(is.null(data$y) && is.null(params$y))
    if (!has_x && !has_y) {
      cli::cli_abort("{.fn {snake_class(self)}} requires an {.field x} or {.field y} aesthetic.")
    }

    params$width <- params$width %||% (resolution(data$x %||% 0) * 0.75)

    if (is.double(data$x) && !has_groups(data) && any(data$x != data$x[1L])) {
      cli::cli_warn(c(
        "Continuous {.field {flipped_names(params$flipped_aes)$x}} aesthetic",
        "i" = "did you forget {.code aes(group = ...)}?"
      ))
    }

    params
  },

  extra_params = c("na.rm", "orientation"),

  compute_group = function(data, scales, width = NULL, na.rm = FALSE, coef = 1.5, flipped_aes = FALSE) {
    data <- flip_data(data, flipped_aes)
    qs <- c(0, 0.25, 0.5, 0.75, 1)

    if (!is.null(data$weight)) {
      mod <- quantreg::rq(y ~ 1, weights = weight, data = data, tau = qs)
      stats <- as.numeric(stats::coef(mod))
    } else {
      stats <- as.numeric(stats::quantile(data$y, qs))
    }
    names(stats) <- c("ymin", "lower", "middle", "upper", "ymax")
    iqr <- diff(stats[c(2, 4)])

    outliers <- data$y < (stats[2] - coef * iqr) | data$y > (stats[4] + coef * iqr)
    if (any(outliers)) {
      stats[c(1, 5)] <- range(c(stats[2:4], data$y[!outliers]), na.rm = TRUE)
    }

    if (length(unique(data$x)) > 1)
      width <- diff(range(data$x)) * 0.9

    df <- new_data_frame(as.list(stats))
    df$outliers <- list(data$y[outliers])

    if (is.null(data$weight)) {
      n <- sum(!is.na(data$y))
    } else {
      # Sum up weights for non-NA positions of y and weight
      n <- sum(data$weight[!is.na(data$y) & !is.na(data$weight)])
    }

    df$notchupper <- df$middle + 1.58 * iqr / sqrt(n)
    df$notchlower <- df$middle - 1.58 * iqr / sqrt(n)

    df$x <- if (is.factor(data$x)) data$x[1] else mean(range(data$x))
    df$width <- width
    df$relvarwidth <- sqrt(n)
    df$flipped_aes <- flipped_aes
    flip_data(df, flipped_aes)
  }
)


# Simulation Tutorial in R for Engineers and Geoscientists
# Michael Pyrcz, University of Texas at Austin, Twitter @GeostatsGuy

# This will be used in my Introduction to Geostatistics undergraduate class
# It is assumed that students have no previous R experience.
# This utilizes the gstat library by Edzer Pedesma, appreciation to Dr. Pedesma for assistance.

# Load the required libraries, you may have to first go to "Tools/Install Packages..." to install these first
library(gstat)                                 # geostatistical methods by Edzer Pebesma
library(sp)                                    # spatial points addition to regular data frames
library(plyr)                                  # splitting, applying and combining data by Hadley Wickham
library(fields)                                # required for the image plots

# Specify the grid parameters (same as GSLIB / GEO-DAS parameterization in 2D)
nx = 100
ny = 100
xmn = 5.0
ymn = 5.0
xsize = 40.0
ysize = 40.0
xmin = xmn - xsize*0.5
ymin = ymn - ysize*0.5
xmax = xmin + nx * xsize
ymax = ymin + ny * ysize
x<-seq(xmin,xmax,by=xsize)                     # used for axes on image plots
y<-seq(ymin,ymax,by=ysize)

# Specify the parameters For plotting
colmap = topo.colors(100)                      # define the color map and descritation

# Declare functions

# This function completes standard normal transform on a data vector

nscore <- function(x) {                        # written by Ashton Shortridge, May/June, 2008
  # Takes a vector of values x and calculates their normal scores. Returns
  # a list with the scores and an ordered table of original values and
  # scores, which is useful as a back-transform table. See backtr().
  nscore <- qqnorm(x, plot.it = FALSE)$x  # normal score
  trn.table <- data.frame(x=sort(x),nscore=sort(nscore))
  return (list(nscore=nscore, trn.table=trn.table))
}

# This function builds a spatial points dataframe with the locations for estimation / simulation

addcoord <- function(nx,xmin,xsize,ny,ymin,ysize) { # Michael Pyrcz, March, 2018
  # makes a 2D dataframe with coordinates based on GSLIB specification
  coords = matrix(nrow = nx*ny,ncol=2)
  ixy = 1
  for(iy in 1:nx) {
    for(ix in 1:ny) {
      coords[ixy,1] = xmin + (ix-1)*xsize
      coords[ixy,2] = ymin + (iy-1)*ysize
      ixy = ixy + 1
    }
  }
  coords.df = data.frame(coords)
  colnames(coords.df) <- c("X","Y")
  coordinates(coords.df) =~X+Y
  return (coords.df)
}

sim2darray <- function(spdataframe,nx,ny,ireal) { # Michael Pyrcz, March, 2018
  # makes a 2D array from realizations spatial point dataframe
  model = matrix(nrow = nx,ncol = ny)
  ixy = 1
  for(iy in 1:ny) {
    for(ix in 1:nx) {
      model[ix,iy] = spdataframe@data[ixy,ireal]
      ixy = ixy + 1
    }
  }
  return (model)
}

sim2vector <- function(spdataframe,nx,ny,ireal) { # Michael Pyrcz, March, 2018
  # makes a 1D vector from spatial point dataframe
  model = rep(0,nx*ny)
  ixy = 1
  for(iy in 1:ny) {
    for(ix in 1:nx) {
      model[ixy] = spdataframe@data[ixy,ireal]
      ixy = ixy + 1
    }
  }
  return (model)
}

# Set the working directory, I always like to do this so I don't lose files and to simplify subsequent read and writes
setwd("C:/PGE337")

# Read the data table from a comma delimited file - data on GitHub/GeostatsGuy/GeoDataSets
mydata = read.csv("2D_MV_200Wells.csv")        # read in comma delimited data file

# Let's visualize the first several rows of our data so we can make sure we successfully loaded it
head(mydata)                                   # show the first several rows of a data table in the console
# The columns are variables with variable names at the top and the rows are samples

# Convert the dataframe to a spatial points dataframe
class(mydata)                                  # confirms that it is a dataframe
coordinates(mydata) = ~X+Y                     # indicate the X, Y spatial coordinates
summary(mydata)                                # confirms that it is now a spatial points dataframe
head(coordinates(mydata))                      # check the first several coordinates

# Normal scores transform of the porosity data to assist with variogram calculation
npor.trn = nscore(mydata$porosity)                  # normal scores transform
mydata[["NPorosity"]]<-npor.trn$nscore         # append the normal scores transform into the spatial data table
head(mydata)

# Make the model 2D grid
coords <- addcoord(nx,xmin,xsize,ny,ymin,ysize) # make a dataframe with all the estimation locations
summary(coords)                                # check the coordinates

# What is the sill of the raw variable
sill = var(mydata$porosity)
min = min(mydata$porosity)
max = max(mydata$porosity)
zlim = c(min,max)                              # define the property min and max

# Anisotropic variogram
vm1 <- vgm(psill = 0.5*sill, "Sph", 400, anis = c(000, 1.0),nugget=0.5*sill)
vm1
vm2 <- vgm(psill = 1.0*sill, "Exp", 200, anis = c(035, 0.5),nugget=0.0*sill)
vm2
vm3 <- vgm(psill = 1.0*sill, "Sph", 600, anis = c(060, 0.2),nugget=0.0*sill)
vm3

# Gaussian simulation

condsim1 = krige(porosity~1, mydata, coords, model = vm1, nmax = 100, nsim = 4)
condsim2 = krige(porosity~1, mydata, coords, model = vm2, nmax = 100, nsim = 4)
condsim3 = krige(porosity~1, mydata, coords, model = vm3, nmax = 100, nsim = 4)

krige1 = krige(porosity~1, mydata, coords, model = vm1, nmax = 100)
krige2 = krige(porosity~1, mydata, coords, model = vm2, nmax = 100)
krige3 = krige(porosity~1, mydata, coords, model = vm3, nmax = 100)

# nmax is the maximum number of data for each kriging solution
# this may take a long time to run, decrease nmax to spped up (e.g. 100)

# Plot all the realizations
#par(mar=c(1,1,1,1))
par(mfrow=c(2,2))
real1 <- sim2darray(condsim1,nx,ny,1)      # extract realization #1 to a 2D array and plot
#image.plot(real1,x=x,y=y,xlab="X(m)",ylab="Y(m)",zlim = zlim,col=colmap,legend.shrink = 0.6); mtext(line=1, side=3, "Realization #1", outer=F);box(which="plot")
image.plot(real1,x=x,y=y,xlab="X(m)",ylab="Y(m)",zlim = zlim);
points(mydata$X,mydata$Y,pch="+",cex=1.0,col="black") # add well locations

real2 <- sim2darray(condsim1,nx,ny,2)      # extract realization #2 to a 2D array and plot
image.plot(real2,x=x,y=y,xlab="X(m)",ylab="Y(m)",zlim = zlim,col=colmap,legend.shrink = 0.6); mtext(line=1, side=3, "Realization #2", outer=F);box(which="plot")
points(mydata$X,mydata$Y,pch="+",cex=1.0,col="black") # add well locations

real3 <- sim2darray(condsim1,nx,ny,3)      # extract realization #3 to a 2D array and plot
image.plot(real3,x=x,y=y,xlab="X(m)",ylab="Y(m)",zlim = zlim,col=colmap,legend.shrink = 0.6); mtext(line=1, side=3, "Realization #3", outer=F);box(which="plot")
points(mydata$X,mydata$Y,pch="+",cex=1.0,col="black") # add well locations

est <- sim2darray(krige1,nx,ny,1)      # extract realization #4 to a 2D array and plot
image.plot(est,x=x,y=y,xlab="X(m)",ylab="Y(m)",zlim = zlim,col=colmap,legend.shrink = 0.6); mtext(line=1, side=3, "Kriging", outer=F);box(which="plot")
points(mydata$X,mydata$Y,pch="+",cex=1.0,col="black") # add well locations

par(mfrow=c(2,2))
real1 <- sim2darray(condsim2,nx,ny,1)      # extract realization #1 to a 2D array and plot
image.plot(real1,x=x,y=y,xlab="X(m)",ylab="Y(m)",zlim = zlim,col=colmap,legend.shrink = 0.6); mtext(line=1, side=3, "Realization #1", outer=F);box(which="plot")
points(mydata$X,mydata$Y,pch="+",cex=1.0,col="black") # add well locations

real2 <- sim2darray(condsim2,nx,ny,2)      # extract realization #2 to a 2D array and plot
image.plot(real2,x=x,y=y,xlab="X(m)",ylab="Y(m)",zlim = zlim,col=colmap,legend.shrink = 0.6); mtext(line=1, side=3, "Realization #2", outer=F);box(which="plot")
points(mydata$X,mydata$Y,pch="+",cex=1.0,col="black") # add well locations

real3 <- sim2darray(condsim2,nx,ny,3)      # extract realization #3 to a 2D array and plot
image.plot(real3,x=x,y=y,xlab="X(m)",ylab="Y(m)",zlim = zlim,col=colmap,legend.shrink = 0.6); mtext(line=1, side=3, "Realization #3", outer=F);box(which="plot")
points(mydata$X,mydata$Y,pch="+",cex=1.0,col="black") # add well locations

est <- sim2darray(krige2,nx,ny,1)      # extract realization #4 to a 2D array and plot
image.plot(est,x=x,y=y,xlab="X(m)",ylab="Y(m)",zlim = zlim,col=colmap,legend.shrink = 0.6); mtext(line=1, side=3, "Kriging", outer=F);box(which="plot")
points(mydata$X,mydata$Y,pch="+",cex=1.0,col="black") # add well locations

par(mfrow=c(2,2))
real1 <- sim2darray(condsim3,nx,ny,1)      # extract realization #1 to a 2D array and plot
image.plot(real1,x=x,y=y,xlab="X(m)",ylab="Y(m)",zlim = zlim,col=colmap,legend.shrink = 0.6); mtext(line=1, side=3, "Realization #1", outer=F);box(which="plot")
points(mydata$X,mydata$Y,pch="+",cex=1.0,col="black") # add well locations

real2 <- sim2darray(condsim3,nx,ny,2)      # extract realization #2 to a 2D array and plot
image.plot(real2,x=x,y=y,xlab="X(m)",ylab="Y(m)",zlim = zlim,col=colmap,legend.shrink = 0.6); mtext(line=1, side=3, "Realization #2", outer=F);box(which="plot")
points(mydata$X,mydata$Y,pch="+",cex=1.0,col="black") # add well locations

real3 <- sim2darray(condsim3,nx,ny,3)      # extract realization #3 to a 2D array and plot
image.plot(real3,x=x,y=y,xlab="X(m)",ylab="Y(m)",zlim = zlim,col=colmap,legend.shrink = 0.6); mtext(line=1, side=3, "Realization #3", outer=F);box(which="plot")
points(mydata$X,mydata$Y,pch="+",cex=1.0,col="black") # add well locations

est <- sim2darray(krige3,nx,ny,1)      # extract realization #4 to a 2D array and plot
image.plot(est,x=x,y=y,xlab="X(m)",ylab="Y(m)",zlim = zlim,col=colmap,legend.shrink = 0.6); mtext(line=1, side=3, "Kriging", outer=F);box(which="plot")
points(mydata$X,mydata$Y,pch="+",cex=1.0,col="black") # add well locations

par(mfrow=c(3,2))

# Minimum acceptance checks, check the distributions and variagrams of the realization

# Variogram 1
# Plot the CDFs for the 4 realizations and compare to the raw data CDF
plot(ecdf(condsim1@data[,1]),main="Variogram 1",xlab="Gaussian Values",ylab="Cumulative Probability",col="red")
plot(ecdf(condsim1@data[,2]),add=TRUE,col="red")
plot(ecdf(condsim1@data[,3]),add=TRUE,col="red")
plot(ecdf(condsim1@data[,4]),add=TRUE,col="red")
plot(ecdf(mydata$porosity),add=TRUE,col="black")

# Calculate the varograms for the major and minor directions and compare to the variogram model
# We just arbitrarily picked 035, 125 azimuth, model is isotropic so direction shouldn't matter
vg.sim1.035 = variogram(sim1~1,condsim1,cutoff = 1000,width =20,alpha = 35.0,tol.hor=22.5)
vg.sim1.125 = variogram(sim1~1,condsim1,cutoff = 1000,width =20,alpha = 125.0,tol.hor=22.5)
vg.sim2.035 = variogram(sim2~1,condsim1,cutoff = 1000,width =20,alpha = 35.0,tol.hor=22.5)
vg.sim2.125 = variogram(sim2~1,condsim1,cutoff = 1000,width =20,alpha = 125.0,tol.hor=22.5)
vg.sim3.035 = variogram(sim3~1,condsim1,cutoff = 1000,width =20,alpha = 35.0,tol.hor=22.5)
vg.sim3.125 = variogram(sim3~1,condsim1,cutoff = 1000,width =20,alpha = 125.0,tol.hor=22.5)
vg.sim4.035 = variogram(sim4~1,condsim1,cutoff = 1000,width =20,alpha = 35.0,tol.hor=22.5)
vg.sim4.125 = variogram(sim4~1,condsim1,cutoff = 1000,width =20,alpha = 125.0,tol.hor=22.5)

# Plot the vairograms from the realizations and the model variogram.
plot(vg.sim1.035$dist,vg.sim1.035$gamma,pch=19,cex=0.1,main="Variogram 1",xlab="  Lag Distance (m) ",ylab=" Semivariogram ", col="black",xlim=c(0,1000),ylim=c(0,1.2*sill))
points(vg.sim1.125$dist,vg.sim1.125$gamma,pch=19,cex=0.1,col="red")
points(vg.sim2.035$dist,vg.sim2.035$gamma,pch=19,cex=0.1,col="black")
points(vg.sim2.125$dist,vg.sim2.125$gamma,pch=19,cex=0.1,col="red")
points(vg.sim3.035$dist,vg.sim3.035$gamma,pch=19,cex=0.1,col="black")
points(vg.sim3.125$dist,vg.sim3.125$gamma,pch=19,cex=0.1,col="red")
points(vg.sim4.035$dist,vg.sim4.035$gamma,pch=19,cex=0.1,col="black")
points(vg.sim4.125$dist,vg.sim4.125$gamma,pch=19,cex=0.1,col="red")
abline(h = 1.0*sill)
# Include variogram model
unit_vector = c(0,1,0)                         # unit vector for 000 azimuth
vm1.000 <- variogramLine(vm1,maxdist=1000,min=0.0001,n=100,dir=unit_vector,covariance=FALSE) # calculate 035 variogram model
lines(vm1.000$dist,vm1.000$gamma,pch=19,cex=0.1,col="black") # include variogram model
unit_vector = c(1,0,0)                         # unit vector for 090 azimuth
vm1.090 <- variogramLine(vm1,maxdist=1000,min=0.0001,n=100,dir=unit_vector,covariance=FALSE) # calculate 125 variogram model
lines(vm1.090$dist,vm1.090$gamma,col="red")

# Repeat the above checks for the 2 other sets of simulated realizations
# Variogram 2
# Plot the CDFs for the 4 realizations and compare to the raw data CDF
plot(ecdf(condsim2@data[,1]),main="Variogram 2",xlab="Gaussian Values",ylab="Cumulative Probability",col="red")
plot(ecdf(condsim2@data[,2]),add=TRUE,col="red")
plot(ecdf(condsim2@data[,3]),add=TRUE,col="red")
plot(ecdf(condsim2@data[,4]),add=TRUE,col="red")
plot(ecdf(mydata$porosity),add=TRUE,col="black")

vg.sim1.035 = variogram(sim1~1,condsim2,cutoff = 1000,width =20,alpha = 35.0,tol.hor=22.5)
vg.sim1.125 = variogram(sim1~1,condsim2,cutoff = 1000,width =20,alpha = 125.0,tol.hor=22.5)
vg.sim2.035 = variogram(sim2~1,condsim2,cutoff = 1000,width =20,alpha = 35.0,tol.hor=22.5)
vg.sim2.125 = variogram(sim2~1,condsim2,cutoff = 1000,width =20,alpha = 125.0,tol.hor=22.5)
vg.sim3.035 = variogram(sim3~1,condsim2,cutoff = 1000,width =20,alpha = 35.0,tol.hor=22.5)
vg.sim3.125 = variogram(sim3~1,condsim2,cutoff = 1000,width =20,alpha = 125.0,tol.hor=22.5)
vg.sim4.035 = variogram(sim4~1,condsim2,cutoff = 1000,width =20,alpha = 35.0,tol.hor=22.5)
vg.sim4.125 = variogram(sim4~1,condsim2,cutoff = 1000,width =20,alpha = 125.0,tol.hor=22.5)

plot(vg.sim1.035$dist,vg.sim1.035$gamma,pch=19,cex=0.1,main="Variogram 2",xlab="  Lag Distance (m) ",ylab=" Semivariogram ", col="black",xlim=c(0,1000),ylim=c(0,1.2*sill))
points(vg.sim1.125$dist,vg.sim1.125$gamma,pch=19,cex=0.1,col="red")
points(vg.sim2.035$dist,vg.sim2.035$gamma,pch=19,cex=0.1,col="black")
points(vg.sim2.125$dist,vg.sim2.125$gamma,pch=19,cex=0.1,col="red")
points(vg.sim3.035$dist,vg.sim3.035$gamma,pch=19,cex=0.1,col="black")
points(vg.sim3.125$dist,vg.sim3.125$gamma,pch=19,cex=0.1,col="red")
points(vg.sim4.035$dist,vg.sim4.035$gamma,pch=19,cex=0.1,col="black")
points(vg.sim4.125$dist,vg.sim4.125$gamma,pch=19,cex=0.1,col="red")
abline(h = 1.0*sill)
# Include variogram model
unit_vector = c(sin(35*pi/180),cos(35*pi/180),0) # unit vector for 035 azimuth
vm2.035 <- variogramLine(vm2,maxdist=1000,min=0.0001,n=100,dir=unit_vector,covariance=FALSE) # calculate 035 variogram model
lines(vm2.035$dist,vm2.035$gamma,pch=19,cex=0.1,col="black") # include variogram model

unit_vector = c(sin(55*pi/180),-1*cos(35*pi/180),0) # unit vector for 125 azimuth
vm2.125 <- variogramLine(vm2,maxdist=1000,min=0.0001,n=100,dir=unit_vector,covariance=FALSE) # calculate 125 variogram model
lines(vm2.125$dist,vm2.125$gamma,col="red") # include variogram model

# Variogram 3
# Plot the CDFs for the 4 realizations and compare to the raw data CDF
plot(ecdf(condsim3@data[,1]),main="Variogram 3",xlab="Gaussian Values",ylab="Cumulative Probability",col="red")
plot(ecdf(condsim3@data[,2]),add=TRUE,col="red")
plot(ecdf(condsim3@data[,3]),add=TRUE,col="red")
plot(ecdf(condsim3@data[,4]),add=TRUE,col="red")
plot(ecdf(mydata$porosity),add=TRUE,col="black")

c = sqrt(2)

vg.sim1.060 = variogram(sim1~1,condsim3,cutoff = 1000,width =20,alpha = 60.0,tol.hor=22.5)
vg.sim1.150 = variogram(sim1~1,condsim3,cutoff = 1000,width =20,alpha = 150.0,tol.hor=22.5)
vg.sim2.060 = variogram(sim2~1,condsim3,cutoff = 1000,width =20,alpha = 60.0,tol.hor=22.5)
vg.sim2.150 = variogram(sim2~1,condsim3,cutoff = 1000,width =20,alpha = 150.0,tol.hor=22.5)
vg.sim3.060 = variogram(sim3~1,condsim3,cutoff = 1000,width =20,alpha = 60.0,tol.hor=22.5)
vg.sim3.150 = variogram(sim3~1,condsim3,cutoff = 1000,width =20,alpha = 150.0,tol.hor=22.5)
vg.sim4.060 = variogram(sim4~1,condsim3,cutoff = 1000,width =20,alpha = 60.0,tol.hor=22.5)
vg.sim4.150 = variogram(sim4~1,condsim3,cutoff = 1000,width =20,alpha = 150.0,tol.hor=22.5)

plot(vg.sim1.060$dist,vg.sim1.060$gamma,pch=19,cex=0.1,main="Varogram 3",xlab="  Lag Distance (m) ",ylab=" Semivariogram ", col="black",xlim=c(0,1000),ylim=c(0,1.2*sill))
points(vg.sim1.150$dist,vg.sim1.150$gamma,pch=19,cex=0.1,col="red")
points(vg.sim2.060$dist,vg.sim2.060$gamma,pch=19,cex=0.1,col="black")
points(vg.sim2.150$dist,vg.sim2.150$gamma,pch=19,cex=0.1,col="red")
points(vg.sim3.060$dist,vg.sim3.060$gamma,pch=19,cex=0.1,col="black")
points(vg.sim3.150$dist,vg.sim3.150$gamma,pch=19,cex=0.1,col="red")
points(vg.sim4.060$dist,vg.sim4.060$gamma,pch=19,cex=0.1,col="black")
points(vg.sim4.150$dist,vg.sim4.150$gamma,pch=19,cex=0.1,col="red")
abline(h = 1.0*sill)
# Include variogram model
unit_vector = c(sin(60*pi/180),cos(60*pi/180),0) # unit vector for 060 azimuth
vm3.060 <- variogramLine(vm3,maxdist=1000,min=0.0001,n=100,dir=unit_vector,covariance=FALSE) # calculate 035 variogram model
lines(vm3.060$dist,vm3.060$gamma,pch=19,cex=0.1,col="black") # include variogram model

unit_vector = c(sin(30*pi/180),-1*cos(60*pi/180),0) # unit vector for 125 azimuth
vm3.150 <- variogramLine(vm3,maxdist=1000,min=0.0001,n=100,dir=unit_vector,covariance=FALSE) # calculate 125 variogram model
lines(vm3.150$dist,vm3.150$gamma,col="red") # include variogram model

# On your own try changing the variogram parameters and observe the results.  Also consider kriging with a trend.

# Hope this was helpful,

# Michael

# Appreciation to Edzer Pedesma for the gstat package.


num = as.integer(readline(prompt="Enter int: "))
factorial = 1
if(num < 0) {
print("Error: must be +")
} else if(num == 0) {
print("1")
} else {
for(i in 1:num) {
factorial = factorial * i
}
print(paste(factorial))
}


# OBRESTNE KRIVULJE
# Finančni praktikum 2020/21
# Mitja Mandić

#prva naloga

euribor.15 <- read.table("prva_naloga/podatki/hist_EURIBOR_2015.csv", sep = ",", header = TRUE, row.names = 1, check.names = FALSE)
euribor.15 <- as.data.frame(t(euribor.15[,c(1, 22, 42, 64, 84, 104, 126, 149, 170, 192, 214, 235)]))
euribor.16 <- read.table("prva_naloga/podatki/hist_EURIBOR_2016.csv", sep = ",", header = TRUE, row.names = 1, check.names = FALSE)
euribor.16 <- as.data.frame(t(euribor.16[,c(1, 21, 42, 63, 84, 106, 128, 149, 172, 194, 215, 237)]))
euribor.17 <- read.table("prva_naloga/podatki/hist_EURIBOR_2017.csv", sep = ",", header = TRUE, row.names = 1, check.names = FALSE)
euribor.17 <- as.data.frame(t(euribor.17[,c(1, 23, 43, 66, 84, 106, 128, 149, 172, 193, 215, 237)]))

euribor <- rbind(euribor.15,euribor.16,euribor.17)

prva.c.6m <- ts(euribor[,"6m"], start = 2015, frequency = 12)
prva.c.12m <- ts(euribor[,"12m"], start = 2015, frequency = 12)

ts.plot(prva.c.6m,prva.c.12m, gpars = list(xlab = "Datum", ylab = "%", col = c("red", "blue")))
legend("topright", bty="n", lty=c(1,1), col=c("red","blue"),
       legend=c("6m", "12m"))
title("EURIBOR")
graf.ts <- recordPlot()
#druga naloga

#1. julij 2015, 3. oktober 2016, 1. september 2017

druga.b <- euribor[c("01/07/2015", "03/10/2016", "01/09/2017"),]
#druga.b <- as.data.frame(t(druga.b))

  plot(t(druga.b[1,]), ylim = c(-0.4, 0.4), col = c("red"),x=c(1/4,1/2,1,2,3,6,9,12), pch = 16, ylab = "%", xlab = "Časovna enota")
points(t(druga.b[2,]), col = c("blue"),pch = 16,x=c(1/4,1/2,1,2,3,6,9,12))
points(t(druga.b[3,]), col = c("black"),pch = 16,x=c(1/4,1/2,1,2,3,6,9,12))
lines(t(druga.b[1,]),col = c("red"),pch = 16,x=c(1/4,1/2,1,2,3,6,9,12))
lines(t(druga.b[2,]),col = c("blue"),pch = 16,x=c(1/4,1/2,1,2,3,6,9,12))
lines(t(druga.b[3,]),col = c("black"),pch = 16,x=c(1/4,1/2,1,2,3,6,9,12))
legend("topleft",bty="n",lty = c(1,1),col=c("red", "blue", "black"), legend=c("1. julij 2015", "3. oktober 2016", "1. september 2017"))
title("Casovna struktura Euribor")
graf.druga.b <- recordPlot()
#Vse krivulje so naraščajoče, torej imajo višjo donosnost pri kasnejših datumih zapadlosti, torej imajo normalno obliko.
#So precej položne in z izjemo leta 2015 skozi negativne.

#tretja naloga
T <- 6
U <- 12

euribor.tretja <- euribor[,c("6m","12m")]
euribor.tretja[,"terminska"] <- 2 * ((1 + euribor.tretja[,"12m"]/100)/(1 + 1/2 * euribor.tretja[,"6m"]/100) - 1)*100 #račun terminske obrestne mere

napoved <- euribor.tretja[,"terminska"]
napoved[c(31,32,33,34,35,36)] <- 0
napoved[c(seq(7,36))] <- napoved[c(seq(1,30))]

napoved[c(1,2,3,4,5,6)] <- NA
euribor.tretja["napoved"] <- napoved #Dodan stolpec z napovedanimi vrednostmi.

  plot(x=euribor.tretja[seq(6,12),"napoved"],y=euribor.tretja[seq(6,12),"6m"], xlim = c(-0.3,0.5), ylim = c(-0.3,0.5), type="p",
                xlab = "napoved", ylab = "opazovano",col = "blue")
points(x=euribor.tretja[seq(13,24),"napoved"],y=euribor.tretja[seq(13,24),"6m"], col = "red")
points(x=euribor.tretja[seq(25,36),"napoved"],y=euribor.tretja[seq(25,36),"6m"], col = "green")
lines(x = c(-0.5,0,5), y = c(-0.5,0,5), col = "grey")
legend("topleft",bty="n",lty = c(1,1),col=c("blue", "red", "green"), legend=c("2015", "2016", "2017"))
abline(lm(euribor.tretja[,"6m"]~euribor.tretja[,"napoved"]))
title("6m euribor 2015-2017")
graf.3c <- recordPlot()

plot(x=euribor.tretja[seq(6,12),"napoved"],y=euribor.tretja[seq(6,12),"6m"], xlim = c(-0.1,0.5), ylim = c(-0.1,0.5), type="p",
                     xlab = "napoved", ylab = "opazovano",col = "blue")
abline(lm(euribor.tretja[seq(6,12),"6m"]~euribor.tretja[seq(6,12),"napoved"]))
lines(x = c(-0.5,0,5), y = c(-0.5,0,5), col = "grey")
title("6m Euribor 2015")
graf.3d.prva <- recordPlot()

plot(x=euribor.tretja[seq(13,24),"napoved"],y=euribor.tretja[seq(13,24),"6m"], xlim = c(-0.3,0.3), ylim = c(-0.3,0.3), type="p",
                                     xlab = "napoved", ylab = "opazovano",col = "red")
abline(lm(euribor.tretja[seq(13,24),"6m"]~euribor.tretja[seq(13,24),"napoved"]))
lines(x = c(-0.5,0,5), y = c(-0.5,0,5), col = "grey")
title("6m Euribor 2016")
graf.3d.druga <- recordPlot()

plot(x=euribor.tretja[seq(25,36),"napoved"],y=euribor.tretja[seq(25,36),"6m"], xlim = c(-0.3,0.1), ylim = c(-0.3,0.1), type="p",
                       xlab = "napoved", ylab = "opazovano",col = "green")
abline(lm(euribor.tretja[seq(25,36),"6m"]~euribor.tretja[seq(25,36),"napoved"]))
lines(x = c(-0.5,0,5), y = c(-0.5,0,5), col = "grey")
title("6m Euribor 2017")
graf.3d.tretja <- recordPlot()

#odgovor 3.e
#Regresijska premica bi morala biti simetrala lihih kvadrantov, na kateri bi ležale vse narisane točke. Ker je napoved večja od
#izmerjene vrednosti, so točke na grafih v desnem spodnjem kotu.

#link na github repo: https://github.com/mitja-mandic/financni-praktikum


# The posterior conditional function utilized by the
# Gibbs sampler in function.r. They have all the
# same form maybe they should be implemented in a
# smarter way.

# The basic structure is the following

# 1. Get the old parameter
# 2. Propose a jump
# 3. Accept it using the MH ratio
# 4. Return the old or new value based on the MH ratio

updateTheta <- function(cp) {
  theta_star <- proposeTheta(cp$Theta)
  if (theta_star < 0) {
    return(cp)
  }

  old_lik <- cp$old_lik + priorTheta(cp$Theta)
  theta_star_mat <- getPmat(theta_star, cp$Rho, cp$acgt)
  new_lik_func <- logLikAll(cp$dat, theta_star_mat, cp$DeltaD, cp$DeltaS, cp$laVec, cp$nuVec, cp$m)
  new_lik <- new_lik_func + priorTheta(theta_star)

  if (metroDesc(new_lik, old_lik)) {
    cp$Theta <- theta_star
    cp$ThetaMat <- theta_star_mat
    cp$old_lik <- new_lik_func
  }

  return(cp)
}

updateRho <- function(cp) {
  rho_star <- proposeRho(cp$Rho)
  if (rho_star <= 0) {
    return(cp)
  }

  old_lik <- cp$old_lik + priorRho(cp$Rho)
  rho_star_mat <- getPmat(cp$Theta, rho_star, cp$acgt)
  new_lik_func <- logLikAll(cp$dat, rho_star_mat, cp$DeltaD, cp$DeltaS, cp$laVec, cp$nuVec, cp$m)
  new_lik <- new_lik_func + priorRho(rho_star)

  if (metroDesc(new_lik, old_lik)) {
    cp$Rho <- rho_star
    cp$ThetaMat <- rho_star_mat
    cp$old_lik <- new_lik_func
  }

  return(cp)
}

updateDeltaD <- function(cp) {
  deltad_star <- proposeDeltaD(cp$DeltaD)
  if (deltad_star < 0 || deltad_star > 1) {
    return(cp)
  }

  old_lik <- cp$old_lik + priorDeltaD(cp$DeltaD)
  new_lik_func <- logLikAll(cp$dat, cp$ThetaMat, deltad_star, cp$DeltaS, cp$laVec, cp$nuVec, cp$m)
  new_lik <- new_lik_func + priorDeltaD(deltad_star)

  if (metroDesc(new_lik, old_lik)) {
    cp$DeltaD <- deltad_star
    cp$old_lik <- new_lik_func
  }

  return(cp)
}

updateDeltaS <- function(cp) {
  deltas_star <- proposeDeltaS(cp$DeltaS)
  if (deltas_star < 0 || deltas_star > 1) {
    return(cp)
  }

  old_lik <- cp$old_lik + priorDeltaS(cp$DeltaS)
  new_lik_func <- logLikAll(cp$dat, cp$ThetaMat, cp$DeltaD, deltas_star, cp$laVec, cp$nuVec, cp$m)
  new_lik <- new_lik_func + priorDeltaS(deltas_star)

  if (metroDesc(new_lik, old_lik)) {
    cp$DeltaS <- deltas_star
    cp$old_lik <- new_lik_func
  }

  return(cp)
}

updateLambda <- function(cp) {
  lambda_star <- proposeLambda(cp$Lambda)
  if (lambda_star < 0 || lambda_star > 1) {
    return(cp)
  }

  old_lik <- cp$old_lik + priorLambda(cp$Lambda)
  laVecStarLeft <- seqProbVecLambda(lambda_star, cp$LambdaDisp, cp$m, cp$termini)
  if (cp$same_overhangs) {
    # It left and right are the same
    laVecStar <- laVecStarLeft
  } else {
    # The left and right overhangs are not the same
    laVecStar <- c(laVecStarLeft[1:(cp$m / 2)], cp$laVecRight[(cp$m / 2 + 1):cp$m])
  }

  new_lik_func <- logLikAll(cp$dat, cp$ThetaMat, cp$DeltaD, cp$DeltaS, laVecStar, cp$nuVec, cp$m)
  new_lik <- new_lik_func + priorLambda(lambda_star)

  if (metroDesc(new_lik, old_lik)) {
    cp$Lambda <- lambda_star
    cp$laVec <- laVecStar
    cp$old_lik <- new_lik_func
  }

  return(cp)
}

updateLambdaRight <- function(cp) {
  stopifnot(!cp$same_overhangs, cp$termini == "both")

  lambda_right_star <- proposeLambdaRight(cp$LambdaRight)
  if (lambda_right_star < 0 || lambda_right_star > 1) {
    return(cp)
  }

  old_lik <- cp$old_lik + priorLambdaRight(cp$LambdaRight)
  laVecStarRight <- seqProbVecLambda(lambda_right_star, cp$LambdaDisp, cp$m, cp$termini)
  # The left and right overhangs are not the same
  laVecStar <- c(cp$laVec[1:(cp$m / 2)], laVecStarRight[(cp$m / 2 + 1):cp$m])
  new_lik_func <- logLikAll(cp$dat, cp$ThetaMat, cp$DeltaD, cp$DeltaS, laVecStar, cp$nuVec, cp$m)
  new_lik <- new_lik_func + priorLambdaRight(lambda_right_star)

  if (metroDesc(new_lik, old_lik)) {
    cp$LambdaRight <- lambda_right_star
    cp$laVecRight <- laVecStar
    cp$old_lik <- new_lik_func
  }

  return(cp)
}

updateLambdaDisp <- function(cp) {
  lambda_disp_star <- proposeLambdaDisp(cp$LambdaDisp)
  if (lambda_disp_star < 0) {
    return(cp)
  }

  old_lik <- cp$old_lik + priorLambdaDisp(cp$LambdaDisp)
  if (cp$same_overhangs) {
    laVecStar <- seqProbVecLambda(cp$Lambda, lambda_disp_star, cp$m, cp$termini)
  } else {
    leftLaVecStar <- seqProbVecLambda(cp$Lambda, lambda_disp_star, cp$m, cp$termini)
    rightLaVecStar <- seqProbVecLambda(cp$LambdaRight, lambda_disp_star, cp$m, cp$termini)
    laVecStar <- c(leftLaVecStar[1:(cp$m / 2)], rightLaVecStar[(cp$m / 2 + 1):cp$m])
  }
  new_lik_func <- logLikAll(cp$dat, cp$ThetaMat, cp$DeltaD, cp$DeltaS, laVecStar, cp$nuVec, cp$m)
  new_lik <- new_lik_func + priorLambdaDisp(lambda_disp_star)

  if (metroDesc(new_lik, old_lik)) {
    cp$LambdaDisp <- lambda_disp_star
    cp$laVec <- laVecStar
    cp$old_lik <- new_lik_func
  }

  return(cp)
}