meatball2000
meatball2000

Reputation: 1

Extracting eigenvectors from eigendecomposition

I'm following the sequence of steps:

  1. Given A is m by n then we perform SVD on A = USVT

  2. Then, find U’ = (1/2)(U+UT) to obtain a symmetric matrix

  3. Then, perform eigenvalue decomposition on U’, m by m.

  4. Extract the positive eigenvectors that correspond the to the positive eigenvalues and form a matrix X say m by k

  5. Perform SVD on XTX and obtain the U’s which are in SO(n) for the positive eigenvalues

  6. Repeat Step 4 and 5 but for the negative eigenvectors

However, I can't seem to get the correct U's for positive eigenvalues (as I verified using SVD and eigenvector calculators online) and the negative eigenvectors are absent. Any help on the following or any improvements I can make?

import numpy as np

def svd(A):
    U, S, VT = np.linalg.svd(A, full_matrices=True)
    return U, S, VT

def symmetric(U):
    U_symmetric = 0.5 * (U + U.T)
    return U_symmetric

def eigenvalue_decomposition(U):
    eigenvalues, eigenvectors = np.linalg.eig(U)
    return eigenvalues, eigenvectors

def extract_positive_eigenvectors(eigenvalues, eigenvectors):
    positive_indices = np.where(eigenvalues > 0)
    if len(positive_indices[0]) == 0:
        return None
    X = eigenvectors[:, positive_indices]
    return X

def extract_negative_eigenvectors(eigenvalues, eigenvectors):
    negative_indices = np.where(eigenvalues < 0)
    if len(negative_indices[0]) == 0:
        return None
    X = eigenvectors[:, negative_indices]
    return X

A = np.array([[1, 2, 2], [0, 1, 2]])

U, _, _ = svd(A)
U_symmetric = symmetric(U)
eigenvalues, eigenvectors = eigenvalue_decomposition(U_symmetric)

# extract positive eigenvectors (if any)
X_positive = extract_positive_eigenvectors(eigenvalues, eigenvectors)

if X_positive is not None:
    X_positive_2d = X_positive.reshape(X_positive.shape[0], -1)
    U_positive, _, _ = svd(np.dot(X_positive_2d.T, X_positive_2d))
else:
    U_positive = None

print("Matrix U from SVD of XTX for positive eigenvectors:")
print(U_positive)

# extract negative eigenvectors (if any)
X_negative = extract_negative_eigenvectors(eigenvalues, eigenvectors)

if X_negative is not None:
    X_negative_2d = X_negative.reshape(X_negative.shape[0], -1)
    U_negative, _, _ = svd(np.dot(X_negative_2d.T, X_negative_2d))
else:
    U_negative = None

print("Matrix U from SVD of XTX for negative eigenvectors:")
print(U_negative)

Upvotes: 0

Views: 94

Answers (1)

Sauron
Sauron

Reputation: 1353

  • In extract_positive_eigenvectors you need to use the indices obtained from np.where to extract the corresponding eigenvectors correctly. Currently, you are using the indices directly, which results in incorrect slicing.
X = eigenvectors[:, positive_indices[0]]  # for positive eigenvectors
  • Same in extract_negative_eigenvectors funct.
X = eigenvectors[:, negative_indices[0]] # for negative eigenvectors

Upvotes: 0

Related Questions