9#include <kernel/lafem/tuple_vector.hpp>
10#include <kernel/lafem/dense_vector.hpp>
11#include <kernel/lafem/container.hpp>
63 typename MatrixB_ = MatrixA_,
64 typename MatrixD_ = MatrixB_>
76 static_assert(std::is_same<typename MatrixA_::DataType, typename MatrixB_::DataType>::value,
77 "A and B have different data-types");
78 static_assert(std::is_same<typename MatrixA_::DataType, typename MatrixD_::DataType>::value,
79 "A and D have different data-types");
82 static_assert(std::is_same<typename MatrixA_::VectorTypeL, typename MatrixB_::VectorTypeL>::value,
83 "A and B have different compatible L-vectors");
84 static_assert(std::is_same<typename MatrixA_::VectorTypeR, typename MatrixD_::VectorTypeR>::value,
85 "A and D have different compatible R-vectors");
88 typedef typename MatrixTypeA::DataType
DataType;
97 template <
typename DT2_ = DataType,
typename IT2_ = IndexType>
103 template <
typename DataType2_,
typename IndexType2_>
173 auto found = filename.rfind(
"/");
174 if (found != std::string::npos)
176 directory = filename.substr(0, found + 1);
179 std::ifstream file(filename.c_str(), std::ifstream::in);
180 if (! file.is_open())
181 XABORTM(
"Unable to open Matrix file " + filename);
184 std::getline(file, line);
185 if (line.find(
"%%MatrixMarket saddlepointmatrix coordinate real general") == String::npos)
186 XABORTM(
"Input-file is not a complatible file");
191 std::getline(file, line);
193 }
while (line.find(
"%%") == 0 || line ==
"");
195 MatrixA_ tmp_a(mode, directory + line);
198 std::getline(file, line);
200 MatrixB_ tmp_b(mode, directory + line);
203 std::getline(file, line);
205 MatrixD_ tmp_d(mode, directory + line);
235 std::ofstream file(filename.c_str(), std::ofstream::out);
236 if (! file.is_open())
237 XABORTM(
"Unable to open Matrix file " + filename);
240 auto found = filename.rfind(
".");
241 if (found != std::string::npos)
243 suffix = filename.substr(found);
244 filename.erase(found);
246 found = filename.rfind(
"/");
247 if (found != std::string::npos)
249 directory = filename.substr(0, found + 1);
250 filename.erase(0, found + 1);
253 file <<
"%%MatrixMarket saddlepointmatrix coordinate real general\n";
254 file << filename <<
"_a" << suffix <<
"\n";
255 file << filename <<
"_b" << suffix <<
"\n";
256 file << filename <<
"_d" << suffix <<
"\n";
260 _matrix_a.write_out(mode, directory + filename +
"_a" + suffix);
261 _matrix_b.write_out(mode, directory + filename +
"_b" + suffix);
262 _matrix_d.write_out(mode, directory + filename +
"_d" + suffix);
327 template<
int i_,
int j_>
330 static_assert((0 <= i_) && (0 <= j_),
"invalid sub-matrix index");
331 static_assert((i_ <= 1) && (j_ <= 1),
"invalid sub-matrix index");
332 static_assert((i_ < 1) || (j_ < 1),
"sub-matrix block (1,1) does not exist in SaddlePointMatrix");
337 template<
int i_,
int j_>
340 static_assert((0 <= i_) && (0 <= j_),
"invalid sub-matrix index");
341 static_assert((i_ <= 1) && (j_ <= 1),
"invalid sub-matrix index");
342 static_assert((i_ < 1) || (j_ < 1),
"sub-matrix block (1,1) does not exist in SaddlePointMatrix");
352 template <Perspective perspective_ = Perspective::native>
355 return _matrix_a.template rows<perspective_>() +
_matrix_d.template rows<perspective_>();
364 template <Perspective perspective_ = Perspective::native>
367 return _matrix_a.template columns<perspective_>() +
_matrix_b.template columns<perspective_>();
376 template <Perspective perspective_ = Perspective::native>
379 return _matrix_a.template used_elements<perspective_>() +
_matrix_b.template used_elements<perspective_>() +
_matrix_d.template used_elements<perspective_>();
385 return String(
"SaddePointMatrix<") + MatrixTypeA::name() +
"," +
386 MatrixTypeB::name() +
"," +
387 MatrixTypeD::name() +
">";
390 template <Perspective perspective_ = Perspective::native>
393 return rows<perspective_>() * columns<perspective_>();
426 void lump_rows(
VectorTypeL& lump,
bool =
true)
const
429 lump.rest().format();
446 block_a().apply(r.template at<0>(), x.template at<0>());
447 block_b().apply(r.template at<0>(), x.template at<1>(), r.template at<0>(),
DataType(1));
448 block_d().apply(r.template at<1>(), x.template at<0>());
453 XASSERTM(r.
size() == this->rows(),
"Vector size of r does not match!");
454 XASSERTM(x.
size() == this->columns(),
"Vector size of x does not match!");
462 block_a().apply(r_first, x_first);
464 block_d().apply(r_rest, x_first);
481 block_a().apply_transposed(r.template at<0>(), x.template at<0>());
482 block_d().apply_transposed(r.template at<0>(), x.template at<1>(), r.template at<0>(),
DataType(1));
483 block_b().apply_transposed(r.template at<1>(), x.template at<0>());
488 XASSERTM(r.
size() == this->columns(),
"Vector size of r does not match!");
489 XASSERTM(x.
size() == this->rows(),
"Vector size of x does not match!");
497 block_a().apply_transposed(r_first, x_first);
499 block_b().applytransposed(r_rest, x_first);
521 block_a().apply(r.template at<0>(), x.template at<0>(), y.template at<0>(), alpha);
522 block_b().apply(r.template at<0>(), x.template at<1>(), r.template at<0>(), alpha);
523 block_d().apply(r.template at<1>(), x.template at<0>(), y.template at<1>(), alpha);
529 XASSERTM(r.
size() == this->rows(),
"Vector size of r does not match!");
530 XASSERTM(x.
size() == this->columns(),
"Vector size of x does not match!");
531 XASSERTM(y.
size() == this->rows(),
"Vector size of y does not match!");
542 block_a().apply(r_first, x_first, y_first, alpha);
543 block_b().apply(r_first, x_rest, r_first, alpha);
544 block_d().apply(r_rest, x_first, y_rest, alpha);
566 block_a().apply_transposed(r.template at<0>(), x.template at<0>(), y.template at<0>(), alpha);
567 block_d().apply_transposed(r.template at<0>(), x.template at<1>(), r.template at<0>(), alpha);
568 block_b().apply_transposed(r.template at<1>(), x.template at<0>(), y.template at<1>(), alpha);
574 XASSERTM(r.
size() == this->columns(),
"Vector size of r does not match!");
575 XASSERTM(x.
size() == this->rows(),
"Vector size of x does not match!");
576 XASSERTM(y.
size() == this->columns(),
"Vector size of y does not match!");
587 block_a().apply_transposed(r_first, x_first, y_first, alpha);
588 block_d().apply_transposed(r_first, x_rest, r_first, alpha);
589 block_b().apply_transposed(r_rest, x_first, y_rest, alpha);
635 const Index arows(this->
block_a().
template rows<Perspective::pod>());
639 return this->
block_a().get_length_of_line(row) + this->
block_b().get_length_of_line(row);
643 return this->
block_d().get_length_of_line(row - arows);
649 void set_line(
const Index row,
typename MatrixA_::DataType *
const pval_set,
typename MatrixA_::IndexType *
const pcol_set,
650 const Index col_start,
const Index stride = 1)
const
652 const Index arows(this->
block_a().
template rows<Perspective::pod>());
658 this->
block_a().set_line(row, pval_set, pcol_set, col_start, stride);
659 this->
block_b().set_line(row, pval_set + stride * length_of_a, pcol_set + stride * length_of_a, col_start + this->
block_a().
template columns<Perspective::pod>(), stride);
663 this->
block_d().set_line(row - arows, pval_set, pcol_set, col_start, stride);
667 void set_line_reverse(
const Index row,
const typename MatrixA_::DataType *
const pval_set,
const Index stride = 1)
669 const Index arows(this->
block_a().
template rows<Perspective::pod>());
675 this->
block_a().set_line_reverse(row, pval_set, stride);
676 this->
block_b().set_line_reverse(row, pval_set + stride * length_of_a, stride);
680 this->
block_d().set_line_reverse(row - arows, pval_set, stride);
686 const Index rows_a =
block_a().template rows<Perspective::pod>();
690 return block_d().row_degree(row - rows_a);
693 template<
typename IT2_>
694 Index get_row_col_indices(
const Index row, IT2_*
const pcol_idx,
const IT2_ col_offset)
const
696 const Index rows_a =
block_a().template rows<Perspective::pod>();
697 const Index cols_a =
block_a().template columns<Perspective::pod>();
700 Index degree_a =
block_a().get_row_col_indices(row, pcol_idx, col_offset);
701 return degree_a +
block_b().get_row_col_indices(row, pcol_idx + degree_a, col_offset + cols_a);
704 return block_d().get_row_col_indices(row - rows_a, pcol_idx, col_offset);
707 template<
typename DT2_>
708 Index get_row_values(
const Index row, DT2_ *
const pvals)
const
710 const Index rows_a =
block_a().template rows<Perspective::pod>();
714 return degree_a +
block_b().get_row_values(row, pvals + degree_a);
717 return block_d().get_row_values(row - rows_a, pvals);
720 template<
typename DT2_>
721 Index set_row_values(
const Index row,
const DT2_ *
const pvals)
723 const Index rows_a =
block_a().template rows<Perspective::pod>();
727 return degree_a +
block_b().set_row_values(row, pvals + degree_a);
730 return block_d().set_row_values(row - rows_a, pvals);
738 return (3 *
sizeof(std::uint64_t)) + this->
block_a().get_checkpoint_size(config) + this->
block_b().get_checkpoint_size(config) + this->
block_d().get_checkpoint_size(config);
744 std::uint64_t isize = *(std::uint64_t*) data.data();
745 std::vector<char>::iterator start = std::begin(data) +
sizeof(std::uint64_t);
746 std::vector<char>::iterator end = std::begin(data) +
sizeof(std::uint64_t) + (
int) isize;
747 std::vector<char> buffer_a(start, end);
748 this->
block_a().restore_from_checkpoint_data(buffer_a);
750 data.erase(std::begin(data), end);
751 isize = *(std::uint64_t*) data.data();
752 start = std::begin(data) +
sizeof(std::uint64_t);
753 end = std::begin(data) +
sizeof(std::uint64_t) + (
int) isize;
754 std::vector<char> buffer_b(start, end);
755 this->
block_b().restore_from_checkpoint_data(buffer_b);
757 data.erase(std::begin(data), end);
758 this->
block_d().restore_from_checkpoint_data(data);
764 std::size_t old_size = data.size();
765 data.insert(std::end(data),
sizeof(std::uint64_t),0);
766 std::uint64_t ireal_size = this->
block_a().set_checkpoint_data(data, config);
767 std::uint64_t ret_size = ireal_size;
768 char* csize =
reinterpret_cast<char*
>(&ireal_size);
769 for(std::size_t i(0) ; i <
sizeof(std::uint64_t) ; ++i)
771 data[old_size + i] = csize[i];
774 old_size = data.size();
775 data.insert(std::end(data),
sizeof(std::uint64_t), 0);
776 ireal_size = this->
block_b().set_checkpoint_data(data, config);
777 ret_size += ireal_size;
778 csize =
reinterpret_cast<char*
>(&ireal_size);
779 for(std::size_t i(0) ; i <
sizeof(std::uint64_t) ; ++i)
781 data[old_size + i] = csize[i];
784 return 2*
sizeof(std::uint64_t) + ret_size + this->
block_d().set_checkpoint_data(data, config);
794 template <
typename MatrixA2_,
typename MatrixB2_,
typename MatrixD2_>
802 template <
typename MatrixA2_,
typename MatrixB2_,
typename MatrixD2_>
812 template<
typename MatrixA_,
typename MatrixB_,
typename MatrixD_>
813 struct SaddlePointMatrixElement<MatrixA_, MatrixB_, MatrixD_, 0, 0>
815 typedef MatrixA_ Type;
816 static Type& get(SaddlePointMatrix<MatrixA_, MatrixB_, MatrixD_>& matrix)
818 return matrix.block_a();
820 static const Type& get(
const SaddlePointMatrix<MatrixA_, MatrixB_, MatrixD_>& matrix)
822 return matrix.block_a();
826 template<
typename MatrixA_,
typename MatrixB_,
typename MatrixD_>
827 struct SaddlePointMatrixElement<MatrixA_, MatrixB_, MatrixD_, 0, 1>
829 typedef MatrixB_
Type;
830 static Type& get(SaddlePointMatrix<MatrixA_, MatrixB_, MatrixD_>& matrix)
832 return matrix.block_b();
834 static const Type& get(
const SaddlePointMatrix<MatrixA_, MatrixB_, MatrixD_>& matrix)
836 return matrix.block_b();
840 template<
typename MatrixA_,
typename MatrixB_,
typename MatrixD_>
841 struct SaddlePointMatrixElement<MatrixA_, MatrixB_, MatrixD_, 1, 0>
843 typedef MatrixD_
Type;
844 static Type& get(SaddlePointMatrix<MatrixA_, MatrixB_, MatrixD_>& matrix)
846 return matrix.block_d();
848 static const Type& get(
const SaddlePointMatrix<MatrixA_, MatrixB_, MatrixD_>& matrix)
850 return matrix.block_d();
#define XABORTM(msg)
Abortion macro definition with custom message.
#define XASSERT(expr)
Assertion macro definition.
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Index size() const
Returns the containers size.
Dense data vector class template.
Saddle-Point matrix meta class template.
SaddlePointMatrix clone(LAFEM::CloneMode mode=LAFEM::CloneMode::Weak) const
Creates and returns a deep copy of this matrix.
void apply(VectorTypeL &r, const VectorTypeR &x, const VectorTypeL &y, DataType alpha=DataType(1)) const
Applies this matrix onto a vector.
SaddlePointMatrix()
default CTOR
MatrixD_ MatrixTypeD
type of sub-matrix D
const SaddlePointMatrixElement< MatrixA_, MatrixB_, MatrixD_, i_, j_ >::Type & at() const
Returns a sub-matrix block.
MatrixTypeB _matrix_b
sub-matrix B
VectorTypeL create_vector_l() const
Returns a new compatible L-Vector.
MatrixTypeA _matrix_a
sub-matrix A
MatrixB_ MatrixTypeB
type of sub-matrix B
static constexpr int num_row_blocks
number of row blocks (vertical size)
Index columns() const
Returns the total number of columns in this matrix.
bool same_layout(const SaddlePointMatrix &x) const
Checks if the structural layout of this matrix matches that of another matrix. This excludes comparis...
DataType max_rel_diff(const SaddlePointMatrix &x) const
Retrieve the maximum relative difference of this matrix and another one y.max_rel_diff(x) returns .
std::uint64_t set_checkpoint_data(std::vector< char > &data, SerialConfig &config)
void apply_transposed(VectorTypeR &r, const VectorTypeL &x) const
Applies this matrix onto a vector.
MatrixTypeA::DataType DataType
data type
void write_out(FileMode mode, String filename) const
Write out matrix to file.
MatrixTypeA & block_a()
Returns the sub-matrix block A.
SaddlePointMatrix(SaddlePointMatrix &&other)
move ctor
Index get_length_of_line(const Index row) const
Returns the number of NNZ-elements of the selected row.
VectorTypeR create_vector_r() const
Returns a new compatible R-Vector.
Index used_elements() const
Returns the total number of non-zeros in this matrix.
void apply(VectorTypeL &r, const VectorTypeR &x) const
Applies this matrix onto a vector.
const MatrixTypeB & block_b() const
Returns the sub-matrix block B.
MatrixTypeA::IndexType IndexType
index type
Index rows() const
Returns the total number of rows in this matrix.
MatrixA_ MatrixTypeA
type of sub-matrix A
static constexpr int num_col_blocks
number of column blocks (horizontal size)
void format(DataType value=DataType(0))
Reset all elements of the container to a given value or zero if missing.
std::uint64_t get_checkpoint_size(SerialConfig &config)
Calculate size.
TupleVector< typename MatrixTypeA::VectorTypeL, typename MatrixTypeD::VectorTypeL > VectorTypeL
Compatible L-vector type.
const MatrixTypeA & block_a() const
Returns the sub-matrix block A.
void clear()
Free all allocated arrays.
SaddlePointMatrix & operator=(SaddlePointMatrix &&other)
move-assign operator
static String name()
Returns a descriptive string for this container.
void convert(const SaddlePointMatrix< MatrixA2_, MatrixB2_, MatrixD2_ > &other)
Conversion method.
MatrixTypeD _matrix_d
sub-matrix C
void extract_diag(VectorTypeL &diag) const
extract main diagonal vector from matrix
std::size_t bytes() const
Returns the total amount of bytes allocated.
void restore_from_checkpoint_data(std::vector< char > &data)
Extract object from checkpoint.
const MatrixTypeD & block_d() const
Returns the sub-matrix block D.
TupleVector< typename MatrixTypeA::VectorTypeR, typename MatrixTypeB::VectorTypeR > VectorTypeR
Compatible R-vector type.
MatrixTypeB & block_b()
Returns the sub-matrix block B.
SaddlePointMatrix(FileMode mode, const String &filename)
Constructor.
void read_from(FileMode mode, const String &filename)
Read in matrix from file.
SaddlePointMatrixElement< MatrixA_, MatrixB_, MatrixD_, i_, j_ >::Type & at()
Returns a sub-matrix block.
void apply_transposed(VectorTypeR &r, const VectorTypeL &x, const VectorTypeR &y, DataType alpha=DataType(1)) const
Applies this matrix onto a vector.
virtual ~SaddlePointMatrix()
virtual destructor
MatrixTypeD & block_d()
Returns the sub-matrix block D.
SaddlePointMatrix(MatrixTypeA &&matrix_a, MatrixTypeB &&matrix_b, MatrixTypeD &&matrix_d)
Sub-Matrix move constructor.
Config class for serialize parameter.
Variadic TupleVector class template.
void format(DataType value=DataType(0))
Reset all elements of the container to a given value or zero if missing.
String class implementation.
String & trim_me(const String &charset)
Trims this string.
T_ max(T_ a, T_ b)
Returns the maximum of two values.
@ value
specifies whether the space should supply basis function values
std::uint64_t Index
Index data type.
Saddle-Point matrix element helper class template.