A python package to compute eigenvalues using the dual applications of Chebyshev polynomials algorithm. The algorithm is described in SciPost Phys. 11, 103 (2021).
This package implements an algorithm that computes the eigenvalues of hermitian linear operators within a given window. Besides the original algorithm, we also provide a way to deal with degeneracies systematically, and remove the need of prior estimations of the number of eigenvalues. The algorithm is useful for large, sufficiently sparse matrices.
This is an experimental version, so use at your own risk.
- Installation
- The algorithm
- First application of Chebyshev polynomials
- Second application of Chebyshev polynomials
- Dealing with degeneracies
- How do we save memory?
- Usage example
pip install pydacp
We write an arbitrary vector in terms of the eigenvectors of an operator
where
with
Thus, it removes the vector components with eigenvalues outside the window
The Chebyshev filter is less effective at the edge of the interval
$[-a, a]$ . As a consequence, incorrect eigenvalues leak into the window. We remove them by running the algorithm twice and identifying unstable values.
Now we have one vector
with $E'c = (E{max} + E_{min})/2$, and $E'0 = (E{max} - E_{min})/2$.
One can generate a complete basis within the desired subspace as:
with
In fact, we can span the basis above by, instead of computing trigonometric functions of a matrix, computing several Chebyshev polynomials of
The remaininig problem is that we do not know the value of
The final set of vectors
The method above is not able to resolve degeneracies: each random vector can only span a non-degenerate subspace of
To make sure a complete basis is generated, after the end of each Chebyshev evolution, we check the orthogonality of the subspace by performing a QR decomposition of the overlap matrix
DACP provides an algorithm to directly compute the projected and overlap matrices without storing all vectors. This is possible because of two properties combined:
$[T_i(\mathcal{H}), \mathcal{H}]=0$ $T_i(\mathcal{H})T_j(\mathcal{H}) = \frac12 \left(T_{i+j}(\mathcal{H}) + T_{|i-j|}(\mathcal{H}) \right)~.$
Combining those two properties, we only need to store the filtered vectors from previous runs
and
Because there reduction of memory usage when the eigenvectors are computed, we do not include an eigenvector calculator. For this particular use we recommend other established sparse methods such as Arnoldi.
from dacp.dacp import eigvalsh, eigh
# Generate a random matrix with size 100 x 100
N = 100
matrix = random_values((N,N)) + random_values((N,N))*1j
matrix = (matrix.conj().T + matrix)/(2*np.sqrt(N))
matrix = csr_matrix(matrix)
# Compute eigenvalues
eigvals = eigvalsh(matrix, window_size)