Matrix creation Octave / Matlab, loopless solution request

冷暖自知 提交于 2019-12-07 22:50:01

问题


I want to create a matrix like

A = [0 0 0 0 1;
     0 0 0 1 1;
     0 0 0 1 1;
     0 0 0 1 1;
     0 0 1 1 1;
     0 1 1 1 1]

based on a vector indicating how many '0's should precede '1's on each row:

B = [4 3 3 3 2 1]

Is there a loopless way to do this ?


回答1:


You don't mention in your question how the horizontal size of the array should be defined (the number of ones).

For predefined width you can use this code:

width = 5;

A = cell2mat(arrayfun(@(x) [ zeros(1,x), ones(1,width-x) ], B, 'UniformOutput', false)');

If you want that A has minimal width, but still at least one 1 in every row:

A = cell2mat(arrayfun(@(x) [ zeros(1,x), ones(1,max(B)+1-x) ], B, 'UniformOutput', false)');



回答2:


A shorter “old-school” way to achieve this without a loop would be as follows:

A = repmat(B',1,max(B)+1)<repmat([1:max(B)+1],size(B,2),1)

If you want to have a minimum number of ones

min_ones=1; %or whatever
A = repmat(B',1,max(B)+min_ones)<repmat([1:max(B)+min_ones],size(B,2),1)

I don’t know how this compares speedwise to @nrz’s approach (I’ve only got Octave to hand right now), but to me it's more intuitive as it’s simply comparing a max(B) + min_ones * column tiling of B:

4  4  4  4  4
3  3  3  3  3
3  3  3  3  3
3  3  3  3  3
2  2  2  2  2
1  1  1  1  1

with a row tiling of [1 : max(B) + min_ones]

1  2  3  4  5
1  2  3  4  5
1  2  3  4  5
1  2  3  4  5
1  2  3  4  5
1  2  3  4  5

To generate:

A =

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



回答3:


This requires only one line, and seems to be faster than previous solutions based on repmat or arrayfun:

%// Example data
ncols = 5;
B = [4 3 3 3 2 1];

%// Generate A
A = bsxfun(@gt, 1:ncols, B(:));


来源:https://stackoverflow.com/questions/10258448/matrix-creation-octave-matlab-loopless-solution-request

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!