Beispiel #1
0
    def __call__(self, link, staple, mask):
        verbose = g.default.is_verbose(
            "metropolis"
        )  # need verbosity categories [ performance, progress ]
        project_method = self.params["project_method"]
        step_size = self.params["step_size"]

        number_accept = 0
        possible_accept = 0

        t = g.timer("metropolis")

        t("action")
        action = g.component.real(g.eval(-g.trace(link * g.adj(staple)) *
                                         mask))

        t("lattice")
        V = g.lattice(link)
        V_eye = g.identity(link)

        t("random")
        self.rng.element(V, scale=step_size, normal=True)

        t("update")
        V = g.where(mask, V, V_eye)

        link_prime = g.eval(V * link)
        action_prime = g.component.real(
            g.eval(-g.trace(link_prime * g.adj(staple)) * mask))

        dp = g.component.exp(g.eval(action - action_prime))

        rn = g.lattice(dp)

        t("random")
        self.rng.uniform_real(rn)

        t("random")
        accept = dp > rn
        accept *= mask

        number_accept += g.norm2(accept)
        possible_accept += g.norm2(mask)

        link @= g.where(accept, link_prime, link)

        t()

        g.project(link, project_method)

        # g.message(t)
        if verbose:
            g.message(
                f"Metropolis acceptance rate: {number_accept / possible_accept}"
            )
Beispiel #2
0
def left_increment(dst, src_left, scale):
    dst = g.util.to_list(dst)
    src_left = g.util.to_list(src_left)
    group = dst[0].otype
    algebra = group.cartesian()
    assert src_left[0].otype.__name__ == algebra.__name__

    for src_left_mu, dst_mu in zip(src_left, dst):
        if group.__name__ != algebra.__name__:
            dst_mu @= group.compose(
                g.project(g.convert(g(scale * src_left_mu), group), "defect"),
                dst_mu)
        else:
            dst_mu @= group.compose(g(scale * src_left_mu), dst_mu)
Beispiel #3
0
    def __call__(self, link, staple, mask):
        verbose = g.default.is_verbose(
            "su2_heat_bath"
        )  # need verbosity categories [ performance, progress ]
        project_method = self.params["project_method"]

        # params
        niter = self.params["niter"]

        # temporaries
        grid = link.grid
        u2 = g.lattice(grid, g.ot_matrix_su_n_fundamental_group(2))
        u2_eye = g.identity(u2)
        one = g.identity(g.complex(grid))
        zero = g.complex(grid)
        zero[:] = 0
        eps = g.complex(grid)
        eps[:] = grid.precision.eps * 10.0
        xr = [g.complex(grid) for i in range(4)]
        a = [g.complex(grid) for i in range(4)]
        two_pi = g.complex(grid)
        two_pi[:] = 2.0 * np.pi
        accepted = g.complex(grid)
        d = g.complex(grid)
        V_eye = g.identity(link)

        # pauli
        pauli1, pauli2, pauli3 = tuple([g.lattice(u2) for i in range(3)])
        ident = g.identity(u2)
        pauli1[:] = 1j * np.array([[0, 1], [1, 0]], dtype=grid.precision.complex_dtype)
        pauli2[:] = 1j * np.array([[0, 1j], [-1j, 0]], dtype=grid.precision.complex_dtype)
        pauli3[:] = 1j * np.array([[1, 0], [0, -1]], dtype=grid.precision.complex_dtype)

        # counter
        num_sites = round(g.norm2(g.where(mask, one, zero)))

        # shortcuts
        inv = g.component.pow(-1.0)

        # go through subgroups
        for subgroup in link.otype.su2_subgroups():

            V = g.eval(link * g.adj(staple))

            # extract u2 subgroup following Kennedy/Pendleton
            link.otype.block_extract(u2, V, subgroup)
            u2 @= u2 - g.adj(u2) + g.identity(u2) * g.trace(g.adj(u2))
            udet = g.matrix.det(u2)
            adet = g.component.abs(udet)
            nzmask = adet > eps
            u2 @= g.where(nzmask, u2, u2_eye)
            udet = g.where(nzmask, udet, one)
            xi = g.eval(0.5 * g.component.sqrt(udet))
            u2 @= 0.5 * u2 * inv(xi)

            # make sure that su2 subgroup projection worked
            assert g.group.defect(u2) < u2.grid.precision.eps * 10.0

            xi @= 2.0 * xi
            alpha = g.component.real(xi)

            # main loop
            it = 0
            num_accepted = 0
            accepted[:] = 0
            d[:] = 0
            while (num_accepted < num_sites) and (it < niter):
                self.rng.uniform_real(xr, min=0.0, max=1.0)

                xr[1] @= -g.component.log(xr[1]) * inv(alpha)
                xr[2] @= -g.component.log(xr[2]) * inv(alpha)
                xr[3] @= g.component.cos(g.eval(xr[3] * two_pi))
                xr[3] @= xr[3] * xr[3]

                xrsq = g.eval(xr[2] + xr[1] * xr[3])

                d = g.where(accepted, d, xrsq)

                thresh = g.eval(one - d * 0.5)
                xrsq @= xr[0] * xr[0]

                newly_accepted = g.where(xrsq < thresh, one, zero)
                accepted = g.where(mask, g.where(newly_accepted, newly_accepted, accepted), zero)

                num_accepted = round(g.norm2(g.where(accepted, one, zero)))

                it += 1

            if verbose:
                g.message(f"SU(2)-heatbath update needed {it} / {niter} iterations")

            # update link
            a[0] @= g.where(mask, one - d, zero)

            a123mag = g.component.sqrt(g.component.abs(one - a[0] * a[0]))

            phi, cos_theta = g.complex(grid), g.complex(grid)
            self.rng.uniform_real([phi, cos_theta])
            phi @= phi * two_pi
            cos_theta @= (cos_theta * 2.0) - one
            sin_theta = g.component.sqrt(g.component.abs(one - cos_theta * cos_theta))

            a[1] @= a123mag * sin_theta * g.component.cos(phi)
            a[2] @= a123mag * sin_theta * g.component.sin(phi)
            a[3] @= a123mag * cos_theta

            ua = g.eval(a[0] * ident + a[1] * pauli1 + a[2] * pauli2 + a[3] * pauli3)

            b = g.where(mask, g.adj(u2) * ua, ident)
            link.otype.block_insert(V, b, subgroup)

            link @= g.where(accepted, V * link, link)

            # check
            check = g.where(accepted, ua * g.adj(ua) - ident, 0.0 * ident)
            delta = (g.norm2(check) / g.norm2(ident)) ** 0.5
            assert delta < grid.precision.eps * 10.0

            check = g.where(accepted, b * g.adj(b) - ident, 0.0 * ident)
            delta = (g.norm2(check) / g.norm2(ident)) ** 0.5
            assert delta < grid.precision.eps * 10.0

            check = g.where(accepted, V * g.adj(V) - V_eye, 0.0 * V_eye)
            delta = (g.norm2(check) / g.norm2(V_eye)) ** 0.5
            assert delta < grid.precision.eps * 10.0

        # project
        g.project(link, project_method)
Beispiel #4
0
################################################################################
# Test projection schemes on promoting SP to DP group membership
################################################################################
V0 = g.convert(rng.element(g.mcolor(grid_sp)), g.double)
for method in ["defect_left", "defect_right"]:
    V = g.copy(V0)
    I = g.identity(V)
    I_s = g.identity(g.complex(grid_dp))
    for i in range(3):
        eps_uni = (g.norm2(g.adj(V) * V - I) / g.norm2(I))**0.5
        eps_det = (g.norm2(g.matrix.det(V) - I_s) / g.norm2(I_s))**0.5
        g.message(
            f"Before {method} iteration {i}, unitarity defect: {eps_uni}, determinant defect: {eps_det}"
        )
        g.project(V, method)
    assert eps_uni < 1e-14 and eps_det < 1e-14

################################################################################
# Test SU(2) fundamental and conversion to adjoint
################################################################################

rng = g.random("test")

for eps_ref, grid in [(1e-6, grid_sp), (1e-12, grid_dp)]:
    g.message(
        f"Test SU(2) fundamental and adjoint conversion on grid {grid.precision.__name__}"
    )

    U = [g.matrix_su2_fundamental(grid) for i in range(2)]
    rng.element(
Beispiel #5
0
def projected_convert(x, otype):
    return g.project(g.convert(x, otype), "defect")
Beispiel #6
0
    group_defect = g.group.defect(Vt_split[t])
    g.message(f"Distance to group manifold: {group_defect}")
    if group_defect > 1e-12:
        g.message(
            f"Time slice {t} on split grid {Vt_split[t].grid.srank} has group_defect = {group_defect}"
        )
        sys.exit(1)

g.message("Unsplit")

g.unsplit(Vt, Vt_split, cache)

g.message("Project to group (should only remove rounding errors)")

Vt = [g.project(vt, "defect") for vt in Vt]

g.message("Test")

# test results
for t in range(Nt):
    f = g.qcd.gauge.fix.landau([Usep[mu][t] for mu in range(3)])
    dfv = f.gradient(Vt[t], Vt[t])
    theta = g.norm2(dfv).real / Vt[t].grid.gsites / dfv.otype.Nc
    g.message(f"theta[{t}] = {theta}")
    g.message(f"V[{t}][0,0,0] = ", Vt[t][0, 0, 0])
    if theta > p_theta_eps or np.isnan(theta):
        g.message(f"Time slice{t} did not converge: {theta} >= {p_theta_eps}")
        sys.exit(1)

# merge time slices
Beispiel #7
0
def update_field(P, U, ep):
    for Pmu, Umu in zip(P, U):
        Umu @= g.project(g.matrix.exp(g(ep * Pmu)), "defect") * Umu