Adding smaller eigenvalues option in cupy.scipy.sparse.linalg.eigsh
Added option for extracting eigendecomposition for smaller eigenvalues for the eigsh function.
@@ -28,7 +28,9 @@ def eigsh(a, k=6, *, which='LM', ncv=None, maxiter=None, tol=0,
k (int): The number of eigenvalues and eigenvectors to compute. Must be
``1 <= k < n``.
which (str): 'LM' or 'LA'. 'LM': finds ``k`` largest (in magnitude)
- eigenvalues. 'LA': finds ``k`` largest (algebraic) eigenvalues.
+ eigenvalues. 'LA': finds ``k`` largest (algebraic) eigenvalues
+ 'LM' or 'LA'. 'SM': finds ``k`` smallest (in magnitude)
+ eigenvalues. 'SA': finds ``k`` smallest (algebraic) eigenvalues.
ncv (int): The number of Lanczos vectors generated. Must be
``k + 1 < ncv < n``. If ``None``, default value is used.
maxiter (int): Maximum number of Lanczos update iterations.
@@ -60,8 +62,8 @@ def eigsh(a, k=6, *, which='LM', ncv=None, maxiter=None, tol=0,
raise ValueError('k must be greater than 0 (actual: {})'.format(k))
if k >= n:
raise ValueError('k must be smaller than n (actual: {})'.format(k))
- if which not in ('LM', 'LA'):
- raise ValueError('which must be \'LM\' or \'LA\' (actual: {})'
+ if which not in ('LM', 'LA','SA','SM'):
+ raise ValueError('which must be \'LM\' , \'LA\', \'SM\',\'SA\' (actual: {})'
''.format(which))
if ncv is None:
ncv = min(max(2 * k, k + 32), n - 1)
@@ -283,6 +285,12 @@ def _eigsh_solve_ritz(alpha, beta, beta_k, k, which):
idx = numpy.argsort(numpy.absolute(w))
wk = w[idx[-k:]]
sk = s[:, idx[-k:]]
+ elif which == 'SA':
+ idx = numpy.argsort(w)
+ elif which == 'SM':
+ idx = numpy.argsort(numpy.absolute(w))
+ wk = w[idx[0:k]]
+ sk = s[:, idx[0:k]]
return cupy.array(wk), cupy.array(sk)
