Minimizes: \(1/2 ||w-v||^2_2 \quad\) s.t. \(sum_i w_i = 1, w_i \geq 0\)

project_onto_simplex(y)

Arguments

y

n dimensional vector to be projected onto the simplex

Value

proj_y projection of y onto the unit simplex of dimension n

Details

This code replicates a solution referenced on stackexchange, which linked to following Matlab code.

Examples

library(ggplot2) x1 <- runif(2, -5, 5) x2 <- c(.1, 1.6) x3 <- c(.1, 1.1) x4 <- c(.1,.1) x_vals <- list(x1, x2, x3, x4) proj_xs <- lapply(x_vals, project_onto_simplex) vis_list <- list() for (idx in 1:4){ x <- x_vals[[idx]] proj_x <- proj_xs[[idx]] data1 <- data.frame(X = x[1], Y = x[2], X_proj = proj_x[1], Y_proj = proj_x[2]) data_simplex <- data.frame(X_low = 0, Y_low = 1, X_high = 1, Y_high = 0) vis_list[[idx]] <- ggplot() + geom_segment(data = data1, aes(x = X, y = Y, xend = X_proj, yend = Y_proj)) + geom_point(data = data1, aes(x = X, y = Y)) + geom_point(data = data1, aes(x = X_proj, y = Y_proj), color = "blue") + geom_segment(data = data_simplex, aes(x = X_low, y = Y_low, xend = X_high, yend = Y_high), color = "blue") + coord_fixed() }
#> Coordinate system already present. Adding new coordinate system, which will replace the existing one.
#> Coordinate system already present. Adding new coordinate system, which will replace the existing one.
#> Coordinate system already present. Adding new coordinate system, which will replace the existing one.
#> Coordinate system already present. Adding new coordinate system, which will replace the existing one.
gridExtra::grid.arrange(grobs = vis_list, nrow = 2)