yams/third_party/hdbscan-cpp/HDBSCAN-CPP/HdbscanStar/cluster.cpp

104 lines
4.1 KiB
C++

#include "cluster.hpp"
#include <iostream>
int cluster::counter = 0;
cluster::cluster() {
_id = ++counter;
}
cluster::cluster(
int label, cluster* parent, double birthLevel,
int numPoints) //: Label(label), Parent(parent), _birthLevel(birthLevel), _numPoints(numPoints)
{
_id = ++counter;
_deathLevel = 0;
_propagatedStability = 0;
_numConstraintsSatisfied = 0;
_propagatedNumConstraintsSatisfied = 0;
Parent = parent;
Label = label;
_birthLevel = birthLevel;
_numPoints = numPoints;
HierarchyPosition = 0;
Stability = 0;
PropagatedLowestChildDeathLevel = std::numeric_limits<double>::max();
if (Parent != NULL)
Parent->HasChildren = true;
HasChildren = false;
PropagatedDescendants.resize(0);
}
bool cluster ::operator==(const cluster& other) const {
return (this->_id == other._id);
}
void cluster::detachPoints(int numPoints, double level) {
_numPoints -= numPoints;
Stability += (numPoints * (1 / level - 1 / _birthLevel));
if (_numPoints == 0)
_deathLevel = level;
else if (_numPoints < 0)
throw std::invalid_argument("Cluster cannot have less than 0 points.");
}
void cluster::propagate() {
if (Parent != NULL) {
if (PropagatedLowestChildDeathLevel == std::numeric_limits<double>::max())
PropagatedLowestChildDeathLevel = _deathLevel;
if (PropagatedLowestChildDeathLevel < Parent->PropagatedLowestChildDeathLevel)
Parent->PropagatedLowestChildDeathLevel = PropagatedLowestChildDeathLevel;
if (!HasChildren) {
Parent->_propagatedNumConstraintsSatisfied += _numConstraintsSatisfied;
Parent->_propagatedStability += Stability;
Parent->PropagatedDescendants.push_back(this);
} else if (_numConstraintsSatisfied > _propagatedNumConstraintsSatisfied) {
Parent->_propagatedNumConstraintsSatisfied += _numConstraintsSatisfied;
Parent->_propagatedStability += Stability;
Parent->PropagatedDescendants.push_back(this);
} else if (_numConstraintsSatisfied < _propagatedNumConstraintsSatisfied) {
Parent->_propagatedNumConstraintsSatisfied += _propagatedNumConstraintsSatisfied;
Parent->_propagatedStability += _propagatedStability;
Parent->PropagatedDescendants.insert(Parent->PropagatedDescendants.end(),
PropagatedDescendants.begin(),
PropagatedDescendants.end());
} else if (_numConstraintsSatisfied == _propagatedNumConstraintsSatisfied) {
// Chose the parent over descendants if there is a tie in stability:
if (Stability >= _propagatedStability) {
Parent->_propagatedNumConstraintsSatisfied += _numConstraintsSatisfied;
Parent->_propagatedStability += Stability;
Parent->PropagatedDescendants.push_back(this);
} else {
Parent->_propagatedNumConstraintsSatisfied += _propagatedNumConstraintsSatisfied;
Parent->_propagatedStability += _propagatedStability;
Parent->PropagatedDescendants.insert(Parent->PropagatedDescendants.end(),
PropagatedDescendants.begin(),
PropagatedDescendants.end());
}
}
}
}
void cluster::addPointsToVirtualChildCluster(std::set<int> points) {
for (std::set<int>::iterator it = points.begin(); it != points.end(); ++it) {
_virtualChildCluster.insert(*it);
}
}
bool cluster::virtualChildClusterConstraintsPoint(int point) {
return (_virtualChildCluster.find(point) != _virtualChildCluster.end());
}
void cluster::addVirtualChildConstraintsSatisfied(int numConstraints) {
_propagatedNumConstraintsSatisfied += numConstraints;
}
void cluster::addConstraintsSatisfied(int numConstraints) {
_numConstraintsSatisfied += numConstraints;
}
void cluster::releaseVirtualChildCluster() {
_virtualChildCluster.clear();
}
int cluster::getClusterId() {
return this->_id;
}