11#include <kernel/util/math.hpp> 
   12#include <kernel/lafem/forward.hpp> 
   13#include <kernel/lafem/container.hpp> 
   14#include <kernel/lafem/dense_vector.hpp> 
   15#include <kernel/lafem/sparse_layout.hpp> 
   16#include <kernel/lafem/arch/scale.hpp> 
   17#include <kernel/lafem/arch/axpy.hpp> 
   18#include <kernel/lafem/arch/apply.hpp> 
   19#include <kernel/lafem/arch/norm.hpp> 
   20#include <kernel/adjacency/graph.hpp> 
   75    template <
typename DT_, 
typename IT_ = Index>
 
   89        typedef IT_ IndexType;
 
   97        Index _num_of_offsets;
 
  107          _num_rows(matrix.
rows()),
 
  115          _col_ptr = 
new IT_[_num_cols];
 
  117          for(
Index i(0); i < _num_cols; ++i)
 
  119            _col_ptr[i] = _deadcode;
 
  126          if(_col_ptr != 
nullptr)
 
  132        template<
typename LocalMatrix_, 
typename RowMapping_, 
typename ColMapping_>
 
  133        void operator()(
const LocalMatrix_& loc_mat, 
const RowMapping_& row_map,
 
  134                        const ColMapping_& col_map, DT_ alpha = DT_(1))
 
  137          for(
int i(0); i < row_map.get_num_local_dofs(); ++i)
 
  140            const Index ix = row_map.get_index(i);
 
  143            for(IT_ k(0); k < _num_of_offsets; ++k)
 
  145              if(_offsets[k] + ix + 1 >= _num_rows && _offsets[k] + ix + 1 < 2 * _num_rows)
 
  147                _col_ptr[_offsets[k] + ix + 1 - _num_rows] = IT_(k * _num_rows + ix);
 
  152            for(
int j(0); j < col_map.get_num_local_dofs(); ++j)
 
  155              const Index jx = col_map.get_index(j);
 
  158              ASSERTM(_col_ptr[jx] != _deadcode, 
"invalid column index");
 
  161              _data[_col_ptr[jx]] += alpha * loc_mat[i][j];
 
  168            for(IT_ k(0); k < _num_of_offsets; ++k)
 
  170              if(_offsets[k] + ix + 1 >= _num_rows && _offsets[k] + ix + 1 < 2 * _num_rows)
 
  172                _col_ptr[_offsets[k] + ix + 1 - _num_rows] = _deadcode;
 
  190        typedef DT_ DataType;
 
  191        typedef IT_ IndexType;
 
  199        Index _num_of_offsets;
 
  209          _num_rows(matrix.
rows()),
 
  217          _col_ptr = 
new IT_[_num_cols];
 
  219          for(
Index i(0); i < _num_cols; ++i)
 
  221            _col_ptr[i] = _deadcode;
 
  228          if(_col_ptr != 
nullptr)
 
  234        template<
typename LocalMatrix_, 
typename RowMapping_, 
typename ColMapping_>
 
  235        void operator()(LocalMatrix_& loc_mat, 
const RowMapping_& row_map,
 
  236                        const ColMapping_& col_map, DT_ alpha = DT_(1))
 
  239          for(
int i(0); i < row_map.get_num_local_dofs(); ++i)
 
  242            const Index ix = row_map.get_index(i);
 
  245            for(IT_ k(0); k < _num_of_offsets; ++k)
 
  247              if(_offsets[k] + ix + 1 >= _num_rows && _offsets[k] + ix + 1 < 2 * _num_rows)
 
  249                _col_ptr[_offsets[k] + ix + 1 - _num_rows] = IT_(k * _num_rows + ix);
 
  254            for(
int j(0); j < col_map.get_num_local_dofs(); ++j)
 
  257              const Index jx = col_map.get_index(j);
 
  260              ASSERTM(_col_ptr[jx] != _deadcode, 
"invalid column index");
 
  263              loc_mat[i][j] += alpha * _data[_col_ptr[jx]];
 
  270            for(IT_ k(0); k < _num_of_offsets; ++k)
 
  272              if(_offsets[k] + ix + 1 >= _num_rows && _offsets[k] + ix + 1 < 2 * _num_rows)
 
  274                _col_ptr[_offsets[k] + ix + 1 - _num_rows] = _deadcode;
 
  299      Index & _used_elements()
 
  304      Index & _num_of_offsets()
 
  328        const IT_ * 
const _offsets;
 
  331        ImageIterator() : _k(IT_(0)), _s(IT_(0)), _offsets(
nullptr) {}
 
  339          _offsets = other._offsets;
 
  345          return this->_k != other._k;
 
  354        Index operator*()
 const 
  356          return Index(_s + _offsets[_k]);
 
  360      template <
typename DT2_ = DT_, 
typename IT2_ = IT_>
 
  364      template <
typename DataType2_, 
typename IndexType2_>
 
  391        this->
_indices.assign(layout_in._indices.begin(), layout_in._indices.end());
 
  392        this->
_indices_size.assign(layout_in._indices_size.begin(), layout_in._indices_size.end());
 
  393        this->
_scalar_index.assign(layout_in._scalar_index.begin(), layout_in._scalar_index.end());
 
  415        Container<DT_, IT_>(rows_in * columns_in)
 
  417        if (val_in.
size() != rows_in * offsets_in.
size())
 
  419          XABORTM(
"Size of values does not match to number of offsets and row count!");
 
  425        Index tused_elements(0);
 
  427        for (
Index i(0); i < offsets_in.
size(); ++i)
 
  431          if (toffset + 
Index(2) > rows_in + columns_in)
 
  433            XABORTM(
"Offset out of matrix!");
 
  436          tused_elements += columns_in + 
Math::min(rows_in, columns_in + rows_in - toffset - 1) - 
Math::max(columns_in + rows_in - toffset - 1, columns_in);
 
  460      template <
typename MT_>
 
  477        Index num_rows = graph.get_num_nodes_domain();
 
  478        Index num_cols = graph.get_num_nodes_image();
 
  483        std::set<IT_> moffsets;
 
  485        for(
Index row(0); row < num_rows; ++row)
 
  487          for(
Index j(dom_ptr[row]); j < dom_ptr[row+1]; ++j)
 
  489            moffsets.insert(IT_(num_rows - 1 + img_idx[j] - row));
 
  494        auto * ptoffsets = toffsets.
elements();
 
  497        for (
auto off : moffsets)
 
  499          ptoffsets[idx] = off;
 
  504        toffsets_mem.
convert(toffsets);
 
  545      template <
typename DT2_ = DT_, 
typename IT2_ = IT_>
 
  549        deserialize<DT2_, IT2_>(input);
 
  573        this->
move(std::forward<SparseMatrixBanded>(other));
 
  589        t.
clone(*
this, clone_mode);
 
  601      template<
typename DT2_, 
typename IT2_>
 
  627        this->
_indices.assign(layout_in._indices.begin(), layout_in._indices.end());
 
  628        this->
_indices_size.assign(layout_in._indices_size.begin(), layout_in._indices_size.end());
 
  629        this->
_scalar_index.assign(layout_in._scalar_index.begin(), layout_in._scalar_index.end());
 
  647      template <
typename DT2_, 
typename IT2_>
 
  653      template <
typename DT2_, 
typename IT2_>
 
  656        XASSERT(csr.template used_elements<Perspective::pod>() > 0);
 
  658        std::set<IT_> offset_set;
 
  661        for (
Index row(0) ; row < nrows ; ++row)
 
  666            IT_ off = IT_(csr.
col_ind()[i] - row + nrows - 1);
 
  667            offset_set.insert(off);
 
  671        DenseVector<DT_, IT_> val_new(
Index(offset_set.size()) * nrows, DT_(0));
 
  672        for (
Index row(0) ; row < nrows ; ++row)
 
  677            Index offset = (col - row + nrows - 1);
 
  678            Index band = 
Index(std::distance(offset_set.begin(), offset_set.find(IT_(offset))));
 
  679            val_new.elements()[band * nrows + row] = csr.
val()[i];
 
  683        DenseVector<IT_, IT_> offsets_new(
Index(offset_set.size()));
 
  684        auto it_offset = offset_set.begin();
 
  685        for (
Index i(0) ; i < offset_set.size() ; ++i, ++it_offset)
 
  687          offsets_new(i, *it_offset);
 
  691        SparseMatrixBanded<DT_, IT_> temp(nrows, ncolumns, val_new, offsets_new);
 
  692        this->
move(std::move(temp));
 
  704        std::ios_base::openmode bin = std::ofstream::out | std::ofstream::binary;
 
  706          bin = std::ofstream::out;
 
  708        char* buff = 
nullptr;
 
  714        file.open(filename.c_str(), bin);
 
  716          XABORTM(
"Unable to open Matrix file " + filename);
 
  733          if (! std::is_same<DT_, double>::value)
 
  734            std::cout<<
"Warning: You are writing out a banded matrix that is not double precision!\n";
 
  736        this->
template _serialize<double, std::uint64_t>(
FileMode::fm_bm, file);
 
  739          XABORTM(
"Filemode not supported!");
 
  756        MemoryPool::synchronize();
 
  763          if (row + toffset + 
Index(1) == col + trows)
 
  765            return this->
val()[i * trows + row];
 
  786      template <Perspective = Perspective::native>
 
  797      template <Perspective = Perspective::native>
 
  808      template <Perspective = Perspective::native>
 
  834      DT_ 
const * 
val()
 const 
  861        return "SparseMatrixBanded";
 
  872        this->_copy_content(x, full);
 
  886                const DT_ alpha = DT_(1))
 
  888        XASSERTM(x.
rows() == this->rows(), 
"Matrix rows do not match!");
 
  889        XASSERTM(x.
columns() == this->columns(), 
"Matrix columns do not match!");
 
  896        Arch::Axpy::value(this->
val(), alpha, x.
val(), this->rows() * this->num_of_offsets());
 
  899        Statistics::add_time_axpy(ts_stop.
elapsed(ts_start));
 
  910        XASSERTM(x.
rows() == this->rows(), 
"Matrix rows do not match!");
 
  911        XASSERTM(x.
columns() == this->columns(), 
"Matrix columns do not match!");
 
  918        Arch::Scale::value(this->
val(), x.
val(), alpha, this->rows() * this->num_of_offsets());
 
  921        Statistics::add_time_axpy(ts_stop.
elapsed(ts_start));
 
  939        Statistics::add_time_reduction(ts_stop.
elapsed(ts_start));
 
  952        XASSERTM(r.
size() == this->rows(), 
"Vector size of r does not match!");
 
  953        XASSERTM(x.
size() == this->columns(), 
"Vector size of x does not match!");
 
  955        XASSERTM(r.template elements<Perspective::pod>() != x.template elements<Perspective::pod>(), 
"Vector x and r must not share the same memory!");
 
  967            this->num_of_offsets(),
 
  972        Statistics::add_time_blas2(ts_stop.
elapsed(ts_start));
 
  983        XASSERTM(r.
size() == this->columns(), 
"Vector size of r does not match!");
 
  984        XASSERTM(x.
size() == this->rows(), 
"Vector size of x does not match!");
 
  986        XASSERTM(r.template elements<Perspective::pod>() != x.template elements<Perspective::pod>(), 
"Vector x and r must not share the same memory!");
 
  991        Arch::Apply::banded_transposed(r.
elements(),
 
  998          this->num_of_offsets(),
 
 1003        Statistics::add_time_blas2(ts_stop.
elapsed(ts_start));
 
 1017                 const DT_ alpha = DT_(1))
 const 
 1019        XASSERTM(r.
size() == this->rows(), 
"Vector size of r does not match!");
 
 1020        XASSERTM(x.
size() == this->columns(), 
"Vector size of x does not match!");
 
 1021        XASSERTM(y.
size() == this->rows(), 
"Vector size of y does not match!");
 
 1023        XASSERTM(r.template elements<Perspective::pod>() != x.template elements<Perspective::pod>(), 
"Vector x and r must not share the same memory!");
 
 1042            this->num_of_offsets(),
 
 1047        Statistics::add_time_blas2(ts_stop.
elapsed(ts_start));
 
 1061        const DT_ alpha = DT_(1))
 const 
 1063        XASSERTM(r.
size() == this->columns(), 
"Vector size of r does not match!");
 
 1064        XASSERTM(x.
size() == this->rows(), 
"Vector size of x does not match!");
 
 1065        XASSERTM(y.
size() == this->columns(), 
"Vector size of y does not match!");
 
 1067        XASSERTM(r.template elements<Perspective::pod>() != x.template elements<Perspective::pod>(), 
"Vector x and r must not share the same memory!");
 
 1079        Arch::Apply::banded_transposed(r.
elements(),
 
 1086          this->num_of_offsets(),
 
 1091        Statistics::add_time_blas2(ts_stop.
elapsed(ts_start));
 
 1098        XASSERTM(diag.
size() == 
rows(), 
"diag size does not match matrix row count!");
 
 1126      template <
typename DT2_ = DT_, 
typename IT2_ = IT_>
 
 1146        Statistics::add_time_reduction(ts_stop.
elapsed(ts_start));
 
 1161        if(this->
size() == 0 && x.
size() == 0 && this->get_elements().size() == 0 && this->get_indices().size() == 0 && x.
get_elements().size() == 0 && x.
get_indices().size() == 0)
 
 1175        offsets_a = 
const_cast<IT_*
>(this->
offsets());
 
 1176        offsets_b = 
const_cast<IT_*
>(x.
offsets());
 
 1182          if (offsets_a[i] != offsets_b[i])
 
 1203      template <
typename DT2_ = DT_, 
typename IT2_ = IT_>
 
 1206        return this->
template _serialize<DT2_, IT2_>(
FileMode::fm_bm, config);
 
 1217        std::ios_base::openmode bin = std::ifstream::in | std::ifstream::binary;
 
 1219          bin = std::ifstream::in;
 
 1220        std::ifstream file(filename.c_str(), bin);
 
 1221        if (! file.is_open())
 
 1222          XABORTM(
"Unable to open Matrix file " + filename);
 
 1238          this->
template _deserialize<double, std::uint64_t>(
FileMode::fm_bm, file);
 
 1241          XABORTM(
"Filemode not supported!");
 
 1258      template <
typename ITX_>
 
 1277      template <
typename ITX_>
 
 1281        if (i == 
Index (-1))
 
 1328        const IT_ * toffsets(
offsets());
 
 1332        for(IT_ k(0); k < tnum_of_offsets; ++k)
 
 1334          if(toffsets[k] + domain_node + 1 >= trows)
 
 1344        const IT_ * toffsets(
offsets());
 
 1348        for(IT_ k(0); k < tnum_of_offsets; ++k)
 
 1350          if(toffsets[k] + domain_node + 1 >= 2 * trows)
 
 1355        return ImageIterator(tnum_of_offsets, domain_node + 1 - trows, toffsets);
 
#define ASSERT(expr)
Debug-Assertion macro definition.
#define XABORTM(msg)
Abortion macro definition with custom message.
#define ASSERTM(expr, msg)
Debug-Assertion macro definition with custom message.
#define XASSERT(expr)
Assertion macro definition.
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Adjacency Graph implementation.
Index * get_domain_ptr()
Returns the domain pointer array.
Index * get_image_idx()
Returns the image node index array.
const std::vector< IT_ * > & get_indices() const
Returns a list of all Index arrays.
std::vector< DT_ * > _elements
List of pointers to all datatype dependent arrays.
const std::vector< DT_ * > & get_elements() const
Returns a list of all data arrays.
std::vector< Index > _elements_size
List of corresponding datatype array sizes.
Index size() const
Returns the containers size.
void assign(const Container< DT2_, IT2_ > &other)
Assignment operation.
std::vector< IT_ * > _indices
List of pointers to all IT_ dependent arrays.
void clone(const Container &other, CloneMode clone_mode=CloneMode::Weak)
Clone operation.
void move(Container &&other)
Assignment move operation.
std::vector< Index > _indices_size
List of corresponding IT_ array sizes.
std::vector< Index > _scalar_index
List of scalars with datatype index.
Dense data vector class template.
void convert(const DenseVector< DT2_, IT2_ > &other)
Conversion method.
DT_ * elements()
Get a pointer to the data array.
void copy(const VT_ &a)
Performs .
Config class for serialize parameter.
Layout scheme for sparse matrix containers.
Gather-Axpy operation for SparseMatrixBanded.
ImageIterator class for Adjactor interface implementation.
Scatter-Axpy operation for SparseMatrixBanded.
void extract_diag(VectorTypeL &diag) const
SparseMatrixBanded clone(CloneMode clone_mode=CloneMode::Weak) const
Clone operation.
SparseMatrixBanded & operator=(SparseMatrixBanded &&other)
Move operator.
void read_from(FileMode mode, std::istream &file)
Read in matrix from stream.
friend std::ostream & operator<<(std::ostream &lhs, const SparseMatrixBanded &b)
SparseMatrixBanded streaming operator.
void apply(DenseVector< DT_, IT_ > &r, const DenseVector< DT_, IT_ > &x) const
Calculate .
DT_ ValueType
our value type
void convert(const SparseMatrixBanded< DT2_, IT2_ > &other)
Conversion method.
Index rows() const
Retrieve matrix row count.
bool same_layout(const SparseMatrixBanded &x) const
Checks if the structural layout of this matrix matches that of another matrix. This excludes comparis...
SparseMatrixBanded(const SparseLayout< IT_, layout_id > &layout_in)
Constructor.
void copy(const SparseMatrixBanded &x, bool full=false)
Performs .
DT_ DataType
Our datatype.
SparseLayout< IT_, layout_id > layout() const
Retrieve convenient sparse matrix layout object.
DenseVector< DataType, IT_ > VectorTypeR
Compatible R-vector type.
SparseMatrixBanded(const Index rows_in, const Index columns_in, DenseVector< DT_, IT_ > &val_in, DenseVector< IT_, IT_ > &offsets_in)
Constructor.
void deserialize(std::vector< char > input)
Deserialization of complete container entity.
IT_ * offsets()
Retrieve offsets array.
Index start_offset(const Index i) const
Returns first row-index of the diagonal matching to the offset i.
IT_ IndexType
Our indextype.
void write_out(FileMode mode, const String &filename) const
Write out matrix to file.
Index used_elements() const
Retrieve non zero element count.
static constexpr SparseLayoutId layout_id
Our used layout type.
SparseMatrixBanded(FileMode mode, String filename)
Constructor.
Index end_offset(const Index i) const
Returns last row-index of the diagonal matching to the offset i.
void apply_transposed(DenseVector< DT_, IT_ > &r, const DenseVector< DT_, IT_ > &x) const
Calculate .
DT_ * val()
Retrieve element array.
Index _start_offset(const Index i, const ITX_ *const offsets, const Index rows_in, const Index columns_in, const Index noo) const
Returns first row-index of the diagonal matching to the offset i.
VectorTypeL extract_diag() const
extract main diagonal vector from matrix
DT_ operator()(Index row, Index col) const
Retrieve specific matrix element.
DenseVector< DataType, IT_ > VectorTypeL
Compatible L-vector type.
void read_from(FileMode mode, const String &filename)
Read in matrix from file.
DT_ max_rel_diff(const SparseMatrixBanded &x) const
Retrieve the maximum relative difference of this matrix and another one y.max_rel_diff(x) returns .
Index num_of_offsets() const
Retrieve number of offsets.
Index get_num_nodes_image() const
SparseMatrixBanded(FileMode mode, std::istream &file)
Constructor.
Index _end_offset(const Index i, const ITX_ *const offsets, const Index rows_in, const Index columns_in, const Index noo) const
Returns last row-index of the diagonal matching to the offset i.
void write_out(FileMode mode, std::ostream &file) const
Write out matrix to file.
SparseMatrixBanded(const Adjacency::Graph &graph)
Constructor.
DT_ norm_frobenius() const
Calculates the Frobenius norm of this matrix.
void clone(const SparseMatrixBanded< DT2_, IT2_ > &other, CloneMode clone_mode=CloneMode::Weak)
Clone operation.
std::vector< char > serialize(const LAFEM::SerialConfig &config=SerialConfig()) const
Serialization of complete container entity.
VectorTypeL create_vector_l() const
Returns a new compatible L-Vector.
ImageIterator image_begin(Index domain_node) const
SparseMatrixBanded()
Constructor.
Index get_num_nodes_domain() const
VectorTypeR create_vector_r() const
Returns a new compatible R-Vector.
ImageIterator image_end(Index domain_node) const
void apply(DenseVector< DT_, IT_ > &r, const DenseVector< DT_, IT_ > &x, const DenseVector< DT_, IT_ > &y, const DT_ alpha=DT_(1)) const
Calculate .
SparseMatrixBanded(std::vector< char > input)
Constructor.
void axpy(const SparseMatrixBanded &x, const DT_ alpha=DT_(1))
Calculate .
SparseMatrixBanded(const MT_ &other)
Constructor.
void scale(const SparseMatrixBanded &x, const DT_ alpha)
Calculate .
SparseMatrixBanded(SparseMatrixBanded &&other)
Move Constructor.
Index columns() const
Retrieve matrix column count.
void apply_transposed(DenseVector< DT_, IT_ > &r, const DenseVector< DT_, IT_ > &x, const DenseVector< DT_, IT_ > &y, const DT_ alpha=DT_(1)) const
Calculate .
static String name()
Returns a descriptive string.
IT_ * col_ind()
Retrieve column indices array.
DT_ * val()
Retrieve non zero element array.
Index rows() const
Retrieve matrix row count.
Index columns() const
Retrieve matrix column count.
IT_ * row_ptr()
Retrieve row start index array.
static void copy(DT_ *dest, const DT_ *src, const Index count)
Copy memory area from src to dest.
static void release_memory(void *address)
release memory or decrease reference counter
static void increase_memory(void *address)
increase memory counter
static void add_flops(Index flops)
Add an amount of flops to the global flop counter.
String class implementation.
double elapsed(const TimeStamp &before) const
Calculates the time elapsed between two time stamps.
constexpr std::size_t FileOutStreamBufferSize
OutStreamBufferSize.
T_ abs(T_ x)
Returns the absolute value.
T_ min(T_ a, T_ b)
Returns the minimum of two values.
T_ max(T_ a, T_ b)
Returns the maximum of two values.
String stringify(const T_ &item)
Converts an item into a String.
std::uint64_t Index
Index data type.