Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .jules/bolt.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@
## 2025-11-01 - [Avoid Temporary Array Allocations in Reductions]
**Learning:** In loops over parameters like temperature (`thermal_scan`), doing `np.sum(arr1 * arr2)` where array sizes match the system Hilbert space creates huge temporary arrays per loop iteration. Memory allocation dominates execution time.
**Action:** Use `np.dot(arr1, arr2)` instead of `np.sum(arr1 * arr2)` for 1D arrays to evaluate reductions in C-level BLAS/NumPy functions, bypassing Python/NumPy array allocations and boosting performance significantly with less peak memory.

## 2025-11-01 - [Vectorize Lattice Fourier Transforms]
**Learning:** O(N^2) Python loops computing phase factors for lattice transformations \sum_{i,j} G_{ij} \exp(i k \cdot (r_i - r_j)) are extremely slow (taking ~100+ ms for N=200).
**Action:** Vectorize this by replacing the loop with matrix algebra. Since \exp(i k \cdot (r_i - r_j)) = \exp(i k \cdot r_i) \exp(-i k \cdot r_j), we can construct a 1D phase array `phases = np.exp(1j * np.dot(r_vectors, k))` and then compute the final result as the quadratic form `phases @ G @ phases.conj()`. This reduces execution time to sub-milliseconds, bypassing the Python overhead entirely.
15 changes: 6 additions & 9 deletions physics/spectral/greens_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,15 +127,12 @@ def fourier_transform_lattice(greens_function: Array, lattice_k_vectors: Array,
greens_function = np.asarray(greens_function, dtype=complex)
k = np.asarray(lattice_k_vectors)
r_vectors = np.asarray(lattice_r_vectors)
N = len(r_vectors)
result = 0.0 + 0.0j
for i in range(N):
r_i = r_vectors[i]
for j in range(N):
r_j = r_vectors[j]
phase = np.exp(1j * np.dot(k, r_i - r_j))
result += greens_function[i, j] * phase
return result

# Vectorized: \sum_{i,j} G_{ij} exp(i k\cdot (r_i - r_j))
# Let P_i = exp(i k \cdot r_i). Then phase_{i,j} = P_i * P_j^*
# G(k) = P^T G P^*
phases = np.exp(1j * np.dot(r_vectors, k))
return complex(phases @ greens_function @ phases.conj())

def fourier_transform_lattice_translational(greens_function: Array, lattice_k_vectors: Array, lattice_r_vectors: Array) -> Array:
r"""
Expand Down