|
AbstractLinAlgPack: C++ Interfaces For Vectors, Matrices And Related Linear Algebra Objects
Version of the Day
|
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 using Teuchos::null; 00104 const Range1D rng = RangePack::full_range(rng_in,1,sv_in.dim()); 00105 const SpVectorSlice sv = sv_in(rng); 00106 00107 RTOpPack::SparseSubVector sub_vec; 00108 00109 if(!sv.nz()) { 00110 sub_vec.initialize( 00111 rng.lbound()-1 // global_offset 00112 ,rng.size() // sub_dim 00113 ,0 // nz 00114 ,null // vlaues 00115 ,1 // values_stride 00116 ,null // indices 00117 ,1 // indices_stride 00118 ,0 // local_offset 00119 ,1 // is_sorted 00120 ); 00121 } 00122 else { 00123 SpVectorSlice::const_iterator itr = sv.begin(); 00124 TEUCHOS_TEST_FOR_EXCEPT( !( itr != sv.end() ) ); 00125 if( sv.dim() && sv.nz() == sv.dim() && sv.is_sorted() ) { 00126 const Teuchos::ArrayRCP<const value_type> values = 00127 Teuchos::arcp(&itr->value(), 0, values_stride*rng.size(), false) ; 00128 sub_vec.initialize( 00129 rng.lbound()-1 // global_offset 00130 ,rng.size() // sub_dim 00131 ,values // values 00132 ,values_stride // values_stride 00133 ); 00134 } 00135 else { 00136 const Teuchos::ArrayRCP<const value_type> values = 00137 Teuchos::arcp(&itr->value(), 0, values_stride*sv.nz(), false) ; 00138 const Teuchos::ArrayRCP<const index_type> indexes = 00139 Teuchos::arcp(&itr->index(), 0, indices_stride*sv.nz(), false); 00140 sub_vec.initialize( 00141 rng.lbound()-1 // global_offset 00142 ,sv.dim() // sub_dim 00143 ,sv.nz() // sub_nz 00144 ,values // values 00145 ,values_stride // values_stride 00146 ,indexes // indices 00147 ,indices_stride // indices_stride 00148 ,sv.offset() // local_offset 00149 ,sv.is_sorted() // is_sorted 00150 ); 00151 } 00152 } 00153 00154 return sub_vec; 00155 }
1.7.6.1