Esempio n. 1
0
    def __call__(self,
                 x0=None,
                 **kwargs):  ## > runs cg with/without preconditioner
        """
            Runs the conjugate gradient minimization.

            Parameters
            ----------
            x0 : field, *optional*
                Starting guess for the minimization.
            tol : scalar, *optional*
                Tolerance specifying convergence; measured by current relative
                residual (default: 1E-4).
            clevel : integer, *optional*
                Number of times the tolerance should be undershot before
                exiting (default: 1).
            limii : integer, *optional*
                Maximum number of iterations performed (default: 10 * b.dim()).

            Returns
            -------
            x : field
                Latest `x` of the minimization.
            convergence : integer
                Latest convergence level indicating whether the minimization
                has converged or not.

        """
        self.x = field(self.b.domain, val=x0, target=self.b.target)

        if (self.W is None):
            return self._calc_without(**kwargs)
        else:
            return self._calc_with(**kwargs)
Esempio n. 2
0
    def __call__(self,x0=None,**kwargs): ## > runs cg with/without preconditioner
        """
            Runs the conjugate gradient minimization.

            Parameters
            ----------
            x0 : field, *optional*
                Starting guess for the minimization.
            tol : scalar, *optional*
                Tolerance specifying convergence; measured by current relative
                residual (default: 1E-4).
            clevel : integer, *optional*
                Number of times the tolerance should be undershot before
                exiting (default: 1).
            limii : integer, *optional*
                Maximum number of iterations performed (default: 10 * b.dim()).

            Returns
            -------
            x : field
                Latest `x` of the minimization.
            convergence : integer
                Latest convergence level indicating whether the minimization
                has converged or not.

        """
        self.x = field(self.b.domain,val=x0,target=self.b.target)

        if(self.W is None):
            return self._calc_without(**kwargs)
        else:
            return self._calc_with(**kwargs)
Esempio n. 3
0
 def _briefing(self, x):  ## > prepares x for `multiply`
     ## inspect x
     if (not isinstance(x, field)):
         return field(self.domain, val=x, target=None), False
     ## check x.domain
     elif (x.domain == self.domain):
         return x, False
     elif (x.domain == self.codomain):
         return x, True
     ## transform
     else:
         return x.transform(target=self.codomain, overwrite=False), True
Esempio n. 4
0
 def _briefing(self,x): ## > prepares x for `multiply`
     ## inspect x
     if(not isinstance(x,field)):
         return field(self.domain,val=x,target=None),False
     ## check x.domain
     elif(x.domain==self.domain):
         return x,False
     elif(x.domain==self.codomain):
         return x,True
     ## transform
     else:
         return x.transform(target=self.codomain,overwrite=False),True
Esempio n. 5
0
    def _calc_without(self,
                      tol=1E-4,
                      clevel=1,
                      limii=None):  ## > runs cg without preconditioner
        clevel = int(clevel)
        if (limii is None):
            limii = 10 * self.b.domain.dim(split=False)
        else:
            limii = int(limii)

        r = self.b - self.A(self.x)
        d = field(self.b.domain, val=np.copy(r.val), target=self.b.target)
        gamma = r.dot(d)
        if (gamma == 0):
            return self.x, clevel + 1
        delta_ = np.absolute(gamma)**(-0.5)

        convergence = 0
        ii = 1
        while (True):
            q = self.A(d)
            alpha = gamma / d.dot(q)  ## positive definite
            if (not np.isfinite(alpha)):
                self.note.cprint(
                    "\niteration : %08u   alpha = NAN\n... dead." % ii)
                return self.x, 0
            self.x += alpha * d
            if (np.signbit(np.real(alpha))):
                about.warnings.cprint(
                    "WARNING: positive definiteness of A violated.")
                r = self.b - self.A(self.x)
            elif (ii % self.reset == 0):
                r = self.b - self.A(self.x)
            else:
                r -= alpha * q
            gamma_ = gamma
            gamma = r.dot(r)
            beta = max(0, gamma / gamma_)  ## positive definite
            d = r + beta * d

            delta = delta_ * np.absolute(gamma)**0.5
            self.note.cflush(
                "\niteration : %08u   alpha = %3.1E   beta = %3.1E   delta = %3.1E"
                % (ii, np.real(alpha), np.real(beta), np.real(delta)))
            if (gamma == 0):
                convergence = clevel + 1
                self.note.cprint("   convergence level : INF\n... done.")
                break
            elif (np.absolute(delta) < tol):
                convergence += 1
                self.note.cflush("   convergence level : %u" % convergence)
                if (convergence == clevel):
                    self.note.cprint("\n... done.")
                    break
            else:
                convergence = max(0, convergence - 1)
            if (ii == limii):
                self.note.cprint("\n... quit.")
                break

            if (self.spam is not None):
                self.spam(self.x, ii)

            ii += 1

        if (self.spam is not None):
            self.spam(self.x, ii)

        return self.x, convergence
Esempio n. 6
0
    def _calc_without(self,tol=1E-4,clevel=1,limii=None): ## > runs cg without preconditioner
        clevel = int(clevel)
        if(limii is None):
            limii = 10*self.b.domain.dim(split=False)
        else:
            limii = int(limii)

        r = self.b-self.A(self.x)
        d = field(self.b.domain,val=np.copy(r.val),target=self.b.target)
        gamma = r.dot(d)
        if(gamma==0):
            return self.x,clevel+1
        delta_ = np.absolute(gamma)**(-0.5)

        convergence = 0
        ii = 1
        while(True):
            q = self.A(d)
            alpha = gamma/d.dot(q) ## positive definite
            if(not np.isfinite(alpha)):
                self.note.cprint("\niteration : %08u   alpha = NAN\n... dead."%ii)
                return self.x,0
            self.x += alpha*d
            if(np.signbit(np.real(alpha))):
                about.warnings.cprint("WARNING: positive definiteness of A violated.")
                r = self.b-self.A(self.x)
            elif(ii%self.reset==0):
                r = self.b-self.A(self.x)
            else:
                r -= alpha*q
            gamma_ = gamma
            gamma = r.dot(r)
            beta = max(0,gamma/gamma_) ## positive definite
            d = r+beta*d

            delta = delta_*np.absolute(gamma)**0.5
            self.note.cflush("\niteration : %08u   alpha = %3.1E   beta = %3.1E   delta = %3.1E"%(ii,np.real(alpha),np.real(beta),np.real(delta)))
            if(gamma==0):
                convergence = clevel+1
                self.note.cprint("   convergence level : INF\n... done.")
                break
            elif(np.absolute(delta)<tol):
                convergence += 1
                self.note.cflush("   convergence level : %u"%convergence)
                if(convergence==clevel):
                    self.note.cprint("\n... done.")
                    break
            else:
                convergence = max(0,convergence-1)
            if(ii==limii):
                self.note.cprint("\n... quit.")
                break

            if(self.spam is not None):
                self.spam(self.x,ii)

            ii += 1

        if(self.spam is not None):
            self.spam(self.x,ii)

        return self.x,convergence