void RandUniList( long count, long first, long last, RandListType list[]) { /*------------------------------------------- create a list of random integers from uniform distribution. There are count numbers put into the list array, and the numbers fall between first and last, inclusive. The numbers are non-repeating, and not necessarily ordered. This method only works for a uniform distribution, but it should be fast for any number of count items. cwb - 6/27/00 -------------------------------------------*/ long i, j, c, range, *klist; range = last - first +1; if (count > range || range <= 0) { fprintf(stderr, "Programmer error in RandUniList: " "count > range || range <= 0\n"); exit (-1); } /* if count == range for some weird reason, just fill the array and return */ if (count == range) { for(i=0; i< count; i++) list[i] = first + i; return; } /* if count <= 2, handle things directly */ /* for less complexity and more speed */ if (count <= 2) { list[0] = (long) RandUniRange(first, last); if (count == 2) while ( (list[1] = RandUniRange(first, last)) == list[0]); return; } /* otherwise, go through the whole groovy algorithm */ /* allocate space for the temp list */ klist = (long *) Mem_Malloc(sizeof(long) * range, "RandUniList"); /* populate the list with valid numbers */ for( i=0, j = first; j <= last; klist[i++] = j++); /* now randomize the list */ for( i=0; i < range; i++) { while( (j=RandUniRange(0, range-1) ) == i); c = klist[i]; klist[i] = klist[j]; klist[j] = c; } /* remove count items from the top of the */ /* shuffled list */ for( i=0; i< count; i++) { list[i] = klist[i]; } Mem_Free(klist); }
static void _make_disturbance( void) { /*======================================================*/ /* PURPOSE */ /* Generate disturbances, if any, for this year. */ /* HISTORY */ /* Chris Bennett @ LTER-CSU 6/15/2000 */ /*------------------------------------------------------*/ RealF pc; /* probability of colonization if current */ /* disturbance is fecalpat*/ /*new disturbance event generated, if any*/ DisturbEvent event; /*------------------------------------------------------*/ /* Can't have simultaneous disturbances*/ if (Plot.disturbance != NoDisturb) { switch( Plot.disturbance) { case FecalPat: if (Plot.pat_removed) { Plot.disturbed = 0; Plot.pat_removed = FALSE; Plot.disturbance = NoDisturb; } else { pc = Globals.pat.recol[Slope] * Plot.disturbed + Globals.pat.recol[Intcpt]; if (RandUni() <= pc) { Plot.pat_removed = TRUE; /* slight effects for one year*/ Plot.disturbed = 1; } else { Plot.pat_removed = FALSE; Plot.disturbed++; } } break; default: Plot.disturbed = (Plot.disturbed) ? Plot.disturbed -1 : 0; } if (Plot.disturbed == 0) Plot.disturbance = NoDisturb; } /* if the disturbance was expired above, */ /* we can generate a new one immediately*/ if (Plot.disturbance == NoDisturb) { /* pick some type of disturbance (other than none)*/ event = (DisturbEvent) RandUniRange(1, LastDisturb -1); /* make sure this is off unless needed */ Plot.pat_removed = FALSE; switch( event) { case FecalPat: if (!Globals.pat.use) {event=NoDisturb; break;} event = (RandUni() <= Globals.pat.occur) ? event : NoDisturb; if (event == NoDisturb) break; Plot.pat_removed = (RandUni() <= Globals.pat.removal) ? TRUE : FALSE; Plot.disturbed = 0; break; case AntMound: if (!Globals.mound.use) {event=NoDisturb; break;} event = (RandUni() <= Globals.mound.occur) ? event :NoDisturb; if (event == NoDisturb) break; Plot.disturbed = RandUniRange(Globals.mound.minyr, Globals.mound.maxyr); break; case Burrow: if (!Globals.burrow.use) {event=NoDisturb; break;} event = (RandUni() <= Globals.burrow.occur) ? event :NoDisturb; if (event == NoDisturb) break; Plot.disturbed = (Globals.burrow.minyr > 0) ? RandUniRange(1, Globals.burrow.minyr) : 0; break; } Plot.disturbance = event; } }