1

I want to draw a Hankel matrix with R use only matrix(), seq() and rep() function of R. Until now, I draw this in some way:

#Do this exercise with other packages, need to rework
install.packages("matrixcalc")
library(matrixcalc)
E1 <- hankel.matrix( 5, seq( 1, 9 ) )
print(E1)
#Use matrix() only, not efficient
E2 <- matrix(c(1,2,3,4,5,2,3,4,5,6,3,4,5,6,7,4,5,6,7,8,5,6,7,8,9), ncol=5)
print(E2)
#Use seq() but not worked
E3 <- matrix(c(seq(1:5),seq(2:6),seq(3:7),seq(4:8),seq(5:9)), ncol=5)
print(E3)

E1 used a library to draw a Hankel matrix and in E2, I tried to put the number manually to draw one but it will take a lot of time if I want a new big matrix. I tried to use seq() but it not worked. It will draw like this:

      [,1] [,2] [,3] [,4] [,5]
[1,]    1    1    1    1    1
[2,]    2    2    2    2    2
[3,]    3    3    3    3    3
[4,]    4    4    4    4    4
[5,]    5    5    5    5    5

I am still very new with R so every idea is welcome.

Raphaël VO
  • 2,413
  • 4
  • 19
  • 32
  • BTW: The seq calls were incorrect, shouldn't use ":" inside seq. Or just use ":"... `E3 <- matrix( c(1:5,2:6,3:7,4:8,5:9), ncol=5) print(E3)` – IRTFM Oct 11 '14 at 00:52
  • Can you explain why shouldn't use `:` inside `seq()`? – Raphaël VO Oct 11 '14 at 11:29
  • Because positional matching of arguments (no names to the argument) would give a multi-element vector to the first argument and no value to the second argument. The ":"-function is really an infix version of the `seq` function – IRTFM Oct 11 '14 at 17:02

2 Answers2

5

You can do this :

matrix(rep(1:5,5)+rep(0:4,each=5),ncol=5)
#       [,1] [,2] [,3] [,4] [,5]
# [1,]    1    2    3    4    5
# [2,]    2    3    4    5    6
# [3,]    3    4    5    6    7
# [4,]    4    5    6    7    8
# [5,]    5    6    7    8    9

Or more elegant but using outer:

outer(0:4,1:5,'+')

EDIT :

the rep solution works like this:

    12345 12345 12345 ...  (rep times,      repeat the vector n times
  + 00000 11111 22222 ...  (rep with each , repeat each element n times
  = 12345 23456 34567 .....

outer can be tricky at first, maybe this answer here can help you to understand it and to general debug.

Community
  • 1
  • 1
agstudy
  • 119,832
  • 17
  • 199
  • 261
  • I will very appreciate if you can explain the parameter in your code and about `rep()`. I read it definition but in actually I just can't understand it. I am still very very new to R :( – Raphaël VO Oct 10 '14 at 19:30
  • The same problem for `outer()`, I can't understand how it works. I asked my professor about how to debug in R but he just guided me use `Ctrl+Enter` to check in every step, is there any solution to debug in R use R Studio – Raphaël VO Oct 10 '14 at 19:33
  • @Tuong - in the RStudio `Debug` dropdown menu, look at the different choices for `On Error` – Rich Scriven Oct 10 '14 at 19:38
  • @Tuong I add some explanation of the solution and also how you can debug the outer. – agstudy Oct 10 '14 at 19:59
  • @agstudy I think I understood how to use two `rep()` together, but for `1:n` will this way be still appliable?I'll read about the `outer` later.@RichardScriven I just want to go inside a loop, or some native function to read how the variable change after each step, just like C or C++, can we do it in R? – Raphaël VO Oct 10 '14 at 22:25
2

I'm reversing the order of the two different solutions so that the qualifying one is at the top:

A general function (meaning on that doesn't depend on the values being sequential) that only uses a couple of extra functions (like c() and "[") to do the work:

N <- c(9L, 7L, 3L, 2L, 1L, 8L, 4L, 5L, 6L, 10L)
hankel2 <- function(N, n){stopifnot(length(N)==2*n); 
                          matrix( rep(N,n)[c(rep(TRUE,n),rep(FALSE,n+1))], n) }
hankel2(N,5)
     [,1] [,2] [,3] [,4] [,5]
[1,]    9    7    3    2    1
[2,]    7    3    2    1    8
[3,]    3    2    1    8    4
[4,]    2    1    8    4    5
[5,]    1    8    4    5    6

The trick with that first (of three) efforts was to depend on argument recycling of logical vectors when used inside the "[" function. It creates a gap of n+1 items after choosing n items by indexing with FALSE ( which has the effect of omitting items.)


Embed is a cute little function that has a fairly opaque help file but occasionally delivers very compact code:

> x <- 1:10
> embed (x, 5)[1:5, 5:1]
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    2    3    4    5
[2,]    2    3    4    5    6
[3,]    3    4    5    6    7
[4,]    4    5    6    7    8
[5,]    5    6    7    8    9

You could make a function:

> hankel <- function( n ) embed(1:(2*n),5)[1:n, n:1]
> hankel(5)
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    2    3    4    5
[2,]    2    3    4    5    6
[3,]    3    4    5    6    7
[4,]    4    5    6    7    8
[5,]    5    6    7    8    9

(Admittedly not playing by the specifications although I wondered if any of the solutions so far would stand up to a vector that wasn't sequential. This one does:)

> hankel5 <- function( n ) embed(sample(1:10,10),5)[1:n, n:1]
> hankel5(5)
     [,1] [,2] [,3] [,4] [,5]
[1,]    3    5    7    9    4
[2,]    5    7    9    4   10
[3,]    7    9    4   10    1
[4,]    9    4   10    1    8
[5,]    4   10    1    8    2

So this is the other general function:

hankel <- function( N, n ) {stopifnot(length(N) == 2*n); embed(N,n)[1:n, n:1]
IRTFM
  • 258,963
  • 21
  • 364
  • 487