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);
732 template <
typename SubType2_>
735 this->first().convert(other.first());
736 this->rest().convert(other.rest());
739 template <
typename SubType2_>
742 this->first().convert_reverse(other.first());
743 this->rest().convert_reverse(other.rest());
748 template<
typename SubType_>
749 class PowerDiagMatrix<SubType_, 1>
751 template<
typename,
int>
752 friend class PowerDiagMatrix;
756 typedef typename SubMatrixType::DataType
DataType;
757 typedef typename SubMatrixType::IndexType
IndexType;
761 typedef PowerVector<typename SubMatrixType::VectorTypeL, 1>
VectorTypeL;
763 typedef PowerVector<typename SubMatrixType::VectorTypeR, 1>
VectorTypeR;
765 template <
typename DT2_ = DataType,
typename IT2_ = IndexType>
766 using ContainerType = PowerDiagMatrix<typename SubType_::template ContainerType<DT2_, IT2_>, 1>;
769 template <
typename DataType2_,
typename IndexType2_>
780 _first(std::move(the_first))
791 explicit PowerDiagMatrix(
const SparseLayout<IndexType, layout_id>& layout) :
797 PowerDiagMatrix(PowerDiagMatrix&& other) :
803 PowerDiagMatrix&
operator=(PowerDiagMatrix&& other)
813 explicit PowerDiagMatrix(
FileMode mode,
const String& filename)
819 explicit PowerDiagMatrix(
FileMode mode, std::istream& file,
const String& directory =
"")
825 std::getline(file, line);
827 }
while (line.find(
"%%") == 0 || line ==
"");
830 _first = std::move(tmp_first);
836 auto found = filename.rfind(
"/");
837 if (found != std::string::npos)
839 directory = filename.substr(0, found + 1);
842 std::ifstream file(filename.c_str(), std::ifstream::in);
843 if (! file.is_open())
844 XABORTM(
"Unable to open Matrix file " + filename);
846 PowerDiagMatrix
other(mode, file, directory);
854 PowerDiagMatrix(
const PowerDiagMatrix&) =
delete;
856 PowerDiagMatrix&
operator=(
const PowerDiagMatrix&) =
delete;
865 std::ofstream file(filename.c_str(), std::ofstream::out);
866 if (! file.is_open())
867 XABORTM(
"Unable to open Matrix file " + filename);
869 String suffix, directory;
870 auto found = filename.rfind(
".");
871 if (found != std::string::npos)
873 suffix = filename.substr(found);
874 filename.erase(found);
876 found = filename.rfind(
"/");
877 if (found != std::string::npos)
879 directory = filename.substr(0, found + 1);
880 filename.erase(0, found + 1);
883 file <<
"%%MatrixMarket powerdiagmatrix coordinate real general\n";
884 file << filename <<
"_pd" << 1 << suffix <<
"\n";
893 _first.write_out(mode, directory + prefix +
"_pd" +
stringify(length) + suffix);
898 return PowerDiagMatrix(
_first.clone(mode));
903 (*this)=
other.clone(clone_mode);
907 std::size_t
bytes()
const
914 return PowerDiagMatrix(
_first.transpose());
917 template<
int i,
int j>
920 static_assert(i == 0,
"invalid sub-matrix index");
921 static_assert(j == 0,
"invalid sub-matrix index");
925 template<
int i,
int j>
928 static_assert(i == 0,
"invalid sub-matrix index");
929 static_assert(j == 0,
"invalid sub-matrix index");
935 XASSERTM((i == 0) && (j == 0),
"invalid sub-matrix index");
941 XASSERTM((i == 0) && (j == 0),
"invalid sub-matrix index");
948 return _first.get_checkpoint_size(config);
954 _first.restore_from_checkpoint_data(data);
960 return _first.set_checkpoint_data(data, config);
973 int row_blocks()
const
978 int col_blocks()
const
983 template <Perspective perspective_ = Perspective::native>
986 return first().template rows<perspective_>();
989 template <Perspective perspective_ = Perspective::native>
992 return first().template columns<perspective_>();
995 template <Perspective perspective_ = Perspective::native>
998 return first().template used_elements<perspective_>();
1001 static String
name()
1003 return String(
"PowerDiagMatrix<") + SubMatrixType::name() +
"," +
stringify(1) +
">";
1006 template <Perspective perspective_ = Perspective::native>
1009 return rows<perspective_>() * columns<perspective_>();
1014 first().format(
value);
1024 first().extract_diag(diag.first());
1029 first().apply(r.first(), x.first());
1032 void apply(DenseVector<DataType, IndexType>& r,
const DenseVector<DataType, IndexType>& x)
const
1034 first().apply(r, x);
1039 first().apply(r.first(), x.first(), y.first(), alpha);
1042 void apply(DenseVector<DataType, IndexType>& r,
const DenseVector<DataType, IndexType>& x,
1043 const DenseVector<DataType, IndexType>& y,
DataType alpha =
DataType(1))
const
1045 first().apply(r, x, y, alpha);
1050 first().apply_transposed(r.first(), x.first());
1053 void apply_transposed(DenseVector<DataType, IndexType>& r,
const DenseVector<DataType, IndexType>& x)
const
1055 first().apply_transposed(r, x);
1060 first().apply_transposed(r.first(), x.first(), y.first(), alpha);
1063 void apply_transposed(DenseVector<DataType, IndexType>& r,
const DenseVector<DataType, IndexType>& x,
1064 const DenseVector<DataType, IndexType>& y,
DataType alpha =
DataType(1))
const
1066 first().apply_transposed(r, x, y, alpha);
1077 return first().max_rel_diff(x.first());
1092 void scale_rows(
const PowerDiagMatrix& a,
const VectorTypeL& w)
1094 first().scale_rows(a.first(), w.first());
1097 void scale_cols(
const PowerDiagMatrix& a,
const VectorTypeR& w)
1099 first().scale_cols(a.first(), w.first());
1105 return this->first().get_length_of_line(row);
1110 const Index col_start,
const Index stride = 1)
const
1112 this->first().set_line(row, pval_set, pcol_set, col_start, stride);
1115 void set_line_reverse(
const Index row,
const DataType *
const pval_set,
const Index stride = 1)
1117 this->first().set_line_reverse(row, pval_set, stride);
1127 template <
typename SubType2_>
1128 void convert(
const PowerDiagMatrix<SubType2_, 1> & other)
1130 this->first().convert(
other.first());
1133 template <
typename SubType2_>
1134 void convert_reverse(PowerDiagMatrix<SubType2_, 1> & other)
const
1136 this->first().convert_reverse(
other.first());
1149 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.