Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fill columns of a matrix with random numbers of specific range of a 100*5 matrix?

Tags:

matrix

matlab

I've a matrix of order 100*5 . Now the objective is to fill each columns of the matrix with random integer within a specific range. Now the problem is for every column the range of the random number changes. For instance, for the first column, the range is 1 to 100 , for the second its -10 to 1 and so on till 5th column.

This is what I've tried:

b = [0,100;-10,1;0,1;-1,1;10,20]
range = b(:,2) - b(:,1) 
offset = b(:,1)
A = round(rand(100,5) * range - offset)

which is from this question. However this generates an error,

Error using * Inner matrix dimensions must agree.

What's possibly causing this and how to resolve it ?

like image 477
OBX Avatar asked Jan 20 '26 18:01

OBX


2 Answers

lets bsxfun this thing!

A = round(bsxfun(@minus,bsxfun(@times,rand(100,5) ,range'), offset'))
like image 186
Ander Biguri Avatar answered Jan 22 '26 07:01

Ander Biguri


As an alternative solution, you could use repmat to complete what you already had:

b = [0, 100; -10, 1; 0, 1; -1, 1; 10, 20].'; 
rng = b(2, :) - b(1, :); 
ofst = b(1, :);
A = round(rand(100,5) .* repmat(rng, 100, 1) + repmat(ofst, 100, 1));

You don't have to define rng or ofst, and this can be simply written as:

A = round(rand(10,5) .* repmat(diff(b), 10, 1) + repmat(b(1,:), 10, 1));

Out of curiousity I wrote this quick benchmark* to compare to Ander's bsxfun method. It appears that bsxfun has some initial overhead which means for 5 columns (test other cases yourself) and less than a few thousand rows, repmat is quicker. Above this, the creation of additional large arrays by repmat probably causes a slow down, and we see bsxfun is much quicker.

small vals large vals

For future readers if this doesn't apply to you: with broadcasting introduced from R2016b you may find you can dodge using bsxfun and repmat entirely.

*benchmarking code. Tested on Windows 64-bit R2015b, your mileage may vary etc.

function benchie()
    b = [0, 100; -10, 1; 0, 1; -1, 1; 10, 20].';
    Tb = [];
    Tr = [];
    K = 20;
    for k = 1:K
        n = 2^k;
        fb = @()bsxfunMethod(b,n);
        fr = @()repmatMethod(b,n);
        Tb(end+1) = timeit(fb);
        Tr(end+1) = timeit(fr);
    end
    figure; plot(2.^(1:K), Tb, 2.^(1:K), Tr); legend('bsxfun', 'repmat');
end
function bsxfunMethod(b, n)
    round(bsxfun(@minus,bsxfun(@times, rand(n,5), diff(b)), b(1,:)));
end
function repmatMethod(b, n)
    round(rand(n,5) .* repmat(diff(b), n, 1) + repmat(b(1,:), n, 1));
end
like image 20
Wolfie Avatar answered Jan 22 '26 07:01

Wolfie



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!