CMP++: Uncertainty Quantification & Bayesian Calibration
Loading...
Searching...
No Matches
cluster.h
Go to the documentation of this file.
1#ifndef CLUSTER_H
2#define CLUSTER_H
3
4#include <cmp_defines.h>
5#include <distribution.h>
6#include <grid.h>
7
12namespace cmp::cluster {
13
37 private:
39 Eigen::MatrixXd centroids_;
40
41 size_t nClusters_;
42 size_t nPoints_;
43 size_t dim_;
44
45 public:
46 GeometricCluster() = default;
47
57 bool fit(const Eigen::Ref<const Eigen::MatrixXd> &points, size_t nClusters, std::default_random_engine &rng, size_t max_iter = 1000);
58
65 const size_t &operator[](size_t i) const;
66
73 Eigen::VectorXd centroid(size_t i) const;
74
78 size_t nClusters() const;
79
83 size_t nPoints() const;
84
88 size_t dim() const;
89
94 const Eigen::VectorXs &getLabels() const {
95 return labels_;
96 }
97};
98
133
134 private:
135 struct Cluster {
136 size_t id_;
137 size_t nPoints_;
138
139 // Sufficient statistics
140 Eigen::VectorXd sumOfX_;
141 Eigen::MatrixXd sumOfXXT_;
142
143 // Default constructor
144 Cluster() : id_(0), nPoints_(0) {}
145
146 // Constructor with id and dimension
147 Cluster(size_t id, size_t dim) : id_(id), nPoints_(0),
148 sumOfX_(Eigen::VectorXd::Zero(dim)),
149 sumOfXXT_(Eigen::MatrixXd::Zero(dim, dim)) {}
150 };
151
152 private:
153
154 // Workspaces for the Gibbs sampler to avoid heap allocations
155 std::vector<double> logp_workspace_;
156 std::vector<double> probs_workspace_;
157 std::vector<size_t> clusterIDs_workspace_;
158
159 Eigen::MatrixXd xObs_;
161 size_t nPoints_{0};
162 int dim_{0};
163 std::vector<size_t> clusterIDs_;
164
165 // This prior is conjugate to the Gaussian likelihood
168 double alpha_{1.0};
169
170 std::map<size_t, Cluster> clusters_;
172
173 // Random number generator for sampling
174 std::default_random_engine rng_;
175 std::uniform_real_distribution<double> distU_{0.0, 1.0};
176
177 public:
178
179// public API
189 double alpha,
190 const cmp::distribution::GammaDistribution &alphaPrior,
192 unsigned int seed = 12345
193 );
194
201 void condition(const Eigen::Ref<const Eigen::MatrixXd> &data, const Eigen::VectorXs& init_labels);
202
206 void step();
207
211 void remapLabels();
212
219 return labels_;
220 }
221
227 size_t nClusters() const {
228 return clusters_.size();
229 }
230
236 double getAlpha() const {
237 return alpha_;
238 }
239
240 private:
241
247 void init(const Eigen::VectorXs& init_labels);
248
255 void removePointFromCluster(const size_t &pointIndex, const size_t &clusterID);
256
263 void addPointToCluster(const size_t &pointIndex, const size_t &clusterID);
264
272 double logNIWPosterior(const Eigen::VectorXd& x, const Cluster& c) const;
273
277 void updateAlpha() {
278 double K = static_cast<double>(clusters_.size());
279 double N = static_cast<double>(nPoints_);
280
281 // Extract prior parameters from your distribution object
282 double a = alphaPrior_.getAlpha();
283 double b = alphaPrior_.getBeta();
284
285 // 1. Instantiate the Beta distribution and sample eta
287 double eta = beta_dist.sample(rng_);
288
289 // 2. Calculate the weights for the Gamma mixture
290 double weight1 = (a + K - 1.0) / (N * (b - std::log(eta)));
291 double pi_eta = weight1 / (weight1 + 1.0);
292
293 // 3. Sample the new alpha using your custom cmp::distribution classes
294 double u = distU_(rng_);
295 double updated_beta = b - std::log(eta); // The rate parameter
296
297 if(u < pi_eta) {
298 // Gamma(a + K, b - ln(eta))
299 cmp::distribution::GammaDistribution new_gamma(a + K, updated_beta);
300 alpha_ = new_gamma.sample(rng_);
301 } else {
302 // Gamma(a + K - 1, b - ln(eta))
303 cmp::distribution::GammaDistribution new_gamma(a + K - 1.0, updated_beta);
304 alpha_ = new_gamma.sample(rng_);
305 }
306
307 // Safety bounds just in case of severe numerical underflow
308 if(alpha_ < 1e-5) alpha_ = 1e-5;
309 }
310
311};
312
313
328 private:
329 size_t nClusters_;
330 std::default_random_engine rng_;
332 public:
333 DummyCluster(size_t nClusters, unsigned int seed = 42)
334 : nClusters_(nClusters), rng_(seed) {}
335
341 void fit(const Eigen::Ref<const Eigen::MatrixXd> &points) {
342 size_t nPoints = points.rows();
343 std::uniform_int_distribution<size_t> dist(0, nClusters_ - 1);
344 labels_ = Eigen::VectorXs::Zero(nPoints);
345 for(size_t i = 0; i < nPoints; i++) {
346 labels_(i) = dist(rng_);
347 }
348 }
349
355 const Eigen::VectorXs &getLabels() const {
356 return labels_;
357 }
358
359
360};
361
362} // namespace cmp::cluster
363
364
367#endif
Implements an infinite Gaussian Mixture Model using a Dirichlet Process Mixture Model (DPMM) and Gibb...
Definition cluster.h:132
size_t nClusters() const
Gets the current number of active clusters.
Definition cluster.h:227
Eigen::MatrixXd xObs_
Observed data points matrix (N x D).
Definition cluster.h:159
std::vector< double > logp_workspace_
Temporary buffer for cluster log-probabilities.
Definition cluster.h:155
Eigen::VectorXs getLabels() const
Gets the current cluster label assignments vector.
Definition cluster.h:218
std::map< size_t, Cluster > clusters_
Map from cluster ID to sufficient statistics cluster structure.
Definition cluster.h:170
std::vector< size_t > clusterIDs_
List of active cluster IDs.
Definition cluster.h:163
double getAlpha() const
Gets the current concentration parameter alpha.
Definition cluster.h:236
Eigen::VectorXs labels_
Current cluster assignment label vector.
Definition cluster.h:160
void condition(const Eigen::Ref< const Eigen::MatrixXd > &data, const Eigen::VectorXs &init_labels)
Conditions the DPMM model on the given dataset with initial cluster labels.
Definition cluster.cpp:195
void removePointFromCluster(const size_t &pointIndex, const size_t &clusterID)
Removes a point from the sufficient statistics of a specified cluster.
Definition cluster.cpp:120
void addPointToCluster(const size_t &pointIndex, const size_t &clusterID)
Adds a point to the sufficient statistics of a specified cluster.
Definition cluster.cpp:140
cmp::distribution::NormalInverseWishartDistribution hyper_
Hyperprior distribution parameters for clusters.
Definition cluster.h:166
cmp::distribution::GammaDistribution alphaPrior_
Prior distribution parameters for concentration parameter.
Definition cluster.h:167
size_t nextClusterId_
Counter to generate unique new cluster IDs.
Definition cluster.h:171
double alpha_
Concentration parameter alpha for the Dirichlet Process.
Definition cluster.h:168
void updateAlpha()
Updates the concentration parameter alpha via auxiliary variable sampling.
Definition cluster.h:277
std::default_random_engine rng_
Pseudo-random number generator engine.
Definition cluster.h:174
size_t nPoints_
Number of observation points.
Definition cluster.h:161
void remapLabels()
Remaps cluster labels to be contiguous integers starting from 0.
Definition cluster.cpp:285
int dim_
Dimensionality of the feature space.
Definition cluster.h:162
double logNIWPosterior(const Eigen::VectorXd &x, const Cluster &c) const
Computes the log posterior probability of a point under a cluster's NIW predictive distribution.
Definition cluster.cpp:159
std::uniform_real_distribution< double > distU_
Uniform real generator for rejection sampler.
Definition cluster.h:175
std::vector< size_t > clusterIDs_workspace_
Temporary buffer for cluster IDs.
Definition cluster.h:157
void step()
Performs one complete sweep of collapsed Gibbs sampling over all points.
Definition cluster.cpp:215
void init(const Eigen::VectorXs &init_labels)
Initializes cluster counts, sums, and sufficient statistics.
Definition cluster.cpp:100
std::vector< double > probs_workspace_
Temporary buffer for cluster probability weights.
Definition cluster.h:156
Simple partitioning algorithm that assigns observations to clusters uniformly at random.
Definition cluster.h:327
Eigen::VectorXs labels_
Vector of randomly assigned labels.
Definition cluster.h:331
size_t nClusters_
Number of target clusters.
Definition cluster.h:329
std::default_random_engine rng_
Random number generator.
Definition cluster.h:330
void fit(const Eigen::Ref< const Eigen::MatrixXd > &points)
Randomly assigns each data point to a cluster uniformly at random.
Definition cluster.h:341
DummyCluster(size_t nClusters, unsigned int seed=42)
Definition cluster.h:333
const Eigen::VectorXs & getLabels() const
Gets the randomly generated cluster labels.
Definition cluster.h:355
Implements a standard k-means clustering algorithm.
Definition cluster.h:36
const size_t & operator[](size_t i) const
Accesses the cluster label of the i-th point.
Definition cluster.cpp:72
size_t dim() const
Returns the dimension of the data.
Definition cluster.cpp:88
const Eigen::VectorXs & getLabels() const
Returns the cluster assignments vector.
Definition cluster.h:94
Eigen::VectorXd centroid(size_t i) const
Returns the centroid of the i-th cluster.
Definition cluster.cpp:76
size_t nPoints() const
Returns the number of data points.
Definition cluster.cpp:84
size_t nClusters() const
Returns the number of clusters.
Definition cluster.cpp:80
size_t nClusters_
Number of clusters.
Definition cluster.h:41
bool fit(const Eigen::Ref< const Eigen::MatrixXd > &points, size_t nClusters, std::default_random_engine &rng, size_t max_iter=1000)
Fits the K-means clustering model on the given dataset.
Definition cluster.cpp:3
Eigen::MatrixXd centroids_
Centroid coordinates for each cluster.
Definition cluster.h:39
Eigen::VectorXs labels_
Cluster label assigned to each data point.
Definition cluster.h:38
size_t nPoints_
Number of data points.
Definition cluster.h:42
size_t dim_
Dimensionality of data features.
Definition cluster.h:43
Definition distribution.h:403
double sample(std::default_random_engine &rng)
Definition distribution.h:450
Definition distribution.h:337
double getBeta() const
Definition distribution.h:398
double sample(std::default_random_engine &rng)
Definition distribution.h:379
double getAlpha() const
Definition distribution.h:395
Definition cmp_defines.h:19
Matrix< size_t, Eigen::Dynamic, 1 > VectorXs
Definition cmp_defines.h:20
Definition cluster.h:12
Eigen::VectorXd sumOfX_
Sum of all points in the cluster.
Definition cluster.h:140
Cluster(size_t id, size_t dim)
Definition cluster.h:147
size_t id_
Unique cluster ID (not necessarily contiguous).
Definition cluster.h:136
Eigen::MatrixXd sumOfXXT_
Sum of all outer products x * x^T for points in the cluster.
Definition cluster.h:141
size_t nPoints_
Number of points assigned to this cluster.
Definition cluster.h:137