Nothing
## ----setup, include = FALSE, echo = FALSE, message = FALSE--------------------
knitr::opts_chunk$set(echo = TRUE, collapse = TRUE, comment = "#>")
library(mize)
## ----cost function------------------------------------------------------------
# R and D are the input and output distance matrices, respectively
cost_fun <- function(R, D) {
diff2 <- (R - D) ^ 2
sum(diff2) * 0.5
}
## ----convert dist to matrix---------------------------------------------------
eurodist_mat <- as.matrix(eurodist)
## ----MMDS gradient------------------------------------------------------------
# R is the input distance matrix
# D is the output distance matrix
# y is a n x d matrix of output coordinates
cost_grad <- function(R, D, y) {
K <- (R - D) / (D + 1.e-10)
G <- matrix(nrow = nrow(y), ncol = ncol(y))
for (i in 1:nrow(y)) {
dyij <- sweep(-y, 2, -y[i, ])
G[i, ] <- apply(dyij * K[, i], 2, sum)
}
as.vector(t(G)) * -2
}
## ----mize function------------------------------------------------------------
mmds_fn <- function(par) {
R <- as.matrix(eurodist)
y <- matrix(par, ncol = 2, byrow = TRUE)
D <- as.matrix(stats::dist(y))
cost_fun(R, D)
}
## ----mize gradient------------------------------------------------------------
mmds_gr <- function(par) {
R <- as.matrix(eurodist)
y <- matrix(par, ncol = 2, byrow = TRUE)
D <- as.matrix(stats::dist(y))
cost_grad(R, D, y)
}
## ----optimization-------------------------------------------------------------
set.seed(42)
ed0 <- rnorm(attr(eurodist, 'Size') * 2)
res_euro <- mize(ed0, list(fn = mmds_fn, gr = mmds_gr),
method = "L-BFGS", verbose = TRUE,
grad_tol = 1e-5, check_conv_every = 10)
## ----plot results, fig.width=5.5, fig.height=5.5------------------------------
plot_mmds <- function(coords, dist, ...) {
if (methods::is(coords, "numeric")) {
coords <- matrix(coords, ncol = 2, byrow = TRUE)
}
graphics::plot(coords, type = 'n')
graphics::text(coords[, 1], coords[, 2], labels = labels(dist), ...)
}
plot_mmds(res_euro$par, eurodist, cex = 0.5)
## ----rotated plot, fig.width=5.5, fig.height=5.5------------------------------
rot90 <- matrix(c(0, -1, 1, 0), ncol = 2)
rotated <- t(rot90 %*% t(matrix(res_euro$par, ncol = 2, byrow = TRUE)))
plot_mmds(rotated, eurodist, cex = 0.5)
## ----more efficient fg--------------------------------------------------------
make_fg <- function(distmat) {
R <- as.matrix(distmat)
cost_fun <- function(R, D) {
diff2 <- (R - D) ^ 2
sum(diff2) * 0.5
}
cost_grad <- function(R, D, y) {
K <- (R - D) / (D + 1.e-10)
G <- matrix(nrow = nrow(y), ncol = ncol(y))
for (i in 1:nrow(y)) {
dyij <- sweep(-y, 2, -y[i, ])
G[i, ] <- apply(dyij * K[, i], 2, sum)
}
as.vector(t(G)) * -2
}
list(
fn = function(par) {
y <- matrix(par, ncol = 2, byrow = TRUE)
D <- as.matrix(stats::dist(y))
cost_fun(R, D)
},
gr = function(par) {
y <- matrix(par, ncol = 2, byrow = TRUE)
D <- as.matrix(stats::dist(y))
cost_grad(R, D, y)
},
fg = function(par) {
y <- matrix(par, ncol = 2, byrow = TRUE)
D <- as.matrix(stats::dist(y))
list(
fn = cost_fun(R, D),
gr = cost_grad(R, D, y)
)
}
)
}
## ----optimization with improved fg--------------------------------------------
res_euro <- mize(ed0, make_fg(eurodist),
method = "L-BFGS", verbose = TRUE,
grad_tol = 1e-5, check_conv_every = 10)
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.