Yuan Chen
Yuan Chen

Reputation: 87

What's happening here when swapping two columns of an np.array?

import numpy as np
from scipy import linalg as linalg
M = np.array([[1,2],[2,1],[3,4],[4,3]])
Evals, Evecs = linalg.eigh(M.T.dot(M))
EvecShape = Evecs.shape
print Evals
print Evecs
ncols = EvecShape[1]
for i in range(ncols/2):
    Evals[i], Evals[ncols-1-i] = Evals[ncols-1-i], Evals[i]
    Evecs[:,i], Evecs[:,ncols-1-i] = Evecs[:,ncols-1-i], Evecs[:,i]
print Evals
print Evecs

I want to calculate the eigenvalues and eigenvectors of MT*M and order the eigenvalues in a descending order by swapping corresponding columns. The result printed are below:

[  2.  58.]
[[-0.70710678  0.70710678]
 [ 0.70710678  0.70710678]]
[ 58.   2.]
[[ 0.70710678  0.70710678]
[ 0.70710678  0.70710678]]

It seems that I did swap the elements in Evals. But for Evecs, it is clear that something is wrong. Can anyone tell me what's happening here?

Upvotes: 0

Views: 45

Answers (2)

Paul Panzer
Paul Panzer

Reputation: 53029

The problem with your code is that when you try to swap the columns you overwrite one with the other before you read out the first. This is because array slices if possible don't copy data but reference the buffer of the array sliced.

To mitigate you can either

  • force a copy using .copy() like so

.

Evecs[:,i], Evecs[:,ncols-1-i] = Evecs[:,ncols-1-i], Evecs[:,i].copy()

or

  • avoid the loop and just do

.

Evecs = Evecs[:, ::-1]

Upvotes: 1

nuriselcuk
nuriselcuk

Reputation: 527

You are trying to sort eigenvector like two-dimensional array. Not good. Use particular methods. Here below;

import numpy as np
from scipy import linalg as linalg
M = np.array([[1,2],[2,1],[3,4],[4,3]])
Evals, Evecs = linalg.eigh(M.T.dot(M))
print Evals
print Evecs

index = Evals.argsort()[::-1]   

Evals= Evals[index]
Evecs = Evecs [:,index]

print Evals
print Evecs

Upvotes: 1

Related Questions