FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
sparse_matrix_cscr.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/lafem/forward.hpp>
12#include <kernel/lafem/container.hpp>
13#include <kernel/lafem/dense_vector.hpp>
14#include <kernel/lafem/sparse_layout.hpp>
15#include <kernel/lafem/arch/scale_row_col.hpp>
16#include <kernel/lafem/arch/scale.hpp>
17#include <kernel/lafem/arch/axpy.hpp>
18#include <kernel/lafem/arch/apply.hpp>
19#include <kernel/lafem/arch/norm.hpp>
20#include <kernel/lafem/arch/diagonal.hpp>
21#include <kernel/lafem/arch/lumping.hpp>
22#include <kernel/lafem/arch/row_norm.hpp>
23#include <kernel/adjacency/graph.hpp>
24#include <kernel/adjacency/permutation.hpp>
25#include <kernel/util/statistics.hpp>
26#include <kernel/util/time_stamp.hpp>
27#include <kernel/lafem/vector_mirror.hpp>
28
29#include <fstream>
30
31
32namespace FEAT
33{
34 namespace LAFEM
35 {
60 template <typename DT_, typename IT_ = Index>
61 class SparseMatrixCSCR : public Container<DT_, IT_>
62 {
63 private:
64 Index & _size()
65 {
66 return this->_scalar_index.at(0);
67 }
68
69 Index & _rows()
70 {
71 return this->_scalar_index.at(1);
72 }
73
74 Index & _columns()
75 {
76 return this->_scalar_index.at(2);
77 }
78
79 Index & _used_elements()
80 {
81 return this->_scalar_index.at(3);
82 }
83
84 Index & _used_rows()
85 {
86 return this->_scalar_index.at(4);
87 }
88
89 public:
91 typedef DT_ DataType;
93 typedef IT_ IndexType;
95 typedef DT_ ValueType;
103 typedef const IT_* ImageIterator;
105 template <typename DT2_ = DT_, typename IT2_ = IT_>
107
109 template <typename DataType2_, typename IndexType2_>
111
112 static constexpr bool is_global = false;
113 static constexpr bool is_local = true;
114
120 explicit SparseMatrixCSCR() :
121 Container<DT_, IT_> (0)
122 {
123 this->_scalar_index.push_back(0);
124 this->_scalar_index.push_back(0);
125 this->_scalar_index.push_back(0);
126 this->_scalar_index.push_back(0);
127 }
128
140 explicit SparseMatrixCSCR(Index rows_in, Index columns_in) :
141 Container<DT_, IT_> (rows_in * columns_in)
142 {
143 this->_scalar_index.push_back(rows_in);
144 this->_scalar_index.push_back(columns_in);
145 this->_scalar_index.push_back(0);
146 this->_scalar_index.push_back(0);
147 }
148
161 explicit SparseMatrixCSCR(Index rows_in, Index columns_in, Index used_elements_in, Index used_rows_in) :
162 Container<DT_, IT_> (rows_in * columns_in)
163 {
164 XASSERT(rows_in != Index(0) && columns_in != Index(0));
165
166 this->_scalar_index.push_back(rows_in);
167 this->_scalar_index.push_back(columns_in);
168 this->_scalar_index.push_back(used_elements_in);
169 this->_scalar_index.push_back(used_rows_in);
170
171 this->_indices.push_back(MemoryPool::template allocate_memory<IT_>(_used_elements()));
172 this->_indices_size.push_back(_used_elements());
173
174 this->_indices.push_back(MemoryPool::template allocate_memory<IT_>(_used_rows() + 1));
175 this->_indices_size.push_back(_used_rows() + 1);
176
177 this->_indices.push_back(MemoryPool::template allocate_memory<IT_>(_used_rows()));
178 this->_indices_size.push_back(_used_rows());
179
180 this->_elements.push_back(MemoryPool::template allocate_memory<DT_>(_used_elements()));
181 this->_elements_size.push_back(_used_elements());
182 }
183
191 explicit SparseMatrixCSCR(const SparseLayout<IT_, layout_id> & layout_in) :
192 Container<DT_, IT_> (layout_in._scalar_index.at(0))
193 {
194 this->_indices.assign(layout_in._indices.begin(), layout_in._indices.end());
195 this->_indices_size.assign(layout_in._indices_size.begin(), layout_in._indices_size.end());
196 this->_scalar_index.assign(layout_in._scalar_index.begin(), layout_in._scalar_index.end());
197
198 for (auto i : this->_indices)
200
201 this->_elements.push_back(MemoryPool::template allocate_memory<DT_>(_used_elements()));
202 this->_elements_size.push_back(_used_elements());
203 }
204
212 template <typename MT_>
213 explicit SparseMatrixCSCR(const MT_ & other) :
214 Container<DT_, IT_>(other.size())
215 {
216 convert(other);
217 }
218
227 explicit SparseMatrixCSCR(FileMode mode, const String& filename) :
228 Container<DT_, IT_>(0)
229 {
230 read_from(mode, filename);
231 }
232
241 explicit SparseMatrixCSCR(FileMode mode, std::istream& file) :
242 Container<DT_, IT_>(0)
243 {
244 read_from(mode, file);
245 }
246
260 explicit SparseMatrixCSCR(const Index rows_in, const Index columns_in,
261 DenseVector<IT_, IT_> & col_ind_in, DenseVector<DT_, IT_> & val_in, DenseVector<IT_, IT_> & row_ptr_in,
262 DenseVector<IT_, IT_> & row_numbers_in) :
263 Container<DT_, IT_>(rows_in * columns_in)
264 {
266 XASSERT(col_ind_in.size() > 0);
267 XASSERT(val_in.size() > 0);
268 XASSERT(row_ptr_in.size() > 0);
269 XASSERT(row_numbers_in.size() > 0);
270 XASSERT(row_numbers_in.size() + 1 == row_ptr_in.size());
271
272 this->_scalar_index.push_back(rows_in);
273 this->_scalar_index.push_back(columns_in);
274 this->_scalar_index.push_back(val_in.size());
275 this->_scalar_index.push_back(row_numbers_in.size());
276
277 this->_elements.push_back(val_in.elements());
278 this->_elements_size.push_back(val_in.size());
279 this->_indices.push_back(col_ind_in.elements());
280 this->_indices_size.push_back(col_ind_in.size());
281 this->_indices.push_back(row_ptr_in.elements());
282 this->_indices_size.push_back(row_ptr_in.size());
283 this->_indices.push_back(row_numbers_in.elements());
284 this->_indices_size.push_back(row_numbers_in.size());
285
286 for (Index i(0) ; i < this->_elements.size() ; ++i)
288 for (Index i(0) ; i < this->_indices.size() ; ++i)
290 }
291
300 explicit SparseMatrixCSCR(const SparseMatrixCSR<DT_, IT_> & csr, const VectorMirror<DT_, IT_> & non_zero_rows) :
301 Container<DT_, IT_>(csr.size())
302 {
303 XASSERT(non_zero_rows.num_indices() > 0);
304
305 const IT_ * row_main(nullptr);
306 const IT_ * indices(nullptr);
307 IT_ * trow_main(nullptr);
308 IT_ * tindices(nullptr);
309 row_main = csr.row_ptr();
310 indices = non_zero_rows.indices();
311
312 Index tused_elements(0);
313 for (Index i(0) ; i < non_zero_rows.num_indices() ; ++i)
314 {
315 const Index row(indices[i]);
316 tused_elements += row_main[row+1] - row_main[row];
317 }
318
319 this->_scalar_index.push_back(csr.rows());
320 this->_scalar_index.push_back(csr.columns());
321 this->_scalar_index.push_back(tused_elements);
322 this->_scalar_index.push_back(non_zero_rows.num_indices());
323
324 this->_indices.push_back(MemoryPool::template allocate_memory<IT_>(_used_elements()));
325 this->_indices_size.push_back(_used_elements());
326
327 this->_indices.push_back(MemoryPool::template allocate_memory<IT_>(_used_rows() + 1));
328 this->_indices_size.push_back(_used_rows() + 1);
329
330 this->_indices.push_back(MemoryPool::template allocate_memory<IT_>(_used_rows()));
331 this->_indices_size.push_back(_used_rows());
332
333 this->_elements.push_back(MemoryPool::template allocate_memory<DT_>(_used_elements()));
334 this->_elements_size.push_back(_used_elements());
335
336 Index row_count(0);
337 IT_ offset(0);
338 this->row_ptr()[0]=offset;
339 for (Index i(0) ; i < non_zero_rows.num_indices() ; ++i)
340 {
341 const IT_ row(indices[i]);
342 const IT_ start(row_main[row]);
343 const IT_ end(row_main[row+1]);
344 const IT_ row_size(end - start);
345 MemoryPool::set_memory(this->row_ptr() + row_count + 1, offset + row_size);
346 MemoryPool::set_memory(this->row_numbers() + row_count, row);
347 MemoryPool::copy(this->val() + offset, csr.val() + start, row_size);
348 MemoryPool::copy(this->col_ind() + offset, csr.col_ind() + start, row_size);
349 ++row_count;
350 offset += row_size;
351 }
352
353 delete[] trow_main;
354 delete[] tindices;
355 }
356
364 explicit SparseMatrixCSCR(const Adjacency::Graph & graph) :
365 Container<DT_, IT_>(0)
366 {
367 // get number of rows, columns and indices
368 Index num_rows = graph.get_num_nodes_domain();
369 Index num_cols = graph.get_num_nodes_image();
370 Index num_nzes = graph.get_num_indices();
371
372 if (num_nzes == 0)
373 {
374 this->move(SparseMatrixCSCR(num_rows, num_cols));
375 return;
376 }
377
378 // get graph arrays
379 const Index* dom_ptr = graph.get_domain_ptr();
380 const Index* img_idx = graph.get_image_idx();
381
382 // count number of non-empty rows
383 Index num_nzrs = Index(0);
384 for(Index i(0); i < num_rows; ++i)
385 {
386 num_nzrs += Index(dom_ptr[i] < dom_ptr[i+1] ? 1 : 0);
387 }
388
389 // allocate output matrix
390 SparseMatrixCSCR<DT_, IT_> matrix(num_rows, num_cols, num_nzes, num_nzrs);
391
392 // get matrix arrays
393 IndexType* trow_ptr = matrix.row_ptr();
394 IndexType* trow_idx = matrix.row_numbers();
395 IndexType* tcol_idx = matrix.col_ind();
396
397 // fill arrays
398 trow_ptr[0] = IndexType(dom_ptr[0]);
399 for(Index i(0), j(0); i < num_rows; ++i)
400 {
401 if(dom_ptr[i] < dom_ptr[i + 1])
402 {
403 ASSERT(j < num_nzrs);
404 trow_idx[ j] = IndexType(i);
405 trow_ptr[++j] = IndexType(dom_ptr[i+1]);
406 }
407 }
408
409 for(Index k(0); k < num_nzes; ++k)
410 tcol_idx[k] = IndexType(img_idx[k]);
411
412 this->convert(matrix);
413 }
414
422 template <typename DT2_ = DT_, typename IT2_ = IT_>
423 explicit SparseMatrixCSCR(std::vector<char> input) :
424 Container<DT_, IT_>(0)
425 {
426 deserialize<DT2_, IT2_>(input);
427 }
428
437 Container<DT_, IT_>(std::forward<SparseMatrixCSCR>(other))
438 {
439 }
440
449 {
450 this->move(std::forward<SparseMatrixCSCR>(other));
451
452 return *this;
453 }
454
464 {
466 t.clone(*this, clone_mode);
467 return t;
468 }
469
478 template<typename DT2_, typename IT2_>
480 {
481 Container<DT_, IT_>::clone(other, clone_mode);
482 }
483
491 template <typename DT2_, typename IT2_>
493 {
494 this->assign(other);
495 }
496
504 template <typename MT_>
505 void convert(const MT_ & a)
506 {
507 typename MT_::template ContainerType<DT_, IT_> ta;
508 ta.convert(a);
509
510 const Index arows(ta.template rows<Perspective::pod>());
511 const Index acolumns(ta.template columns<Perspective::pod>());
512 const Index aused_elements(ta.template used_elements<Perspective::pod>());
513 Index aused_rows(0);
514
515 for (Index i(0); i < arows; ++i)
516 {
517 aused_rows += ta.get_length_of_line(i) > 0;
518 }
519
520 DenseVector<DT_, IT_> tval(aused_elements);
521 DenseVector<IT_, IT_> tcol_ind(aused_elements);
522 DenseVector<IT_, IT_> trow_ptr(aused_rows + 1);
523 DenseVector<IT_, IT_> trow_numbers(aused_rows);
524
525 DT_ * pval(tval.elements());
526 IT_ * pcol_ind(tcol_ind.elements());
527 IT_ * prow_ptr(trow_ptr.elements());
528 IT_ * prow_numbers(trow_numbers.elements());
529
530 Index row_index(0);
531 Index offset(0);
532 prow_ptr[0] = IT_(0);
533 for (Index i(0); i < arows; ++i)
534 {
535 Index length = ta.get_length_of_line(i);
536 if (length > 0)
537 {
538 prow_ptr[row_index + 1] = IT_(offset + length);
539 prow_numbers[row_index] = IT_(i);
540 ++row_index;
541 offset += length;
542 }
543 }
544
545
546 for (Index i(0); i < arows; ++i)
547 {
548 ta.set_line(i, pval + prow_ptr[i], pcol_ind + prow_ptr[i], 0);
549 }
550
551 this->move(SparseMatrixCSCR<DT_, IT_>(arows, acolumns, tcol_ind, tval, trow_ptr, trow_numbers));
552 }
553
562 {
563 for (Index i(0) ; i < this->_elements.size() ; ++i)
565 for (Index i(0) ; i < this->_indices.size() ; ++i)
567
568 this->_elements.clear();
569 this->_indices.clear();
570 this->_elements_size.clear();
571 this->_indices_size.clear();
572 this->_scalar_index.clear();
573
574 this->_indices.assign(layout_in._indices.begin(), layout_in._indices.end());
575 this->_indices_size.assign(layout_in._indices_size.begin(), layout_in._indices_size.end());
576 this->_scalar_index.assign(layout_in._scalar_index.begin(), layout_in._scalar_index.end());
577
578 for (auto i : this->_indices)
580
581 this->_elements.push_back(MemoryPool::template allocate_memory<DT_>(_used_elements()));
582 this->_elements_size.push_back(_used_elements());
583
584 return *this;
585 }
586
594 template <typename DT2_ = DT_, typename IT2_ = IT_>
595 void deserialize(std::vector<char> input)
596 {
597 this->template _deserialize<DT2_, IT2_>(FileMode::fm_cscr, input);
598 }
599
610 template <typename DT2_ = DT_, typename IT2_ = IT_>
611 std::vector<char> serialize(const LAFEM::SerialConfig& config = SerialConfig()) const
612 {
613 return this->template _serialize<DT2_, IT2_>(FileMode::fm_cscr, config);
614 }
615
622 void read_from(FileMode mode, const String& filename)
623 {
624 std::ios_base::openmode bin = std::ifstream::in | std::ifstream::binary;
625 if(mode == FileMode::fm_mtx)
626 bin = std::ifstream::in;
627 std::ifstream file(filename.c_str(), bin);
628 if (! file.is_open())
629 XABORTM("Unable to open Matrix file " + filename);
630 read_from(mode, file);
631 file.close();
632 }
633
640 void read_from(FileMode mode, std::istream& file)
641 {
642 switch(mode)
643 {
646 this->template _deserialize<double, std::uint64_t>(FileMode::fm_cscr, file);
647 break;
648 default:
649 XABORTM("Filemode not supported!");
650 }
651 }
652
659 void write_out(FileMode mode, const String& filename) const
660 {
661 std::ios_base::openmode bin = std::ofstream::out | std::ofstream::binary;
662 if(mode == FileMode::fm_mtx)
663 bin = std::ofstream::out;
664 std::ofstream file;
665 char* buff = nullptr;
666 if(mode == FileMode::fm_mtx)
667 {
668 buff = new char[LAFEM::FileOutStreamBufferSize];
669 file.rdbuf()->pubsetbuf(buff, LAFEM::FileOutStreamBufferSize);
670 }
671 file.open(filename.c_str(), bin);
672 if(! file.is_open())
673 XABORTM("Unable to open Matrix file " + filename);
674 write_out(mode, file);
675 file.close();
676 delete[] buff;
677 }
678
685 void write_out(FileMode mode, std::ostream& file) const
686 {
687 switch(mode)
688 {
691 this->template _serialize<double, std::uint64_t>(FileMode::fm_cscr, file);
692 break;
693 default:
694 XABORTM("Filemode not supported!");
695 }
696 }
697
706 DT_ operator()(Index row, Index col) const
707 {
708 ASSERT(row < rows());
709 ASSERT(col < columns());
710
711 Index row_index(0);
712 while (row_index < this->used_rows() && Index(this->row_numbers()[row_index]) < row)
713 {
714 ++row_index;
715 }
716
717 if (row_index == this->used_rows() || Index(this->row_numbers()[row_index]) > row)
718 return DT_(0.);
719
720 //row_numbers[row_index] == row
721 for (Index i(Index(this->row_ptr()[row_index])) ; i < Index(this->row_ptr()[row_index + 1]) ; ++i)
722 {
723 if (Index(this->_indices.at(0)[i]) == col)
724 return this->_elements.at(0)[i];
725 if (Index(this->_indices.at(0)[i]) > col)
726 return DT_(0.);
727 }
728 return DT_(0.);
729 }
730
737 {
739 }
740
746 template <Perspective = Perspective::native>
747 Index rows() const
748 {
749 return this->_scalar_index.at(1);
750 }
751
757 template <Perspective = Perspective::native>
759 {
760 return this->_scalar_index.at(2);
761 }
762
768 template <Perspective = Perspective::native>
770 {
771 return this->_scalar_index.at(4);
772 }
773
779 template <Perspective = Perspective::native>
781 {
782 return this->_scalar_index.at(3);
783 }
784
790 IT_ * col_ind()
791 {
792 if (this->_indices.size() == 0)
793 return nullptr;
794
795 return this->_indices.at(0);
796 }
797
798 IT_ const * col_ind() const
799 {
800 if (this->_indices.size() == 0)
801 return nullptr;
802
803 return this->_indices.at(0);
804 }
805
811 DT_ * val()
812 {
813 if (this->_elements.size() == 0)
814 return nullptr;
815
816 return this->_elements.at(0);
817 }
818
819 DT_ const * val() const
820 {
821 if (this->_elements.size() == 0)
822 return nullptr;
823
824 return this->_elements.at(0);
825 }
826
832 IT_ * row_ptr()
833 {
834 if (this->_indices.size() == 0)
835 return nullptr;
836
837 return this->_indices.at(1);
838 }
839
840 IT_ const * row_ptr() const
841 {
842 if (this->_indices.size() == 0)
843 return nullptr;
844
845 return this->_indices.at(1);
846 }
847
854 {
855 if (this->_indices.size() == 0)
856 return nullptr;
857
858 return this->_indices.at(2);
859 }
860
861 IT_ const * row_numbers() const
862 {
863 if (this->_indices.size() == 0)
864 return nullptr;
865
866 return this->_indices.at(2);
867 }
868
874 static String name()
875 {
876 return "SparseMatrixCSCR";
877 }
878
885 void copy(const SparseMatrixCSCR & x, bool full = false)
886 {
887 this->_copy_content(x, full);
888 }
889
892
901 void axpy(
902 const SparseMatrixCSCR & x,
903 const DT_ alpha = DT_(1))
904 {
905 XASSERTM(x.rows() == this->rows(), "Matrix rows do not match!");
906 XASSERTM(x.columns() == this->columns(), "Matrix columns do not match!");
907 XASSERTM(x.used_elements() == this->used_elements(), "Matrix used_elements do not match!");
908
909 TimeStamp ts_start;
910
912 Arch::Axpy::value(this->val(), alpha, x.val(), this->used_elements());
913
914 TimeStamp ts_stop;
915 Statistics::add_time_axpy(ts_stop.elapsed(ts_start));
916 }
917
924 void scale(const SparseMatrixCSCR & x, const DT_ alpha)
925 {
926 XASSERTM(x.rows() == this->rows(), "Row count does not match!");
927 XASSERTM(x.columns() == this->columns(), "Column count does not match!");
928 XASSERTM(x.used_elements() == this->used_elements(), "Nonzero count does not match!");
929
930 TimeStamp ts_start;
931
933 Arch::Scale::value(this->val(), x.val(), alpha, this->used_elements());
934
935 TimeStamp ts_stop;
936 Statistics::add_time_axpy(ts_stop.elapsed(ts_start));
937 }
938
944 DT_ norm_frobenius() const
945 {
946 TimeStamp ts_start;
947
949 DT_ result = Arch::Norm2::value(this->val(), this->used_elements());
950
951 TimeStamp ts_stop;
952 Statistics::add_time_reduction(ts_stop.elapsed(ts_start));
953
954 return result;
955 }
956
963 DT_ max_rel_diff(const SparseMatrixCSCR& x) const
964 {
965 XASSERTM(x.used_elements() == this->used_elements(), "Nonzero count does not match!");
966 TimeStamp ts_start;
967
968 DataType max_rel_diff = Arch::MaxRelDiff::value(this->val(), x.val(), this->used_elements());
969
970 TimeStamp ts_stop;
971 Statistics::add_time_reduction(ts_stop.elapsed(ts_start));
972
973 return max_rel_diff;
974 }
975
984 bool same_layout(const SparseMatrixCSCR& x) const
985 {
986 if(this->size() == 0 && x.size() == 0 && this->get_elements().size() == 0 && this->get_indices().size() == 0 && x.get_elements().size() == 0 && x.get_indices().size() == 0)
987 return true;
988 if (this->rows() != x.rows())
989 return false;
990 if (this->columns() != x.columns())
991 return false;
992 if (this->used_elements() != x.used_elements())
993 return false;
994 if (this->used_rows() != x.used_rows())
995 return false;
996
997 IT_ * col_ind_a;
998 IT_ * col_ind_b;
999 IT_ * row_ptr_a;
1000 IT_ * row_ptr_b;
1001
1002 bool ret(true);
1003
1004 col_ind_a = const_cast<IT_*>(this->col_ind());
1005 row_ptr_a = const_cast<IT_*>(this->row_ptr());
1006 col_ind_b = const_cast<IT_*>(x.col_ind());
1007 row_ptr_b = const_cast<IT_*>(x.row_ptr());
1008 for (Index i(0) ; i < this->used_elements() ; ++i)
1009 {
1010 if (col_ind_a[i] != col_ind_b[i])
1011 {
1012 ret = false;
1013 break;
1014 }
1015 }
1016 if (ret)
1017 {
1018 for (Index i(0) ; i < this->used_rows() + 1; ++i)
1019 {
1020 if (row_ptr_a[i] != row_ptr_b[i])
1021 {
1022 ret = false;
1023 break;
1024 }
1025 }
1026 }
1027
1028 return ret;
1029 }
1030
1038 {
1039 XASSERTM(r.size() == this->rows(), "Vector size of r does not match!");
1040 XASSERTM(x.size() == this->columns(), "Vector size of x does not match!");
1041
1042 TimeStamp ts_start;
1043
1044 if (this->used_elements() == 0)
1045 {
1046 r.format();
1047 return;
1048 }
1049
1050 XASSERTM(r.template elements<Perspective::pod>() != x.template elements<Perspective::pod>(), "Vector x and r must not share the same memory!");
1051
1053 Arch::Apply::cscr(r.elements(), DT_(1), x.elements(), DT_(0), r.elements(),
1054 this->val(), this->col_ind(), this->row_ptr(), this->row_numbers(), this->used_rows(), this->rows(), this->columns(), this->used_elements(), false);
1055
1056 TimeStamp ts_stop;
1057 Statistics::add_time_blas2(ts_stop.elapsed(ts_start));
1058 }
1059
1067 {
1068 XASSERTM(r.size() == this->columns(), "Vector size of r does not match!");
1069 XASSERTM(x.size() == this->rows(), "Vector size of x does not match!");
1070
1071 TimeStamp ts_start;
1072
1073 if (this->used_elements() == 0)
1074 {
1075 r.format();
1076 return;
1077 }
1078
1079 XASSERTM(r.template elements<Perspective::pod>() != x.template elements<Perspective::pod>(), "Vector x and r must not share the same memory!");
1080
1082 Arch::Apply::cscr(r.elements(), DT_(1), x.elements(), DT_(0), r.elements(),
1083 this->val(), this->col_ind(), this->row_ptr(), this->row_numbers(), this->used_rows(), this->rows(), this->columns(), this->used_elements(), true);
1084
1085 TimeStamp ts_stop;
1086 Statistics::add_time_blas2(ts_stop.elapsed(ts_start));
1087 }
1088
1097 void apply(
1099 const DenseVector<DT_, IT_> & x,
1100 const DenseVector<DT_, IT_> & y,
1101 const DT_ alpha = DT_(1)) const
1102 {
1103 XASSERTM(r.size() == this->rows(), "Vector size of r does not match!");
1104 XASSERTM(x.size() == this->columns(), "Vector size of x does not match!");
1105 XASSERTM(y.size() == this->rows(), "Vector size of y does not match!");
1106
1107 TimeStamp ts_start;
1108
1109 if (this->used_elements() == 0 || Math::abs(alpha) < Math::eps<DT_>())
1110 {
1111 r.copy(y);
1112 //r.scale(beta);
1113 return;
1114 }
1115
1116 XASSERTM(r.template elements<Perspective::pod>() != x.template elements<Perspective::pod>(), "Vector x and r must not share the same memory!");
1117
1118 Statistics::add_flops( (this->used_elements() + this->rows()) * 2 );
1119 Arch::Apply::cscr(r.elements(), alpha, x.elements(), DT_(1.), y.elements(),
1120 this->val(), this->col_ind(), this->row_ptr(), this->row_numbers(), this->used_rows(), this->rows(), this->columns(), this->used_elements(), false);
1121
1122 TimeStamp ts_stop;
1123 Statistics::add_time_blas2(ts_stop.elapsed(ts_start));
1124 }
1125
1136 const DenseVector<DT_, IT_> & x,
1137 const DenseVector<DT_, IT_> & y,
1138 const DT_ alpha = DT_(1)) const
1139 {
1140 XASSERTM(r.size() == this->columns(), "Vector size of r does not match!");
1141 XASSERTM(x.size() == this->rows(), "Vector size of x does not match!");
1142 XASSERTM(y.size() == this->columns(), "Vector size of y does not match!");
1143
1144 TimeStamp ts_start;
1145
1146 if (this->used_elements() == 0 || Math::abs(alpha) < Math::eps<DT_>())
1147 {
1148 r.copy(y);
1149 //r.scale(beta);
1150 return;
1151 }
1152
1153 XASSERTM(r.template elements<Perspective::pod>() != x.template elements<Perspective::pod>(), "Vector x and r must not share the same memory!");
1154
1155 Statistics::add_flops( (this->used_elements() + this->rows()) * 2 );
1156 Arch::Apply::cscr(r.elements(), alpha, x.elements(), DT_(1.), y.elements(),
1157 this->val(), this->col_ind(), this->row_ptr(), this->row_numbers(), this->used_rows(), this->rows(), this->columns(), this->used_elements(), true);
1158
1159 TimeStamp ts_stop;
1160 Statistics::add_time_blas2(ts_stop.elapsed(ts_start));
1161 }
1163
1166 {
1167 return VectorTypeL(this->rows());
1168 }
1169
1171 VectorTypeR create_vector_r() const
1172 {
1173 return VectorTypeR(this->columns());
1174 }
1175
1178 {
1179 const IT_ * prow_ptr(this->row_ptr());
1180 return Index(prow_ptr[row + 1] - prow_ptr[row]);
1181 }
1182
1184
1186 void set_line(const Index row, DT_ * const pval_set, IT_ * const pcol_set,
1187 const Index col_start, const Index stride = 1) const
1188 {
1189 const IT_ * prow_ptr(this->row_ptr());
1190 const IT_ * pcol_ind(this->col_ind());
1191 const DT_ * pval(this->val());
1192
1193 Index row_idx(0);
1194 while (row_idx < this->used_rows() && row_idx < row)
1195 {
1196 ++row_idx;
1197 }
1198 XASSERTM(row_idx < this->used_rows(), "invalid row number provided!");
1199
1200 const Index start((Index(prow_ptr[row_idx])));
1201 const Index end((Index(prow_ptr[row_idx + 1] - prow_ptr[row_idx])));
1202 for (Index i(0); i < end; ++i)
1203 {
1204 pval_set[i * stride] = pval[start + i];
1205 pcol_set[i * stride] = pcol_ind[start + i] + IT_(col_start);
1206 }
1207 }
1208
1210
1217 friend std::ostream & operator<< (std::ostream & lhs, const SparseMatrixCSCR & b)
1218 {
1219
1220 lhs << "[\n";
1221 for (Index i(0) ; i < b.rows() ; ++i)
1222 {
1223 lhs << "[";
1224 for (Index j(0) ; j < b.columns() ; ++j)
1225 {
1226 lhs << " " << stringify(b(i, j));
1227 }
1228 lhs << "]\n";
1229 }
1230 lhs << "]\n";
1231
1232 return lhs;
1233 }
1234 }; //SparseMatrixCSCR
1235
1236#ifdef FEAT_EICKT
1237 extern template class SparseMatrixCSCR<float, std::uint32_t>;
1238 extern template class SparseMatrixCSCR<double, std::uint32_t>;
1239 extern template class SparseMatrixCSCR<float, std::uint64_t>;
1240 extern template class SparseMatrixCSCR<double, std::uint64_t>;
1241#endif
1242
1243 } // namespace LAFEM
1244} // 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 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.
Adjacency Graph implementation.
Definition: graph.hpp:34
Index * get_domain_ptr()
Returns the domain pointer array.
Definition: graph.hpp:359
Index * get_image_idx()
Returns the image node index array.
Definition: graph.hpp:374
Index get_num_indices() const
Returns the total number indices.
Definition: graph.hpp:390
Container base class.
Definition: container.hpp:220
const std::vector< IT_ * > & get_indices() const
Returns a list of all Index arrays.
Definition: container.hpp:1078
std::vector< DT_ * > _elements
List of pointers to all datatype dependent arrays.
Definition: container.hpp:226
const std::vector< DT_ * > & get_elements() const
Returns a list of all data arrays.
Definition: container.hpp:1068
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
void assign(const Container< DT2_, IT2_ > &other)
Assignment operation.
Definition: container.hpp:280
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
std::vector< Index > _indices_size
List of corresponding IT_ array sizes.
Definition: container.hpp:232
void format(DT_ value=DT_(0))
Reset all elements of the container to a given value or zero if missing.
Definition: container.hpp:851
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.
void copy(const VT_ &a)
Performs .
Config class for serialize parameter.
Definition: container.hpp:47
Layout scheme for sparse matrix containers.
CSCR based sparse matrix.
IT_ * col_ind()
Retrieve column indices array.
bool same_layout(const SparseMatrixCSCR &x) const
Checks if the structural layout of this matrix matches that of another matrix. This excludes comparis...
IT_ * row_numbers()
Retrieve row numbers of non zero rows.
SparseMatrixCSCR(FileMode mode, const String &filename)
Constructor.
void convert(const MT_ &a)
Conversion method.
Index columns() const
Retrieve matrix column count.
SparseMatrixCSCR(const SparseLayout< IT_, layout_id > &layout_in)
Constructor.
Index rows() const
Retrieve matrix row count.
Index get_length_of_line(const Index row) const
Returns the number of NNZ-elements of the selected row.
void clone(const SparseMatrixCSCR< DT2_, IT2_ > &other, CloneMode clone_mode=CloneMode::Weak)
Clone operation.
DT_ operator()(Index row, Index col) const
Retrieve specific matrix element.
SparseMatrixCSCR(Index rows_in, Index columns_in, Index used_elements_in, Index used_rows_in)
Constructor.
SparseMatrixCSCR(const Index rows_in, const Index columns_in, DenseVector< IT_, IT_ > &col_ind_in, DenseVector< DT_, IT_ > &val_in, DenseVector< IT_, IT_ > &row_ptr_in, DenseVector< IT_, IT_ > &row_numbers_in)
Constructor.
VectorTypeR create_vector_r() const
Returns a new compatible R-Vector.
void apply_transposed(DenseVector< DT_, IT_ > &r, const DenseVector< DT_, IT_ > &x, const DenseVector< DT_, IT_ > &y, const DT_ alpha=DT_(1)) const
Calculate .
void apply(DenseVector< DT_, IT_ > &r, const DenseVector< DT_, IT_ > &x, const DenseVector< DT_, IT_ > &y, const DT_ alpha=DT_(1)) const
Calculate .
SparseLayout< IT_, layout_id > layout() const
Retrieve convenient sparse matrix layout object.
SparseMatrixCSCR(Index rows_in, Index columns_in)
Constructor.
void axpy(const SparseMatrixCSCR &x, const DT_ alpha=DT_(1))
Calculate .
Index used_elements() const
Retrieve non zero element count.
void write_out(FileMode mode, const String &filename) const
Write out matrix to file.
DT_ * val()
Retrieve non zero element array.
DenseVector< DT_, IT_ > VectorTypeL
Compatible L-vector type.
void copy(const SparseMatrixCSCR &x, bool full=false)
Performs .
SparseMatrixCSCR & operator=(SparseMatrixCSCR &&other)
Move operator.
void apply_transposed(DenseVector< DT_, IT_ > &r, const DenseVector< DT_, IT_ > &x) const
Calculate .
static String name()
Returns a descriptive string.
friend std::ostream & operator<<(std::ostream &lhs, const SparseMatrixCSCR &b)
SparseMatrixCSCR streaming operator.
void write_out(FileMode mode, std::ostream &file) const
Write out matrix to file.
VectorTypeL create_vector_l() const
Returns a new compatible L-Vector.
Index used_rows() const
Retrieve used matrix non zero row count.
void read_from(FileMode mode, const String &filename)
Read in matrix from file.
SparseMatrixCSCR(SparseMatrixCSCR &&other)
Move Constructor.
SparseMatrixCSCR(const Adjacency::Graph &graph)
Constructor.
DenseVector< DT_, IT_ > VectorTypeR
Compatible R-vector type.
void convert(const SparseMatrixCSCR< DT2_, IT2_ > &other)
Conversion method.
IT_ * row_ptr()
Retrieve row start index array.
DT_ norm_frobenius() const
Calculates the Frobenius norm of this matrix.
SparseMatrixCSCR(FileMode mode, std::istream &file)
Constructor.
void scale(const SparseMatrixCSCR &x, const DT_ alpha)
Calculate .
void apply(DenseVector< DT_, IT_ > &r, const DenseVector< DT_, IT_ > &x) const
Calculate .
const IT_ * ImageIterator
ImageIterator typedef for Adjactor interface implementation.
SparseMatrixCSCR(std::vector< char > input)
Constructor.
std::vector< char > serialize(const LAFEM::SerialConfig &config=SerialConfig()) const
Serialization of complete container entity.
void read_from(FileMode mode, std::istream &file)
Read in matrix from stream.
static constexpr SparseLayoutId layout_id
Our used layout type.
SparseMatrixCSCR clone(CloneMode clone_mode=CloneMode::Weak) const
Clone operation.
SparseMatrixCSCR(const SparseMatrixCSR< DT_, IT_ > &csr, const VectorMirror< DT_, IT_ > &non_zero_rows)
Constructor.
DT_ ValueType
Value type, meaning the type of each 'block'.
void deserialize(std::vector< char > input)
Deserialization of complete container entity.
DT_ max_rel_diff(const SparseMatrixCSCR &x) const
Retrieve the maximum relative difference of this matrix and another one y.max_rel_diff(x) returns .
SparseMatrixCSCR(const MT_ &other)
Constructor.
CSR based sparse matrix.
IT_ * col_ind()
Retrieve column indices array.
DT_ * val()
Retrieve non zero element array.
Index rows() const
Retrieve matrix row count.
Index columns() const
Retrieve matrix column count.
IT_ * row_ptr()
Retrieve row start index array.
Handles vector prolongation, restriction and serialization.
IT_ * indices()
Get a pointer to the non zero indices array.
Index num_indices() const
Returns the number of indices in the mirror.
static void copy(DT_ *dest, const DT_ *src, const Index count)
Copy memory area from src to dest.
static void set_memory(DT_ *address, const DT_ val, const Index count=1)
set memory to specific value
static void release_memory(void *address)
release memory or decrease reference counter
static void increase_memory(void *address)
increase memory counter
static void add_flops(Index flops)
Add an amount of flops to the global flop counter.
Definition: statistics.hpp:206
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
SparseLayoutId
Definition: base.hpp:63
T_ abs(T_ x)
Returns the absolute value.
Definition: math.hpp:275
FEAT namespace.
Definition: adjactor.hpp:12
String stringify(const T_ &item)
Converts an item into a String.
Definition: string.hpp:944
std::uint64_t Index
Index data type.