Browse code

Implement av_bmg_next(), a Box-Muller Gaussian random generator.

See the thread:
"[FFmpeg-devel] [PATCH] Box-Muller gaussian generator".

Originally committed as revision 20808 to svn://svn.ffmpeg.org/ffmpeg/trunk

Stefano Sabatini authored on 2009/12/13 01:24:37
Showing 3 changed files
... ...
@@ -35,8 +35,8 @@
35 35
 #define AV_VERSION(a, b, c) AV_VERSION_DOT(a, b, c)
36 36
 
37 37
 #define LIBAVUTIL_VERSION_MAJOR 50
38
-#define LIBAVUTIL_VERSION_MINOR  5
39
-#define LIBAVUTIL_VERSION_MICRO  1
38
+#define LIBAVUTIL_VERSION_MINOR  6
39
+#define LIBAVUTIL_VERSION_MICRO  0
40 40
 
41 41
 #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
42 42
                                                LIBAVUTIL_VERSION_MINOR, \
... ...
@@ -39,6 +39,21 @@ void av_cold av_lfg_init(AVLFG *c, unsigned int seed){
39 39
     c->index=0;
40 40
 }
41 41
 
42
+void av_bmg_get(AVLFG *lfg, double out[2])
43
+{
44
+    double x1, x2, w;
45
+
46
+    do {
47
+        x1 = 2.0/UINT_MAX*av_lfg_get(lfg) - 1.0;
48
+        x2 = 2.0/UINT_MAX*av_lfg_get(lfg) - 1.0;
49
+        w = x1*x1 + x2*x2;
50
+    } while (w >= 1.0);
51
+
52
+    w = sqrt((-2.0 * log(w)) / w);
53
+    out[0] = x1 * w;
54
+    out[1] = x2 * w;
55
+}
56
+
42 57
 #ifdef TEST
43 58
 #include "log.h"
44 59
 #include "common.h"
... ...
@@ -59,6 +74,24 @@ int main(void)
59 59
         STOP_TIMER("624 calls of av_lfg_get");
60 60
     }
61 61
     av_log(NULL, AV_LOG_ERROR, "final value:%X\n", x);
62
+
63
+    /* BMG usage example */
64
+    {
65
+        double mean   = 1000;
66
+        double stddev = 53;
67
+
68
+        av_lfg_init(&state, 42);
69
+
70
+        for (i = 0; i < 1000; i += 2) {
71
+            double bmg_out[2];
72
+            av_bmg_get(&state, bmg_out);
73
+            av_log(NULL, AV_LOG_INFO,
74
+                   "%f\n%f\n",
75
+                   bmg_out[0] * stddev + mean,
76
+                   bmg_out[1] * stddev + mean);
77
+        }
78
+    }
79
+
62 80
     return 0;
63 81
 }
64 82
 #endif
... ...
@@ -51,4 +51,12 @@ static inline unsigned int av_mlfg_get(AVLFG *c){
51 51
     return c->state[c->index++ & 63] = 2*a*b+a+b;
52 52
 }
53 53
 
54
+/**
55
+ * Gets the next two numbers generated by a Box-Muller Gaussian
56
+ * generator using the random numbers issued by lfg.
57
+ *
58
+ * @param out[2] array where are placed the two generated numbers
59
+ */
60
+void av_bmg_get(AVLFG *lfg, double out[2]);
61
+
54 62
 #endif /* AVUTIL_LFG_H */