Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce IndexSet::is_subset_of(). #15928

Merged
merged 3 commits into from
Aug 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions doc/news/changes/minor/20230824Bangerth
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
New: The function IndexSet::is_subset_of() does as its name suggests.
<br>
(Wolfgang Bangerth, 2023/08/24)
10 changes: 10 additions & 0 deletions include/deal.II/base/index_set.h
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,16 @@ class IndexSet
void
fill_binary_vector(VectorType &vector) const;

/**
* Determine whether the current object represents a set of indices
* that is a subset of the set represented by the argument. This
* function returns `true` if the two sets are the same, that is, it
* considers the "subset" comparison typically used in set theory,
* rather than the "strict subset" comparison.
*/
bool
is_subset_of(const IndexSet &other) const;

/**
* Output a text representation of this IndexSet to the given stream. Used
* for testing.
Expand Down
17 changes: 17 additions & 0 deletions source/base/index_set.cc
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,23 @@ IndexSet::add_indices(const IndexSet &other, const size_type offset)



bool
IndexSet::is_subset_of(const IndexSet &other) const
{
// See whether there are indices in the current set that are not in 'other'.
// If so, then this is clearly not a subset of 'other'.
IndexSet A_minus_B = *this;
A_minus_B.subtract_set(other);
if (A_minus_B.n_elements() > 0)
return false;
else
// Else, every index in 'this' is also in 'other', since we ended up
// with an empty set upon subtraction. This means that we have a subset:
return true;
}



void
IndexSet::write(std::ostream &out) const
{
Expand Down
66 changes: 66 additions & 0 deletions tests/base/index_set_34.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// ---------------------------------------------------------------------
//
// Copyright (C) 2009 - 2018 by the deal.II authors
//
// This file is part of the deal.II library.
//
// The deal.II library is free software; you can use it, redistribute
// it, and/or modify it under the terms of the GNU Lesser General
// Public License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
// The full text of the license can be found in the file LICENSE.md at
// the top level directory of deal.II.
//
// ---------------------------------------------------------------------


// test IndexSet::is_subset_of()

#include <deal.II/base/index_set.h>

#include "../tests.h"


void
test()
{
// Create an index set that has about 30% of its possible indices:
const unsigned int N = 1000;
IndexSet index_set(N);
for (unsigned int i = 0; i < N / 3; ++i)
index_set.add_index(random_value<unsigned int>(0, N - 1));
index_set.compress();

// Test that the set is a subset of itself:
Assert(index_set.is_subset_of(index_set), ExcInternalError());

// Now take out one value after the other in some random order, and
// make sure that the result is a subset of the original set (and
// that the original one is *not* a subset (because it must be a
// superset):
const IndexSet original = index_set;
while (index_set.is_empty() == false)
{
IndexSet to_remove(N);
to_remove.add_index(index_set.nth_index_in_set(
random_value<unsigned int>(0, index_set.n_elements() - 1)));
to_remove.compress();

index_set.subtract_set(to_remove);

Assert(index_set.is_subset_of(original) == true, ExcInternalError());
Assert(original.is_subset_of(index_set) == false, ExcInternalError());
}

deallog << "OK" << std::endl;
}



int
main()
{
initlog();

test();
}
2 changes: 2 additions & 0 deletions tests/base/index_set_34.output
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

DEAL::OK