the_dude
the_dude

Reputation: 37

How do I create random matrix where each column is all zeroes except for one random row?

I want to create a matrix of size m-by-n where all elements in a column are 0 except one element which is 1. That one element must be at a random position.

eg.

[0 1 0 0 0
 0 0 1 0 0
 1 0 0 1 0
 0 0 0 0 0 
 0 0 0 0 1]

Upvotes: 3

Views: 166

Answers (5)

Shai
Shai

Reputation: 114786

You can also use rand and max to do the job:

m=4;
n=5;
R=rand(m,n);
result = bsxfun(@eq, R, max(R,[],1))

On my machine it gave:

 1     1     0     0     0
 0     0     0     0     0
 0     0     1     0     1
 0     0     0     1     0

How it works: Generating a random matrix, R, and then setting to 1 the entry corresponding to the maximal element at each column. No need for sorting.


Regarding the original answer of Divakar, since it uses randperm it is restricted to square matrix only, and it will only produce random permutation matrices.
One possible way to correct his solution is to use randi instead of randperm:

result = bsxfun( @eq, (1:m)', randi(m, 1, n ) )

May give this output:

 1     0     1     0     0
 0     0     0     0     0
 0     0     0     0     0
 0     1     0     1     1

As for the answer of bla, using accumarry can save the use of zeros and sub2ind:

m=5; n=10;
R=randi(m,n,1);
A = accumarray( {R, (1:n)' }, 1, [m n] )

May give this output:

 0     0     0     0     1     0     0     1     0     0
 0     1     0     0     0     0     1     0     1     0
 1     0     0     1     0     0     0     0     0     1
 0     0     0     0     0     1     0     0     0     0
 0     0     1     0     0     0     0     0     0     0

Upvotes: 4

Divakar
Divakar

Reputation: 221524

You can use sparse with randi for a one-liner, like so -

full(sparse(randi(m,1,n),1:n,1,m,n))

Sample run -

>> m = 5; n = 6;
>> full(sparse(randi(m,1,n),1:n,1,m,n))
ans =
     0     1     0     0     0     1
     0     0     1     1     0     0
     0     0     0     0     0     0
     1     0     0     0     1     0
     0     0     0     0     0     0

Upvotes: 3

rayryeng
rayryeng

Reputation: 104474

Another idea I have is to create the identity matrix of size m x m, then use randi with a range from 1 up to m to create a vector of n elements long. After, you'd use this vector to access the columns of the identity matrix to complete the random matrix you desire:

m = 5; n = 5; %// Given your example
M = eye(m);
out = M(:,randi(m, n, 1));

Here's one possible run of the above code:

out =

     1     0     0     0     0
     0     0     0     0     0
     0     0     0     1     0
     0     0     0     0     0
     0     1     1     0     1

Upvotes: 3

Luis Mendo
Luis Mendo

Reputation: 112659

To add some variety, here's another approach:

m = 4;
n = 5;
[~, result] = sort(rand(m,n));
result = double(result==1);

This gives, for example,

result =
     0     0     0     0     1
     0     1     0     0     0
     1     0     0     1     0
     0     0     1     0     0

Upvotes: 4

bla
bla

Reputation: 26069

here's an example using randi:

m=5; n=10;
A=zeros(m,n);
R=randi(m,n,1);
A(sub2ind(size(A),R',1:n))=1


A =

 0     0     0     0     0     0     0     1     0     1
 0     0     1     0     0     0     0     0     0     0
 0     1     0     1     0     1     0     0     0     0
 0     0     0     0     1     0     0     0     0     0
 1     0     0     0     0     0     1     0     1     0

Upvotes: 3

Related Questions