solver

Eigensolvers with a few extra computation methods

The Solver class is the main interface for dealing with eigenvalue problems. It is made to work specifically with pybinding’s Model objects, but it may use any eigensolver algorithm under the hood.

A few different algorithms are provided out of the box: the lapack(), arpack() and feast() functions return concrete Solver implementation using the LAPACK, ARPACK and FEAST algorithms, respectively.

The Solver may easily be extended with new eigensolver algorithms. All that is required is a function which takes a Hamiltonian matrix and returns the computed eigenvalues and eigenvectors. See _SolverPythonImpl for example.

Classes

Solver(impl) Computes the eigenvalues and eigenvectors of a Hamiltonian matrix

Functions

arpack(model, k[, sigma]) ARPACK Solver implementation for sparse matrices
feast(model, energy_range, initial_size_guess) FEAST Solver implementation for sparse matrices
lapack(model, **kwargs) LAPACK Solver implementation for dense matrices
class Solver(impl: _pybinding.Solver)

Computes the eigenvalues and eigenvectors of a Hamiltonian matrix

This the common interface for various eigensolver implementations. It should not be created directly, but via the specific functions: lapack(), arpack() and feast(). Those functions will set up their specific solver strategy and return a properly configured Solver object.

calc_bands(k0, k1, *ks, step=0.1)

Calculate the band structure on a path in reciprocal space

Parameters:
k0, k1, *ks : array_like

Points in reciprocal space which form the path for the band calculation. At least two points are required.

step : float, optional

Calculation step length in reciprocal space units. Lower step values will return more detailed results.

Returns:
Bands
calc_dos(energies, broadening)

Calculate the density of states as a function of energy

\[\text{DOS}(E) = \frac{1}{c \sqrt{2\pi}} \sum_n{e^{-\frac{(E_n - E)^2}{2 c^2}}}\]

for each \(E\) in energies, where \(c\) is broadening and \(E_n\) is eigenvalues[n].

Parameters:
energies : array_like

Values for which the DOS is calculated.

broadening : float

Controls the width of the Gaussian broadening applied to the DOS.

Returns:
Series
calc_eigenvalues(map_probability_at=None)

Return an Eigenvalues result object with an optional probability colormap

While the eigenvalues property returns the raw values array, this method returns a result object with more data. In addition to the energy states, this result may show a colormap of the probability density for each state at a single position.

Parameters:
map_probability_at : array_like, optional

Cartesian position where the probability density of each energy state should be calculated.

Returns:
Eigenvalues
calc_ldos(energies, broadening, position, sublattice='', reduce=True)

Calculate the local density of states as a function of energy at the given position

\[\text{LDOS}(E) = \frac{1}{c \sqrt{2\pi}} \sum_n{|\Psi_n(r)|^2 e^{-\frac{(E_n - E)^2}{2 c^2}}}\]

for each \(E\) in energies, where \(c\) is broadening, \(E_n\) is eigenvalues[n] and \(r\) is a single site position determined by the arguments position and sublattice.

Parameters:
energies : array_like

Values for which the DOS is calculated.

broadening : float

Controls the width of the Gaussian broadening applied to the DOS.

position : array_like

Cartesian position of the lattice site for which the LDOS is calculated. Doesn’t need to be exact: the method will find the actual site which is closest to the given position.

sublattice : str

Only look for sites of a specific sublattice, closest to position. The default value considers any sublattice.

reduce : bool

This option is only relevant for multi-orbital models. If true, the resulting LDOS will summed over all the orbitals at the target site and the result will be a 1D array. If false, the individual orbital results will be preserved and the result will be a 2D array with shape == (energy.size, num_orbitals).

Returns:
Series
calc_probability(n, reduce=1e-05)

Calculate the spatial probability density

\[\text{P}(r) = |\Psi_n(r)|^2\]

for each position \(r\) in system.positions where \(\Psi_n(r)\) is eigenvectors[:, n].

Parameters:
n : int or array_like

Index of the desired eigenstate. If an array of indices is given, the probability will be calculated at each one and a sum will be returned.

reduce : float, optional

Reduce degenerate states by summing their probabilities. Neighboring states are considered degenerate if their energy is difference is lower than the value of reduce. This is disabled by passing reduce=0.

Returns:
StructureMap
calc_spatial_ldos(energy, broadening)

Calculate the spatial local density of states at the given energy

\[\text{LDOS}(r) = \frac{1}{c \sqrt{2\pi}} \sum_n{|\Psi_n(r)|^2 e^{-\frac{(E_n - E)^2}{2 c^2}}}\]

for each position \(r\) in system.positions, where \(E\) is energy, \(c\) is broadening, \(E_n\) is eigenvalues[n] and \(\Psi_n(r)\) is eigenvectors[:, n].

Parameters:
energy : float

The energy value for which the spatial LDOS is calculated.

broadening : float

Controls the width of the Gaussian broadening applied to the DOS.

Returns:
StructureMap
clear()

Clear the computed results and start over

static find_degenerate_states(energies, abs_tolerance=1e-05)

Return groups of indices which belong to degenerate states

Parameters:
energies : array_like
abs_tolerance : float, optional

Examples

>>> energies = np.array([0.1, 0.1, 0.2, 0.5, 0.5, 0.5, 0.7, 0.8, 0.8])
>>> Solver.find_degenerate_states(energies)
[[0, 1], [3, 4, 5], [7, 8]]
>>> energies = np.array([0.1, 0.2, 0.5, 0.7])
>>> Solver.find_degenerate_states(energies)
[]
report(shortform=False) → str

Return a report of the last solve() computation

Parameters:
shortform : bool, optional

Return a short one line version of the report

set_wave_vector(k)

Set the wave vector for periodic models

Parameters:
k : array_like

Wave vector in reciprocal space.

solve()

Explicitly solve the eigenvalue problem right now

This method is usually not needed because the main result properties, eigenvalues and eigenvectors, will call this implicitly the first time they are accessed. However, since the solve() routine may be computationally expensive, it is useful to have the ability to call it ahead of time as needed.

eigenvalues

1D array of computed energy states

eigenvectors

2D array where each column represents a wave function

eigenvectors.shape == (system.num_sites, eigenvalues.size)

model

The tight-binding model attached to this solver

system

The tight-binding system attached to this solver (shortcut for Solver.model.system)

arpack(model, k, sigma=0, **kwargs)

ARPACK Solver implementation for sparse matrices

This solver is intended for large models with sparse Hamiltonian matrices. It only computes a small targeted subset of eigenvalues and eigenvectors. Internally this solver uses the scipy.sparse.linalg.eigsh() function for sparse Hermitian matrices.

Parameters:
model : Model

Model which will provide the Hamiltonian matrix.

k : int

The desired number of eigenvalues and eigenvectors. This number must be smaller than the size of the matrix, preferably much smaller for optimal performance. The computed eigenvalues are the ones closest to sigma.

sigma : float, optional

Look for eigenvalues near sigma.

**kwargs

Advanced arguments: forwarded to scipy.sparse.linalg.eigsh().

Returns:
Solver
feast(model, energy_range, initial_size_guess, recycle_subspace=False, is_verbose=False)

FEAST Solver implementation for sparse matrices

This solver is only available if the C++ extension module was compiled with FEAST.

Parameters:
model : Model

Model which will provide the Hamiltonian matrix.

energy_range : tuple of float

The lowest and highest eigenvalue between which to compute the solutions.

initial_size_guess : int

Initial user guess for number of eigenvalues which will be found in the given energy_range. This value may be completely wrong - the solver will auto-correct as needed. However, for optimal performance the estimate should be as close to 1.5 * actual_size as possible.

recycle_subspace : bool, optional

Reuse previously computed values as a starting point for the next computation. This improves performance when subsequent computations differ only slightly, as is the case for the band structure of periodic systems where the results change gradually as a function of the wave vector. It may hurt performance otherwise.

is_verbose : bool, optional

Show the raw output from the FEAST routine.

Returns:
Solver
lapack(model, **kwargs)

LAPACK Solver implementation for dense matrices

This solver is intended for small models which are best represented by dense matrices. Always solves for all the eigenvalues and eigenvectors. Internally this solver uses the scipy.linalg.eigh() function for dense Hermitian matrices.

Parameters:
model : Model

Model which will provide the Hamiltonian matrix.

**kwargs

Advanced arguments: forwarded to scipy.linalg.eigh().

Returns:
Solver