Re: [R] elegant matrix creation

From: Kjetil Halvorsen <kjetil_at_acelerate.com>
Date: Thu 29 Jul 2004 - 02:44:02 EST

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?
>



R-help@stat.math.ethz.ch mailing list
https://www.stat.math.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html Received on Thu Jul 29 03:03:03 2004

This archive was generated by hypermail 2.1.8 : Wed 03 Nov 2004 - 22:55:19 EST