⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 krylov.py

📁 利用C
💻 PY
📖 第 1 页 / 共 2 页
字号:
# -*- coding: utf-8 -*-"""@license: Copyright (C) 2005Author: 脜smund 脴deg氓rd, Ola Skavhaug, Gunnar StaffSimula Research Laboratory ASThis file is part of PyCC.PyCC  free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.PyCC is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with PyFDM; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USAConjGrad: A generic implementation of the (preconditioned) conjugate gradient method.""""""Solve Ax = b with the Krylov methods.A: Matrix or discrete operator. Must support A*x to operate on x.x: Anything that A can operate on, as well as support inner productand multiplication/addition/subtraction with scalars and vectors. Alsoincremental operators like __imul__ and __iadd__ might be neededb: Right-hand side, probably the same type as x."""#from debug import debugdef debug(string, level):    print stringimport numpy as _nfrom math import sqrt#debug("Deprecation warning: You have imported Krylov.py. Use Solvers.py instead",level=0)def inner(u,v):    """Compute innerproduct of u and v.       It is not computed here, we just check type of operands and       call a suitable innerproduct method"""    if isinstance(u,_n.ndarray):        # assume both are numarrays:        return _n.dot(u,v)    else:        # assume that left operand implements inner        return u.inner(v) """Conjugate Gradient Methods"""def conjgrad(A, x, b, tolerance=1.0E-05, relativeconv=False, maxit=500):    """    conjgrad(A,x,b): Solve Ax = b with the conjugate gradient method.    @param A: See module documentation    @param x: See module documentation    @param b: See module documentation    @param tolerance: Convergence criterion    @type tolerance: float    @param relativeconv: Control relative vs. absolute convergence criterion.    That is, if relativeconv is True, ||r||_2/||r_init||_2 is used as    convergence criterion, else just ||r||_2 is used.  Actually ||r||_2^2 is    used, since that save a few cycles.    @type relativeconv: bool    @return:  the solution x.    """    r = b - A*x    p = 1.0*r    r0 = inner(r,r)    if relativeconv:        tolerance *= sqrt(inner(b,b))    iter = 0    while sqrt(r0) > tolerance and iter <= maxit:        w = A*p        a = r0/inner(p,w)        x += a*p        r -= a*w        r1 = inner(r,r)        p *= r1/r0        p += r        r0 = r1        print "rho ", sqrt(r0)        iter += 1    #debug("CG finished, iter: %d, ||e||=%e" % (iter,sqrt(r0)))    return xdef precondconjgrad(B, A, x, b, tolerance=1.0E-05, relativeconv=False, maxiter=500):    r"""Preconditioned Conjugate Gradients method. Algorithm described here;     http://www.math-linux.com/spip.php?article55"""    r = b - A*x    z = B*r    d = 1.0*z    rz = inner(r,z)    if relativeconv: tolerance *= sqrt(rz)    iter = 0    while sqrt(rz) > tolerance and iter <= maxiter:        z = A*d        alpha = rz / inner(d,z)        x += alpha*d        r -= alpha*z        z = B*r        rz_prev = rz        rz = inner(r,z)        print "rho ", sqrt(rz)         beta =  rz / rz_prev        d = z + beta*d        iter += 1    return xdef old_precondconjgrad(B, A, x, b, tolerance=1.0E-05, relativeconv=False, maxiter=500):    """    conjgrad(B,A,x,b): Solve Ax = b with the preconditioned conjugate gradient method.    @param B: Preconditioner supporting the __mul__ operator for operating on    x.    @param A: Matrix or discrete operator. Must support A*x to operate on x.    @param x: Anything that A can operate on, as well as support inner product    and multiplication/addition/subtraction with scalar and something of the    same type    @param b: Right-hand side, probably the same type as x.    @param tolerance: Convergence criterion    @type tolerance: float    @param relativeconv: Control relative vs. absolute convergence criterion.    That is, if relativeconv is True, ||r||_2/||r_init||_2 is used as    convergence criterion, else just ||r||_2 is used.  Actually ||r||_2^2 is    used, since that save a few cycles.    @type relativeconv: bool    @return:  the solution x.    """    r0 = b - A*x    r = 1.0*r0    z = 1.0*r    s = B*r    p = 1.0*s    rho = rho0 = inner(s, r)    if relativeconv:        tolerance *= sqrt(inner(B*b,b))    iter = 0    while sqrt(rho0) > tolerance and iter <= maxiter:        z = A*p        t = B*z        g = inner(p,z)        a = rho0/g        x += a*p        r -= a*z        s -= a*t        rho = inner(s, r)        b = rho/rho0        p *= b; p += s        rho0 = rho        iter += 1    debug("PCG finished, iter: %d, ||rho||=%e" % (iter,sqrt(rho0)))    return x"""Bi-conjugate gradients method"""def BiCGStab(A, x, b, tolerance=1.0E-05, relativeconv=False, maxiter=1000, info=False):    """    BiCGStab(A,x,b): Solve Ax = b with the Biconjugate gradient stabilized    method.    @param A: Matrix or discrete operator. Must support A*x to operate on x.    @param x: Anything that A can operate on, as well as support inner product    and multiplication/addition/subtraction with scalar and something of the    same type    @param b: Right-hand side, probably the same type as x.    @param tolerance: Convergence criterion    @type tolerance: float    @param relativeconv: Control relative vs. absolute convergence criterion.    That is, if relativeconv is True, ||r||_2/||r_init||_2 is used as    convergence criterion, else just ||r||_2 is used.  Actually ||r||_2^2 is    used, since that save a few cycles.    @type relativeconv: bool    @return:  the solution x.    """    r = b - A*x    p = r.copy()    rs= r.copy()    rr = inner(r,rs)    if relativeconv:        tolerance *= sqrt(inner(b,b))    iter = 0    debug("r0=" +  str(sqrt(inner(r,r))), 0)    while sqrt(inner(r,r)) > tolerance  and  iter < maxiter:        Ap    = A*p        alpha = rr/inner(rs,Ap)        print "alpha ", alpha        s     = r-alpha*Ap        As    = A*s        w     = inner(As,s)/inner(As,As)        x    += alpha*p+w*s        r     = s -w*As#        r = b - A*x        rrn   = inner(r,rs)        beta  = (rrn/rr)*(alpha/w)        if beta==0.0:            debug("BiCGStab breakdown, beta=0, at iter=" + str(iter) + " with residual=" + str(sqrt(inner(r,r))), 0)#            return (x,iter,sqrt(inner(r,r)))            return x         rr    = rrn        p     = r+beta*(p-w*Ap)        iter += 1        #debug("r=",sqrt(inner(r,r)))    debug("BiCGStab finished, iter: " + str(iter) + "|r|= " + str(sqrt(inner(r,r))), 0)    if info:        info = {}        info["iter"] = iter        print "Her jeg her"         return x, info    return xdef precondBiCGStab(B, A, x, b, tolerance=1.0E-05, relativeconv=False, maxit=200):    """    precondBiCGStab(B,A,x,b): Solve Ax = b with the preconditioned biconjugate    gradient stabilized method.    @param B: Preconditioner supporting the __mul__ operator for operating on    x.    @param A: Matrix or discrete operator. Must support A*x to operate on x.    @param x: Anything that A can operate on, as well as support inner product    and multiplication/addition/subtraction with scalar and something of the    same type    @param b: Right-hand side, probably the same type as x.    @param tolerance: Convergence criterion    @type tolerance: float    @param relativeconv: Control relative vs. absolute convergence criterion.    That is, if relativeconv is True, ||r||_2/||r_init||_2 is used as    convergence criterion, else just ||r||_2 is used.  Actually ||r||_2^2 is    used, since that save a few cycles.    @type relativeconv: bool    @return:  the solution x.    """    r = b - A*x    debug("b0=%e"%sqrt(inner(b,b)),1)    p = r.copy()    rs= r.copy()    rr = inner(r,rs)    if relativeconv:        tolerance *= sqrt(inner(B*r,r))    iter = 0    # Alloc w    debug("r0=%e"%sqrt(inner(r,r)),1)    while sqrt(inner(r,r)) > tolerance and iter <= maxit:        #debug("iter, sqrt(inner(r,r))", iter, sqrt(inner(r,r)))        ph    = B*p        Ap    = A*ph        alpha = rr/inner(rs,Ap)        s     = r-alpha*Ap        sh    = B*s        As    = A*sh        w     = inner(As,s)/inner(As,As)        x    += alpha*ph+w*sh        r     = s -w*As        rrn   = inner(r,rs)        beta  = (rrn/rr)*(alpha/w)        if beta==0.0:            debug("BiCGStab breakdown, beta=0, at iter=" + str(iter)+" with residual=" + str(sqrt(inner(r,r))), 0)#            return (x,iter,sqrt(inner(r,r)))            return x        debug("|r|_%d = %e " %(iter,sqrt(inner(r,r))), 1)        rr    = rrn        p     = r+beta*(p-w*Ap)        iter += 1    debug("precondBiCGStab finished, iter: %d, ||e||=%e" % (iter,sqrt(inner(r,r))),1)    return (x,iter,sqrt(inner(r,r)))def precondLBiCGStab(B, A, x, b, tolerance=1.0E-05, relativeconv=False):    """    precondBiCGStab(B,A,x,b): Solve Ax = b with the preconditioned biconjugate    gradient stabilized method.    @param B: Preconditioner supporting the __mul__ operator for operating on    x.    @param A: Matrix or discrete operator. Must support A*x to operate on x.    @param x: Anything that A can operate on, as well as support inner product    and multiplication/addition/subtraction with scalar and something of the    same type    @param b: Right-hand side, probably the same type as x.    @param tolerance: Convergence criterion    @type tolerance: float    @param relativeconv: Control relative vs. absolute convergence criterion.    That is, if relativeconv is True, ||r||_2/||r_init||_2 is used as    convergence criterion, else just ||r||_2 is used.  Actually ||r||_2^2 is    used, since that save a few cycles.    @type relativeconv: bool    @return:  the solution x.    """    r = b - A*x    p = 1.0*r    rs= 1.0*r    rr = inner(r,rs)    if relativeconv:        tolerance *= sqrt(inner(b,b))    iter = 0    while sqrt(inner(r,r)) > tolerance:        Ap    = A*p        BAp   = B*Ap

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -