[R] elegant matrix creation
Kjetil Halvorsen
kjetil at acelerate.com
Wed Jul 28 18:44:02 CEST 2004
Robin Hankin wrote:
> Hello everybody.
>
> I am trying to reproduce a particular matrix in an elegant way. If I
> have
>
> jj1 <-
> structure(c(1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,
> 3,1,2,3,1,2,3,1,2,3,2,3,1,2,3,1,2,3,1,2,3,
> 1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,3,1,2,3,1,
> 2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,
> 2),.Dim = as.integer(c(9,9)))
>
> [ image(jj1) is good here ] then I can get this with
>
> kronecker(matrix(1,3,1),kronecker(1+outer(0:2,0:2,"+")%%3,matrix(1,1,3)))
>
> I want to reproduce the following matrices in an equivalent way:
>
> jj2 <- matrix(c(1,2,3,1,2,3,1,2,3,2,3,1,2,3,1,2,3,1,
> 1,2,3,1,2,3,1,2,3,3,1,2,3,1,2,3,1,2,1,2,3,1,2,
> 3,1,2,3,3,1,2,3,1,2,3,1,2,2,3,1,2,3,1,2,3,1,3,
> 1,2,3,1,2,3,1,2,2,3,1,2,3,1,2,3,1),9,9)
>
> jj3 <- structure(c(1,2,3,2,3,1,3,1,2,1,2,1,2,3,2,3,1,
> 3,1,3,1,2,1,2,3,2,3,2,3,1,3,1,2,1,2,3,2,3,
> 2,3,1,3,1,2,1,2,1,2,3,2,3,1,3,1,3,1,2,1,2,
> 3,2,3,1,3,1,3,1,2,1,2,3,2,3,2,3,1,3,1,2,1, 2),.Dim =
> as.integer(c(9,9)))
>
some musings. You have not told us hove jj3 arises naturally, but its
structure seems to have something to do with magic squares. So
library(magic) # on CRAN
is.magic(jj3) # TRUE
This is not in accordance with my concept of magic squares, since
an n*n magic square should have all the numbers from 1 to n^2 exactly
once. But all rowSums and colSums are equal.
Note that if we view jj3 as a 3*3 block matrix, with each block
a 3*3 matrix, then all the blockx are generated rowwise the following
way: Let x in 1:3 be the generator, and + be sum modulo 3, but we take
the rep 3 and not 0.
Then we have
x x x
x+1 x+1 x+2
x+2 x x
and the 3*3 matrix of the generators can be generated in the following way:
> xx <- ((magic(3) %% 3)+1)[,3:1]
> xx
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 2 3 1
[3,] 3 1 2
> "++" <- function(x,a) {
if ( (x+a)%%3 == 0 ) 3 else (x+a) %% 3 }
> makeBlock <- function(x) {
+ matrix( c( rep(x,3), rep("++"(x,1), 2), rep("++"(x,2), 2),
+ rep(x,2) ) , 3,3, byrow=TRUE) }
> makeBlock(1)
[,1] [,2] [,3]
[1,] 1 1 1
[2,] 2 2 3
[3,] 3 1 1
> ans <- matrix (NA,9,9)
> for (i in 1:3) for (j in 1:3) {
+ ans[3*(i-1)+1:3, 3*(j-1)+1:3] <- makeBlock(xx[i,j]) }
> ans
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
[1,] 1 1 1 2 2 2 3 3 3
[2,] 2 2 3 3 3 1 1 1 2
[3,] 3 1 1 1 2 2 2 3 3
[4,] 2 2 2 3 3 3 1 1 1
[5,] 3 3 1 1 1 2 2 2 3
[6,] 1 2 2 2 3 3 3 1 1
[7,] 3 3 3 1 1 1 2 2 2
[8,] 1 1 2 2 2 3 3 3 1
[9,] 2 3 3 3 1 1 1 2 2
> ans ==jj3
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
[1,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[2,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[3,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[4,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[5,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[6,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[7,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[8,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[9,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
Kjetil Halvorsen
> [ note that jj1-jj3 each have precisely 3 occurrences of A, B, and C
> along each row, column and (broken) diagonal ].
>
> Can anyone give me a nice elegant way of creating jj2 and jj3 please?
>
More information about the R-help
mailing list