Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making a numpy ndarray matrix symmetric

I have a 70x70 numpy ndarray, which is mainly diagonal. The only off-diagonal values are the below the diagonal. I would like to make the matrix symmetric.

As a newcomer from Matlab world, I can't get it working without for loops. In MATLAB it was easy:

W = max(A,A')

where A' is matrix transposition and the max() function takes care to make the W matrix which will be symmetric.

Is there an elegant way to do so in Python as well?

EXAMPLE The sample A matrix is:

1 0 0 0
0 2 0 0
1 0 2 0
0 1 0 3

The desired output matrix W is:

1 0 1 0
0 2 0 1
1 0 2 0
0 1 0 3
like image 318
Vladislavs Dovgalecs Avatar asked Mar 06 '15 17:03

Vladislavs Dovgalecs


People also ask

How do you convert a matrix into a symmetric matrix?

Given an integer N and a N x N matrix, the task is to convert the given matrix into a symmetric matrix by replacing (i, j)th and (j, i)th element with their arithmetic mean. Explanation: The diagonal elements are same.

How do you make an array symmetric in Python?

Use the NumPy tril and triu functions as follows. It essentially "mirrors" elements in the lower triangle into the upper triangle. tril(m, k=0) gets the lower triangle of a matrix m (returns a copy of the matrix m with all elements above the k th diagonal zeroed).

How do you know if a matrix is symmetric in NumPy?

An Efficient solution to check a matrix is symmetric or not is to compare matrix elements without creating a transpose. We basically need to compare mat[i][j] with mat[j][i].


2 Answers

Found a following solution which works for me:

import numpy as np
W = np.maximum( A, A.transpose() )
like image 159
Vladislavs Dovgalecs Avatar answered Oct 30 '22 14:10

Vladislavs Dovgalecs


Use the NumPy tril and triu functions as follows. It essentially "mirrors" elements in the lower triangle into the upper triangle.

import numpy as np
A = np.array([[1, 0, 0, 0], [0, 2, 0, 0], [1, 0, 2, 0], [0, 1, 0, 3]])
W = np.tril(A) + np.triu(A.T, 1)

tril(m, k=0) gets the lower triangle of a matrix m (returns a copy of the matrix m with all elements above the kth diagonal zeroed). Similarly, triu(m, k=0) gets the upper triangle of a matrix m (all elements below the kth diagonal zeroed).

To prevent the diagonal being added twice, one must exclude the diagonal from one of the triangles, using either np.tril(A) + np.triu(A.T, 1) or np.tril(A, -1) + np.triu(A.T).

Also note that this behaves slightly differently to using maximum. All elements in the upper triangle are overwritten, regardless of whether they are the maximum or not. This means they can be any value (e.g. nan or inf).

like image 11
Ruben9922 Avatar answered Oct 30 '22 16:10

Ruben9922