Back to index

radiance  4R0+20100331
urand.c
Go to the documentation of this file.
00001 #ifndef lint
00002 static const char    RCSid[] = "$Id: urand.c,v 2.10 2006/04/05 06:22:56 greg Exp $";
00003 #endif
00004 /*
00005  * Anticorrelated random function due to Christophe Schlick
00006  */
00007 
00008 #include "copyright.h"
00009 
00010 #include  <stdlib.h>
00011 
00012 #include  "standard.h"
00013 #include  "random.h"
00014 
00015 #undef initurand
00016 
00017 #define  MAXORDER    (8*sizeof(unsigned short))
00018 
00019 static unsigned short  empty_tab = 0;
00020 
00021 unsigned short  *urperm = &empty_tab;     /* urand() permutation */
00022 int  urmask = 0;                   /* bits used in permutation */
00023 
00024 int
00025 initurand(size)             /* initialize urand() for size entries */
00026 int  size;
00027 {
00028        int  order, n;
00029        register int  i, offset;
00030 
00031        if ((urperm != NULL) & (urperm != &empty_tab))
00032               free((void *)urperm);
00033        if (--size <= 0) {
00034               empty_tab = 0;
00035               urperm = &empty_tab;
00036               urmask = 0;
00037               return(0);
00038        }
00039        for (i = 1; (size >>= 1); i++)
00040               if (i == MAXORDER)
00041                      break;
00042        order = i;
00043        urmask = (1<<order) - 1;
00044        urperm = (unsigned short *)malloc((urmask+1)*sizeof(unsigned short));
00045        if (urperm == NULL) {
00046               eputs("out of memory in initurand\n");
00047               quit(1);
00048        }
00049        urperm[0] = 0;
00050        for (n = 1, offset = 1; n <= order; n++, offset <<= 1)
00051               for (i = offset; i--; ) {
00052                      urperm[i+offset] = urperm[i] <<= 1;
00053                      if (random() & 0x4000)
00054                             urperm[i]++;
00055                      else
00056                             urperm[i+offset]++;
00057               }
00058        return(urmask+1);
00059 }
00060 
00061 
00062 int
00063 ilhash(d, n)                /* hash a set of integer values */
00064 register int  *d;
00065 register int  n;
00066 {
00067        static int  tab[8] = {103699,96289,73771,65203,81119,87037,92051,98899};
00068        register int  hval;
00069 
00070        hval = 0;
00071        while (n-- > 0)
00072               hval ^= *d++ * tab[n&7];
00073        return(hval & 0x7fffffff);
00074 }