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.

ModuleWhat it defines
stdlibprintf, eprintf, list and table utilities, xml.get
iterlazy iterators: iter.range, iter.count, iter.imap, iter.ichain, iter.tproduct, …
setset_add, set_remove, set_contains, set_print
pprintaligned printing of vectors and matrices
verbosediagnostics: print_obj, timeit, depr_warn, print_mem_usage_short
strictmakes reading an undeclared global an error
rcparamthe Lua view of _rcParam, with rcparams.get/rcparams.set
test_fieldsconstructors for the analytic fields a test needs
qudathe Lua side of the QUDA binding
gaugeplaquettes, clovers, gauge transforms, topological charge, background fields
ape-smear, hex-smear, stout-smear, wuppertal-smearthe smearing kernels
wilson-flowwilson_flow and the gradient-flow Runge–Kutta steps
baryonqcd.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

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

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

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

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

gauge_transform_D(g, F)                           --> field

A DiracFermion or a ColorVector transformed, which is g(x)·F(x).

gauge_transform_P

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:

MethodWhat 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.

ModuleConstructorMethod
krylov/CGmakeCG(t)conjugate gradient
krylov/BiCGStabmakeBiCGStab(t)stabilized bi-conjugate gradient
krylov/GCRmakeGCR(t)generalized conjugate residual
krylov/GMRESmakeGMRES(t)generalized minimal residual
krylov/LanczosmakeLanczos(t)Lanczos, for eigenvalues rather than solves

The settings the solvers share:

KeyDefaultMeaning
MaxIterations1000never iterate more than this
MinIterations0iterate at least this many times before testing
RelativeError1e-7stop when A:error(x,b) / A:norm(b) falls below it
AbsoluteErrorfalsestop when A:error(x,b) falls below it
TrueResidualfalsemeasure the error with A:error rather than from the recurrence
Loggingfalserecord every residual in status.Norms
ConvergenceFactorfalsegive up when the per-iteration gain is worse than this
ZeroGuard1e-209treat anything this small as zero

The status table:

FieldMeaning
Status"OK", or a word naming what went wrong
Syndromethat reason in words
Iterationshow many were used
RelativeResidual, AbsoluteResidualthe error reached
RHSNorm, SolutionNorm‖b‖ and ‖x‖
Normsthe 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.

EntryBuilds
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.

EntryWhat it does
qcdLib.GaugeLoops.action(params)the action of a weighted combination of shapes
qcdLib.GaugeLoops.flow_force(params)the force that drives a gradient flow of that action
qcdLib.GaugeLoops.matrix(name)the path table of one named shape

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.