pythonmatrixrandomscipyeigenvalue

non-symmetric square matrix with given eigenvalues


Given an array of eigenvalues, how can I generate a non-symmetric square matrix which has those eigenvalues?

I have tried the QR decomposition, but it returns a symmetric one. Here's what I have done so far.

from scipy.stats import ortho_group

eigenvalues = [0.63, 0.2, 0.09, 0.44, 0.3]
s = np.diag(eigenvalues)
q = ortho_group.rvs(len(eigenvalues))
print(np.linalg.eigvalsh(q.T @ s @ q)) # checking the eigenvalues

print(q.T @ s @ q)

Solution

  • Conjugation of a diagonal matrix with an orthogonal matrix always gives a symmetric matrix. To get a non-symmetric matrix, conjugate with a non-orthogonal invertible matrix instead:

    import numpy as np
    
    eigenvalues = [0.63, 0.2, 0.09, 0.44, 0.3]
    D = np.diag(eigenvalues)
    n  = len(eigenvalues)
    rng = np.random.default_rng()
    while True: 
        P = rng.random((n, n))
        try: 
            Pinv = np.linalg.inv(P)
            break
        except np.linalg.LinAlgError:
            pass
    
    A = P@D@Pinv
    print(A)
    print("\nEigenvalues:")
    print(np.linalg.eigvals(A)) # checking the eigenvalues
    

    It gives:

    [[ -1.23417213  11.91027222 -13.37533243  10.2722421   -4.59655968]
     [ -0.24097482   3.09499536  -2.88526862   1.82847184  -1.06480054]
     [  0.55926723  -3.15271219   4.08323704  -3.29506564   1.1910062 ]
     [  0.45811586  -2.57807667   3.0211003   -2.22846412   0.92175117]
     [ -0.62006334   5.94747059  -6.43946088   4.61080106  -2.05559614]]
    
    Eigenvalues:
    [0.63 0.44 0.09 0.3  0.2 ]