Python wrapper for epsteinlib
Project description
EpsteinLib
Version 0.3
Authors: Andreas A. Buchheit, Jonathan Busse, Ruben Gutendorf, DevOps: Jan Schmitz
Contact: buchheit@num.uni-sb.de
EpsteinLib is a C library designed for the fast and efficient computation of the Epstein zeta function for arbitrary multidimensional lattices. In addition to the C library, we also offer a Python package, epsteinlib, which can be easily installed via pip.
Originally studied by Epstein [1,2], the Epstein zeta function forms the basis for computing general multidimensional lattice sums in classical and quantum physics applications [3]. Together with its regularization, it serves as the central ingredient in the singular Euler-Maclaurin (SEM) expansion, which generalizes the 300-year-old Euler summation formula to lattice sums in higher dimensions with physically relevant power-law interactions [4-5]. An efficiently computable representation of the Epstein zeta function is provided in [6,7].
For a $d$-dimensional lattice $\Lambda=A\mathbb Z^d$, with $A\in \mathbb R^{d\times d}$ regular, $x,y \in \mathbb R^d$, and $\nu \in \mathbb C$, the Epstein zeta function is defined by the Dirichlet series
$$ Z_{\Lambda,\nu}\begin{vmatrix} x \ y \end{vmatrix} = \sum_{z \in \Lambda}{}^{'} \frac{e^{-2\pi i y \cdot z}}{\left| x- z\right|^\nu},\quad \mathrm{Re}(\nu)>d, $$
which can be meromorphically continued to $\nu \in \mathbb C$. Here, the primed sum excludes the case $z = x.$
The Epstein zeta function is implemented in this library as
double complex epsteinZeta(double nu, unsigned int dim, const double *A, const double *x, const double *y);
In the Python package, it is implemented as
def epstein_zeta(nu: float | int, A: NDArray[np.float64], x: NDArray[np.float64], y: NDArray[np.float64]) -> complex
and evalutates to full precision over the whole parameter range up to ten dimensions.
In addition, this library includes the regularized Epstein zeta function, which is analytic around $y=0$, and is defined via
$$ Z_{\Lambda,\nu}^{\mathrm{reg}}\begin{vmatrix} x \ y \end{vmatrix} = e^{2\pi i x\cdot y} Z_{\Lambda,\nu}\left|\begin{aligned} x \ y \end{aligned}\right| -\frac{\hat{s}(y)}{V_{\Lambda}}, $$
where $V_{\Lambda}=|\det A|$ is the volume of the elementary lattice cell,
$$ \hat{s}(y)=-\pi^{\nu-\frac{d}{2}} \frac{\Gamma((d-\nu)/2)}{\Gamma(\nu/2)}|y|^{\nu-d} $$
is the distributional Fourier transform of $\vert z \vert^{-\nu}$, where $\Gamma$ denotes the gamma function.
In this library, the regularized Epstein zeta function is included as
double complex epsteinZetaReg(double nu, unsigned int dim, const double *A, const double *x, const double *y);
or
def epstein_zeta_reg(nu: float | int, A: NDArray[np.float64], x: NDArray[np.float64], y: NDArray[np.float64]) -> complex
Installation
Install our required dependencies: meson, ninja, pkg-config, python3 e.g. with
# Archlinux
pacman -S meson ninja pkgconf python
# MacOS
brew install meson ninja pkg-config python3
Installing only the Python wrapper with pip
# Create a virtualenvironment and activate it if you are not already inside one.
python3 -m venv .venv && source .venv/bin/activate
# Install epsteinlib
python -m pip install epsteinlib
Installing the C library and the Python wrapper with meson
- git clone https://github.com/epsteinlib/epsteinlib.git
cd epsteinlib
meson setup build
meson compile -C build
- To test the library, run
meson test -C build
Proceed either with system-wide or local installation
System-wide installation
Meson supports a system-wide installation of the compiled library. After that, you can use #include <epsteinZeta.h>
and link with gcc -lepsteinZeta
. This may require superuser rights.
-
To install system-wide:
meson install -C build
. -
Try to compile the sample program in
test/lattice_sum.c
with the commandgcc -o lattice_sum lattice_sum.c -lm -lepsteinZeta
. You may encounter the problem that the shared library cannot be found. In this case, you need to modify the environment variables. Please continue with the next step. Otherwise, you are done. -
Update the environment variables to correctly locate the shared library at runtime. You can find
/path/to/library
in the output given bymeson install
.
# Linux
export $LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/library
# MacOS
export $DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:/path/to/library
Local installation
- Copy the header
include/epsteinZeta.h
and move the compiled librarybuild/src/libepsteinZeta.so
to places of your choice, e. g.
cp include/epsteinZeta.h /your/path/to/include
mv build/src/libepsteinZeta.so /your/path/to/library
- To test your library, try to compile
test/lattice_sum.c
with the commandgcc -o lattice_sum lattice_sum.c -lm -L/your/path/to/library -lepsteinZeta -I/your/path/to/include
.
View api documentation
See https://epsteinlib.github.io/epsteinlib/
Usage
Minimal working examples for calculating the Madelung constant in $3$ dimensions.
in C
// If the library is installed, compile with `gcc -o lattice_sum lattice_sum.c -lm -lepsteinZeta
// If the library is not installed, compile with `gcc -o lattice_sum lattice_sum.c -lm -L/path/to/library -lepsteinZeta -I/path/to/include
#include <complex.h>
#include <math.h>
#include <stdio.h>
#include "epsteinZeta.h"
int main() {
// Madelung constant found in literature
double madelungRef = -1.7475645946331821906362120355443974;
unsigned int dim = 3;
double m[] = {1, 0, 0, 0, 1,
0, 0, 0, 1}; // identity matrix for whole numbers
double x[] = {0, 0, 0}; // no shift
double y[] = {0.5, 0.5, 0.5}; // alternating sum
double nu = 1.0;
double madelung = creal(epsteinZeta(nu, dim, m, x, y));
printf("Madelung sum in 3 dimensions:\t %.16lf\n", creal(madelung));
printf("Reference value:\t\t %.16lf\n", madelungRef);
printf("Relative error:\t\t\t +%.2e\n",
fabs(madelungRef - madelung) / fabs(madelungRef));
return fabs(madelung - madelungRef) > pow(10, -14);
}
in Python
import numpy as np
from epsteinlib import epstein_zeta
madelung_ref = -1.7475645946331821906362120355443974
dim = 3
a = np.identity(dim) # identity matrix for whole numbers
x = np.zeros(dim) # no shift
y = np.full(dim, 0.5) # alternating sum
nu = 1.0
madelung = np.real(epstein_zeta(nu, a, x, y))
print(f"Madelung sum in 3 dimensions:\t {madelung:.16f}")
print(f"Reference value:\t\t {madelung_ref:.16f}")
print(f"Relative error:\t\t\t +{abs(madelung_ref - madelung) / abs(madelung_ref):.2e}")
Development environment
We provide a nix devshell to have a reproducible development environment with the same dependencies across different operating systems. Once you have installed and configured nix starting developing is as easy as running nix develop
.
Nix installation instructions
Nix based - recommended
sudo tee -a /etc/nix/nix.conf <<CFG
max-jobs = auto
#max-jobs = 1
experimental-features = nix-command flakes auto-allocate-uids
auto-allocate-uids = true
auto-optimise-store = true
CFG
systemctl enable --now nix-daemon.socket
usermod -a -G nix-users <your username>
- Reboot
cd <path/to/repo>
nix develop
ornix run -- <your args>
Nix-Portable based - if you do not have root rights
- Install nix-portable:
mkdir -p ~/.local/bin
cd ~/.local/bin
curl -L https://github.com/DavHau/nix-portable/releases/latest/download/nix-portable-$(uname -m) > ./nix-portable
chmod +x ./nix-portable
cat > ./nix <<NIX
#!/usr/bin/env bash
CURDIR=\$(dirname "\$(readlink -f "\$0")")
NP_RUNTIME=bwrap "\$CURDIR/nix-portable" nix \$@
NIX
chmod +x ./nix
export PATH=~/.local/bin:"$PATH"
cd ~
nix run 'nixpkgs#hello'
- Configure nix.conf by executing
tee -a ~/.nix-portable/conf/nix.conf <<CFG
max-jobs = auto
#max-jobs = 1
auto-optimise-store = true
CFG
- Add .local/bin permanently to your PATH
echo 'PATH=$HOME/.local/bin:"$PATH"' >> ~/.env
echo 'export $(envsubst < .env)' | tee -a .bashrc >> .zshrc
cd <path/to/repo>
nix develop
ornix run -- <your args>
Contributing
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
References
[1] P. Epstein. “Zur Theorie allgemeiner Zetafunctionen”. Math. Ann. 56 (1903), pp. 615–644.
[2] P. Epstein. “Zur Theorie allgemeiner Zetafunktionen. II”. Math. Ann. 63 (1906), pp. 205–216
[3] Andreas A. Buchheit et al. “Exact Continuum Representation of Long-range Interacting Systems and Emerging Exotic Phases in Unconventional Superconductors”, Phys. Rev. Research 5, 043065 (2023)
[4] Andreas A Buchheit and Torsten Keßler. “On the Efficient Computation of Large Scale Singular Sums with Applications to Long-Range Forces in Crystal Lattices”. J. Sci. Comput. 90.1 (2022), pp. 1–20
[5] Andreas A Buchheit and Torsten Keßler. “Singular Euler–Maclaurin expansion on multidimensional lattices”. Nonlinearity 35.7 (2022), p. 3706
[6] R. Crandall. “Unified algorithms for polylogarithm, L-series, and zeta variants”. Algorithmic Reflections: Selected Works. PSIpress, 2012
[7] Andreas A. Buchheit, Torsten Keßler, and Kirill Serkh. "On the computation of lattice sums without translational invariance". arXiv preprint arXiv:2403.03213.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
File details
Details for the file epsteinlib-0.3.0.tar.gz
.
File metadata
- Download URL: epsteinlib-0.3.0.tar.gz
- Upload date:
- Size: 90.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.0.0 CPython/3.11.9
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 4d435b90aff38b5d397ff4a3df82666f8f2472c9eb555a20fc530c9082f126e3 |
|
MD5 | c6bd770248561c3136fcd598801990be |
|
BLAKE2b-256 | 5c428a4441fc69eade89e2c1e544ed974b252a6b9fd9055a29fd6e6784714a89 |