qlat.field_types — Typed Lattice Field Classes¶
Source: qlat/qlat/field_types.pyx.in
Note: Update this document when updating the source file.
Outline¶
Overview¶
field_types is a template module (.pyx.in) that generates concrete
Field{Type} subclasses of FieldBase for every lattice data type. Each
generated class (e.g., FieldColorMatrix, FieldRealD, FieldChar) shares a
uniform API and supports the NumPy buffer protocol for zero-copy array access.
All field classes are registered in the field_type_dict lookup:
field_type_dict[ElemTypeRealD] returns FieldRealD, enabling generic
construction via Field(ctype, geo, multiplicity).
Field Types¶
Complex Matrix Types¶
Class |
Element |
Element Shape |
|---|---|---|
|
3×3 complex (SU(3)) |
|
|
4×3 complex (spin-color) |
|
|
2×3 complex |
|
|
2×2 complex |
|
|
4×4 complex |
|
Complex Scalar Types¶
Class |
Element |
Element Shape |
|---|---|---|
|
Complex vector, length 12 |
|
|
Double-precision complex scalar |
scalar |
|
Single-precision complex scalar |
scalar |
Real Scalar Types¶
Class |
Element |
Element Shape |
|---|---|---|
|
Double-precision real scalar |
scalar |
|
Single-precision real scalar |
scalar |
Integer Types¶
Class |
Element |
|---|---|
|
64-bit signed integer |
|
32-bit signed integer |
|
64-bit signed integer |
|
32-bit signed integer |
|
8-bit signed integer |
|
8-bit signed integer |
Construction¶
f = FieldRealD() # empty (uninitialized)
f = FieldRealD(geo, 1) # single multiplicity
f = FieldRealD(geo, 3) # multiple multiplicities
geo is a Geometry object defining the lattice on which the field lives.
The second argument specifies how many elements per site.
Properties¶
Property |
Type |
Description |
|---|---|---|
|
|
The lattice geometry of the field |
|
|
Total lattice dimensions |
|
|
Number of local sites stored on this node |
|
|
Number of elements per site |
|
|
Size of one element in bytes |
Mutation Operations¶
f.set_zero() # set all elements to zero
f.set_unit(coef=1.0+0j) # set to unit matrix/scalar (times coef)
f.set_rand(rng, upper=1.0, lower=0.0) # uniform random in [lower, upper)
f.set_rand_g(rng, center=0.0, sigma=1.0) # Gaussian random
rng is an RngState object for reproducible random number generation.
Global Reductions¶
These methods perform MPI reductions across all nodes:
sp = f.glb_sum() # global sum → SelectedPoints (n_points=1)
sp = f.glb_sum_tslice(t_dir=3) # sum per timeslice → SelectedPoints
# Available only for RealD, RealF, Long, Int, Int64t, Int32t:
sp = f.glb_max() # global maximum → SelectedPoints (n_points=1)
sp = f.glb_min() # global minimum → SelectedPoints (n_points=1)
Each returns a SelectedPoints{Type} with the result.
norm = f.qnorm() # global squared norm (scalar float)
f_n = f.qnorm_field() # per-site squared norm → FieldRealD
Element Access by Coordinate¶
Read/write individual elements or collections of elements specified by coordinate arrays:
sp = f.get_elems_xg(xg_arr) # get elements at coordinates → SelectedPoints
f.set_elems_xg(xg_arr, val) # set elements at coordinates from value
sp = f.get_elem_xg(xg_arr, m) # get single multiplicity m at coordinates
f.set_elem_xg(xg_arr, m, val) # set single multiplicity m at coordinates
xg_arr can be an xg coordinate, xg_list, or xg_arr.
Field Shifting and Reflection¶
f1 = f.shift(shift, is_reflect=False) # return shifted copy (self is unchanged)
If shift is None, returns a copy. Otherwise, the field is shifted
cyclically by the given coordinate. If is_reflect=True, coordinates are
negated after shifting.
I/O Operations¶
f.read_direct(filename, new_size_node=None)
f.write_direct(filename, new_size_node=None)
f.read_sfr_dynamic(sfr, filename) # read from ShuffledFieldsReader
f.write_sfw_dynamic(sfw, filename, skip_if_exist=False) # write via ShuffledFieldsWriter
Assignment and Copying¶
The @= operator assigns field data. It accepts Field, SelectedField, or
SelectedPoints of the same type:
f1 @= f2 # copy field data (geo unchanged if already set)
f1 @= selected_field # scatter SelectedField into Field
f1 @= selected_points # scatter SelectedPoints into Field
Other assignment methods:
f2 = f.copy(is_copying_data=True) # deep copy (or shallow if False)
f.swap(f1) # swap data with another Field{Type}
f.swap_cast(f1) # swap with FieldChar (byte-cast)
f.swap_sp_cast(sp, geo) # swap with SelectedPointsChar (byte-cast)
NumPy Buffer Protocol¶
All field types implement the Python buffer protocol, enabling zero-copy NumPy access:
arr = np.asarray(f) # shape: (n_sites, multiplicity, *element_shape)
arr = np.asarray(f, dtype=np.float64) # real components only
arr = np.asarray(f, dtype=np.complex128) # complex components only
For scalar types (RealD, ComplexD, Int, etc.), the element shape is empty. For matrix types, element dimensions appear after the multiplicity axis.
Field Type Dictionary¶
The module registers each generated class into field_type_dict:
from qlat.field_type_dict import field_type_dict
FieldRealD = field_type_dict[ElemTypeRealD] # equivalent to FieldRealD
f = Field(ElemTypeRealD, geo, multiplicity) # generic construction via factory
This enables generic code that constructs fields by element type.
Examples¶
import qlat as q
import numpy as np
q.begin_with_mpi([[1, 1, 1, 4]])
# Create a geometry and field
geo = q.Geometry(q.Coordinate([4, 4, 4, 8]))
f = q.FieldRealD(geo, 1)
# Set to Gaussian random
rng = q.RngState("seed-42")
f.set_rand_g(rng, center=0.0, sigma=1.0)
# Access as NumPy array (zero-copy)
arr = np.asarray(f)
print(f"Shape: {arr.shape}") # (local_sites, multiplicity)
# Set zero and set a site to 1
f.set_zero()
f.set_elem_xg(q.Coordinate([0, 0, 0, 0]), 0, 1.0)
sp = f.get_elem_xg(q.Coordinate([0, 0, 0, 0]), 0)
print(f"Value: {np.asarray(sp)}")
# Global sum
sp_sum = f.glb_sum()
total = np.asarray(sp_sum).ravel()[0]
print(f"Total sum: {total}")
# Copy and shift
f_shift = f.shift(q.Coordinate([1, 0, 0, 0]))
# I/O
f.write_direct("field.dat")
f2 = q.FieldRealD()
f2.read_direct("field.dat")
q.end_with_mpi()