nll <- function(X, Y, beta) {
A <- Y - X %*% beta
loglike <- crossprod(A)
return(loglike)
}
# Proximal operator
prox.l1 <- function(u, lambda) {
uhat <- abs(u) - lambda
prox <- sign(u) * pmax(rep(0, length(u)), uhat)
return(prox)
}
l2norm <- function(x) sqrt(sum(x^2))
ADMM <- function(X,Y,rho=5,lambda=.1,iter=100, eps = 0.0001){
n <- nrow(X)
p <- ncol(X)
beta <- matrix(0, nrow=iter, ncol=p)
beta[1,] <- rep(0, p)
obj <- rep(0, iter)
obj[1] <- nll(X, Y, beta[1,]) + lambda * sum(abs(beta[1,]))
z <- matrix(0, nrow=iter, ncol=p)
v <- rep(0, p)
invmat <- solve(2*crossprod(X) + diag(rho, p))
s <- 0
r <- 0
t <- 0
for (t in 2:iter){
beta[t,] <- invmat %*% (2*crossprod(X, Y) + rho * (z[t-1,]-v))
z[t,] <- prox.l1(beta[t,] + v, lambda/rho)
v <- v + beta[t,] - z[t,]
obj[t] <- nll(X, Y, beta[t,]) + lambda * sum(abs(beta[t,]))
r <- beta[t,] - z[t,]
s <- -rho * (z[t,] - z[t-1,])
r.norm <- l2norm(r)
s.norm <- l2norm(s)
if (r.norm < eps & s.norm < eps) {
break
}
}
beta <- beta[-c(t+1:iter),]
obj <- obj[-c(t+1:iter)]
result <- list("beta.hat" = beta[nrow(beta),], "beta"=beta, "objective"=obj, "iter"=t)
return(result)
}
x <- cbind(1, matrix(rnorm(1000*4), ncol = 4))
beta <- c(1.4, -2, -3, 4, 5)
eps <- rnorm(1000*1)
y <- x%*%beta + eps
ADMM(X = x, Y = y)
$beta.hat
[1] 1.379323 -1.990279 -2.998234 4.018089 5.044086
$beta
[,1] [,2] [,3] [,4] [,5]
[1,] 0.000000 0.000000 0.000000 0.000000 0.000000
[2,] 1.376414 -1.985059 -2.991330 4.008202 5.031837
[3,] 1.379269 -1.990212 -2.998172 4.018014 5.044009
[4,] 1.379323 -1.990278 -2.998234 4.018089 5.044086
[5,] 1.379323 -1.990279 -2.998234 4.018089 5.044086
$objective
[1] 58940.123 1022.952 1022.613 1022.613 1022.613
$iter
[1] 5