flip half of matrix over the diagonal to make a symmetric matrix

112 vues (au cours des 30 derniers jours)
Shan  Chu
Shan Chu le 4 Mai 2016
Commenté : Steven Lord le 9 Avr 2024
Dear all, If I have a half of a matrix, e.g
1
2 3
4 5 6
7 8 9 10
...
I want to flip it over the diagonal to make a symmetric matrix:
1 2 4 7
2 3 5 8
4 5 6 9
7 8 9 10
Please help. Thanks
  2 commentaires
Jan
Jan le 4 Mai 2016
Tghe solution depends on how the triangular "array" is stored. Are there zeros in the upper right elements?
John D'Errico
John D'Errico le 4 Mai 2016
Is the matrix stored as a matrix, so only the lower triangle, with zeros as the upper triangle. Or is there junk in the upper triangle? Or do you have the elements of the lower triangle, stored in a vector?
All of these things are pertinent to any efficient solution.

Connectez-vous pour commenter.

Réponse acceptée

Azzi Abdelmalek
Azzi Abdelmalek le 4 Mai 2016
A=[1 0 0 0
2 3 0 0
4 5 6 0
7 8 9 10]
[n,m]=size(A);
B=A'+A
B(1:n+1:end)=diag(A)
  3 commentaires
Junho Kweon
Junho Kweon le 28 Mai 2019
Oh my.. I like fewer version. :)
Bill Tubbs
Bill Tubbs le 28 Mai 2020
I think you can do it in one line like this:
B = triu(A.',1) + tril(A) % Takes bottom half of A to make B symmetric
Also, this does not do a conjugate transpose.

Connectez-vous pour commenter.

Plus de réponses (4)

Simon Liljestrand
Simon Liljestrand le 29 Sep 2017
A=[1 0 0 0
2 3 0 0
4 5 6 0
7 8 9 10];
B=A'+triu(A',1)';
  2 commentaires
Stephen23
Stephen23 le 29 Sep 2017
Modifié(e) : Stephen23 le 29 Sep 2017
+1 Neat. Also possible with fewer transposes:
>> B = A+tril(A,-1).'
B =
1 2 4 7
2 3 5 8
4 5 6 9
7 8 9 10
Simon Liljestrand
Simon Liljestrand le 29 Sep 2017
Ah, that makes it a little more elegant still!

Connectez-vous pour commenter.


Ben McSeveney
Ben McSeveney le 15 Fév 2018
Modifié(e) : Stephen23 le 15 Fév 2018
If I have a column vector e.g.
1
2
3
How do I quickly create a symmetric matrix i.e.
[1 2 3;
2 1 2;
3 2 1]
?
  3 commentaires
Jos (10584)
Jos (10584) le 15 Fév 2018
for which the answer will be toeplitz
v = 1:5
toeplitz(v)
Tom Davis
Tom Davis le 15 Fév 2018
[a,circshift(a,1),circshift(a,2)]
triu(a' - a + ones(size(a,1))) + tril(a - a' + ones(size(a,1))) - eye(size(a,1))

Connectez-vous pour commenter.


Walter Bova
Walter Bova le 16 Avr 2018
A = (A+A') - eye(size(A)).*A
  1 commentaire
sun
sun le 15 Juin 2020
Modifié(e) : sun le 17 Juin 2020
This formula A = (A+A') - eye(size(A)).*A is correct.

Connectez-vous pour commenter.


Rohit Sachdeva
Rohit Sachdeva le 9 Avr 2024
Modifié(e) : Rohit Sachdeva le 9 Avr 2024
As most people have pointed out, I just wanted to add another way of doing this:
B = (A+A') - diag(diag(A));
The (A+A') part is clear to most of us. This is how the 2nd term works:
  • First diag(.) extracts the diagonal elements of A.
  • The next diag(.) creats a matrix with just those diagonal elements.
  • Finally we subtract that matrix of diagonal elements from the (A+A') as required.
This eliminates the need of the eye(.) function. Hope it helps!
  1 commentaire
Steven Lord
Steven Lord le 9 Avr 2024
In general, this doesn't work.
A = magic(4)
A = 4x4
16 2 3 13 5 11 10 8 9 7 6 12 4 14 15 1
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
B = (A+A') - diag(diag(A))
B = 4x4
16 7 12 17 7 11 17 22 12 17 6 27 17 22 27 1
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
It does work if the matrix is real and one of the triangular parts already contains all 0 values.
C = triu(A)
C = 4x4
16 2 3 13 0 11 10 8 0 0 6 12 0 0 0 1
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
D = (C+C') - diag(diag(C))
D = 4x4
16 2 3 13 2 11 10 8 3 10 6 12 13 8 12 1
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
It doesn't work if the matrix is complex even if the matrix is triangular.
format shortg
C(1, 2) = 2+3i
C =
16 + 0i 2 + 3i 3 + 0i 13 + 0i 0 + 0i 11 + 0i 10 + 0i 8 + 0i 0 + 0i 0 + 0i 6 + 0i 12 + 0i 0 + 0i 0 + 0i 0 + 0i 1 + 0i
D = (C+C') - diag(diag(C))
D =
16 + 0i 2 + 3i 3 + 0i 13 + 0i 2 - 3i 11 + 0i 10 + 0i 8 + 0i 3 + 0i 10 + 0i 6 + 0i 12 + 0i 13 + 0i 8 + 0i 12 + 0i 1 + 0i
D is not symmetric, it is however Hermitian.
issymmetric(D)
ans = logical
0
ishermitian(D)
ans = logical
1
But if you used the non-conjugate transpose then the result is symmetric but not Hermitian:
E = (C+C.')-diag(diag(C))
E =
16 + 0i 2 + 3i 3 + 0i 13 + 0i 2 + 3i 11 + 0i 10 + 0i 8 + 0i 3 + 0i 10 + 0i 6 + 0i 12 + 0i 13 + 0i 8 + 0i 12 + 0i 1 + 0i
issymmetric(E)
ans = logical
1
ishermitian(E)
ans = logical
0

Connectez-vous pour commenter.

Catégories

En savoir plus sur Operating on Diagonal Matrices dans Help Center et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by