00001 /* 00002 * HydroExpDist.c Estimates a rainfall distribution: 00003 * takes (exp(normal-distribution))^1.35 00004 * matches the STD exactly 00005 * 00006 * Variable Def.Location Type Units Usage 00007 * -------- ------------ ---- ----- ----- 00008 * da[ntot] HydroExpDist double m double array of precip distribution 00009 * db[ntot] HydroExpDist double m double array of precip distribution 00010 * dc[ntot] HydroExpDist double m double array of precip distribution 00011 * dumdbl HydroExpDist double m temporary double 00012 * err various int - error flag, halts program 00013 * ii various int - temporary loop counter 00014 * kk various int - temporary loop counter 00015 * mnth HydroExpDist int - month of the year 00016 * pvals[31] HydroExpDist double m daily precipitation array for a month 00017 * stda HydroExpDist double - STD of the 'a' distribution values 00018 * stdb HydroExpDist double - STD of the 'b' distribution values 00019 * sumx HydroExpDist double m sum of the distribution values 00020 * sumxx HydroExpDist double m sum of the squared distribution values 00021 * 00022 * 00023 * Original: July 1998 Mark Morehead 00024 */ 00025 #include "hydroclimate.h" 00026 #include "hydroparams.h" 00027 #include "hydrodaysmonths.h" 00028 00029 #ifdef DBG 00030 #include "hydroinout.h" 00031 #endif 00032 00033 #define ntot (60) 00034 00035 /*--------------------------- 00036 * Start of HydroExpDist.c 00037 *---------------------------*/ 00038 int hydroexpdist(double pvals[31],int mnth) 00039 { 00040 00041 double dumdbl, sumx, sumxx; 00042 double stda, stdb; 00043 double da[ntot], db[ntot], dc[ntot]; 00044 int ii, kk, err; 00045 00046 /*------------------------ 00047 * Initialize variables 00048 *------------------------*/ 00049 err = 0; 00050 sumx = 0.0; 00051 sumxx = 0.0; 00052 00053 /*---------------------------------------------------------------- 00054 * Transform more than the number of needed values 00055 * this allows for the removal of outliers 00056 * Pretend to be making a two sided distribution with mean == 0 00057 * therefore: sumx == 0 00058 *----------------------------------------------------------------*/ 00059 for( ii=0; ii<ntot; ii++) { 00060 dumdbl = ranarray[nran]; 00061 nran++; 00062 if( dumdbl < 0.0 ) 00063 dumdbl = -dumdbl; 00064 da[ii] = pow(exp(dumdbl),Pexponent[ep]); 00065 sumxx += sq(da[ii]); 00066 } 00067 00068 /*------------------------------------------------------------------------- 00069 * Calculate the standard deviation of the 1st round of numbers (da[ii]) 00070 *-------------------------------------------------------------------------*/ 00071 stda = sqrt( sumxx/ntot); 00072 00073 /*------------------------------------------------------------------- 00074 * Normalize the values to the input Standard Deviation (1st Pass) 00075 * remove outliers (or save good values) 00076 * find new Standard Deviation 00077 *-------------------------------------------------------------------*/ 00078 sumx = 0.0; 00079 sumxx = 0.0; 00080 kk = 0; 00081 for( ii=0; ii<ntot; ii++ ) { 00082 dumdbl = (Pmassbal[ep]*Pnomstd[mnth][ep]/stda)*da[ii]; 00083 if( 0 < dumdbl && dumdbl < Prange[ep]*Pmassbal[ep]*Pnomstd[mnth][ep] ) { 00084 db[kk] = dumdbl; 00085 sumxx += sq(db[kk]); 00086 kk++; 00087 } 00088 } 00089 00090 /*---------------------------------------------------------------------- 00091 * Calculate the Standard Deviation of the generated numbers (db[ii]) 00092 *----------------------------------------------------------------------*/ 00093 stdb = sqrt( sumxx/kk); 00094 00095 /*------------------------------------------------------------------- 00096 * Normalize the values to the input Standard Deviation (2nd Pass) 00097 *-------------------------------------------------------------------*/ 00098 for( ii=0; ii<kk; ii++) 00099 dc[ii] = (Pmassbal[ep]*Pnomstd[mnth][ep]/stdb)*db[ii]; 00100 00101 /*-------------------------------------------- 00102 * make sure we return enough usable points 00103 *--------------------------------------------*/ 00104 //if( kk < daysim[mnth] ) { 00105 if ( kk < days_in_month(mnth) ) { 00106 fprintf( stderr, " HydroExpDist ERROR: Not enough points generated for the non-normal distribution.\n"); 00107 fprintf( stderr, " Increase NTOT in expdist.c \n"); 00108 // fprintf( stderr, " epoch = %d, year = %d, month = %d, daysim = %d \n",ep+1,yr,mnth,daysim[mnth]); 00109 fprintf( stderr, " epoch = %d, year = %d, month = %d, daysim = %d \n",ep+1,yr,mnth,days_in_month(mnth)); 00110 fprintf( stderr, " started ntot \t = %d \n", ntot); 00111 fprintf( stderr, " Generated (kk) \t = %d \n", kk); 00112 // fprintf( stderr, " needed daysim \t = %d \n", daysim[mnth]); 00113 fprintf( stderr, " needed daysim \t = %d \n", days_in_month(mnth)); 00114 err = 1; 00115 } 00116 else 00117 // for( ii=0; ii<daysim[mnth]; ii++ ) 00118 for( ii=0; ii<days_in_month(mnth) ; ii++ ) 00119 pvals[ii] = dc[ii]; 00120 00121 00122 #ifdef DBG 00123 if( tblstart[ep] <= yr && yr <= tblend[ep] && mnth == 0 ) { 00124 fprintf( fidlog, " HydroExpDist:\n"); 00125 // fprintf( fidlog, " epoch = %d, year = %d, month = %d, daysim = %d \n",ep+1,yr,mnth+1,daysim[mnth]); 00126 fprintf( fidlog, " epoch = %d, year = %d, month = %d, daysim = %d \n",ep+1,yr,mnth+1,days_in_month(mnth)); 00127 fprintf( fidlog, " started ntot \t = %d \n", ntot); 00128 fprintf( fidlog, " Generated (kk) \t = %d \n", kk); 00129 // fprintf( fidlog, " needed daysim \t = %d \n", daysim[mnth]); 00130 fprintf( fidlog, " needed daysim \t = %d \n", days_in_month(mnth)); 00131 sumx = 0.0; 00132 if( 0 ) { 00133 // for( ii=0; ii<daysim[mnth]; ii++) { 00134 for( ii=0; ii<days_in_month(mnth); ii++) { 00135 fprintf( fidlog, " ii = %d, \t pvals[ii] = %f \n", ii, pvals[ii] ); 00136 sumx += pvals[ii]; 00137 } 00138 fprintf( fidlog, " sum(pvals) \t = %f \n\n", sumx ); 00139 } 00140 } 00141 00142 #endif 00143 00144 return(err); 00145 } /* end of HydroExpdDist.c */