/* 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); }