0
votes

I have two matrices aand b of 1 column and n rows.

These matrices represent min and max values.

From these I need to create a n by m matrix. m is the max value of [a ; b]

The result must contain each value between a(:) and b(:), padded with zeros.

note: it's easy to do with a for loop, but I want to avoid loops.

Exemple :

Starting with these two matrices :

>> a = [3 ; 5 ; 2 ; 7 ; 4]

a =

     3
     5
     2
     7
     4

>> b = [7 ; 7 ; 5 ; 8 ; 4]

b =

     5
     7
     4
     8
     4

I want to end with this matrix :

result =

     3     4     5     6     7     0     0     0
     5     6     7     0     0     0     0     0
     2     3     4     5     0     0     0     0
     7     8     0     0     0     0     0     0
     4     0     0     0     0     0     0     0

So far I have this :

>> result = zeros(size(a,1), max([a ; b]));
>> rows = [1:size(a,1)]

rows =

     1     2     3     4     5

>> index = sub2ind(size(result), rows, b - a + 1)
>> result(index) = b

result =

     0     0     0     0     7     0     0     0
     0     0     7     0     0     0     0     0
     0     0     0     5     0     0     0     0
     0     8     0     0     0     0     0     0
     4     0     0     0     0     0     0     0

>> result(:,1) = a

result =

     3     0     0     0     7     0     0     0
     5     0     7     0     0     0     0     0
     2     0     0     5     0     0     0     0
     7     8     0     0     0     0     0     0
     4     0     0     0     0     0     0     0
2

2 Answers

3
votes

I'd solve this with a simple loop, which is also probably the fastest solution

a = [3 ; 5 ; 2 ; 7 ; 4]
b = [7 ; 7 ; 5 ; 8 ; 4]
nSteps = b-a+1;
nRows = size(a,1);

result = zeros(nRows, max([a ; b]));

for iRow = 1:nRows
   result(iRow,1:nSteps(iRow)) = a(iRow):b(iRow);
end

result =

 3     4     5     6     7     0     0     0
 5     6     7     0     0     0     0     0
 2     3     4     5     0     0     0     0
 7     8     0     0     0     0     0     0
 4     0     0     0     0     0     0     0

In case you don't need readability, here's a non-loop solution:

result = ones(nRows, max([a ; b]));
result(:,1) = a;
result = cumsum(result,2);
result(bsxfun(@gt,result,b))=0

result =

     3     4     5     6     7     0     0     0
     5     6     7     0     0     0     0     0
     2     3     4     5     0     0     0     0
     7     8     0     0     0     0     0     0
     4     0     0     0     0     0     0     0
0
votes

Some problems aren't worth the effort of vectorising:

a = [3 ; 5 ; 2 ; 7 ; 4];
b = [7 ; 7 ; 5 ; 8 ; 4];

cols = max(max(a),max(b))
result = zeros(length(a),cols)

for i = 1:length(a)
    A = a(i):b(i)
    result(i,:) = padarray(A, [0 cols-length(A)], 0, 'post');
end