FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
null_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
9#include <kernel/lafem/dense_vector.hpp>
10#include <kernel/lafem/dense_vector_blocked.hpp>
11
12
13namespace FEAT
14{
15 namespace LAFEM
16 {
18 namespace Intern
19 {
20 template<typename DT_, typename IT_, int size_>
21 struct BlockedVectorHelper
22 {
23 static_assert(size_ > 1, "invalid block size");
24 typedef DenseVectorBlocked<DT_, IT_, size_> VectorType;
25 };
26
27 template<typename DT_, typename IT_>
28 struct BlockedVectorHelper<DT_, IT_, 1>
29 {
30 typedef DenseVector<DT_, IT_> VectorType;
31 };
32 } // namespace Intern
34
54 template<typename DT_, typename IT_, int BlockHeight_ = 1, int BlockWidth_ = 1>
56 {
57 static_assert(BlockHeight_ > 0, "invalid block size");
58 static_assert(BlockWidth_ > 0, "invalid block size");
59
60 public:
62 typedef DT_ DataType;
64 typedef IT_ IndexType;
66 static constexpr int BlockHeight = BlockHeight_;
68 static constexpr int BlockWidth = BlockWidth_;
71
73 typedef const IT_* ImageIterator;
74
76 template <typename DT2_ = DT_, typename IT2_ = IT_>
78
80 template <typename DataType2_, typename IndexType2_>
82
84 typedef typename Intern::BlockedVectorHelper<DT_, IT_, BlockHeight_>::VectorType VectorTypeL;
86 typedef typename Intern::BlockedVectorHelper<DT_, IT_, BlockWidth_>::VectorType VectorTypeR;
87
88 static constexpr bool is_global = false;
89 static constexpr bool is_local = true;
90
91 private:
93 Index _num_rows, _num_cols;
94
95 public:
96
102 explicit NullMatrix() :
103 _num_rows(0u), _num_cols(0u)
104 {
105 }
106
115 explicit NullMatrix(Index rows_in, Index columns_in) :
116 _num_rows(rows_in), _num_cols(columns_in)
117 {
118 }
119
128 _num_rows(other._num_rows), _num_cols(other._num_cols)
129 {
130 }
131
140 {
141 this->_num_rows = other._num_rows;
142 this->_num_cols = other._num_cols;
143
144 return *this;
145 }
146
155 NullMatrix clone(CloneMode DOXY(clone_mode) = CloneMode::Weak) const
156 {
157 return NullMatrix(_num_rows, _num_cols);
158 }
159
168 template<typename DT2_, typename IT2_>
169 void clone(
171 CloneMode DOXY(clone_mode) = CloneMode::Weak)
172 {
173 this->_num_rows = other.rows();
174 this->_num_cols = other.columns();
175 }
176
184 template <typename DT2_, typename IT2_>
186 {
187 this->_num_rows = other.rows();
188 this->_num_cols = other.columns();
189 }
190
197 template <Perspective perspective_ = Perspective::native>
198 Index rows() const
199 {
200 Index result(this->_num_rows);
201 if (perspective_ == Perspective::pod)
202 {
203 result *= Index(BlockHeight_);
204 }
205 return result;
206 }
207
214 template <Perspective perspective_ = Perspective::native>
216 {
217 Index result(this->_num_cols);
218 if (perspective_ == Perspective::pod)
219 {
220 result *= Index(BlockWidth_);
221 }
222 return result;
223 }
224
231 template <Perspective perspective_ = Perspective::native>
233 {
234 return Index(0);
235 }
236
242 static String name()
243 {
244 return "NullMatrix";
245 }
246
253 void resize(Index rows_in, Index columns_in)
254 {
255 this->_num_rows = rows_in;
256 this->_num_cols = columns_in;
257 }
258
264 std::size_t bytes() const
265 {
266 return std::size_t(0);
267 }
268
275 void copy(const NullMatrix & DOXY(x), bool DOXY(full) = false)
276 {
277 // nothing to do here
278 }
279
285 void format(const DT_ DOXY(value) = DT_(0))
286 {
287 // nothing to do here
288 }
289
292
301 void axpy(
302 const NullMatrix & x,
303 const NullMatrix & y,
304 const DT_ DOXY(alpha) = DT_(1))
305 {
306 XASSERTM(x.rows() == y.rows(), "Matrix rows do not match!");
307 XASSERTM(x.rows() == this->rows(), "Matrix rows do not match!");
308 XASSERTM(x.columns() == y.columns(), "Matrix columns do not match!");
309 XASSERTM(x.columns() == this->columns(), "Matrix columns do not match!");
310 XASSERTM(x.used_elements() == y.used_elements(), "Matrix used_elements do not match!");
311 XASSERTM(x.used_elements() == this->used_elements(), "Matrix used_elements do not match!");
312
313 // nothing to do here
314 }
315
322 void scale(const NullMatrix & x, const DT_ DOXY(alpha))
323 {
324 XASSERTM(x.rows() == this->rows(), "Row count does not match!");
325 XASSERTM(x.columns() == this->columns(), "Column count does not match!");
326 XASSERTM(x.used_elements() == this->used_elements(), "Nonzero count does not match!");
327
328 // nothing to do here
329 }
330
336 DT_ norm_frobenius() const
337 {
338 return DT_(0);
339 }
340
347 void row_norm2(VectorTypeL& row_norms) const
348 {
349 XASSERTM(row_norms.size() == this->rows(), "Matrix/Vector dimension mismatch");
350
351 row_norms.format();
352 }
353
360 void row_norm2sqr(VectorTypeL& row_norms) const
361 {
362 XASSERTM(row_norms.size() == this->rows(), "Matrix/Vector dimension mismatch");
363
364 row_norms.format();
365 }
366
386 void row_norm2sqr(VectorTypeL& row_norms, const VectorTypeR& scal) const
387 {
388 XASSERTM(row_norms.size() == this->rows(), "Matrix/Vector dimension mismatch");
389 XASSERTM(scal.size() == this->columns(), "Matrix/scalings dimension mismatch");
390
391 row_norms.format();
392 }
393
402 {
404 }
405
412 {
413 x = this->transpose();
414 }
415
423 {
424 XASSERTM(r.size() == this->rows<Perspective::pod>(), "Vector size of r does not match!");
425 XASSERTM(x.size() == this->columns<Perspective::pod>(), "Vector size of x does not match!");
426
427 r.format();
428 }
429
437 {
438 XASSERTM(r.size() == this->columns<Perspective::pod>(), "Vector size of r does not match!");
439 XASSERTM(x.size() == this->rows<Perspective::pod>(), "Vector size of x does not match!");
440
441 r.format();
442 }
443
451 {
452 XASSERTM(r.size() == this->rows(), "Vector size of r does not match!");
453 XASSERTM(x.size() == this->columns<Perspective::pod>(), "Vector size of x does not match!");
454
455 r.format();
456 }
457
465 {
466 XASSERTM(r.size() == this->columns(), "Vector size of r does not match!");
467 XASSERTM(x.size() == this->rows<Perspective::pod>(), "Vector size of x does not match!");
468
469 r.format();
470 }
471
479 {
480 XASSERTM(r.size() == this->rows<Perspective::pod>(), "Vector size of r does not match!");
481 XASSERTM(x.size() == this->columns(), "Vector size of x does not match!");
482
483 r.format();
484 }
485
493 {
494 XASSERTM(r.size() == this->columns<Perspective::pod>(), "Vector size of r does not match!");
495 XASSERTM(x.size() == this->rows(), "Vector size of x does not match!");
496
497 r.format();
498 }
499
507 {
508 XASSERTM(r.size() == this->rows(), "Vector size of r does not match!");
509 XASSERTM(x.size() == this->columns(), "Vector size of x does not match!");
510
511 r.format();
512 }
513
521 {
522 XASSERTM(r.size() == this->columns(), "Vector size of r does not match!");
523 XASSERTM(x.size() == this->rows(), "Vector size of x does not match!");
524
525 r.format();
526 }
527
536 void apply(
538 const DenseVector<DT_, IT_> & x,
539 const DenseVector<DT_, IT_> & y,
540 const DT_ DOXY(alpha) = DT_(1)) const
541 {
542 XASSERTM(r.size() == this->rows<Perspective::pod>(), "Vector size of r does not match!");
543 XASSERTM(x.size() == this->columns<Perspective::pod>(), "Vector size of x does not match!");
544 XASSERTM(y.size() == this->rows<Perspective::pod>(), "Vector size of y does not match!");
545
546 r.copy(y);
547 }
548
559 const DenseVector<DT_, IT_> & x,
560 const DenseVector<DT_, IT_> & y,
561 const DT_ DOXY(alpha) = DT_(1)) const
562 {
563 XASSERTM(r.size() == this->columns<Perspective::pod>(), "Vector size of r does not match!");
564 XASSERTM(x.size() == this->rows<Perspective::pod>(), "Vector size of x does not match!");
565 XASSERTM(y.size() == this->columns<Perspective::pod>(), "Vector size of y does not match!");
566
567 r.copy(y);
568 }
569
578 void apply(
580 const DenseVector<DT_, IT_> & x,
582 const DT_ DOXY(alpha) = DT_(1)) const
583 {
584 XASSERTM(r.size() == this->rows(), "Vector size of r does not match!");
585 XASSERTM(x.size() == this->columns<Perspective::pod>(), "Vector size of x does not match!");
586 XASSERTM(y.size() == this->rows(), "Vector size of y does not match!");
587
588 r.copy(y);
589 }
600 const DenseVector<DT_, IT_> & x,
602 const DT_ DOXY(alpha) = DT_(1)) const
603 {
604 XASSERTM(r.size() == this->columns(), "Vector size of r does not match!");
605 XASSERTM(x.size() == this->rows<Perspective::pod>(), "Vector size of x does not match!");
606 XASSERTM(y.size() == this->columns(), "Vector size of y does not match!");
607
608 r.copy(y);
609 }
610
611
620 void apply(
623 const DenseVector<DT_, IT_> & y,
624 const DT_ DOXY(alpha) = DT_(1)) const
625 {
626 XASSERTM(r.size() == this->rows<Perspective::pod>(), "Vector size of r does not match!");
627 XASSERTM(x.size() == this->columns(), "Vector size of x does not match!");
628 XASSERTM(y.size() == this->rows<Perspective::pod>(), "Vector size of y does not match!");
629
630 r.copy(y);
631 }
632
644 const DenseVector<DT_, IT_> & y,
645 const DT_ DOXY(alpha) = DT_(1)) const
646 {
647 XASSERTM(r.size() == this->columns<Perspective::pod>(), "Vector size of r does not match!");
648 XASSERTM(x.size() == this->rows(), "Vector size of x does not match!");
649 XASSERTM(y.size() == this->columns<Perspective::pod>(), "Vector size of y does not match!");
650
651 r.copy(y);
652 }
653
662 void apply(
666 const DT_ DOXY(alpha) = DT_(1)) const
667 {
668 XASSERTM(r.size() == this->rows(), "Vector size of r does not match!");
669 XASSERTM(x.size() == this->columns(), "Vector size of x does not match!");
670 XASSERTM(y.size() == this->rows(), "Vector size of y does not match!");
671
672 r.copy(y);
673 }
674
687 const DT_ DOXY(alpha) = DT_(1)) const
688 {
689 XASSERTM(r.size() == this->columns(), "Vector size of r does not match!");
690 XASSERTM(x.size() == this->rows(), "Vector size of x does not match!");
691 XASSERTM(y.size() == this->columns(), "Vector size of y does not match!");
692
693 r.copy(y);
694 }
695
704 void apply(
707 const DenseVector<DT_, IT_> & y,
708 const DT_ DOXY(alpha) = DT_(1)) const
709 {
710 XASSERTM(r.size() == this->rows(), "Vector size of r does not match!");
711 XASSERTM(x.size() == this->columns(), "Vector size of x does not match!");
712 XASSERTM(y.size() == this->rows<Perspective::pod>(), "Vector size of y does not match!");
713
714 r.copy(y);
715 }
716
728 const DenseVector<DT_, IT_> & y,
729 const DT_ DOXY(alpha) = DT_(1)) const
730 {
731 XASSERTM(r.size() == this->columns(), "Vector size of r does not match!");
732 XASSERTM(x.size() == this->rows(), "Vector size of x does not match!");
733 XASSERTM(y.size() == this->columns<Perspective::pod>(), "Vector size of y does not match!");
734
735 r.copy(y);
736 }
737
739
741 void lump_rows(VectorTypeL& lump) const
742 {
743 XASSERTM(lump.size() == rows(), "lump vector size does not match matrix row count!");
744 lump.format();
745 }
746
757 {
758 VectorTypeL lump = create_vector_l();
759 lump_rows(lump);
760 return lump;
761 }
762
763
765 void extract_diag(VectorTypeL & diag) const
766 {
767 XASSERTM(diag.size() == rows(), "diag size does not match matrix row count!");
768 XASSERTM(rows() == columns(), "matrix is not square!");
769 diag.format();
770 }
771
774 {
775 VectorTypeL diag = create_vector_l();
776 extract_diag(diag);
777 return diag;
778 }
779
781 // Returns a new compatible L-Vector.
782 VectorTypeL create_vector_l() const
783 {
784 return VectorTypeL(this->rows());
785 }
786
787 // Returns a new compatible R-Vector.
788 VectorTypeR create_vector_r() const
789 {
790 return VectorTypeR(this->columns());
791 }
792
794 Index get_length_of_line(const Index) const
795 {
796 return Index(0);
797 }
798
800 void set_line(const Index, DT_ * const, IT_ * const, const Index, const Index = 1) const
801 {
802 // nothing to do here
803 }
804
805 void set_line_reverse(const Index, DT_ * const, const Index = 1)
806 {
807 // nothing to do here
808 }
810
813 {
814 return size_t(0);
815 }
816
818 void restore_from_checkpoint_data(std::vector<char> & /*data*/)
819 {
820 // nothing to do here
821 }
822
824 void set_checkpoint_data(std::vector<char>& /*data*/)
825 {
826 // nothing to do here
827 }
828
829 /* ******************************************************************* */
830 /* A D J A C T O R I N T E R F A C E I M P L E M E N T A T I O N */
831 /* ******************************************************************* */
832 public:
835 {
836 return rows();
837 }
838
841 {
842 return columns();
843 }
844
846 inline ImageIterator image_begin(Index domain_node) const
847 {
848 XASSERTM(domain_node < rows(), "Domain node index out of range");
849 return nullptr;
850 }
851
853 inline ImageIterator image_end(Index domain_node) const
854 {
855 XASSERTM(domain_node < rows(), "Domain node index out of range");
856 return nullptr;
857 }
858 }; // class NullMatrix
859 } // namespace LAFEM
860} // namespace FEAT
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Definition: assertion.hpp:263
Index size() const
Returns the containers size.
Definition: container.hpp:1136
void format(DT_ value=DT_(0))
Reset all elements of the container to a given value or zero if missing.
Definition: container.hpp:851
Blocked Dense data vector class template.
void copy(const DenseVectorBlocked &x, bool full=false)
Performs .
Index size() const
The number of elements.
Dense data vector class template.
void copy(const VT_ &a)
Performs .
Null Matrix implementation.
Definition: null_matrix.hpp:56
void apply_transposed(DenseVector< DT_, IT_ > &r, const DenseVector< DT_, IT_ > &x, const DenseVector< DT_, IT_ > &y, const DT_ alpha=DT_(1)) const
Calculate .
Index columns() const
Retrieve matrix column count.
void apply(DenseVectorBlocked< DT_, IT_, BlockHeight_ > &r, const DenseVectorBlocked< DT_, IT_, BlockWidth_ > &x, const DenseVector< DT_, IT_ > &y, const DT_ alpha=DT_(1)) const
Calculate .
VectorTypeL lump_rows() const
Returns the lumped rows vector.
void apply(DenseVector< DT_, IT_ > &r, const DenseVectorBlocked< DT_, IT_, BlockWidth_ > &x, const DenseVector< DT_, IT_ > &y, const DT_ alpha=DT_(1)) const
Calculate .
void copy(const NullMatrix &x, bool full=false)
Performs .
void apply_transposed(DenseVector< DT_, IT_ > &r, const DenseVectorBlocked< DT_, IT_, BlockHeight_ > &x, const DenseVector< DT_, IT_ > &y, const DT_ alpha=DT_(1)) const
Calculate .
static String name()
Returns a descriptive string.
void apply(DenseVector< DT_, IT_ > &r, const DenseVector< DT_, IT_ > &x, const DenseVector< DT_, IT_ > &y, const DT_ alpha=DT_(1)) const
Calculate .
void apply(DenseVectorBlocked< DT_, IT_, BlockHeight_ > &r, const DenseVectorBlocked< DT_, IT_, BlockWidth_ > &x, const DenseVectorBlocked< DT_, IT_, BlockHeight_ > &y, const DT_ alpha=DT_(1)) const
Calculate .
NullMatrix(NullMatrix &&other)
Move Constructor.
void restore_from_checkpoint_data(std::vector< char > &)
Extract object from checkpoint.
void resize(Index rows_in, Index columns_in)
Resizes the matrix to different dimensions.
void apply_transposed(DenseVectorBlocked< DT_, IT_, BlockWidth_ > &r, const DenseVectorBlocked< DT_, IT_, BlockHeight_ > &x, const DenseVector< DT_, IT_ > &y, const DT_ alpha=DT_(1)) const
Calculate .
void row_norm2sqr(VectorTypeL &row_norms, const VectorTypeR &scal) const
Computes the square of the 2-norm for every row, where every row is scaled by a vector.
void apply_transposed(DenseVector< DT_, IT_ > &r, const DenseVector< DT_, IT_ > &x) const
Calculate .
NullMatrix()
Constructor.
void apply(DenseVectorBlocked< DT_, IT_, BlockHeight_ > &r, const DenseVector< DT_, IT_ > &x) const
Calculate .
void apply_transposed(DenseVectorBlocked< DT_, IT_, BlockWidth_ > &r, const DenseVector< DT_, IT_ > &x, const DenseVectorBlocked< DT_, IT_, BlockWidth_ > &y, const DT_ alpha=DT_(1)) const
Calculate .
void axpy(const NullMatrix &x, const NullMatrix &y, const DT_ alpha=DT_(1))
Calculate .
Tiny::Matrix< DataType, BlockHeight, BlockWidth > ValueType
Value type, meaning the type of each block.
Definition: null_matrix.hpp:70
NullMatrix< DT_, IT_, BlockWidth_, BlockHeight_ > transpose() const
Calculate .
const IT_ * ImageIterator
ImageIterator typedef for Adjactor interface implementation.
Definition: null_matrix.hpp:73
void apply_transposed(DenseVectorBlocked< DT_, IT_, BlockWidth_ > &r, const DenseVector< DT_, IT_ > &x) const
Calculate .
void apply_transposed(DenseVector< DT_, IT_ > &r, const DenseVectorBlocked< DT_, IT_, BlockHeight_ > &x) const
Calculate .
void apply(DenseVectorBlocked< DT_, IT_, BlockHeight_ > &r, const DenseVector< DT_, IT_ > &x, const DenseVectorBlocked< DT_, IT_, BlockHeight_ > &y, const DT_ alpha=DT_(1)) const
Calculate .
static constexpr int BlockHeight
Our block height.
Definition: null_matrix.hpp:66
Intern::BlockedVectorHelper< DT_, IT_, BlockWidth_ >::VectorType VectorTypeR
Compatible R-vector type.
Definition: null_matrix.hpp:86
Index get_num_nodes_domain() const
void apply_transposed(DenseVectorBlocked< DT_, IT_, BlockWidth_ > &r, const DenseVectorBlocked< DT_, IT_, BlockHeight_ > &x, const DenseVectorBlocked< DT_, IT_, BlockWidth_ > &y, const DT_ alpha=DT_(1)) const
Calculate .
void apply(DenseVector< DT_, IT_ > &r, const DenseVector< DT_, IT_ > &x) const
Calculate .
Index rows() const
Retrieve matrix row count.
IT_ IndexType
Our indextype.
Definition: null_matrix.hpp:64
void apply_transposed(DenseVectorBlocked< DT_, IT_, BlockWidth_ > &r, const DenseVectorBlocked< DT_, IT_, BlockHeight_ > &x) const
Calculate .
void format(const DT_ value=DT_(0))
Reset all elements of the container to a given value or zero if missing.
uint64_t get_checkpoint_size()
Calculate size.
void lump_rows(VectorTypeL &lump) const
void apply(DenseVectorBlocked< DT_, IT_, BlockHeight_ > &r, const DenseVectorBlocked< DT_, IT_, BlockWidth_ > &x) const
Calculate .
void clone(const NullMatrix< DT2_, IT2_, BlockHeight_, BlockWidth_ > &other, CloneMode clone_mode=CloneMode::Weak)
Clone operation.
Intern::BlockedVectorHelper< DT_, IT_, BlockHeight_ >::VectorType VectorTypeL
Compatible L-vector type.
Definition: null_matrix.hpp:84
NullMatrix & operator=(NullMatrix &&other)
Move operator.
ImageIterator image_end(Index domain_node) const
VectorTypeL extract_diag() const
extract main diagonal vector from matrix
void set_checkpoint_data(std::vector< char > &)
Index get_num_nodes_image() const
void scale(const NullMatrix &x, const DT_ alpha)
Calculate .
void row_norm2sqr(VectorTypeL &row_norms) const
Computes the square of the 2-norm for every row.
Index used_elements() const
Retrieve non zero element count.
DT_ norm_frobenius() const
Calculates the Frobenius norm of this matrix.
NullMatrix clone(CloneMode clone_mode=CloneMode::Weak) const
Clone operation.
void row_norm2(VectorTypeL &row_norms) const
Computes the 2-norm for every row.
void convert(const NullMatrix< DT2_, IT2_, BlockHeight_, BlockWidth_ > &other)
Conversion method.
void transpose(const NullMatrix< DT_, IT_, BlockWidth_, BlockHeight_ > &x)
Calculate .
Index _num_rows
matrix dimensions
Definition: null_matrix.hpp:93
static constexpr int BlockWidth
Our block width.
Definition: null_matrix.hpp:68
std::size_t bytes() const
Returns the total amount of bytes allocated.
void apply(DenseVector< DT_, IT_ > &r, const DenseVectorBlocked< DT_, IT_, BlockWidth_ > &x) const
Calculate .
DT_ DataType
Our datatype.
Definition: null_matrix.hpp:62
NullMatrix(Index rows_in, Index columns_in)
Constructor.
void extract_diag(VectorTypeL &diag) const
ImageIterator image_begin(Index domain_node) const
String class implementation.
Definition: string.hpp:46
Tiny Matrix class template.
LAFEM common type definitions.
FEAT namespace.
Definition: adjactor.hpp:12
@ value
specifies whether the space should supply basis function values
std::uint64_t Index
Index data type.