Skip to content

Commit

Permalink
copy and modify docs from pymablock
Browse files Browse the repository at this point in the history
  • Loading branch information
antoniolrm committed Feb 15, 2024
1 parent 3c795e1 commit a9f9844
Show file tree
Hide file tree
Showing 10 changed files with 565 additions and 0 deletions.
12 changes: 12 additions & 0 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
version: 2

build:
os: ubuntu-22.04
tools:
python: "mambaforge-4.10"

conda:
environment: docs/environment.yml

sphinx:
configuration: docs/source/conf.py
21 changes: 21 additions & 0 deletions docs/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Minimal makefile for Sphinx documentation
#

# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = source
BUILDDIR = build

# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

.PHONY: help Makefile

# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

21 changes: 21 additions & 0 deletions docs/environment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: pydacp-docs

channels:
- conda-forge

dependencies:
- python=3.11
- myst-nb
- numpy
- scipy
- matplotlib-base
- sphinx-togglebutton
- sphinx-copybutton
- pip
- git
- make
- pip:
- sphinx-book-theme>=1.1.0
- sphinx-tippy
- ..

37 changes: 37 additions & 0 deletions docs/make.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
@ECHO OFF

pushd %~dp0


REM Command file for Sphinx documentation

if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=source
set BUILDDIR=build

if "%1" == "" goto help

%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from

echo.https://www.sphinx-doc.org/
exit /b 1
)

%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end

:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%

:end
popd
10 changes: 10 additions & 0 deletions docs/source/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.0.0] - 2024-02-15

- First release of _pyDACP_.
5 changes: 5 additions & 0 deletions docs/source/_static/local.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.tippy-box {
background-color:var(--pst-color-surface);
color:var(--pst-color-text-base);
border: 1px solid var(--pst-color-border);
}
25 changes: 25 additions & 0 deletions docs/source/_templates/layout.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{% extends "!layout.html" %}

{% block extrahead %}
{{ super() }}
<!-- Matomo -->
<script>
var _paq = window._paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="https://piwik.kwant-project.org/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '8']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
</script>
<!-- End Matomo Code -->
{% endblock %}

{# Replace "pyDAC" with a stylized version for prettiness #}
{% block content %}
{{ super() | replace('pyDACP', '<b style="color:#8b4aa0ff;">pyDACP</b>') }}
{% endblock %}
116 changes: 116 additions & 0 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html

# -- Path setup --------------------------------------------------------------

# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import os
import sys

import dacp # noqa: F401

package_path = os.path.abspath("../dacp")
# Suppress superfluous frozen modules warning.
os.environ["PYDEVD_DISABLE_FILE_VALIDATION"] = "1"
sys.path.insert(0, package_path)


# -- Project information -----------------------------------------------------

project = "pyDACP"
copyright = "2023, Pymablock developers"
author = "Pymablock developers"
gitlab_url = "https://gitlab.kwant-project.org/qt/pyDACP"

# The full version, including alpha/beta/rc tags
release = dacp.__version__
major, minor = dacp.__version_tuple__[:2]
version = f"{major}.{minor}"

# -- General configuration ---------------------------------------------------

# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
"sphinx.ext.napoleon",
"sphinx.ext.autodoc",
"sphinx.ext.autosummary",
"sphinx.ext.mathjax",
"sphinx.ext.viewcode",
"sphinx.ext.intersphinx",
"myst_nb",
"sphinx_togglebutton",
"sphinx_copybutton",
"sphinx_tippy",
]
myst_enable_extensions = [
"dollarmath",
"amsmath",
"substitution",
"colon_fence",
]
nb_execution_timeout = 120
nb_execution_raise_on_error = True
autodoc_typehints = "description"
autodoc_typehints_format = "short"

intersphinx_mapping = {
"python": ("https://docs.python.org/3", None),
"kwant": ("https://kwant-project.org/doc/1", None),
"numpy": ("https://numpy.org/doc/stable/", None),
"scipy": ("https://docs.scipy.org/doc/scipy/", None),
"sympy": ("https://docs.sympy.org/latest/", None),
}

default_role = "autolink"

# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = []

autoclass_content = "both"
# -- Options for HTML output -------------------------------------------------

# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = "sphinx_book_theme"

html_theme_options = {
"repository_url": "https://gitlab.kwant-project.org/qt/pyDACP",
"use_repository_button": True,
"use_issues_button": True,
"use_edit_page_button": True,
"path_to_docs": "docs/source",
"repository_branch": "main",
"use_download_button": True,
"home_page_in_toc": True,
"logo": {
"image_light": "_static/logo.svg",
"image_dark": "_static/logo_dark.svg",
},
"extra_footer": (
'<hr><div id="matomo-opt-out"></div>'
'<script src="https://piwik.kwant-project.org/index.php?'
"module=CoreAdminHome&action=optOutJS&divId=matomo-opt-out"
'&language=auto&showIntro=1"></script>'
),
}


# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ["_static"]
html_css_files = ["local.css"]
123 changes: 123 additions & 0 deletions docs/source/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# pyDACP

A python package to compute eigenvalues using the dual applications of Chebyshev polynomials algorithm. The algorithm is described in [SciPost Phys. 11, 103 (2021)](https://scipost.org/SciPostPhys.11.6.103).

This package implements an algorithm that computes the eigenvalues of hermitian linear opeators 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.

## Content

* Instalation
* The algorithm
+ First application of Chebyshev polynomials
+ Second application of Chebyshev polynomials
+ Dealing with degeneracies
- Eigenvalues + eigenvectors method (under development)
- Eigenvalues-only method
* Usage example

## Installation

After cloning the repository, simply run:
```
pip install .
```

## The algorithm

### First application of Chebyshev polynomials

We write an arbitrary vector in terms of the eigenvectors of the Hamiltonian $`\mathcal{H}`$:
```math
|r\rangle = \sum_{E_i \in [-a, a]} \alpha_i |\psi_i\rangle + \sum_{E_i \notin [-a, a]} \beta_i |\phi_i\rangle.
```

The idea now is to obtain an energy-filtered vector $`|r_E\rangle`$ by removing the second term of the equation above.
To do so, we define the operator
```math
\mathcal{F} := \frac{\mathcal{H}^2 - E_c}{E_0}
```
with $`E_c = E_{max}^2 + a^2`$, and $`E_0 = E_{max}^2 - a^2`$.

For a large enough $`k`$, the $`k`$-th order Chebyshev polynomial of $`\mathcal{F}`$ is
```math
T_k(\mathcal{F}) \approx e^{\frac{2k}{E_{max}}\sqrt{a^2 - \mathcal{H}^2}},
```
which indeed filters states within the $`[-a, a]`$ window. So,
```math
T_k(\mathcal{F})|r\rangle = |r_E\rangle.
```

### Second application of Chebyshev polynomials

Now we have one single vector $`|r_E\rangle`$ within the energy window we want.
And we use again Chebyshev polynomials to span the full basis of the subspace $`\mathcal{L}`$
with $`E \in [-a, a]`$.
For that, we define a second operator, $`\mathcal{G}`$,
which is simply the rescaled Hamiltonian such that all eigenvalues are within $`[-1, 1]`$:
```math
\mathcal{G} = \frac{\mathcal{H} - E_c'}{E_0'}
```
with $`E'_c = (E_{max} + E_{min})/2`$, and $`E'_0 = (E_{max} - E_{min})/2`$.

A full basis is then simply:
```math
\left\lbrace I, \sin(X), \cdots, \sin(nX), \cos(X), \cdots, \cos(nX)\right\rbrace |r_E\rangle.
```
with $`X:=\pi\mathcal{G}/a_r`$, and $`a_r = a/\mathrm{max}(|E_{max}|, |E_{min}|)`$.

In fact, we can span the basis above by, instead of computing trigonometric functions of a matrix, computing simply several Chebyshev **polynomials** of $`\mathcal{G}`$.

The remaininig problem is that we don't know the value of $`n`$, so we must (over)estimate the dimension of this subspace.
And guess what: we use **again** Chebyshev polynomials by performing a low-resolution KPM.
Since we overestimate the dimension, we also want to get rid of linearly dependent vectors, so we do SVD.

The final set of vectors $`\lbrace \psi_k \rbrace`$ is then used to compute the projected low-energy Hamiltonian:
```math
H_{\text{eff}}^{ij} = \langle \psi_i |\mathcal{H}|\psi_j\rangle.
```

### Dealing with degeneracies

The method above is not able to resolve degeneracies: each random vector can only span a non-degenerate subspace of $`\mathcal{L}`$.
Therefore, we solve the problem by adding more random vectors.
The library has two different implementations to solve degeneracies, which defines the methods that return or not the eigenvectors.

#### Eigenvalues + eigenvectors method (under development)

To make sure a complete basis is generated, after the end of each Chebolution&trade run finishes, we diagonalize the set of eigenvectors by performing QR-decomposition of $`[\psi_k]`$:
```math
[\psi_k] = QR
```
and take $`Q`$ as the new basis.
When adding new random vectors no longer increase the subspace dimension, the projected matrix
```math
H_{\text{eff}}^{ij} = \langle \psi_i |\mathcal{H}|\psi_j\rangle.
```
is computed.

#### Eigenvalues-only method

A second option for the DACP algorithm is to directly compute the projected and overlap matrices without storing all vectors.
However, when dealing with degeneracies, it means that we no longer orthogonalize the set $`\{\psi_k\}`$.
Instead, we perform QR decomposition of the overlap matrix, and similarly to the previous case, we stop when the subspace dimension stops increasing.

## Usage example

* Eigenvalues-only
```python
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)
```

* Eigenvalues and eigenvectors
```python
eigvals, eigvecs = eigh(matrix, window_size)
```
Loading

0 comments on commit a9f9844

Please sign in to comment.