44 if (sigma_neighborhood < 1)
46 size_t nelem = distance_matrix.
GetRows();
49 std::vector<double> sigmas(nelem);
50 for (
size_t r = 0; r < nelem; ++r)
52 std::set<double> dist;
53 for (
size_t c = 0; c < nelem; ++c)
55 dist.insert(distance_matrix[r][c]);
56 auto it = dist.begin();
57 std::advance(it, sigma_neighborhood - 1);
61 sigmas[r] = *dist.rbegin();
65 for (
size_t r = 0; r < nelem; ++r)
66 for (
size_t c = 0; c < nelem; ++c)
68 if ((r == c) || (distance_matrix[r][c] > epsilon))
71 w[r][c] = exp(-
Sqr(distance_matrix[r][c]) / (2 * sigmas[r] * sigmas[c]));
86 if (sigma_neighborhood < 1)
88 size_t nelem = distance_matrix.
GetRows();
92 for (
size_t r = 0; r < nelem; ++r)
94 std::set<double> dist;
95 for (
size_t c = 0; c < nelem; ++c)
97 dist.insert(distance_matrix[r][c]);
98 auto it = dist.begin();
99 std::advance(it, sigma_neighborhood - 1);
100 if (it != dist.end())
103 sigma += *dist.rbegin();
105 sigma /= double(nelem);
123 size_t nelem = distance_matrix.
GetRows();
127 for (
size_t r = 0; r < nelem; ++r)
129 double m = *std::max_element(distance_matrix[r] + r, distance_matrix[r] + nelem);
130 if (m > sigma) sigma = m;
132 sigma /= 2 * pow(
double(nelem), 1 /
double(dimension));
150 size_t nelem = distance_matrix.
GetRows();
156 for (
size_t r = 0; r < nelem; ++r)
157 for (
size_t c = 0; c < nelem; ++c)
159 if ((r == c) || (distance_matrix[r][c] > epsilon))
162 w[r][c] = exp(-
Sqr(distance_matrix[r][c]) / sigma);
174 for (
size_t r = 0; r < w.
GetRows(); ++r)
177 for (
size_t c = 0; c < w.
GetCols(); ++c)
179 if (s != 0) s = 1 / sqrt(s);
186 eigenpairs = l.MakeTQLIEigensystem(1000);
194 std::vector<double> vals(eigenpairs.size());
195 auto vit = vals.begin();
196 for (
auto eit = eigenpairs.rbegin(); eit != eigenpairs.rend(); ++eit)
208 if ((limit < 0.0) || (limit > 1.0))
211 for (
auto eit = eigenpairs.rbegin(); eit != eigenpairs.rend(); ++eit)
213 if (eit->first < limit)
228 if (ncoordinates < 1)
230 size_t nelem = eigenpairs.size();
231 std::vector<std::vector<double> > data(nelem, std::vector<double>(ncoordinates));
232 std::multimap<double, MatrixDouble>::const_reverse_iterator stopit;
233 if (ncoordinates >= nelem)
234 stopit = eigenpairs.rend();
237 stopit = eigenpairs.rbegin();
238 std::advance(stopit, ncoordinates);
241 for (
auto eit = eigenpairs.rbegin(); eit != stopit; ++eit)
243 for (
size_t tmp = 0; tmp < nelem; ++tmp)
244 data[tmp][coord] = eit->second[tmp][0];
249 for (
auto & elem : data)
252 for (
size_t i = 0; i < ncoordinates; ++i)
255 for (
size_t i = 0; i < ncoordinates; ++i)
size_t GetRows() const noexcept
Returns the number of rows.
size_t GetCols() const noexcept
Returns the number of columns.
std::vector< std::vector< double > > ProjectData(size_t ncoordinates, bool normalize) const
Projects the data on the first coordinates.
static SpectralClustering CreateGlobalScaleFromDimension(const SquareMatrixDouble &distance_matrix, size_t dimension, double epsilon=std::numeric_limits< double >::max())
Clustering with global automatic scale.
static SpectralClustering CreateLocalScaleFromNN(const SquareMatrixDouble &distance_matrix, size_t sigma_neighborhood=7, double epsilon=std::numeric_limits< double >::max())
Clustering with local automatic scale.
std::vector< double > GetEigenvalues() const
Returns the eigenvalues (sorted from highest to lowest)
size_t EstimateClusterNumber(double limit=1.0) const
Estimates the number of clusters.
constexpr SumType< T > Sqr(const T &v) noexcept(noexcept(v *v))
Returns the square of a value.
static SpectralClustering CreateGlobalScaleFromNN(const SquareMatrixDouble &distance_matrix, size_t sigma_neighborhood=1, double epsilon=std::numeric_limits< double >::max())
Clustering with global automatic scale.
static SpectralClustering CreateFixedScale(const SquareMatrixDouble &distance_matrix, double sigma, double epsilon=std::numeric_limits< double >::max())
Clustering with global fixed scale.
Square double matrix class.
Invalid argument error (e.g.: nullptr pointer)
SpectralClustering(const SpectralClustering &)=delete