AbstractLinAlgPack: C++ Interfaces For Vectors, Matrices And Related Linear Algebra Objects Version of the Day
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 // 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 Roscoe A. Bartlett (rabartl@sandia.gov) 
00038 // 
00039 // ***********************************************************************
00040 // @HEADER
00041 
00042 #include <assert.h>
00043 
00044 #include "AbstractLinAlgPack_PermutationSerial.hpp"
00045 #include "AbstractLinAlgPack_VectorDenseEncap.hpp"
00046 #include "DenseLinAlgPack_IVector.hpp"
00047 #include "DenseLinAlgPack_PermVecMat.hpp"
00048 #include "DenseLinAlgPack_PermOut.hpp"
00049 #include "Teuchos_Assert.hpp"
00050 
00051 namespace AbstractLinAlgPack {
00052 
00053 // Constructors / initializers
00054 
00055 PermutationSerial::PermutationSerial( size_type dim )
00056   :space_(dim)
00057 {}
00058 
00059 PermutationSerial::PermutationSerial(
00060   const i_vector_ptr_t      &perm
00061   ,const i_vector_ptr_t     &inv_perm
00062   ,bool                     allocate_missing_perm
00063   ,bool                     check_inv_perm
00064   )
00065 {
00066   this->initialize(perm,inv_perm,allocate_missing_perm,check_inv_perm);
00067 }
00068   
00069 void PermutationSerial::initialize_identity( size_type dim )
00070 {
00071   namespace rcp = MemMngPack;
00072   space_.initialize(dim);
00073   perm_     = Teuchos::null;
00074   inv_perm_ = Teuchos::null;
00075 }
00076 
00077 void PermutationSerial::initialize(
00078   const i_vector_ptr_t      &perm
00079   ,const i_vector_ptr_t     &inv_perm
00080   ,bool                     allocate_missing_perm
00081   ,bool                     check_inv_perm
00082   )
00083 {
00084   TEUCHOS_TEST_FOR_EXCEPTION(
00085     perm.get() == NULL && inv_perm.get() == NULL, std::invalid_argument
00086     ,"PermutationSerial::initialize(...) : Error!" );
00087   if( perm.get() != NULL && inv_perm.get() != NULL ) {
00088     TEUCHOS_TEST_FOR_EXCEPTION(
00089       perm->size() != inv_perm->size(), std::invalid_argument
00090       ,"PermutationSerial::initialize(...) : Error!" );
00091     if(check_inv_perm) {
00092       // ToDo: Permform this check!
00093     }
00094   }
00095   space_.initialize( perm.get() ? perm->size() : inv_perm->size() );
00096   perm_     = perm;
00097   inv_perm_ = inv_perm;
00098   if( allocate_missing_perm && perm_.get() == NULL ) {
00099     Teuchos::RCP<IVector>
00100       _perm = Teuchos::rcp(new IVector(inv_perm_->size()));
00101     DenseLinAlgPack::inv_perm( *inv_perm_, _perm.get() );
00102     perm_ = _perm;
00103   }
00104   if( allocate_missing_perm && inv_perm_.get() == NULL ) {
00105     Teuchos::RCP<IVector>
00106       _inv_perm = Teuchos::rcp(new IVector(perm_->size()));
00107     DenseLinAlgPack::inv_perm( *perm_, _inv_perm.get() );
00108     inv_perm_ = _inv_perm;
00109   }
00110 }
00111 
00112 // Overridden from Permutation
00113 
00114 const VectorSpace& PermutationSerial::space() const
00115 {
00116   return space_;
00117 }
00118 
00119 size_type PermutationSerial::dim() const
00120 {
00121   return space_.dim();
00122 }
00123 
00124 bool PermutationSerial::is_identity() const
00125 {
00126   return perm_.get() == NULL && inv_perm_.get() == NULL;
00127 }
00128 
00129 std::ostream& PermutationSerial::output(std::ostream& out) const
00130 {
00131   const size_type dim = this->dim();
00132   out << "Serial " << dim << " x " << dim << " permtutation matrix:\n";
00133   out << "perm =";
00134   if( perm_.get() )
00135     out << "\n" << *perm_;
00136   else
00137     out << " NULL\n";
00138   out << "inv_perm =";
00139   if( inv_perm_.get() )
00140     out << "\n" << *inv_perm_;
00141   else
00142     out << " NULL\n";
00143   return out;
00144 }
00145 
00146 void PermutationSerial::permute( 
00147   BLAS_Cpp::Transp          P_trans
00148   ,const Vector       &x
00149   ,VectorMutable      *y
00150   ) const
00151 {
00152 #ifdef TEUCHOS_DEBUG
00153   TEUCHOS_TEST_FOR_EXCEPTION(
00154     y == NULL, std::invalid_argument
00155     ,"PermutationSerial::permute(P_trans,x,y) : Error!" );
00156 #endif
00157 #ifdef ABSTRACTLINALGPACK_ASSERT_COMPATIBILITY
00158   bool is_compatible;
00159   is_compatible = space_.is_compatible(x.space());
00160   TEUCHOS_TEST_FOR_EXCEPTION(
00161     !is_compatible, std::invalid_argument
00162     ,"PermutationSerial::permute(P_trans,x,y) : Error, "
00163     "this->space().is_compatible(x.space()) returned false!" );
00164   is_compatible = space_.is_compatible(y->space());
00165   TEUCHOS_TEST_FOR_EXCEPTION(
00166     !is_compatible, std::invalid_argument
00167     ,"PermutationSerial::permute(P_trans,x,y) : Error, "
00168     "this->space().is_compatible(y->space()) returned false!" );
00169 #endif
00170   VectorDenseMutableEncap       y_d(*y);
00171   VectorDenseEncap              x_d(x);
00172   const IVector                 *p            = NULL;
00173   bool                          call_inv_perm = false;
00174   if( ( p = perm_.get() ) != NULL ) {
00175     if( P_trans == BLAS_Cpp::no_trans )
00176       call_inv_perm = false;
00177     else
00178       call_inv_perm = true;
00179   }
00180   else if( ( p = inv_perm_.get() ) != NULL ) {
00181     if( P_trans == BLAS_Cpp::no_trans )
00182       call_inv_perm = true;
00183     else
00184       call_inv_perm = false;
00185   }
00186   if( p ) {
00187     if( call_inv_perm )
00188       DenseLinAlgPack::inv_perm_ele( x_d(), *p, &y_d() );
00189     else
00190       DenseLinAlgPack::perm_ele( x_d(), *p, &y_d() );
00191   }
00192   else {
00193     // Just the identity permutation, nothing to do!
00194   }
00195 }
00196 
00197 void PermutationSerial::permute( 
00198   BLAS_Cpp::Transp          P_trans
00199   ,VectorMutable      *y
00200   ) const
00201 {
00202 #ifdef TEUCHOS_DEBUG
00203   TEUCHOS_TEST_FOR_EXCEPTION(
00204     y == NULL, std::invalid_argument
00205     ,"PermutationSerial::permute(P_trans,y) : Error!" );
00206 #endif
00207   VectorSpace::vec_mut_ptr_t
00208     t = y->clone();
00209   this->permute(P_trans,*t,y);
00210 }
00211 
00212 } // end namespace AbstractLinAlgPack
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends