AbstractLinAlgPack: C++ Interfaces For Vectors, Matrices And Related Linear Algebra Objects Version of the Day
AbstractLinAlgPack_SpVectorView.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 "AbstractLinAlgPack_SpVectorView.hpp"
00043 
00044 namespace {
00045 
00046 // Setup some template classes to check at complile time that
00047 // the layout of SpVectorSlice::element_type is proper.
00048 template<int N, class T>
00049 class assert_compile_time {
00050 public:
00051   assert_compile_time()
00052   {
00053     // This should not compile if instantiated with a type T that
00054     // is not an integer.  However, if the compiler checks this
00055     // function without instantiating it, it can not cause an error
00056     // because it does not know the type of T to see if the
00057     // conversion is legal or not.
00058     T d;
00059     static_cast<int*>(d);
00060   }
00061 };
00062 
00063 // Template specialization for no error
00064 template<>
00065 class assert_compile_time<0,double> {
00066 public:
00067   assert_compile_time()
00068   {}
00069 };
00070 
00071 // Validate that there is an integer stride between values
00072 assert_compile_time<
00073     ((int)sizeof(AbstractLinAlgPack::SpVectorSlice::element_type)
00074    % (int)sizeof(AbstractLinAlgPack::value_type))
00075   , double
00076   >
00077 validate_value_stride;
00078 
00079 // Validate that there is an integer stride between indexes
00080 assert_compile_time<
00081     ((int)sizeof(AbstractLinAlgPack::SpVectorSlice::element_type)
00082    % (int)sizeof(AbstractLinAlgPack::index_type))
00083   , double
00084   >
00085 validate_index_stride;
00086 
00087 // Compute the stride between values
00088 const int values_stride = (int)sizeof(AbstractLinAlgPack::SpVectorSlice::element_type)
00089   / (int)sizeof(AbstractLinAlgPack::value_type);
00090 
00091 // Compute the stride between indexes
00092 const int indices_stride = (int)sizeof(AbstractLinAlgPack::SpVectorSlice::element_type)
00093   / (int)sizeof(AbstractLinAlgPack::index_type);
00094 
00095 } // end namespace
00096 
00097 RTOpPack::SparseSubVector
00098 AbstractLinAlgPack::sub_vec_view(
00099   const SpVectorSlice&   sv_in
00100   ,const Range1D&        rng_in
00101   )
00102 {
00103   const Range1D        rng = RangePack::full_range(rng_in,1,sv_in.dim());
00104   const SpVectorSlice  sv = sv_in(rng);
00105 
00106   RTOpPack::SparseSubVector  sub_vec;
00107 
00108   if(!sv.nz()) {
00109     sub_vec.initialize(
00110       rng.lbound()-1  // global_offset
00111       ,rng.size()     // sub_dim
00112       ,0              // nz
00113       ,NULL           // vlaues
00114       ,1              // values_stride
00115       ,NULL           // indices
00116       ,1              // indices_stride
00117       ,0              // local_offset
00118       ,1              // is_sorted
00119       );
00120   }
00121   else {
00122     SpVectorSlice::const_iterator
00123       itr = sv.begin();
00124     TEUCHOS_TEST_FOR_EXCEPT( !( itr != sv.end() ) );
00125     const value_type  *values  = &itr->value();
00126     if( sv.dim() && sv.nz() == sv.dim() && sv.is_sorted() ) {
00127       sub_vec.initialize(
00128         rng.lbound()-1    // global_offset
00129         ,rng.size()       // sub_dim
00130         ,values           // values
00131         ,values_stride    // values_stride
00132         );
00133     }
00134     else {
00135       const value_type   *values  = &itr->value();
00136       const index_type   *indexes = &itr->index();
00137       sub_vec.initialize(
00138         rng.lbound()-1    // global_offset
00139         ,sv.dim()         // sub_dim
00140         ,sv.nz()          // sub_nz
00141         ,values           // values
00142         ,values_stride    // values_stride
00143         ,indexes          // indices
00144         ,indices_stride   // indices_stride
00145         ,sv.offset()      // local_offset
00146         ,sv.is_sorted()   // is_sorted
00147         );
00148     }
00149   }
00150   
00151   return sub_vec;
00152 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends