Create a matrix from 2 vectors

11 Ansichten (letzte 30 Tage)
Jose Luis
Jose Luis am 8 Jan. 2017
Kommentiert: Star Strider am 11 Jan. 2017
I have a vector A =[ 1;3;1;4] and a vector B = [ 8,9,9,6]. The values of A must increase one by one till reaching the value speficied in B, then, how can I obtain the following matrix:
[1 2 3 4 5 6 7 8 0; 3 4 5 6 7 8 9 0 0; 1 2 3 4 5 6 7 8 9; 4 5 6 0 0 0 0 0 0]
without using a for loop?
Thank your very much for your help

Akzeptierte Antwort

Star Strider
Star Strider am 8 Jan. 2017
This creates your matrix with an expressed loop, however there are obviously loops within the functions.
The Code
A = [ 1;3;1;4];
B = [ 8,9,9,6];
C = ones(size(A,1), max(B));
C = cumsum(C,2);
C = bsxfun(@plus, C, A-1);
I = bsxfun(@le, C, B(:));
C = C.*I % Desired Result
C =
1 2 3 4 5 6 7 8 0
3 4 5 6 7 8 9 0 0
1 2 3 4 5 6 7 8 9
4 5 6 0 0 0 0 0 0
The ‘C’ matrix is (obviously) the output.
  6 Kommentare
Jose Luis
Jose Luis am 11 Jan. 2017
Bearbeitet: Star Strider am 11 Jan. 2017
Thank you very much for your help. I was a little afraid of two bsxfun functions taking too much time, but after comparing with the alternatives proposed by Guillaume it seems to be the best (faster) way of doing this task . Indeed, the correction proposed by Guillaume does improve the code as it doesn't append zeros at the end of the matrix, so that the final code is:
C = cumsum(ones(size(A, 1), max(B(:) - A(:) + 1)), 2);
C = bsxfun(@plus, C, A-1);
I = bsxfun(@le, C, B(:));
C = C.*I
Star Strider
Star Strider am 11 Jan. 2017
As always, my pleasure!

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (1)

Guillaume
Guillaume am 8 Jan. 2017
There is nothing wrong with using loops when they make the code clearer. This is, arguably, the most efficient loop version:
C = zeros(numel(A), max(B(:) - A(:)) + 1);
for row = 1:numel(A)
C(row, 1:B(row)-A(row)+1) = A(row):B(row);
end
Another option, not using explicit loops, shorter but probably far less efficient than Star's answer:
ncols = max(B(:) - A(:)) + 1;
C = cell2mat(arrayfun(@(s, e) [s:e, zeros(1, ncols-e+s-1)], A, B(:), 'UniformOutput', false))
  1 Kommentar
Star Strider
Star Strider am 11 Jan. 2017
Guillaume, thank you for the corrections to my code.
+1

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu Performance and Memory finden Sie in Help Center und File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by