Put elements into corresponding locations of upper triangular matrix

Hi all,
Imagine I have a vector:
inpt = (1:6)';
Now I'd like to put elements of inpt in the upper triangular part of a 3 by 3 matrix otpt, so I have:
otpt =
1 2 4
0 3 5
0 0 6
What's the best way to do it? Thanks!

1 Kommentar

Is this a homework question? If so, please mention it, because then a different type of answers is required.

Melden Sie sich an, um zu kommentieren.

 Akzeptierte Antwort

Jan
Jan am 26 Jul. 2017
Bearbeitet: Jan am 26 Jul. 2017
Start with nested loops:
v = 1:6;
n = round((sqrt(8 * numel(v) + 1) - 1) / 2);
M = zeros(n, n);
c = 0;
for i2 = 1:n
for i1 = 1:i2
c = c + 1;
M(i1, i2) = v(c);
end
end
In the next step you can vectorize the inner loop: Move the loop index inside the assignment:
n = round((sqrt(8 * numel(v) + 1) - 1) / 2);
M = zeros(n, n);
a = 1;
for k = 1:n
b = a + k - 1;
M(1:k, k) = v(a:b);
a = b + 1;
end
Is this nicer? Questionable, but maybe faster.
Now use a built-in function:
n = round((sqrt(8 * numel(v) + 1) - 1) / 2);
M(triu(ones(n)) == 1) = v;
or better:
M(triu(true(n))) = v;
[EDITED] Some timings - what did you expect?
v = 1:5050;
tic; for k = 1:10000; y = SerialTriU(v); end, toc
Elapsed time is 0.772492 seconds. % Two loops
Elapsed time is 2.448738 seconds. % Inner loop vectorized
Elapsed time is 1.029641 seconds. % TRIU(ONES)
Elapsed time is 0.659360 seconds. % TRIU(TRUE)

5 Kommentare

Jan you are a legend!
Jan
Jan am 27 Jul. 2017
Bearbeitet: Jan am 27 Jul. 2017
Thanks. I admit, that the timings have less power, if you consider that they are taken for 10'000 loops. If the total time is 0.00024 or 0.000065 seconds is not such important usually. As long as this code is not repeated millions of time and the bottleneck of the code, optimizing it might be very accademically or even a waste of (life) time.
But in the forum I try to share the methods, how efficient code can be developped. Perhaps these methods are useful for other problems also.
Hi Jan,
Very good answer. I just had a question. How about if we want to do the following:
v = 1:6;
we want:
M =
1 2 3
0 4 5
0 0 6
Any help would be appreciated.
This should do the trick:
A=1:6
B=tril(ones(3))
B(B==1)=A
B'
A=1:6
B=triu(ones(3))
B(B==1)=A
saves you a line.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (1)

Let vector ‘inpt’ have size = n*(n+1)/2,1.
otpt = zeros(n);
otpt(triu(ones(n),0)==1) = inpt;

3 Kommentare

Thanks for this!
Brilliant! it's actually the sum formula for arithmetic sequence! very helpful for understanding.
Absolutely brilliant, concise and crisp!

Melden Sie sich an, um zu kommentieren.

Gefragt:

am 26 Jul. 2017

Kommentiert:

am 3 Okt. 2021

Community Treasure Hunt

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

Start Hunting!

Translated by