-
Notifications
You must be signed in to change notification settings - Fork 6
/
hydroexpdist.c
123 lines (112 loc) · 4.44 KB
/
hydroexpdist.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*-------------------------------------------------------------------------------------------
* hydroexpdist.c
*
* Author: Albert Kettner, March 2006
*
* Estimates rainfall distribution: takes (exp(normal-distribution))^1.35 matches the STD
* exactly.
*
* Variable Def.Location Type Units Usage
* -------- ------------ ---- ----- -----
* da[ntot] HydroExpDist double m double array of precip distribution
* db[ntot] HydroExpDist double m double array of precip distribution
* dc[ntot] HydroExpDist double m double array of precip distribution
* dumdbl HydroExpDist double m temporary double
* err various int - error flag, halts program
* ii various int - temporary loop counter
* kk various int - temporary loop counter
* mnth HydroExpDist int - month of the year
* pvals[31] HydroExpDist double m daily precipitation array for a month
* stda HydroExpDist double - STD of the 'a' distribution values
* stdb HydroExpDist double - STD of the 'b' distribution values
* sumx HydroExpDist double m sum of the distribution values
* sumxx HydroExpDist double m sum of the squared distribution values
*
*
*-------------------------------------------------------------------------------------------*/
#include "hydroclimate.h"
#include "hydroparams.h"
#include "hydrodaysmonths.h"
#define ntot (60)
/*---------------------------
* Start of HydroExpDist.c
*---------------------------*/
int
hydroexpdist (double pvals[31], int mnth)
{
double dumdbl, sumx, sumxx;
double stda, stdb;
double da[ntot], db[ntot], dc[ntot];
int ii, kk, err;
/*------------------------
* Initialize variables
*------------------------*/
err = 0;
sumx = 0.0;
sumxx = 0.0;
/*----------------------------------------------------------------
* Transform more than the number of needed values
* this allows for the removal of outliers
* Pretend to be making a two sided distribution with mean == 0
* therefore: sumx == 0
*----------------------------------------------------------------*/
for (ii = 0; ii < ntot; ii++)
{
dumdbl = ranarray[nran];
nran++;
if (dumdbl < 0.0)
dumdbl = -dumdbl;
da[ii] = pow (exp (dumdbl), Pexponent[ep]);
sumxx += sq (da[ii]);
}
/*-------------------------------------------------------------------------
* Calculate the standard deviation of the 1st round of numbers (da[ii])
*-------------------------------------------------------------------------*/
stda = sqrt (sumxx / ntot);
/*-------------------------------------------------------------------
* Normalize the values to the input Standard Deviation (1st Pass)
* remove outliers (or save good values)
* find new Standard Deviation
*-------------------------------------------------------------------*/
sumx = 0.0;
sumxx = 0.0;
kk = 0;
for (ii = 0; ii < ntot; ii++)
{
dumdbl = (Pmassbal[ep] * Pnomstd[mnth][ep] / stda) * da[ii];
if (0 < dumdbl && dumdbl < Prange[ep] * Pmassbal[ep] * Pnomstd[mnth][ep])
{
db[kk] = dumdbl;
sumxx += sq (db[kk]);
kk++;
}
}
/*----------------------------------------------------------------------
* Calculate the Standard Deviation of the generated numbers (db[ii])
*----------------------------------------------------------------------*/
stdb = sqrt (sumxx / kk);
/*-------------------------------------------------------------------
* Normalize the values to the input Standard Deviation (2nd Pass)
*-------------------------------------------------------------------*/
for (ii = 0; ii < kk; ii++)
dc[ii] = (Pmassbal[ep] * Pnomstd[mnth][ep] / stdb) * db[ii];
/*--------------------------------------------
* make sure we return enough usable points
*--------------------------------------------*/
if (kk < daysim[mnth])
{
fprintf (stderr,
" HydroExpDist ERROR: Not enough points generated for the non-normal distribution.\n");
fprintf (stderr, " Increase NTOT in expdist.c \n");
fprintf (stderr, " epoch = %d, year = %d, month = %d, daysim = %d \n",
ep + 1, yr, mnth, daysim[mnth]);
fprintf (stderr, " started ntot \t = %d \n", ntot);
fprintf (stderr, " Generated (kk) \t = %d \n", kk);
fprintf (stderr, " needed daysim \t = %d \n", daysim[mnth]);
err = 1;
}
else
for (ii = 0; ii < daysim[mnth]; ii++)
pvals[ii] = dc[ii];
return (err);
} /* end of HydroExpdDist.c */