如何用100 * 5矩阵的特定范围的随机数填充矩阵的列?

时间:2017-08-09 09:50:35

标签: matlab matrix

我有一个订单100*5的矩阵。现在的目标是用特定范围内的随机整数填充矩阵的每列。现在问题是每列的随机数范围都会发生变化。例如,对于第一列,范围是1到100,第二列是-10到1,依此类推到第5列。

这是我尝试过的:

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)

来自this问题。但是这会产生错误,

  

使用*内部矩阵尺寸时出错必须同意。

可能导致此问题以及如何解决问题?

4 个答案:

答案 0 :(得分:4)

bsxfun这个东西!

A = round(bsxfun(@minus,bsxfun(@times,rand(100,5) ,range'), offset'))

答案 1 :(得分:3)

作为替代解决方案,您可以使用repmat来完成已有的内容:

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));

您不必定义rngofst,这可以简单地写成:

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

出于好奇,我写了这个快速基准*来与Ander的bsxfun方法进行比较。似乎bsxfun有一些初始开销,这意味着5列(自己测试其他情况)和少于几千行,repmat更快。在此之上,repmat创建额外的大型数组可能会导致速度变慢,我们会看到bsxfun更快。

small vals large vals

对于未来的读者,如果这不适用于您: broadcasting introduced from R2016b您可能会发现您可以完全使用bsxfunrepmat躲闪。

*基准测试代码。在Windows 64位R2015b上测试,您的里程可能会有所不同等。

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

答案 2 :(得分:2)

您可以使用randi执行此操作,将b行传递到其第一个参数:

b = [0,100;-10,1;0,1;-1,1;10,20];
A = zeros(100,5);
f=@(ii)randi(b(ii,:),100,1);
for ii = 1:size(A,2)
  A(:,ii) = f(ii);
end

我怀疑有一种方法可以在没有循环遍历行/列的情况下执行此操作,可能使用bsxfun

答案 3 :(得分:2)

您可以使用arrayfun,即使我没有看到使用循环和编写更易读的代码有任何损害,如史蒂夫的回答。

A = cell2mat(arrayfun(@(imin, imax) randi([imin, imax], 100, 1), b(:,1), b(:,2), 'uni', 0)')