This is s.onefrand.c in view mode; [Download] [Up]
h14773 s 00001/00001/00068 d D 1.2 86/09/17 23:21:27 root 2 1 c switched to random(). e s 00069/00000/00000 d D 1.1 84/08/11 11:56:02 root 1 0 c original distributed version e u U f i t T I 1 /* %M% %I% (CARL) %G% %U% */ /* * 1/f noise according to Voss' algorithm. * Sequence length (seq) may be any number, but is truncated to the * nearest power of 2. * The algorithm: * Select log2(sequence) separate white noise generators, i.e., * one for each bit of a binary number. * Initialize a counting register. * In a loop, add 1 to the counting register, determine which * bits have changed from its previous value. For each changed * bit, invoke the appropriate generator to produce a new number. * Sum the normalized output of all generators as the current number. * The procedure f1init() is used to reset the sequence length. * On the next call to onefrand(), the new value of seq will be used. */ #include<math.h> #include<stdio.h> static f1ini; static double seq = 32.0*1024.0; double onefrand(lb, ub) double lb, ub; { double tmp; register int i, dif; static int gens; static double *sums; double sum; static double div; static int cnt = -1, ocnt; if (f1ini == 0) { f1ini++; if (seq <= 1.0) seq = 2.0; gens = log(seq) / log(2.0); if (sums != NULL) free(sums); sums = (double *) malloc(sizeof(double)*gens); for (i = 0; i < gens; i++) sums[i] = 0; div = pow(2.0, (double) ((sizeof(int) * 8) - 1)) - 1.0; } ocnt = cnt++; /* increment count */ dif = cnt ^ ocnt; /* set sums to change */ for ( i = 0; i < gens; i++ ) /* form new sums */ { if (dif & (1 << i)) D 2 sums[i] = rand(); E 2 I 2 sums[i] = random(); E 2 } for ( sum = i = 0; i < gens; i++ ) /* sum them all */ sum += sums[i]; sum /= gens * div; sum = (sum * (ub - lb)) + lb; /* norm to spec */ return(sum); } f1init(sequence) double sequence; { f1ini = 0; seq = sequence; } E 1
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.