42 #ifndef SPARSE_VECTOR_CLASS_DEF_H
43 #define SPARSE_VECTOR_CLASS_DEF_H
47 #include "AbstractLinAlgPack_SparseVectorClassDecl.hpp"
48 #include "AbstractLinAlgPack_compare_element_indexes.hpp"
49 #include "Teuchos_Assert.hpp"
51 namespace AbstractLinAlgPack {
58 template<
class T_Element>
59 SparseVectorSlice<T_Element>
60 create_slice(
const SparseVectorUtilityPack::SpVecIndexLookup<T_Element>& index_lookup
64 if(rng.full_range()) {
65 rng = Range1D(1,size);
74 if(!index_lookup.nz())
75 return SparseVectorSlice<T_Element>(0, 0, 0, rng.ubound() - rng.lbound() + 1,
true);
78 typedef SparseVectorUtilityPack::SpVecIndexLookup<T_Element> SpVecIndexLookup;
79 index_lookup.validate_state();
80 typename SpVecIndexLookup::poss_type
81 lower_poss = index_lookup.find_poss(rng.lbound(), SpVecIndexLookup::LOWER_ELE),
82 upper_poss = index_lookup.find_poss(rng.ubound(), SpVecIndexLookup::UPPER_ELE);
83 if( lower_poss.poss == upper_poss.poss
84 && ( lower_poss.rel == SpVecIndexLookup::AFTER_ELE
85 || upper_poss.rel == SpVecIndexLookup::BEFORE_ELE )
89 return SparseVectorSlice<T_Element>(0, 0, 0, rng.ubound() - rng.lbound() + 1,
true);
93 return SparseVectorSlice<T_Element>(index_lookup.ele() + lower_poss.poss
94 , upper_poss.poss - lower_poss.poss + 1, index_lookup.offset() - rng.lbound() + 1
95 , rng.ubound() - rng.lbound() + 1,
true);
102 template <
class T_Element,
class T_Alloc>
106 alloc_(sp_vec.alloc_), size_(sp_vec.size_), max_nz_(sp_vec.max_nz_)
107 , assume_sorted_(sp_vec.assume_sorted_)
108 , know_is_sorted_(sp_vec.know_is_sorted_)
115 alloc_.allocate(max_nz_,NULL)
121 while(ele_from_itr != sp_vec.end()) {
125 alloc_.construct(ele_to_itr++,*ele_from_itr++);
130 template <
class T_Element,
class T_Alloc>
135 alloc_(alloc), size_(sp_vec_slc.dim()), max_nz_(sp_vec_slc.nz())
136 , assume_sorted_(sp_vec_slc.is_sorted())
137 , know_is_sorted_(false)
144 alloc_.allocate(max_nz_,NULL)
151 while(ele_from_itr != sp_vec_slc.end()) {
155 alloc_.construct(ele_to_itr++,*ele_from_itr++);
160 template <
class T_Element,
class T_Alloc>
165 if(
this == &sp_vec)
return *
this;
167 know_is_sorted_ = sp_vec.know_is_sorted_;
168 assume_sorted_ = sp_vec.assume_sorted_;
170 if( max_nz() < sp_vec.
nz() ) {
178 for(
iterator ele_itr = begin(); ele_itr != end();) {
182 alloc_.destroy(ele_itr++);
186 size_ = sp_vec.size_;
190 index_lookup_.set_sp_vec(index_lookup_.ele(),sp_vec.
nz(),sp_vec.
offset());
194 iterator ele_to_itr = index_lookup_.ele();
196 while(ele_from_itr != sp_vec.end()) {
200 alloc_.construct(ele_to_itr++,*ele_from_itr++);
208 template <
class T_Element,
class T_Alloc>
213 know_is_sorted_ =
false;
216 if(max_nz() < sp_vec_slc.
nz()) {
219 resize(sp_vec_slc.
dim(),sp_vec_slc.
nz(),sp_vec_slc.
offset());
224 for(
iterator ele_itr = begin(); ele_itr != end();) {
228 alloc_.destroy(ele_itr++);
232 size_ = sp_vec_slc.
dim();
236 index_lookup_.set_sp_vec(index_lookup_.ele(),sp_vec_slc.
nz()
239 if( sp_vec_slc.
nz() ) {
241 iterator ele_to_itr = index_lookup_.ele();
243 while(ele_from_itr != sp_vec_slc.end()) {
247 alloc_.construct(ele_to_itr++,*ele_from_itr++);
255 template <
class T_Element,
class T_Alloc>
258 if(!sv.
dim())
return DenseLinAlgPack::NO_OVERLAP;
263 if( this_begin == sv_begin && end() == sv.end() )
265 return DenseLinAlgPack::SAME_MEM;
268 if( ( this_begin < sv_begin && end() < sv_begin )
269 || ( sv_begin < this_begin && sv.end() < this_begin ) )
271 return DenseLinAlgPack::NO_OVERLAP;
274 return DenseLinAlgPack::SOME_OVERLAP;
277 template <
class T_Element,
class T_Alloc>
282 if(index_lookup_.ele()) {
283 for(
element_type* p = index_lookup_.ele(); p < index_lookup_.ele() + index_lookup_.nz(); ++p) {
291 delete [] index_lookup_.ele();
293 alloc_.deallocate(index_lookup_.ele(), max_nz_);
299 know_is_sorted_ =
false;
304 index_lookup_.set_sp_vec(
new element_type[max_nz_ = max_nz], 0, offset );
306 index_lookup_.set_sp_vec( alloc_.allocate( max_nz_ = max_nz, 0 ), 0, offset );
312 index_lookup_.set_sp_vec( 0, 0, offset );
317 template <
class T_Element,
class T_Alloc>
323 nz > max_nz, std::length_error
324 ,
"SparseVector<...>::uninitialized_resize(...) : nz can not be greater"
327 resize(size,max_nz,offset);
328 index_lookup_.set_sp_vec(index_lookup_.ele(), nz, index_lookup_.offset());
331 template <
class T_Element,
class T_Alloc>
339 typedef typename SpVecIndexLookup::poss_type poss_type;
343 ? index_lookup_.find_poss(ele.index(), SpVecIndexLookup::LOWER_ELE)
344 : poss_type(0,SpVecIndexLookup::BEFORE_ELE)
349 nz() && poss.rel == SpVecIndexLookup::EQUAL_TO_ELE, std::length_error
350 ,
"SparseVector<...>::insert_element(...) : Error, this index"
351 " all ready exists!" );
354 insert_poss = (poss.rel == SpVecIndexLookup::BEFORE_ELE ? poss.poss : poss.poss+1);
357 index_lookup_.ele() + insert_poss, index_lookup_.ele() + index_lookup_.nz()
358 , index_lookup_.ele() + index_lookup_.nz() + 1 );
359 index_lookup_.ele()[insert_poss] = ele;
360 index_lookup_.incr_nz();
363 index_lookup_.ele()[0] = ele;
364 index_lookup_.incr_nz();
368 template <
class T_Element,
class T_Alloc>
370 if( index_lookup_.nz() > 0 )
372 know_is_sorted_ =
true;
375 template <
class T_Element,
class T_Alloc>
379 if(!index_lookup_.nz())
return;
384 typename T_Element::index_type last_index;
385 for(T_Element* p = index_lookup_.ele();
386 p < index_lookup_.ele() + index_lookup_.nz(); ++p)
388 typename T_Element::index_type curr_index = p->index() + offset();
391 (1 > curr_index) || (curr_index > dim()), std::out_of_range
392 ,
"SparseVector<...>::assert_valid_and_sorted():"
393 <<
" Error, not in range: element (0-based) " << p - index_lookup_.ele() - 1
394 <<
" with index + offset = " << curr_index
395 <<
" is not in range" );
397 if(p == index_lookup_.ele()) {
398 last_index = curr_index;
404 ,
"SparseVector<...>::assert_valid_and_sorted():"
405 <<
" Error, not sorted: element (0-based) " << p - index_lookup_.ele() - 1
406 <<
" and " << p - index_lookup_.ele() <<
" are not in assending order" );
409 ,
"SparseVector<...>::assert_valid_and_sorted():"
410 <<
" Error, duplicate indexes: element (0-based) " << p - index_lookup_.ele() - 1
411 <<
" and " << p - index_lookup_.ele() <<
" have duplicate indexes" );
413 last_index = curr_index;
421 template <
class T_Element>
424 if(!sv.
dim())
return DenseLinAlgPack::NO_OVERLAP;
427 sv_begin = sv.
begin();
429 if( this_begin == sv_begin && end() == sv.end() )
431 return DenseLinAlgPack::SAME_MEM;
434 if( ( this_begin < sv_begin && end() < sv_begin )
435 || ( sv_begin < this_begin && sv.end() < this_begin ) )
437 return DenseLinAlgPack::NO_OVERLAP;
440 return DenseLinAlgPack::SOME_OVERLAP;
445 #endif // SPARSE_VECTOR_CLASS_DEF_H
SparseVector< T_Element, T_Alloc > & operator=(const SparseVector< T_Element, T_Alloc > &sp_vec)
Assignment operator.
difference_type offset() const
Return the offset for the indexes (ith real index = begin()[i-1]->index() + offset()# ...
ptrdiff_t difference_type
const element_type * const_iterator
void resize(size_type size, size_type max_nz, difference_type offset=0)
Resize to #size# with a maximum of max_nz# non-zero elements.
size_type dim() const
Return the number of elements in the full vector.
Sparse Vector Slice class template.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
element_type * ele() const
void set_sp_vec(element_type *ele, size_type nz, difference_type offset)
Set a new sparse vector.
bool is_sorted() const
Return true if the sequence is assumed sorted.
const element_type * const_iterator
void assert_valid_and_sorted() const
Assert that sparse vector is sorted.
size_type dim() const
Return the number of elements in the full vector.
size_type nz() const
Return the number of non-zero elements.
void uninitialized_resize(size_type size, size_type nz, size_type max_nz, difference_type offset=0)
Resize to #size# with a max_nz# uninitialized non-zero elements.
EOverLap overlap(const SparseVectorSlice< T_Element > &sv) const
Sparse Vector class template.
ele1.index() < ele2.index()
difference_type offset() const
Return the offset for the indexes (ith real index = begin()[i-1]->index() + offset()# ...
void sort()
Sort the elements into assending order by index.
SparseVector(const allocator_type &alloc=allocator_type())
Constructs a sparse vector with no elements (nz() == dim() == 0#) and assumes the elements are not so...
Sparse Vector Index Lookup and Caching class.
EOverLap overlap(const SparseVectorSlice< T_Element > &sv) const
AbstractLinAlgPack::size_type size_type
iterator begin()
Returns iterator that iterates forward through the nonzero elements.
size_type nz() const
Return the number of non-zero elements.
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
void insert_element(element_type ele)
Add an element into a sorted sequence.
void validate_state() const
Called by client to ensure that the internal state is valid.