def METHOD_NAME(x, dx, t):
    x = g.util.to_list(x)
    dx = g.util.to_list(dx)
    # momentum vectors
    if context.m is None:
        context.m = [g.lattice(a) for a in dx]
        context.v = [g.lattice(a) for a in dx]
        context.mhat = [g.lattice(a) for a in dx]
        context.vhat = [g.lattice(a) for a in dx]
        context.epsfield = [g.lattice(a) for a in dx]
        for a in context.m + context.v:
            a[:] = 0
        for a in context.epsfield:
            a[:] = self.eps_regulator
    for i in range(self.maxiter):
        context.t += 1
        # x = theta(t-1)
        gt = f.gradient(x, dx)
        gt2 = []
        for a in gt:
            ar = g(g.component.real(a))
            ai = g(g.component.imag(a))
            gt2.append(g(g.component.multiply(ar, ar) + 1j * g.component.multiply(ai, ai)))
        for nu in range(len(dx)):
            context.m[nu] @= self.beta1 * context.m[nu] + (1 - self.beta1) * gt[nu]
            context.v[nu] @= self.beta2 * context.v[nu] + (1 - self.beta2) * gt2[nu]
            context.mhat[nu] @= (1.0 / (1.0 - self.beta1**context.t)) * context.m[nu]
            context.vhat[nu] @= (1.0 / (1.0 - self.beta2**context.t)) * context.v[nu]
            vhat_nu_real = g(g.component.sqrt(g.component.real(context.vhat[nu])))
            vhat_nu_imag = g(g.component.sqrt(g.component.imag(context.vhat[nu])))
            reg_mhat_real = g.component.multiply(
                g.component.real(context.mhat[nu]),
                g.component.inv(context.epsfield[nu] + vhat_nu_real),
            )
            reg_mhat_imag = g.component.multiply(
                g.component.imag(context.mhat[nu]),
                g.component.inv(context.epsfield[nu] + vhat_nu_imag),
            )
            # make sure object type is correct
            tmp = g.lattice(gt[nu])
            tmp @= -self.alpha * (reg_mhat_real + 1j * reg_mhat_imag)
            dx[nu] @= g.group.compose(tmp, dx[nu])
        rs = (sum(g.norm2(gt)) / sum([s.grid.gsites * s.otype.nfloats for s in gt])) ** 0.5
        self.log_convergence(i, rs, self.eps)
        if i % self.nf == 0:
            self.log(
                f"iteration {i}: f(x) = {f(x):.15e}, |df|/sqrt(dof) = {rs:e}, alpha = {self.alpha}, beta1 = {self.beta1}, beta2 = {self.beta2}"
            )
        if rs <= self.eps:
            self.log(
                f"converged in {i+1} iterations: f(x) = {f(x):.15e}, |df|/sqrt(dof) = {rs:e}"
            )
            return True
    self.log(f"NOT converged in {i+1} iterations;  |df|/sqrt(dof) = {rs:e} / {self.eps:e}")
    return False