FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
sparse_vector.hpp
1// FEAT3: Finite Element Analysis Toolbox, Version 3
2// Copyright (C) 2010 by Stefan Turek & the FEAT group
3// FEAT3 is released under the GNU General Public License version 3,
4// see the file 'copyright.txt' in the top level directory for details.
5
6#pragma once
7
8// includes, FEAT
11#include <kernel/util/type_traits.hpp>
12#include <kernel/lafem/container.hpp>
13#include <kernel/lafem/dense_vector.hpp>
14#include <kernel/util/math.hpp>
15#include <kernel/adjacency/permutation.hpp>
16#include <kernel/lafem/arch/max_abs_index.hpp>
17#include <kernel/lafem/arch/min_abs_index.hpp>
18#include <kernel/lafem/arch/max_index.hpp>
19#include <kernel/lafem/arch/min_index.hpp>
20#include <kernel/lafem/arch/max_rel_diff.hpp>
21
22
23namespace FEAT
24{
25 namespace LAFEM
26 {
47 template <typename DT_, typename IT_ = Index>
48 class SparseVector : public Container<DT_, IT_>
49 {
50 private:
51 template <typename T1_, typename T2_>
52 static void _insertion_sort(T1_ * key, T2_ * val1, Index size)
53 {
54 T1_ swap_key;
55 T2_ swap1;
56 for (Index i(1), j ; i < size ; ++i)
57 {
58 swap_key = key[i];
59 swap1 = val1[i];
60 j = i;
61 while (j > 0 && key[j-1] > swap_key)
62 {
63 key[j] = key[j-1];
64 val1[j] = val1[j-1];
65 --j;
66 }
67 key[j] = swap_key;
68 val1[j] = swap1;
69 }
70 }
71
72 Index & _used_elements()
73 {
74 return this->_scalar_index.at(1);
75 }
76
77 Index & _allocated_elements()
78 {
79 return this->_scalar_index.at(2);
80 }
81
82 Index & _sorted()
83 {
84 return this->_scalar_index.at(4);
85 }
86
87 bool _remove_element(IT_ ind)
88 {
89 IT_* pindices = this->_indices.at(0);
90 IT_* ptr = std::find(pindices, pindices + _used_elements(), ind);
91 if(ptr == pindices + _used_elements())
92 {
93 return false;
94 }
95 _sorted() = 0;
96 *ptr = std::numeric_limits<IT_>::max();
97 sort();
98 return true;
99 }
100
101 public:
103 typedef DT_ DataType;
105 typedef IT_ IndexType;
106
112 explicit SparseVector() :
113 Container<DT_, IT_> (0)
114 {
115 this->_scalar_index.push_back(0);
116 this->_scalar_index.push_back(0);
117 this->_scalar_index.push_back(Math::min<Index>(0, 1000));
118 this->_scalar_index.push_back(1);
119 }
120
128 explicit SparseVector(Index size_in) :
129 Container<DT_, IT_>(size_in)
130 {
131 this->_scalar_index.push_back(0);
132 this->_scalar_index.push_back(0);
133 this->_scalar_index.push_back(Math::min<Index>(size_in, 1000));
134 this->_scalar_index.push_back(1);
135 }
136
147 explicit SparseVector(Index size_in, DenseVector<DT_, IT_> & elements_in,
148 DenseVector<IT_, IT_> & indices_in, bool is_sorted = true) :
149 Container<DT_, IT_>(size_in)
150 {
151 XASSERT(size_in != Index(0));
152 XASSERTM(indices_in.size() == elements_in.size(), "Vector size mismatch!");
153
154 this->_scalar_index.push_back(elements_in.size());
155 this->_scalar_index.push_back(elements_in.size());
156 this->_scalar_index.push_back(Math::min<Index>(size_in, 1000));
157 this->_scalar_index.push_back(Index(is_sorted));
158
159 this->_elements.push_back(elements_in.elements());
160 this->_elements_size.push_back(elements_in.size());
161 this->_indices.push_back(indices_in.elements());
162 this->_indices_size.push_back(indices_in.size());
163
164 for (Index i(0) ; i < this->_elements.size() ; ++i)
166 for (Index i(0) ; i < this->_indices.size() ; ++i)
168
169 this->sort();
170 }
171
179 template <typename DT2_ = DT_, typename IT2_ = IT_>
180 explicit SparseVector(std::vector<char> input) :
181 Container<DT_, IT_>(0)
182 {
183 deserialize<DT2_, IT2_>(input);
184 }
185
194 Container<DT_, IT_>(std::forward<SparseVector>(other))
195 {
196 }
197
206 explicit SparseVector(FileMode mode, const String& filename) :
207 Container<DT_, IT_>(0)
208 {
209 read_from(mode, filename);
210 }
211
220 explicit SparseVector(FileMode mode, std::istream& file) :
221 Container<DT_, IT_>(0)
222 {
223 read_from(mode, file);
224 }
225
234 {
235 this->move(std::forward<SparseVector>(other));
236
237 return *this;
238 }
239
249 {
250 SparseVector t;
251 t.clone(*this, clone_mode);
252 return t;
253 }
254
263 template<typename DT2_, typename IT2_>
264 void clone(const SparseVector<DT2_, IT2_> & other, CloneMode clone_mode = CloneMode::Deep)
265 {
266 Container<DT_, IT_>::clone(other, clone_mode);
267 }
268
279 template <typename DT2_, typename IT2_>
281 {
282 // clean up previous mess before creating a new vector
283 this->sort();
284 this->clone(other);
285 }
286
292 template <Perspective = Perspective::native>
293 DT_ * elements()
294 {
295 if(this->_elements.empty())
296 return nullptr;
297 if (sorted() == 0)
298 const_cast<SparseVector *>(this)->sort();
299 return this->_elements.at(0);
300 }
301
302 template <Perspective = Perspective::native>
303 DT_ const * elements() const
304 {
305 if(this->_elements.empty())
306 return nullptr;
307 if (sorted() == 0)
308 const_cast<SparseVector *>(this)->sort();
309 return this->_elements.at(0);
310 }
311
317 IT_ * indices()
318 {
319 if(this->_indices.empty())
320 return nullptr;
321 if (sorted() == 0)
322 const_cast<SparseVector *>(this)->sort();
323 return this->_indices.at(0);
324 }
325
326 IT_ const * indices() const
327 {
328 if(this->_indices.empty())
329 return nullptr;
330 if (sorted() == 0)
331 const_cast<SparseVector *>(this)->sort();
332 return this->_indices.at(0);
333 }
334
342 const DT_ operator()(Index index) const
343 {
344 ASSERTM(index < this->_scalar_index.at(0), "index exceeds sparse vector size");
345
346 MemoryPool::synchronize();
347
348 if (this->_elements.empty())
349 return DT_(0.);
350
351 if (sorted() == 0)
352 const_cast<SparseVector *>(this)->sort();
353
354 Index i(0);
355 while (i < used_elements())
356 {
357 if (indices()[i] >= index)
358 break;
359 ++i;
360 }
361
362 if (i < used_elements() && indices()[i] == index)
363 return elements()[i];
364 else
365 return DT_(0.);
366 }
367
368
375 void operator()(Index index, DT_ val)
376 {
377 ASSERTM(index < this->_scalar_index.at(0), "index exceeds sparse vector size");
378
379 // flag container as not sorted anymore
380 // CAUTION: do not use any method triggering resorting until we are finished
381 _sorted() = 0;
382
383 // vector is empty, no arrays allocated
384 if (this->_elements.empty())
385 {
386 this->_elements.push_back(MemoryPool::template allocate_memory<DT_>(alloc_increment()));
387 this->_elements_size.push_back(alloc_increment());
388 MemoryPool::template set_memory<DT_>(this->_elements.back(), DT_(4711), alloc_increment());
389 this->_indices.push_back(MemoryPool::template allocate_memory<IT_>(alloc_increment()));
390 this->_indices_size.push_back(alloc_increment());
391 MemoryPool::template set_memory<IT_>(this->_indices.back(), IT_(4711), alloc_increment());
392 this->_allocated_elements() = alloc_increment();
393 this->_elements.at(0)[0] = val;
394 this->_indices.at(0)[0] = IT_(index);
395 this->_used_elements() = 1;
396 }
397
398 // append element in already allocated arrays
399 else if(_used_elements() < allocated_elements())
400 {
401 this->_elements.at(0)[this->_used_elements()] = val;
402 this->_indices.at(0)[this->_used_elements()] = IT_(index);
403 ++this->_used_elements();
404 }
405
406 // reallocate arrays, append element
407 else
408 {
409 _allocated_elements() += alloc_increment();
410
411 DT_ * elements_new(MemoryPool::template allocate_memory<DT_>(allocated_elements()));
412 MemoryPool::template set_memory<DT_>(elements_new, DT_(4711), allocated_elements());
413 IT_ * indices_new(MemoryPool::template allocate_memory<IT_>(allocated_elements()));
414 MemoryPool::template set_memory<IT_>(indices_new, IT_(4711), allocated_elements());
415
416 MemoryPool::copy(elements_new, this->_elements.at(0), _used_elements());
417 MemoryPool::copy(indices_new, this->_indices.at(0), _used_elements());
418
421
422 this->_elements.at(0) = elements_new;
423 this->_indices.at(0) = indices_new;
424
425 this->_elements.at(0)[this->_used_elements()] = val;
426 this->_indices.at(0)[this->_used_elements()] = IT_(index);
427
428 ++this->_used_elements();
429 this->_elements_size.at(0) = allocated_elements();
430 this->_indices_size.at(0) = allocated_elements();
431 }
432 }
433
434 void sort()
435 {
436 if (sorted() == 0)
437 {
438 //first of all, mark vector as sorted, because otherwise we would call ourselves inifite times
439 // CAUTION: do not use any method triggering resorting until we are finished
440 _sorted() = 1;
441
442 // check if there is anything to be sorted
443 if(_used_elements() == Index(0))
444 return;
445
446 IT_ * pindices = this->_indices.at(0);
447 DT_ * pelements = this->_elements.at(0);
448
449 _insertion_sort(pindices, pelements, _used_elements());
450
451 // find and mark duplicate entries
452 for (Index i(1) ; i < _used_elements() ; ++i)
453 {
454 if (pindices[i-1] == pindices[i])
455 {
456 pindices[i-1] = std::numeric_limits<IT_>::max();
457 }
458 }
459
460 // sort out marked duplicated elements
461 _insertion_sort(pindices, pelements, _used_elements());
462 Index junk(0);
463 while (pindices[_used_elements() - 1 - junk] == std::numeric_limits<IT_>::max() && junk < _used_elements())
464 ++junk;
465 _used_elements() -= junk;
466 }
467 }
468
469 template<typename IndexContainer>
470 bool remove_elements(const IndexContainer& inds)
471 {
472 bool success = true;
473 for(auto i : inds)
474 {
475 success &= _remove_element(IndexType(i));
476 }
477 return success;
478 }
479
480 bool remove_element(IndexType ind)
481 {
482 return _remove_element(ind);
483 }
484
485 bool element_exists(IndexType ind) const
486 {
487 const IT_* pindices = this->_indices.at(0);
488 return std::find(pindices, pindices + this->_scalar_index.at(1), ind) != pindices + this->_scalar_index.at(1);
489 }
490
496 DT_ max_abs_element() const
497 {
498 TimeStamp ts_start;
499
500 Index max_abs_index = Arch::MaxAbsIndex::value(this->template elements<Perspective::pod>(), this->template used_elements<Perspective::pod>());
501 ASSERT(max_abs_index < this->template used_elements<Perspective::pod>());
502 DT_ result(this->template elements<Perspective::pod>()[max_abs_index]);
503 result = Math::abs(result);
504
505 TimeStamp ts_stop;
506 Statistics::add_time_reduction(ts_stop.elapsed(ts_start));
507
508 return result;
509 }
510
516 DT_ min_abs_element() const
517 {
518 TimeStamp ts_start;
519
520 Index min_abs_index = Arch::MinAbsIndex::value(this->template elements<Perspective::pod>(), this->template used_elements<Perspective::pod>());
521 ASSERT(min_abs_index < this->template used_elements<Perspective::pod>());
522 DT_ result(this->template elements<Perspective::pod>()[min_abs_index]);
523 result = Math::abs(result);
524
525 TimeStamp ts_stop;
526 Statistics::add_time_reduction(ts_stop.elapsed(ts_start));
527
528 return result;
529 }
530
536 DT_ max_element() const
537 {
538 TimeStamp ts_start;
539
540 Index max_index = Arch::MaxIndex::value(this->template elements<Perspective::pod>(), this->template used_elements<Perspective::pod>());
541 ASSERT(max_index < this->template used_elements<Perspective::pod>());
542 DT_ result(this->template elements<Perspective::pod>()[max_index]);
543
544 TimeStamp ts_stop;
545 Statistics::add_time_reduction(ts_stop.elapsed(ts_start));
546
547 return result;
548 }
549
555 DT_ min_element() const
556 {
557 TimeStamp ts_start;
558
559 Index min_index = Arch::MinIndex::value(this->template elements<Perspective::pod>(), this->template used_elements<Perspective::pod>());
560 ASSERT(min_index < this->template used_elements<Perspective::pod>());
561 DT_ result(this->template elements<Perspective::pod>()[min_index]);
562
563 TimeStamp ts_stop;
564 Statistics::add_time_reduction(ts_stop.elapsed(ts_start));
565
566 return result;
567 }
568
575 DT_ max_rel_diff(const SparseVector & x) const
576 {
577 XASSERTM(x.used_elements() == this->used_elements(), "Nonzero count does not match!");
578 TimeStamp ts_start;
579
580 DataType max_rel_diff = Arch::MaxRelDiff::value(this->template elements<Perspective::pod>(),
581 x.template elements<Perspective::pod>(), this->template used_elements<Perspective::pod>());
582
583 TimeStamp ts_stop;
584 Statistics::add_time_reduction(ts_stop.elapsed(ts_start));
585
586 return max_rel_diff;
587 }
588
589
597 template <typename DT2_ = DT_, typename IT2_ = IT_>
598 void deserialize(std::vector<char> input)
599 {
600 this->template _deserialize<DT2_, IT2_>(FileMode::fm_sv, input);
601 }
602
613 template <typename DT2_ = DT_, typename IT2_ = IT_>
614 std::vector<char> serialize(const LAFEM::SerialConfig& config = SerialConfig()) const
615 {
616 return this->template _serialize<DT2_, IT2_>(FileMode::fm_sv, config);
617 }
618
625 void read_from(FileMode mode, const String& filename)
626 {
627 std::ios_base::openmode bin = std::ifstream::in | std::ifstream::binary;
628 if(mode == FileMode::fm_mtx)
629 bin = std::ifstream::in;
630 std::ifstream file(filename.c_str(), bin);
631 if (! file.is_open())
632 XABORTM("Unable to open Vector file " + filename);
633 read_from(mode, file);
634 file.close();
635 }
636
643 void read_from(FileMode mode, std::istream& file)
644 {
645 switch(mode)
646 {
648 case FileMode::fm_sv:
649 this->template _deserialize<double, std::uint64_t>(FileMode::fm_sv, file);
650 break;
651 case FileMode::fm_mtx:
652 {
653 this->clear();
654 this->_scalar_index.push_back(0);
655 this->_scalar_index.push_back(0);
656 this->_scalar_index.push_back(Math::min<Index>(0, 1000));
657 this->_scalar_index.push_back(1);
658
659 Index rows;
660 Index nnz;
661 String line;
662 std::getline(file, line);
663 if (line.find("%%MatrixMarket matrix coordinate real general") == String::npos)
664 {
665 XABORTM("Input-file is not a compatible mtx-file");
666 }
667 while(!file.eof())
668 {
669 std::getline(file,line);
670 if (file.eof())
671 XABORTM("Input-file is empty");
672
673 String::size_type begin(line.find_first_not_of(" "));
674 if (line.at(begin) != '%')
675 break;
676 }
677 {
678 String::size_type begin(line.find_first_not_of(" "));
679 line.erase(0, begin);
680 String::size_type end(line.find_first_of(" "));
681 String srows(line, 0, end);
682 rows = (Index)atol(srows.c_str());
683 line.erase(0, end);
684
685 begin = line.find_first_not_of(" ");
686 line.erase(0, begin);
687 end = line.find_first_of(" ");
688 String scols(line, 0, end);
689 Index cols((Index)atol(scols.c_str()));
690 line.erase(0, end);
691 if (cols != 1)
692 XABORTM("Input-file is no sparse-vector-file");
693
694 begin = line.find_first_not_of(" ");
695 line.erase(0, begin);
696 end = line.find_first_of(" ");
697 String snnz(line, 0, end);
698 nnz = (Index)atol(snnz.c_str());
699 line.erase(0, end);
700 }
701
702 DenseVector<IT_, IT_> ind(nnz);
703 DenseVector<DT_, IT_> val(nnz);
704
705 IT_ * pind(ind.elements());
706 DT_ * pval(val.elements());
707
708 while(!file.eof())
709 {
710 std::getline(file, line);
711 if (file.eof())
712 break;
713
714 String::size_type begin(line.find_first_not_of(" "));
715 line.erase(0, begin);
716 String::size_type end(line.find_first_of(" "));
717 String srow(line, 0, end);
718 IT_ row((IT_)atol(srow.c_str()));
719 --row;
720 line.erase(0, end);
721
722 begin = line.find_first_not_of(" ");
723 line.erase(0, begin);
724 end = line.find_first_of(" ");
725 line.erase(0, end);
726
727 begin = line.find_first_not_of(" ");
728 line.erase(0, begin);
729 end = line.find_first_of(" ");
730 String sval(line, 0, end);
731 DT_ tval((DT_)atof(sval.c_str()));
732
733 *pval = tval;
734 *pind = row;
735 ++pval;
736 ++pind;
737 }
738 this->move(SparseVector<DT_, IT_>(rows, val, ind, false));
739 break;
740 }
741 default:
742 XABORTM("Filemode not supported!");
743 }
744 }
745
752 void write_out(FileMode mode, const String& filename) const
753 {
754 std::ios_base::openmode bin = std::ofstream::out | std::ofstream::binary;
755 if(mode == FileMode::fm_mtx)
756 bin = std::ofstream::out;
757 std::ofstream file;
758 char* buff = nullptr;
759 if(mode == FileMode::fm_mtx)
760 {
761 buff = new char[LAFEM::FileOutStreamBufferSize];
762 file.rdbuf()->pubsetbuf(buff, LAFEM::FileOutStreamBufferSize);
763 }
764 file.open(filename.c_str(), bin);
765 if(! file.is_open())
766 XABORTM("Unable to open Matrix file " + filename);
767 write_out(mode, file);
768 file.close();
769 delete[] buff;
770 }
771
778 void write_out(FileMode mode, std::ostream& file) const
779 {
780 switch(mode)
781 {
783 case FileMode::fm_sv:
784 this->template _serialize<double, std::uint64_t>(FileMode::fm_sv, file);
785 break;
786 case FileMode::fm_mtx:
787 {
788
789 file << "%%MatrixMarket matrix coordinate real general\n";
790 file << this->size() << " " << 1 << " " << this->used_elements() << "\n";
791
792 const Index u_elem(this->used_elements());
793 const IT_ * pind(this->indices());
794 const DT_ * pval(this->elements());
795 for (Index i(0) ; i < u_elem ; ++i, ++pind, ++pval)
796 {
797 file << *pind+1 << " " << 1 << " " << stringify_fp_sci(*pval) << "\n";
798 }
799 break;
800 }
801 default:
802 XABORTM("Filemode not supported!");
803 }
804 }
805
811 template <Perspective = Perspective::native>
813 {
814 if(this->_scalar_index.empty())
815 return Index(0);
816 if (sorted() == 0)
817 const_cast<SparseVector *>(this)->sort();
818 return this->_scalar_index.at(1);
819 }
820
827 {
828 if(this->_scalar_index.empty())
829 return Index(0);
830 return this->_scalar_index.at(2);
831 }
832
839 {
840 if(this->_scalar_index.empty())
841 return Index(0);
842 return this->_scalar_index.at(3);
843 }
844
850 Index sorted() const
851 {
852 if(this->_scalar_index.empty())
853 return Index(0);
854 return this->_scalar_index.at(4);
855 }
856
859 {
860 if (perm.size() == 0)
861 return;
862
863 XASSERTM(perm.size() == this->size(), "Container size does not match permutation size");
864
865 SparseVector<DT_, IT_> target(this->size());
866
867 auto inv = perm.inverse();
868 const Index * const inv_pos(inv.get_perm_pos());
869 for (Index i(0) ; i < this->used_elements() ; ++i)
870 {
871 const Index col = this->indices()[i];
872 target(inv_pos[col], (*this)(col));
873 }
874
875 target.sort();
876 this->move(std::move(target));
877 }
878
884 static String name()
885 {
886 return "SparseVector";
887 }
888
889
899 bool same_layout(const SparseVector& other) const
900 {
901 if(this->size() != other.size())
902 return false;
903 if(this->used_elements() != other.used_elements())
904 return false;
905
906 Index n = this->used_elements();
907 if(n == Index(0))
908 return true; // both vectors are empty
909
910 const IT_* a = this->indices();
911 const IT_* b = other.indices();
912
913 // shallow copy? (aka same array)
914 if(a == b)
915 return true;
916
917 // check all array entries
918 for(Index i(0); i < n; ++i)
919 {
920 if(a[i] != b[i])
921 return false;
922 }
923
924 // okay, arrays are identical
925 return true;
926 }
927
934 friend std::ostream & operator<< (std::ostream & lhs, const SparseVector & b)
935 {
936 lhs << "[";
937 for (Index i(0) ; i < b.size() ; ++i)
938 {
939 lhs << " " << stringify(b(i));
940 }
941 lhs << "]";
942
943 return lhs;
944 }
945 }; // class SparseVector<...>
946
947#ifdef FEAT_EICKT
948 extern template class SparseVector<float, std::uint32_t>;
949 extern template class SparseVector<double, std::uint32_t>;
950 extern template class SparseVector<float, std::uint64_t>;
951 extern template class SparseVector<double, std::uint64_t>;
952#endif
953
954
955 } // namespace LAFEM
956} // namespace FEAT
#define ASSERT(expr)
Debug-Assertion macro definition.
Definition: assertion.hpp:229
#define XABORTM(msg)
Abortion macro definition with custom message.
Definition: assertion.hpp:192
#define ASSERTM(expr, msg)
Debug-Assertion macro definition with custom message.
Definition: assertion.hpp:230
#define XASSERT(expr)
Assertion macro definition.
Definition: assertion.hpp:262
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Definition: assertion.hpp:263
FEAT Kernel base header.
Index size() const
returns the size of the permutation
Permutation inverse() const
Computes the inverse permutation.
Container base class.
Definition: container.hpp:220
std::vector< DT_ * > _elements
List of pointers to all datatype dependent arrays.
Definition: container.hpp:226
std::vector< Index > _elements_size
List of corresponding datatype array sizes.
Definition: container.hpp:230
Index size() const
Returns the containers size.
Definition: container.hpp:1136
std::vector< IT_ * > _indices
List of pointers to all IT_ dependent arrays.
Definition: container.hpp:228
void clone(const Container &other, CloneMode clone_mode=CloneMode::Weak)
Clone operation.
Definition: container.hpp:902
void move(Container &&other)
Assignment move operation.
Definition: container.hpp:989
virtual void clear()
Free all allocated arrays.
Definition: container.hpp:875
std::vector< Index > _indices_size
List of corresponding IT_ array sizes.
Definition: container.hpp:232
std::vector< Index > _scalar_index
List of scalars with datatype index.
Definition: container.hpp:234
Dense data vector class template.
DT_ * elements()
Get a pointer to the data array.
Config class for serialize parameter.
Definition: container.hpp:47
Sparse vector class template.
void write_out(FileMode mode, const String &filename) const
Write out vector to file.
SparseVector(FileMode mode, std::istream &file)
Constructor.
DT_ max_abs_element() const
Retrieve the absolute maximum value of this vector.
static String name()
Returns a descriptive string.
void read_from(FileMode mode, const String &filename)
Read in vector from file.
SparseVector(SparseVector &&other)
Move Constructor.
void deserialize(std::vector< char > input)
Deserialization of complete container entity.
DT_ min_element() const
Retrieve the minimum value of this vector.
void read_from(FileMode mode, std::istream &file)
Read in vector from stream.
DT_ * elements()
Get a pointer to the data array.
bool same_layout(const SparseVector &other) const
Checks whether the layout of this vector is identical to another sparse vector.
void operator()(Index index, DT_ val)
Set specific vector element.
IT_ * indices()
Get a pointer to the non zero indices array.
void clone(const SparseVector< DT2_, IT2_ > &other, CloneMode clone_mode=CloneMode::Deep)
Clone operation.
Index sorted() const
Retrieve status of element sorting.
Index alloc_increment() const
Retrieve allocation incrementation value.
SparseVector(FileMode mode, const String &filename)
Constructor.
Index used_elements() const
Retrieve non zero element count.
SparseVector clone(CloneMode clone_mode=CloneMode::Deep) const
Clone operation.
void convert(const SparseVector< DT2_, IT2_ > &other)
Conversion method.
std::vector< char > serialize(const LAFEM::SerialConfig &config=SerialConfig()) const
Serialization of complete container entity.
SparseVector & operator=(SparseVector &&other)
Assignment move operator.
SparseVector(std::vector< char > input)
Constructor.
DT_ min_abs_element() const
Retrieve the absolute minimum value of this vector.
DT_ max_element() const
Retrieve the maximum value of this vector.
SparseVector(Index size_in)
Constructor.
DT_ max_rel_diff(const SparseVector &x) const
Retrieve the maximum relative difference of this vector and another one y.max_rel_diff(x) returns .
const DT_ operator()(Index index) const
Retrieve specific vector element.
SparseVector(Index size_in, DenseVector< DT_, IT_ > &elements_in, DenseVector< IT_, IT_ > &indices_in, bool is_sorted=true)
Constructor.
Index allocated_elements() const
Retrieve amount of allocated elements.
IT_ IndexType
Our indextype.
void permute(Adjacency::Permutation &perm)
Permutate vector according to the given Permutation.
friend std::ostream & operator<<(std::ostream &lhs, const SparseVector &b)
SparseVector streaming operator.
void write_out(FileMode mode, std::ostream &file) const
Write out vector to file.
static void copy(DT_ *dest, const DT_ *src, const Index count)
Copy memory area from src to dest.
static void release_memory(void *address)
release memory or decrease reference counter
static void increase_memory(void *address)
increase memory counter
String class implementation.
Definition: string.hpp:46
Time stamp class.
Definition: time_stamp.hpp:54
double elapsed(const TimeStamp &before) const
Calculates the time elapsed between two time stamps.
Definition: time_stamp.hpp:100
constexpr std::size_t FileOutStreamBufferSize
OutStreamBufferSize.
Definition: base.hpp:124
T_ abs(T_ x)
Returns the absolute value.
Definition: math.hpp:275
@ success
solving successful (convergence criterion fulfilled)
FEAT namespace.
Definition: adjactor.hpp:12
String stringify(const T_ &item)
Converts an item into a String.
Definition: string.hpp:944
String stringify_fp_sci(DataType_ value, int precision=0, int width=0, bool sign=false)
Prints a floating point value to a string in scientific notation.
Definition: string.hpp:1088
std::uint64_t Index
Index data type.