コード例 #1
0
ファイル: multi_shift_fgmres.py プロジェクト: spieseba/gpt
    def arnoldi(self, mat, V, rlen, mmp, sfgmres, prec, idx, t):
        H = []
        for i in range(rlen):
            if prec is not None:

                t("prec")
                Z = [sfgmres[j].Z[i] for j in idx] + [mmp]
                for z in Z:
                    z[:] = 0
                rhos = prec(Z, [V[i]])
                for j, rho in zip(idx, rhos[0:-1]):
                    sfgmres[j].gamma[i] = rho / rhos[-1]

            t("arnoldi")
            ips = np.zeros(i + 2, np.complex128)
            zv = mmp if prec is not None else V[i]
            mat(V[i + 1], zv)
            g.orthogonalize(
                V[i + 1],
                V[0:i + 1],
                ips[0:-1],
                nblock=10,
            )
            ips[-1] = g.norm2(V[i + 1])**0.5
            V[i + 1] /= ips[-1]
            H.append(ips)
        return H
コード例 #2
0
ファイル: multi_shift_fom.py プロジェクト: lehner/gpt
 def arnoldi(self, mat, V, rlen):
     H = []
     for i in range(rlen):
         ips = np.zeros(i + 2, np.complex128)
         mat(V[i + 1], V[i])
         g.orthogonalize(
             V[i + 1],
             V[0:i + 1],
             ips[0:-1],
             nblock=10,
         )
         ips[-1] = g.norm2(V[i + 1])**0.5
         V[i + 1] /= ips[-1]
         H.append(ips)
     return H
コード例 #3
0
ファイル: arnoldi.py プロジェクト: wettig/gpt
    def __call__(self):

        t0 = g.time()
        new = g.lattice(self.basis[-1])
        self.mat(new, self.basis[-1])
        t1 = g.time()
        ips = np.zeros((len(self.basis) + 1, ), np.complex128)
        g.orthogonalize(new, self.basis, ips[0:-1])
        ips[-1] = g.norm2(new)**0.5
        new /= ips[-1]
        self.basis.append(new)
        self.H.append(ips)
        t2 = g.time()

        if self.verbose:
            g.message(
                f"Arnoldi: len(H) = {len(self.H)} took {t1-t0} s for matrix and {t2-t1} s for linear algebra"
            )
コード例 #4
0
    def __call__(self, second_orthogonalization=True):
        t0 = g.time()
        new = g.lattice(self.basis[-1])
        self.mat(new, self.basis[-1])
        t1 = g.time()
        ips = np.zeros((len(self.basis) + 1, ), np.complex128)
        g.orthogonalize(new, self.basis, ips[0:-1])
        if second_orthogonalization:
            delta_ips = np.zeros((len(self.basis) + 1, ), np.complex128)
            g.orthogonalize(new, self.basis, delta_ips[0:-1])
            # the following line may be omitted
            ips += delta_ips
        ips[-1] = g.norm2(new)**0.5
        new /= ips[-1]
        self.basis.append(new)
        self.H.append(ips)
        t2 = g.time()

        if self.verbose:
            g.message(
                f"Arnoldi: len(H) = {len(self.H)} took {t1-t0} s for matrix and {t2-t1} s for linear algebra"
            )
コード例 #5
0
ファイル: fgmres.py プロジェクト: ssolbUR/gpt
    def __call__(self, mat, src, psi, prec=None):
        # verbosity
        self.verbose = g.default.is_verbose("fgmres")
        checkres = True  # for now

        # total time
        tt0 = time()

        # parameters
        rlen = self.restartlen

        # tensors
        dtype = np.complex128
        H = np.zeros((rlen + 1, rlen), dtype)
        c = np.zeros((rlen + 1), dtype)
        s = np.zeros((rlen + 1), dtype)
        y = np.zeros((rlen + 1), dtype)
        gamma = np.zeros((rlen + 1), dtype)

        # fields
        mmpsi, r = g.copy(src), g.copy(src),
        V = [g.lattice(src) for i in range(rlen + 1)]
        if not prec is None:  # save vectors if unpreconditioned
            Z = [g.lattice(src) for i in range(rlen + 1)]

        # residual
        ssq = g.norm2(src)
        rsq = self.eps**2. * ssq

        # initial values
        r2 = self.restart(mat, psi, mmpsi, src, r, V, gamma)

        for k in range(self.maxiter):
            # iteration within current krylov space
            i = k % rlen

            # iteration criteria
            reached_maxiter = (k + 1 == self.maxiter)
            need_restart = (i + 1 == rlen)

            t0 = time()
            if not prec is None:
                prec(V[i], Z[i])
            t1 = time()

            t2 = time()
            if not prec is None:
                mat(Z[i], V[i + 1])
            else:
                mat(V[i], V[i + 1])
            t3 = time()

            t4 = time()
            g.orthogonalize(V[i + 1], V[0:i + 1], H[:, i])
            t5 = time()

            t6 = time()
            H[i + 1, i] = g.norm2(V[i + 1])**0.5

            if H[i + 1, i] == 0.:
                g.message("fgmres breakdown, H[%d, %d] = 0" % (i + 1, i))
                break

            V[i + 1] /= H[i + 1, i]
            t7 = time()

            t8 = time()
            self.qr_update(s, c, H, gamma, i)
            r2 = np.absolute(gamma[i + 1])**2
            t9 = time()

            if self.verbose:
                g.message(
                    "Timing[s]: Prec = %g, Matrix = %g, Orthog = %g, RestArnoldi = %g, QR = %g"
                    % (t1 - t0, t3 - t2, t5 - t4, t7 - t6, t9 - t8))
                g.message("res^2[ %d, %d ] = %g" % (k, i, r2))

            if r2 <= rsq or need_restart or reached_maxiter:
                if not prec is None:
                    self.update_psi(psi, gamma, H, y, Z, i)
                else:
                    self.update_psi(psi, gamma, H, y, V, i)

                if r2 <= rsq:
                    if self.verbose:
                        tt1 = time()
                        g.message("Converged in %g s" % (tt1 - tt0))
                    if checkres:
                        res = self.calc_res(mat, psi, mmpsi, src, r) / ssq
                        g.message(
                            "Computed res = %g, true res = %g, target = %g" %
                            (r2**0.5, res**0.5, self.eps))
                    break

                if reached_maxiter:
                    if verbose:
                        tt1 = time()
                        g.message("Did NOT converge in %g s" % (tt1 - tt0))
                        if checkres:
                            res = self.calc_res(mat, psi, mmpsi, src, r) / ssq
                            g.message(
                                "Computed res = %g, true res = %g, target = %g"
                                % (r2**0.5, res**0.5, self.eps))

                if need_restart:
                    r2 = self.restart(mat, psi, mmpsi, src, r, V, gamma)
                    if self.verbose:
                        g.message("Performed restart")
コード例 #6
0
    def __call__(self, which_lvls=None):
        if which_lvls is not None:
            assert type(which_lvls) == list
            for elem in which_lvls:
                assert elem >= self.finest and elem <= self.coarsest
        else:
            which_lvls = self.lvl

        for lvl in which_lvls:
            if lvl == self.coarsest:
                continue

            # aliases
            t = self.t[lvl]
            pp = self.print_prefix[lvl]

            # start clocks
            t("misc")

            # neighbors
            nc_lvl = self.nc_lvl[lvl]

            # aliases
            basis = self.basis[lvl]
            blockmap = self.blockmap[lvl]
            nb = self.nb[lvl]
            vector_type = self.vector_type[lvl]

            # pre-orthonormalize basis vectors globally
            t("pre_ortho")
            g.default.push_verbose("orthogonalize", False)
            for n in range(self.npreortho[lvl]):
                if self.verbose:
                    g.message("%s pre ortho step %d" % (pp, n))
                for i, v in enumerate(basis[0:nb]):
                    v /= g.norm2(v)**0.5
                    g.orthogonalize(v, basis[:i])
            g.default.pop_verbose()

            if self.verbose:
                g.message("%s done pre-orthonormalizing basis vectors" % pp)

            # find near-null vectors
            t("find_null_vecs")
            src, psi = g.copy(basis[0]), g.copy(basis[0])
            for i, v in enumerate(basis[0:nb]):
                if vector_type == "test":
                    psi[:] = 0.0
                    src @= v
                elif vector_type == "null":
                    src[:] = 0.0
                    psi @= v
                else:
                    assert 0
                g.default.push_verbose(get_slv_name(self.solver[lvl]), False)
                self.solver[lvl](self.mat[lvl])(psi, src)
                g.default.pop_verbose()
                self.history[lvl].append(get_slv_history(self.solver[lvl]))
                v @= psi

            if self.verbose:
                g.message("%s done finding null-space vectors" % pp)

            # post-orthonormalize basis vectors globally
            t("post_ortho")
            g.default.push_verbose("orthogonalize", False)
            for n in range(self.npostortho[lvl]):
                if self.verbose:
                    g.message("%s post ortho step %d" % (pp, n))
                for i, v in enumerate(basis[0:nb]):
                    v /= g.norm2(v)**0.5
                    g.orthogonalize(v, basis[:i])
            g.default.pop_verbose()

            if self.verbose:
                g.message("%s done post-orthonormalizing basis vectors" % pp)

            # chiral doubling
            t("chiral_split")
            g.coarse.split_chiral(basis)

            if self.verbose:
                g.message("%s done doing chiral doubling" % pp)

            # orthonormalize blocks
            t("block_ortho")
            for i in range(self.nblockortho[lvl]):
                if self.verbose:
                    g.message("%s block ortho step %d" % (pp, i))
                blockmap.orthonormalize()

            if self.check_blockortho:
                t("block_ortho_check")
                blockmap.check_orthogonality()

            if self.verbose:
                g.message("%s done block-orthonormalizing" % pp)

            # create coarse links + operator
            t("create_operator")
            g.coarse.create_links(
                self.A[nc_lvl],
                self.mat[lvl],
                self.basis[lvl],
                {
                    "make_hermitian": self.make_hermitian[lvl],
                    "save_links": self.save_links[lvl],
                },
            )
            self.mat[nc_lvl] = g.qcd.fermion.coarse(self.A[nc_lvl],
                                                    {"level": nc_lvl})

            if self.verbose:
                g.message("%s done setting up next coarser operator" % pp)

            t()

            if self.verbose:
                g.message("%s done with entire setup" % pp)
コード例 #7
0
ファイル: orthogonalize.py プロジェクト: wettig/gpt
#!/usr/bin/env python3
#
# Authors: Christoph Lehner 2020
#
# Desc.: Illustrate core concepts and features
#
import gpt as g
import numpy as np
import sys

# load configuration
fine_grid = g.grid([8, 8, 8, 16], g.single)

# basis
n = 31
basis = [g.vcomplex(fine_grid, 30) for i in range(n)]
rng = g.random("block_seed_string_13")
rng.cnormal(basis)

# gram-schmidt
for i in range(n):
    basis[i] /= g.norm2(basis[i]) ** 0.5
    g.orthogonalize(basis[i], basis[:i])

    for j in range(i):
        eps = g.inner_product(basis[j], basis[i])
        g.message(" <%d|%d> =" % (j, i), eps)
        assert abs(eps) < 1e-6
コード例 #8
0
ファイル: irl.py プロジェクト: mbruno46/gpt
    def step(self, mat, lmd, lme, evec, w, Nm, k):
        assert k < Nm

        verbose = g.default.is_verbose("irl")
        ckpt = self.ckpt

        alph = 0.0
        beta = 0.0

        evec_k = evec[k]

        results = [w, alph, beta]
        if ckpt.load(results):
            w, alph, beta = results  # use checkpoint

            if verbose:
                g.message("%-65s %-45s" %
                          ("alpha[ %d ] = %s" % (k, alph), "beta[ %d ] = %s" %
                           (k, beta)))

        else:
            if self.params["mem_report"]:
                g.mem_report(details=False)

            # compute
            t0 = g.time()
            mat(w, evec_k)
            t1 = g.time()

            # allow to restrict maximal number of applications within run
            self.napply += 1
            if "maxapply" in self.params:
                if self.napply == self.params["maxapply"]:
                    if verbose:
                        g.message(
                            "Maximal number of matrix applications reached")
                    sys.exit(0)

            if k > 0:
                w -= lme[k - 1] * evec[k - 1]

            zalph = g.inner_product(evec_k, w)
            alph = zalph.real

            w -= alph * evec_k

            beta = g.norm2(w)**0.5
            w /= beta

            t2 = g.time()
            if k > 0:
                g.orthogonalize(w, evec[0:k])
            t3 = g.time()

            ckpt.save([w, alph, beta])

            if verbose:
                g.message("%-65s %-45s %-50s" % (
                    "alpha[ %d ] = %s" % (k, zalph),
                    "beta[ %d ] = %s" % (k, beta),
                    " timing: %g s (matrix), %g s (ortho)" %
                    (t1 - t0, t3 - t2),
                ))

        lmd[k] = alph
        lme[k] = beta

        if k < Nm - 1:
            evec[k + 1] @= w
コード例 #9
0
    def __call__(self, mat, src, ckpt=None):

        # verbosity
        verbose = g.default.is_verbose("irl")

        # checkpointer
        if ckpt is None:
            ckpt = g.checkpointer_none()
        ckpt.grid = src.grid
        self.ckpt = ckpt

        # first approximate largest eigenvalue
        pit = g.algorithms.eigen.power_iteration(eps=0.05, maxiter=10, real=True)
        lambda_max = pit(mat, src)[0]

        # parameters
        Nm = self.params["Nm"]
        Nu = self.params["Nu"]
        Nk = self.params["Nk"]
        Nstop = self.params["Nstop"]
        Np = Nm-Nk
        MaxIter=self.params["maxiter"]
        Np /= MaxIter
        assert Nm >= Nk and Nstop <= Nk
        print ( 'Nm=',Nm,'Nu=',Nu,'Nk=',Nk )

        # tensors
        dtype = np.float64
        ctype = np.complex128
         
        lme = np.zeros((Nu,Nm), ctype)
        lmd = np.zeros((Nu,Nm), ctype)
        lme2 = np.zeros((Nu,Nm), ctype)
        lmd2 = np.empty((Nu,Nm), ctype)
        Qt = np.zeros((Nm,Nm),ctype)
        Q = np.zeros((Nm,Nm),ctype)
        ev = np.empty((Nm,), dtype)
        ev2_copy = np.empty((Nm,), dtype)

        # fields
        f = g.lattice(src)
        v = g.lattice(src)
        evec = [g.lattice(src) for i in range(Nm)]
        w = [g.lattice(src) for i in range(Nu)]
        w_copy = [g.lattice(src) for i in range(Nu)]

        # advice memory storage
        if not self.params["advise"] is None:
            g.advise(evec, self.params["advise"])

        # scalars
        k1 = 1
        k2 = Nk
        beta_k = 0.0

        rng=g.random("test")
        # set initial vector
#        rng.zn(w)
        for i in range(Nu):
            rng.zn(w[i])
            if i > 0: 
                g.orthogonalize(w[i],evec[0:i])
            evec[i]=g.copy(w[i])
            evec[i] *= 1.0/ g.norm2(evec[i]) ** 0.5
            g.message("norm(evec[%d]=%e "%(i,g.norm2(evec[i])))
            if i > 0: 
                for j in range(i):
                    ip=g.innerProduct(evec[j],w[i])
                    if np.abs(ip) >1e-6:
                        g.message("inner(evec[%d],w[%d])=%e %e"% (j,i,ip.real,ip.imag))
#           evec[i] @= src[i] / g.norm2(src[i]) ** 0.5

        # initial Nk steps
        Nblock_k = int(Nk/Nu)
        for b in range(Nblock_k):
            self.blockStep(mat, lmd, lme, evec, w, w_copy, Nm, b,Nu)

        Nblock_p = int(Np/Nu)
        # restarting loop
#        for it in range(self.params["maxiter"]):
        for it in range(MaxIter):
            if verbose:
                g.message("Restart iteration %d" % it)

            Nblock_l = Nblock_k + it*Nblock_p;
            Nblock_r = Nblock_l + Nblock_p;
            Nl = Nblock_l*Nu
            Nr = Nblock_r*Nu
#           ev2.resize(Nr)
            ev2 = np.empty((Nr,), dtype)

            for b in range(Nblock_l, Nblock_r):
                self.blockStep(mat,  lmd, lme, evec, w, w_copy, Nm, b,Nu)

            for u in range(Nu):
                for k in range(Nr):
                    lmd2[u,k]=lmd[u,k]
                    lme2[u,k]=lme[u,k]


            Qt = np.identity(Nr, ctype)
            
            # diagonalize
            t0 = g.time()
#            self.diagonalize(ev2, lme2, Nm, Qt)
            self.diagonalize(ev2,lmd2,lme2,Nu,Nr,Qt)
#    def diagonalize(self, eval, lmd, lme, Nu, Nk, Nm, Qt):
            t1 = g.time()

            if verbose:
                g.message("Diagonalization took %g s" % (t1 - t0))

            # sort
            ev2_copy = ev2.copy()
            ev2 = list(reversed(sorted(ev2)))

            for i in range(Nr):
                g.message("Rval[%d]= %e"%(i,ev2[i]))

            # rotate
#            t0 = g.time()
#            g.rotate(evec, Qt, k1 - 1, k2 + 1, 0, Nm)
#            t1 = g.time()

#            if verbose:
#                g.message("Basis rotation took %g s" % (t1 - t0))

            # convergence test
            if it >= self.params["Nminres"]:
                if verbose:
                    g.message("Rotation to test convergence")

                # diagonalize
                for k in range(Nr):
                    ev2[k] = ev[k]
            #        lme2[k] = lme[k]
                for u in range(Nu):
                    for k in range(Nr):
                        lmd2[u,k]=lmd[u,k]
                        lme2[u,k]=lme[u,k]
                Qt = np.identity(Nm, ctype)

                t0 = g.time()
#                self.diagonalize(ev2, lme2, Nk, Qt)
                self.diagonalize(ev2,lmd2,lme2,Nu,Nr,Qt)
                t1 = g.time()

                if verbose:
                    g.message("Diagonalization took %g s" % (t1 - t0))

                B = g.copy(evec[0])

                allconv = True
                if beta_k >= self.params["betastp"]:
                    jj = 1
                    while jj <= Nstop:
                        j = Nstop - jj
                        g.linear_combination(B, evec[0:Nr], Qt[j, 0:Nr])
                        g.message("norm=%e"%(g.norm2(B)))
                        B *= 1.0 / g.norm2(B) ** 0.5
                        if not ckpt.load(v):
                            mat(v, B)
                            ckpt.save(v)
                        ev_test = g.innerProduct(B, v).real
                        eps2 = g.norm2(v - ev_test * B) / lambda_max ** 2.0
                        if verbose:
                            g.message(
                                "%-65s %-45s %-50s"
                                % (
                                    "ev[ %d ] = %s" % (j, ev2_copy[j]),
                                    "<B|M|B> = %s" % (ev_test),
                                    "|M B - ev B|^2 / ev_max^2 = %s" % (eps2),
                                )
                            )
                        if eps2 > self.params["resid"]:
                            allconv = False
                        if jj == Nstop:
                            break
                        jj = min([Nstop, 2 * jj])

                if allconv:
                    if verbose:
                        g.message("Converged in %d iterations" % it)
                        break

        t0 = g.time()
        g.rotate(evec, Qt, 0, Nstop, 0, Nk)
        t1 = g.time()

        if verbose:
            g.message("Final basis rotation took %g s" % (t1 - t0))

        return (evec[0:Nstop], ev2_copy[0:Nstop])
コード例 #10
0
    def blockStep(self, mat, lmd, lme, evec, w, w_copy, Nm, b, Nu):
        assert (b+1)*Nu <= Nm

        verbose = g.default.is_verbose("irl")
        ckpt = self.ckpt

        alph = 0.0
        beta = 0.0
        L= b*Nu
        R= (b+1)*Nu


        for k in range (L,R):
            if self.params["mem_report"]:
                g.mem_report(details=False)
# compute
            t0 = g.time()
            if not ckpt.load(w[k-L]):
                mat(w[k-L], evec[k])
#                            mat(v, B)
                ckpt.save(w[k-L])
            t1 = g.time()
    
                # allow to restrict maximal number of applications within run
            self.napply += 1
            if "maxapply" in self.params:
                if self.napply == self.params["maxapply"]:
                    if verbose:
                        g.message("Maximal number of matrix applications reached")
                    sys.exit(0)
        for u in range (Nu):
            for k in range (u,Nu):
                ip=g.innerProduct(evec[L+k],evec[L+u])
                if np.abs(ip) >1e-6:
                    g.message("inner(evec[%d],evec[%d])=%e %e"% (L+k,L+u,ip.real,ip.imag))
    
        if b > 0:
            for u in range (Nu):
                for k in range (L-Nu+u,L):
                    w[u] -= np.conjugate(lme[u,k]) * evec[k]
                for k in range (L-Nu+u,L):
                    ip=g.innerProduct(evec[k],w[u])
#                    if g.norm2(ip)>1e-6:
                    if np.abs(ip) >1e-6:
                        g.message("inner(evec[%d],w[%d])=%e %e"% (k,u,ip.real,ip.imag))
        else:
            for u in range (Nu):
                g.message("norm(evec[%d])=%e"%(u,g.norm2(evec[u])))

        for u in range (Nu):
            for k in range (L+u,R):
                lmd[u][k] = g.innerProduct(evec[k],w[u])
                lmd[k-L][L+u]=np.conjugate(lmd[u][k])
            lmd[u][L+u]=np.real(lmd[u][L+u])

        for u in range (Nu):
            for k in range (L,R):
                w[u] -= lmd[u][k]*evec[k]
            for k in range (L,R):
                ip=g.innerProduct(evec[k],w[u])
                if np.abs(ip) >1e-6:
                    g.message("inner(evec[%d],w[%d])=%e %e"% (k,u,ip.real,ip.imag))
            w_copy[u] = g.copy(w[u]);

        for u in range (Nu):
            for k in range (L,R):
                lme[u][k]=0.;
       
        for u in range (Nu):
            g.orthogonalize(w[u],evec[0:R])
            w[u] *= 1.0 / g.norm2(w[u]) ** 0.5
            for k in range (R):
                ip=g.innerProduct(evec[k],w[u])
                if np.abs(ip) >1e-6:
                    g.message("inner(evec[%d],w[%d])=%e %e"% (k,u,ip.real,ip.imag))
       
        for u in range (Nu):
            g.orthogonalize(w[u],evec[0:R])
            w[u] *= 1.0 / g.norm2(w[u]) ** 0.5
            for k in range (R):
                ip=g.innerProduct(evec[k],w[u])
                if np.abs(ip) >1e-6:
                    g.message("inner(evec[%d],w[%d])=%e %e"% (k,u,ip.real,ip.imag))

        for u in range (0,Nu):
            if u >0: 
                g.orthogonalize(w[u],w[0:u])
            w[u] *= 1.0 / g.norm2(w[u]) ** 0.5
            for k in range (u):
                ip=g.innerProduct(w[k],w[u])
                if np.abs(ip) >1e-6:
                    g.message("inner(w[%d],w[%d])=%e %e"% (k,u,ip.real,ip.imag))
            ip=g.innerProduct(w[u],w[u])
            g.message("inner(w[%d],w[%d])=%e %e"% (u,u,ip.real,ip.imag))

        for u in range (Nu):
            for v in range (u,Nu):
                lme[u][L+v] = g.innerProduct(w[u],w_copy[v])
            lme[u][L+u] = np.real(lme[u][L+u])
        t3 = g.time()

        for u in range (Nu):
            for k in range (L+u,R):
                g.message( 
                    " In block %d, beta[%d][%d]=%e %e"
                    %( b, u, k-b*Nu,lme[u][k].real,lme[u][k].imag )
                )
    
#                ckpt.save([w, alph, beta])
    

        if b < (Nm/Nu - 1):
            for u in range (Nu):
                evec[R+u] = g.copy(w[u])
                ip=g.innerProduct(evec[R+u],evec[R+u])
                if np.abs(ip) >1e-6:
                    g.message("inner(evec[%d],evec[%d])=%e %e"% (R+u,R+u,ip.real,ip.imag))
コード例 #11
0
        def inv(psi, src, t):
            t("setup")

            # parameters
            rlen = self.restartlen

            # tensors
            dtype_r, dtype_c = g.double.real_dtype, g.double.complex_dtype
            alpha = np.empty((rlen), dtype_c)
            beta = np.empty((rlen, rlen), dtype_c)
            gamma = np.empty((rlen), dtype_r)
            chi = np.empty((rlen), dtype_c)

            # fields
            r, mmpsi = g.copy(src), g.copy(src)
            p = [g.lattice(src) for i in range(rlen)]
            z = [g.lattice(src) for i in range(rlen)]

            # initial residual
            r2 = self.restart(mat, psi, mmpsi, src, r, p)

            # source
            ssq = g.norm2(src)
            if ssq == 0.0:
                assert r2 != 0.0  # need either source or psi to not be zero
                ssq = r2

            # target residual
            rsq = self.eps ** 2.0 * ssq

            for k in range(self.maxiter):
                # iteration within current krylov space
                i = k % rlen

                # iteration criteria
                need_restart = i + 1 == rlen

                t("prec")
                if prec is not None:
                    prec(p[i], r)
                else:
                    p[i] @= r

                t("mat")
                mat(z[i], p[i])

                t("ortho")
                g.orthogonalize(z[i], z[0:i], beta[:, i])

                t("linalg")
                ip, z2 = g.inner_product_norm2(z[i], r)
                gamma[i] = z2 ** 0.5
                if gamma[i] == 0.0:
                    self.debug(f"breakdown, gamma[{i:d}] = 0")
                    break
                z[i] /= gamma[i]
                alpha[i] = ip / gamma[i]
                r2 = g.axpy_norm2(r, -alpha[i], z[i], r)

                t("other")
                self.log_convergence((k, i), r2, rsq)

                if r2 <= rsq or need_restart:
                    t("update_psi")
                    self.update_psi(psi, alpha, beta, gamma, chi, p, i)

                if r2 <= rsq:
                    msg = f"converged in {k+1} iterations;  computed squared residual {r2:e} / {rsq:e}"
                    if self.checkres:
                        res = self.calc_res(mat, psi, mmpsi, src, r)
                        msg += f";  true squared residual {res:e} / {rsq:e}"
                    self.log(msg)
                    return

                if need_restart:
                    t("restart")
                    r2 = self.restart(mat, psi, mmpsi, src, r, p)
                    self.debug("performed restart")

            msg = f"NOT converged in {k+1} iterations;  computed squared residual {r2:e} / {rsq:e}"
            if self.checkres:
                res = self.calc_res(mat, psi, mmpsi, src, r)
                msg += f";  true squared residual {res:e} / {rsq:e}"
            self.log(msg)
コード例 #12
0
ファイル: fgmres.py プロジェクト: lehner/gpt
        def inv(psi, src, t):
            # timing
            t("setup")

            # parameters
            rlen = self.restartlen

            # tensors
            dtype = g.double.complex_dtype
            H = np.zeros((rlen + 1, rlen), dtype)
            c = np.zeros((rlen + 1), dtype)
            s = np.zeros((rlen + 1), dtype)
            y = np.zeros((rlen + 1), dtype)
            gamma = np.zeros((rlen + 1), dtype)

            # fields
            mmpsi, r = (
                g.copy(src),
                g.copy(src),
            )
            V = [g.lattice(src) for i in range(rlen + 1)]
            Z = (
                [g.lattice(src) for i in range(rlen + 1)] if prec is not None else None
            )  # save vectors if unpreconditioned
            ZV = Z if prec is not None else V

            # initial residual
            t("restart")
            r2 = self.restart(mat, psi, mmpsi, src, r, V, Z, gamma, t)
            t("setup")

            # source
            ssq = g.norm2(src)
            if ssq == 0.0:
                assert r2 != 0.0  # need either source or psi to not be zero
                ssq = r2

            # target residual
            rsq = self.eps ** 2.0 * ssq

            for k in range(self.maxiter):
                # iteration within current krylov space
                i = k % rlen

                # iteration criteria
                need_restart = i + 1 == rlen

                t("prec")
                if prec is not None:
                    prec(ZV[i], V[i])

                t("mat")
                mat(V[i + 1], ZV[i])

                t("ortho")
                g.orthogonalize(V[i + 1], V[0 : i + 1], H[:, i], nblock=10)

                t("linalg norm2")
                H[i + 1, i] = g.norm2(V[i + 1]) ** 0.5
                if H[i + 1, i] == 0.0:
                    self.debug(f"breakdown, H[{i+1:d}, {i:d}] = 0")
                    break
                t("linalg div")
                V[i + 1] /= H[i + 1, i]

                t("qr")
                self.qr_update(s, c, H, gamma, i)

                t("other")
                r2 = np.absolute(gamma[i + 1]) ** 2
                self.log_convergence((k, i), r2, rsq)

                if r2 <= rsq or need_restart:
                    t("update_psi")
                    self.update_psi(psi, gamma, H, y, ZV, i)

                if r2 <= rsq:
                    msg = f"converged in {k+1} iterations;  computed squared residual {r2:e} / {rsq:e}"
                    if self.checkres:
                        res = self.calc_res(mat, psi, mmpsi, src, r, t)
                        msg += f";  true squared residual {res:e} / {rsq:e}"
                    self.log(msg)
                    return

                if need_restart:
                    t("restart")
                    r2 = self.restart(mat, psi, mmpsi, src, r, V, Z, gamma, t)
                    self.debug("performed restart")

            msg = f"NOT converged in {k+1} iterations;  computed squared residual {r2:e} / {rsq:e}"
            if self.checkres:
                res = self.calc_res(mat, psi, mmpsi, src, r, t)
                msg += f";  true squared residual {res:e} / {rsq:e}"
            self.log(msg)
コード例 #13
0
ファイル: fgcr.py プロジェクト: daknuett/gpt
        def inv(psi, src):
            self.history = []
            # verbosity
            verbose = g.default.is_verbose("fgcr")

            # timing
            t = g.timer("fgcr")
            t("setup")

            # parameters
            rlen = self.restartlen

            # tensors
            dtype_r, dtype_c = g.double.real_dtype, g.double.complex_dtype
            alpha = np.empty((rlen), dtype_c)
            beta = np.empty((rlen, rlen), dtype_c)
            gamma = np.empty((rlen), dtype_r)
            chi = np.empty((rlen), dtype_c)

            # fields
            r, mmpsi = g.copy(src), g.copy(src)
            p = [g.lattice(src) for i in range(rlen)]
            z = [g.lattice(src) for i in range(rlen)]

            # initial residual
            r2 = self.restart(mat, psi, mmpsi, src, r, p)

            # source
            ssq = g.norm2(src)
            if ssq == 0.0:
                assert r2 != 0.0  # need either source or psi to not be zero
                ssq = r2

            # target residual
            rsq = self.eps**2.0 * ssq

            for k in range(self.maxiter):
                # iteration within current krylov space
                i = k % rlen

                # iteration criteria
                reached_maxiter = k + 1 == self.maxiter
                need_restart = i + 1 == rlen

                t("prec")
                if prec is not None:
                    prec(p[i], r)
                else:
                    p[i] @= r

                t("mat")
                mat(z[i], p[i])

                t("ortho")
                g.default.push_verbose("orthogonalize", False)
                g.orthogonalize(z[i], z[0:i], beta[:, i])
                g.default.pop_verbose()

                t("linalg")
                ip, z2 = g.inner_product_norm2(z[i], r)
                gamma[i] = z2**0.5
                if gamma[i] == 0.0:
                    g.message("fgcr: breakdown, gamma[%d] = 0" % (i))
                    break
                z[i] /= gamma[i]
                alpha[i] = ip / gamma[i]
                r2 = g.axpy_norm2(r, -alpha[i], z[i], r)

                t("other")
                self.history.append(r2)

                if verbose:
                    g.message("fgcr: res^2[ %d, %d ] = %g, target = %g" %
                              (k, i, r2, rsq))

                if r2 <= rsq or need_restart or reached_maxiter:
                    t("update_psi")
                    self.update_psi(psi, alpha, beta, gamma, chi, p, i)
                    comp_res = r2 / ssq

                    if r2 <= rsq:
                        if verbose:
                            t()
                            g.message(
                                "fgcr: converged in %d iterations, took %g s" %
                                (k + 1, t.total))
                            g.message(t)
                            if self.checkres:
                                res = self.calc_res(mat, psi, mmpsi, src,
                                                    r) / ssq
                                g.message(
                                    "fgcr: computed res = %g, true res = %g, target = %g"
                                    % (comp_res**0.5, res**0.5, self.eps))
                            else:
                                g.message(
                                    "fgcr: computed res = %g, target = %g" %
                                    (comp_res**0.5, self.eps))
                        break

                    if reached_maxiter:
                        if verbose:
                            t()
                            g.message(
                                "fgcr: did NOT converge in %d iterations, took %g s"
                                % (k + 1, t.dt["total"]))
                            g.message(t)
                            if self.checkres:
                                res = self.calc_res(mat, psi, mmpsi, src,
                                                    r) / ssq
                                g.message(
                                    "fgcr: computed res = %g, true res = %g, target = %g"
                                    % (comp_res**0.5, res**0.5, self.eps))
                            else:
                                g.message(
                                    "fgcr: computed res = %g, target = %g" %
                                    (comp_res**0.5, self.eps))
                        break

                    if need_restart:
                        t("restart")
                        r2 = self.restart(mat, psi, mmpsi, src, r, p)
                        if verbose:
                            g.message("fgcr: performed restart")
コード例 #14
0
ファイル: basis.py プロジェクト: waterret/gpt
def orthonormalize(basis, nblock=4):
    for i, v in enumerate(basis):
        gpt.orthogonalize(v, basis[:i], nblock=nblock)
        v /= gpt.norm2(v) ** 0.5
    return basis
コード例 #15
0
ファイル: fgmres.py プロジェクト: krox/gpt
        def inv(psi, src):
            self.history = []
            # verbosity
            verbose = g.default.is_verbose("fgmres")

            # timing
            t = g.timer("fgmres")
            t("setup")

            # parameters
            rlen = self.restartlen

            # tensors
            dtype = g.double.complex_dtype
            H = np.zeros((rlen + 1, rlen), dtype)
            c = np.zeros((rlen + 1), dtype)
            s = np.zeros((rlen + 1), dtype)
            y = np.zeros((rlen + 1), dtype)
            gamma = np.zeros((rlen + 1), dtype)

            # fields
            mmpsi, r = (
                g.copy(src),
                g.copy(src),
            )
            V = [g.lattice(src) for i in range(rlen + 1)]
            Z = (
                [g.lattice(src) for i in range(rlen + 1)] if prec is not None else None
            )  # save vectors if unpreconditioned

            # initial residual
            r2 = self.restart(mat, psi, mmpsi, src, r, V, Z, gamma)

            # source
            ssq = g.norm2(src)
            if ssq == 0.0:
                assert r2 != 0.0  # need either source or psi to not be zero
                ssq = r2

            # target residual
            rsq = self.eps ** 2.0 * ssq

            for k in range(self.maxiter):
                # iteration within current krylov space
                i = k % rlen

                # iteration criteria
                reached_maxiter = k + 1 == self.maxiter
                need_restart = i + 1 == rlen

                t("prec")
                if prec is not None:
                    prec(Z[i], V[i])

                t("mat")
                if prec is not None:
                    mat(V[i + 1], Z[i])
                else:
                    mat(V[i + 1], V[i])

                t("ortho")
                g.default.push_verbose("orthogonalize", False)
                g.orthogonalize(V[i + 1], V[0 : i + 1], H[:, i])
                g.default.pop_verbose()

                t("linalg")
                H[i + 1, i] = g.norm2(V[i + 1]) ** 0.5
                if H[i + 1, i] == 0.0:
                    g.message("fgmres: breakdown, H[%d, %d] = 0" % (i + 1, i))
                    break
                V[i + 1] /= H[i + 1, i]

                t("qr")
                self.qr_update(s, c, H, gamma, i)

                t("other")
                r2 = np.absolute(gamma[i + 1]) ** 2
                self.history.append(r2)

                if verbose:
                    g.message(
                        "fgmres: res^2[ %d, %d ] = %g, target = %g" % (k, i, r2, rsq)
                    )

                if r2 <= rsq or need_restart or reached_maxiter:
                    t("update_psi")
                    if prec is not None:
                        self.update_psi(psi, gamma, H, y, Z, i)
                    else:
                        self.update_psi(psi, gamma, H, y, V, i)
                    comp_res = r2 / ssq

                    if r2 <= rsq:
                        if verbose:
                            t()
                            g.message(
                                "fgmres: converged in %d iterations, took %g s"
                                % (k + 1, t.dt["total"])
                            )
                            g.message(t)
                            if self.checkres:
                                res = self.calc_res(mat, psi, mmpsi, src, r) / ssq
                                g.message(
                                    "fgmres: computed res = %g, true res = %g, target = %g"
                                    % (comp_res ** 0.5, res ** 0.5, self.eps)
                                )
                            else:
                                g.message(
                                    "fgmres: computed res = %g, target = %g"
                                    % (comp_res ** 0.5, self.eps)
                                )
                        break

                    if reached_maxiter:
                        if verbose:
                            t()
                            g.message(
                                "fgmres: did NOT converge in %d iterations, took %g s"
                                % (k + 1, t.dt["total"])
                            )
                            g.message(t)
                            if self.checkres:
                                res = self.calc_res(mat, psi, mmpsi, src, r) / ssq
                                g.message(
                                    "fgmres: computed res = %g, true res = %g, target = %g"
                                    % (comp_res ** 0.5, res ** 0.5, self.eps)
                                )
                            else:
                                g.message(
                                    "fgmres: computed res = %g, target = %g"
                                    % (comp_res ** 0.5, self.eps)
                                )
                        break

                    if need_restart:
                        t("restart")
                        r2 = self.restart(mat, psi, mmpsi, src, r, V, Z, gamma)
                        if verbose:
                            g.message("fgmres: performed restart")
コード例 #16
0
ファイル: fgcr.py プロジェクト: ssolbUR/gpt
    def __call__(self, mat, src, psi, prec=None):
        # verbosity
        verbose = g.default.is_verbose("fgcr")
        checkres = True  # for now

        # total time
        tt0 = time()

        # parameters
        rlen = self.restartlen

        # tensors
        dtype_r, dtype_c = np.float64, np.complex128
        alpha = np.empty((rlen), dtype_c)
        beta = np.empty((rlen, rlen), dtype_c)
        gamma = np.empty((rlen), dtype_r)
        delta = np.empty((rlen), dtype_c)

        # fields
        r, mmr, mmpsi = g.copy(src), g.copy(src), g.copy(src)
        p = [g.lattice(src) for i in range(rlen)]
        mmp = [g.lattice(src) for i in range(rlen)]

        # residual target
        ssq = g.norm2(src)
        rsq = self.eps**2. * ssq

        # initial values
        r2 = self.restart(mat, psi, mmpsi, src, r)

        for k in range(self.maxiter):
            # iteration within current krylov space
            i = k % rlen

            # iteration criteria
            reached_maxiter = k + 1 == self.maxiter
            need_restart = i + 1 == rlen

            t0 = time()
            if not prec is None:
                prec(r, p[i])
            else:
                p[i] @= r
            t1 = time()

            t2 = time()
            mat(p[i], mmp[i])
            t3 = time()

            t4 = time()
            g.orthogonalize(mmp[i], mmp[0:i], beta[:, i])
            t5 = time()

            t6 = time()
            ip, mmp2 = g.innerProductNorm2(mmp[i], r)
            gamma[i] = mmp2**0.5

            if gamma[i] == 0.:
                g.message("fgcr breakdown, gamma[%d] = 0" % (i))
                break

            mmp[i] /= gamma[i]
            alpha[i] = ip / gamma[i]
            r2 = g.axpy_norm2(r, -alpha[i], mmp[i], r)
            t7 = time()

            if verbose:
                g.message(
                    "Timing[s]: Prec = %g, Matrix = %g, Orthog = %g, Rest = %g"
                    % (t1 - t0, t3 - t2, t5 - t4, t7 - t6))
                g.message("res^2[ %d, %d ] = %g" % (k, i, r2))

            if r2 <= rsq or need_restart or reached_maxiter:
                self.update_psi(psi, alpha, beta, gamma, delta, p, i)

                if r2 <= rsq:
                    if verbose:
                        tt1 = time()
                        g.message("Converged in %g s" % (tt1 - tt0))
                        if checkres:
                            res = self.calc_res(mat, psi, mmpsi, src, r) / ssq
                            g.message(
                                "Computed res = %g, true res = %g, target = %g"
                                % (r2**0.5, res**0.5, self.eps))
                    break

                if reached_maxiter:
                    if verbose:
                        tt1 = time()
                        g.message("Did NOT converge in %g s" % (tt1 - tt0))
                        if checkres:
                            res = self.calc_res(mat, psi, mmpsi, src, r) / ssq
                            g.message(
                                "Computed res = %g, true res = %g, target = %g"
                                % (r2**0.5, res**0.5, self.eps))

                if need_restart:
                    r2 = self.restart(mat, psi, mmpsi, src, r)
                    if verbose:
                        g.message("Performed restart")