-2

In matlab, how to generate a vector like this:

[1,1,1,...,1,1, 2,2,2,...,2,2, 3,3,3,...,3,3, 4,4,4,...,4,4]
f. c.
  • 1,095
  • 11
  • 26

3 Answers3

5

Given the simple structure of your vector, a very simple solution is available:

ceil((1:24)/6)

Very fast for small vectors, and competitive for large ones. When the vector gets really large the reshape alternative has better speed.

Of course it can easily be generalized:

N = 4;
M = 6;
ceil((1:M*N)/M)
Dennis Jaheruddin
  • 21,208
  • 8
  • 66
  • 122
  • 1
    Fastest on both of mine as well – Dan Oct 23 '13 at 14:08
  • I don't think *speed* is a concern for such a tiny vector. – Marc Claesen Oct 23 '13 at 14:47
  • 1
    @MarcClaesen Actually, the number of repetitions is unspecified in the OP, so it might not be tiny – Luis Mendo Oct 23 '13 at 15:43
  • @LuisMendo this solution is, by definition, of length 24. – Marc Claesen Oct 24 '13 at 06:10
  • @MarcClaesen This solution is trivial to generalize to any length. Although it does slow down faster than the others. – Dan Oct 24 '13 at 06:13
  • 1
    @Dan that was my point. Doing timings on such a small vector has no meaning at all. All you're seeing there is that the overhead on this approach is marginally lower than for other approaches. This becomes entirely irrelevant once you move on to *large* vectors. Such timings are useless. – Marc Claesen Oct 24 '13 at 06:20
  • 1
    @MarcClaesen I agree that timings on small samples are not that relevant, however I suggested this method mostly for ease of use. Hence I hope that the lack of superior speed is not a reason to vote this solution down. – Dennis Jaheruddin Oct 24 '13 at 08:12
  • @DennisJaheruddin Actually, I upvoted your answer. I think it's a clever and elegant solution. I merely reacted to the "fast solution" responses. Don't misinterpret my responses as criticism to your solution. This is my favorite answer. – Marc Claesen Oct 24 '13 at 10:20
4

You can use:

N = 4;
M = 6;
result = reshape(repmat(1:N,M,1),1,[])

This works by generating [1,2,3,...,N], then copying into M rows (repmat), and then reading by columns (reshape).

A usually faster alternative is to replace repmat by matrix product and reshape by linear indexing (thanks to @Dan and @Floris):

result = ones(M,1)*(1:N);
result = result(:).'

Also see @Dan's answer, which may be faster depending on the version/machine, or @Dennis's, which is probably the fastest.

Luis Mendo
  • 110,752
  • 13
  • 76
  • 147
  • 1
    reshape is slower than `myMatrix(:)'`. So do it in two lines and be even faster... – Floris Oct 23 '13 at 15:24
  • 1
    Though it has more overhead, the reshape solution outperforms for large vectors. At `M = 60000` and `N = 40000` the `kron` solution rouns out of memory, the other solutions take 2 minutes and the `reshape` solution is done in 7 seconds. – Dennis Jaheruddin Oct 24 '13 at 08:16
4
kron(1:4, ones(1,6))

I think using a kronecker product might be quicker, but it also might not. See A similar function to R's rep in Matlab

Community
  • 1
  • 1
Dan
  • 45,079
  • 17
  • 88
  • 157
  • Nice solution. But as for speed, it seems to take twice as much on my machine... (R2010b, Win Vista) – Luis Mendo Oct 23 '13 at 13:55
  • 1
    @LuisMendo Interesting, for me `kron` was 10 times faster in Octave, but half the speed in Matlab. Using `(:)'` instead of `reshape` is even faster in Matlab. – Dan Oct 23 '13 at 13:58