qlat.field_analysis — Field Smearing, Sphere Summation, and Convolution¶
Source: qlat/qlat/field_analysis.py
Note: Update this document when updating the source file.
Outline¶
Overview¶
field_analysis provides utilities for analysing and transforming lattice
fields using Fourier-transform techniques. The main capabilities are:
Gaussian smearing — smear a density or observable field in coordinate space via multiplication in momentum space. Both 4D and spatial-only variants are supported.
Sphere summation — sum field values within a Euclidean-distance radius using an FFT-based convolution.
Field convolution — compute the cross-correlation of two complex fields via FFT.
Step-based smearing — iterative nearest-neighbour smearing that converges to a Gaussian for many steps. Both a local (single-node) and a distributed variant are provided.
All Fourier operations use qlat.mk_fft and exploit the convolution
theorem: convolution in coordinate space equals pointwise multiplication
in momentum space.
Smear functions are named object-first (field_smear, field_smear_step,
mk_field_smear_mom_kernel*), the iteration count is num_step (the last
positional parameter, default 1), and every smearing function returns a
new field without modifying its input.
Shift Index Utilities¶
mk_shift_xg_idx_arr¶
mk_shift_xg_idx_arr(
total_site: tuple, xg_shift: tuple, geo: Geometry | None = None
) -> np.ndarray
Build an index array that maps each site to the site shifted by
xg_shift (with periodic boundary conditions). With geo=None the run’s
global geometry is used (the historical behavior); passing geo expresses
the result in geo’s local index order, so the helper also works for a
rank-local geometry under MPI. Every shifted site must be local to geo,
and eo != 0 geometries are rejected.
Parameter |
Type |
Description |
|---|---|---|
|
|
Lattice dimensions, e.g. |
|
|
Shift in each direction |
|
|
Geometry whose local index order is used; |
Returns an integer np.ndarray of shape (geo.local_volume(),) suitable for
advanced indexing: field[shift_idx] yields the shifted field.
Results are cached (up to 16 entries), keyed on the full geometry so a cached array is never reused for a different geometry.
Step-Based Smearing¶
field_smear_step_local¶
field_smear_step_local(field: Field, coef: float, num_step: int = 1) -> Field
Iterative nearest-neighbour smearing using local index arrays (no MPI communication). At each step, the field value at each site is mixed with the average of its 8 nearest neighbours (positive and negative shifts in all 4 directions).
Parameter |
Type |
Default |
Description |
|---|---|---|---|
|
|
— |
Input field (at least complex type) |
|
|
— |
Smearing coefficient (0 = no smearing, 1 = full average) |
|
|
|
Number of smearing iterations |
Returns a new field; the input is not modified.
No communication; rank-local geometry required. This function builds
local index arrays and never performs communication, so it is correct whenever
every site of the field’s lattice is held by the calling rank — for example a
replicated single-node geometry built with
q.Geometry(0, q.Coordinate([1, 1, 1, 1]), node_site) — no matter how many MPI
ranks are running. For a distributed lattice use field_smear_step instead:
it is the shift-based MPI-capable variant (it uses field.shift). If a
shifted neighbour is not local to the rank, field_smear_step_local now raises
an error instead of silently mis-indexing the field.
field_smear_step¶
field_smear_step(field: Field, coef: float, num_step: int = 1) -> Field
Distributed variant of nearest-neighbour smearing. Uses
field.shift() which supports MPI communication. The smearing
kernel is identical to field_smear_step_local.
Returns a new field; the input is not modified.
Momentum-Space Kernels¶
mk_field_smear_mom_kernel¶
mk_field_smear_mom_kernel(total_site: tuple, radius: float) -> FieldRealD
Build the 4D Gaussian smearing kernel in momentum space:
where
If radius == np.inf, the kernel is a delta function at
Results are cached (up to 128 entries).
mk_field_smear_mom_kernel_spatial¶
mk_field_smear_mom_kernel_spatial(total_site: tuple, radius: float) -> FieldRealD
Build the spatial-only Gaussian smearing kernel:
The temporal direction is not smeared. If radius == np.inf, the
kernel selects the spatial zero mode.
Results are cached (up to 128 entries).
mk_sphere_sum_mom_kernel¶
mk_sphere_sum_mom_kernel(
total_site: tuple,
radius: float,
is_only_spatial: bool,
) -> FieldRealD
Build the momentum-space kernel for sphere summation. In coordinate
space this corresponds to a sharp cutoff: sum all sites within
Euclidean distance radius. The kernel is constructed by FFT of a
real-space indicator function.
If radius == np.inf, every site contributes equally.
Results are cached (up to 128 entries).
Fourier-Based Operations¶
sphere_sum_field¶
sphere_sum_field(
field: Field,
radius: float,
*,
is_only_spatial: bool = False,
) -> Field
Approximate sphere summation of a field via FFT convolution:
The field must be at least complex type. The result is normalised so that the sum approximates a spherical average.
field_smear¶
field_smear(
field: Field,
radius: float,
num_step: int = 1,
*,
spatial_only: bool = False,
) -> Field
Gaussian-smear a field in momentum space and return the result.
The field must be at least complex type. If spatial_only is
True, only the three spatial directions are smeared.
The Gaussian kernel is applied num_step times (num_step = 1 is the
single-pass smearing described above); it is not rescaled by num_step.
The input field is not modified.
Parameter |
Type |
Default |
Description |
|---|---|---|---|
|
|
— |
Input field (at least complex type) |
|
|
— |
Gaussian smearing radius (per application) |
|
|
|
Number of times the Gaussian kernel is applied |
|
|
|
If |
Returns |
|
Smeared field (new object) |
field_convolution¶
field_convolution(
f1: FieldComplexD,
f2: FieldComplexD,
idx1: np.ndarray = None,
idx2: np.ndarray = None,
*,
is_only_spatial: bool = False,
) -> FieldComplexD
Compute the cross-correlation of two complex fields via FFT:
Parameter |
Type |
Default |
Description |
|---|---|---|---|
|
|
— |
First field |
|
|
— |
Second field (must have same |
|
|
|
Multiplicity indices for |
|
|
|
Multiplicity indices for |
|
|
|
If |
idx1 and idx2 must have the same length. The result has
multiplicity len(idx1).
Examples¶
Gaussian Smearing via FFT¶
import qlat as q
import numpy as np
size_node_list = [
[1, 1, 1, 1],
]
q.begin_with_mpi(size_node_list)
total_site = q.Coordinate([4, 4, 4, 8])
geo = q.Geometry(total_site)
f = q.FieldComplexD(geo, 1)
f.set_zero()
f[0] = np.array([1.0 + 0.0j])
smeared = q.field_smear(f, radius=2.0)
print(f"Smeared field sum = {np.asarray(smeared).sum().real:.6f}")
q.end_with_mpi()
Sphere Summation¶
import qlat as q
import numpy as np
size_node_list = [
[1, 1, 1, 1],
]
q.begin_with_mpi(size_node_list)
total_site = q.Coordinate([4, 4, 4, 8])
geo = q.Geometry(total_site)
f = q.FieldComplexD(geo, 1)
f.set_zero()
f[0] = np.array([1.0 + 0.0j])
summed = q.sphere_sum_field(f, radius=3.0)
print(f"Sphere-summed field sum = {np.asarray(summed).sum().real:.6f}")
q.end_with_mpi()
Step-Based Smearing (Single Node)¶
import qlat as q
import numpy as np
size_node_list = [
[1, 1, 1, 1],
]
q.begin_with_mpi(size_node_list)
total_site = q.Coordinate([4, 4, 4, 8])
geo = q.Geometry(total_site)
f = q.FieldComplexD(geo, 1)
f.set_zero()
f[0] = np.array([1.0 + 0.0j])
smeared = q.field_smear_step_local(f, coef=0.5, num_step=10)
print(f"Step-smeared field sum = {np.asarray(smeared).sum().real:.6f}")
q.end_with_mpi()
Field Convolution¶
import qlat as q
import numpy as np
size_node_list = [
[1, 1, 1, 1],
]
q.begin_with_mpi(size_node_list)
total_site = q.Coordinate([4, 4, 4, 8])
geo = q.Geometry(total_site)
f1 = q.FieldComplexD(geo, 1)
f1.set_zero()
f1[0] = np.array([1.0 + 0.0j])
f2 = q.FieldComplexD(geo, 1)
f2.set_zero()
f2[0] = np.array([1.0 + 0.0j])
ff = q.field_convolution(f1, f2)
print(f"Convolution result at origin = {np.asarray(ff)[0]}")
q.end_with_mpi()