AbstractLinAlgPack_PermutationSerial.cpp

00001 // @HEADER
00002 // ***********************************************************************
00003 // 
00004 // Moocho: Multi-functional Object-Oriented arCHitecture for Optimization
00005 //                  Copyright (2003) Sandia Corporation
00006 // 
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 // 
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //  
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //  
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov) 
00025 // 
00026 // ***********************************************************************
00027 // @HEADER
00028 
00029 #include <assert.h>
00030 
00031 #include "AbstractLinAlgPack_PermutationSerial.hpp"
00032 #include "AbstractLinAlgPack_VectorDenseEncap.hpp"
00033 #include "DenseLinAlgPack_IVector.hpp"
00034 #include "DenseLinAlgPack_PermVecMat.hpp"
00035 #include "DenseLinAlgPack_PermOut.hpp"
00036 #include "Teuchos_TestForException.hpp"
00037 
00038 namespace AbstractLinAlgPack {
00039 
00040 // Constructors / initializers
00041 
00042 PermutationSerial::PermutationSerial( size_type dim )
00043   :space_(dim)
00044 {}
00045 
00046 PermutationSerial::PermutationSerial(
00047   const i_vector_ptr_t      &perm
00048   ,const i_vector_ptr_t     &inv_perm
00049   ,bool                     allocate_missing_perm
00050   ,bool                     check_inv_perm
00051   )
00052 {
00053   this->initialize(perm,inv_perm,allocate_missing_perm,check_inv_perm);
00054 }
00055   
00056 void PermutationSerial::initialize_identity( size_type dim )
00057 {
00058   namespace rcp = MemMngPack;
00059   space_.initialize(dim);
00060   perm_     = Teuchos::null;
00061   inv_perm_ = Teuchos::null;
00062 }
00063 
00064 void PermutationSerial::initialize(
00065   const i_vector_ptr_t      &perm
00066   ,const i_vector_ptr_t     &inv_perm
00067   ,bool                     allocate_missing_perm
00068   ,bool                     check_inv_perm
00069   )
00070 {
00071   TEST_FOR_EXCEPTION(
00072     perm.get() == NULL && inv_perm.get() == NULL, std::invalid_argument
00073     ,"PermutationSerial::initialize(...) : Error!" );
00074   if( perm.get() != NULL && inv_perm.get() != NULL ) {
00075     TEST_FOR_EXCEPTION(
00076       perm->size() != inv_perm->size(), std::invalid_argument
00077       ,"PermutationSerial::initialize(...) : Error!" );
00078     if(check_inv_perm) {
00079       // ToDo: Permform this check!
00080     }
00081   }
00082   space_.initialize( perm.get() ? perm->size() : inv_perm->size() );
00083   perm_     = perm;
00084   inv_perm_ = inv_perm;
00085   if( allocate_missing_perm && perm_.get() == NULL ) {
00086     Teuchos::RefCountPtr<IVector>
00087       _perm = Teuchos::rcp(new IVector(inv_perm_->size()));
00088     DenseLinAlgPack::inv_perm( *inv_perm_, _perm.get() );
00089     perm_ = _perm;
00090   }
00091   if( allocate_missing_perm && inv_perm_.get() == NULL ) {
00092     Teuchos::RefCountPtr<IVector>
00093       _inv_perm = Teuchos::rcp(new IVector(perm_->size()));
00094     DenseLinAlgPack::inv_perm( *perm_, _inv_perm.get() );
00095     inv_perm_ = _inv_perm;
00096   }
00097 }
00098 
00099 // Overridden from Permutation
00100 
00101 const VectorSpace& PermutationSerial::space() const
00102 {
00103   return space_;
00104 }
00105 
00106 size_type PermutationSerial::dim() const
00107 {
00108   return space_.dim();
00109 }
00110 
00111 bool PermutationSerial::is_identity() const
00112 {
00113   return perm_.get() == NULL && inv_perm_.get() == NULL;
00114 }
00115 
00116 std::ostream& PermutationSerial::output(std::ostream& out) const
00117 {
00118   const size_type dim = this->dim();
00119   out << "Serial " << dim << " x " << dim << " permtutation matrix:\n";
00120   out << "perm =";
00121   if( perm_.get() )
00122     out << "\n" << *perm_;
00123   else
00124     out << " NULL\n";
00125   out << "inv_perm =";
00126   if( inv_perm_.get() )
00127     out << "\n" << *inv_perm_;
00128   else
00129     out << " NULL\n";
00130   return out;
00131 }
00132 
00133 void PermutationSerial::permute( 
00134   BLAS_Cpp::Transp          P_trans
00135   ,const Vector       &x
00136   ,VectorMutable      *y
00137   ) const
00138 {
00139 #ifdef TEUCHOS_DEBUG
00140   TEST_FOR_EXCEPTION(
00141     y == NULL, std::invalid_argument
00142     ,"PermutationSerial::permute(P_trans,x,y) : Error!" );
00143 #endif
00144 #ifdef ABSTRACTLINALGPACK_ASSERT_COMPATIBILITY
00145   bool is_compatible;
00146   is_compatible = space_.is_compatible(x.space());
00147   TEST_FOR_EXCEPTION(
00148     !is_compatible, std::invalid_argument
00149     ,"PermutationSerial::permute(P_trans,x,y) : Error, "
00150     "this->space().is_compatible(x.space()) returned false!" );
00151   is_compatible = space_.is_compatible(y->space());
00152   TEST_FOR_EXCEPTION(
00153     !is_compatible, std::invalid_argument
00154     ,"PermutationSerial::permute(P_trans,x,y) : Error, "
00155     "this->space().is_compatible(y->space()) returned false!" );
00156 #endif
00157   VectorDenseMutableEncap       y_d(*y);
00158   VectorDenseEncap              x_d(x);
00159   const IVector                 *p            = NULL;
00160   bool                          call_inv_perm = false;
00161   if( ( p = perm_.get() ) != NULL ) {
00162     if( P_trans == BLAS_Cpp::no_trans )
00163       call_inv_perm = false;
00164     else
00165       call_inv_perm = true;
00166   }
00167   else if( ( p = inv_perm_.get() ) != NULL ) {
00168     if( P_trans == BLAS_Cpp::no_trans )
00169       call_inv_perm = true;
00170     else
00171       call_inv_perm = false;
00172   }
00173   if( p ) {
00174     if( call_inv_perm )
00175       DenseLinAlgPack::inv_perm_ele( x_d(), *p, &y_d() );
00176     else
00177       DenseLinAlgPack::perm_ele( x_d(), *p, &y_d() );
00178   }
00179   else {
00180     // Just the identity permutation, nothing to do!
00181   }
00182 }
00183 
00184 void PermutationSerial::permute( 
00185   BLAS_Cpp::Transp          P_trans
00186   ,VectorMutable      *y
00187   ) const
00188 {
00189 #ifdef TEUCHOS_DEBUG
00190   TEST_FOR_EXCEPTION(
00191     y == NULL, std::invalid_argument
00192     ,"PermutationSerial::permute(P_trans,y) : Error!" );
00193 #endif
00194   VectorSpace::vec_mut_ptr_t
00195     t = y->clone();
00196   this->permute(P_trans,*t,y);
00197 }
00198 
00199 } // end namespace AbstractLinAlgPack

Generated on Thu Sep 18 12:33:52 2008 for AbstractLinAlgPack: C++ Interfaces For Vectors, Matrices And Related Linear Algebra Objects by doxygen 1.3.9.1