Skip to content

Commit 7fe5c86

Browse files
authored
use log-sum-exp in estimate_log_prob_resp to prevent overflow (Ref to #443) (#444)
* Implement log-sum-exp trick in Gaussian Mixture Model to prevent overflow * fix lint problem
1 parent 60382a3 commit 7fe5c86

1 file changed

Lines changed: 5 additions & 4 deletions

File tree

  • algorithms/linfa-clustering/src/gaussian_mixture

algorithms/linfa-clustering/src/gaussian_mixture/algorithm.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -341,10 +341,11 @@ impl<F: Float> GaussianMixtureModel<F> {
341341
observations: &ArrayBase<D, Ix2>,
342342
) -> (Array1<F>, Array2<F>) {
343343
let weighted_log_prob = self.estimate_weighted_log_prob(observations);
344-
let log_prob_norm = weighted_log_prob
345-
.mapv(|x| x.exp())
346-
.sum_axis(Axis(1))
347-
.mapv(|x| x.ln());
344+
// Log-sum-exp trick to avoid overflow: ln(Σ exp(xᵢ)) = max + ln(Σ exp(xᵢ - max))
345+
let log_max = weighted_log_prob
346+
.map_axis(Axis(1), |row| row.fold(F::neg_infinity(), |a, &b| a.max(b)));
347+
let shifted = &weighted_log_prob - &log_max.clone().insert_axis(Axis(1));
348+
let log_prob_norm = shifted.mapv(|x| x.exp()).sum_axis(Axis(1)).mapv(|x| x.ln()) + &log_max;
348349
let log_resp = weighted_log_prob - log_prob_norm.to_owned().insert_axis(Axis(1));
349350
(log_prob_norm, log_resp)
350351
}

0 commit comments

Comments
 (0)