Commit 7e2a940d authored by Mark Olesen's avatar Mark Olesen
Browse files

SortableList + ListOps changes

- dropped setSize() in favour of List::setSize().
  The size of the indices is set in sort() anyhow and undefined before that.
- added reverseSort() method
- added ListOps uniqueOrder() and duplicateOrder()
parent 41bbcb63
......@@ -27,6 +27,7 @@ Description
\*---------------------------------------------------------------------------*/
#include "SortableList.H"
#include "ListOps.H"
using namespace Foam;
......@@ -35,49 +36,101 @@ using namespace Foam;
int main(int argc, char *argv[])
{
labelList orig(5);
labelList orig(8);
orig[0] = 7;
orig[1] = 4;
orig[1] = 9;
orig[2] = 1;
orig[3] = 2;
orig[4] = 9;
orig[4] = 4;
orig[5] = 7;
orig[6] = 4;
orig[7] = 0;
labelList order;
labelList a(orig);
Info << "before: " << a << endl;
sortedOrder(a, order);
Info<< "unsorted: " << a << endl;
sort(a);
Info << "after: " << a << endl;
Info<< "sorted: " << a << endl;
Info<< "indices: " << order << endl;
SortableList<label> b(orig);
Info << "sorted: " << b << endl;
Info << "indices: " << b.indices() << endl;
Info<< "unsorted: " << orig << endl;
Info<< "sorted: " << b << endl;
Info<< "indices: " << b.indices() << endl;
Info << "shrunk: " << b.shrink() << endl;
Info << "indices: " << b.indices() << endl;
Info<< "shrunk: " << b.shrink() << endl;
Info<< "indices: " << b.indices() << endl;
// repeat by assignment
b = orig;
Info << "unsorted: " << b << endl;
Info<< "unsorted: " << b << endl;
b.sort();
Info << "sorted: " << b << endl;
Info << "indices: " << b.indices() << endl;
Info<< "sorted: " << b << endl;
Info<< "indices: " << b.indices() << endl;
// find unique/duplicate values
b = orig;
Info<< "unsorted: " << b << endl;
uniqueOrder(b, order);
Info<< "unique: " << order << endl;
duplicateOrder(b, order);
Info<< "duplicate:" << order << endl;
// sort reverse
Info<< "unsorted: " << b << endl;
b.reverseSort();
Info<< "rsort: " << b << endl;
Info<< "indices: " << b.indices() << endl;
// transfer assignment
b.transfer(orig);
Info << "unsorted: " << b << endl;
a = orig;
b.transfer(a);
Info<< "unsorted: " << b << endl;
b.sort();
Info<< "sorted: " << b << endl;
Info<< "indices: " << b.indices() << endl;
a.transfer(b);
Info<< "plain: " << a << endl;
Info<< "sorted: " << b << endl;
Info<< "indices: " << b.indices() << endl;
// sort/duplicate/unique with identical values
b.setSize(8);
b = 5;
Info<< "unsorted: " << b << endl;
uniqueOrder(b, order);
Info<< "unique: " << order << endl;
duplicateOrder(b, order);
Info<< "duplicate:" << order << endl;
b.sort();
Info << "sorted: " << b << endl;
Info << "indices: " << b.indices() << endl;
Info<< "sorted: " << b << endl;
Info<< "indices: " << b.indices() << endl;
// with a single value
b.setSize(1);
Info<< "unsorted: " << b << endl;
uniqueOrder(b, order);
Info<< "unique: " << order << endl;
duplicateOrder(b, order);
Info<< "duplicate:" << order << endl;
b.sort();
labelList flatten;
flatten.transfer(b);
Info << "flatten: " << flatten << endl;
Info << "sorted: " << b << endl;
Info << "indices: " << b.indices() << endl;
Info<< "sorted: " << b << endl;
Info<< "indices: " << b.indices() << endl;
Info << "End\n" << endl;
Info<< "\nEnd\n" << endl;
return 0;
}
......
......@@ -82,6 +82,13 @@ void inplaceMapKey(const UList<label>& oldToNew, Container&);
template<class T>
void sortedOrder(const UList<T>&, labelList& order);
//- Generate (sorted) indices corresponding to duplicate list values
template<class T>
void duplicateOrder(const UList<T>&, labelList& order);
//- Generate (sorted) indices corresponding to unique list values
template<class T>
void uniqueOrder(const UList<T>&, labelList& order);
//- Extract elements of List whose region is certain value.
// Use e.g. to extract all selected elements:
......
......@@ -174,16 +174,65 @@ void Foam::sortedOrder
)
{
order.setSize(lst.size());
forAll(order, elemI)
{
order[elemI] = elemI;
}
Foam::stableSort(order, typename UList<T>::less(lst));
}
template<class T>
void Foam::duplicateOrder
(
const UList<T>& lst,
labelList& order
)
{
if (lst.size() < 2)
{
order.clear();
return;
}
sortedOrder(lst, order);
label n = 0;
for (label i = 0; i < order.size() - 1; ++i)
{
if (lst[order[i]] == lst[order[i+1]])
{
order[n++] = order[i];
}
}
order.setSize(n);
}
template<class T>
void Foam::uniqueOrder
(
const UList<T>& lst,
labelList& order
)
{
sortedOrder(lst, order);
if (order.size() > 1)
{
label n = 0;
for (label i = 0; i < order.size() - 1; ++i)
{
if (lst[order[i]] != lst[order[i+1]])
{
order[n++] = order[i];
}
}
order.setSize(n);
}
}
template<class T, class ListType>
ListType Foam::subset
(
......
......@@ -24,6 +24,23 @@ License
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
template <class Type>
void Foam::SortableList<Type>::sortIndices(List<label>& ind) const
{
// list lengths must be identical
ind.setSize(this->size());
forAll(ind, i)
{
ind[i] = i;
}
Foam::stableSort(ind, typename UList<Type>::less(*this));
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template <class Type>
......@@ -73,13 +90,6 @@ Foam::SortableList<Type>::SortableList(const SortableList<Type>& lst)
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template <class Type>
void Foam::SortableList<Type>::setSize(const label newSize)
{
List<Type>::setSize(newSize);
indices_.setSize(newSize, -1);
}
template <class Type>
void Foam::SortableList<Type>::clear()
......@@ -100,20 +110,28 @@ Foam::List<Type>& Foam::SortableList<Type>::shrink()
template <class Type>
void Foam::SortableList<Type>::sort()
{
// list lengths must be identical
indices_.setSize(this->size());
sortIndices(indices_);
List<Type> lst(this->size());
forAll(indices_, i)
{
indices_[i] = i;
lst[i] = this->operator[](indices_[i]);
}
Foam::stableSort(indices_, typename UList<Type>::less(*this));
List<Type>::transfer(lst);
}
template <class Type>
void Foam::SortableList<Type>::reverseSort()
{
sortIndices(indices_);
List<Type> lst(this->size());
label endI = indices_.size();
forAll(indices_, i)
{
lst[i] = this->operator[](indices_[i]);
lst[--endI] = this->operator[](indices_[i]);
}
List<Type>::transfer(lst);
......@@ -123,7 +141,14 @@ void Foam::SortableList<Type>::sort()
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template <class Type>
void Foam::SortableList<Type>::operator=(const UList<Type>& rhs)
inline void Foam::SortableList<Type>::operator=(const Type& t)
{
UList<Type>::operator=(t);
}
template <class Type>
inline void Foam::SortableList<Type>::operator=(const UList<Type>& rhs)
{
List<Type>::operator=(rhs);
indices_.clear();
......@@ -131,7 +156,7 @@ void Foam::SortableList<Type>::operator=(const UList<Type>& rhs)
template <class Type>
void Foam::SortableList<Type>::operator=(const SortableList<Type>& rhs)
inline void Foam::SortableList<Type>::operator=(const SortableList<Type>& rhs)
{
List<Type>::operator=(rhs);
indices_ = rhs.indices();
......
......@@ -60,6 +60,9 @@ class SortableList
//- Original indices
labelList indices_;
//- Resize and sort the parameter according to the list values
void sortIndices(List<label>&) const;
public:
// Constructors
......@@ -99,9 +102,6 @@ public:
return indices_;
}
//- Size the list. Growing can cause undefined indices (until next sort)
void setSize(const label);
//- Clear the list and the indices
void clear();
......@@ -112,13 +112,19 @@ public:
// also resizes the indices as required
void sort();
//- Reverse (stable) sort the list
void reverseSort();
// Member Operators
//- Assignment of all entries to the given value
inline void operator=(const Type&);
//- Assignment from UList operator. Takes linear time.
void operator=(const UList<Type>&);
inline void operator=(const UList<Type>&);
//- Assignment operator. Takes linear time.
void operator=(const SortableList<Type>&);
inline void operator=(const SortableList<Type>&);
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment