forked from hydromad/hydromad
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathevalParsRollapply.Rd
157 lines (139 loc) · 5.11 KB
/
evalParsRollapply.Rd
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/evalParsRollapply.R
\name{evalParsRollapply}
\alias{evalParsRollapply}
\alias{evalParsTS}
\title{Calculate an objective function on a rolling time series for a matrix of
parameters}
\usage{
evalParsRollapply(
par.matrix,
object,
width = 30,
objective = hydromad.getOption("objective"),
parallel = hydromad.getOption("parallel")[["evalParsTS"]],
filehash.name = tempfile()
)
evalParsTS(
par.matrix,
object,
fun = function(thisMod) fitted(thisMod),
length.out = NULL,
...,
parallel = hydromad.getOption("parallel")[["evalParsTS"]],
filehash.name = tempfile()
)
}
\arguments{
\item{par.matrix}{Named matrix or data.frame of parameter values, with each
row corresponding to a model realisation to evaluate}
\item{object}{an object of class \code{hydromad}.}
\item{width}{integer specifying window width, aligned center. Passed to
\code{\link[zoo]{rollapply}}}
\item{objective}{the objective function or expression, which can refer to Q
and X. See \code{\link{objFunVal.hydromad}}}
\item{parallel}{If \code{"clusterApply"}, evaluate parameters in parallel
using a local cluster. The implementation assumes that the \code{ff}
file \code{filehash.name} can be written to simultaneously all cluster
workers.}
\item{filehash.name}{Name of \code{ff} file in which to store
results, allowing large samples that do not fit in memory. Defaults to
\code{tempfile()}, which is automatically deleted when exiting from R. To
store results in memory, set \code{filehash.name=NULL}.}
\item{fun}{function that takes a hydromad object and returns a vector, by
default the fitted timeseries.}
\item{length.out}{Length of output vector returned by \code{fun}. If
missing, \code{fun} will be run on the first parameter set in
\code{par.matrix}.}
\item{\dots}{Additional arguments to \code{fun}}
}
\value{
Either a matrix or \code{ff} file-backed matrix, with each
row being a time series of rolling objective functions for the corresponding
row of \code{par.matrix}
}
\description{
For each row of a named matrix of parameters, run a model and return a
vector. By default, \code{evalParsTS} returns the predicted time series.
\code{evalParsRollapply} instead calculates an objective function on rolling
windows of the resulting time series, i.e. see how the objective function
changes over time. Special facilities are provided to evaluate large sample
sizes, including with parallelisation.
}
\details{
If timeseries are long, then the results matrix will be large
(\code{nrow(par.matrix)} x \code{length.out}). By default the results matrix
is therefore stored in a \code{ff} file-backed matrix.
Individual model evaluations are generally very fast, so parallelisation is
only really worthwhile when large numbers of evaluations are needed.
Parallelisation method \code{"clusterApply"} uses multiple R sessions that
write to a shared \code{ff} object. It only operates on a single
multicore machine. Parallelisation method \code{"foreach"} offers a broader
range of options but only works if the final results matrix is small enough
to fit in memory.
}
\note{
When using \code{ff}, performance may be improved by specifying
\code{options(ffcaching='mmeachflush')}.
}
\examples{
data(Cotter)
obs <- Cotter[1:1000]
## Define rainfall-runoff model structure
object <- hydromad(obs,
sma = "cwi", routing = "expuh",
tau_q = c(0, 2), tau_s = c(2, 100), v_s = c(0, 1)
)
## Set the random seed to obtain replicable results
set.seed(19)
# Draw 10 Latin Hypercube random samples
par.matrix <- parameterSets(getFreeParsRanges(object), samples = 10)
# Calculate rolling time series of r.squared for each parameter set,
# keeping results in memory
runs <- evalParsRollapply(par.matrix, object,
objective = hmadstat("r.squared"), filehash.name = NULL
)
\dontrun{
## Setup parallelisation on three cores
library(parallel)
hydromad.options("parallel" = list("evalParsTS" = "clusterApply"))
cl <- makeCluster(3)
clusterEvalQ(cl, library(hydromad))
par.matrix <- parameterSets(getFreeParsRanges(object), samples = 1000)
# Calculate rolling time series of r.squared for each parameter set,
# storing result in tempfile()
# Takes about 2 minutes
runs <- evalParsRollapply(par.matrix, object,
objective = hmadstat("r.squared")
)
# Excerpt of results
runs
# Path of backing file - about 7MB
filename(runs)
# ff object can be used like a regular matrix, e.g. plotting the
# rolling time series of R.squared for the first parameter set
plot(runs[1, ])
## Do the same with foreach
library(doParallel)
registerDoParallel(cl)
hydromad.options("parallel" = list("evalParsTS" = "foreach"))
runs <- evalParsRollapply(par.matrix, object,
objective = hmadstat("r.squared"), filehash.name = NULL
)
## runs is a matrix
}
}
\references{
Herman, J. D., P. M. Reed, and T. Wagener. 2013. "Time-Varying
Sensitivity Analysis Clarifies the Effects of Watershed Model Formulation on
Model Behavior." Water Resources Research 49 (3): 1400-1414.
doi: \href{http://dx.doi.org/10.1002/wrcr.2012410.1002/wrcr.20124}{here}
}
\seealso{
\code{\link{evalPars}} to calculate a single objective function for
each parameter set
}
\author{
Joseph Guillaume
}
\keyword{models}