library(ggplot2)
|
|
library(gganimate)
|
|
library(patchwork)
|
|
|
|
gradient <- function(f, x, d){
|
|
return((f(x + d) - f(x - d)) / (2*d))
|
|
}
|
|
|
|
gradient.ascent.move <- function(f, x, d, mu){
|
|
return(x + mu * gradient(f, x, d))
|
|
}
|
|
|
|
func.g <- function(x) x
|
|
func.k <- function(x) sin(x)
|
|
func.h <- function(x) x * sin(x)
|
|
func.l <- function(x) 2 + cos(x) + sin(2*x)
|
|
|
|
gradient.ascent.iterate <- function(f, x, d, mu, n){
|
|
if(n == 1) {
|
|
return(gradient.ascent.move(f, x, d, mu))
|
|
}
|
|
|
|
return(gradient.ascent.niter(f
|
|
,gradient.descent.move(f, x, d, mu)
|
|
,d
|
|
,mu
|
|
,n-1
|
|
))
|
|
}
|
|
|
|
gradient.ascent.iterverb <- function(f, x, d, mu, n, xs=numeric()){
|
|
next_x <- gradient.ascent.move(f, x, d, mu)
|
|
xs[length(xs)+1] <- next_x
|
|
|
|
if(n == 1) {
|
|
return(xs)
|
|
}
|
|
|
|
return(gradient.ascent.iterverb(f, next_x, d, mu, n-1, xs))
|
|
}
|
|
|
|
trace.ascent <- function(f, x, d, eta, n, xs) {
|
|
df_dc = data.frame(x=numeric()
|
|
,y=numeric()
|
|
,i=integer()
|
|
,start_x=character()
|
|
,eta=numeric())
|
|
|
|
for(start in x) {
|
|
for(e in eta) {
|
|
first_it <- TRUE
|
|
if(first_it == TRUE) {
|
|
df_dc <- rbind(df_dc, data.frame(x=c(start)
|
|
,y=c(f(start))
|
|
,i=c(0)
|
|
,start_x=c(as.character(start))
|
|
,eta=c(e)
|
|
))
|
|
first_it <- FALSE
|
|
}
|
|
|
|
xf <- gradient.ascent.iterverb(f, start, d, e, n)
|
|
|
|
df_dc <- rbind(df_dc, data.frame(x=xf
|
|
,y=f(xf)
|
|
,i=1:length(xf)
|
|
,start_x=rep(as.character(start), length(xf))
|
|
,eta=e)
|
|
)
|
|
}
|
|
}
|
|
|
|
return(df_dc)
|
|
}
|
|
|
|
plot.ascent <- function(f, x, d, eta, n, xs) {
|
|
df_dc = trace.ascent(f, x, d, eta, n, xs)
|
|
|
|
func_str = deparse(substitute(f))
|
|
|
|
df_f <- data.frame(x=xs, y=f(xs))
|
|
p1 <- ggplot(df_f, aes(x=x, y=y)) +
|
|
geom_line() +
|
|
geom_point(aes(colour=start_x
|
|
,size=i
|
|
)
|
|
,data=df_dc) +
|
|
labs(size="iteration"
|
|
,alpha="iteration"
|
|
,color="start x"
|
|
,y=sprintf("%s(x)", func_str)) +
|
|
facet_grid(eta ~ ., labeller=label_both)
|
|
|
|
p2 <- ggplot(df_dc, aes(x=i, y=y)) +
|
|
geom_line(aes(colour=start_x), show.legend=FALSE) +
|
|
labs(x="iteration"
|
|
,y=sprintf("%s(x)", func_str)) +
|
|
facet_grid(eta ~ ., labeller=label_both)
|
|
|
|
p <- (p1 | p2) +
|
|
plot_annotation(title=sprintf("function: %s", func_str)) +
|
|
plot_layout(guides="collect"
|
|
,widths=10
|
|
,heights=2)
|
|
|
|
return(p)
|
|
}
|
|
|
|
animate.ascent <- function(f, x, d, eta, n, xs) {
|
|
df_dc = trace.ascent(f, x, d, eta, n, xs)
|
|
|
|
func_str <- deparse(substitute(f))
|
|
|
|
df_f <- data.frame(x=xs, y=f(xs))
|
|
|
|
p <- ggplot(df_f, aes(x=x, y=y)) +
|
|
geom_line() +
|
|
geom_point(aes(colour=start_x), size=2.5, data=df_dc) +
|
|
labs(color="start x", y=sprintf("%s(x)", func_str)) +
|
|
facet_grid(eta ~ ., labeller=label_both) +
|
|
ggtitle(sprintf("function: %s", func_str))
|
|
|
|
anim <- p + transition_reveal(i)
|
|
|
|
return(anim)
|
|
}
|