Python: scipy.sparse.linalg.eigsh for complex Hermitian matrices - python

I am trying to diagonalise a simple sparse Hermitian matrix using python's scipy.sparse.linalg.eigsh function; although the documentation says it supports Hermitian matrices, the file python wrapper file arpack.py says it does not:
# The entry points to ARPACK are
# - (s,d)seupd : single and double precision symmetric matrix
# - (s,d,c,z)neupd: single,double,complex,double complex general matrix
# This wrapper puts the *neupd (general matrix) interfaces in eigs()
# and the *seupd (symmetric matrix) in eigsh().
# There is no Hermetian complex/double complex interface.
# To find eigenvalues of a Hermetian matrix you
# must use eigs() and not eigsh()
# It might be desirable to handle the Hermetian case differently
# and, for example, return real eigenvalues.
Indeed the above comments from the wrapper are vindicated when I try to run the following code for diagonalising a sparse complex Hermitian matrix using eigsh:
from scipy.sparse import *
from scipy.sparse.linalg import *
import math
sign = lambda x: math.copysign(1, x)
S = lil_matrix((5,5), dtype=complex)
for i in range(5):
for j in range(5):
S[i,j] = sign(i-j)*1j
eigval = eigsh(-S, k=1, M=None,sigma=None, which='LM', v0=None, ncv=None, tol=0, return_eigenvectors=False)
Then the following error comes up:
ValueError: Input matrix is not real-valued.
Of course, if I use a regular numpy matrix for S and the numpy.linalg.eigh function, then all the eigenvalues are computed. But
I do not want all the eigenvalues, and
I need my matrix to be sparse.
Does anyone know what then is the point of having a sparse version eigsh for sparse complex Hermitian matrices if it cannot be used?
Note: I understand that the matrix in the example here is not necessarily sparse by some definition of sparsity but it's just used for illustrative purposes.

Related

Diagonalizing an unitary matrix with numpy doesn't yield orthonormal eigenvectors

I'm trying to diagonalize an unitary matrix using numpy, in particular the numpy.linalg.eig function. Since the matrix is unitary, its eigenvectors are supposed to form an orthonormal basis. However, it seems that this is not the case:
import numpy as np
from qiskit.circuit.library import QFT
from qiskit.quantum_info import Operator
op = Operator(QFT(num_qubits=4, do_swaps=True)).data
eigvals, eigvecs = np.linalg.eig(op) # Compute the eigenvalues
eigvecs = eigvecs.T # Since the eigenvectors are arranged in columns
lambda_i = eigvals[2]
lambda_j = eigvals[-1]
v_i = eigvecs[2].reshape((-1, 1))
v_j = eigvecs[-1].reshape((-1, 1))
print(np.linalg.norm(op # v_i - lambda_i * v_i)) # Should be close to 0 by definition, actually yields 6.706985734026871e-16, which is fine
print(np.linalg.norm(op # v_j - lambda_j * v_j)) # Should be close to 0 by definition, actually yields 8.151878100248519e-16, which is fine
print(v_j.T.conj() # v_i) # Should be close to zero since the basis is supposed to be orthonormal but actually yields array([[-0.15147621-0.06735767j]]), which is not fine
print(np.linalg.norm(op.T.conj() # op - np.eye(16))) # Should be around zero if and only if op.data is unitary, actually yields 2.3337334181537826e-15, which is ine
I've tested it with the qiskit library, however my question is purely numpy-related. If required, the same matrix can be loaded using the following .npy file:
b"\x93NUMPY\x01\x00v\x00{'descr': '<c16', 'fortran_order': False, 'shape': (16, 16), } \n\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00C\x8d2\xcfk\x90\xcd?`\xa9\xae\xa6\xe2}\xb8?\xcb;\x7ff\x9e\xa0\xc6?\xca;\x7ff\x9e\xa0\xc6?c\xa9\xae\xa6\xe2}\xb8?C\x8d2\xcfk\x90\xcd?\x05\\\x143&\xa6q<\xfd\xff\xff\xff\xff\xff\xcf?^\xa9\xae\xa6\xe2}\xb8\xbfC\x8d2\xcfk\x90\xcd?\xc9;\x7ff\x9e\xa0\xc6\xbf\xcb;\x7ff\x9e\xa0\xc6?A\x8d2\xcfk\x90\xcd\xbfc\xa9\xae\xa6\xe2}\xb8?\xfd\xff\xff\xff\xff\xff\xcf\xbf\x00\x00\x00\x00\x00\x00\x00\x00C\x8d2\xcfk\x90\xcd\xbf`\xa9\xae\xa6\xe2}\xb8\xbf\xcb;\x7ff\x9e\xa0\xc6\xbf\xca;\x7ff\x9e\xa0\xc6\xbfc\xa9\xae\xa6\xe2}\xb8\xbfC\x8d2\xcfk\x90\xcd\xbf\x05\\\x143&\xa6q\xbc\xfd\xff\xff\xff\xff\xff\xcf\xbf^\xa9\xae\xa6\xe2}\xb8?C\x8d2\xcfk\x90\xcd\xbf\xc9;\x7ff\x9e\xa0\xc6?\xcb;\x7ff\x9e\xa0\xc6\xbfA\x8d2\xcfk\x90\xcd?c\xa9\xae\xa6\xe2}\xb8\xbf\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00\xcb;\x7ff\x9e\xa0\xc6?\xca;\x7ff\x9e\xa0\xc6?\x05\\\x143&\xa6q<\xfd\xff\xff\xff\xff\xff\xcf?\xca;\x7ff\x9e\xa0\xc6\xbf\xcb;\x7ff\x9e\xa0\xc6?\xfd\xff\xff\xff\xff\xff\xcf\xbf\x00\x00\x00\x00\x00\x00\x00\x00\xcb;\x7ff\x9e\xa0\xc6\xbf\xca;\x7ff\x9e\xa0\xc6\xbf\x05\\\x143&\xa6q\xbc\xfd\xff\xff\xff\xff\xff\xcf\xbf\xca;\x7ff\x9e\xa0\xc6?\xcb;\x7ff\x9e\xa0\xc6\xbf\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00\xcb;\x7ff\x9e\xa0\xc6?\xca;\x7ff\x9e\xa0\xc6?\x05\\\x143&\xa6q<\xfd\xff\xff\xff\xff\xff\xcf?\xca;\x7ff\x9e\xa0\xc6\xbf\xcb;\x7ff\x9e\xa0\xc6?\xfd\xff\xff\xff\xff\xff\xcf\xbf\x00\x00\x00\x00\x00\x00\x00\x00\xcb;\x7ff\x9e\xa0\xc6\xbf\xca;\x7ff\x9e\xa0\xc6\xbf\x05\\\x143&\xa6q\xbc\xfd\xff\xff\xff\xff\xff\xcf\xbf\xca;\x7ff\x9e\xa0\xc6?\xcb;\x7ff\x9e\xa0\xc6\xbf\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00a\xa9\xae\xa6\xe2}\xb8?C\x8d2\xcfk\x90\xcd?\xca;\x7ff\x9e\xa0\xc6\xbf\xcb;\x7ff\x9e\xa0\xc6?D\x8d2\xcfk\x90\xcd\xbf[\xa9\xae\xa6\xe2}\xb8\xbf\x05\\\x143&\xa6q\xbc\xfd\xff\xff\xff\xff\xff\xcf\xbfC\x8d2\xcfk\x90\xcd?c\xa9\xae\xa6\xe2}\xb8\xbf\xcb;\x7ff\x9e\xa0\xc6?\xc9;\x7ff\x9e\xa0\xc6?Z\xa9\xae\xa6\xe2}\xb8\xbfC\x8d2\xcfk\x90\xcd?\xfd\xff\xff\xff\xff\xff\xcf\xbf\x00\x00\x00\x00\x00\x00\x00\x00a\xa9\xae\xa6\xe2}\xb8\xbfC\x8d2\xcfk\x90\xcd\xbf\xca;\x7ff\x9e\xa0\xc6?\xcb;\x7ff\x9e\xa0\xc6\xbfD\x8d2\xcfk\x90\xcd?[\xa9\xae\xa6\xe2}\xb8?\x05\\\x143&\xa6q<\xfd\xff\xff\xff\xff\xff\xcf?C\x8d2\xcfk\x90\xcd\xbfc\xa9\xae\xa6\xe2}\xb8?\xcb;\x7ff\x9e\xa0\xc6\xbf\xc9;\x7ff\x9e\xa0\xc6\xbfZ\xa9\xae\xa6\xe2}\xb8?C\x8d2\xcfk\x90\xcd\xbf\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00\x05\\\x143&\xa6q<\xfd\xff\xff\xff\xff\xff\xcf?\xfd\xff\xff\xff\xff\xff\xcf\xbf\x00\x00\x00\x00\x00\x00\x00\x00\x05\\\x143&\xa6q\xbc\xfd\xff\xff\xff\xff\xff\xcf\xbf\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00\x05\\\x143&\xa6q<\xfd\xff\xff\xff\xff\xff\xcf?\xfd\xff\xff\xff\xff\xff\xcf\xbf\x00\x00\x00\x00\x00\x00\x00\x00\x05\\\x143&\xa6q\xbc\xfd\xff\xff\xff\xff\xff\xcf\xbf\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00\x05\\\x143&\xa6q<\xfd\xff\xff\xff\xff\xff\xcf?\xfd\xff\xff\xff\xff\xff\xcf\xbf\x00\x00\x00\x00\x00\x00\x00\x00\x05\\\x143&\xa6q\xbc\xfd\xff\xff\xff\xff\xff\xcf\xbf\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00\x05\\\x143&\xa6q<\xfd\xff\xff\xff\xff\xff\xcf?\xfd\xff\xff\xff\xff\xff\xcf\xbf\x00\x00\x00\x00\x00\x00\x00\x00\x05\\\x143&\xa6q\xbc\xfd\xff\xff\xff\xff\xff\xcf\xbf\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00^\xa9\xae\xa6\xe2}\xb8\xbfC\x8d2\xcfk\x90\xcd?\xcb;\x7ff\x9e\xa0\xc6\xbf\xca;\x7ff\x9e\xa0\xc6\xbfC\x8d2\xcfk\x90\xcd?d\xa9\xae\xa6\xe2}\xb8\xbf\x05\\\x143&\xa6q<\xfd\xff\xff\xff\xff\xff\xcf?C\x8d2\xcfk\x90\xcd\xbf]\xa9\xae\xa6\xe2}\xb8\xbf\xc9;\x7ff\x9e\xa0\xc6?\xcb;\x7ff\x9e\xa0\xc6\xbfd\xa9\xae\xa6\xe2}\xb8?A\x8d2\xcfk\x90\xcd?\xfd\xff\xff\xff\xff\xff\xcf\xbf\x00\x00\x00\x00\x00\x00\x00\x00^\xa9\xae\xa6\xe2}\xb8?C\x8d2\xcfk\x90\xcd\xbf\xcb;\x7ff\x9e\xa0\xc6?\xca;\x7ff\x9e\xa0\xc6?C\x8d2\xcfk\x90\xcd\xbfd\xa9\xae\xa6\xe2}\xb8?\x05\\\x143&\xa6q\xbc\xfd\xff\xff\xff\xff\xff\xcf\xbfC\x8d2\xcfk\x90\xcd?]\xa9\xae\xa6\xe2}\xb8?\xc9;\x7ff\x9e\xa0\xc6\xbf\xcb;\x7ff\x9e\xa0\xc6?d\xa9\xae\xa6\xe2}\xb8\xbfA\x8d2\xcfk\x90\xcd\xbf\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00\xc9;\x7ff\x9e\xa0\xc6\xbf\xcb;\x7ff\x9e\xa0\xc6?\x05\\\x143&\xa6q\xbc\xfd\xff\xff\xff\xff\xff\xcf\xbf\xcb;\x7ff\x9e\xa0\xc6?\xc9;\x7ff\x9e\xa0\xc6?\xfd\xff\xff\xff\xff\xff\xcf\xbf\x00\x00\x00\x00\x00\x00\x00\x00\xc9;\x7ff\x9e\xa0\xc6?\xcb;\x7ff\x9e\xa0\xc6\xbf\x05\\\x143&\xa6q<\xfd\xff\xff\xff\xff\xff\xcf?\xcb;\x7ff\x9e\xa0\xc6\xbf\xc9;\x7ff\x9e\xa0\xc6\xbf\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00\xc9;\x7ff\x9e\xa0\xc6\xbf\xcb;\x7ff\x9e\xa0\xc6?\x05\\\x143&\xa6q\xbc\xfd\xff\xff\xff\xff\xff\xcf\xbf\xcb;\x7ff\x9e\xa0\xc6?\xc9;\x7ff\x9e\xa0\xc6?\xfd\xff\xff\xff\xff\xff\xcf\xbf\x00\x00\x00\x00\x00\x00\x00\x00\xc9;\x7ff\x9e\xa0\xc6?\xcb;\x7ff\x9e\xa0\xc6\xbf\x05\\\x143&\xa6q<\xfd\xff\xff\xff\xff\xff\xcf?\xcb;\x7ff\x9e\xa0\xc6\xbf\xc9;\x7ff\x9e\xa0\xc6\xbf\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00C\x8d2\xcfk\x90\xcd\xbfc\xa9\xae\xa6\xe2}\xb8?\xca;\x7ff\x9e\xa0\xc6?\xcb;\x7ff\x9e\xa0\xc6\xbfZ\xa9\xae\xa6\xe2}\xb8\xbfD\x8d2\xcfk\x90\xcd?\x05\\\x143&\xa6q\xbc\xfd\xff\xff\xff\xff\xff\xcf\xbfd\xa9\xae\xa6\xe2}\xb8?C\x8d2\xcfk\x90\xcd?\xcb;\x7ff\x9e\xa0\xc6\xbf\xc9;\x7ff\x9e\xa0\xc6\xbfC\x8d2\xcfk\x90\xcd?Y\xa9\xae\xa6\xe2}\xb8?\xfd\xff\xff\xff\xff\xff\xcf\xbf\x00\x00\x00\x00\x00\x00\x00\x00C\x8d2\xcfk\x90\xcd?c\xa9\xae\xa6\xe2}\xb8\xbf\xca;\x7ff\x9e\xa0\xc6\xbf\xcb;\x7ff\x9e\xa0\xc6?Z\xa9\xae\xa6\xe2}\xb8?D\x8d2\xcfk\x90\xcd\xbf\x05\\\x143&\xa6q<\xfd\xff\xff\xff\xff\xff\xcf?d\xa9\xae\xa6\xe2}\xb8\xbfC\x8d2\xcfk\x90\xcd\xbf\xcb;\x7ff\x9e\xa0\xc6?\xc9;\x7ff\x9e\xa0\xc6?C\x8d2\xcfk\x90\xcd\xbfY\xa9\xae\xa6\xe2}\xb8\xbf\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00\xfd\xff\xff\xff\xff\xff\xcf\xbf\x00\x00\x00\x00\x00\x00\x00\x00\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00\xfd\xff\xff\xff\xff\xff\xcf\xbf\x00\x00\x00\x00\x00\x00\x00\x00\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00\xfd\xff\xff\xff\xff\xff\xcf\xbf\x00\x00\x00\x00\x00\x00\x00\x00\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00\xfd\xff\xff\xff\xff\xff\xcf\xbf\x00\x00\x00\x00\x00\x00\x00\x00\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00\xfd\xff\xff\xff\xff\xff\xcf\xbf\x00\x00\x00\x00\x00\x00\x00\x00\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00\xfd\xff\xff\xff\xff\xff\xcf\xbf\x00\x00\x00\x00\x00\x00\x00\x00\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00\xfd\xff\xff\xff\xff\xff\xcf\xbf\x00\x00\x00\x00\x00\x00\x00\x00\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00\xfd\xff\xff\xff\xff\xff\xcf\xbf\x00\x00\x00\x00\x00\x00\x00\x00\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00C\x8d2\xcfk\x90\xcd\xbf`\xa9\xae\xa6\xe2}\xb8\xbf\xcb;\x7ff\x9e\xa0\xc6?\xca;\x7ff\x9e\xa0\xc6?c\xa9\xae\xa6\xe2}\xb8\xbfC\x8d2\xcfk\x90\xcd\xbf\x05\\\x143&\xa6q<\xfd\xff\xff\xff\xff\xff\xcf?^\xa9\xae\xa6\xe2}\xb8?C\x8d2\xcfk\x90\xcd\xbf\xc9;\x7ff\x9e\xa0\xc6\xbf\xcb;\x7ff\x9e\xa0\xc6?A\x8d2\xcfk\x90\xcd?c\xa9\xae\xa6\xe2}\xb8\xbf\xfd\xff\xff\xff\xff\xff\xcf\xbf\x00\x00\x00\x00\x00\x00\x00\x00C\x8d2\xcfk\x90\xcd?`\xa9\xae\xa6\xe2}\xb8?\xcb;\x7ff\x9e\xa0\xc6\xbf\xca;\x7ff\x9e\xa0\xc6\xbfc\xa9\xae\xa6\xe2}\xb8?C\x8d2\xcfk\x90\xcd?\x05\\\x143&\xa6q\xbc\xfd\xff\xff\xff\xff\xff\xcf\xbf^\xa9\xae\xa6\xe2}\xb8\xbfC\x8d2\xcfk\x90\xcd?\xc9;\x7ff\x9e\xa0\xc6?\xcb;\x7ff\x9e\xa0\xc6\xbfA\x8d2\xcfk\x90\xcd\xbfc\xa9\xae\xa6\xe2}\xb8?\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00\xcb;\x7ff\x9e\xa0\xc6\xbf\xca;\x7ff\x9e\xa0\xc6\xbf\x05\\\x143&\xa6q<\xfd\xff\xff\xff\xff\xff\xcf?\xca;\x7ff\x9e\xa0\xc6?\xcb;\x7ff\x9e\xa0\xc6\xbf\xfd\xff\xff\xff\xff\xff\xcf\xbf\x00\x00\x00\x00\x00\x00\x00\x00\xcb;\x7ff\x9e\xa0\xc6?\xca;\x7ff\x9e\xa0\xc6?\x05\\\x143&\xa6q\xbc\xfd\xff\xff\xff\xff\xff\xcf\xbf\xca;\x7ff\x9e\xa0\xc6\xbf\xcb;\x7ff\x9e\xa0\xc6?\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00\xcb;\x7ff\x9e\xa0\xc6\xbf\xca;\x7ff\x9e\xa0\xc6\xbf\x05\\\x143&\xa6q<\xfd\xff\xff\xff\xff\xff\xcf?\xca;\x7ff\x9e\xa0\xc6?\xcb;\x7ff\x9e\xa0\xc6\xbf\xfd\xff\xff\xff\xff\xff\xcf\xbf\x00\x00\x00\x00\x00\x00\x00\x00\xcb;\x7ff\x9e\xa0\xc6?\xca;\x7ff\x9e\xa0\xc6?\x05\\\x143&\xa6q\xbc\xfd\xff\xff\xff\xff\xff\xcf\xbf\xca;\x7ff\x9e\xa0\xc6\xbf\xcb;\x7ff\x9e\xa0\xc6?\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00a\xa9\xae\xa6\xe2}\xb8\xbfC\x8d2\xcfk\x90\xcd\xbf\xca;\x7ff\x9e\xa0\xc6\xbf\xcb;\x7ff\x9e\xa0\xc6?D\x8d2\xcfk\x90\xcd?[\xa9\xae\xa6\xe2}\xb8?\x05\\\x143&\xa6q\xbc\xfd\xff\xff\xff\xff\xff\xcf\xbfC\x8d2\xcfk\x90\xcd\xbfc\xa9\xae\xa6\xe2}\xb8?\xcb;\x7ff\x9e\xa0\xc6?\xc9;\x7ff\x9e\xa0\xc6?Z\xa9\xae\xa6\xe2}\xb8?C\x8d2\xcfk\x90\xcd\xbf\xfd\xff\xff\xff\xff\xff\xcf\xbf\x00\x00\x00\x00\x00\x00\x00\x00a\xa9\xae\xa6\xe2}\xb8?C\x8d2\xcfk\x90\xcd?\xca;\x7ff\x9e\xa0\xc6?\xcb;\x7ff\x9e\xa0\xc6\xbfD\x8d2\xcfk\x90\xcd\xbf[\xa9\xae\xa6\xe2}\xb8\xbf\x05\\\x143&\xa6q<\xfd\xff\xff\xff\xff\xff\xcf?C\x8d2\xcfk\x90\xcd?c\xa9\xae\xa6\xe2}\xb8\xbf\xcb;\x7ff\x9e\xa0\xc6\xbf\xc9;\x7ff\x9e\xa0\xc6\xbfZ\xa9\xae\xa6\xe2}\xb8\xbfC\x8d2\xcfk\x90\xcd?\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00\x05\\\x143&\xa6q\xbc\xfd\xff\xff\xff\xff\xff\xcf\xbf\xfd\xff\xff\xff\xff\xff\xcf\xbf\x00\x00\x00\x00\x00\x00\x00\x00\x05\\\x143&\xa6q<\xfd\xff\xff\xff\xff\xff\xcf?\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00\x05\\\x143&\xa6q\xbc\xfd\xff\xff\xff\xff\xff\xcf\xbf\xfd\xff\xff\xff\xff\xff\xcf\xbf\x00\x00\x00\x00\x00\x00\x00\x00\x05\\\x143&\xa6q<\xfd\xff\xff\xff\xff\xff\xcf?\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00\x05\\\x143&\xa6q\xbc\xfd\xff\xff\xff\xff\xff\xcf\xbf\xfd\xff\xff\xff\xff\xff\xcf\xbf\x00\x00\x00\x00\x00\x00\x00\x00\x05\\\x143&\xa6q<\xfd\xff\xff\xff\xff\xff\xcf?\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00\x05\\\x143&\xa6q\xbc\xfd\xff\xff\xff\xff\xff\xcf\xbf\xfd\xff\xff\xff\xff\xff\xcf\xbf\x00\x00\x00\x00\x00\x00\x00\x00\x05\\\x143&\xa6q<\xfd\xff\xff\xff\xff\xff\xcf?\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00^\xa9\xae\xa6\xe2}\xb8?C\x8d2\xcfk\x90\xcd\xbf\xcb;\x7ff\x9e\xa0\xc6\xbf\xca;\x7ff\x9e\xa0\xc6\xbfC\x8d2\xcfk\x90\xcd\xbfd\xa9\xae\xa6\xe2}\xb8?\x05\\\x143&\xa6q<\xfd\xff\xff\xff\xff\xff\xcf?C\x8d2\xcfk\x90\xcd?]\xa9\xae\xa6\xe2}\xb8?\xc9;\x7ff\x9e\xa0\xc6?\xcb;\x7ff\x9e\xa0\xc6\xbfd\xa9\xae\xa6\xe2}\xb8\xbfA\x8d2\xcfk\x90\xcd\xbf\xfd\xff\xff\xff\xff\xff\xcf\xbf\x00\x00\x00\x00\x00\x00\x00\x00^\xa9\xae\xa6\xe2}\xb8\xbfC\x8d2\xcfk\x90\xcd?\xcb;\x7ff\x9e\xa0\xc6?\xca;\x7ff\x9e\xa0\xc6?C\x8d2\xcfk\x90\xcd?d\xa9\xae\xa6\xe2}\xb8\xbf\x05\\\x143&\xa6q\xbc\xfd\xff\xff\xff\xff\xff\xcf\xbfC\x8d2\xcfk\x90\xcd\xbf]\xa9\xae\xa6\xe2}\xb8\xbf\xc9;\x7ff\x9e\xa0\xc6\xbf\xcb;\x7ff\x9e\xa0\xc6?d\xa9\xae\xa6\xe2}\xb8?A\x8d2\xcfk\x90\xcd?\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00\xc9;\x7ff\x9e\xa0\xc6?\xcb;\x7ff\x9e\xa0\xc6\xbf\x05\\\x143&\xa6q\xbc\xfd\xff\xff\xff\xff\xff\xcf\xbf\xcb;\x7ff\x9e\xa0\xc6\xbf\xc9;\x7ff\x9e\xa0\xc6\xbf\xfd\xff\xff\xff\xff\xff\xcf\xbf\x00\x00\x00\x00\x00\x00\x00\x00\xc9;\x7ff\x9e\xa0\xc6\xbf\xcb;\x7ff\x9e\xa0\xc6?\x05\\\x143&\xa6q<\xfd\xff\xff\xff\xff\xff\xcf?\xcb;\x7ff\x9e\xa0\xc6?\xc9;\x7ff\x9e\xa0\xc6?\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00\xc9;\x7ff\x9e\xa0\xc6?\xcb;\x7ff\x9e\xa0\xc6\xbf\x05\\\x143&\xa6q\xbc\xfd\xff\xff\xff\xff\xff\xcf\xbf\xcb;\x7ff\x9e\xa0\xc6\xbf\xc9;\x7ff\x9e\xa0\xc6\xbf\xfd\xff\xff\xff\xff\xff\xcf\xbf\x00\x00\x00\x00\x00\x00\x00\x00\xc9;\x7ff\x9e\xa0\xc6\xbf\xcb;\x7ff\x9e\xa0\xc6?\x05\\\x143&\xa6q<\xfd\xff\xff\xff\xff\xff\xcf?\xcb;\x7ff\x9e\xa0\xc6?\xc9;\x7ff\x9e\xa0\xc6?\xfd\xff\xff\xff\xff\xff\xcf?\x00\x00\x00\x00\x00\x00\x00\x00C\x8d2\xcfk\x90\xcd?c\xa9\xae\xa6\xe2}\xb8\xbf\xca;\x7ff\x9e\xa0\xc6?\xcb;\x7ff\x9e\xa0\xc6\xbfZ\xa9\xae\xa6\xe2}\xb8?D\x8d2\xcfk\x90\xcd\xbf\x05\\\x143&\xa6q\xbc\xfd\xff\xff\xff\xff\xff\xcf\xbfd\xa9\xae\xa6\xe2}\xb8\xbfC\x8d2\xcfk\x90\xcd\xbf\xcb;\x7ff\x9e\xa0\xc6\xbf\xc9;\x7ff\x9e\xa0\xc6\xbfC\x8d2\xcfk\x90\xcd\xbfY\xa9\xae\xa6\xe2}\xb8\xbf\xfd\xff\xff\xff\xff\xff\xcf\xbf\x00\x00\x00\x00\x00\x00\x00\x00C\x8d2\xcfk\x90\xcd\xbfc\xa9\xae\xa6\xe2}\xb8?\xca;\x7ff\x9e\xa0\xc6\xbf\xcb;\x7ff\x9e\xa0\xc6?Z\xa9\xae\xa6\xe2}\xb8\xbfD\x8d2\xcfk\x90\xcd?\x05\\\x143&\xa6q<\xfd\xff\xff\xff\xff\xff\xcf?d\xa9\xae\xa6\xe2}\xb8?C\x8d2\xcfk\x90\xcd?\xcb;\x7ff\x9e\xa0\xc6?\xc9;\x7ff\x9e\xa0\xc6?C\x8d2\xcfk\x90\xcd?Y\xa9\xae\xa6\xe2}\xb8?"
The behavior seems to occur only for purely complex (that is, with a nil real part) eigenvalues. For most of the other eigenvectors, the scalar product does yield 0, but I was able to remplicate this behavior on others.
I don't think it is due to some numerical approximation since the final scalar product is quite large.
I don't think it is due to some conjugation that I would have forgot. As a sanity check, I've ensured that v_i and v_j are indeed eigenvectors of op, which means they are correct, and which means they should be orthogonal.
The error in the reasoning comes from this part:
As a sanity check, I've ensured that v_i and v_j are indeed eigenvectors of op, which means they are correct, and which means they should be orthogonal.
If v_i and v_j are associated to the same eigenvalue lambda, then (v_i+v_j)/sqrt(2) is an eigenvector associated to lambda and which isn't orthogonal to v_i or v_j.
In order to ensure that the eigenvectors are orthogonal, simply perform:
eigvecs = np.linalg.qr(eigvecs)[0]
eigvecs will now contain orthonormal eigenvectors of op.

Determinant of a complex matrix in PyTorch

Is there a way to calculate the determinant of a complex matrix in PyTroch?
torch.det is not implemented for 'ComplexFloat'
Unfortunately it's not implemented currently. One way would be to implement your own version or simply use np.linalg.det.
Here is a short function which computes the determinant of a complex matrix that I wrote using LU-decomposition:
def complex_det(A):
def complex_diag(A):
return torch.view_as_complex(torch.stack((A.real.diag(), A.imag.diag()),dim=1))
#Perform LU decomposition to matrix A:
A_LU, pivots = A.lu()
P, A_L, A_U = torch.lu_unpack(A_LU, pivots)
#Det. of multiplied matrices is multiplcation of det.:
det = torch.prod(complex_diag(A_L)) * torch.prod(complex_diag(A_U)) * torch.det(P.real) #Could probably calculate det(P) [which is +-1] efficiently using Sylvester's determinant identity
return det
#Test it:
A = torch.view_as_complex(torch.randn(3,3,2))
complex_det(A)
As of version 1.8, PyTorch has native support for numpy-style torch.linalg operations. In particular, torch.linalg.det has support for cfloat and cdouble complex number data-types:
torch.linalg.det(input)
Computes the determinant of a square matrix input, or of each square matrix in a batched input.
This function supports float, double, cfloat and cdouble dtypes.

Scipy eigsh returning wrong results for complex input matrix

I am trying to find the eigenvalues and eigenvectors of a complex matrix with scipy.sparse.linalg.eigsh using its shift-invert mode. With just real numbers in the matrix I get the same result for the spicy.linalg.eigh solver, but when adding the imaginary parts the eigenvalues diverge. A tiny example:
import numpy as np
from scipy.linalg import eigh
from scipy.sparse.linalg import eigsh
n = 10
X = np.random.random((n, n)) - 0.5 + (np.random.random((n, n)) - 0.5) * 1j
X = np.dot(X, X.T) # create a symmetric matrix
evals_all, evecs_all = eigh(X)
evals_small, evecs_small = eigsh(X, 3, sigma=0, which='LM')
print(sorted(evals_all, key=abs))
print(sorted(evals_small, key=abs))
The prints in this case are for example
[0.041577858515751132, -0.084104744918533481, -0.58668240775486691, 0.63845672501004724, -1.2311727737115068, 1.5193345703630159, -1.8652302423152105, 1.9970059660853923, -2.6414593461321654, 2.8624290667460293]
[-0.017278543470343462, -0.32684893256215408, 0.34551438015659475]
whereas in the real case, the first three eigenvalues are identical.
I am aware that I'm passing a dense matrix to the sparse solver, but this is just intended as an example.
I am probably missing something obvious somewhere, but I'd be happy about some hints where to look. Thank you!
scipy is not checking your input if it's hermitian.
Doing it like proposed in the link:
if not np.allclose(X, np.asmatrix(X).H):
raise ValueError('expected symmetric or Hermitian matrix')
outputs:
ValueError: expected symmetric or Hermitian matrix
I think this is also indicated by those negative eigenvalues you see (but complex-based math is really not my speciality...).

logm function of hermitian matrix returns non-hermitian matrix

When I use the linear algebra module in scipy to calculate the matrix logarithm of a hermitian matrix, the matrix that it outputs isn't hermitian. I first define a vector using:
n = np.random.uniform(size = 3) + 1j*np.random.uniform(size = 3)
Then I define the respective hermitian matrix:
N = np.outer(n,n.conj())
However, linalg.logm(N) doesn't return a hermitian matrix. Why is this happening?
All but one eigenvalues of the random matrix are zero. Since functions on matrices can be written as functions on the eigenvalues of a matrix, I see why the logarithm has a problem there, because log(0) is not defined. Maybe the function doesn't see this problem and just returns garbage.
I guess that you just need to make sure that your random Hermitian matrix has nonzero eigenvalues.

Efficient numpy / lapack routine for product of inverse and sparse matrix?

I have a matrix B that is square and dense, and a matrix A that is rectangular and sparse.
Is there a way to efficiently compute the product B^-1 * A?
So far, I use (in numpy)
tmp = B.inv()
return tmp * A
which, I believe, makes us of A's sparsity. I was thinking about using the sparse method
numpy.sparse.linalg.spsolve, but this requires B, and not A, to be sparse.
Is there another way to speed things up?
Since the matrix to be inverted is dense, spsolve is not the tool you want. In addition, it is bad numerical practice to calculate the inverse of a matrix and multiply it by another - you are much better off using LU decomposition, which is supported by scipy.
Another point is that unless you are using the matrix class (I think that the ndarray class is better, this is something of a question of taste), you need to use dot instead of the multiplication operator. And if you want to efficiently multiply a sparse matrix by a dense matrix, you need to use the dot method of the sparse matrix. Unfortunately this only works if the first matrix is sparse, so you need to use the trick which Anycorn suggested of taking the transpose to swap the order of operations.
Here is a lazy implementation which doesn't use the LU decomposition, but which should otherwise be efficient:
B_inv = scipy.linalg.inv(B)
C = (A.transpose().dot(B_inv.transpose())).transpose()
Doing it properly with the LU decomposition involves finding a way to efficiently multiply a triangular matrix by a sparse matrix, which currently eludes me.

Categories