17 #include <deal.II/base/std_cxx14/memory.h> 18 #include <deal.II/base/utilities.h> 19 #include <deal.II/base/vector_slice.h> 21 #include <deal.II/lac/dynamic_sparsity_pattern.h> 22 #include <deal.II/lac/full_matrix.h> 23 #include <deal.II/lac/sparsity_pattern.h> 24 #include <deal.II/lac/sparsity_tools.h> 33 DEAL_II_NAMESPACE_OPEN
48 , store_diagonal_first_in_row(false)
67 "This constructor can only be called if the provided argument " 68 "is the sparsity pattern for an empty matrix. This constructor can " 69 "not be used to copy-construct a non-empty sparsity pattern."));
78 const unsigned int max_per_row)
93 const std::vector<unsigned int> &row_lengths)
100 reinit(m, n, row_lengths);
106 const unsigned int max_per_row)
112 reinit(m, m, max_per_row);
118 const std::vector<unsigned int> &row_lengths)
124 reinit(m, m, row_lengths);
130 const unsigned int max_per_row,
155 const size_type *
const original_row_start =
159 const size_type *
const original_row_end =
165 const size_type *
const original_last_before_side_diagonals =
166 (row > extra_off_diagonals ?
169 row - extra_off_diagonals) :
172 const size_type *
const original_first_after_side_diagonals =
173 (row <
rows - extra_off_diagonals - 1 ?
174 std::upper_bound(original_row_start,
176 row + extra_off_diagonals) :
184 next_free_slot = std::copy(original_row_start,
185 original_last_before_side_diagonals,
189 for (
size_type i = 1; i <= std::min(row, extra_off_diagonals);
190 ++i, ++next_free_slot)
191 *next_free_slot = row - i;
192 for (
size_type i = 1; i <= std::min(extra_off_diagonals,
rows - row - 1);
193 ++i, ++next_free_slot)
194 *next_free_slot = row + i;
197 next_free_slot = std::copy(original_first_after_side_diagonals,
217 "This operator can only be called if the provided argument " 218 "is the sparsity pattern for an empty matrix. This operator can " 219 "not be used to copy a non-empty sparsity pattern."));
222 ExcMessage(
"This operator can only be called if the current object is " 233 const unsigned int max_per_row)
236 const std::vector<unsigned int> row_lengths(m, max_per_row);
237 reinit(m, n, row_lengths);
246 const VectorSlice<
const std::vector<unsigned int>> &row_lengths)
254 if ((m == 0) || (n == 0))
279 std::size_t vec_len = 0;
282 std::max(row_lengths[i], 1U) :
297 (row_lengths.size() == 0 ?
299 std::min(static_cast<size_type>(
300 *std::max_element(row_lengths.begin(), row_lengths.end())),
331 std::max(std::min(static_cast<size_type>(row_lengths[i - 1]), n),
332 static_cast<size_type>(1U)) :
333 std::min(static_cast<size_type>(row_lengths[i - 1]), n));
334 Assert((rowstart[rows] == vec_len) ||
335 ((vec_len == 1) && (rowstart[rows] == 0)),
370 const std::size_t nonzero_elements =
373 std::bind(std::not_equal_to<size_type>(),
374 std::placeholders::_1,
377 std::unique_ptr<size_type[]> new_colnums(
new size_type[nonzero_elements]);
388 for (
size_type j = rowstart[line]; j < rowstart[line + 1];
407 new_colnums[next_free_entry++] = tmp_entries[j];
410 rowstart[line] = next_row_start;
411 next_row_start = next_free_entry;
420 (row_length != 0 && new_colnums[rowstart[line]] == line),
427 Assert((rowstart[line] == next_row_start) ||
428 (std::find(&new_colnums[rowstart[line] + 1],
429 &new_colnums[next_row_start],
430 new_colnums[rowstart[line]]) ==
431 &new_colnums[next_row_start]),
433 Assert((rowstart[line] == next_row_start) ||
434 (std::adjacent_find(&new_colnums[rowstart[line] + 1],
435 &new_colnums[next_row_start]) ==
436 &new_colnums[next_row_start]),
444 rowstart[
rows] = next_row_start;
448 colnums = std::move(new_colnums);
465 const bool do_diag_optimize = (sp.
n_rows() == sp.
n_cols());
466 std::vector<unsigned int> row_lengths(sp.
n_rows());
470 if (do_diag_optimize && !sp.
exists(i, i))
483 end_row = sp.
end(row);
485 for (; col_num != end_row; ++col_num)
488 if ((col != row) || !do_diag_optimize)
509 const bool do_diag_optimize = (dsp.
n_rows() == dsp.
n_cols());
510 std::vector<unsigned int> row_lengths(dsp.
n_rows());
514 if (do_diag_optimize && !dsp.
exists(i, i))
524 for (
unsigned int index = 0; index <
row_length; ++index)
527 if ((col != row) || !do_diag_optimize)
540 template <
typename number>
547 const bool matrix_is_square = (matrix.
m() == matrix.
n());
549 std::vector<unsigned int> entries_per_row(matrix.
m(), 0);
550 for (
size_type row = 0; row < matrix.
m(); ++row)
552 for (
size_type col = 0; col < matrix.
n(); ++col)
553 if (matrix(row, col) != 0)
554 ++entries_per_row[row];
555 if (matrix_is_square && (matrix(row, row) == 0))
556 ++entries_per_row[row];
559 reinit(matrix.
m(), matrix.
n(), entries_per_row);
566 std::vector<size_type> column_indices;
567 column_indices.reserve(
568 entries_per_row.size() > 0 ?
569 *std::max_element(entries_per_row.begin(), entries_per_row.end()) :
571 for (
size_type row = 0; row < matrix.
m(); ++row)
573 column_indices.resize(entries_per_row[row]);
576 for (
size_type col = 0; col < matrix.
n(); ++col)
577 if (matrix(row, col) != 0)
579 column_indices[current_index] = col;
586 if (matrix_is_square && (col == row))
588 column_indices[current_index] = row;
596 add_entries(row, column_indices.begin(), column_indices.end(),
true);
607 const std::vector<unsigned int> &row_lengths)
609 reinit(m, n, make_slice(row_lengths));
683 Utilities::lower_bound<const size_type *>(sorted_region_start,
686 if ((p != &
colnums[rowstart[i + 1]]) && (*p == j))
722 template <
typename ForwardIterator>
725 ForwardIterator
begin,
727 const bool indices_are_sorted)
729 if (indices_are_sorted ==
true)
733 ForwardIterator it =
begin;
734 bool has_larger_entries =
false;
742 has_larger_entries =
true;
745 if (has_larger_entries ==
false)
746 for (; it !=
end; ++it)
748 if (store_diagonal_first_in_row && *it == row)
750 Assert(k <= rowstart[row + 1],
752 rowstart[row + 1] - rowstart[row]));
758 for (ForwardIterator p = begin; p !=
end; ++p)
765 for (ForwardIterator it = begin; it !=
end; ++it)
800 return k - rowstart[i];
807 std::pair<SparsityPattern::size_type, SparsityPattern::size_type>
827 return std::make_pair(row, col);
879 out <<
']' << std::endl;
900 out <<
colnums[j] <<
" " << -
static_cast<signed int>(i) << std::endl;
908 unsigned int m = this->
n_rows();
909 unsigned int n = this->
n_cols();
911 <<
"<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" viewBox=\"0 0 " 912 << n + 2 <<
" " << m + 2
914 "<style type=\"text/css\" >\n" 922 << n + 2 <<
"\" height=\"" << m + 2
923 <<
"\" fill=\"rgb(128, 128, 128)\"/>\n" 924 " <rect x=\"1\" y=\"1\" width=\"" 925 << n + 0.1 <<
"\" height=\"" << m + 0.1
926 <<
"\" fill=\"rgb(255, 255, 255)\"/>\n\n";
929 for (; it !=
end; ++it)
931 out <<
" <rect class=\"pixel\" x=\"" << it->
column() + 1 <<
"\" y=\"" 932 << it->
row() + 1 <<
"\" width=\".9\" height=\".9\"/>\n";
934 out <<
"</svg>" << std::endl;
948 if (static_cast<size_type>(
949 std::abs(static_cast<int>(i -
colnums[j]))) > b)
950 b = std::abs(static_cast<signed int>(i -
colnums[j]));
969 out.write(reinterpret_cast<const char *>(
rowstart.get()),
971 reinterpret_cast<const char *>(
rowstart.get()));
973 out.write(reinterpret_cast<const char *>(
colnums.get()),
975 reinterpret_cast<const char *>(
colnums.get()));
1006 in.read(reinterpret_cast<char *>(
rowstart.get()),
1008 reinterpret_cast<char *>(
rowstart.get()));
1013 in.read(reinterpret_cast<char *>(colnums.get()),
1014 reinterpret_cast<char *>(colnums.get() +
max_vec_len) -
1015 reinterpret_cast<char *>(colnums.get()));
1038 SparsityPattern::add_entries<const SparsityPattern::size_type *>(
1043 #ifndef DEAL_II_VECTOR_ITERATOR_IS_POINTER 1046 std::vector<SparsityPattern::size_type>::const_iterator>(
1048 std::vector<size_type>::const_iterator,
1049 std::vector<size_type>::const_iterator,
1053 SparsityPattern::add_entries<std::vector<SparsityPattern::size_type>::iterator>(
1055 std::vector<size_type>::iterator,
1056 std::vector<size_type>::iterator,
1059 DEAL_II_NAMESPACE_CLOSE
size_type row_length(const size_type row) const
Iterator lower_bound(Iterator first, Iterator last, const T &val)
const types::global_dof_index invalid_size_type
void add_entries(const size_type row, ForwardIterator begin, ForwardIterator end, const bool indices_are_sorted=false)
static::ExceptionBase & ExcMatrixIsCompressed()
bool exists(const size_type i, const size_type j) const
#define AssertDimension(dim1, dim2)
void print_svg(std::ostream &out) const
std::size_t memory_consumption() const
static::ExceptionBase & ExcIO()
static const size_type invalid_entry
std::pair< size_type, size_type > matrix_position(const std::size_t global_index) const
void print_gnuplot(std::ostream &out) const
size_type row_position(const size_type i, const size_type j) const
size_type operator()(const size_type i, const size_type j) const
#define AssertThrow(cond, exc)
static::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
std::unique_ptr< size_type[]> colnums
static::ExceptionBase & ExcNotCompressed()
static::ExceptionBase & ExcMessage(std::string arg1)
size_type max_entries_per_row() const
size_type bandwidth() const
void add(const size_type i, const size_type j)
void block_write(std::ostream &out) const
#define Assert(cond, exc)
unsigned int row_length(const size_type row) const
SparsityPattern & operator=(const SparsityPattern &)
void copy_from(const size_type n_rows, const size_type n_cols, const ForwardIterator begin, const ForwardIterator end)
types::global_dof_index size_type
void reinit(const size_type m, const size_type n, const unsigned int max_per_row)
unsigned int max_row_length
size_type column_number(const size_type row, const size_type index) const
static::ExceptionBase & ExcNotQuadratic()
static::ExceptionBase & ExcNotEnoughSpace(int arg1, int arg2)
bool store_diagonal_first_in_row
std::unique_ptr< std::size_t[]> rowstart
void print(std::ostream &out) const
static::ExceptionBase & ExcEmptyObject()
void block_read(std::istream &in)
bool exists(const size_type i, const size_type j) const
bool is_compressed() const
std::size_t n_nonzero_elements() const
static::ExceptionBase & ExcInternalError()