I want to create a circulant matrix from a vector in R. A circulant matrix is a matrix with the following form.
1 2 3 4
4 1 2 3
3 4 1 2
2 3 4 1
The second row is the same as the first row except the last element is at the beginning, and so on.
Now I have the vector, say, (1, 2, 3, 4) and I want to find a efficient (fast) way to create this matrix. In practice, the numbers are not integers and can be any numbers.
Here is what I am doing now.
x <- 1:4
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)])
}
I wonder if there is a faster way to do this? I need to generate this kind of matrices over and over. A small improvement for one step will make a big difference. Thank you.
This makes use of vector recycling (it throws a warning):
circ<-function(x) {
n<-length(x)
matrix(x[matrix(1:n,n+1,n+1,byrow=T)[c(1,n:2),1:n]],n,n)
}
circ(letters[1:4])
# [,1] [,2] [,3] [,4]
#[1,] "a" "b" "c" "d"
#[2,] "d" "a" "b" "c"
#[3,] "c" "d" "a" "b"
#[4,] "b" "c" "d" "a"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With