46 #ifndef ANASAZI_MINRES_HPP 
   47 #define ANASAZI_MINRES_HPP 
   53 namespace Experimental {
 
   55 template <
class Scalar, 
class MV, 
class OP>
 
   56 class PseudoBlockMinres
 
   68   void setTol(
const std::vector<Scalar>& tolerances) { tolerances_ = tolerances; };
 
   69   void setMaxIter(
const int maxIt) { maxIt_ = maxIt; };
 
   83   std::vector<Scalar> tolerances_;
 
   86   void symOrtho(Scalar a, Scalar b, Scalar *c, Scalar *s, Scalar *r);
 
   88 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR 
   89   Teuchos::RCP<Teuchos::Time> AddTime_, ApplyOpTime_, ApplyPrecTime_, AssignTime_, DotTime_, LockTime_, NormTime_, ScaleTime_, TotalTime_;
 
   95 template <
class Scalar, 
class MV, 
class OP>
 
   97   ONE(Teuchos::ScalarTraits<Scalar>::one()), 
 
   98   ZERO(Teuchos::ScalarTraits<Scalar>::zero()) 
 
  100 #ifdef ANASAZI_TEUCHOS_TIME_MONITOR 
  119 template <
class Scalar, 
class MV, 
class OP>
 
  120 void PseudoBlockMinres<Scalar,MV,OP>::solve()
 
  122   #ifdef ANASAZI_TEUCHOS_TIME_MONITOR 
  127   int ncols = MVT::GetNumberVecs(*B_);
 
  131   std::vector<Scalar> alpha(ncols), beta, beta1(ncols), phibar, oldBeta(ncols,ZERO), epsln(ncols,ZERO), cs(ncols,-ONE), sn(ncols,ZERO), dbar(ncols,ZERO), oldeps(ncols), delta(ncols), gbar(ncols), phi(ncols), gamma(ncols), tmpvec(ncols);
 
  132   std::vector<int> indicesToRemove, newlyConverged, unconvergedIndices(ncols);
 
  136   V = MVT::Clone(*B_, ncols);
 
  137   Y = MVT::Clone(*B_, ncols);
 
  138   R1 = MVT::Clone(*B_, ncols);
 
  139   R2 = MVT::Clone(*B_, ncols);
 
  140   W = MVT::Clone(*B_, ncols);
 
  141   W1 = MVT::Clone(*B_, ncols);
 
  142   W2 = MVT::Clone(*B_, ncols);
 
  143   scaleHelper = MVT::Clone(*B_, ncols);
 
  146   indicesToRemove.reserve(ncols);
 
  147   newlyConverged.reserve(ncols);
 
  150   for(
int i=0; i<ncols; i++)
 
  151     unconvergedIndices[i] = i;
 
  155   locX = MVT::CloneCopy(*X_);
 
  160     #ifdef ANASAZI_TEUCHOS_TIME_MONITOR 
  163     OPT::Apply(*A_,*locX,*R1);
 
  166     #ifdef ANASAZI_TEUCHOS_TIME_MONITOR 
  169     MVT::MvAddMv(ONE, *B_, -ONE, *R1, *R1);
 
  174     #ifdef ANASAZI_TEUCHOS_TIME_MONITOR 
  177     MVT::Assign(*R1,*R2);
 
  185   if(Prec_ != Teuchos::null)
 
  187     #ifdef ANASAZI_TEUCHOS_TIME_MONITOR 
  191     OPT::Apply(*Prec_,*R1,*Y);
 
  195     #ifdef ANASAZI_TEUCHOS_TIME_MONITOR 
  203     #ifdef ANASAZI_TEUCHOS_TIME_MONITOR 
  206     MVT::MvDot(*Y,*R1, beta1);
 
  208     for(
size_t i=0; i<beta1.size(); i++)
 
  209       beta1[i] = sqrt(beta1[i]);
 
  220   for(
int iter=1; iter <= maxIt_; iter++)
 
  223     indicesToRemove.clear();
 
  224     for(
int i=0; i<ncols; i++)
 
  226       Scalar relres = phibar[i]/beta1[i];
 
  231       if(relres < tolerances_[i])
 
  233         indicesToRemove.push_back(i);
 
  238     newNumConverged = indicesToRemove.size();
 
  239     if(newNumConverged > 0)
 
  241       #ifdef ANASAZI_TEUCHOS_TIME_MONITOR 
  246       newlyConverged.resize(newNumConverged);
 
  247       for(
int i=0; i<newNumConverged; i++)
 
  248         newlyConverged[i] = unconvergedIndices[indicesToRemove[i]];
 
  252       MVT::SetBlock(*helperLocX,newlyConverged,*X_);
 
  255       if(newNumConverged == ncols)
 
  259       std::vector<int> helperVec(ncols - newNumConverged);
 
  261       std::set_difference(unconvergedIndices.begin(), unconvergedIndices.end(), newlyConverged.begin(), newlyConverged.end(), helperVec.begin());
 
  262       unconvergedIndices = helperVec;
 
  265       std::vector<int> thingsToKeep(ncols - newNumConverged);
 
  266       helperVec.resize(ncols);
 
  267       for(
int i=0; i<ncols; i++)
 
  269       ncols = ncols - newNumConverged;
 
  271       std::set_difference(helperVec.begin(), helperVec.end(), indicesToRemove.begin(), indicesToRemove.end(), thingsToKeep.begin());
 
  275       helperMV = MVT::CloneCopy(*V,thingsToKeep);
 
  277       helperMV = MVT::CloneCopy(*Y,thingsToKeep);
 
  279       helperMV = MVT::CloneCopy(*R1,thingsToKeep);
 
  281       helperMV = MVT::CloneCopy(*R2,thingsToKeep);
 
  283       helperMV = MVT::CloneCopy(*W,thingsToKeep);
 
  285       helperMV = MVT::CloneCopy(*W1,thingsToKeep);
 
  287       helperMV = MVT::CloneCopy(*W2,thingsToKeep);
 
  289       helperMV = MVT::CloneCopy(*locX,thingsToKeep);
 
  291       scaleHelper = MVT::Clone(*V,ncols);
 
  295       oldeps.resize(ncols);
 
  300       tmpvec.resize(ncols);
 
  301       std::vector<Scalar> helperVecS(ncols);
 
  302       for(
int i=0; i<ncols; i++)
 
  303         helperVecS[i] = beta[thingsToKeep[i]];
 
  305       for(
int i=0; i<ncols; i++)
 
  306         helperVecS[i] = beta1[thingsToKeep[i]];
 
  308       for(
int i=0; i<ncols; i++)
 
  309         helperVecS[i] = phibar[thingsToKeep[i]];
 
  311       for(
int i=0; i<ncols; i++)
 
  312         helperVecS[i] = oldBeta[thingsToKeep[i]];
 
  313       oldBeta = helperVecS;
 
  314       for(
int i=0; i<ncols; i++)
 
  315         helperVecS[i] = epsln[thingsToKeep[i]];
 
  317       for(
int i=0; i<ncols; i++)
 
  318         helperVecS[i] = cs[thingsToKeep[i]];
 
  320       for(
int i=0; i<ncols; i++)
 
  321         helperVecS[i] = sn[thingsToKeep[i]];
 
  323       for(
int i=0; i<ncols; i++)
 
  324         helperVecS[i] = dbar[thingsToKeep[i]];
 
  328       A_->removeIndices(indicesToRemove);
 
  334       #ifdef ANASAZI_TEUCHOS_TIME_MONITOR 
  339     for(
int i=0; i<ncols; i++)
 
  340       tmpvec[i] = ONE/beta[i];
 
  342       #ifdef ANASAZI_TEUCHOS_TIME_MONITOR 
  345       MVT::MvScale (*V, tmpvec);
 
  351       #ifdef ANASAZI_TEUCHOS_TIME_MONITOR 
  354       OPT::Apply(*A_, *V, *Y);
 
  360       for(
int i=0; i<ncols; i++)
 
  361         tmpvec[i] = beta[i]/oldBeta[i];
 
  363         #ifdef ANASAZI_TEUCHOS_TIME_MONITOR 
  366         MVT::Assign(*R1,*scaleHelper);
 
  369         #ifdef ANASAZI_TEUCHOS_TIME_MONITOR 
  372         MVT::MvScale(*scaleHelper,tmpvec);
 
  375         #ifdef ANASAZI_TEUCHOS_TIME_MONITOR 
  378         MVT::MvAddMv(ONE, *Y, -ONE, *scaleHelper, *Y);
 
  384       #ifdef ANASAZI_TEUCHOS_TIME_MONITOR 
  387       MVT::MvDot(*V, *Y, alpha);
 
  391     for(
int i=0; i<ncols; i++)
 
  392       tmpvec[i] = alpha[i]/beta[i];
 
  394       #ifdef ANASAZI_TEUCHOS_TIME_MONITOR 
  397       MVT::Assign(*R2,*scaleHelper);
 
  400       #ifdef ANASAZI_TEUCHOS_TIME_MONITOR 
  403       MVT::MvScale(*scaleHelper,tmpvec);
 
  406       #ifdef ANASAZI_TEUCHOS_TIME_MONITOR 
  409       MVT::MvAddMv(ONE, *Y, -ONE, *scaleHelper, *Y);
 
  420     if(Prec_ != Teuchos::null)
 
  422       #ifdef ANASAZI_TEUCHOS_TIME_MONITOR 
  426       OPT::Apply(*Prec_,*R2,*Y);
 
  430       #ifdef ANASAZI_TEUCHOS_TIME_MONITOR 
  440       #ifdef ANASAZI_TEUCHOS_TIME_MONITOR 
  443       MVT::MvDot(*Y,*R2, beta);
 
  445       for(
int i=0; i<ncols; i++)
 
  446         beta[i] = sqrt(beta[i]);
 
  451     for(
int i=0; i<ncols; i++)
 
  453       delta[i] = cs[i]*dbar[i]    + sn[i]*alpha[i];
 
  454       gbar[i]  = sn[i]*dbar[i]    - cs[i]*alpha[i];
 
  455       epsln[i] =                    sn[i]*beta[i];
 
  456       dbar[i]  =                  - cs[i]*beta[i];
 
  460     for(
int i=0; i<ncols; i++)
 
  462       symOrtho(gbar[i], beta[i], &cs[i], &sn[i], &gamma[i]);
 
  464       phi[i] = cs[i]*phibar[i];
 
  465       phibar[i] = sn[i]*phibar[i];
 
  477       #ifdef ANASAZI_TEUCHOS_TIME_MONITOR 
  480       MVT::Assign(*W1,*scaleHelper);
 
  483       #ifdef ANASAZI_TEUCHOS_TIME_MONITOR 
  486       MVT::MvScale(*scaleHelper,oldeps);
 
  489       #ifdef ANASAZI_TEUCHOS_TIME_MONITOR 
  492       MVT::MvAddMv(ONE, *V, -ONE, *scaleHelper, *W);
 
  495       #ifdef ANASAZI_TEUCHOS_TIME_MONITOR 
  498       MVT::Assign(*W2,*scaleHelper);
 
  501       #ifdef ANASAZI_TEUCHOS_TIME_MONITOR 
  504       MVT::MvScale(*scaleHelper,delta);
 
  507       #ifdef ANASAZI_TEUCHOS_TIME_MONITOR 
  510       MVT::MvAddMv(ONE, *W, -ONE, *scaleHelper, *W);
 
  512     for(
int i=0; i<ncols; i++)
 
  513       tmpvec[i] = ONE/gamma[i];
 
  515       #ifdef ANASAZI_TEUCHOS_TIME_MONITOR 
  518       MVT::MvScale(*W,tmpvec);
 
  524       #ifdef ANASAZI_TEUCHOS_TIME_MONITOR 
  527       MVT::Assign(*W,*scaleHelper);
 
  530       #ifdef ANASAZI_TEUCHOS_TIME_MONITOR 
  533       MVT::MvScale(*scaleHelper,phi);
 
  536       #ifdef ANASAZI_TEUCHOS_TIME_MONITOR 
  539       MVT::MvAddMv(ONE, *locX, ONE, *scaleHelper, *locX);
 
  545     #ifdef ANASAZI_TEUCHOS_TIME_MONITOR 
  548     MVT::SetBlock(*locX,unconvergedIndices,*X_);
 
  552 template <
class Scalar, 
class MV, 
class OP>
 
  553 void PseudoBlockMinres<Scalar,MV,OP>::symOrtho(Scalar a, Scalar b, Scalar *c, Scalar *s, Scalar *r)
 
  555   const Scalar absA = std::abs(a);
 
  556   const Scalar absB = std::abs(b);
 
  557   if ( absB == ZERO ) {
 
  564   } 
else if ( absA == ZERO ) {
 
  568   } 
else if ( absB >= absA ) { 
 
  571       *s = -ONE / sqrt( ONE+tau*tau );
 
  573       *s =  ONE / sqrt( ONE+tau*tau );
 
  579       *c = -ONE / sqrt( ONE+tau*tau );
 
  581       *c =  ONE / sqrt( ONE+tau*tau );
 
Virtual base class which defines basic traits for the operator type. 
 
static RCP< Time > getNewTimer(const std::string &name)
 
Traits class which defines basic operations on multivectors. 
 
Anasazi header file which uses auto-configuration information to include necessary C++ headers...