FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
tuple_matrix.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#include <kernel/lafem/tuple_vector.hpp>
9
10
11namespace FEAT
12{
13 namespace LAFEM
14 {
30 template<typename First_, typename... Rest_>
32 {
33 private:
34 template<typename,typename...>
35 friend class TupleMatrixRow;
36
37 typedef TupleMatrixRow<Rest_...> RestClass;
38
39 public:
41 static constexpr int num_blocks = TupleMatrixRow<Rest_...>::num_blocks + 1;
42
44 typedef typename First_::DataType DataType;
46 typedef typename First_::IndexType IndexType;
47
48 // ensure that all sub-matrix have the same data-type
49 static_assert(std::is_same<DataType, typename RestClass::DataType>::value,
50 "sub-matrices have different data-types");
51 static_assert(std::is_same<IndexType, typename RestClass::IndexType>::value,
52 "sub-matrices have different index-types");
53
55 template <typename DT2_ = DataType, typename IT2_ = IndexType>
57 typename First_::template ContainerType<DT2_, IT2_>,
58 typename Rest_::template ContainerType<DT2_, IT2_>...>;
59
61 template <typename DataType2_, typename IndexType2_>
63
65 typedef typename First_::VectorTypeL VectorTypeL;
67 typedef TupleVector<typename First_::VectorTypeR, typename Rest_::VectorTypeR...> VectorTypeR;
68
69 protected:
71 First_ _first;
74
77 {
78 return First_::name() + "," + RestClass::sub_name_list();
79 }
80
81 public:
84 {
85 }
86
88 explicit TupleMatrixRow(First_&& the_first, RestClass&& the_rest) :
89 _first(std::forward<First_>(the_first)),
90 _rest(std::forward<RestClass>(the_rest))
91 {
92 }
93
95 explicit TupleMatrixRow(First_&& the_first, Rest_&&... the_rest) :
96 _first(std::forward<First_>(the_first)),
97 _rest(std::forward<Rest_>(the_rest)...)
98 {
99 }
100
103 _first(std::forward<First_>(other._first)),
104 _rest(std::forward<RestClass>(other._rest))
105 {
106 }
107
110 {
111 if(this != &other)
112 {
113 _first = std::forward<First_>(other._first);
114 _rest = std::forward<RestClass>(other._rest);
115 }
116 return *this;
117 }
118
123
131 {
132 return TupleMatrixRow(_first.clone(mode), _rest.clone(mode));
133 }
134
141 void clone(const TupleMatrixRow& other, CloneMode clone_mode)
142 {
143 _first.clone(other._first, clone_mode);
144 _rest.clone(other._rest, clone_mode);
145 }
146
152 void clone(const TupleMatrixRow& other)
153 {
154 _first.clone(other._first);
155 _rest.clone(other._rest);
156 }
157
159 First_& first()
160 {
161 return _first;
162 }
163
164 const First_& first() const
165 {
166 return _first;
167 }
168
169 TupleMatrixRow<Rest_...>& rest()
170 {
171 return _rest;
172 }
173
174 const TupleMatrixRow<Rest_...>& rest() const
175 {
176 return _rest;
177 }
179
189 template<int i_>
190 typename TupleElement<i_, First_, Rest_...>::Type& at()
191 {
192 static_assert((0 <= i_) && (i_ < num_blocks), "invalid sub-matrix index");
194 }
195
197 template<int i_>
198 typename TupleElement<i_, First_, Rest_...>::Type const& at() const
199 {
200 static_assert((0 <= i_) && (i_ < num_blocks), "invalid sub-matrix index");
202 }
203
210 template <Perspective perspective_ = Perspective::native>
211 Index rows() const
212 {
213 const Index rows_f = _first.template rows<perspective_>();
214 const Index rows_r = _rest.template rows<perspective_>();
215 XASSERTM(rows_f == rows_r, "row count mismatch");
216 return rows_f;
217 }
218
225 template <Perspective perspective_ = Perspective::native>
227 {
228 return _first.template columns<perspective_>() + _rest.template columns<perspective_>();
229 }
230
237 template <Perspective perspective_ = Perspective::native>
239 {
240 return _first.template used_elements<perspective_>() + _rest.template used_elements<perspective_>();
241 }
242
248 std::size_t bytes() const
249 {
250 return _first.bytes() + _rest.bytes();
251 }
252
254 static String name()
255 {
256 return String("TupleMatrixRow<") + sub_name_list() + ">";
257 }
258
266 {
267 first().format(value);
268 rest().format(value);
269 }
270
278 void format(Random & rng, DataType min, DataType max)
279 {
280 first().format(rng, min, max);
281 rest().format(rng, min, max);
282 }
283
285 void clear()
286 {
287 first().clear();
288 rest().clear();
289 }
290
293 {
294 return first().create_vector_l();
295 }
296
299 {
300 return VectorTypeR(first().create_vector_r(), rest().create_vector_r());
301 }
302
303 void apply(VectorTypeL& r, const VectorTypeR& x) const
304 {
305 first().apply(r, x.first());
306 rest().apply(r, x.rest(), r, DataType(1));
307 }
308
309 void apply_transposed(VectorTypeR& r, const VectorTypeL& x) const
310 {
311 first().apply_transposed(r.first(), x);
312 rest().apply_transposed(r.rest(), x);
313 }
314
315 void apply(VectorTypeL& r, const VectorTypeR& x, const VectorTypeL& y, DataType alpha = DataType(1)) const
316 {
317 first().apply(r, x.first(), y, alpha);
318 rest().apply(r, x.rest(), r, alpha);
319 }
320
321 void apply_transposed(VectorTypeR& r, const VectorTypeL& x, const VectorTypeR& y, DataType alpha = DataType(1)) const
322 {
323 first().apply_transposed(r.first(), x, y.first(), alpha);
324 rest().apply_transposed(r.rest(), x, y.rest(), alpha);
325 }
326
327 Index get_length_of_line(const Index row) const
328 {
329 return first().get_length_of_line(row) + rest().get_length_of_line(row);
330 }
331
332 void set_line(const Index row, DataType * const pval_set, IndexType * const pcol_set, const Index col_start, const Index stride = 1) const
333 {
334 const Index first_length(first().get_length_of_line(row));
335
336 first().set_line(row, pval_set, pcol_set, col_start, stride);
337 rest().set_line(row, pval_set + stride * first_length, pcol_set + stride * first_length, col_start + first().template columns<Perspective::pod>(), stride);
338 }
339
340 void set_line_reverse(const Index row, DataType * const pval_set, const Index stride = 1)
341 {
342 const Index first_length(first().get_length_of_line(row));
343
344 first().set_line_reverse(row, pval_set, stride);
345 rest().set_line_reverse(row, pval_set + stride * first_length, stride);
346 }
347
348 Index row_degree(const Index row) const
349 {
350 return first().row_degree(row) + rest().row_degree(row);
351 }
352
353 template<typename IT2_>
354 Index get_row_col_indices(const Index row, IT2_* const pcol_idx, const IT2_ col_offset) const
355 {
356 const Index first_cols = first().template columns<Perspective::pod>();
357 const Index first_degree = first().get_row_col_indices(row, pcol_idx, col_offset);
358 return first_degree + rest().get_row_col_indices(row, pcol_idx + first_degree, col_offset + IT2_(first_cols));
359 }
360
361 template<typename DT2_>
362 Index get_row_values(const Index row, DT2_ * const pvals) const
363 {
364 const Index first_degree = first().get_row_values(row, pvals);
365 return first_degree + rest().get_row_values(row, pvals + first_degree);
366 }
367
368 template<typename DT2_>
369 Index set_row_values(const Index row, const DT2_ * const pvals)
370 {
371 const Index first_degree = first().set_row_values(row, pvals);
372 return first_degree + rest().set_row_values(row, pvals + first_degree);
373 }
374
376 std::uint64_t get_checkpoint_size(SerialConfig& config)
377 {
378 return sizeof(std::uint64_t) + _first.get_checkpoint_size(config) + _rest.get_checkpoint_size(config); //sizeof(std::uint64_t) bits needed to store lenght of checkpointed _first
379 }
380
382 void restore_from_checkpoint_data(std::vector<char> & data)
383 {
384 std::uint64_t isize = *(std::uint64_t*) data.data(); //get size of checkpointed _first
385 std::vector<char>::iterator start = std::begin(data) + sizeof(std::uint64_t);
386 std::vector<char>::iterator last_of_first = std::begin(data) + sizeof(std::uint64_t) + (int) isize;
387 std::vector<char> buffer_first(start, last_of_first);
388 _first.restore_from_checkpoint_data(buffer_first);
389
390 data.erase(std::begin(data), last_of_first);
392 }
393
395 std::uint64_t set_checkpoint_data(std::vector<char>& data, SerialConfig& config)
396 {
397 std::size_t old_size = data.size();
398 data.insert(std::end(data), sizeof(std::uint64_t), 0); //add placeholder
399 std::uint64_t ireal_size = _first.set_checkpoint_data(data, config); //add data of _first to the overall checkpoint and save its size
400 char* csize = reinterpret_cast<char*>(&ireal_size);
401 for(std::size_t i(0) ; i < sizeof(std::uint64_t) ; ++i) //overwrite the guessed datalength
402 {
403 data[old_size + i] = csize[i];
404 }
405
406 return sizeof(std::uint64_t) + ireal_size + _rest.set_checkpoint_data(data, config); //generate and add checkpoint data for the _rest
407 }
408
409 template<typename OtherFirst_, typename... OtherRest_>
410 void convert(const TupleMatrixRow<OtherFirst_, OtherRest_...>& other)
411 {
412 first().convert(other.first());
413 rest().convert(other.rest());
414 }
415
416 template<typename OtherFirst_, typename... OtherRest_>
417 void convert_reverse(TupleMatrixRow<OtherFirst_, OtherRest_...>& other) const
418 {
419 first().convert_reverse(other.first());
420 rest().convert_reverse(other.rest());
421 }
422 }; // template class TupleMatrixRow
423
425 // specialization for a single sub-matrix
426 template<typename First_>
427 class TupleMatrixRow<First_>
428 {
429 private:
430 template<typename,typename...>
431 friend class TupleMatrixRow;
432
433 public:
435 static constexpr int num_blocks = 1;
436
438 typedef typename First_::DataType DataType;
440 typedef typename First_::IndexType IndexType;
441
442 template <typename DT2_ = DataType, typename IT2_ = IndexType>
443 using ContainerType = TupleMatrixRow<typename First_::template ContainerType<DT2_, IT2_> >;
444
446 template <typename DataType2_, typename IndexType2_>
447 using ContainerTypeByDI = ContainerType<DataType2_, IndexType2_>;
448
450 typedef typename First_::VectorTypeL VectorTypeL;
452 typedef TupleVector<typename First_::VectorTypeR> VectorTypeR;
453
454 protected:
456 First_ _first;
457
459 static String sub_name_list()
460 {
461 return First_::name();
462 }
463
464 public:
466 TupleMatrixRow()
467 {
468 }
469
471 explicit TupleMatrixRow(First_&& the_first) :
472 _first(std::forward<First_>(the_first))
473 {
474 }
475
477 TupleMatrixRow(TupleMatrixRow&& other) :
478 _first(std::forward<First_>(other._first))
479 {
480 }
481
483 TupleMatrixRow& operator=(TupleMatrixRow&& other)
484 {
485 if(this != &other)
486 {
487 _first = std::forward<First_>(other._first);
488 }
489 return *this;
490 }
491
493 TupleMatrixRow(const TupleMatrixRow&) = delete;
495 TupleMatrixRow& operator=(const TupleMatrixRow&) = delete;
496
497 TupleMatrixRow clone(LAFEM::CloneMode mode = LAFEM::CloneMode::Weak) const
498 {
499 return TupleMatrixRow(_first.clone(mode));
500 }
501
502 void clone(const TupleMatrixRow& other, CloneMode clone_mode)
503 {
504 _first.clone(other._first, clone_mode);
505 }
506
507 void clone(const TupleMatrixRow& other)
508 {
509 _first.clone(other._first);
510 }
511
513 First_& first()
514 {
515 return _first;
516 }
517
518 const First_& first() const
519 {
520 return _first;
521 }
523
524 template<int i_>
525 First_& at()
526 {
527 static_assert(i_ == 0, "invalid sub-matrix index");
528 return first();
529 }
530
532 template<int i_>
533 const First_& at() const
534 {
535 static_assert(i_ == 0, "invalid sub-matrix index");
536 return first();
537 }
538
539 template <Perspective perspective_ = Perspective::native>
540 Index rows() const
541 {
542 return _first.template rows<perspective_>();
543 }
544
545 template <Perspective perspective_ = Perspective::native>
546 Index columns() const
547 {
548 return _first.template columns<perspective_>();
549 }
550
551 template <Perspective perspective_ = Perspective::native>
552 Index used_elements() const
553 {
554 return _first.template used_elements<perspective_>();
555 }
556
557 std::size_t bytes() const
558 {
559 return _first.bytes();
560 }
561
562 static String name()
563 {
564 return String("TupleMatrixRow<") + sub_name_list() + ">";
565 }
566
567 void format(DataType value = DataType(0))
568 {
569 first().format(value);
570 }
571
572 void format(Random & rng, DataType min, DataType max)
573 {
574 first().format(rng, min, max);
575 }
576
577 void clear()
578 {
579 first().clear();
580 }
581
583 {
584 return first().create_vector_l();
585 }
586
588 {
589 return VectorTypeR(first().create_vector_r());
590 }
591
592 void apply(VectorTypeL& r, const VectorTypeR& x) const
593 {
594 first().apply(r, x.first());
595 }
596
597 void apply(VectorTypeL& r, const VectorTypeR& x, const VectorTypeL& y, DataType alpha = DataType(1)) const
598 {
599 first().apply(r, x.first(), y, alpha);
600 }
601
602 void apply_transposed(VectorTypeR& r, const VectorTypeL& x) const
603 {
604 first().apply_transposed(r.first(), x);
605 }
606
607 void apply_transposed(VectorTypeR& r, const VectorTypeL& x, const VectorTypeR& y, DataType alpha = DataType(1)) const
608 {
609 first().apply_transposed(r.first(), x, y.first(), alpha);
610 }
611
612 Index get_length_of_line(const Index row) const
613 {
614 return first().get_length_of_line(row);
615 }
616
617 void set_line(const Index row, DataType * const pval_set, IndexType * const pcol_set, const Index col_start, const Index stride = 1) const
618 {
619 first().set_line(row, pval_set, pcol_set, col_start, stride);
620 }
621
622 void set_line_reverse(const Index row, DataType * const pval_set, const Index stride = 1)
623 {
624 first().set_line_reverse(row, pval_set, stride);
625 }
626
627 Index row_degree(const Index row) const
628 {
629 return first().row_degree(row);
630 }
631
632 template<typename IT2_>
633 Index get_row_col_indices(const Index row, IT2_* const pcol_idx, const IT2_ col_offset) const
634 {
635 return first().get_row_col_indices(row, pcol_idx, col_offset);
636 }
637
638 template<typename DT2_>
639 Index get_row_values(const Index row, DT2_ * const pvals) const
640 {
641 return first().get_row_values(row, pvals);
642 }
643
644 template<typename DT2_>
645 Index set_row_values(const Index row, const DT2_ * const pvals)
646 {
647 return first().set_row_values(row, pvals);
648 }
649
651 std::uint64_t get_checkpoint_size(SerialConfig& config)
652 {
653 return _first.get_checkpoint_size(config);
654 }
655
657 void restore_from_checkpoint_data(std::vector<char> & data)
658 {
659 _first.restore_from_checkpoint_data(data);
660 }
661
663 std::uint64_t set_checkpoint_data(std::vector<char>& data, SerialConfig& config)
664 {
665 return _first.set_checkpoint_data(data, config);
666 }
667
668 template<typename OtherFirst_>
669 void convert(const TupleMatrixRow<OtherFirst_>& other)
670 {
671 first().convert(other.first());
672 }
673
674 template<typename OtherFirst_>
675 void convert_reverse(TupleMatrixRow<OtherFirst_>& other) const
676 {
677 first().convert_reverse(other.first());
678 }
679 }; // template class TupleMatrixRow
681
683 namespace Intern
684 {
685 // helper class: checks whether 'T_' is an instance of 'TupleMatrixRow<...>'
686 template<typename T_>
687 struct IsTMR_
688 {
689 static constexpr bool value = false;
690 };
691
692 template<typename... T_>
693 struct IsTMR_<TupleMatrixRow<T_...>>
694 {
695 static constexpr bool value = true;
696 };
697 } // namespace Intern
699
708 template<int i_, int j_, typename FirstRow_, typename... RestRows_>
710 {
711 public:
712 static_assert(i_ > 0, "invalid row index"); // i_=0 is specialized below
713 static_assert(j_ >= 0, "invalid column index");
714
715 typedef typename TupleMatrixElement<i_-1, j_, RestRows_...>::Type Type;
716
717 template<typename Meta_>
718 static Type& get(Meta_& meta)
719 {
721 }
722
723 template<typename Meta_>
724 static const Type& get(const Meta_& meta)
725 {
727 }
728 };
729
731 // specialization for i_ = 0;
732 // Note: This specialization explicitly assumes that 'FirstRow_' is an instance of
733 // 'TupleMatrixRow', which is ensured by a static_assert in the TupleMatrix class.
734 template<int j_, typename First_, typename... Rest_, typename... RestRows_>
735 class TupleMatrixElement<0, j_, TupleMatrixRow<First_, Rest_...>, RestRows_... >
736 {
737 public:
738 static_assert(j_ >= 0, "invalid column index");
739
740 typedef typename TupleElement<j_, First_, Rest_...>::Type Type;
741
742 template<typename Meta_>
743 static Type& get(Meta_& meta)
744 {
745 return TupleElement<j_, First_, Rest_...>::get(meta.first());
746 }
747
748 template<typename Meta_>
749 static const Type& get(const Meta_& meta)
750 {
751 return TupleElement<j_, First_, Rest_...>::get(meta.first());
752 }
753 };
755
768 template<typename FirstRow_, typename... RestRows_>
770 {
771 private:
772 template<typename,typename...>
773 friend class TupleMatrix;
774
775 typedef TupleMatrix<RestRows_...> RestClass;
776
777 // sanity check: ensure that 'FirstRow_' is an instance of TupleMatrixRow
778 // note: this is essential for the implementation of TupleMatrixElement!
779 static_assert(Intern::IsTMR_<FirstRow_>::value,
780 "template parameter of TupleMatrix must be TupleMatrixRow<...>");
781
782 public:
784 static constexpr int num_row_blocks = TupleMatrix<RestRows_...>::num_row_blocks + 1;
786 static constexpr int num_col_blocks = FirstRow_::num_blocks;
787
788 // sanity check: number of column blocks must match for all rows
789 static_assert(num_col_blocks == RestClass::num_col_blocks, "column blocks mismatch");
790
792 typedef typename FirstRow_::DataType DataType;
794 typedef typename FirstRow_::IndexType IndexType;
795
796 // ensure that all sub-matrix have the same data-type
797 static_assert(std::is_same<DataType, typename RestClass::DataType>::value,
798 "sub-matrices have different data-types");
799 static_assert(std::is_same<IndexType, typename RestClass::IndexType>::value,
800 "sub-matrices have different index-types");
801
803 template <typename DT2_ = DataType, typename IT2_ = IndexType>
805 typename FirstRow_::template ContainerType<DT2_, IT2_>,
806 typename RestRows_::template ContainerType<DT2_, IT2_>...>;
807
809 template <typename DataType2_, typename IndexType2_>
811
813 typedef TupleVector<typename FirstRow_::VectorTypeL, typename RestRows_::VectorTypeL...> VectorTypeL;
815 typedef typename FirstRow_::VectorTypeR VectorTypeR;
816
818 static_assert(std::is_same<VectorTypeR, typename RestClass::VectorTypeR>::value, "vector type mismatch");
819
820 protected:
822 FirstRow_ _first;
825
828 {
829 return FirstRow_::name() + "," + RestClass::sub_name_list();
830 }
831
832 public:
835 {
836 }
837
839 explicit TupleMatrix(FirstRow_&& the_first, RestClass&& the_rest) :
840 _first(std::forward<FirstRow_>(the_first)),
841 _rest(std::forward<RestClass>(the_rest))
842 {
843 }
844
846 explicit TupleMatrix(FirstRow_&& the_first, RestRows_&&... the_rest) :
847 _first(std::forward<FirstRow_>(the_first)),
848 _rest(std::forward<RestRows_>(the_rest)...)
849 {
850 }
851
854 _first(std::forward<FirstRow_>(other._first)),
855 _rest(std::forward<RestClass>(other._rest))
856 {
857 }
858
861 {
862 if(this != &other)
863 {
864 _first = std::forward<FirstRow_>(other._first);
865 _rest = std::forward<RestClass>(other._rest);
866 }
867 return *this;
868 }
869
871 TupleMatrix(const TupleMatrix&) = delete;
874
882 {
883 return TupleMatrix(_first.clone(mode), _rest.clone(mode));
884 }
885
892 void clone(const TupleMatrix& other, CloneMode clone_mode)
893 {
894 _first.clone(other._first, clone_mode);
895 _rest.clone(other._rest, clone_mode);
896 }
897
903 void clone(const TupleMatrix& other)
904 {
905 _first.clone(other._first);
906 _rest.clone(other._rest);
907 }
908
910 FirstRow_& first()
911 {
912 return _first;
913 }
914
915 const FirstRow_& first() const
916 {
917 return _first;
918 }
919
920 TupleMatrix<RestRows_...>& rest()
921 {
922 return _rest;
923 }
924
925 const TupleMatrix<RestRows_...>& rest() const
926 {
927 return _rest;
928 }
930
940 template<int i_, int j_>
941 typename TupleMatrixElement<i_, j_, FirstRow_, RestRows_...>::Type& at()
942 {
943 static_assert((0 <= i_) && (i_ < num_row_blocks), "invalid sub-matrix row index");
944 static_assert((0 <= j_) && (j_ < num_col_blocks), "invalid sub-matrix column index");
946 }
947
949 template<int i_, int j_>
950 const typename TupleMatrixElement<i_, j_, FirstRow_, RestRows_...>::Type& at() const
951 {
952 static_assert((0 <= i_) && (i_ < num_row_blocks), "invalid sub-matrix row index");
953 static_assert((0 <= j_) && (j_ < num_col_blocks), "invalid sub-matrix column index");
955 }
956
963 template <Perspective perspective_ = Perspective::native>
964 Index rows() const
965 {
966 return _first.template rows<perspective_>() + _rest.template rows<perspective_>();
967 }
968
975 template <Perspective perspective_ = Perspective::native>
977 {
978 const Index cols_f = _first.template columns<perspective_>();
979 const Index cols_r = _rest.template columns<perspective_>();
980 XASSERTM(cols_f == cols_r, "column count mismatch");
981 return cols_f;
982 }
983
990 template <Perspective perspective_ = Perspective::native>
992 {
993 return _first.template used_elements<perspective_>() + _rest.template used_elements<perspective_>();
994 }
995
1001 std::size_t bytes() const
1002 {
1003 return _first.bytes() + _rest.bytes();
1004 }
1005
1007 static String name()
1008 {
1009 return String("TupleMatrix<") + sub_name_list() + ">";
1010 }
1011
1019 {
1020 first().format(value);
1021 rest().format(value);
1022 }
1023
1031 void format(Random & rng, DataType min, DataType max)
1032 {
1033 first().format(rng, min, max);
1034 rest().format(rng, min, max);
1035 }
1036
1038 void clear()
1039 {
1040 first().clear();
1041 rest().clear();
1042 }
1043
1046 {
1047 return VectorTypeL(first().create_vector_l(), rest().create_vector_l());
1048 }
1049
1052 {
1053 return first().create_vector_r();
1054 }
1055
1062 void apply(VectorTypeL& r, const VectorTypeR& x) const
1063 {
1064 first().apply(r.first(), x);
1065 rest().apply(r.rest(), x);
1066 }
1067
1075 {
1076 first().apply_transposed(r, x.first());
1077 rest().apply_transposed(r, x.rest(), r, DataType(1));
1078 }
1079
1088 void apply(VectorTypeL& r, const VectorTypeR& x, const VectorTypeL& y, DataType alpha = DataType(1)) const
1089 {
1090 first().apply(r.first(), x, y.first(), alpha);
1091 rest().apply(r.rest(), x, y.rest(), alpha);
1092 }
1093
1102 void apply_transposed(VectorTypeR& r, const VectorTypeL& x, const VectorTypeR& y, DataType alpha = DataType(1)) const
1103 {
1104 first().apply_transposed(r, x.first(), y, alpha);
1105 rest().apply_transposed(r, x.rest(), r, alpha);
1106 }
1107
1108 Index get_length_of_line(const Index row) const
1109 {
1110 const Index first_rows = first().template rows<Perspective::pod>();
1111 if(row < first_rows)
1112 return first().get_length_of_line(row);
1113 else
1114 return rest().get_length_of_line(row - first_rows);
1115 }
1116
1117 void set_line(const Index row, DataType * const pval_set, IndexType * const pcol_set, const Index col_start, const Index stride = 1) const
1118 {
1119 const Index first_rows = first().template rows<Perspective::pod>();
1120 if(row < first_rows)
1121 first().set_line(row, pval_set, pcol_set, col_start, stride);
1122 else
1123 rest().set_line(row - first_rows, pval_set, pcol_set, col_start, stride);
1124 }
1125
1126 void set_line_reverse(const Index row, DataType * const pval_set, const Index stride = 1)
1127 {
1128 const Index first_rows = first().template rows<Perspective::pod>();
1129 if(row < first_rows)
1130 first().set_line_reverse(row, pval_set, stride);
1131 else
1132 rest().set_line_reverse(row - first_rows, pval_set, stride);
1133 }
1134
1135 Index row_degree(const Index row) const
1136 {
1137 const Index first_rows = first().template rows<Perspective::pod>();
1138 if(row < first_rows)
1139 return first().row_degree(row);
1140 else
1141 return rest().row_degree(row - first_rows);
1142 }
1143
1144 template<typename IT2_>
1145 Index get_row_col_indices(const Index row, IT2_* const pcol_idx, const IT2_ col_offset) const
1146 {
1147 const Index first_rows = first().template rows<Perspective::pod>();
1148 if(row < first_rows)
1149 return first().get_row_col_indices(row, pcol_idx, col_offset);
1150 else
1151 return rest().get_row_col_indices(row - first_rows, pcol_idx, col_offset);
1152 }
1153
1154 template<typename DT2_>
1155 Index get_row_values(const Index row, DT2_ * const pvals) const
1156 {
1157 const Index first_rows = first().template rows<Perspective::pod>();
1158 if(row < first_rows)
1159 return first().get_row_values(row, pvals);
1160 else
1161 return rest().get_row_values(row - first_rows, pvals);
1162 }
1163
1164 template<typename DT2_>
1165 Index set_row_values(const Index row, const DT2_ * const pvals)
1166 {
1167 const Index first_rows = first().template rows<Perspective::pod>();
1168 if(row < first_rows)
1169 return first().set_row_values(row, pvals);
1170 else
1171 return rest().set_row_values(row - first_rows, pvals);
1172 }
1173
1175 std::uint64_t get_checkpoint_size(SerialConfig& config)
1176 {
1177 return sizeof(std::uint64_t) + _first.get_checkpoint_size(config) + _rest.get_checkpoint_size(config); //sizeof(std::uint64_t) bits needed to store lenght of checkpointed _first
1178 }
1179
1181 void restore_from_checkpoint_data(std::vector<char> & data)
1182 {
1183 std::uint64_t isize = *(std::uint64_t*) data.data(); //get size of checkpointed _first
1184 std::vector<char>::iterator start = std::begin(data) + sizeof(std::uint64_t);
1185 std::vector<char>::iterator last_of_first = std::begin(data) + sizeof(std::uint64_t) + (int) isize;
1186 std::vector<char> buffer_first(start, last_of_first);
1187 _first.restore_from_checkpoint_data(buffer_first);
1188
1189 data.erase(std::begin(data), last_of_first);
1191 }
1192
1194 std::uint64_t set_checkpoint_data(std::vector<char>& data, SerialConfig& config)
1195 {
1196 std::size_t old_size = data.size();
1197 data.insert(std::end(data), sizeof(std::uint64_t), 0); //add placeholder
1198 std::uint64_t ireal_size = _first.set_checkpoint_data(data, config); //add data of _first to the overall checkpoint and save its size
1199 char* csize = reinterpret_cast<char*>(&ireal_size);
1200 for(std::size_t i(0) ; i < sizeof(std::uint64_t) ; ++i) //overwrite the guessed datalength
1201 {
1202 data[old_size +i] = csize[i];
1203 }
1204 return sizeof(std::uint64_t) + ireal_size + _rest.set_checkpoint_data(data, config); //generate and add checkpoint data for the _rest
1205 }
1206
1207 template<typename OtherFirstRow_, typename... OtherRestRows_>
1208 void convert(const TupleMatrix<OtherFirstRow_, OtherRestRows_...>& other)
1209 {
1210 first().convert(other.first());
1211 rest().convert(other.rest());
1212 }
1213
1214 template<typename OtherFirstRow_, typename... OtherRestRows_>
1215 void convert_reverse(TupleMatrix<OtherFirstRow_, OtherRestRows_...>& other) const
1216 {
1217 first().convert_reverse(other.first());
1218 rest().convert_reverse(other.rest());
1219 }
1220 }; // template class TupleMatrix
1221
1223 // specialization for 1 row
1224 template<typename FirstRow_>
1225 class TupleMatrix<FirstRow_>
1226 {
1227 private:
1228 template<typename,typename...>
1229 friend class TupleMatrix;
1230
1231 // sanity check: ensure that 'FirstRow_' is an instance of TupleMatrixRow
1232 static_assert(Intern::IsTMR_<FirstRow_>::value,
1233 "template parameter of TupleMatrix must be TupleMatrixRow<...>");
1234
1235 public:
1237 static constexpr int num_blocks = 1;
1238
1240 static constexpr int num_row_blocks = num_blocks;
1242 static constexpr int num_col_blocks = FirstRow_::num_blocks;
1243
1244
1246 typedef typename FirstRow_::DataType DataType;
1248 typedef typename FirstRow_::IndexType IndexType;
1249
1250 template < typename DT2_ = DataType, typename IT2_ = IndexType>
1251 using ContainerType = TupleMatrix<typename FirstRow_::template ContainerType<DT2_, IT2_> >;
1252
1253 template <typename DataType2_, typename IndexType2_>
1254 using ContainerTypeByDI = ContainerType<DataType2_, IndexType2_>;
1255
1257 typedef TupleVector<typename FirstRow_::VectorTypeL> VectorTypeL;
1259 typedef typename FirstRow_::VectorTypeR VectorTypeR;
1260
1261 protected:
1263 FirstRow_ _first;
1264
1266 static String sub_name_list()
1267 {
1268 return FirstRow_::name();
1269 }
1270
1271 public:
1273 TupleMatrix()
1274 {
1275 }
1276
1278 explicit TupleMatrix(FirstRow_&& the_first) :
1279 _first(std::forward<FirstRow_>(the_first))
1280 {
1281 }
1282
1284 TupleMatrix(TupleMatrix&& other) :
1285 _first(std::forward<FirstRow_>(other._first))
1286 {
1287 }
1288
1290 TupleMatrix& operator=(TupleMatrix&& other)
1291 {
1292 if(this != &other)
1293 {
1294 _first = std::forward<FirstRow_>(other._first);
1295 }
1296 return *this;
1297 }
1298
1300 TupleMatrix(const TupleMatrix&) = delete;
1302 TupleMatrix& operator=(const TupleMatrix&) = delete;
1303
1304 TupleMatrix clone(LAFEM::CloneMode mode = LAFEM::CloneMode::Weak) const
1305 {
1306 return TupleMatrix(_first.clone(mode));
1307 }
1308
1309 void clone(const TupleMatrix& other, CloneMode clone_mode)
1310 {
1311 _first.clone(other._first, clone_mode);
1312 }
1313
1314 void clone(const TupleMatrix& other)
1315 {
1316 _first.clone(other._first);
1317 }
1318
1319 FirstRow_& first()
1320 {
1321 return _first;
1322 }
1323
1324 const FirstRow_& first() const
1325 {
1326 return _first;
1327 }
1328
1329 template<int i_, int j_>
1330 typename TupleMatrixElement<i_, j_, FirstRow_>::Type& at()
1331 {
1332 static_assert(0 == i_, "invalid sub-matrix row index");
1333 static_assert((0 <= j_) && (j_ < num_col_blocks), "invalid sub-matrix column index");
1334 return TupleMatrixElement<i_, j_, FirstRow_>::get(*this);
1335 }
1336
1337 template<int i_, int j_>
1338 const typename TupleMatrixElement<i_, j_, FirstRow_>::Type& at() const
1339 {
1340 static_assert(0 == i_, "invalid sub-matrix row index");
1341 static_assert((0 <= j_) && (j_ < num_col_blocks), "invalid sub-matrix column index");
1342 return TupleMatrixElement<i_, j_, FirstRow_>::get(*this);
1343 }
1344
1345 template <Perspective perspective_ = Perspective::native>
1346 Index rows() const
1347 {
1348 return _first.template rows<perspective_>();
1349 }
1350
1351 template <Perspective perspective_ = Perspective::native>
1352 Index columns() const
1353 {
1354 return _first.template columns<perspective_>();
1355 }
1356
1357 template <Perspective perspective_ = Perspective::native>
1358 Index used_elements() const
1359 {
1360 return _first.template used_elements<perspective_>();
1361 }
1362
1363 std::size_t bytes() const
1364 {
1365 return _first.bytes();
1366 }
1367
1368 static String name()
1369 {
1370 return String("TupleMatrix<") + sub_name_list() + ">";
1371 }
1372
1373 void format(DataType value = DataType(0))
1374 {
1375 first().format(value);
1376 }
1377
1378 void format(Random & rng, DataType min, DataType max)
1379 {
1380 first().format(rng, min, max);
1381 }
1382
1383 void clear()
1384 {
1385 first().clear();
1386 }
1387
1390 {
1391 return VectorTypeL(first().create_vector_l());
1392 }
1393
1396 {
1397 return first().create_vector_r();
1398 }
1399
1400 void apply(VectorTypeL& r, const VectorTypeR& x) const
1401 {
1402 first().apply(r.first(), x);
1403 }
1404
1405 void apply(VectorTypeL& r, const VectorTypeR& x, const VectorTypeL& y, DataType alpha = DataType(1)) const
1406 {
1407 first().apply(r.first(), x, y.first(), alpha);
1408 }
1409
1410 void apply_transposed(VectorTypeR& r, const VectorTypeL& x) const
1411 {
1412 first().apply_transposed(r, x.first());
1413 }
1414
1415 void apply_transposed(VectorTypeR& r, const VectorTypeL& x, const VectorTypeR& y, DataType alpha = DataType(1)) const
1416 {
1417 first().apply(r, x.first(), y, alpha);
1418 }
1419
1420 Index get_length_of_line(const Index row) const
1421 {
1422 return first().get_length_of_line(row);
1423 }
1424
1425 void set_line(const Index row, DataType * const pval_set, IndexType * const pcol_set, const Index col_start, const Index stride = 1) const
1426 {
1427 first().set_line(row, pval_set, pcol_set, col_start, stride);
1428 }
1429
1430 void set_line_reverse(const Index row, DataType * const pval_set, const Index stride = 1)
1431 {
1432 first().set_line_reverse(row, pval_set, stride);
1433 }
1434
1435 Index row_degree(const Index row) const
1436 {
1437 return first().row_degree(row);
1438 }
1439
1440 template<typename IT2_>
1441 Index get_row_col_indices(const Index row, IT2_* const pcol_idx, const IT2_ col_offset) const
1442 {
1443 return first().get_row_col_indices(row, pcol_idx, col_offset);
1444 }
1445
1446 template<typename DT2_>
1447 Index get_row_values(const Index row, DT2_ * const pvals) const
1448 {
1449 return first().get_row_values(row, pvals);
1450 }
1451
1452 template<typename DT2_>
1453 Index set_row_values(const Index row, const DT2_ * const pvals)
1454 {
1455 return first().set_row_values(row, pvals);
1456 }
1457
1459 std::uint64_t get_checkpoint_size(SerialConfig& config)
1460 {
1461 return _first.get_checkpoint_size(config);
1462 }
1463
1465 void restore_from_checkpoint_data(std::vector<char> & data)
1466 {
1467 _first.restore_from_checkpoint_data(data);
1468 }
1469
1471 std::uint64_t set_checkpoint_data(std::vector<char>& data, SerialConfig& config)
1472 {
1473 return _first.set_checkpoint_data(data, config);
1474 }
1475
1476 template<typename OtherFirstRow_>
1477 void convert(const TupleMatrix<OtherFirstRow_>& other)
1478 {
1479 first().convert(other.first());
1480 }
1481
1482 template<typename OtherFirstRow_>
1483 void convert_reverse(TupleMatrix<OtherFirstRow_>& other) const
1484 {
1485 first().convert_reverse(other.first());
1486 }
1487 }; // template class TupleMatrix
1489 } // namespace LAFEM
1490} // namespace FEAT
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Definition: assertion.hpp:263
Config class for serialize parameter.
Definition: container.hpp:47
TupleMatrix element helper class template.
Variadic TupleMatrix class template.
TupleMatrix & operator=(TupleMatrix &&other)
move-assign operator
static constexpr int num_col_blocks
number of column blocks (horizontal size)
FirstRow_::IndexType IndexType
sub-matrix index-type
TupleMatrixElement< i_, j_, FirstRow_, RestRows_... >::Type & at()
Returns a sub-matrix block.
void format(Random &rng, DataType min, DataType max)
Reset all elements of the container to random values.
VectorTypeL create_vector_l() const
Returns a new compatible L-Vector.
VectorTypeR create_vector_r() const
Returns a new compatible R-Vector.
TupleMatrix clone(LAFEM::CloneMode mode=LAFEM::CloneMode::Weak) const
Creates and returns a copy of this matrix.
void clone(const TupleMatrix &other)
Turns this matrix into a clone of other.
static constexpr int num_row_blocks
number of row blocks (vertical size)
std::size_t bytes() const
Returns the total amount of bytes allocated.
void clear()
Free all allocated arrays.
std::uint64_t get_checkpoint_size(SerialConfig &config)
Calculate size.
FirstRow_ _first
sanity check: vector types must match for all rows
TupleMatrix(FirstRow_ &&the_first, RestRows_ &&... the_rest)
Sub-Matrix emplacement constructor.
void format(DataType value=DataType(0))
Reset all elements of the container to a given value or zero if missing.
Index columns() const
Returns the total number of columns in this matrix.
void apply(VectorTypeL &r, const VectorTypeR &x) const
Calculate .
ContainerType< DataType2_, IndexType2_ > ContainerTypeByDI
this typedef lets you create a vector container with new Datatype and Index types
Index rows() const
Returns the total number of rows in this matrix.
void restore_from_checkpoint_data(std::vector< char > &data)
Extract object from checkpoint.
FirstRow_::DataType DataType
sub-matrix data-type
RestClass _rest
all remaining sub-matrix rows
TupleMatrix & operator=(const TupleMatrix &)=delete
deleted copy-assign operator
Index used_elements() const
Returns the total number of non-zeros in this matrix.
void apply_transposed(VectorTypeR &r, const VectorTypeL &x) const
Calculate .
static String sub_name_list()
Returns a list of all sub-matrix type names.
TupleMatrix< typename FirstRow_::template ContainerType< DT2_, IT2_ >, typename RestRows_::template ContainerType< DT2_, IT2_ >... > ContainerType
Our 'base' class type.
void apply_transposed(VectorTypeR &r, const VectorTypeL &x, const VectorTypeR &y, DataType alpha=DataType(1)) const
Calculate .
TupleMatrix(FirstRow_ &&the_first, RestClass &&the_rest)
rest-class emplacement ctor; for internal use only
TupleVector< typename FirstRow_::VectorTypeL, typename RestRows_::VectorTypeL... > VectorTypeL
Compatible L-vector type.
TupleMatrix(const TupleMatrix &)=delete
deleted copy-ctor
const TupleMatrixElement< i_, j_, FirstRow_, RestRows_... >::Type & at() const
Returns a sub-matrix block.
void clone(const TupleMatrix &other, CloneMode clone_mode)
Turns this matrix into a clone of other.
std::uint64_t set_checkpoint_data(std::vector< char > &data, SerialConfig &config)
TupleMatrix(TupleMatrix &&other)
move ctor
static String name()
Returns a descriptive string for this container.
void apply(VectorTypeL &r, const VectorTypeR &x, const VectorTypeL &y, DataType alpha=DataType(1)) const
Calculate .
FirstRow_::VectorTypeR VectorTypeR
Compatible R-vector type.
TupleMatrix row helper class template.
void restore_from_checkpoint_data(std::vector< char > &data)
Extract object from checkpoint.
static String name()
Returns a descriptive string for this container.
VectorTypeL create_vector_l() const
Returns a new compatible L-Vector.
void clone(const TupleMatrixRow &other, CloneMode clone_mode)
Turns this matrix into a clone of other.
Index columns() const
Returns the total number of columns in this matrix.
static constexpr int num_blocks
number of matrix columns
static String sub_name_list()
Returns a list of all sub-matrix type names.
TupleVector< typename First_::VectorTypeR, typename Rest_::VectorTypeR... > VectorTypeR
Compatible R-vector type.
TupleElement< i_, First_, Rest_... >::Type const & at() const
Returns a sub-matrix block.
TupleMatrixRow< typename First_::template ContainerType< DT2_, IT2_ >, typename Rest_::template ContainerType< DT2_, IT2_ >... > ContainerType
Our 'base' class type.
std::uint64_t get_checkpoint_size(SerialConfig &config)
Calculate size.
VectorTypeR create_vector_r() const
Returns a new compatible R-Vector.
TupleMatrixRow & operator=(TupleMatrixRow &&other)
move-assign operator
RestClass _rest
all remaining sub-matrices
TupleMatrixRow(TupleMatrixRow &&other)
move ctor
Index used_elements() const
Returns the total number of non-zeros in this matrix.
TupleMatrixRow(First_ &&the_first, RestClass &&the_rest)
rest-class emplacement ctor; for internal use only
ContainerType< DataType2_, IndexType2_ > ContainerTypeByDI
this typedef lets you create a vector container with new Datatype and Index types
void format(Random &rng, DataType min, DataType max)
Reset all elements of the container to random values.
TupleMatrixRow(First_ &&the_first, Rest_ &&... the_rest)
Sub-Matrix emplacement constructor.
void format(DataType value=DataType(0))
Reset all elements of the container to a given value or zero if missing.
First_::IndexType IndexType
sub-matrix index-type
std::size_t bytes() const
Returns the total amount of bytes allocated.
First_::DataType DataType
sub-matrix data-type
TupleMatrixRow clone(LAFEM::CloneMode mode=LAFEM::CloneMode::Weak) const
Creates and returns a copy of this matrix.
void clone(const TupleMatrixRow &other)
Turns this matrix into a clone of other.
TupleMatrixRow(const TupleMatrixRow &)=delete
deleted copy-ctor
TupleElement< i_, First_, Rest_... >::Type & at()
Returns a sub-matrix block.
First_::VectorTypeL VectorTypeL
Compatible L-vector type.
Index rows() const
Returns the total number of rows in this matrix.
First_ _first
the first sub-matrix
TupleMatrixRow & operator=(const TupleMatrixRow &)=delete
deleted copy-assign operator
void clear()
Free all allocated arrays.
std::uint64_t set_checkpoint_data(std::vector< char > &data, SerialConfig &config)
Variadic TupleVector class template.
Pseudo-Random Number Generator.
Definition: random.hpp:54
String class implementation.
Definition: string.hpp:47
@ other
generic/other permutation strategy
@ rest
restriction (multigrid)
FEAT namespace.
Definition: adjactor.hpp:12
@ value
specifies whether the space should supply basis function values
std::uint64_t Index
Index data type.
Tuple container element helper class template.