00001
00016 #include <stdlib.h>
00017 #include <math.h>
00018 #include <errno.h>
00019 #include <string.h>
00020 #include <stdarg.h>
00021 #include <time.h>
00022 #include <float.h>
00023 #include "random.h"
00024 #include "find.h"
00025 #include "output.h"
00026 #include "exception.h"
00027 #include "globals.h"
00028 #include "complex.h"
00029
00030 #ifdef WIN32
00031 #define finite _finite
00032 #endif
00033
00034 #define QNAN sqrt(-1)
00035
00036 static unsigned int *ur_state = NULL;
00037
00038 int random_init(void)
00039 {
00040
00041 if (global_randomseed==0)
00042 srand((unsigned int)time(NULL));
00043 else
00044 {
00045 srand(1);
00046 ur_state = &global_randomseed;
00047 }
00048
00049 return 1;
00050 }
00051
00054 static struct {
00055 char *name;
00056 RANDOMTYPE type;
00057 int nargs;
00058 } *p, map[] = {
00059
00060 {"degenerate", RT_DEGENERATE,1},
00061 {"uniform",RT_UNIFORM,2},
00062 {"normal",RT_NORMAL,2},
00063 {"bernoulli",RT_BERNOULLI,1},
00064 {"sampled",RT_SAMPLED,-1},
00065 {"pareto",RT_PARETO,2},
00066 {"lognormal",RT_LOGNORMAL,2},
00067 {"exponential",RT_EXPONENTIAL,1},
00068 {"rayleigh",RT_RAYLEIGH,1},
00069
00070 {"weibull",RT_WEIBULL,2},
00071 {"gamma",RT_GAMMA,1},
00072 {"beta",RT_BETA,2},
00073 {"triangle",RT_TRIANGLE,2},
00075 };
00078 RANDOMTYPE random_type(char *name)
00079 {
00080 for (p=map; p<map+sizeof(map)/sizeof(map[0]); p++)
00081 {
00082 if (strcmp(p->name,name)==0)
00083 return p->type;
00084 }
00085 return RT_INVALID;
00086 }
00089 int random_nargs(char *name)
00090 {
00091 for (p=map; p<map+sizeof(map)/sizeof(map[0]); p++)
00092 {
00093 if (strcmp(p->name,name)==0)
00094 return p->nargs;
00095 }
00096 return 0;
00097 }
00098
00100 int randwarn()
00101 {
00102 static int warned=0;
00103 if (global_nondeterminism_warning && !warned)
00104 {
00105 warned=1;
00106 output_warning("non-deterministic behavior probable--rand was called while running multiple threads");
00107 }
00108
00109 return rand();
00110 }
00111
00112
00113 double randunit(void)
00114 {
00115 double u;
00116 unsigned int ur;
00117
00118 if (ur_state!=NULL)
00119 srand(*ur_state);
00120 ur = randwarn();
00121 if (ur_state!=NULL)
00122 *ur_state = ur;
00123 u = ur/(RAND_MAX+1.0);
00124 if (u<1) return u;
00125
00126 return randunit();
00127 }
00128 double randunit_pos(void)
00129 {
00130 double ur = 0.0;
00131 while (ur<=0)
00132 ur = randunit();
00133 return ur;
00134 }
00135
00142 double random_degenerate(double a)
00143 {
00144
00145 double aa = fabs(a);
00146 if (a!=0 && (aa<1e-30 || aa>1e30))
00147 output_warning("random_degenerate(a=%g): a is outside normal bounds of +/-1e(+/-30)", a);
00148
00149
00150
00151
00152 return a;
00153 }
00154
00168 double random_uniform(double a,
00169 double b)
00170 {
00171
00172 double aa=fabs(a), ab=fabs(b);
00173 if (a!=0 && (aa<1e-30 || aa>1e30))
00174 output_warning("random_uniform(a=%g, b=%g): a is outside normal bounds of +/-1e(+/-30)", a, b);
00175
00176
00177
00178
00179 if (b!=0 && (ab<1e-30 || ab>1e30))
00180 output_warning("random_uniform(a=%g, b=%g): b is outside normal bounds of +/-1e(+/-30)", a, b);
00181
00182
00183
00184
00185 if (b<a)
00186 output_warning("random_uniform(a=%g, b=%g): b is less than a", a, b);
00187
00188
00189
00190
00191 return randunit()*(b-a)+a;
00192 }
00193
00215 double random_normal(double m,
00216 double s)
00217 {
00218
00219 double r=randunit();
00220 if (s<0)
00221 output_warning("random_normal(m=%g, s=%g): s is negative", m, s);
00222
00223
00224
00225
00226 while (r<=0 || r>1)
00227 r=randunit();
00228 return sqrt(-2*log(r)) * sin(2*PI*randunit())*s+m;
00229 }
00230
00238 double random_bernoulli(double p)
00239 {
00240 double ap = fabs(p);
00241 if (ap!=0 && (ap<1e-30 || ap>1e30))
00242 output_warning("random_bernoulli(p=%g): p is not within the normal bounds of +/-1e(+/-30)", p);
00243
00244
00245
00246
00247 if (p<0 || p>1)
00248 output_warning("random_bernoulli(p=%g): p is not between 0 and 1", p);
00249
00250
00251
00252
00253
00254 return (p>=randunit()) ? 1 : 0;
00255 }
00256
00265 double random_sampled(unsigned n,
00266 double *x)
00267 {
00268 if (n>0)
00269 {
00270 double v = x[(unsigned)(randunit()*n)];
00271 double av = fabs(v);
00272 if (v!=0 && (v<1e-30 || v>1e30))
00273 output_warning("random_sampled(n=%d,...): sampled value is not within normal bounds of +/-1e(+/-30)",n);
00274
00275
00276
00277
00278 return v;
00279 }
00280 else
00281 {
00282 throw_exception("random_sampled(n=%d,...): n must be a positive number", n);
00283
00284
00285
00286
00287 return QNAN;
00288 }
00289 }
00290
00291
00300 double random_pareto(double m,
00301 double k)
00302 {
00303 double am = fabs(m);
00304 double ak = fabs(k);
00305 double r = randunit();
00306 if (am!=0 && (am<1e-03 || am>1e30))
00307 output_warning("random_pareto(m=%g, k=%g): m is not within the normal bounds of +/-1e(+/-30)", m, k);
00308
00309
00310
00311
00312 if (ak>1e30)
00313 output_warning("random_pareto(m=%g, k=%g): k is not within the normal bounds of +/-1e(+/-30)", m, k);
00314
00315
00316
00317
00318 if (k<=0)
00319 throw_exception("random_pareto(m=%g, k=%g): k must be greater than 1", m, k);
00320
00321
00322
00323
00324 while (r<=0 || r>=1)
00325 r = randunit();
00326 return m*pow(r,-1/k);
00327 }
00328
00334 double random_lognormal(double gmu,
00335 double gsigma)
00336 {
00337 return exp(random_normal(0,1)*gsigma+gmu);
00338 }
00339
00351 double random_exponential(double lambda)
00352 {
00353 double r=randunit();
00354 if (lambda<=0)
00355 throw_exception("random_exponential(l=%g): l must be greater than 0", lambda);
00356
00357
00358
00359
00360 if (lambda<1e-30 || lambda>1e30)
00361 output_warning("random_exponential(l=%g): l is not within the normal bounds of 1e(+/-30)", lambda);
00362
00363
00364
00365
00366 while (r<=0 || r>=1)
00367 r=randunit();
00368 return -log(r)/lambda;
00369 }
00370
00380 double random_weibull(double lambda,
00381 double k)
00382 {
00383 double r = randunit();
00384 if (k<=0)
00385 throw_exception("random_weibull(l=%g, k=%g): k must be greater than 0", lambda, k);
00386
00387
00388
00389
00390 return lambda * pow(-log(1-randunit()),1/k);
00391 }
00392
00400 double random_rayleigh(double sigma)
00401 {
00402 return sigma*sqrt(-2*log(1-randunit()));
00403 }
00404
00412 double random_gamma(double alpha, double beta)
00413 {
00414
00415 double na = floor(alpha);
00416 if (fabs(na-alpha)<1e-8 && na<12)
00417 {
00418 unsigned int i;
00419 double prod = 1;
00420 for (i=0; i<na; i++)
00421 prod *= randunit_pos();
00422 return -beta * log(prod);
00423 }
00424 else if (na<1)
00425 {
00426 double p, q, x, u, v;
00427 p = E/(alpha+E);
00428 do {
00429 u = randunit();
00430 v = randunit_pos();
00431 if (u<p)
00432 {
00433 x = exp((1/alpha)*log(v));
00434 q = exp(-x);
00435 }
00436 else
00437 {
00438 x = 1 - log(v);
00439 q = exp((alpha-1)*log(x));
00440 }
00441 } while (randunit()>=q);
00442 return beta*x;
00443 }
00444 else
00445 {
00446 double sqrta = sqrt(2*alpha-1);
00447 double x, y, v;
00448 do {
00449 do {
00450 y = tan(PI*randunit());
00451 x = sqrta*y+alpha-1;
00452 } while (x<=0);
00453 v = randunit();
00454 } while (v>(1+y*y) * exp((alpha-1)*log(x/(alpha-1))-sqrta*y));
00455 return beta*x;
00456 }
00457 }
00458
00467 double random_beta(double alpha, double beta)
00468 {
00469
00470 double x1 = random_gamma(alpha,1);
00471 double x2 = random_gamma(beta,1);
00472 return x1 / (x1+x2);
00473 }
00474
00490 double random_triangle(double a, double b)
00491 {
00492 return (randunit() + randunit())*(b-a)/2 + a;
00493 }
00494
00495
00496 static double _random_value(RANDOMTYPE type, va_list ptr)
00497 {
00498 switch (type) {
00499 case RT_DEGENERATE:
00500 { double a = va_arg(ptr,double);
00501 return random_degenerate(a);
00502 }
00503 case RT_UNIFORM:
00504 { double min = va_arg(ptr,double);
00505 double max = va_arg(ptr,double);
00506 return random_uniform(min,max);
00507 }
00508 case RT_NORMAL:
00509 { double mu = va_arg(ptr,double);
00510 double sigma = va_arg(ptr,double);
00511 return random_normal(mu,sigma);
00512 }
00513 case RT_BERNOULLI:
00514 return random_bernoulli(va_arg(ptr,double));
00515 case RT_SAMPLED:
00516 { unsigned n_samples = va_arg(ptr,unsigned);
00517 double *samples = va_arg(ptr,double*);
00518 return random_sampled(n_samples,samples);
00519 }
00520 case RT_PARETO:
00521 { double base = va_arg(ptr,double);
00522 double gamma = va_arg(ptr,double);
00523 return random_pareto(base,gamma);
00524 }
00525 case RT_LOGNORMAL:
00526 { double gmu = va_arg(ptr,double);
00527 double gsigma = va_arg(ptr,double);
00528 return random_lognormal(gmu,gsigma);
00529 }
00530 case RT_EXPONENTIAL:
00531 { double lambda = va_arg(ptr,double);
00532 return random_exponential(lambda);
00533 }
00534 case RT_RAYLEIGH:
00535 { double sigma = va_arg(ptr,double);
00536 return random_rayleigh(sigma);
00537 }
00538 case RT_WEIBULL:
00539 { double lambda = va_arg(ptr,double);
00540 double k = va_arg(ptr,double);
00541 return random_weibull(lambda,k);
00542 }
00543 case RT_GAMMA:
00544 { double alpha = va_arg(ptr,double);
00545 double beta = va_arg(ptr,double);
00546 return random_gamma(alpha,beta);
00547 }
00548 case RT_BETA:
00549 { double alpha = va_arg(ptr,double);
00550 double beta = va_arg(ptr,double);
00551 return random_beta(alpha,beta);
00552 }
00553 case RT_TRIANGLE:
00554 { double a = va_arg(ptr,double);
00555 double b = va_arg(ptr,double);
00556 return random_triangle(a,b);
00557 }
00558 default:
00559 throw_exception("_random_value(type=%d,...); type is not valid",type);
00560
00561
00562
00563
00564 }
00565 return QNAN;
00566 }
00567
00571 int random_apply(char *group_expression,
00572 char *property,
00573 RANDOMTYPE type,
00574 ...)
00575 {
00576 FINDLIST *list = find_objects(FL_GROUP, group_expression);
00577 OBJECT *obj;
00578 unsigned count=0;
00579 va_list ptr;
00580 va_start(ptr,type);
00581 for (obj=find_first(list); obj!=NULL; find_next(list,obj))
00582 {
00583
00584 object_set_double_by_name(obj,property,_random_value(type,ptr));
00585 count++;
00586 }
00587 va_end(ptr);
00588 return count;
00589 }
00590
00594 double random_value(RANDOMTYPE type,
00595 ...)
00596 {
00597 double x;
00598 va_list ptr;
00599 va_start(ptr,type);
00600 x = _random_value(type,ptr);
00601 va_end(ptr);
00602 return x;
00603 }
00604
00608 double pseudorandom_value(RANDOMTYPE type,
00609 unsigned int *state,
00610 ...)
00611 {
00612 double x;
00613 va_list ptr;
00614 va_start(ptr,state);
00615
00616 ur_state = state;
00617 x = _random_value(type,ptr);
00618
00619 ur_state = NULL;
00620 va_end(ptr);
00621 return x;
00622 }
00623
00624
00625 static double mean(double sample[], unsigned int count)
00626 {
00627 double sum=0;
00628 unsigned int i;
00629 for (i=0; i<count; i++)
00630 sum += sample[i];
00631 return sum/count;
00632 }
00633 #ifdef min
00634 #undef min
00635 #endif
00636 static double min(double sample[], unsigned int count)
00637 {
00638 double min;
00639 unsigned int i;
00640 for (i=0; i<count; i++)
00641 {
00642 if (i==0) min=sample[0];
00643 else if (sample[i]<min) min=sample[i];
00644 }
00645 return min;
00646 }
00647 #ifdef max
00648 #undef max
00649 #endif
00650 static double max(double sample[], unsigned int count)
00651 {
00652 double max;
00653 unsigned int i;
00654 for (i=0; i<count; i++)
00655 {
00656 if (i==0) max=sample[0];
00657 else if (sample[i]>max) max=sample[i];
00658 }
00659 return max;
00660 }
00661 static double stdev(double sample[], unsigned int count)
00662 {
00663 double sum=0, mean=0;
00664 unsigned int n = 0, i;
00665 for (i=0; i<count; i++)
00666 {
00667 double delta = sample[i] - mean;
00668 n++;
00669 mean += delta/n;
00670 sum += delta*(sample[i]-mean);
00671 }
00672 return sqrt(sum/(n-1));
00673 }
00674 static void sort(double sample[], unsigned int count)
00675 {
00676 }
00677 static int report(char *parameter, double actual, double expected, double error)
00678 {
00679 if (parameter==NULL)
00680 {
00681 output_test(" Parameter Actual Expected Error");
00682 output_test("---------------- ---------- ---------- ----------");
00683 return 0;
00684 }
00685 else
00686 {
00687 int iserror = fabs(actual-expected)>error ? 1 : 0;
00688 if (expected==0)
00689 output_test("%-16.16s %10.4f %10.4f %9.6f %s", parameter,actual,expected,actual-expected, iserror?"ERROR":"");
00690 else
00691 output_test("%-16.16s %10.4f %10.4f %9.6f%% %s", parameter,actual,expected,(actual-expected)/expected*100, iserror?"ERROR":"");
00692 return iserror;
00693 }
00694 }
00695
00702 int random_test(void)
00703 {
00704 int failed = 0, ok=0, errorcount=0, preverrors=0;
00705 static double sample[1000000];
00706 double a, b;
00707 unsigned int count = sizeof(sample)/sizeof(sample[0]);
00708 unsigned int i;
00709 unsigned int initstate, state;
00710
00711 output_test("\nBEGIN: random random distributions tests");
00712
00713
00714 a = 10*randunit()/2-5;
00715 output_test("\ndegenerate(x=%g)",a);
00716 for (i=0; i<count; i++)
00717 {
00718 sample[i] = random_degenerate(a);
00719 if (!finite(sample[i]))
00720 failed++,output_test("Sample %d is not a finite number!",i--);
00721 }
00722 errorcount+=report(NULL,0,0,0);
00723 errorcount+=report("Mean",mean(sample,count),a,0.01);
00724 errorcount+=report("Stdev",stdev(sample,count),0,0.01);
00725 errorcount+=report("Min",min(sample,count),a,0.01);
00726 errorcount+=report("Max",max(sample,count),a,0.01);
00727 if (preverrors==errorcount) ok++; else failed++;
00728 preverrors=errorcount;
00729
00730
00731 a = 10*randunit()/2;
00732 b = 10*randunit()/2 + 5;
00733 output_test("\nuniform(min=%g, max=%g)",a,b);
00734 for (i=0; i<count; i++)
00735 {
00736 sample[i] = random_uniform(a,b);
00737 if (!finite(sample[i]))
00738 failed++,output_test("Sample %d is not a finite number!",i--);
00739 }
00740 errorcount+=report(NULL,0,0,0);
00741 errorcount+=report("Mean",mean(sample,count),(a+b)/2,0.01);
00742 errorcount+=report("Stdev",stdev(sample,count),sqrt((b-a)*(b-a)/12),0.01);
00743 errorcount+=report("Min",min(sample,count),a,0.01);
00744 errorcount+=report("Max",max(sample,count),b,0.01);
00745 if (preverrors==errorcount) ok++; else failed++;
00746 preverrors=errorcount;
00747
00748
00749 a = randunit();
00750 output_test("\nBernoulli(prob=%g)",a);
00751 for (i=0; i<count; i++)
00752 {
00753 sample[i] = random_bernoulli(a);
00754 if (!finite(sample[i]))
00755 failed++,output_test("Sample %d is not a finite number!",i--);
00756 }
00757 errorcount+=report(NULL,0,0,0.01);
00758 errorcount+=report("Mean",mean(sample,count),a,0.01);
00759 errorcount+=report("Stdev",stdev(sample,count),sqrt(a*(1-a)),0.01);
00760 errorcount+=report("Min",min(sample,count),0,0.01);
00761 errorcount+=report("Max",max(sample,count),1,0.01);
00762 if (preverrors==errorcount) ok++; else failed++;
00763 preverrors=errorcount;
00764
00765
00766 a = 20*randunit()-5;
00767 b = 5*randunit();
00768 output_test("\nnormal(mean=%g, stdev=%g)",a,b);
00769 for (i=0; i<count; i++)
00770 {
00771 sample[i] = random_normal(a,b);
00772 if (!finite(sample[i]))
00773 failed++,output_test("Sample %d is not a finite number!",i--);
00774 }
00775 errorcount+=report(NULL,0,0,0.01);
00776 errorcount+=report("Mean",mean(sample,count),a,0.01);
00777 errorcount+=report("Stdev",stdev(sample,count),b,0.01);
00778 if (preverrors==errorcount) ok++; else failed++;
00779 preverrors=errorcount;
00780
00781
00782 a = 1/randunit()-1;
00783 output_test("\nexponential(lambda=%g)",a);
00784 for (i=0; i<count; i++)
00785 {
00786 sample[i] = random_exponential(a);
00787 if (!finite(sample[i]))
00788 failed++,output_test("Sample %d is not a finite number!",i--);
00789 }
00790 errorcount+=report(NULL,0,0,0.01);
00791 errorcount+=report("Mean",mean(sample,count),1/a,0.01);
00792 errorcount+=report("Stdev",stdev(sample,count),1/a,0.01);
00793 errorcount+=report("Min",min(sample,count),0,0.01);
00794 if (preverrors==errorcount) ok++; else failed++;
00795 preverrors=errorcount;
00796
00797
00798 a = 2*randunit()-1;
00799 b = 2*randunit();
00800 output_test("\nlognormal(gmean=%g, gstdev=%g)",a,b);
00801 for (i=0; i<count; i++)
00802 {
00803 sample[i] = random_lognormal(a,b);
00804 if (!finite(sample[i]))
00805 failed++,output_test("Sample %d is not a finite number!",i--);
00806 }
00807 errorcount+=report(NULL,0,0,0.01);
00808 errorcount+=report("Mean",mean(sample,count),exp(a+b*b/2),0.01);
00809 errorcount+=report("Stdev",stdev(sample,count),sqrt((exp(b*b)-1)*exp(2*a+b*b)),0.1);
00810 errorcount+=report("Min",min(sample,count),0,0.1);
00811 if (preverrors==errorcount) ok++; else failed++;
00812 preverrors=errorcount;
00813
00814
00815 a = 10*randunit();
00816 b = randunit()*2+2;
00817 output_test("\nPareto(base=%g, gamma=%g)",a,b);
00818 for (i=0; i<count; i++)
00819 {
00820 sample[i] = random_pareto(a,b);
00821 if (!finite(sample[i]))
00822 failed++,output_test("Sample %d is not a finite number!",i--);
00823 }
00824 errorcount+=report(NULL,0,0,0.01);
00825 errorcount+=report("Mean",mean(sample,count),b*a/(b-1),0.01);
00826 errorcount+=report("Stdev",stdev(sample,count),sqrt(a*a*b/((b-1)*(b-1)*(b-2))),0.25);
00827 errorcount+=report("Min",min(sample,count),a,0.01);
00828 if (preverrors==errorcount) ok++; else failed++;
00829 preverrors=errorcount;
00830
00831
00832 a = 10*randunit();
00833 b = 4*randunit();
00834 output_test("\nRayleigh(sigma=%g)",a);
00835 for (i=0; i<count; i++)
00836 {
00837 sample[i] = random_rayleigh(a);
00838 if (!finite(sample[i]))
00839 failed++,output_test("Sample %d is not a finite number!",i--);
00840 }
00841 errorcount+=report(NULL,0,0,0.01);
00842 errorcount+=report("Mean",mean(sample,count),a*sqrt(3.1415926/2),0.01);
00843 errorcount+=report("Stdev",stdev(sample,count),sqrt((4-3.1415926)/2*a*a),0.01);
00844 if (preverrors==errorcount) ok++; else failed++;
00845 preverrors=errorcount;
00846
00847
00848 a = 15*randunit();
00849 b = 4*randunit();
00850 output_test("\nBeta(a=%f,b=%f)",a,b);
00851 for (i=0; i<count; i++)
00852 {
00853 sample[i] = random_beta(a,b);
00854 if (!finite(sample[i]))
00855 failed++,output_test("Sample %d is not a finite number!",i--);
00856 }
00857 errorcount+=report(NULL,0,0,0.01);
00858 errorcount+=report("Mean",mean(sample,count),a/(a+b),0.01);
00859 errorcount+=report("Stdev",stdev(sample,count),sqrt(a*b/((a+b)*(a+b)*(a+b+1))),0.01);
00860 if (preverrors==errorcount) ok++; else failed++;
00861 preverrors=errorcount;
00862
00863
00864 a = 15*randunit();
00865 b = 4*randunit();
00866 output_test("\nGamma(a=%f,b=%f)",a,b);
00867 for (i=0; i<count; i++)
00868 {
00869 sample[i] = random_gamma(a,b);
00870 if (!finite(sample[i]))
00871 failed++,output_test("Sample %d is not a finite number!",i--);
00872 }
00873 errorcount+=report(NULL,0,0,0.01);
00874 errorcount+=report("Mean",mean(sample,count),a*b,0.25);
00875 errorcount+=report("Stdev",stdev(sample,count),sqrt(a*b*b),0.01);
00876 if (preverrors==errorcount) ok++; else failed++;
00877 preverrors=errorcount;
00878
00879
00880 a = -randunit()*10;
00881 b = randunit()*10;
00882 output_test("\nTriangle(a=%f,b=%f)",a,b);
00883 for (i=0; i<count; i++)
00884 {
00885 sample[i] = random_triangle(a,b);
00886 if (!finite(sample[i]))
00887 output_test("Sample %d is not a finite number!",i--);
00888 }
00889 errorcount+=report(NULL,0,0,0.01);
00890 errorcount+=report("Mean",mean(sample,count),(a+b)/2,0.01);
00891 errorcount+=report("Stdev",stdev(sample,count),sqrt((a-b)*(a-b)/24),0.01);
00892 if (preverrors==errorcount) ok++; else failed++;
00893 preverrors=errorcount;
00894
00895
00896 output_test("\nSampled(count=10, sample=[0..9])");
00897 for (i=0; i<count; i++)
00898 {
00899 double set[10]={0,1,2,3,4,5,6,7,8,9};
00900 sample[i] = random_sampled(10,set);
00901 if (!finite(sample[i]))
00902 failed++,output_test("Sample %d is not a finite number!",i--);
00903 }
00904 errorcount+=report(NULL,0,0,0.01);
00905 errorcount+=report("Mean",mean(sample,count),4.5,0.01);
00906
00907 errorcount+=report("Stdev",stdev(sample,count),sqrt(99/12),0.1);
00908 errorcount+=report("Min",min(sample,count),0,0.01);
00909 errorcount+=report("Max",max(sample,count),9,0.01);
00910 if (preverrors==errorcount) ok++; else failed++;
00911 preverrors=errorcount;
00912
00913
00914 output_test("\nNon-deterministic test (N=%d)",count);
00915 for (i=0; i<count; i++)
00916 sample[i] = random_value(RT_NORMAL,0,1);
00917 for (i=0; i<count; i++)
00918 {
00919 double v = random_value(RT_NORMAL,0,1);
00920 if (sample[i] == v)
00921 failed++,output_test("Sample %d matched (%f==%f)", sample[i],v);
00922 }
00923 if (preverrors==errorcount) ok++; else failed++;
00924 preverrors=errorcount;
00925
00926
00927 initstate = state = rand();
00928 output_test("\nDeterministic test for state %u (N=%d)",initstate,count);
00929 for (i=0; i<count; i++)
00930 sample[i] = pseudorandom_value(RT_NORMAL,&state,0,1);
00931 state = initstate;
00932 for (i=0; i<count; i++)
00933 {
00934 double v = pseudorandom_value(RT_NORMAL,&state,0,1);
00935 if (sample[i] != v)
00936 failed++,output_test("Sample %d did not match (%f!=%f)", sample[i],v);
00937 }
00938 if (preverrors==errorcount) ok++; else failed++;
00939 preverrors=errorcount;
00940
00941
00942 if (failed)
00943 {
00944 output_error("randtest: %d random distributions tests failed--see test.txt for more information",failed);
00945 output_test("!!! %d random distributions tests failed, %d errors found",failed,errorcount);
00946 }
00947 else
00948 {
00949 output_verbose("%d random distributions tests completed with no errors--see test.txt for details",ok);
00950 output_test("randtest: %d random distributions tests completed, %d errors found",ok,errorcount);
00951 }
00952 output_test("END: random distributions tests");
00953 return failed;
00954 }
00955