ENH: add invert (inverse mappings) for bitSet

This commit is contained in:
Mark Olesen
2019-07-12 12:00:00 +02:00
parent 59f5e26b58
commit 0203af1808
3 changed files with 72 additions and 10 deletions

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2018-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -33,6 +33,7 @@ Description
#include "boolList.H"
#include "bitSet.H"
#include "HashSet.H"
#include "ListOps.H"
#include "cpuTime.H"
#include <vector>
#include <unordered_set>
@ -91,6 +92,9 @@ int main(int argc, char *argv[])
set3b.unset(FixedList<label, 3>({ 1, 2, 3}));
Info<<"bitSet unset(FixedList<label>): "; report(set3b, true);
Info<<"bits used: " << flatOutput(set3b.toc()) << nl;
Info<<"inverted: " << flatOutput(invert(set3b)) << nl;
}
Info<< "End\n" << endl;

View File

@ -38,10 +38,9 @@ Foam::labelList Foam::invert
{
labelList inverse(len, -1);
forAll(map, i)
label i = 0;
for (const label newIdx : map)
{
const label newIdx = map[i];
if (newIdx >= 0)
{
#ifdef FULLDEBUG
@ -58,19 +57,57 @@ Foam::labelList Foam::invert
{
FatalErrorInFunction
<< "Map is not one-to-one. At index " << i
<< " element " << newIdx << " has already occurred before"
<< nl << "Please use invertOneToMany instead"
<< " element " << newIdx << " has already occurred\n"
<< "Please use invertOneToMany instead"
<< abort(FatalError);
}
inverse[newIdx] = i;
}
++i;
}
return inverse;
}
Foam::labelList Foam::invert
(
const label len,
const bitSet& map
)
{
labelList inverse(len, -1);
label i = 0;
for (const label newIdx : map)
{
#ifdef FULLDEBUG
if (newIdx >= len)
{
FatalErrorInFunction
<< "Inverse location " << newIdx
<< " is out of range. List has size " << len
<< abort(FatalError);
}
#endif
inverse[newIdx] = i;
++i;
}
return inverse;
}
Foam::labelList Foam::invert(const bitSet& map)
{
return invert(map.size(), map);
}
Foam::labelListList Foam::invertOneToMany
(
const label len,
@ -95,14 +132,15 @@ Foam::labelListList Foam::invertOneToMany
sizes[i] = 0; // reset size counter
}
forAll(map, i)
label i = 0;
for (const label newIdx : map)
{
const label newIdx = map[i];
if (newIdx >= 0)
{
inverse[newIdx][sizes[newIdx]++] = i;
}
++i;
}
return inverse;

View File

@ -334,9 +334,29 @@ void inplaceSubsetList
);
//- Invert one-to-one map. Unmapped elements will be -1.
//- Create an inverse one-to-one mapping.
// \param len the output size
// \param map the unique indices to map, in a [0..len) range.
// Any negative indices are ignored.
//
// \return the inverse mapping with -1 for unmapped elements.
labelList invert(const label len, const labelUList& map);
//- Create an inverse one-to-one mapping for all 'on' bits of the map.
// \param len the output size
// \param map the 'on' bits to use for the mapping indices.
// The last on bit shall be less than len.
//
// \return the inverse mapping with -1 for unmapped elements.
labelList invert(const label len, const bitSet& map);
//- Create an inverse one-to-one mapping for all 'on' bits of the map.
// The output size is dictated by the map size.
// \param map the unique indices to map.
//
// \return the inverse mapping with -1 for unmapped elements.
labelList invert(const bitSet& map);
//- Invert one-to-many map. Unmapped elements will be size 0.
labelListList invertOneToMany(const label len, const labelUList& map);