#! /usr/bin/python3 # Last edited on 2026-02-15 13:07:58 by stolfi def log_tot_prob_from_plogs(QL): # Given a list {QL} of negative numbers, # returns {log(sum{ exp(p) : p in QL})} debug = False np = len(QL) if np == 0: return 0.0 # Sort the list in increasing order: QL = sorted(QL) # Compute the result by factoring the largest factor: max_log = QL[-1] if debug: err.write(f" {max_log = :12.6f}") tot_prob = 0; for p in QL: tot_prob += exp(p - max_log) if debug: err.write(f" {tot_prob = :12.6e}\n") return max_log + log(tot_prob) # ---------------------------------------------------------------------- def test_log_tot_prob_from_plogs(QL, plog_exp): err.write(f"!! with {QL = } {plog_exp = :12.6f}") plog_cmp = log_tot_prob_from_plogs(QL) err.write(f" {plog_cmp = :12.6f}\n") den = max(abs(plog_exp), 1.0e-200) assert abs(plog_cmp - plog_exp)/den < 1.0e-8 return # ---------------------------------------------------------------------- def test_log_tot_prob_from_plogs_all(): err.write("testing {log_tot_prob_from_plogs}\n") test_log_tot_prob_from_plogs([], 0.0) test_log_tot_prob_from_plogs([-6.57], -6.57) test_log_tot_prob_from_plogs([-3.14, -6.57], log(exp(-3.14) + exp(-6.57))) return # ---------------------------------------------------------------------- test_log_tot_prob_from_plogs_all()