Here are some guidelines for suggested solutions.
ndoogan takes the lead!
Benchmark
x <- 1:100 microbenchmark( OP.Circulant(x), Josh.Circulant(x), Dwin.Circulant(x) , Matt.Circulant(x), Matt.Circulant2(x), Ndoogan.Circulant(x), times=100 )
Code used for testing
OP.Circulant <- function(x) { n <- length(x) mat <- matrix(NA, n, n) for (i in 1:n) { mat[i, ] <- c(x[-(1:(n + 1 - i))], x[1:(n + 1 - i)]) } return(mat) } rotn <- function(x, n) rep(x, 2)[n:(n + length(x) - 1)] Dwin.Circulant <- function(x) { n <- length(x) return(t(sapply(x[c(1L, n:2)], rotn, x = x))) } Josh.Circulant <- function(x, nrow = length(x)) { m <- length(x) return(matrix(x[(1:m - rep(1:nrow, each = m))%%m + 1L], ncol = m, byrow = TRUE)) } Matt.Circulant <- function(x) { n <- length(x) mat <- matrix(, n, n) for (i in seq(-n + 1, n - 1)) { mat[row(mat) == col(mat) - i] = x[i%%n + 1] } return(mat) } Matt.Circulant2 <- function(x) { n <- length(x) return(rbind(x[], do.call(rbind, lapply(seq(n - 1), function(i) c(tail(x, i), head(x, -i)))))) } Ndoogan.Circulant <-function(x) { n <- length(x) suppressWarnings( matrix(x[matrix(1:n,n+1,n+1,byrow=T)[c(1,n:2),1:n]],n,n)) }
source share