9#include <kernel/lafem/power_vector.hpp>
10#include <kernel/lafem/sparse_layout.hpp>
11#include <kernel/lafem/meta_element.hpp>
12#include <kernel/lafem/container.hpp>
39 static_assert(blocks_ > 1,
"invalid block size");
42 template<
typename,
int>
52 typedef typename SubMatrixType::DataType
DataType;
54 typedef typename SubMatrixType::IndexType
IndexType;
62 template <
typename DT2_ = DataType,
typename IT2_ = IndexType>
66 template <
typename DataType2_,
typename IndexType2_>
82 _first(std::move(the_first)),
83 _rest(std::move(the_rest))
136 std::getline(file, line);
138 }
while (line.find(
"%%") == 0 || line ==
"");
141 _first = std::move(tmp_first);
143 RestClass tmp_rest(mode, file, directory);
144 _rest = std::move(tmp_rest);
156 auto found = filename.rfind(
"/");
157 if (found != std::string::npos)
159 directory = filename.substr(0, found + 1);
162 std::ifstream file(filename.c_str(), std::ifstream::in);
163 if (! file.is_open())
164 XABORTM(
"Unable to open Matrix file " + filename);
167 std::getline(file, line);
168 if (line.find(
"%%MatrixMarket powerdiagmatrix coordinate real general") == String::npos)
169 XABORTM(
"Input-file is not a complatible file");
173 _first = std::move(other._first);
174 _rest = std::move(other._rest);
184 _first = std::move(other._first);
185 _rest = std::move(other._rest);
208 std::ofstream file(filename.c_str(), std::ofstream::out);
209 if (! file.is_open())
210 XABORTM(
"Unable to open Matrix file " + filename);
213 auto found = filename.rfind(
".");
214 if (found != std::string::npos)
216 suffix = filename.substr(found);
217 filename.erase(found);
219 found = filename.rfind(
"/");
220 if (found != std::string::npos)
222 directory = filename.substr(0, found + 1);
223 filename.erase(0, found + 1);
226 file <<
"%%MatrixMarket powerdiagmatrix coordinate real general\n";
227 for (
Index i(1); i <= blocks_; ++i)
229 file << filename <<
"_pd" << i << suffix <<
"\n";
247 _first.write_out(mode, directory + prefix +
"_pd" +
stringify(length + 1 - blocks_) + suffix);
269 (*this)=other.clone(clone_mode);
298 template<
int i_,
int j_>
301 static_assert(i_ == j_,
"invalid sub-matrix index");
302 static_assert((0 <= i_) && (i_ < blocks_),
"invalid sub-matrix index");
307 template<
int i_,
int j_>
310 static_assert(i_ == j_,
"invalid sub-matrix index");
311 static_assert((0 <= i_) && (i_ < blocks_),
"invalid sub-matrix index");
326 XASSERTM((i == j) && (0 <= i) && (i < blocks_),
"invalid sub-matrix index");
333 XASSERTM((i == j) && (0 <= i) && (i < blocks_),
"invalid sub-matrix index");
346 std::uint64_t isize = *(std::uint64_t*) data.data();
347 std::vector<char>::iterator start = std::begin(data) +
sizeof(std::uint64_t);
348 std::vector<char>::iterator last_of_first = std::begin(data) +
sizeof(std::uint64_t) + (
int) isize;
349 std::vector<char> buffer_first(start, last_of_first);
350 _first.restore_from_checkpoint_data(buffer_first);
352 data.erase(std::begin(data), last_of_first);
359 std::size_t old_size = data.size();
360 data.insert(std::end(data),
sizeof(std::uint64_t), 0);
361 std::uint64_t ireal_size =
_first.set_checkpoint_data(data, config);
362 char* csize =
reinterpret_cast<char*
>(&ireal_size);
363 for(std::size_t i(0) ; i <
sizeof(std::uint64_t) ; ++i)
365 data[old_size + i] = csize[i];
392 int row_blocks()
const
397 int col_blocks()
const
409 template <Perspective perspective_ = Perspective::native>
412 return first().template rows<perspective_>() + rest().template rows<perspective_>();
421 template <Perspective perspective_ = Perspective::native>
424 return first().template columns<perspective_>() + rest().template columns<perspective_>();
433 template <Perspective perspective_ = Perspective::native>
436 return first().template used_elements<perspective_>() + rest().template used_elements<perspective_>();
442 return String(
"PowerDiagMatrix<") + SubMatrixType::name() +
"," +
stringify(blocks_) +
">";
458 first().format(
value);
459 rest().format(
value);
474 first().extract_diag(diag.first());
475 rest().extract_diag(diag.rest());
492 first().apply(r.first(), x.first());
493 rest().apply(r.rest(), x.rest());
498 XASSERTM(r.
size() == this->rows(),
"Vector size of r does not match!");
499 XASSERTM(x.
size() == this->columns(),
"Vector size of x does not match!");
507 first().apply(r_first, x_first);
508 rest().apply(r_rest, x_rest);
525 first().apply_transposed(r.first(), x.first());
526 rest().apply_transposed(r.rest(), x.rest());
531 XASSERTM(r.
size() == this->columns(),
"Vector size of r does not match!");
532 XASSERTM(x.
size() == this->rows(),
"Vector size of x does not match!");
540 first().apply_transposed(r_first, x_first);
541 rest().apply_transposed(r_rest, x_rest);
562 first().apply(r.first(), x.first(), y.first(), alpha);
563 rest().apply(r.rest(), x.rest(), y.rest(), alpha);
569 XASSERTM(r.
size() == this->rows(),
"Vector size of r does not match!");
570 XASSERTM(x.
size() == this->columns(),
"Vector size of x does not match!");
571 XASSERTM(y.
size() == this->rows(),
"Vector size of y does not match!");
582 first().apply(r_first, x_first, y_first, alpha);
583 rest().apply(r_rest, x_rest, y_rest, alpha);
604 first().apply_transposed(r.first(), x.first(), y.first(), alpha);
605 rest().apply_transposed(r.rest(), x.rest(), y.rest(), alpha);
611 XASSERTM(r.
size() == this->columns(),
"Vector size of r does not match!");
612 XASSERTM(x.
size() == this->rows(),
"Vector size of x does not match!");
613 XASSERTM(y.
size() == this->columns(),
"Vector size of y does not match!");
624 first().apply_transposed(r_first, x_first, y_first, alpha);
625 rest().apply_transposed(r_rest, x_rest, y_rest, alpha);
650 return (this->
name() == x.
name()) && (this->first().same_layout(x.first())) && (this->rest().same_layout(x.rest()));
667 first().scale_rows(a.first(), w.first());
668 rest().scale_rows(a.rest(), w.rest());
671 void scale_cols(
const PowerDiagMatrix& a,
const VectorTypeR& w)
673 first().scale_cols(a.first(), w.first());
674 rest().scale_cols(a.rest(), w.rest());
680 const Index brows(this->first().
template rows<Perspective::pod>());
684 return this->first().get_length_of_line(row);
688 return this->rest().get_length_of_line(row - brows);
695 const Index col_start,
const Index stride = 1)
const
697 const Index brows(this->first().
template rows<Perspective::pod>());
698 const Index bcolumns(this->first().
template columns<Perspective::pod>());
702 this->first().set_line(row, pval_set, pcol_set, col_start, stride);
706 this->rest().set_line(row - brows, pval_set, pcol_set, col_start + bcolumns, stride);
710 void set_line_reverse(
const Index row,
const DataType *
const pval_set,
const Index stride = 1)
712 const Index brows(this->first().
template rows<Perspective::pod>());
716 this->first().set_line_reverse(row, pval_set, stride);
720 this->
rest().set_line_reverse(row - brows, pval_set, stride);
726 const Index first_rows = first().template rows<Perspective::pod>();
728 return first().row_degree(row);
730 return rest().row_degree(row - first_rows);
733 template<
typename IT2_>
734 Index get_row_col_indices(
const Index row, IT2_*
const pcol_idx,
const IT2_ col_offset)
const
736 const Index first_rows = first().template rows<Perspective::pod>();
737 const Index first_cols = first().template columns<Perspective::pod>();
739 return first().get_row_col_indices(row, pcol_idx, col_offset);
741 return rest().get_row_col_indices(row - first_rows, pcol_idx, col_offset + IT2_(first_cols));
744 template<
typename DT2_>
745 Index get_row_values(
const Index row, DT2_ *
const pvals)
const
747 const Index first_rows = first().template rows<Perspective::pod>();
749 return first().get_row_values(row, pvals);
751 return rest().get_row_values(row - first_rows, pvals);
754 template<
typename DT2_>
755 Index set_row_values(
const Index row,
const DT2_ *
const pvals)
757 const Index first_rows = first().template rows<Perspective::pod>();
759 return first().set_row_values(row, pvals);
761 return rest().set_row_values(row - first_rows, pvals);
773 template <
typename SubType2_>
776 this->first().convert(other.first());
777 this->rest().convert(other.rest());
780 template <
typename SubType2_>
783 this->first().convert_reverse(other.first());
784 this->rest().convert_reverse(other.rest());
789 template<
typename SubType_>
790 class PowerDiagMatrix<SubType_, 1>
792 template<
typename,
int>
793 friend class PowerDiagMatrix;
797 typedef typename SubMatrixType::DataType
DataType;
798 typedef typename SubMatrixType::IndexType
IndexType;
802 typedef PowerVector<typename SubMatrixType::VectorTypeL, 1>
VectorTypeL;
804 typedef PowerVector<typename SubMatrixType::VectorTypeR, 1>
VectorTypeR;
806 template <
typename DT2_ = DataType,
typename IT2_ = IndexType>
807 using ContainerType = PowerDiagMatrix<typename SubType_::template ContainerType<DT2_, IT2_>, 1>;
810 template <
typename DataType2_,
typename IndexType2_>
821 _first(std::move(the_first))
832 explicit PowerDiagMatrix(
const SparseLayout<IndexType, layout_id>& layout) :
838 PowerDiagMatrix(PowerDiagMatrix&& other) :
844 PowerDiagMatrix&
operator=(PowerDiagMatrix&& other)
854 explicit PowerDiagMatrix(
FileMode mode,
const String& filename)
860 explicit PowerDiagMatrix(
FileMode mode, std::istream& file,
const String& directory =
"")
866 std::getline(file, line);
868 }
while (line.find(
"%%") == 0 || line ==
"");
871 _first = std::move(tmp_first);
877 auto found = filename.rfind(
"/");
878 if (found != std::string::npos)
880 directory = filename.substr(0, found + 1);
883 std::ifstream file(filename.c_str(), std::ifstream::in);
884 if (! file.is_open())
885 XABORTM(
"Unable to open Matrix file " + filename);
887 PowerDiagMatrix
other(mode, file, directory);
895 PowerDiagMatrix(
const PowerDiagMatrix&) =
delete;
897 PowerDiagMatrix&
operator=(
const PowerDiagMatrix&) =
delete;
906 std::ofstream file(filename.c_str(), std::ofstream::out);
907 if (! file.is_open())
908 XABORTM(
"Unable to open Matrix file " + filename);
910 String suffix, directory;
911 auto found = filename.rfind(
".");
912 if (found != std::string::npos)
914 suffix = filename.substr(found);
915 filename.erase(found);
917 found = filename.rfind(
"/");
918 if (found != std::string::npos)
920 directory = filename.substr(0, found + 1);
921 filename.erase(0, found + 1);
924 file <<
"%%MatrixMarket powerdiagmatrix coordinate real general\n";
925 file << filename <<
"_pd" << 1 << suffix <<
"\n";
934 _first.write_out(mode, directory + prefix +
"_pd" +
stringify(length) + suffix);
939 return PowerDiagMatrix(
_first.clone(mode));
944 (*this)=
other.clone(clone_mode);
948 std::size_t
bytes()
const
955 return PowerDiagMatrix(
_first.transpose());
958 template<
int i,
int j>
961 static_assert(i == 0,
"invalid sub-matrix index");
962 static_assert(j == 0,
"invalid sub-matrix index");
966 template<
int i,
int j>
969 static_assert(i == 0,
"invalid sub-matrix index");
970 static_assert(j == 0,
"invalid sub-matrix index");
976 XASSERTM((i == 0) && (j == 0),
"invalid sub-matrix index");
982 XASSERTM((i == 0) && (j == 0),
"invalid sub-matrix index");
989 return _first.get_checkpoint_size(config);
995 _first.restore_from_checkpoint_data(data);
1001 return _first.set_checkpoint_data(data, config);
1014 int row_blocks()
const
1019 int col_blocks()
const
1024 template <Perspective perspective_ = Perspective::native>
1027 return first().template rows<perspective_>();
1030 template <Perspective perspective_ = Perspective::native>
1033 return first().template columns<perspective_>();
1036 template <Perspective perspective_ = Perspective::native>
1039 return first().template used_elements<perspective_>();
1042 static String
name()
1044 return String(
"PowerDiagMatrix<") + SubMatrixType::name() +
"," +
stringify(1) +
">";
1047 template <Perspective perspective_ = Perspective::native>
1050 return rows<perspective_>() * columns<perspective_>();
1055 first().format(
value);
1065 first().extract_diag(diag.first());
1070 first().apply(r.first(), x.first());
1073 void apply(DenseVector<DataType, IndexType>& r,
const DenseVector<DataType, IndexType>& x)
const
1075 first().apply(r, x);
1080 first().apply(r.first(), x.first(), y.first(), alpha);
1083 void apply(DenseVector<DataType, IndexType>& r,
const DenseVector<DataType, IndexType>& x,
1084 const DenseVector<DataType, IndexType>& y,
DataType alpha =
DataType(1))
const
1086 first().apply(r, x, y, alpha);
1091 first().apply_transposed(r.first(), x.first());
1094 void apply_transposed(DenseVector<DataType, IndexType>& r,
const DenseVector<DataType, IndexType>& x)
const
1096 first().apply_transposed(r, x);
1101 first().apply_transposed(r.first(), x.first(), y.first(), alpha);
1104 void apply_transposed(DenseVector<DataType, IndexType>& r,
const DenseVector<DataType, IndexType>& x,
1105 const DenseVector<DataType, IndexType>& y,
DataType alpha =
DataType(1))
const
1107 first().apply_transposed(r, x, y, alpha);
1118 return first().max_rel_diff(x.first());
1133 void scale_rows(
const PowerDiagMatrix& a,
const VectorTypeL& w)
1135 first().scale_rows(a.first(), w.first());
1138 void scale_cols(
const PowerDiagMatrix& a,
const VectorTypeR& w)
1140 first().scale_cols(a.first(), w.first());
1146 return this->first().get_length_of_line(row);
1151 const Index col_start,
const Index stride = 1)
const
1153 this->first().set_line(row, pval_set, pcol_set, col_start, stride);
1156 void set_line_reverse(
const Index row,
const DataType *
const pval_set,
const Index stride = 1)
1158 this->first().set_line_reverse(row, pval_set, stride);
1163 return first().row_degree(row);
1166 template<
typename IT2_>
1167 Index get_row_col_indices(
const Index row, IT2_*
const pcol_idx,
const IT2_ col_offset)
const
1169 return first().get_row_col_indices(row, pcol_idx, col_offset);
1172 template<
typename DT2_>
1173 Index get_row_values(
const Index row, DT2_ *
const pvals)
const
1175 return first().get_row_values(row, pvals);
1178 template<
typename DT2_>
1179 Index set_row_values(
const Index row,
const DT2_ *
const pvals)
1181 return first().set_row_values(row, pvals);
1191 template <
typename SubType2_>
1192 void convert(
const PowerDiagMatrix<SubType2_, 1> & other)
1194 this->first().convert(
other.first());
1197 template <
typename SubType2_>
1198 void convert_reverse(PowerDiagMatrix<SubType2_, 1> & other)
const
1200 this->first().convert_reverse(
other.first());
1213 return (this->
name() == x.name()) && (this->first().same_layout(x.first()));
#define XABORTM(msg)
Abortion macro definition with custom message.
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Index size() const
Returns the containers size.
Dense data vector class template.
Power-Diag-Matrix meta class template.
PowerDiagMatrix(SubMatrixType &&the_first, RestClass &&the_rest)
base-class constructor; this one is protected for a reason
PowerDiagMatrix(FileMode mode, std::istream &file, String directory="")
Constructor.
SubMatrixType & at()
Returns a sub-matrix block.
SubMatrixType & get(int i, int j)
Returns a sub-matrix block.
PowerDiagMatrix(PowerDiagMatrix &&other)
move ctor
ContainerType< DataType2_, IndexType2_ > ContainerTypeByDI
this typedef lets you create a matrix container with different Data and Index types
PowerVector< typename SubMatrixType::VectorTypeL, blocks_ > VectorTypeL
Compatible L-vector type.
PowerVector< typename SubMatrixType::VectorTypeR, blocks_ > VectorTypeR
Compatible R-vector type.
PowerDiagMatrix clone(LAFEM::CloneMode mode=LAFEM::CloneMode::Weak) const
Creates and returns a deep copy of this matrix.
static constexpr SparseLayoutId layout_id
sub-matrix layout type
std::uint64_t set_checkpoint_data(std::vector< char > &data, SerialConfig &config)
PowerDiagMatrix & operator=(PowerDiagMatrix &&other)
move-assign operator
const SubMatrixType & at() const
Returns a sub-matrix block.
PowerDiagMatrix()
default ctor
void restore_from_checkpoint_data(std::vector< char > &data)
Extract object from checkpoint.
SubMatrixType::DataType DataType
sub-matrix data type
PowerDiagMatrix(const PowerDiagMatrix &)=delete
deleted copy-ctor
PowerDiagMatrix(FileMode mode, String filename)
Constructor.
bool same_layout(const PowerDiagMatrix &x) const
Checks if the structural layout of this matrix matches that of another matrix. This excludes comparis...
Index columns() const
Returns the total number of columns in this matrix.
PowerDiagMatrix transpose() const
Creates and returns the transpose of this matrix.
void write_out(FileMode mode, String filename) const
Write out matrix to file.
void clone(const PowerDiagMatrix &other, CloneMode clone_mode=CloneMode::Weak)
Clone operation.
Index rows() const
Returns the total number of rows in this matrix.
static String name()
Returns a descriptive string for this container.
void read_from(FileMode mode, String filename)
Read in matrix from file.
void apply(VectorTypeL &r, const VectorTypeR &x) const
Applies this matrix onto a vector.
SubMatrixType::IndexType IndexType
sub-matrix index type
SubMatrixType _first
the first sub-matrix
std::size_t bytes() const
Returns the total amount of bytes allocated.
std::uint64_t get_checkpoint_size(SerialConfig &config)
Calculate size.
PowerDiagMatrix< SubType_, blocks_-1 > RestClass
rest-class typedef
VectorTypeL create_vector_l() const
Returns a new compatible L-Vector.
PowerDiagMatrix< typename SubType_::template ContainerType< DT2_, IT2_ >, blocks_ > ContainerType
Our 'base' class type.
void write_out_submatrices(FileMode mode, String directory, String prefix, String suffix, Index length=blocks_) const
Write out submatrices to file.
PowerDiagMatrix(const SparseLayout< IndexType, layout_id > &layout)
sub-matrix layout ctor
static constexpr int num_col_blocks
number of column blocks (horizontal size)
void apply(VectorTypeL &r, const VectorTypeR &x, const VectorTypeL &y, DataType alpha=DataType(1)) const
Applies this matrix onto a vector.
void convert(const PowerDiagMatrix< SubType2_, blocks_ > &other)
Conversion method.
SubType_ SubMatrixType
sub-matrix type
const SubMatrixType & get(int i, int j) const
Returns a sub-matrix block.
Index get_length_of_line(const Index row) const
Returns the number of NNZ-elements of the selected row.
void format(DataType value=DataType(0))
Reset all elements of the container to a given value or zero if missing.
void apply_transposed(VectorTypeR &r, const VectorTypeL &x, const VectorTypeR &y, DataType alpha=DataType(1)) const
Applies this matrix onto a vector.
DataType max_rel_diff(const PowerDiagMatrix &x) const
Retrieve the maximum relative difference of this matrix and another one y.max_rel_diff(x) returns .
static constexpr int num_row_blocks
number of row blocks (vertical size)
void clear()
Free all allocated arrays.
VectorTypeR create_vector_r() const
Returns a new compatible R-Vector.
virtual ~PowerDiagMatrix()
virtual destructor
RestClass _rest
the remaining part
void apply_transposed(VectorTypeR &r, const VectorTypeL &x) const
Applies this matrix onto a vector.
void extract_diag(VectorTypeL &diag) const
extract main diagonal vector from matrix
Index used_elements() const
Returns the total number of non-zeros in this matrix.
PowerDiagMatrix & operator=(const PowerDiagMatrix &)=delete
deleted copy-assign operator
Power-Vector meta class template.
Config class for serialize parameter.
Layout scheme for sparse matrix containers.
String class implementation.
String & trim_me(const String &charset)
Trims this string.
@ other
generic/other permutation strategy
T_ max(T_ a, T_ b)
Returns the maximum of two values.
@ rest
restriction (multigrid)
String stringify(const T_ &item)
Converts an item into a String.
@ value
specifies whether the space should supply basis function values
std::uint64_t Index
Index data type.
Power container element helper class template.