Go to the documentation of this file.00001
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005
00006 #include "vnl_sample.h"
00007 #include <vnl/vnl_math.h>
00008
00009 #include <vcl_cmath.h>
00010 #include <vxl_config.h>
00011
00012 #if VXL_STDLIB_HAS_DRAND48
00013 # include <stdlib.h>
00014 #else
00015
00016
00017 static unsigned long vnl_sample_seed = 12345;
00018 #endif
00019
00020 # include <vcl_ctime.h>
00021
00022 void vnl_sample_reseed()
00023 {
00024 #if VXL_STDLIB_HAS_SRAND48
00025 srand48( vcl_time(0) );
00026 #elif !VXL_STDLIB_HAS_DRAND48
00027 vnl_sample_seed = (unsigned long)vcl_time(0);
00028 #endif
00029 }
00030
00031 void vnl_sample_reseed(int seed)
00032 {
00033 #if VXL_STDLIB_HAS_SRAND48
00034 srand48( seed );
00035 #elif !VXL_STDLIB_HAS_DRAND48
00036 vnl_sample_seed = seed;
00037 #endif
00038 }
00039
00040 double vnl_sample_uniform(double a, double b)
00041 {
00042 #if VXL_STDLIB_HAS_DRAND48
00043 double u = drand48();
00044 #else
00045
00046
00047 vnl_sample_seed = (vnl_sample_seed*16807)%2147483647L;
00048 double u = double(vnl_sample_seed)/2147483647L;
00049 #endif
00050 return (1.0 - u)*a + u*b;
00051 }
00052
00053 void vnl_sample_normal_2(double *x, double *y)
00054 {
00055 double u = vnl_sample_uniform(1, 0);
00056 double theta = vnl_sample_uniform(0, 2 * vnl_math::pi);
00057
00058 double r = vcl_sqrt(-2*vcl_log(u));
00059
00060 if (x) *x = r * vcl_cos(theta);
00061 if (y) *y = r * vcl_sin(theta);
00062 }
00063
00064 double vnl_sample_normal(double mean, double sigma)
00065 {
00066 double x;
00067 vnl_sample_normal_2(&x, 0);
00068 return mean + sigma * x;
00069 }
00070
00071
00072 int vnl_sample_bernoulli(double q)
00073 {
00074
00075 if (q==0.0) return 0;
00076 if (q==1.0) return 1;
00077 if (q<0.0 || q>1.0) return -1;
00078
00079 return (vnl_sample_uniform(0.0, 1.0/q) >= 1.0) ? 1 : 0;
00080 }
00081
00082
00083 int vnl_sample_binomial(int n, double q)
00084 {
00085
00086
00087
00088 if (n <= 0 || q<0.0 || q>1.0) return -1;
00089 if (q==0.0) return 0;
00090 if (q==1.0) return n;
00091 int k = 0;
00092 for (int i=n-1; i>=0; --i) {
00093 k += vnl_sample_bernoulli(q);
00094 }
00095 return k;
00096 }