Example #1
0
/* Calculate SPI assuming incomplete gamma distribution. */
void spi_empiric (int nrun,              /* input - run length */
		  double *pp,            /* input - prec array */
		                         /* dimensioned [NYRS][MONTH_OR_WEEK] */
		  double *index)         /* output - index values */
                                         /* also dimensioned [NYRS][MONTH_OR_WEEK] */
{
  int     im, i, j, n, nsort[MONTH_OR_WEEK];
  double  *temparr, *sort[MONTH_OR_WEEK], *t_ptr;
  
  temparr = (double *) malloc(sizeof(double)*((NYRS)+1));
  
  for (j = 0; j < nrun-1; j++)
    index[j] = MISSING;
  
  for (j = nrun-1; j < NYRS*MONTH_OR_WEEK; j++)
    {
      index[j] = 0.0;
      for (i = 0; i < nrun; i++)
	{
	  if(pp[j - i] != MISSING)
	    index[j] += pp[j - i];
	  else
	    {
	      index[j] = MISSING;
	      break;
	    }
	}
    }
  
  for (i = 0; i<MONTH_OR_WEEK; i++)
    {
      t_ptr = temparr;
      n = 0;
      for (j = nrun+i-1; j<NYRS*MONTH_OR_WEEK; j+=MONTH_OR_WEEK)
	{
	  if(index[j] != MISSING)
	    {
	      *t_ptr = index[j];
	      t_ptr++;
	      n++;
	    }
	}
      im = (nrun + i - 1) % MONTH_OR_WEEK;
      nsort[im] = n;
      sort[im] = empiric_fit (n, temparr);
    }
  
  for (j = nrun-1; j < NYRS*MONTH_OR_WEEK; j++)
    {
      im = j%MONTH_OR_WEEK;
      /*printf("%2d %6.2lf ", im, index[j]);*/
      if(index[j] != MISSING)
	{
	  index[j] = empiric_cdf(nsort[im], sort[im], index[j]);
	  /*printf("%6.2lf ", index[j]);*/
	  index[j] = inv_normal(index[j]);
	  /*printf("%6.2lf\n", index[j]);*/
	}
    }
  free(temparr);
  for(i=0; i<MONTH_OR_WEEK; i++) free(sort[i]);
}
/* Calculate indices assuming incomplete gamma distribution. */
void spi_gamma (int nrun,              /* input - run length */
		double *pp,            /* input - prec array */
				       /* dimensioned [NYRS][12] */
		double *beta,          /* output - beta param */
		double *gamm,          /* output - gamma param */
		double *pzero,         /* output - prob of x = 0 */
		double *index)         /* output - index values */
				       /* also dimensioned [NYRS][12] */
{
    int     im, i, j, n;
    double  *temparr, *t_ptr, alpha;

    /* Allocate temporary space */
    temparr = (double *) malloc(sizeof(double)*((NYRS)+1));

    /* The first nrun-1 index values will be missing. */
    for (j = 0; j < nrun-1; j++)
      index[j] = MISSING;

    /* Sum nrun precip. values; 
       store them in the appropriate index location.
       If any value is missing; set the sum to missing.*/
    for (j = nrun-1; j < NYRS*12; j++)
    {
	index[j] = 0.0;
	for (i = 0; i < nrun; i++)
	{
	  if(pp[j - i] != MISSING)
	    index[j] += pp[j - i];
	  else
	    {
	      index[j] = MISSING;
	      break;
	    }
	}
    }

    /*  For nrun<12, the monthly distributions will be substantially
	different.  So we need to compute gamma parameters for
	each month starting with the (nrun-1)th. */
    for (i = 0; i<12; i++)
    {
    	t_ptr = temparr;
	for (j = nrun+i-1; j<NYRS*12; j+=12)
	{
	    if(index[j] != MISSING)
	      {
		*t_ptr = index[j];
		t_ptr++;
	      }
	}
	n = t_ptr - temparr;
	im = (nrun + i - 1) % 12;  /* im is the calendar month; 0=jan...*/

	/* Here's where we do the fitting. */
	gamma_fit (temparr, n, &alpha, &beta[im], &gamm[im], &pzero[im]);
    }

    /* Replace precip. sums stored in index with SPI's */
    for (j = nrun-1; j < NYRS*12; j++)
    {
    	im = j%12;
	if(index[j] != MISSING)
	  {
	    /* Get the probability */
	    index[j] = gamma_cdf(beta[im], gamm[im], pzero[im], index[j]);

	    /* Convert prob. to z value. */
	    index[j] = inv_normal(index[j]);
	  }
    }

    /* Free temp space and return */
    free(temparr);
}