40

In Haskell, if I wanted to get a 10 element list which only contained the number 5, I could do something like this:

take 10 $ repeat 5

Output:

[5,5,5,5,5,5,5,5,5,5]

Is there anything like this in Matlab?

nbro
  • 15,395
  • 32
  • 113
  • 196
Tyler
  • 4,679
  • 12
  • 41
  • 60

5 Answers5

65

It is easy to assign repeated values to an array:

x(1:10) = 5;

If you want to generate the array of elements inline in a statement try something like this:

ones(1,10) * 5

or with repmat

repmat(5, 1, 10)
nbro
  • 15,395
  • 32
  • 113
  • 196
dkantowitz
  • 1,931
  • 1
  • 16
  • 22
  • 1
    `x(1:10)` also works for a character, and `repmat(..)` also works for a string. For example: `repmat('ab', 1, 10)` gives `abababababababababab`. – Evgeni Sergeev May 01 '13 at 07:06
22

The ones method is much faster than using repmat:

>> tic; for i = 1:1e6, x=5*ones(10,1); end; toc
Elapsed time is 3.426347 seconds.
>> tic; for i = 1:1e6, y=repmat(5,10,1); end; toc
Elapsed time is 20.603680 seconds. 

And, in my opinion, makes for much more readable code.

MatlabSorter
  • 1,290
  • 1
  • 11
  • 19
6

Given a predefined m-by-n matrix size and the target value val, in your example:

m = 1;
n = 10;
val = 5;

there are currently 7 different approaches that come to my mind:


1) Using the repmat function (0.094066 seconds)

A = repmat(val,m,n)

2) Indexing on the undefined matrix with assignment (0.091561 seconds)

A(1:m,1:n) = val

3) Indexing on the target value using the ones function (0.151357 seconds)

A = val(ones(m,n))

4) Default initialization with full assignment (0.104292 seconds)

A = zeros(m,n);
A(:) = val

5) Using the ones function with multiplication (0.069601 seconds)

A = ones(m,n) * val

6) Using the zeros function with addition (0.057883 seconds)

A = zeros(m,n) + val

7) Using the repelem function (0.168396 seconds)

A = repelem(val,m,n)

After the description of each approach, between parentheses, its corresponding benchmark performed under Matlab 2017a and with 100000 iterations. The winner is the 6th approach, and this doesn't surprise me.

The explaination is simple: allocation generally produces zero-filled slots of memory... hence no other operations are performed except the addition of val to every member of the matrix, and on the top of that, input arguments sanitization is very short.

The same cannot be said for the 5th approach, which is the second fastest one because, despite the input arguments sanitization process being basically the same, on memory side three operations are being performed instead of two:

  • the initial allocation
  • the transformation of every element into 1
  • the multiplication by val
Tommaso Belluzzo
  • 23,232
  • 8
  • 74
  • 98
5

See repmat in the documentation.

B = repmat(5,1,10)
zellus
  • 9,617
  • 5
  • 39
  • 56
0

As mentioned in other answers you can use:

>> tic; x=5*ones(10,1); toc
Elapsed time is 0.000415 seconds.

An even faster method is:

>> tic;  x=5; x=x(ones(10,1)); toc
Elapsed time is 0.000257 seconds.
bluefocs
  • 63
  • 1
  • 9
  • 1
    By using `timeit` (which is more robust than `tic`/`toc`) and an example with much more than 10 elements, **this can be shown to be false**. The first method is quicker, a test as quick as yours is unlikely to be accurate - for instance simply re-running your example a few times gives different conclusions. Try: `m1 = @() 5*ones(1e7,1); x = 5; m2 = @() x(ones(1e7,1));` To set up anonymous functions which run your tests, then time using `timeit(m1)` and `timeit(m2)`. I get that `m2` is ~3x *slower*. Yes, this is a valid method to create a single-valued array, but it is not a faster method. – Wolfie Dec 04 '17 at 17:43