Belos  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
BelosTsqrOrthoManager.hpp
Go to the documentation of this file.
00001 //@HEADER
00002 // ************************************************************************
00003 //
00004 //                 Belos: Block Linear Solvers Package
00005 //                  Copyright 2004 Sandia Corporation
00006 //
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00008 // the U.S. Government retains certain rights in this software.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00038 //
00039 // ************************************************************************
00040 //@HEADER
00041 
00044 
00045 #ifndef __BelosTsqrOrthoManager_hpp
00046 #define __BelosTsqrOrthoManager_hpp
00047 
00048 #include "BelosTsqrOrthoManagerImpl.hpp"
00049 // Belos doesn't have an SVQB orthomanager implemented yet, so we just
00050 // use a default orthomanager for the case where the inner product
00051 // matrix is nontrivial.
00052 #include "BelosDGKSOrthoManager.hpp"
00053 
00054 
00055 namespace Belos {
00056 
00078 template<class Scalar, class MV>
00079 class OutOfPlaceNormalizerMixin {
00080 public:
00081   typedef Scalar scalar_type;
00082   typedef typename Teuchos::ScalarTraits<Scalar>::magnitudeType magnitude_type;
00085   typedef MV multivector_type;
00086 
00087   typedef Teuchos::SerialDenseMatrix<int, Scalar> mat_type;
00088   typedef Teuchos::RCP<mat_type>                  mat_ptr;
00089 
00098   virtual int
00099   normalizeOutOfPlace (MV& X, MV& Q, mat_ptr B) const = 0;
00100 
00119   virtual int
00120   projectAndNormalizeOutOfPlace (MV& X_in,
00121                                  MV& X_out,
00122                                  Teuchos::Array<mat_ptr> C,
00123                                  mat_ptr B,
00124                                  Teuchos::ArrayView<Teuchos::RCP<const MV> > Q) const = 0;
00125 
00127   virtual ~OutOfPlaceNormalizerMixin () {}
00128 };
00129 
00136 template<class Scalar, class MV>
00137 class TsqrOrthoManager :
00138     public OrthoManager<Scalar, MV>,
00139     public OutOfPlaceNormalizerMixin<Scalar, MV>,
00140     public Teuchos::ParameterListAcceptor
00141 {
00142 public:
00143   typedef Scalar scalar_type;
00144   typedef typename Teuchos::ScalarTraits<Scalar>::magnitudeType magnitude_type;
00146   typedef MV multivector_type;
00147 
00148   typedef Teuchos::SerialDenseMatrix<int, Scalar> mat_type;
00149   typedef Teuchos::RCP<mat_type>                  mat_ptr;
00150 
00151   void setParameterList (const Teuchos::RCP<Teuchos::ParameterList>& params) {
00152     impl_.setParameterList (params);
00153   }
00154 
00155   Teuchos::RCP<Teuchos::ParameterList> getNonconstParameterList () {
00156     return impl_.getNonconstParameterList ();
00157   }
00158 
00159   Teuchos::RCP<Teuchos::ParameterList> unsetParameterList () {
00160     return impl_.unsetParameterList ();
00161   }
00162 
00170   Teuchos::RCP<const Teuchos::ParameterList> getValidParameters() const {
00171     return impl_.getValidParameters();
00172   }
00173 
00183   Teuchos::RCP<const Teuchos::ParameterList> getFastParameters() const {
00184     return impl_.getFastParameters();
00185   }
00186 
00202   TsqrOrthoManager (const Teuchos::RCP<Teuchos::ParameterList>& params,
00203                     const std::string& label = "Belos") :
00204     impl_ (params, label)
00205   {}
00206 
00211   TsqrOrthoManager (const std::string& label) :
00212     impl_ (label)
00213   {}
00214 
00216   virtual ~TsqrOrthoManager() {}
00217 
00239   void
00240   setReorthogonalizationCallback (const Teuchos::RCP<ReorthogonalizationCallback<Scalar> >& callback)
00241   {
00242     impl_.setReorthogonalizationCallback (callback);
00243   }
00244 
00245   void innerProd (const MV &X, const MV &Y, mat_type& Z) const {
00246     return impl_.innerProd (X, Y, Z);
00247   }
00248 
00249   void norm (const MV& X, std::vector<magnitude_type>& normVec) const {
00250     return impl_.norm (X, normVec);
00251   }
00252 
00253   void
00254   project (MV &X,
00255            Teuchos::Array<mat_ptr> C,
00256            Teuchos::ArrayView<Teuchos::RCP<const MV> > Q) const
00257   {
00258     return impl_.project (X, C, Q);
00259   }
00260 
00261   int
00262   normalize (MV &X, mat_ptr B) const
00263   {
00264     return impl_.normalize (X, B);
00265   }
00266 
00267 protected:
00268   virtual int
00269   projectAndNormalizeImpl (MV &X,
00270                            Teuchos::Array<mat_ptr> C,
00271                            mat_ptr B,
00272                            Teuchos::ArrayView<Teuchos::RCP<const MV> > Q) const
00273   {
00274     return impl_.projectAndNormalize (X, C, B, Q);
00275   }
00276 
00277 public:
00294   int
00295   normalizeOutOfPlace (MV& X, MV& Q, mat_ptr B) const
00296   {
00297     return impl_.normalizeOutOfPlace (X, Q, B);
00298   }
00299 
00320   int
00321   projectAndNormalizeOutOfPlace (MV& X_in,
00322                                  MV& X_out,
00323                                  Teuchos::Array<mat_ptr> C,
00324                                  mat_ptr B,
00325                                  Teuchos::ArrayView<Teuchos::RCP<const MV> > Q) const
00326   {
00327     return impl_.projectAndNormalizeOutOfPlace (X_in, X_out, C, B, Q);
00328   }
00329 
00330   magnitude_type orthonormError (const MV &X) const {
00331     return impl_.orthonormError (X);
00332   }
00333 
00334   magnitude_type orthogError (const MV &X1, const MV &X2) const {
00335     return impl_.orthogError (X1, X2);
00336   }
00337 
00345   void setLabel (const std::string& label) {
00346     impl_.setLabel (label);
00347   }
00348 
00349   const std::string& getLabel() const { return impl_.getLabel(); }
00350 
00351 private:
00357   mutable TsqrOrthoManagerImpl<Scalar, MV> impl_;
00358 
00360   std::string label_;
00361 };
00362 
00363 
00377 template<class Scalar, class MV, class OP>
00378 class TsqrMatOrthoManager :
00379     public MatOrthoManager<Scalar, MV, OP>,
00380     public OutOfPlaceNormalizerMixin<Scalar, MV>,
00381     public Teuchos::ParameterListAcceptorDefaultBase
00382 {
00383 public:
00384   typedef Scalar scalar_type;
00385   typedef typename Teuchos::ScalarTraits<Scalar>::magnitudeType magnitude_type;
00387   typedef MV multivector_type;
00389   typedef OP operator_type;
00390 
00391   typedef Teuchos::SerialDenseMatrix<int, Scalar> mat_type;
00392   typedef Teuchos::RCP<mat_type>                  mat_ptr;
00393 
00394 private:
00403   typedef MatOrthoManager<Scalar, MV, OP> base_type;
00404 
00407   typedef TsqrOrthoManagerImpl<Scalar, MV> tsqr_type;
00408 
00411   typedef DGKSOrthoManager<Scalar, MV, OP> dgks_type;
00412 
00415   typedef MultiVecTraits<Scalar, MV> MVT;
00416 
00417 public:
00438   TsqrMatOrthoManager (const Teuchos::RCP<Teuchos::ParameterList>& params,
00439                        const std::string& label = "Belos",
00440                        Teuchos::RCP<const OP> Op = Teuchos::null) :
00441     MatOrthoManager<Scalar, MV, OP> (Op),
00442     tsqr_ (params, label),
00443     pDgks_ (Teuchos::null) // Initialized lazily
00444   {}
00445 
00454   TsqrMatOrthoManager (const std::string& label = "Belos",
00455                        Teuchos::RCP<const OP> Op = Teuchos::null) :
00456     MatOrthoManager<Scalar, MV, OP> (Op),
00457     tsqr_ (label),
00458     pDgks_ (Teuchos::null) // Initialized lazily
00459   {}
00460 
00462   virtual ~TsqrMatOrthoManager() {}
00463 
00471   Teuchos::RCP<const Teuchos::ParameterList> getValidParameters() const {
00472     return tsqr_.getValidParameters ();
00473   }
00474 
00484   Teuchos::RCP<const Teuchos::ParameterList> getFastParameters() {
00485     return tsqr_.getFastParameters ();
00486   }
00487 
00488   void setParameterList (const Teuchos::RCP<Teuchos::ParameterList>& params) {
00489     tsqr_.setParameterList (params);
00490   }
00491 
00492   const std::string& getLabel() const { return tsqr_.getLabel (); }
00493 
00494   void
00495   setOp (Teuchos::RCP<const OP> Op)
00496   {
00497     // We override the base class' setOp() so that the
00498     // DGKSOrthoManager instance gets the new op.
00499     //
00500     // The base_type notation helps C++ resolve the name for a
00501     // member function of a templated base class.
00502     base_type::setOp (Op); // base class gets a copy of the Op too
00503 
00504     if (! Op.is_null()) {
00505       ensureDgksInit (); // Make sure the DGKS object has been initialized
00506       pDgks_->setOp (Op);
00507     }
00508   }
00509 
00510   Teuchos::RCP<const OP> getOp () const {
00511     // The base_type notation helps C++ resolve the name for a
00512     // member function of a templated base class.
00513     return base_type::getOp();
00514   }
00515 
00516   void
00517   project (MV &X,
00518            Teuchos::RCP<MV> MX,
00519            Teuchos::Array<mat_ptr> C,
00520            Teuchos::ArrayView<Teuchos::RCP<const MV> > Q) const
00521   {
00522     if (getOp().is_null()) {
00523       tsqr_.project (X, C, Q);
00524       if (! MX.is_null()) {
00525         // MX gets a copy of X; M is the identity operator.
00526         MVT::Assign (X, *MX);
00527       }
00528     } else {
00529       ensureDgksInit ();
00530       pDgks_->project (X, MX, C, Q);
00531     }
00532   }
00533 
00534   void
00535   project (MV &X,
00536            Teuchos::Array<mat_ptr> C,
00537            Teuchos::ArrayView<Teuchos::RCP<const MV> > Q) const
00538   {
00539     project (X, Teuchos::null, C, Q);
00540   }
00541 
00542   int
00543   normalize (MV& X, Teuchos::RCP<MV> MX, mat_ptr B) const
00544   {
00545     if (getOp().is_null()) {
00546       const int rank = tsqr_.normalize (X, B);
00547       if (! MX.is_null()) {
00548         // MX gets a copy of X; M is the identity operator.
00549         MVT::Assign (X, *MX);
00550       }
00551       return rank;
00552     } else {
00553       ensureDgksInit ();
00554       return pDgks_->normalize (X, MX, B);
00555     }
00556   }
00557 
00558   int normalize (MV& X, mat_ptr B) const {
00559     return normalize (X, Teuchos::null, B);
00560   }
00561 
00562   // Attempted fix for a warning about hiding
00563   // OrthoManager::projectAndNormalize(). Unfortunately, this fix turns out
00564   // to produce a compilation error with cray++, see bug #6129,
00565   // <https://software.sandia.gov/bugzilla/show_bug.cgi?id=6129>.
00566   //using Belos::OrthoManager<Scalar, MV>::projectAndNormalize;
00567 
00568 protected:
00569   virtual int
00570   projectAndNormalizeWithMxImpl (MV &X,
00571                                  Teuchos::RCP<MV> MX,
00572                                  Teuchos::Array<mat_ptr> C,
00573                                  mat_ptr B,
00574                                  Teuchos::ArrayView<Teuchos::RCP<const MV> > Q) const
00575   {
00576     if (getOp().is_null()) {
00577       const int rank = tsqr_.projectAndNormalize (X, C, B, Q);
00578       if (! MX.is_null()) {
00579         // MX gets a copy of X; M is the identity operator.
00580         MVT::Assign (X, *MX);
00581       }
00582       return rank;
00583     } else {
00584       ensureDgksInit ();
00585       return pDgks_->projectAndNormalize (X, MX, C, B, Q);
00586     }
00587   }
00588 
00589 public:
00590   int
00591   normalizeOutOfPlace (MV& X, MV& Q, mat_ptr B) const
00592   {
00593     if (getOp().is_null()) {
00594       return tsqr_.normalizeOutOfPlace (X, Q, B);
00595     } else {
00596       // DGKS normalizes in place, so we have to copy.
00597       ensureDgksInit ();
00598       const int rank = pDgks_->normalize (X, B);
00599       MVT::Assign (X, Q);
00600       return rank;
00601     }
00602   }
00603 
00604   int
00605   projectAndNormalizeOutOfPlace (MV& X_in,
00606                                  MV& X_out,
00607                                  Teuchos::Array<mat_ptr> C,
00608                                  mat_ptr B,
00609                                  Teuchos::ArrayView<Teuchos::RCP<const MV> > Q) const
00610   {
00611     using Teuchos::null;
00612 
00613     if (getOp().is_null()) {
00614       return tsqr_.projectAndNormalizeOutOfPlace (X_in, X_out, C, B, Q);
00615     } else {
00616       // DGKS normalizes in place, so we have to copy.
00617       ensureDgksInit ();
00618       const int rank = pDgks_->projectAndNormalize (X_in, null, C, B, Q);
00619       MVT::Assign (X_in, X_out);
00620       return rank;
00621     }
00622   }
00623 
00624   magnitude_type
00625   orthonormError (const MV &X, Teuchos::RCP<const MV> MX) const
00626   {
00627     if (getOp().is_null()) {
00628       return tsqr_.orthonormError (X); // Ignore MX
00629     } else {
00630       ensureDgksInit ();
00631       return pDgks_->orthonormError (X, MX);
00632     }
00633   }
00634 
00635   magnitude_type orthonormError (const MV &X) const {
00636     return orthonormError (X, Teuchos::null);
00637   }
00638 
00639   magnitude_type orthogError (const MV &X1, const MV &X2) const {
00640     return orthogError (X1, Teuchos::null, X2);
00641   }
00642 
00643   magnitude_type
00644   orthogError (const MV &X1,
00645                Teuchos::RCP<const MV> MX1,
00646                const MV &X2) const
00647   {
00648     if (getOp ().is_null ()) {
00649       // Ignore MX1, since we don't need to write to it.
00650       return tsqr_.orthogError (X1, X2);
00651     } else {
00652       ensureDgksInit ();
00653       return pDgks_->orthogError (X1, MX1, X2);
00654     }
00655   }
00656 
00657   void
00658   setLabel (const std::string& label)
00659   {
00660     tsqr_.setLabel (label);
00661 
00662     // Make sure DGKS gets the new label, if it's initialized.
00663     // Otherwise, it will get the new label on initialization.
00664     if (! pDgks_.is_null ()) {
00665       pDgks_->setLabel (label);
00666     }
00667   }
00668 
00669 private:
00671   void
00672   ensureDgksInit () const
00673   {
00674     // NOTE (mfh 11 Jan 2011) DGKS has a parameter that needs to be
00675     // set.  For now, we just use the default value of the parameter.
00676     if (pDgks_.is_null ()) {
00677       pDgks_ = Teuchos::rcp (new dgks_type (getLabel (), getOp ()));
00678     }
00679   }
00680 
00688   mutable tsqr_type tsqr_;
00689 
00695   mutable Teuchos::RCP<dgks_type> pDgks_;
00696 };
00697 
00698 } // namespace Belos
00699 
00700 #endif // __BelosTsqrOrthoManager_hpp
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines