aboutsummaryrefslogtreecommitdiff
path: root/libcrystfel/src/utils.h
diff options
context:
space:
mode:
authorWolfgang Brehm <wolfgang.brehm@gmail.com>2019-08-01 13:10:51 +0200
committerThomas White <taw@physics.org>2019-08-26 14:04:06 +0200
commit63542ec9e052b147da54a656c9eed6ec35efe431 (patch)
treef31d0f1263017dcf7dd920ec27f94c52034fafcd /libcrystfel/src/utils.h
parent14b58086754586c4cf431ee0b54cb4adc7cc4cfd (diff)
add stable inline mean variance function
Diffstat (limited to 'libcrystfel/src/utils.h')
-rw-r--r--libcrystfel/src/utils.h21
1 files changed, 20 insertions, 1 deletions
diff --git a/libcrystfel/src/utils.h b/libcrystfel/src/utils.h
index cd21bd93..44e6af6c 100644
--- a/libcrystfel/src/utils.h
+++ b/libcrystfel/src/utils.h
@@ -35,6 +35,7 @@
#include <math.h>
#include <complex.h>
+#include <float.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
@@ -268,7 +269,25 @@ static inline struct quaternion invalid_quaternion(void)
return quat;
}
-
+/* function to compute mean and variance stably
+ * \param x value
+ * \param w weight
+ * \param sumw pointer to accumulator variable for the sum of weights
+ * \param mean pointer to online mean value
+ * \param M2 pointer to online variance times sumw
+ */
+static inline void mean_variance(const double x,
+ const double w,
+ double* sumw, double* mean, double* M2)
+{
+ if (w<DBL_MIN) return;
+ const double temp = w + *sumw;
+ const double delta = x - *mean;
+ const double R = delta * w / temp;
+ *mean += R;
+ *M2 += *sumw*delta*R;
+ *sumw = temp;
+}
#ifdef __cplusplus
}