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);

}
Example #2
0
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;

   }

}