File indexing completed on 2025-04-19 09:09:48
0001 #include "ATOOLS/Math/Cluster_Algorithm.H"
0002
0003 #include "ATOOLS/Math/MathTools.H"
0004 #include "ATOOLS/Org/My_Limits.H"
0005
0006 using namespace ATOOLS;
0007
0008 template <class PointType,class MeasureType,class RecombinationType>
0009 Cluster_Algorithm<PointType,MeasureType,RecombinationType>::
0010 Cluster_Algorithm(): m_recalc(false) {}
0011
0012 template <class PointType,class MeasureType,class RecombinationType>
0013 bool Cluster_Algorithm<PointType,MeasureType,RecombinationType>::
0014 ArrangePoints()
0015 {
0016 for (size_t i(0);i<m_n;++i) {
0017 m_p[i]=m_p[m_i[i]];
0018 for (size_t j(0);j<m_j.size();++j) if (m_j[j]==(int)m_i[i]) m_j[j]=i;
0019 }
0020 m_p.resize(m_n);
0021 return true;
0022 }
0023
0024 template <class PointType,class MeasureType,class RecombinationType>
0025 bool Cluster_Algorithm<PointType,MeasureType,RecombinationType>::
0026 Cluster(const double &crit,const cs::code &code)
0027 {
0028 m_n=m_p.size();
0029 if (m_n>m_i.size()) {
0030 m_i.resize(m_n);
0031 m_d.resize(m_n);
0032 for (size_t i(0);i<m_n;++i) m_d[i]=Double_Vector(m_n);
0033 }
0034 m_j.resize(m_n);
0035 m_dmin=std::numeric_limits<double>::max();
0036 for (size_t i(0);i<m_n;++i) m_j[i]=m_i[i]=i;
0037 for (size_t i(0);i<m_n;++i) {
0038 SetDMin(i,i,m_d[i][i]=m_measure(m_p[i]));
0039 for (size_t j(i+1);j<m_n;++j)
0040 SetDMin(i,j,m_d[i][j]=m_measure(m_p[i],m_p[j]));
0041 }
0042 m_r.clear();
0043 m_lp.clear();
0044 if (m_n==0) return false;
0045 if (code==cs::num && m_n<=crit) return ArrangePoints();
0046 while (true) {
0047 m_r.push_back(m_dmin);
0048 size_t iimin(m_i[m_imin]), ijmin(m_i[m_jmin]);
0049 if (iimin!=ijmin) {
0050 for (size_t i(0);i<m_j.size();++i) if (m_j[i]==(int)ijmin) m_j[i]=iimin;
0051 m_p[iimin]=m_recom(m_p[iimin],m_p[ijmin]);
0052 }
0053 else {
0054 m_lp.push_back(m_p[iimin]);
0055 m_recom(m_p[iimin]);
0056 int pos(-m_lp.size());
0057 for (size_t i(0);i<m_j.size();++i) if (m_j[i]==(int)ijmin) m_j[i]=pos;
0058 }
0059 for (size_t i(m_jmin+1);i<m_n;++i) m_i[i-1]=m_i[i];
0060 --m_n;
0061 if ((code==cs::num && m_n<=crit) || m_n==0) return ArrangePoints();
0062 if (iimin!=ijmin) {
0063 if (!m_recalc) {
0064 for (size_t i(0);i<m_imin;++i)
0065 m_d[m_i[i]][iimin]=m_measure(m_p[m_i[i]],m_p[iimin]);
0066 m_d[iimin][iimin]=m_measure(m_p[iimin]);
0067 for (size_t j(m_imin+1);j<m_n;++j)
0068 m_d[iimin][m_i[j]]=m_measure(m_p[iimin],m_p[m_i[j]]);
0069 }
0070 else {
0071 for (size_t i(0);i<m_n;++i) {
0072 for (size_t j(i+1);j<m_n;++j)
0073 m_d[m_i[i]][m_i[j]]=m_measure(m_p[m_i[i]],m_p[m_i[j]]);
0074 }
0075 }
0076 }
0077 m_dmin=std::numeric_limits<double>::max();
0078 for (size_t i(0);i<m_n;++i) {
0079 size_t ii(m_i[i]);
0080 SetDMin(i,i,m_d[ii][ii]);
0081 for (size_t j(i+1);j<m_n;++j) SetDMin(i,j,m_d[ii][m_i[j]]);
0082 }
0083 if (m_dmin==std::numeric_limits<double>::max()) break;
0084 if (code==cs::dist && m_dmin>=crit) return ArrangePoints();
0085 }
0086 ArrangePoints();
0087 return false;
0088 }
0089