Libraries
Besides the C interface, qlua installs a library of Lua modules. They are loaded with require, and the names they define are globals — these are pre-5.1-module-style files, not modules that return a table. iter is the exception: it is a module proper, and its names are reached through the table of that name.
There are two collections. qlib is the one this section is about; lhpc is a production measurement library and has a section of its own. Every name either of them defines is listed, with its arguments, in the appendix.
The common modules
qlib is not a module but a collection: a directory of files installed beside the interpreter, each require-d by the name of its file. Requiring one of them often requires others — stdlib pulls in iter, verbose, pprint and rcparam — so a script that asks for stdlib has most of the collection loaded.
| Module | What it defines |
|---|
stdlib | printf, eprintf, list and table utilities, xml.get | iter | lazy iterators: iter.range, iter.count, iter.imap, iter.ichain, iter.tproduct, … | set | set_add, set_remove, set_contains, set_print | pprint | aligned printing of vectors and matrices | verbose | diagnostics: print_obj, timeit, depr_warn, print_mem_usage_short | strict | makes reading an undeclared global an error | rcparam | the Lua view of _rcParam, with rcparams.get/rcparams.set | test_fields | constructors for the analytic fields a test needs | quda | the Lua side of the QUDA binding | gauge | plaquettes, clovers, gauge transforms, topological charge, background fields | ape-smear, hex-smear, stout-smear, wuppertal-smear | the smearing kernels | wilson-flow | wilson_flow and the gradient-flow Runge–Kutta steps | baryon | qcd.proton3, qcd.antiproton3 | qcdlib/, krylov/ | subdirectories of their own |
strict is the one with no names of its own: requiring it puts a metatable on the globals so that reading one that was never assigned raises instead of giving nil.
The utility modules of the collection come first, a subsection each. The rest of it is described under headings of its own: gauge under Gauge fields, the four kernels under Smearing, wilson-flow and baryon under Flow and spectroscopy, and the two subdirectories under qcdlib and Krylov solvers.
stdlib
The one module every script requires. printf and eprintf, about fifty list- and table-handling functions named systematically — list_* for operations on arrays, table_* for operations on keyed tables, string_* for the string helpers — and a few things Lua 5.1 does without.
printf
printf(fmt, ...) --> nothing
string.format followed by a write to standard output. The first thing most scripts require.
eprintf
eprintf(fmt, ...) --> nothing
The same, to standard error.
interval
interval(lo, hi) --> iterator
A for iterator over the integers from lo to hi, both ends included.
skip
skip(excl, ...) --> iterator
Wraps an iterator so that the value excl is passed over.
xml.get
xml.get(x, n, ...) --> value
Descends into a table parsed by xml.parse, following each argument in turn: a number picks an element by position, a string picks the first child carrying that tag.
range
range(lo, hi, step) --> table
The arithmetic sequence from lo up to but not including hi, as a list. step defaults to 1 and may be negative; with one argument the sequence starts at 0.
basename
basename(str) --> string
The last component of a path, trailing slashes removed.
dirname
dirname(str) --> string
Everything before the last component of a path, or "." when there is nothing.
space2full
space2full(c, t_axis, c_t) --> table
A full lattice coordinate from a spatial one, with c_t — 0 if it is left out — inserted at t_axis.
full2space
full2space(cfull, t_axis) --> table
The reverse: the coordinate at t_axis dropped.
calc_avg_var
calc_avg_var(f) --> number, number
The mean of a real lattice field over the whole lattice, and the mean square of its deviation from that.
list
list(...) --> table
Its arguments as a list. The constructor, for places where a literal {...} will not do.
list_copy
list_copy(src) --> table
A shallow copy of the array part of src, non-integer keys left behind.
list_append
list_append(res, x) --> nothing
Appends x to res, in place.
list_extend
list_extend(res, t) --> nothing
Appends every element of t, in place.
list_slice
list_slice(tab, klist) --> table
The elements of tab named by the keys in klist, in that order.
list_islice
list_islice(tab, i0,i1,istep) --> table
The slice tab[i0 : i1 : istep), the indices being those range would give.
list_map
list_map(func, list) --> table
func applied to every element, keys kept.
list_equal
list_equal(a,b) --> boolean
Whether two lists have the same length and equal elements.
list_index
list_index(clist, cx) --> number or nil
The position of the first element equal to cx.
list_join
list_join(...) --> table
The lists given, run together into one.
list_tostring
list_tostring(tab, fmt, sep) --> string
Each element through fmt (%s by default), joined with sep (", " by default).
list_scal
list_scal(a, v) --> table
Every element multiplied by a.
list_reshape2d
list_reshape2d(l, s12) --> table
A flat list of s1*s2 elements as s1 lists of s2, where s12 is {s1, s2}.
list_pad
list_pad(l, n, a) --> nothing
Appends a until the list is n long.
is_zero
is_zero(v) --> boolean
Whether v is zero — a predicate to hand to list_all or list_any.
is_nonzero
is_nonzero(v) --> boolean
Whether it is not.
list_all
list_all(l, f) --> boolean
Whether f holds of every element. Without f the element's own truth is the test.
list_any
list_any(l, f) --> boolean
Whether it holds of any.
table_elem
table_elem(i) --> function
The function that takes a table and returns its i-th element — a primitive for building iterators.
table_count
table_count(t) --> number
How many pairs the table holds, counting the keys # does not.
table_copy
table_copy(tab, level) --> table
A copy, duplicating subtables level deep and sharing what lies below. With no level the copy goes all the way down.
table_equal
table_equal(a, b, skip_nil) --> boolean
Whether two tables hold the same pairs; with skip_nil a key missing from one is not a difference.
table_index
table_index(clist, cx) --> key or nil
The key whose value is cx, over all keys rather than only the array part.
table_update
table_update(dst, t) --> nothing
Copies every pair of t into dst, in place.
table_deepupdate
table_deepupdate(dst, t) --> nothing
The same, descending into subtables instead of replacing them.
table_merge
table_merge(...) --> table
A new table holding the pairs of all the tables given, later ones winning. First-level subtables are shared, not copied.
table_deepmerge
table_deepmerge(...) --> table
The same, merging subtables rather than replacing them, and copying them as it goes.
table_delete_keys
table_delete_keys(t, klist) --> nothing
Removes the named keys.
table_tostring
table_tostring(tab, fmt, sep) --> string
Each pair through fmt ('%s'->'%s' by default), joined with sep.
table_setdefault
table_setdefault(t, k, v) --> value
t[k], after setting it to v if it was nil.
table_assert_const
table_assert_const(ls, v0, msg) --> nothing
Raises unless every value in ls equals v0. msg names the table in the message.
table_assert_type
table_assert_type(ls, tp, msg) --> nothing
Raises unless every value has type tp.
string_is_prefix
string_is_prefix(a, b) --> boolean
Whether a is a prefix of b.
string_del_prefix
string_del_prefix(a, b) --> string or nil
b with the prefix a taken off, or nil if a is not one.
string_is_postfix
string_is_postfix(a, b) --> boolean
Whether a is a suffix of b.
string_del_postfix
string_del_postfix(a, b) --> string or nil
b with that suffix taken off.
string_split
string_split(str, sep) --> table
The non-empty runs of str between the characters of sep, which is a pattern character class rather than a separator string.
bitwise_and
bitwise_and(x, y) --> number
Bitwise AND of two non-negative integers, which Lua 5.1 has no operator for.
bitwise_or
bitwise_or(x, y) --> number
Bitwise OR of the same.
ceil_multiple
ceil_multiple(x, intx) --> number
x rounded up to the next multiple of intx.
iter
Lazy sequences: iterators that are built from other iterators and drawn one value at a time, so that a long product or a big mapping need not be held in memory at once.
This module is a module proper — module('iter', package.seeall) — so its names live in the table iter and are written iter.imap(...), not bare. The naming is systematic: i* takes iterators, l* takes lists, t* takes tables, v* takes values, the result is an iterator, and a name ending _list is the same thing drained into a list.
iter.irepeat
iter.irepeat(n, ...) --> iterator
Collects everything the given iterator yields and replays it, n times over; nil repeats without end.
iter.icycle
iter.icycle(...) --> iterator
irepeat with no limit.
iter.vrepeat
iter.vrepeat(n, ...) --> iterator
Yields the values given, n times over, or without end when n is nil.
iter.count
iter.count(i0, di) --> iterator
The endless arithmetic sequence from i0 in steps of di, 1 by default.
iter.range
iter.range(i, n, di) --> iterator
What range builds as a list, drawn one value at a time.
iter.ienumerate
iter.ienumerate(...) --> iterator
Each value of an iterator preceded by its position, counting from 1.
iter.imap
iter.imap(mapfunc, ...) --> iterator
mapfunc applied to each value as it is drawn.
iter.ichop
iter.ichop(n, ...) --> iterator
The values collected into lists of at most n; the last list is short.
iter.ichop_pad
iter.ichop_pad(n, l) --> iterator
The same, with the last list padded to n by repeating its first element.
iter.ichain
iter.ichain(...) --> iterator
The opposite of ichop: an iterator of lists flattened into an iterator of their elements.
iter.ifirst
iter.ifirst(n, ...) --> iterator
The first n values and no more.
iter.lproduct_rlex
iter.lproduct_rlex(...) --> iterator
The Cartesian product of the lists given, as lists, the first index running fastest.
iter.lproduct_lex
iter.lproduct_lex(...) --> iterator
The same with the last index running fastest.
iter.tproduct
iter.tproduct(t) --> iterator
The Cartesian product of a table of lists, yielding tables with the same keys.
iter.litems
iter.litems(l) --> iterator
A list, drawn one element at a time.
iter.igen_list
iter.igen_list(...) --> table
An iterator drained into a list.
iter.ichop_list
iter.ichop_list(n, ...) --> table
ichop drained into a list of lists.
iter.lchop
iter.lchop(n, l) --> iterator
ichop of a list.
iter.lchop_list
iter.lchop_list(n, l) --> table
A list cut into lists of at most n.
iter.lchop_pad
iter.lchop_pad(n, l) --> iterator
ichop_pad of a list.
iter.imap_list
iter.imap_list(f, ...) --> table
imap drained into a list.
iter.lmap
iter.lmap(f, l) --> iterator
f over the elements of a list, lazily.
iter.lmap_list
iter.lmap_list(f, l) --> table
The same, drained into a list.
iter.imap_batch
iter.imap_batch(nbatch, fbatch, ...) --> iterator
Maps in batches: fbatch is handed lists of nbatch values and returns lists of results, which are yielded one at a time. For a mapping that is cheaper in bulk.
iter.ordered_titems
iter.ordered_titems(t, keysort_func) --> iterator
pairs with the keys sorted, so that every node walks the table in the same order. keysort_func is passed to table.sort.
iter.ordered_tmap_table
iter.ordered_tmap_table(f, t, keysort_func) --> table
A table with the same keys and f of each value, the values visited in sorted key order.
iter.ordered_tmap_pair_table
iter.ordered_tmap_pair_table(f, t, keysort_func) --> table
The same, except that f(k, v) returns both the new key and the new value.
iter.titems
iter.titems(f, t) --> raises
Raises. It walked a table in hash order, which two nodes need not agree on; ordered_titems is what to use.
iter.tmap_table
iter.tmap_table(f, t) --> raises
Raises, for the same reason: ordered_tmap_table.
iter.tmap_pair_table
iter.tmap_pair_table(f, t) --> raises
Raises, for the same reason: ordered_tmap_pair_table.
set
A set here is a plain table whose keys are its elements, each with the value true. These seven functions are all there is to it; require "set" also brings in stdlib.
set_add
set_add(s, key) --> nothing
Puts key into the set.
set_remove
set_remove(s, key) --> nothing
Takes it out.
set_contains
set_contains(s, key) --> boolean
Whether it is there.
set_print
set_print(s) --> nothing
Prints the set, one key to a line.
set_list
set_list(s) --> table
The keys as a list, in whatever order the table holds them.
set_fromtable
set_fromtable(t) --> table
A set of the values of t, which is how a list becomes a set.
list_uniq
list_uniq(l) --> table
The distinct elements of a list, by way of a set, so the order is lost.
pprint
Printing vectors and matrices so that the columns line up, and three measures for saying how far apart two matrices are.
index_strlen
index_strlen(n, nmax) --> number
How many decimal digits an index below n needs, nmax at the most.
index_strfmt
index_strfmt(n, nmax) --> string
A %d format of that width, for indices that line up.
list_concat_multiline
list_concat_multiline(list, sep, per_line) --> table
The list as strings of per_line elements each, every one labeled with the index it starts at.
print_vector_aligned
print_vector_aligned(vec, fmt, sep, val_per_line, title) --> nothing
Prints a vector val_per_line elements to a line, each through fmt, every line headed title[i] with the index of its first element.
print_vector
print_vector(vec, title) --> nothing
The same with a format chosen for the type: eight to a line for a real vector, four for a complex one.
print_matrix_aligned
print_matrix_aligned(mat, fmt, sep, val_per_line, title) --> nothing
The same for a matrix, row by row, each line headed with the row and the column it starts at.
print_matrix
print_matrix(mat, title) --> nothing
print_matrix_aligned with the format the matrix's type asks for.
print_cmatrix
print_cmatrix(mat, title, flags) --> nothing
The upper triangle of a complex matrix, one element to a line.
matrix_vdot
matrix_vdot(a, b) --> number
The square root of the trace of a†·b — the pairing matrix_rdiff and print_cmatrix_cmp measure with.
matrix_nrm
matrix_nrm(a) --> number
The square root of the trace of a·a†.
matrix_rdiff
matrix_rdiff(a, b) --> number
The relative difference 2|a−b| / (|a| + |b|), and zero when both are zero. The usual way these libraries compare two matrices.
narg
narg(x) --> number
The phase of a number or a complex, 0 or π for a real one.
nabs
nabs(x) --> number
The modulus of either.
print_cmatrix_cmp
print_cmatrix_cmp(a, b, title) --> nothing
Prints the ratio of the norms of two complex matrices and their normalized overlap in polar form — one line saying how far apart they are.
verbose
Diagnostics: what the job is running on, what an object holds, how long a function took, and the warnings a library gives when it is called wrongly or out of date.
print_network_settings
print_network_settings() --> nothing
Prints how many nodes the job has and the shape of the process grid.
print_subgrid_settings
print_subgrid_settings(L) --> nothing
Prints, for one lattice, the process grid and the local subgrid each node holds.
print_obj
print_obj(t, name, opt) --> nothing
Prints an object and everything it holds, one line to a leaf. opt.depth is how deep to go — -1, the default, is all the way — and opt.exclude lists objects to stop at, which is how a cycle is broken; a cycle met anyway is printed as <cyclicRef> rather than followed.
print_type
print_type(x, tit) --> nothing
Prints the type of x.
spprint_table
spprint_table(t, indent, level, spprint_elem) --> string
A nested list as a string, the first level levels broken onto lines of their own and indented from indent. spprint_elem formats the leaves and defaults to tostring.
print_mem_usage_short
print_mem_usage_short(msg) --> nothing
One line of qcd.memory_usage counts, gathered by field type and labeled msg.
func_info_fmt
func_info_fmt(d) --> string
A debug.getinfo record as name[what], falling back to the file and line the function was defined on.
call_info_fmt
call_info_fmt(d) --> string
A call site as name(source:line)[what]. With no argument it describes its caller's caller, which is what a warning wants to name.
print_warn
print_warn(...) --> nothing
Writes a formatted warning to standard error, prefixed with where it was called from.
depr_warn
depr_warn(func, opt) --> function
Wraps a function so that calling it prints a deprecation notice first. opt.verbose — or verbose.depr_warn in the run-control parameters — says how often: once per run, line per call site, file per file, or each call. opt.replace names what to use instead.
timeit
timeit(func, opt) --> function
Wraps a function so that its calls are counted and their wall time added up. opt.name distinguishes one wrapping from another, and opt.verbose = 'each' prints every call as it returns.
timeit_report
timeit_report(opt) --> nothing
Prints what those wrappers have gathered: name, count, total and average seconds.
test_status
test_status(name) --> object
A collector for test results. Call it as st(test, result) for each check; st:report() prints which named tests failed and how often.
table_opt_extra(t, kl) --> table
The keys of t that are not in kl — the options a function was handed and does not know.
warn_opt_extra(t, kl) --> table
The same, with each of them printed as a warning naming the caller.
rcparam
The Lua view of the run-control parameter table; Run-control parameters says what the keys mean. require "rcparam" makes rcparams — and the older name rcparam, which is the same table — point at _rcParam when the build has one and at a table of defaults when it does not, and fills in rcparams.backend and rcparams.verbose if they are missing.
contract_backend
contract_backend() --> string
The backend the contraction functions are to use, which is rcparams.backend.qbarq.
rcparams.get
rcparams.get(k) --> value
The value at a dotted path in rcparams, or nil if the path does not lead anywhere.
rcparams.set
rcparams.set(k, v) --> nothing
Sets the value at that path, making the tables along the way.
test_fields
Analytic fields with a known answer, for a test to compare against: lists indexed by time, lattice fields linear in one coordinate, and plane-wave color vectors and propagators. The vec_* functions build plain Lua lists of lt numbers, one per time slice, which then modulate a field.
vec_const
vec_const(lt, x) --> table
A list of lt copies of x.
vec_poly
vec_poly(lt, coeff) --> table
The polynomial with coefficients coeff sampled at t = 0 … lt−1.
vec_exp
vec_exp(lt, e) --> table
exp(e·t) over the same range.
vec_cexp
vec_cexp(lt, e) --> table
The same for a complex e, as a list of complex numbers.
vec_sin
vec_sin(lt, e) --> table
sin(e·t).
vec_cos
vec_cos(lt, e) --> table
cos(e·t).
vec_axpy
vec_axpy(a,x,y) --> table
a·x + y, element by element.
vec_scal
vec_scal(a,x) --> table
a·x.
vec_symm_cyclic
vec_symm_cyclic(vec, t0) --> table
The list folded about its middle, so that it reads the same forwards and backwards — the time dependence of a periodic correlator.
vec_shift_cyclic
vec_shift_cyclic(vec, dt) --> table
The list rotated by dt, wrapping at the ends.
vec_gevm
vec_gevm(g_list, vec_list) --> table
The combination Σ g[i]·vec[i], a row vector times a list of lists.
vec_mul
vec_mul(x,y) --> table
The elementwise product of two lists.
vec_mul_lat
vec_mul_lat(x, l, t_axis) --> nothing
Meant to multiply each time slice of a lattice field by the matching element of x. Its body is commented out in the shipped file, so it checks the length of x and does nothing else.
latI_lin
latI_lin(L, axis, x0) --> L:Int
The coordinate along axis counted from x0 and wrapped at the end of the lattice.
latI_rlin
latI_rlin(L, axis, x0) --> L:Int
The same counted backwards from x0.
latI_dist
latI_dist(L, axis, x0) --> L:Int
The smaller of the two — the periodic distance from x0 along axis.
latR_lin
latR_lin(L, axis, x0) --> L:Real
latI_lin as a real field.
latR_rlin
latR_rlin(L, axis, x0) --> L:Real
latI_rlin as a real field.
latR_dist
latR_dist(L, axis, x0) --> L:Real
latI_dist as a real field.
lat_poly
lat_poly(x, coeff) --> field
A polynomial in a field, by Horner's rule, with coeff indexed from the end.
make_latcolvec_pw_c_t
make_latcolvec_pw_c_t(L, t_axis, p3, src0, col) --> L:ColorVector
A plane wave of spatial momentum p3 about src0, times the three numbers in col — an analytic color vector to test against.
make_latcolvec_list_pw_c_expt
make_latcolvec_list_pw_c_expt(L, t_axis, pw3_list, pw_x0, col_list, dep_pw3, dep_col) --> table
One such vector for each momentum and color in the two lists, optionally scaled by dep_pw3 and dep_col so that the components differ in their time dependence.
make_latdirprop_lin_pw
make_latdirprop_lin_pw(L, lc5, ft_mom, ft_x0) --> L:DiracPropagator
A plane wave times a propagator whose entries are linear in the four indices, lc5 being the constant and the four slopes.
make_4latdirferm_t
make_4latdirferm_t(v, t_axis, pw3, pw_x0, dep_spin) --> table
Four DiracFermions built from a color vector, one per spin index, each multiplied by a plane wave and, if dep_spin is given, by its own factor.
quda
The Lua side of the QUDA binding. The file is installed in every build, but the C tables it wraps exist only where qlua was configured with HAS_QUDA — see QUDA — and calling into it without them raises.
qcd.quda.init
qcd.quda.init(L) --> nothing
Starts QUDA on the lattice L and remembers it. Raises if QUDA is already running.
qcd.quda.fini
qcd.quda.fini() --> nothing
Shuts it down, closing whatever solver is open first.
qcd.quda.inverter.simple
qcd.quda.inverter.simple(U, gpx, ipx, opt) --> object
A QUDA inverter for the gauge field U, with gpx and ipx overriding the gauge and invert parameters. The object answers solve(rhs), plaqs() and close().
qcd.quda.inverter.multigrid
qcd.quda.inverter.multigrid(U, gpx, ipx, mpx, imx, opt) --> object
The same with QUDA's multigrid preconditioner, mpx and imx giving the multigrid and its inner invert parameters.
Gauge fields
require "gauge" brings in the observables and transformations every gauge script needs. U throughout is a gauge field: a list of #L lattice ColorMatrix fields indexed from 1, so U[mu+1] is the link in direction mu. Note the off-by-one — the functions that take an axis number take it counted from 0, as the C interface does, while the list is indexed from 1 as Lua does.
gauge_plaquette
gauge_plaquette(U, mu, nu) --> L:ColorMatrix
The 1×1 Wilson loop in the (mu, nu) plane at every site, as an untraced matrix. Axes count from 0.
gauge_plaquette_all
gauge_plaquette_all(U) --> table
Every independent plane at once: res[1+mu][1+nu] is gauge_plaquette(U, mu, nu), the diagonal is the identity and the lower triangle is the conjugate of the upper.
gauge_u1_plaquette
gauge_u1_plaquette(U,i,j) --> L:Complex
The same loop for a U(1) gauge field, whose links are L:Complex rather than L:ColorMatrix.
gauge_u1_plaquette_all
gauge_u1_plaquette_all(U) --> table
Every independent plane of one, in the same shape as gauge_plaquette_all.
gauge_clover
gauge_clover(U, mu, nu) --> L:ColorMatrix
The clover-leaf average of the four 1×1 loops touching a site in the (mu, nu) plane — the standard discretization of the field strength.
gauge_clover_all
gauge_clover_all(U) --> table
The clover in every plane.
gauge_clovsum_plaq
gauge_clovsum_plaq(U, i, j) --> L:ColorMatrix
The sum of the four 1×1 loops touching a site in the (i, j) plane, before the anti-Hermitian part is taken: gauge_clover is this minus its adjoint, over 8i.
gauge_clovsum_rect
gauge_clovsum_rect(U, i, j) --> L:ColorMatrix
The same sum over the 1×2 rectangles, i being the long side. What an improved field strength is built from.
gauge_u1_clover
gauge_u1_clover(U, i, j) --> L:Complex
The clover of a U(1) field: the anti-Hermitian part of its four-loop sum, over 8i.
gauge_u1_clover_all
gauge_u1_clover_all(U) --> table
The U(1) clover in every plane, antisymmetric in the two indices as gauge_clover_all is.
gauge_topcharge_naive
gauge_topcharge_naive(U) --> number
The topological charge from the naive clover discretization. Four dimensions only.
toSUn
toSUn(X) --> L:ColorMatrix
The exponential of the traceless anti-Hermitian part of X, which is the cheapest way of projecting a general matrix field onto the group.
gauge_transform_U(g, U) --> table
The gauge field transformed by the L:ColorMatrix field g: each link becomes g(x)·U_mu(x)·g(x+mu)†.
gauge_transform_U_dir(g, U, mu) --> L:ColorMatrix
One link of that: the gauge field transformed in the direction mu alone.
gauge_transform_D(g, F) --> field
A DiracFermion or a ColorVector transformed, which is g(x)·F(x).
gauge_transform_P(g, P) --> field
A DiracPropagator transformed, which is g(x)·P(x)·g(x)†.
gauge_copy
gauge_copy(U) --> table
An independent copy of the whole gauge field.
gauge_apply_boundary
gauge_apply_boundary(U, bc) --> table
Multiplies the links on the last slice of each axis by the phases in bc, so that a periodic field becomes one with the given boundary conditions.
gauge_u1_const_field
gauge_u1_const_field(L, nflux_munu) --> table
A U(1) gauge field of constant field strength: the plaquette in the (mu, nu) plane is exp(2πi·n / (L[mu]·L[nu])), where n is nflux_munu[1+mu][1+nu] flux quanta. Only the upper triangle of nflux_munu is read.
gauge_u1_const_field_munu
gauge_u1_const_field_munu(L, nflux, mu, nu) --> L:Complex, L:Complex
The two links of such a field for one plane: the mu one, which carries its phase on the last slice of the mu axis only, and the nu one, which carries a phase everywhere.
gauge_add_bgelectric
gauge_add_bgelectric(gauge_u, efield, t_axis) --> table
Multiplies a four-dimensional gauge field, in place, by the constant U(1) field of the electric vector efield — one flux number per spatial axis. t_axis has to be the last axis.
gauge_add_bgmagnetic
gauge_add_bgmagnetic(gauge_u, hfield, t_axis) --> table
The same for a magnetic field, whose three components live in the (y,z), (z,x) and (x,y) planes.
gauge_add_bgem
gauge_add_bgem(gauge_u, bgem, t_axis) --> table
Both at once, from {efield = ..., hfield = ...}; either may be left out.
Five more names are kept for scripts that have not caught up with a renaming. Each calls the one that replaced it and prints a line saying so.
naive_q
naive_q(U) --> number
gauge_topcharge_naive under its old name.
plaquette
plaquette(U,i,j) --> L:ColorMatrix
gauge_plaquette under its old name.
plaquette_all
plaquette_all(U) --> table
gauge_plaquette_all under its old name.
clover_term
clover_term(U, i, j) --> L:ColorMatrix
gauge_clover under its old name.
clover_term_all
clover_term_all(U) --> table
gauge_clover_all under its old name.
Smearing
Four smearing kernels, each require-d from the file named after it. All of them take a gauge field and return a new one; none modifies its argument.
APE_smear
APE_smear(U, A, N, accu, imax, axis) --> table
N steps of APE smearing with staple weight A. Each step projects back onto the group with M:proj, which is what accu and imax control. axis is left out of the smearing — pass the time axis for spatial-only smearing, counted from 0.
stout_smear_full
stout_smear_full(U, rho, n, mu_skip) --> table
n steps of stout smearing with parameter rho, skipping direction mu_skip.
stout_smear_3d
stout_smear_3d(U, rho, n) --> table
The three-dimensional special case: stout_smear_full with the last axis skipped.
get_staple
get_staple(U, mu, numax) --> L:ColorMatrix
The sum of the staples around the link in direction mu, over the directions 1 … numax other than mu — what a smearing step averages the link with. Here mu and numax index the list of links, so they count from 1 while the axes they stand for count from 0.
get_staple_dirset
get_staple_dirset(U, mu, dirset) --> L:ColorMatrix
The same sum over the directions in dirset, a set in the sense of the set module. This one counts mu and the directions from 0, as the rest of the interface does.
wuppertal_smear
wuppertal_smear(U, alpha, N, G, axis) --> field
N steps of Wuppertal (Gaussian) smearing of the fermion field G — a DiracFermion or a DiracPropagator — in the background of U, with width parameter alpha. axis is left out, so passing the time axis gives the usual three-dimensional smearing. Unlike the gauge smearings this one smears the quark, not the links; it is one call to qcd.laplacian with the coefficients worked out from alpha.
wuppertal_smear_bcderiv
wuppertal_smear_bcderiv(U, alpha, N, G_ddmap, axis) --> table
Smears a field and its derivatives with respect to the boundary conditions together, so that they see the same kernel. G_ddmap maps a derivative label to the field to smear — '' for the field itself and 'x', 'y', 'z' or 't' for a first derivative — and the result is a table with the same keys. Only the field alone, and the field with one first derivative, are implemented.
wuppertal_smear_old
wuppertal_smear_old(U, alpha, N, G, axis) --> field
An earlier implementation, which calls qcd.laplacian N times from Lua rather than asking for N iterations at once. Kept for comparison; it prints a deprecation notice.
wuppertal_smear_std
wuppertal_smear_std(U, alpha, N, G, axis) --> field
The same again over qcd.laplacian_std, the unoptimized kernel. Also deprecated, and the slowest of the three.
gauge_hex_smear
gauge_hex_smear(U, n, alpha) --> table
n steps of HEX smearing with the three weights alpha.
gauge_hex_smear_bmw
gauge_hex_smear_bmw(U, n) --> table
The same with the BMW weights {0.95, 0.76, 0.38}.
gauge_hyp_smear
gauge_hyp_smear(U, n, alpha, blk_accu, blk_maxiter) --> table
n steps of HYP smearing. blk_accu and blk_maxiter default to 1e-8 and 150 and control the group projection at each blocking level.
gauge_hyp_smear_std
gauge_hyp_smear_std(U, n) --> table
The same with the standard weights {0.75, 0.60, 0.30}.
gauge_hyp_general
gauge_hyp_general(U, nsteps, alpha, fatlink_sun_func) --> table
The implementation both of those call, with the group projection handed in as a function — which is what makes HEX smearing the same code with a different projection.
Flow and spectroscopy
wilson_flow
wilson_flow(U, eps, opt) --> table
One Runge–Kutta step of the Wilson flow of step length eps (arXiv:1105.4749). opt.update may supply a function that combines the old and new fields, which is how a partial or constrained flow is expressed. The gradflow_* functions in the same file are its pieces, usable separately.
gradflow_rkstep_gauge_nodes
gradflow_rkstep_gauge_nodes(eps, u) --> table
The gauge field at the four nodes of one Runge–Kutta step: {u(t), u(t+eps/4), u(t+2·eps/3), u(t+eps)}. Everything else here is built on it, because a matter field flowed alongside the gauge field needs the intermediate links rather than only the final ones.
gradflow_rkstep_gauge
gradflow_rkstep_gauge(eps, u) --> table
One step of the gauge field alone: the last of those four.
gradflow_rkint_gauge
gradflow_rkint_gauge(eps, n, u) --> table
n steps of it: the field at t + n·eps.
gradflow_rkint_gaugelist
gradflow_rkint_gaugelist(eps, n, u) --> table
The same, keeping what it passes through: a list of n+1 gauge fields, u(t) first. An adjoint flow needs that history.
gradflow_rkstep_field
gradflow_rkstep_field(eps, u012, f) --> field
One step of a matter field in the background of the first three gauge nodes, by the same third-order rule. u012 is what gradflow_rkstep_gauge_nodes returned.
gradflow_rkstep_field_adj
gradflow_rkstep_field_adj(eps, u012, f3) --> field
The adjoint of that step, carrying a field from t+eps back to t.
gradflow_rkstep_gauge_field
gradflow_rkstep_gauge_field(eps, u, f_tab, f_adj_tab) --> table, table, table
One step of the gauge field and, in its background, every field in f_tab forwards and every field in f_adj_tab backwards. Either table may be nil.
gradflow_rkint_gaugelist_field
gradflow_rkint_gaugelist_field(eps, n, u, ftab0) --> table, table
n steps of the gauge field with fields flowing along: the list of n+1 gauge fields and the flowed fields. ftab0 may be one field or a table of them, and is not overwritten — though only its top level is copied.
gradflow_rkint_field_adj
gradflow_rkint_field_adj(eps, n, ulist, ftab_n) --> table
n adjoint steps against a gauge history ulist, carrying the fields from t + n·eps back to t. ulist is what gradflow_rkint_gaugelist wrote.
qcd.proton3
qcd.proton3(d, u) --> L:Complex
The proton two-point function from a down and an up propagator, both three-color DiracPropagators. Defined by require "baryon", not by the C interface.
qcd.antiproton3
qcd.antiproton3(d, u) --> L:Complex
Its negative parity partner, from the same two propagators.
Krylov solvers
The krylov modules are iterative solvers written against an abstract operator rather than against a particular action. Nothing in them mentions a Dirac operator, a gauge field or even a lattice: they ask the operator they are given to apply itself and to do the vector arithmetic, so the same CG drives a clover solve, a small test matrix or a preconditioned composite.
The operator. You supply a table with these methods — the contract is written out in qlib/krylov/README:
| Method | What it must do |
|---|
A:apply(v) | return A·v | A:applyT(v) | return Aᵀ·v | A:dot(v, w) | the inner product, as a real number | A:norm(v) | |v| | A:axpy(a, v, w) | a·v + w, with a real | A:scale(a, v) | a·v | A:residue(x, b) | b − A·x | A:error(x, b) | |b − A·x| | A:zeroVector() | a zero vector of the right shape | A:randomVector() | a random one | A:lattice() | the lattice, where there is one | A:rnd() | the random state it draws from |
The solvers. Each module defines one constructor. It takes a table of settings, and returns an object whose setup(A) gives the thing that solves:
require "krylov/CG"
local cg = makeCG{MaxIterations = 2000, RelativeError = 1e-10}
local x, status = cg:setup(A):solve(b, A, x0)
solve(b, A, x0) returns the solution and a status table. x0 is the starting guess and may be omitted, in which case the solver starts from zero.
The settings the solvers share:
| Key | Default | Meaning |
|---|
MaxIterations | 1000 | never iterate more than this | MinIterations | 0 | iterate at least this many times before testing | RelativeError | 1e-7 | stop when A:error(x,b) / A:norm(b) falls below it | AbsoluteError | false | stop when A:error(x,b) falls below it | TrueResidual | false | measure the error with A:error rather than from the recurrence | Logging | false | record every residual in status.Norms | ConvergenceFactor | false | give up when the per-iteration gain is worse than this | ZeroGuard | 1e-209 | treat anything this small as zero |
The status table:
| Field | Meaning |
|---|
Status | "OK", or a word naming what went wrong | Syndrome | that reason in words | Iterations | how many were used | RelativeResidual, AbsoluteResidual | the error reached | RHSNorm, SolutionNorm | ‖b‖ and ‖x‖ | Norms | the residual history, if Logging was set |
makeCG
makeCG(t) --> object
Conjugate gradient, for an operator that is Hermitian and positive definite. t is the settings table above, and the object answers setup(A).
makeBiCGStab
makeBiCGStab(t) --> object
Stabilized bi-conjugate gradient, which asks nothing of the operator but that it have an adjoint.
makeGCR
makeGCR(t) --> object
Generalized conjugate residual.
makeGMRES
makeGMRES(t) --> object
Generalized minimal residual.
makeLanczos
makeLanczos(t) --> object
Lanczos, for eigenvalues rather than solves, and the odd one out: its settings are Dim — the size of the Krylov space, 150 by default — and Scan, and its object answers distill(A, b) rather than setup.
Composing operators. krylov/OpArith defines the table OpArith, whose entries build new operators out of old ones so that a preconditioned or shifted problem can be handed to an unmodified solver.
| Entry | Builds |
|---|
OpArith.mul(A, B, ...) | the product A·B·… | OpArith.add(A, B, ...) | the sum | OpArith.sub(A, B, ...) | the difference | OpArith.scale(s, A) | s·A | OpArith.axpy(a, X, Y) | a·X + Y | OpArith.axpby(a, X, b, Y) | a·X + b·Y | OpArith.axpb(a, X, b) | a·X + b·I | OpArith.adjoin(A) | the Hermitian conjugate | OpArith.ident(A) | the identity on A's space | OpArith.leftPrecond(P, A) | A left-preconditioned by P | OpArith.projected(A, Q) | A restricted to the image of Q | OpArith.fromFunc(A, f, fT) | an operator from two plain functions | OpArith.count(A) | a copy of A that counts its own applications |
Deflation by splitting. krylov/BlockSplit defines one more constructor.
BlockSplit
BlockSplit(t) --> object
An object whose split(M) separates the difficult part of a spectrum from the easy part. It returns a table of the projectors P and Q = 1 − P, the maps v2s and s2v between the full space and the small one, a prototype operator Ops on the small space, and the singular value estimates MaxS and MinS — or false when it cannot find a useful split. Its settings are Blocks, KDim, MinDim, MaxCondition and LanczosSize.
qcdlib
Three modules of pure gauge observables, all hanging off one global table, qcdLib. They are written in terms of the lattice ColorMatrix algebra, so they work at any number of colors the binary supports.
Closed loops. qcdlib/gauge-loops builds observables out of Wilson loops of a given shape. A shape is a table of paths, and the directory qcdlib/gauge-loops/ holds one file per shape: plaq1, plaq2, rect1, rect2, chair1, chair2, twist1, twist2, adj-plaq1, clover1x1, clover2x2 and clover3x3. Requiring one of those files registers the shape; qcdlib/loop-tables pulls in the usual set.
Given a shape, the module makes an object with actionDensity(U), action(U), count(U) and force(U) — the last being what a flow or a molecular-dynamics step needs.
params is a list of {coefficient, shape} pairs, so a tree-level improved action is written as a plaquette term and a rectangle term with their coefficients.
qcdLib.GaugeLoops.action
qcdLib.GaugeLoops.action(params) --> table
The action of a weighted combination of shapes, as an object with actionDensity(U), action(U), count(U) and force(U).
qcdLib.GaugeLoops.flow_force
qcdLib.GaugeLoops.flow_force(params) --> function
The force that drives a gradient flow of that action — what qcdLib.GradientFlow.flow is handed.
qcdLib.GaugeLoops.matrix
qcdLib.GaugeLoops.matrix(name) --> table
The path table of one named shape, for a caller that wants the loops themselves rather than an action built from them.
A shape itself is built by one of five constructors. Each takes the shape's name and a table holding its path code, and returns the object described above; they differ in which combinations of axes the shape is summed over, which is what a shape's own symmetry decides.
qcdLib.GaugeLoops.make_matrix_xy
qcdLib.GaugeLoops.make_matrix_xy(name, table) --> table
A shape with nothing but matrix(U, opts), which runs the path code on the axes named in opts. No sum, and so no action or force: this is the form qcdLib.GaugeLoops.matrix hands back.
qcdLib.GaugeLoops.make_sym_xy
qcdLib.GaugeLoops.make_sym_xy(name, table) --> table
Summed over the unordered pairs of axes, x < y — a shape symmetric in its two directions, such as the plaquette.
qcdLib.GaugeLoops.make_gen_xy
qcdLib.GaugeLoops.make_gen_xy(name, table) --> table
Summed over the ordered pairs, x ≠ y, for a shape that tells its two directions apart — the rectangle, where one side is the long one.
qcdLib.GaugeLoops.make_mix_xyz
qcdLib.GaugeLoops.make_mix_xyz(name, table) --> table
Summed over x < y and a third axis z different from both: symmetric in two directions and not in the third, which is the chair.
qcdLib.GaugeLoops.make_sym_xyz
qcdLib.GaugeLoops.make_sym_xyz(name, table) --> table
Summed over x < y < z, for a shape symmetric in all three, which is the twist.
Gradient flow. qcdlib/gradient-flow defines one function.
qcdLib.GradientFlow.flow
qcdLib.GradientFlow.flow(force, U, step, opt) --> table
One third-order Runge–Kutta step of the Wilson flow (Lüscher, arXiv:1105.4749), force supplying the gradient — typically qcdLib.GaugeLoops.flow_force of the action being flowed. It returns the flowed gauge field.
The symmetric E and Q. qcdlib/symmetric-EQ defines one more.
qcdLib.symmetricEQ
qcdLib.symmetricEQ(U, opts) --> number, number
The clover-discretized energy density and topological charge, which is what a flow is usually measured with. With opts.improved set it uses the 2×2 and 3×3 clovers as well as the 1×1, which is why those three clover shapes are the ones it requires.
|