Changed implementation of WeightedRips to store simplex values (max distance between simplices' vertices) as an invisible layer on top of each simplex object, so that the data() field of WeightedRips has been freed for use by the users again.
/* Implementations */
#ifdef LOGGING
static rlog::RLogChannel* rlOrderList = DEF_CHANNEL("utilities/orderlist", rlog::Log_Debug);
#endif // LOGGING
template<class T>
void
OrderList<T>::
swap(iterator i, iterator j)
{
typename Parent::iterator i_base = i.get_base();
typename Parent::iterator j_base = j.get_base();
std::swap(i_base->tag, j_base->tag);
// Exchange the actual elements in the list --- so that iterators behave as expected
typename Parent::iterator after_j = boost::next(j_base);
Parent::splice(i_base, *this, j_base);
Parent::splice(after_j, *this, i_base);
}
template<class T>
template<class BinaryPredicate>
void
OrderList<T>::
sort(BinaryPredicate cmp)
{
Parent::sort(OrderListNodeComparison<T, BinaryPredicate>(cmp));
OrderType cur_order = 0;
for (typename Parent::iterator cur = Parent::begin(); cur != Parent::end(); ++cur)
cur->tag = cur_order++;
}
template<class T>
typename OrderList<T>::iterator
OrderList<T>::
push_back(const_reference x)
{
if (empty())
Parent::push_back(NodeType(x, 0));
else
Parent::push_back(NodeType(x, last().get_base()->tag + 1));
return last();
}
template<class T>
typename OrderList<T>::iterator
OrderList<T>::
insert(iterator p, const_reference x)
{
typename Parent::iterator p_base = p.get_base();
OrderType tag = (p_base++)->tag + 1;
typename Parent::iterator new_base = Parent::insert(p_base, NodeType(x, tag));
if (p_base->tag != tag)
return iterator(new_base);
// Find non-overflowing region
unsigned int num_elements = 1, maximum = 1, lower = tag, upper = tag, level = 0;
float inv_density = 1;
typename Parent::iterator prev = p_base, next = p_base;
--(--prev); ++next; // move prev back twice to skip over the newly inserted element
do
{
lower &= ~(1 << level);
upper |= (1 << level);
maximum <<= 1; inv_density *= density_threshold;
++level;
while (prev != Parent::end() && prev->tag >= lower) { --prev; ++num_elements; }
while (next != Parent::end() && next->tag <= upper) { ++next; ++num_elements; }
} while (inv_density * num_elements >= maximum);
++num_elements; // for the extra element inserted
rLog(rlOrderList, "%i, %i, %i", num_elements, lower, upper);
rLog(rlOrderList, "prev is at the end: %i", (prev == Parent::end()));
rLog(rlOrderList, "next is at the end: %i", (next == Parent::end()));
// Reorder
AssertMsg((upper - lower + 1)/num_elements > 0, "Spacing between new tags must be non-zero");
for (unsigned int i = 0; i < num_elements; ++i)
{
(++prev)->tag = lower + i*((upper - lower + 1)/num_elements);
rLog(rlOrderList, "%i", prev->tag);
AssertMsg(prev->tag != 0 || prev == Parent::begin(), "Cannot assign 0 tag except at the beginning of OrderList");
}
AssertMsg(++prev == next, "prev + num_elements != next in OrderList::insert()");
return iterator(new_base);
}
template<class T>
void
OrderList<T>::
show_elements() const
{
for (const_iterator cur = begin(); cur != end(); ++cur)
std::cout << *(cur.get_base()) << std::endl;
std::cout << std::endl;
}
/* OrderComparison */
template<class T>
int
OrderList<T>::OrderComparison::
compare(ComparableType a, ComparableType b) const
{
if (a.get_base()->tag == b.get_base()->tag) return 0;
if (a.get_base()->tag < b.get_base()->tag) return -1;
return 1;
}
template<class T>
bool
OrderList<T>::OrderComparison::
operator()(ComparableType a, ComparableType b) const
{
return (compare(a,b) < 0);
}