Split matrix into square submatices

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Split matrix into square submatices

xiddw
Hi everybody,

I'm looking for an optimal way to split  a big matrix  (e.g. ncol = 8, nrow=8)  into small square submatrices  (e.g. ncol=2, nrow=2)

For example

If I have

>  h
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,]    1    9   17   25   33   41   49   57
[2,]    2   10   18   26   34   42   50   58
[3,]    3   11   19   27   35   43   51   59
[4,]    4   12   20   28   36   44   52   60
[5,]    5   13   21   29   37   45   53   61
[6,]    6   14   22   30   38   46   54   62
[7,]    7   15   23   31   39   47   55   63
[8,]    8   16   24   32   40   48   56   64

and I want to split matriz h into 16 small submatrices:

> g[1]
     [,1] [,2]
[1,]    1    9
[2,]    2   10

> g[2]
     [,1] [,2]
[1,]   17   25
[2,]   18   26

...

> g[4]
     [,1] [,2]
[1,]   49   57
[2,]   50   58

...

> g[16]
     [,1] [,2]
[1,]   55   63
[2,]   56   64

Always the big matrix would be a square matrix and also would have a nrow and ncol in order of  a power of two, so it always could  be splitted in at least halves.

Until now, I'm able to split a matrix but keeping the number of original matrix columns.

I mean, if I want to split into 16 submatrices, using the following command what I get its 4 lists:
But I haven't found a way to split resultant lists in order to get 4 matrices for each list.

> g <- split(as.data.frame(h), (1:4))
> g
$`1`
  V1 V2 V3 V4 V5 V6 V7 V8
1  1  9 17 25 33 41 49 57
5  5 13 21 29 37 45 53 61

$`2`
  V1 V2 V3 V4 V5 V6 V7 V8
2  2 10 18 26 34 42 50 58
6  6 14 22 30 38 46 54 62

$`3`
  V1 V2 V3 V4 V5 V6 V7 V8
3  3 11 19 27 35 43 51 59
7  7 15 23 31 39 47 55 63

$`4`
  V1 V2 V3 V4 V5 V6 V7 V8
4  4 12 20 28 36 44 52 60
8  8 16 24 32 40 48 56 64


I would appreciate any hint. Thanks.
Reply | Threaded
Open this post in threaded view
|

Re: Split matrix into square submatices

Petr Savicky
On Fri, Feb 10, 2012 at 12:02:25AM -0800, xiddw wrote:

> Hi everybody,
>
> I'm looking for an optimal way to split  a big matrix  (e.g. ncol = 8,
> nrow=8)  into small square submatrices  (e.g. ncol=2, nrow=2)
>
> For example
>
> If I have
>
> >  h
>      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
> [1,]    1    9   17   25   33   41   49   57
> [2,]    2   10   18   26   34   42   50   58
> [3,]    3   11   19   27   35   43   51   59
> [4,]    4   12   20   28   36   44   52   60
> [5,]    5   13   21   29   37   45   53   61
> [6,]    6   14   22   30   38   46   54   62
> [7,]    7   15   23   31   39   47   55   63
> [8,]    8   16   24   32   40   48   56   64
>
> and I want to split matriz h into 16 small submatrices:
>
> > g[1]
>      [,1] [,2]
> [1,]    1    9
> [2,]    2   10
>
> > g[2]
>      [,1] [,2]
> [1,]   17   25
> [2,]   18   26
>
> ...
>
> > g[4]
>      [,1] [,2]
> [1,]   49   57
> [2,]   50   58
>
> ...
>
> > g[16]
>      [,1] [,2]
> [1,]   55   63
> [2,]   56   64
>
> Always the big matrix would be a square matrix and also would have a nrow
> and ncol in order of  a power of two, so it always could  be splitted in at
> least halves.
>
> Until now, I'm able to split a matrix but keeping the number of original
> matrix columns.
>
> I mean, if I want to split into 16 submatrices, using the following command
> what I get its 4 lists:
> But I haven't found a way to split resultant lists in order to get 4
> matrices for each list.

Hi.

Try the following.

  k <- 3
  n <- 2^k
  m <- 2^(k - 2)
  a <- matrix(1:n^2, nrow=n, ncol=n)
  g <- vector("list", length=16)
 
  k <- 1
  for (j in 0:3) {
      for (i in 0:3) {
          g[[k]] <- a[m*i + 1:m, m*j + 1:m]
          k <- k + 1
      }
  }
 
  g[1:5]
 
  [[1]]
       [,1] [,2]
  [1,]    1    9
  [2,]    2   10
 
  [[2]]
       [,1] [,2]
  [1,]    3   11
  [2,]    4   12
 
  [[3]]
       [,1] [,2]
  [1,]    5   13
  [2,]    6   14
 
  [[4]]
       [,1] [,2]
  [1,]    7   15
  [2,]    8   16
 
  [[5]]
       [,1] [,2]
  [1,]   17   25
  [2,]   18   26

  ...

Hope this helps.

Petr Savicky.

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
Reply | Threaded
Open this post in threaded view
|

Re: Split matrix into square submatices

Gabor Grothendieck
In reply to this post by xiddw
On Fri, Feb 10, 2012 at 3:02 AM, xiddw <[hidden email]> wrote:

> Hi everybody,
>
> I'm looking for an optimal way to split  a big matrix  (e.g. ncol = 8,
> nrow=8)  into small square submatrices  (e.g. ncol=2, nrow=2)
>
> For example
>
> If I have
>
>>  h
>     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
> [1,]    1    9   17   25   33   41   49   57
> [2,]    2   10   18   26   34   42   50   58
> [3,]    3   11   19   27   35   43   51   59
> [4,]    4   12   20   28   36   44   52   60
> [5,]    5   13   21   29   37   45   53   61
> [6,]    6   14   22   30   38   46   54   62
> [7,]    7   15   23   31   39   47   55   63
> [8,]    8   16   24   32   40   48   56   64
>
> and I want to split matriz h into 16 small submatrices:
>
>> g[1]
>     [,1] [,2]
> [1,]    1    9
> [2,]    2   10
>
>> g[2]
>     [,1] [,2]
> [1,]   17   25
> [2,]   18   26
>
> ...
>
>> g[4]
>     [,1] [,2]
> [1,]   49   57
> [2,]   50   58
>
> ...
>
>> g[16]
>     [,1] [,2]
> [1,]   55   63
> [2,]   56   64
>
> Always the big matrix would be a square matrix and also would have a nrow
> and ncol in order of  a power of two, so it always could  be splitted in at
> least halves.
>
> Until now, I'm able to split a matrix but keeping the number of original
> matrix columns.
>
> I mean, if I want to split into 16 submatrices, using the following command
> what I get its 4 lists:
> But I haven't found a way to split resultant lists in order to get 4
> matrices for each list.
>
>> g <- split(as.data.frame(h), (1:4))
>> g
> $`1`
>  V1 V2 V3 V4 V5 V6 V7 V8
> 1  1  9 17 25 33 41 49 57
> 5  5 13 21 29 37 45 53 61
>
> $`2`
>  V1 V2 V3 V4 V5 V6 V7 V8
> 2  2 10 18 26 34 42 50 58
> 6  6 14 22 30 38 46 54 62
>
> $`3`
>  V1 V2 V3 V4 V5 V6 V7 V8
> 3  3 11 19 27 35 43 51 59
> 7  7 15 23 31 39 47 55 63
>
> $`4`
>  V1 V2 V3 V4 V5 V6 V7 V8
> 4  4 12 20 28 36 44 52 60
> 8  8 16 24 32 40 48 56 64
>
>

Try this:

h <- matrix(1:64, 8) # input

k <- kronecker(matrix(1:16, 4, byrow = TRUE), matrix(1, 2, 2))
g <- lapply(split(h, k), matrix, nr = 2)

--
Statistics & Software Consulting
GKX Group, GKX Associates Inc.
tel: 1-877-GKX-GROUP
email: ggrothendieck at gmail.com

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
Reply | Threaded
Open this post in threaded view
|

Re: Split matrix into square submatices

xiddw
Thanks to Peter and Gabriel for their comments,

The first way which Peter commented was my first approach, however as I use it for a 'large' matrix (in my case nrow = ncol = 512) and I want to split it into very small matrices (e.g. nrow = ncol = {4, 8, 16}) both nested loops I think are a quite expensive and that's why I was looking for a better way.

The Gabor's approach works perfect for my needs, thanks :)