예제 #1
0
파일: Exp4.py 프로젝트: rngantner/ExpInt
 def phiv(self, h, v):
     """
     Computes phi(h*Hm)*v and two other vectors
     
     :param h: factor
     :param v: vector to apply phi(h*Hm) to
     :returns: 3-tuple of vectors ``( phi(h/3*Hm)*v, phi(2h/3*Hm)*v, phi(h*Hm)*v )``
     """
     # if Df is nearly singular, Df^-1 * (exp(Df)-1)*v is numerically ill-conditioned, but should give v
     # check norm of Jacobian:
     if self.rhs.normDf(self.y[-1]) < np.finfo(np.double).eps:
         return (v,v,v)
     
     # if v is too small, phi*v is also almost zero.
     # must check for this since arnoldi iterations needs v != 0
     if norm(v) < np.finfo(np.double).eps:
         res = np.zeros_like(v)
         return (res,res,res)
     
     # use flag argument to find correct KrylovPhi instance
     pk = KrylovPhi(self.rhs, exp4=self, tau=h)
     
     # compute Krylov subspace approximation of phi(h*A)*v
     pk.compute(v)
     p1,p2,p3 = pk.phi3()
     if self.stats:
         self.stats["RHSevals"] += pk.m-1 # dimension of Krylov space minus 1 corresponds to number of applyA calls
     
     return (p1, p2, p3)
예제 #2
0
파일: Exp4.py 프로젝트: rngantner/ExpInt
 def phiv(self, h, v, flag=-1, reuse=False):
     """
     Computes phi(h*Hm)*v and two other vectors
     
     :param h: factor
     :param v: vector to apply phi(h*Hm) to
     :param flag: if it is in (0,1,2), use corresponding instance of ``PhiKrylov``
     :param reuse: if True, attempt to reuse the old Krylov space
     :returns: 3-tuple of vectors ``( phi(h/3*Hm)*v, phi(2h/3*Hm)*v, phi(h*Hm)*v )``
     """
     # if Df is nearly singular, Df^-1 * (exp(Df)-1)*v is numerically ill-conditioned, but should give v
     # check norm of Jacobian:
     if self.rhs.normDf(self.y[-1]) < np.finfo(np.double).eps:
         return (v,v,v)
     
     # if v is too small, phi*v is also almost zero.
     # must check for this since arnoldi iterations needs v != 0
     if norm(v) < np.finfo(np.double).eps:
         res = np.zeros_like(v)
         return (res,res,res)
     
     # use flag argument to find correct KrylovPhi instance
     if not flag in [0,1,2]:
         pk = KrylovPhi(self.rhs, exp4=self, tau=h)
         reuse = False
     else:
         pk = self.krylov[flag]
         pk.tau = h
         if np.isscalar(v) or len(v) <= pk.m_max:
             reuse = False
     
     # reuse already computed krylov space
     if reuse:
         p1,p2,p3 = pk.phi3()
     else:
         # compute Krylov subspace approximation of phi(h*A)*v
         pk.compute(v)
         if self.stats:
             # dimension of Krylov space minus 1 corresponds to number of applyA calls
             self.stats["RHSevals"] += pk.m-1
     p1,p2,p3 = pk.phi3()
     
     return (p1, p2, p3)