Skip to content

Commit 257b949

Browse files
skilledwolfSparshMishra97Copilot
authored
Various sign/indexing fixes and performance improvements (#2)
* - made changes that agree with the Julia version (analytic Exchange matrix elements) up to flipping b field sign (complex conjugate and a sign). * Did checks and compared Julia implementation results to revised package results * added additional comments * fix: Update README to include sigma notation for matrix elements and exchange kernels * added sigma feature to planewave part - next to do the same for exchange matrix element * fix: Update execution counts and correct sigma parameter in Checks_exchange_pwme notebook * fix: Remove unused code cell from Checks_exchange_pwme notebook * Edited Exchange matrix elements to include boths sign of sigma (B_z * charge carrier). - Added h5 file that has planewave and exchange elements for randomly sampled G points * Refactoring and performance improvements * fix: Correct LaTeX formatting for magnetic field sign in README * fix: Add missing line breaks in wavefunction section of README * fix: Add Sparsh Mishra as an author in CITATION.cff and pyproject.toml * Initial plan * Initial plan * Initial plan * Enhance docstring for get_exchange_kernels_GaussLegendre function Co-authored-by: skilledwolf <18141588+skilledwolf@users.noreply.github.com> * Remove commented-out code and placeholder comments from exchange_hankel.py Co-authored-by: skilledwolf <18141588+skilledwolf@users.noreply.github.com> * Initial plan * Address code review feedback on docstring clarity Co-authored-by: skilledwolf <18141588+skilledwolf@users.noreply.github.com> * Add sign_magneticfield validation to exchange_legendre.py Co-authored-by: skilledwolf <18141588+skilledwolf@users.noreply.github.com> * Add missing blank line before Notes section header Co-authored-by: skilledwolf <18141588+skilledwolf@users.noreply.github.com> * Initial plan * Address PR review comments: trailing whitespace, validation, docstring, grammar, unused variable Co-authored-by: skilledwolf <18141588+skilledwolf@users.noreply.github.com> --------- Co-authored-by: sparsh mishra <sparshmishra1@gmail.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: skilledwolf <18141588+skilledwolf@users.noreply.github.com>
1 parent 33e5554 commit 257b949

18 files changed

Lines changed: 1081 additions & 452 deletions

CITATION.cff

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ version: "0.1.0"
66
doi: 10.5281/zenodo.17646158
77
date-released: "2025-11-18"
88
authors:
9+
- family-names: Mishra
10+
given-names: Sparsh
911
- family-names: Wolf
1012
given-names: Tobias
1113
repository-code: "https://github.com/wolft/quantumhall_matrixelements"

README.md

Lines changed: 44 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,18 @@
44

55
Landau-level plane-wave form factors and exchange kernels for quantum Hall systems in a small, reusable package (useful for Hartree-Fock and related calculations). It provides:
66

7-
- Analytic Landau-level plane-wave form factors $F_{n',n}(\mathbf{q})$.
8-
- Exchange kernels $X_{n_1 m_1 n_2 m_2}(\mathbf{G})$.
7+
- Analytic Landau-level plane-wave form factors $F_{n',n}^\sigma(\mathbf{q})$.
8+
- Exchange kernels $X_{n_1 m_1 n_2 m_2}^\sigma(\mathbf{G})$.
99
- Symmetry diagnostics for verifying kernel implementations.
1010

1111
### Plane-Wave Landau-level Form Factors
12-
The plane-wave matrix element $F_{n',n}(\mathbf{q}) = \langle n' | e^{i \mathbf{q} \cdot \mathbf{R}} | n \rangle$ can be written as
12+
For $\sigma = \mathrm{sgn}(qB_z)$, where $q$ is the charge of the carrier and $B_z$ is the magnetic field direction,
13+
The plane-wave matrix element $F^\sigma_{n',n}(\mathbf{q}) = \langle n' | e^{i \mathbf{q} \cdot \mathbf{R}_\sigma} | n \rangle$ can be written as
1314

1415
$$
15-
F_{n',n}(\mathbf{q}) =
16+
F_{n',n}^\sigma(\mathbf{q}) =
1617
i^{|n-n'|}
17-
e^{i(n-n')\theta_{\mathbf{q}}}
18+
e^{i\sigma(n'-n)\theta_{\mathbf{q}}}
1819
\sqrt{\frac{n_{<}!}{n_{>}!}}
1920
\left( \frac{|\mathbf{q}|\ell_{B}}{\sqrt{2}} \right)^{|n-n'|}
2021
L_{n_<}^{|n-n'|}\left( \frac{|\mathbf{q}|^2 \ell_{B}^2}{2} \right)
@@ -26,7 +27,7 @@ where $n_< = \min(n, n')$, $n_> = \max(n, n')$, and $L_n^\alpha$ are the general
2627
### Exchange Kernels
2728

2829

29-
$$ X_{n_1 m_1 n_2 m_2}(\mathbf{G}) = \int \frac{d^2 q}{(2\pi)^2} V(q) F_{m_1, n_1}(\mathbf{q}) F_{n_2, m_2}(-\mathbf{q}) e^{i (\mathbf{q} \times \mathbf{G})_z \ell_B^2} $$
30+
$$ X_{n_1 m_1 n_2 m_2}^\sigma(\mathbf{G}) = \int \frac{d^2 q}{(2\pi)^2} V(q) F_{m_1, n_1}^\sigma(\mathbf{q}) F_{n_2, m_2}^\sigma(-\mathbf{q}) e^{i\sigma (\mathbf{q} \times \mathbf{G})_z \ell_B^2} $$
3031

3132
where $V(q)$ is the interaction potential. For the Coulomb interaction, $V(q) = \frac{2\pi e^2}{\epsilon q}$.
3233

@@ -92,11 +93,25 @@ X_coulomb = get_exchange_kernels(
9293

9394
For more detailed examples, see the example scripts under `examples/` and the tests under `tests/`.
9495

96+
## Magnetic-field sign
97+
98+
The public APIs expose a `sign_magneticfield` keyword that represents
99+
$\sigma = \mathrm{sgn}(q B_z)$, the sign of the charge–field product.
100+
The default `sign_magneticfield=-1` matches the package's internal convention
101+
(electrons in a positive $B_z$). Passing `sign_magneticfield=+1` returns the
102+
appropriate complex-conjugated form factors or exchange kernels for the
103+
opposite field direction without requiring any manual phase adjustments:
104+
105+
```python
106+
F_plusB = get_form_factors(Gs_dimless, thetas, nmax, sign_magneticfield=+1)
107+
X_plusB = get_exchange_kernels(Gs_dimless, thetas, nmax, method="hankel", sign_magneticfield=+1)
108+
```
109+
95110
## Citation
96111

97112
If you use the package `quantumhall-matrixelements` in academic work, you must cite:
98113

99-
> Tobias Wolf, *quantumhall-matrixelements: Quantum Hall Landau-Level Matrix Elements*, version 0.1.0, 2025.
114+
> Sparsh Mishra and Tobias Wolf, *quantumhall-matrixelements: Quantum Hall Landau-Level Matrix Elements*, version 0.1.0, 2025.
100115
> DOI: https://doi.org/10.5281/zenodo.17646158
101116
102117
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.17646158.svg)](https://doi.org/10.5281/zenodo.17646158)
@@ -105,25 +120,30 @@ A machine-readable `CITATION.cff` file is included in the repository and can be
105120

106121
## Backends and Reliability
107122

108-
The package provides three backends for computing exchange kernels, each with different performance and stability characteristics:
123+
The package provides two backends for computing exchange kernels:
124+
125+
1. **`gausslegendre` (Default)**
126+
- **Method**: Gauss-Legendre quadrature mapped from $[-1, 1]$ to $[0, \infty)$ via a rational mapping.
127+
- **Pros**: Fast and numerically stable for all Landau-level indices ($n$).
128+
- **Cons**: May require tuning `nquad` for extremely large momenta or indices ($n > 100$).
129+
- **Recommended for**: General usage, especially for $n \ge 10$.
109130

110-
1. **`gausslegendre` (Default)**:
111-
- **Method**: Gauss-Legendre quadrature mapped from $[-1, 1]$ to $[0, \infty)$ via a rational mapping.
112-
- **Pros**: Fast and numerically stable for all Landau level indices ($n$).
113-
- **Cons**: May require tuning `nquad` for extremely large momenta or indices ($n > 100$).
114-
- **Recommended for**: General usage, especially for large $n$ ($n \ge 10$).
131+
2. **`hankel`**
132+
- **Method**: Discrete Hankel transform.
133+
- **Pros**: High precision and stability.
134+
- **Cons**: Significantly slower than quadrature methods.
135+
- **Recommended for**: Reference calculations and verifying the Gauss–Legendre backend.
115136

116-
2. **`gausslag`**:
117-
- **Method**: Generalized Gauss-Laguerre quadrature.
118-
- **Pros**: Very fast for small $n$.
119-
- **Cons**: Numerically unstable for large $n$ ($n \ge 12$) due to high-order Laguerre polynomial roots.
120-
- **Recommended for**: Small systems ($n < 10$) where speed is critical.
137+
## Notes
138+
The following wavefunction is used to find all matrix elements:
121139

122-
3. **`hankel`**:
123-
- **Method**: Discrete Hankel transform.
124-
- **Pros**: High precision and stability.
125-
- **Cons**: Significantly slower than quadrature methods.
126-
- **Recommended for**: Reference calculations and verifying other backends.
140+
$$
141+
\Psi_{nX}^\sigma(x,y)
142+
= \frac{e^{i\sigma X y \ell_B^{-2}}}{\sqrt{L_y}}i^n\,
143+
\phi_{n}(x -X),
144+
\qquad
145+
X = \sigma k_y \ell_B^{2}.
146+
$$
127147

128148
## Development
129149

@@ -142,6 +162,6 @@ The package provides three backends for computing exchange kernels, each with di
142162

143163
## Authors and license
144164

145-
- Author: Dr. Tobias Wolf
165+
- Authors: Dr. Tobias Wolf, Sparsh Mishra
146166
- Copyright © 2025 Tobias Wolf
147167
- License: MIT (see `LICENSE`).

examples/compare_exchange_backends.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
"""Compare Gauss–Laguerre and Hankel exchange-kernel backends.
1+
"""Compare Gauss–Legendre and Hankel exchange-kernel backends.
22
33
For a small |G|ℓ_B grid and nmax=2, this script computes the exchange
4-
kernels using both the Gauss–Laguerre and Hankel backends and plots the
5-
relative difference of a representative diagonal element X_{0000}(G).
4+
kernels using both the Gauss–Legendre (default) and Hankel backends and plots
5+
the relative difference of a representative diagonal element X_{0000}(G).
66
"""
77
from __future__ import annotations
88

@@ -13,11 +13,11 @@
1313

1414

1515
def main() -> None:
16-
nmax = 2
17-
q = np.linspace(0.2, 3.0, 60)
16+
nmax = 10
17+
q = np.linspace(0.2, 20.0, 60)
1818
theta = np.zeros_like(q)
1919

20-
X_gl = get_exchange_kernels(q, theta, nmax, method="gausslag")
20+
X_gl = get_exchange_kernels(q, theta, nmax, method="gausslegendre")
2121
X_hk = get_exchange_kernels(q, theta, nmax, method="hankel")
2222

2323
# Focus on X_{0000}(G) as a simple representative component
@@ -32,12 +32,11 @@ def main() -> None:
3232
ax.plot(q, rel_diff, marker="o", linestyle="-")
3333
ax.set_xlabel(r"$|G| \ell_B$")
3434
ax.set_ylabel(r"relative difference")
35-
ax.set_title(r"Relative difference of $X_{0000}(G)$: Gauss–Laguerre vs Hankel")
35+
ax.set_title(r"Relative difference of $X_{0000}(G)$: Gauss–Legendre vs Hankel")
3636
ax.grid(True, alpha=0.3)
3737
fig.tight_layout()
3838
plt.show()
3939

4040

4141
if __name__ == "__main__":
4242
main()
43-

examples/plot_exchange_kernels_radial.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""Exchange kernel diagonal elements X_{nnnn}(G) vs |G|ℓ_B.
22
33
This example computes selected diagonal components of the exchange kernel
4-
using the Gauss–Laguerre backend and plots their real parts as a function
4+
using the Gauss–Legendre backend and plots their real parts as a function
55
of |G|ℓ_B.
66
"""
77
from __future__ import annotations
@@ -18,7 +18,7 @@ def main() -> None:
1818
q = np.linspace(0.2, 4.0, 80)
1919
theta = np.zeros_like(q)
2020

21-
X = get_exchange_kernels(q, theta, nmax, method="gausslag")
21+
X = get_exchange_kernels(q, theta, nmax, method="gausslegendre")
2222

2323
fig, ax = plt.subplots()
2424
for n in range(nmax):
@@ -31,7 +31,7 @@ def main() -> None:
3131

3232
ax.set_xlabel(r"$|G| \ell_B$")
3333
ax.set_ylabel(r"$\mathrm{Re}\,X_{nnnn}(G)$ (κ=1)")
34-
ax.set_title("Diagonal exchange kernels (Gauss–Laguerre backend)")
34+
ax.set_title("Diagonal exchange kernels (Gauss–Legendre backend)")
3535
ax.legend()
3636
ax.grid(True, alpha=0.3)
3737
fig.tight_layout()
@@ -40,4 +40,3 @@ def main() -> None:
4040

4141
if __name__ == "__main__":
4242
main()
43-

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ name = "quantumhall_matrixelements"
77
description = "Landau-level plane-wave form factors and exchange kernels for quantum Hall systems."
88
readme = "README.md"
99
authors = [
10-
{ name = "Tobias Wolf", email = "public@wolft.xyz" }
10+
{ name = "Tobias Wolf", email = "public@wolft.xyz" },
11+
{ name = "Sparsh Mishra" }
1112
]
1213
license = { text = "MIT" }
1314
requires-python = ">=3.10"

src/quantumhall_matrixelements/__init__.py

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,16 @@
1010
"""
1111
from __future__ import annotations
1212

13+
from importlib.metadata import PackageNotFoundError
14+
from importlib.metadata import version as _metadata_version
1315
from typing import TYPE_CHECKING
1416

1517
import numpy as np
16-
from importlib.metadata import PackageNotFoundError, version as _metadata_version
1718

18-
from .planewave import get_form_factors
19-
from .exchange_gausslag import get_exchange_kernels_GaussLag
19+
from .diagnostic import get_exchange_kernels_opposite_field, get_form_factors_opposite_field
2020
from .exchange_hankel import get_exchange_kernels_hankel
2121
from .exchange_legendre import get_exchange_kernels_GaussLegendre
22+
from .planewave import get_form_factors
2223

2324
if TYPE_CHECKING:
2425
from numpy.typing import NDArray
@@ -28,13 +29,13 @@
2829

2930

3031
def get_exchange_kernels(
31-
G_magnitudes: "RealArray",
32-
G_angles: "RealArray",
32+
G_magnitudes: RealArray,
33+
G_angles: RealArray,
3334
nmax: int,
3435
*,
3536
method: str | None = None,
3637
**kwargs,
37-
) -> "ComplexArray":
38+
) -> ComplexArray:
3839
"""Dispatcher for exchange kernels.
3940
4041
Parameters
@@ -49,26 +50,24 @@ def get_exchange_kernels(
4950
5051
- ``'gausslegendre'`` (default): Gauss-Legendre quadrature with rational mapping.
5152
Recommended for all nmax.
52-
- ``'gausslag'``: generalized Gauss–Laguerre quadrature.
53-
Fast for small nmax (< 10), but unstable for large nmax.
5453
- ``'hankel'``: Hankel-transform based implementation.
5554
5655
**kwargs :
5756
Additional arguments passed to the backend (e.g. ``nquad``, ``scale``).
57+
Common keywords include ``sign_magneticfield`` (±1) to select the
58+
magnetic-field orientation convention.
5859
5960
Notes
6061
-----
6162
Both backends return kernels normalized for :math:`\\kappa = 1`. Any
6263
physical interaction strength should be applied by the caller.
6364
"""
6465
chosen = (method or "gausslegendre").strip().lower()
65-
if chosen in {"gausslag", "gauss-lag", "gausslaguerre", "gauss-laguerre", "gl"}:
66-
return get_exchange_kernels_GaussLag(G_magnitudes, G_angles, nmax, **kwargs)
6766
if chosen in {"hankel", "hk"}:
6867
return get_exchange_kernels_hankel(G_magnitudes, G_angles, nmax, **kwargs)
6968
if chosen in {"gausslegendre", "gauss-legendre", "legendre", "leg"}:
7069
return get_exchange_kernels_GaussLegendre(G_magnitudes, G_angles, nmax, **kwargs)
71-
raise ValueError(f"Unknown exchange-kernel method: {method!r}. Use 'gausslegendre', 'gausslag', or 'hankel'.")
70+
raise ValueError(f"Unknown exchange-kernel method: {method!r}. Use 'gausslegendre' or 'hankel'.")
7271

7372

7473
try:
@@ -81,7 +80,6 @@ def get_exchange_kernels(
8180
__all__ = [
8281
"get_form_factors",
8382
"get_exchange_kernels",
84-
"get_exchange_kernels_GaussLag",
8583
"get_exchange_kernels_hankel",
8684
"get_exchange_kernels_GaussLegendre",
8785
"__version__",

src/quantumhall_matrixelements/_debug_symmetry.py

Lines changed: 0 additions & 50 deletions
This file was deleted.

0 commit comments

Comments
 (0)