grad.desc = function(
  FUN = function(x, y) x^2 + 2 * y^2, rg = c(-3, -3, 3, 3), init = c(-3, 3),
  gamma = 0.05, tol = 0.001, gr = NULL, len = 50, nmax = 50) {
  x <- seq(rg[1], rg[3], length = len)
  y <- seq(rg[2], rg[4], length = len)
  contour <- expand.grid(x = x, y = y)
  contour$z <- as.vector(outer(x, y, FUN))
  
  nms = names(formals(FUN))
  grad = if (is.null(gr)) {
    deriv(as.expression(body(FUN)), nms, function.arg = TRUE)
  } else {
    function(...) {
      res = FUN(...)
      attr(res, 'gradient') = matrix(gr(...), nrow = 1, ncol = 2)
      res
    }
  }
  
  xy <- init
  newxy <- xy - gamma * attr(grad(xy[1], xy[2]), 'gradient')
  z <- FUN(newxy[1], newxy[2])
  gap <- abs(z - FUN(xy[1], xy[2]))
  i <- 1
  while (gap > tol && i <= nmax) {
    xy <- rbind(xy, newxy[i, ])
    newxy <- rbind(newxy, xy[i + 1, ] - gamma * attr(grad(xy[i + 1, 1], xy[i + 1, 2]), 'gradient'))
    z <- c(z, FUN(newxy[i + 1, 1], newxy[i + 1, 2]))
    gap <- abs(z[i + 1] - FUN(xy[i + 1, 1], xy[i + 1, 2]))
    i <- i + 1
    if (i > nmax) warning('Maximum number of iterations reached!')
  }
  objective <- data.frame(iteration = 1:i, x = xy[, 1], y = xy[, 2], 
                          newx = newxy[, 1], newy = newxy[, 2], z = z)
  invisible(
    list(contour = contour, objective = objective)
  )
}
dat <- grad.desc()
contour <- dat$contour
objective <- dat$objective
library(plyr)
objective <- ldply(objective$iteration, function(i) {
  df <- subset(objective, iteration <= i)
  cbind(df, iteration2 = i)
})
objective2 <- subset(objective, iteration == iteration2)
library(animint)
Loading required package: ggplot2
library(grid)
#library(proto)
(contour.plot <- ggplot() + 
    geom_contour(data = contour, aes(x = x, y = y, z = z, colour = ..level..), size = .5) + 
    scale_colour_continuous(name = "z value") + 
    geom_path(data = objective, aes(x = x, y = y, showSelected = iteration2), 
              colour = "red", size = 1, arrow = arrow(length = unit(.5, "cm"))) + 
    # argument arrow doesn't take effect.
    geom_point(data = objective, aes(x = x, y = y, showSelected = iteration2), colour = "green", 
               size = 2) + 
    geom_text(data = objective2, aes(x = x, y = y - 0.2, label = round(z, 2), showSelected = iteration2), 
              vjust = 1) + 
    # argument vjust or hjust doesn't take effect.
    scale_x_continuous(expand = c(0, 0)) + 
    scale_y_continuous(expand = c(0, 0)) + 
    ggtitle("contour of function value") + 
    theme_animint(width = 600, height = 600))
Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.

(objective.plot <- ggplot() +
    geom_line(data = objective2, aes(x = iteration, y = z), colour = "red") + 
    geom_point(data = objective2, aes(x = iteration, y = z), colour = "red") + 
    geom_tallrect(data = objective2, aes(xmin = iteration - 1 / 2, xmax = iteration + 1 / 2, 
                                         clickSelects = iteration2), alpha = .3) + 
    geom_text(data = objective2, aes(x = iteration, y = z + 0.3, showSelected = iteration2, 
                                     label = iteration)) + 
    ggtitle("objective value vs. iteration") + 
    theme_animint(width = 600, height = 600))
Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.

viz <- list(contour = contour.plot, objective = objective.plot, 
            time = list(variable = "iteration2", ms = 2000), 
            title = "Demonstration of Gradient Descent Algorithm")
animint2dir(viz, out.dir = "grad.desc")
Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.
[1] 1
animint only supports vjust=0opening a web browser with a file:// URL; if the web page is blank, try running
if (!requireNamespace("servr")) install.packages("servr")
servr::httd("/home/anshul/grad.desc")
animint2gist(viz, out.dir = "grad.desc")
Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.Calling 'structure(NULL, *)' is deprecated, as NULL cannot have attributes.
  Consider 'structure(list(), *)' instead.
[1] 1
animint only supports vjust=0Loading required namespace: gistr
<gist>fba7546582315e27b637dfeabe254e59
  URL: https://gist.github.com/fba7546582315e27b637dfeabe254e59
  Description: Demonstration of Gradient Descent Algorithm
  Public: TRUE
  Created/Edited: 2019-01-28T10:33:03Z / 2019-01-28T10:33:03Z
  Files: animint.js, d3.v3.js, geom1_contour_contour_chunk1.tsv, geom1_point_plot_chunk1.tsv, geom2_path_contour_chunk1.tsv, geom2_segment_plot_chunk1.tsv, geom3_point_contour_chunk1.tsv, geom3_text_plot_chunk1.tsv, geom4_text_contour_chunk1.tsv, geom5_line_objective_chunk1.tsv, geom6_point_objective_chunk1.tsv, geom7_tallrect_objective_chunk1.tsv, geom8_text_objective_chunk1.tsv, index.html, jquery-1.11.3.min.js, plot.json, scripts.html, selectize.css, selectize.min.js
  Truncated?: FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE
LS0tCnRpdGxlOiAiR3JhZGllbnQgRGVzY2VudCBpbiBhbmltaW50IgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpgYGB7cn0KCmdyYWQuZGVzYyA9IGZ1bmN0aW9uKAogIEZVTiA9IGZ1bmN0aW9uKHgsIHkpIHheMiArIDIgKiB5XjIsIHJnID0gYygtMywgLTMsIDMsIDMpLCBpbml0ID0gYygtMywgMyksCiAgZ2FtbWEgPSAwLjA1LCB0b2wgPSAwLjAwMSwgZ3IgPSBOVUxMLCBsZW4gPSA1MCwgbm1heCA9IDUwKSB7CiAgeCA8LSBzZXEocmdbMV0sIHJnWzNdLCBsZW5ndGggPSBsZW4pCiAgeSA8LSBzZXEocmdbMl0sIHJnWzRdLCBsZW5ndGggPSBsZW4pCiAgY29udG91ciA8LSBleHBhbmQuZ3JpZCh4ID0geCwgeSA9IHkpCiAgY29udG91ciR6IDwtIGFzLnZlY3RvcihvdXRlcih4LCB5LCBGVU4pKQogIAogIG5tcyA9IG5hbWVzKGZvcm1hbHMoRlVOKSkKICBncmFkID0gaWYgKGlzLm51bGwoZ3IpKSB7CiAgICBkZXJpdihhcy5leHByZXNzaW9uKGJvZHkoRlVOKSksIG5tcywgZnVuY3Rpb24uYXJnID0gVFJVRSkKICB9IGVsc2UgewogICAgZnVuY3Rpb24oLi4uKSB7CiAgICAgIHJlcyA9IEZVTiguLi4pCiAgICAgIGF0dHIocmVzLCAnZ3JhZGllbnQnKSA9IG1hdHJpeChnciguLi4pLCBucm93ID0gMSwgbmNvbCA9IDIpCiAgICAgIHJlcwogICAgfQogIH0KICAKICB4eSA8LSBpbml0CiAgbmV3eHkgPC0geHkgLSBnYW1tYSAqIGF0dHIoZ3JhZCh4eVsxXSwgeHlbMl0pLCAnZ3JhZGllbnQnKQogIHogPC0gRlVOKG5ld3h5WzFdLCBuZXd4eVsyXSkKICBnYXAgPC0gYWJzKHogLSBGVU4oeHlbMV0sIHh5WzJdKSkKICBpIDwtIDEKICB3aGlsZSAoZ2FwID4gdG9sICYmIGkgPD0gbm1heCkgewogICAgeHkgPC0gcmJpbmQoeHksIG5ld3h5W2ksIF0pCiAgICBuZXd4eSA8LSByYmluZChuZXd4eSwgeHlbaSArIDEsIF0gLSBnYW1tYSAqIGF0dHIoZ3JhZCh4eVtpICsgMSwgMV0sIHh5W2kgKyAxLCAyXSksICdncmFkaWVudCcpKQogICAgeiA8LSBjKHosIEZVTihuZXd4eVtpICsgMSwgMV0sIG5ld3h5W2kgKyAxLCAyXSkpCiAgICBnYXAgPC0gYWJzKHpbaSArIDFdIC0gRlVOKHh5W2kgKyAxLCAxXSwgeHlbaSArIDEsIDJdKSkKICAgIGkgPC0gaSArIDEKICAgIGlmIChpID4gbm1heCkgd2FybmluZygnTWF4aW11bSBudW1iZXIgb2YgaXRlcmF0aW9ucyByZWFjaGVkIScpCiAgfQogIG9iamVjdGl2ZSA8LSBkYXRhLmZyYW1lKGl0ZXJhdGlvbiA9IDE6aSwgeCA9IHh5WywgMV0sIHkgPSB4eVssIDJdLCAKICAgICAgICAgICAgICAgICAgICAgICAgICBuZXd4ID0gbmV3eHlbLCAxXSwgbmV3eSA9IG5ld3h5WywgMl0sIHogPSB6KQogIGludmlzaWJsZSgKICAgIGxpc3QoY29udG91ciA9IGNvbnRvdXIsIG9iamVjdGl2ZSA9IG9iamVjdGl2ZSkKICApCn0KYGBgCgoKYGBge3J9CmRhdCA8LSBncmFkLmRlc2MoKQpjb250b3VyIDwtIGRhdCRjb250b3VyCm9iamVjdGl2ZSA8LSBkYXQkb2JqZWN0aXZlCgpsaWJyYXJ5KHBseXIpCm9iamVjdGl2ZSA8LSBsZHBseShvYmplY3RpdmUkaXRlcmF0aW9uLCBmdW5jdGlvbihpKSB7CiAgZGYgPC0gc3Vic2V0KG9iamVjdGl2ZSwgaXRlcmF0aW9uIDw9IGkpCiAgY2JpbmQoZGYsIGl0ZXJhdGlvbjIgPSBpKQp9KQpvYmplY3RpdmUyIDwtIHN1YnNldChvYmplY3RpdmUsIGl0ZXJhdGlvbiA9PSBpdGVyYXRpb24yKQpgYGAKCgpgYGB7cn0KbGlicmFyeShhbmltaW50KQpsaWJyYXJ5KGdyaWQpCiNsaWJyYXJ5KHByb3RvKQoKKGNvbnRvdXIucGxvdCA8LSBnZ3Bsb3QoKSArIAogICAgZ2VvbV9jb250b3VyKGRhdGEgPSBjb250b3VyLCBhZXMoeCA9IHgsIHkgPSB5LCB6ID0geiwgY29sb3VyID0gLi5sZXZlbC4uKSwgc2l6ZSA9IC41KSArIAogICAgc2NhbGVfY29sb3VyX2NvbnRpbnVvdXMobmFtZSA9ICJ6IHZhbHVlIikgKyAKICAgIGdlb21fcGF0aChkYXRhID0gb2JqZWN0aXZlLCBhZXMoeCA9IHgsIHkgPSB5LCBzaG93U2VsZWN0ZWQgPSBpdGVyYXRpb24yKSwgCiAgICAgICAgICAgICAgY29sb3VyID0gInJlZCIsIHNpemUgPSAxLCBhcnJvdyA9IGFycm93KGxlbmd0aCA9IHVuaXQoLjUsICJjbSIpKSkgKyAKICAgICMgYXJndW1lbnQgYXJyb3cgZG9lc24ndCB0YWtlIGVmZmVjdC4KICAgIGdlb21fcG9pbnQoZGF0YSA9IG9iamVjdGl2ZSwgYWVzKHggPSB4LCB5ID0geSwgc2hvd1NlbGVjdGVkID0gaXRlcmF0aW9uMiksIGNvbG91ciA9ICJncmVlbiIsIAogICAgICAgICAgICAgICBzaXplID0gMikgKyAKICAgIGdlb21fdGV4dChkYXRhID0gb2JqZWN0aXZlMiwgYWVzKHggPSB4LCB5ID0geSAtIDAuMiwgbGFiZWwgPSByb3VuZCh6LCAyKSwgc2hvd1NlbGVjdGVkID0gaXRlcmF0aW9uMiksIAogICAgICAgICAgICAgIHZqdXN0ID0gMSkgKyAKICAgICMgYXJndW1lbnQgdmp1c3Qgb3IgaGp1c3QgZG9lc24ndCB0YWtlIGVmZmVjdC4KICAgIHNjYWxlX3hfY29udGludW91cyhleHBhbmQgPSBjKDAsIDApKSArIAogICAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwgMCkpICsgCiAgICBnZ3RpdGxlKCJjb250b3VyIG9mIGZ1bmN0aW9uIHZhbHVlIikgKyAKICAgIHRoZW1lX2FuaW1pbnQod2lkdGggPSA2MDAsIGhlaWdodCA9IDYwMCkpCgoob2JqZWN0aXZlLnBsb3QgPC0gZ2dwbG90KCkgKwogICAgZ2VvbV9saW5lKGRhdGEgPSBvYmplY3RpdmUyLCBhZXMoeCA9IGl0ZXJhdGlvbiwgeSA9IHopLCBjb2xvdXIgPSAicmVkIikgKyAKICAgIGdlb21fcG9pbnQoZGF0YSA9IG9iamVjdGl2ZTIsIGFlcyh4ID0gaXRlcmF0aW9uLCB5ID0geiksIGNvbG91ciA9ICJyZWQiKSArIAogICAgZ2VvbV90YWxscmVjdChkYXRhID0gb2JqZWN0aXZlMiwgYWVzKHhtaW4gPSBpdGVyYXRpb24gLSAxIC8gMiwgeG1heCA9IGl0ZXJhdGlvbiArIDEgLyAyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGlja1NlbGVjdHMgPSBpdGVyYXRpb24yKSwgYWxwaGEgPSAuMykgKyAKICAgIGdlb21fdGV4dChkYXRhID0gb2JqZWN0aXZlMiwgYWVzKHggPSBpdGVyYXRpb24sIHkgPSB6ICsgMC4zLCBzaG93U2VsZWN0ZWQgPSBpdGVyYXRpb24yLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsID0gaXRlcmF0aW9uKSkgKyAKICAgIGdndGl0bGUoIm9iamVjdGl2ZSB2YWx1ZSB2cy4gaXRlcmF0aW9uIikgKyAKICAgIHRoZW1lX2FuaW1pbnQod2lkdGggPSA2MDAsIGhlaWdodCA9IDYwMCkpCgp2aXogPC0gbGlzdChjb250b3VyID0gY29udG91ci5wbG90LCBvYmplY3RpdmUgPSBvYmplY3RpdmUucGxvdCwgCiAgICAgICAgICAgIHRpbWUgPSBsaXN0KHZhcmlhYmxlID0gIml0ZXJhdGlvbjIiLCBtcyA9IDIwMDApLCAKICAgICAgICAgICAgdGl0bGUgPSAiRGVtb25zdHJhdGlvbiBvZiBHcmFkaWVudCBEZXNjZW50IEFsZ29yaXRobSIpCmBgYAoKYGBge3J9CmFuaW1pbnQyZGlyKHZpeiwgb3V0LmRpciA9ICJncmFkLmRlc2MiKQpgYGAKCmBgYHtyfQphbmltaW50Mmdpc3Qodml6LCBvdXQuZGlyID0gImdyYWQuZGVzYyIpCmBgYAoK