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) }