Cherry
Cherry

Reputation: 1041

Generate random 2D matrix with unique rows in octave/matlab

I want to generate a 2D matrix(1000x3) with random values in the range of 1 to 10 in octave. Using randi(10,1000,3) will generate a matrix with repeated row values. But I want to generate unique(unrepeated) rows. Is there any way that, I can do that?

Upvotes: 2

Views: 3119

Answers (2)

mattsilver
mattsilver

Reputation: 4396

You can generate all possible three-item sequences drawn from 1 through 10, with replacement, using the following function:

function result = nchoosek_replacement(n, k)

    %// Edge cases: just return an empty matrix 
    if k < 1 || n < 1 || k >= n
        result = [];
        return
    end

    reps = n^(k-1);
    result = zeros(n^k, k);
    cur_col = repmat(1:n, reps, 1);
    result(:,1) = cur_col(:);

    %// Base case: when k is 1, just return the
    %// fully populated matrix 'result'
    if k == 1
        return
    end

    %// Recursively generate a matrix that will
    %// be used to populate columns 2:end
    next = nchoosek_replacement(n, k-1);

    %// Repeatedly use the matrix above to
    %// populate the matrix 'result'
    for i = 1:n
        cur_range = (i-1)*reps+1:i*reps;
        result(cur_range, 2:end) = next;
    end

end 

With this function defined, you can now generate all possible sequences. In this case there are exactly 1000 so they could simply be shuffled with randperm. A more general approach is to sample from them with randsample, which would also allow for smaller matrices if desired:

max_value = 10;
row_size = 3;    
num_rows = 1000;

possible = nchoosek_replacement(max_value, row_size);
indices = randsample(size(possible, 1), num_rows);
data = possible(indices, :);

Upvotes: 2

krisdestruction
krisdestruction

Reputation: 1960

You can do that easily by getting the cartesian product to create all possibilities and shuffle the array as follows. To create the cartesian product, you will need my custom cartprod.m function that generates a cartesian product.

C = cartprod(1:10,1:10,1:10);

The following line then shuffles the cartesian product C.

S = C(randperm( size(C,1) ),:);

Notes:

  • Every row in S is unique and you can verify that size( unique( S ) ) == 1000.
  • I should note that this code works on Matlab 2015a. I haven't tested it in Octave, which is what OP seems to be using. I've been told the syntax is pretty much identical though.

Upvotes: 2

Related Questions