From 030929dd0663c5e97a02132ce037580167c28cca Mon Sep 17 00:00:00 2001
From: Ulf Zibis <Ulf.Zibis@CoSoCo.de>
Date: 12.07.2019, 23:24:24

avutil/statistics: New statistic functions for mean and variance

diff --git a/Changelog b/Changelog
index c22d16c..1a8b249 100644
--- a/Changelog
+++ b/Changelog
@@ -36,6 +36,7 @@
 - derain filter
 - deesser filter
 - mov muxer writes tracks with unspecified language instead of English by default
+- libavutil statistics


 version 4.1:
diff --git a/libavutil/Makefile b/libavutil/Makefile
index 8a7a44e..356d80f 100644
--- a/libavutil/Makefile
+++ b/libavutil/Makefile
@@ -69,6 +69,7 @@
           sha.h                                                         \
           sha512.h                                                      \
           spherical.h                                                   \
+          statistics.h                                                  \
           stereo3d.h                                                    \
           threadmessage.h                                               \
           time.h                                                        \
@@ -150,6 +151,7 @@
        sha512.o                                                         \
        slicethread.o                                                    \
        spherical.o                                                      \
+       statistics.o                                                     \
        stereo3d.o                                                       \
        threadmessage.o                                                  \
        time.o                                                           \
diff --git a/libavutil/statistics.c b/libavutil/statistics.c
new file mode 100644
index 0000000..8a90d8a
--- /dev/null
+++ b/libavutil/statistics.c
@@ -0,0 +1,71 @@
+/*
+ * statistic functions
+ * Copyright (c) 2019 Ulf Zibis <Ulf.Zibis@CoSoCo.de>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * statistic functions, mostly useful for debugging/logging purposes
+ * @author Michael Ulf Zibis <Ulf.Zibis@CoSoCo.de>
+ */
+
+#include "common.h"
+#include "statistics.h"
+
+float av_weighted_arith_mean(int16_t x_0, int16_t *weights, uint16_t span)
+{
+    float weights_sum = 0, weighted_sum = 0;
+    for (int16_t i = 0, x = x_0; i < span; i++, x++) {
+        weighted_sum += x * weights[i];
+        weights_sum += weights[i];
+    }
+    return weighted_sum / weights_sum;
+}
+
+float av_weighted_quadr_mean(int16_t x_0, int16_t *weights, uint16_t span, uint8_t signd)
+{
+    float weights_sum = 0, weighted_sum = 0;
+    for (int16_t i = 0, x = x_0; i < span; i++, x++) {
+        weighted_sum += weights[i] * pow(x, 2) * (signd && x < 0 ? -1 : 1);
+        weights_sum += weights[i];
+    }
+    weighted_sum /= weights_sum;
+    return sqrt(fabs(weighted_sum)) * (weighted_sum < 0 ? -1 : 1);
+}
+
+float av_weighted_cubic_mean(int16_t x_0, int16_t *weights, uint16_t span)
+{
+    float weights_sum = 0, weighted_sum = 0;
+    for (int16_t i = 0, x = x_0; i < span; i++, x++) {
+        weighted_sum += weights[i] * pow(x, 3);
+        weights_sum += weights[i];
+    }
+    weighted_sum /= weights_sum;
+    return pow(fabs(weighted_sum), 1 / 3.0) * (weighted_sum < 0 ? -1 : 1);
+}
+
+float av_weighted_variance(int16_t x_0, int16_t *weights, uint16_t span, float mean)
+{
+    float weights_sum = 0, weighted_sum = 0;
+    for (int16_t i = 0, x = x_0; i < span; i++, x++) {
+        weighted_sum += pow(x, 2) * weights[i];
+        weights_sum += weights[i];
+    }
+    return sqrt(weighted_sum / weights_sum - pow(mean, 2));
+}
diff --git a/libavutil/statistics.h b/libavutil/statistics.h
new file mode 100644
index 0000000..50c29d9
--- /dev/null
+++ b/libavutil/statistics.h
@@ -0,0 +1,77 @@
+/*
+ * statistic functions
+ * Copyright (c) 2019 Ulf Zibis <Ulf.Zibis@CoSoCo.de>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * statistic functions, mostly useful for debugging/logging purposes
+ * @author Michael Ulf Zibis <Ulf.Zibis@CoSoCo.de>
+ */
+
+#ifndef AVUTIL_STATISTICS_H
+#define AVUTIL_STATISTICS_H
+
+#if defined(__cplusplus) && !defined(__STDC_FORMAT_MACROS) && !defined(PRId64)
+#error missing -D__STDC_FORMAT_MACROS / #define __STDC_FORMAT_MACROS
+#endif
+
+/**
+ * Calculate the weighted arithmetical mean of a given value span.
+ *
+ * @param x_0 the first value of the span
+ * @param weights the array with the corresponding weights, must at least contain span values
+ * @param span the number of values from x_0 on
+ * @return the weighted arithmetical mean
+ */
+float av_weighted_arith_mean(int16_t x_0, int16_t *weights, uint16_t span);
+
+/**
+ * Calculate the weighted quadratical mean of a given value span.
+ *
+ * @param x_0 the first value of the span
+ * @param weights the array with the corresponding weights, must at least contain span values
+ * @param span the number of values from x_0 on
+ * @param signd if true, respect signed values and return signed result
+ * @return the weighted quadratical mean
+ */
+float av_weighted_quadr_mean(int16_t x_0, int16_t *weights, uint16_t span, uint8_t signd);
+
+/**
+ * Calculate the weighted cubic mean of a given value span.
+ *
+ * @param x_0 the first value of the span
+ * @param weights the array with the corresponding weights, must at least contain span values
+ * @param span the number of values from x_0 on
+ * @return the weighted cubic mean
+ */
+float av_weighted_cubic_mean(int16_t x_0, int16_t *weights, uint16_t span);
+
+/**
+ * Calculate the weighted variance of a given value span.
+ *
+ * @param x_0 the first value of the span
+ * @param weights the array with the corresponding weights, must at least contain span values
+ * @param span the number of values from x_0 on
+ * @param mean the to be precalculated mean of the given value span
+ * @return the weighted variance
+ */
+float av_weighted_variance(int16_t x_0, int16_t *weights, uint16_t span, float mean);
+
+#endif /* AVUTIL_STATISTICS_H */
