00001 /* For numerical reasons, it is often best to work with the log of probabilities instead 00002 of the probabilities themselves. Given the set of constants postive constants $A_i$ (stored as 00003 log(A_i)), we frequently need to find $Z$ such that $\frac{1}{Z} \sum A_i = 1$. We provide this 00004 functionality below. All logs are natural logs. */ 00005 00006 #ifndef NPS_ADD_LOGS_H 00007 #define NPS_ADD_LOGS_H 00008 #if !defined BUILDING_NPS_ADD_LOGS && !defined NPS_SMALL 00009 # define NPS_ADD_LOGS_LKG static inline 00010 #else 00011 # define NPS_ADD_LOGS_LKG 00012 #endif 00013 #include <math.h> 00014 #include <stdint.h> 00015 00016 00017 /* log(exp(logA) + exp(logB)) = logA + log(1 + exp(logB - logA)) */ 00018 double nps_logP_add(double logA, double logB); 00019 00020 /* apply nps_logP_add to an array of logP_i to compute log(Z), where Z = \sum P_i. 00021 double nps_logP_logZ(double *restrict logPs, int64_t n); 00022 */ 00023 00024 /* invert un-normalized log probability into probability 00025 logP - a log Probability 00026 logZ - log normalization of the distribution 00027 returns exp(logP - logZ) with checks for numerical issues 00028 */ 00029 double nps_logP_invert(double logP, double logZ); 00030 00031 /* invert un-normalized log probability array into probability array 00032 result - array of size n to hold result 00033 logPs - array of size n 00034 logZ - optional normalizaiton constant (must compute when not given) */ 00035 void nps_logP_invArr(double *result, double *logPs, int64_t n); 00036 00037 #endif 00038 00039