See the thread:
"[FFmpeg-devel] [PATCH] Box-Muller gaussian generator".
Originally committed as revision 20808 to svn://svn.ffmpeg.org/ffmpeg/trunk
| ... | ... |
@@ -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 */ |