R/defineFeasibleSet.R
defineFeasibleSet.RdExtract the feasible (or behavioural) parameter sets meeting some criteria. These could be used as a feasible set or to estimate prediction quantiles according to the GLUE (Generalised Likelihood Uncertainty Estimation) method.
defineFeasibleSet(x, ...)
# S3 method for hydromad
defineFeasibleSet(x, ..., thin = NA)
# S3 method for default
defineFeasibleSet(
x,
model,
objseq = rep(1, NROW(x)),
frac.within = 0,
within.rel = 0.01,
within.abs = 0.1,
groups = NULL,
FUN = sum,
target.coverage = 1,
threshold = -Inf,
glue.quantiles = c(0, 1),
...
)in the hydromad method this is a hydromad
model object which has been run through either fitBySampling
or fitByDream to generate a large number of random parameter
sets with associated objective function scores. In the default
method, the first argument (x) is a matrix of parameter values
corresponding to the objective function values objseq.
extra arguments to the hydromad method are passed on to
the default method. Extra arguments to the default method will
result in an error.
interval between samples for results from DREAM. As it is a
Markov Chain Monte Carlo method, the sequences should be thinned first to
remove autocorrelation and achieve an efficient sample of the parameter
distributions. The default thinning interval NA uses the empirical
autocorrelation. See window.mcmc.
the hydromad model object to be used to run simulations.
Does not apply to the hydromad method.
objective function values corresponding to the parameter sets
x. This does not apply to the hydromad method, where it is
assumed that the objective function values have already been calculated.
Note that objseq can be omitted if not using the
target.coverage or threshold arguments (i.e. if just defining
an error criterion with frac.within, within.rel, within.abs), so the
original simulation run is not necessary.
model simulations are only retained
in the feasible set if some fraction frac.within of the simulated
values are within a fraction within.rel of the observed values OR
within an absolute difference of within.abs (typically mm/day).
groups is an optional grouping variable, of the
same length as the observed data in model, used to aggregate the
observed and fitted time series. The function FUN is applied to each
group. In this case, the error criteria frac.within, within.rel,
within.abs are evaluated on the aggregated values, not the raw time series.
Also target.coverage applies to the aggregated values. Typically
groups would be generated by cut.Date (for regular time
periods) or eventseq (for events). Note that the
feasible.bounds (e.g. for plotting) in this case will be an
aggregated time series, it will not correspond to the original time index.
Use update or predict to generate bounds on the original time
index.
fraction of the observed values to be contained
within the overall ranges of simulated values (minimum and maximum on each
time step) from the feasible set of parameters. Note, this does not refer to
the glue.quantiles values, but to the overall maximum and minimum.
The simulated values can be within the tolerance limit of observed values
given by within.abs to count as coverage.
value of the objective function (the objective function
used to generate objseq) used to define the feasible set: all
parameter sets above this threshold value will be kept. Also this
threshold value is subtracted from the objective function values to
calculate weights when glue.quantiles is given. If left as
-Inf, it will be set to the minimum objective function value in the
final feasible set.
if specified, these GLUE quantiles of the ensemble
simulations will be calculated and stored. They can be extracted with
fitted and shown in xyplot. The quantiles are calcualted using
the wtd.quantile function, and weighted according to
objseq - threshold. If glue.quantiles is left as
c(0,1) then the overall minimum and maximum simulated values are
taken on each time step, which is faster.
a modified version of model, with added elements
feasible.set, feasible.scores, feasible.fitted,
glue.quantiles and feasible.threshold. Can be passed to
xyplot, fitted, predict, update, coef,
and print.
predict.hydromad, update.hydromad,
fitBySampling, fitByDream
data(Queanbeyan)
ts74 <- window(Queanbeyan, start = "1974-01-01", end = "1976-12-01")
mod <- hydromad(ts74, routing = "expuh", rfit = list("inverse", order = c(2, 1)))
mod <- update(mod,
sma = "cwi",
tw = c(0, 100), f = c(0, 8), loss = c(-0.1, 0.1)
)
## Calculate the set of simulations within 15% error (or 1 mm/day) 90% of time.
## In this case we do not need to calculate objective function values
## beforehand. For GLUE quantiles, however, need to give 'objective'.
psets <- parameterSets(coef(mod), samples = 300)
#> Warning: parameters not fully specified, returning list
feas <- defineFeasibleSet(psets,
model = mod,
frac.within = 0.9, within.rel = 0.15, within.abs = 1
)
## How many of the 300 possible parameter sets were retained?
nrow(coef(feas, feasible.set = TRUE))
#> [1] 111
## View ranges of parameters in feasible set
feas
#>
#> Hydromad model with "cwi" SMA and "expuh" routing:
#> Start = 1974-01-01, End = 1976-12-01
#>
#> SMA Parameters:
#> lower upper
#> tw 0 100
#> f 0 8
#> scale NA NA
#> l 0 0 (==)
#> p 1 1 (==)
#> t_ref 20 20 (==)
#> Routing Parameters:
#> lower upper
#> tau_s 13.0292 13.0292 (==)
#> tau_q 0.5728 0.5728 (==)
#> v_s 0.4433 0.4433 (==)
#> v_q 0.5567 0.5567 (==)
#> delay 1.0000 1.0000 (==)
#> loss -0.1000 0.1000
#> Feasible parameter set:
#> tw f scale l p t_ref tau_s tau_q v_s v_q delay loss
#> lower 0.00 0 NA 0 1 20 13.03 0.5728 0.4433 0.5567 1 -0.09933
#> upper 97.66 8 NA 0 1 20 13.03 0.5728 0.4433 0.5567 1 0.10000
#>
#> Routing fit info: list(TRUE, 2)
## Plot simulation bounds
xyplot(feas, feasible.bounds = TRUE, cut = 3)
## Generate set of simulations with NSE > 0.5, for GLUE.
## First, need to calculate objective function values:
fit <- fitBySampling(mod, samples = 300, objective = hmadstat("r.squared"))
## Calculate 5 percent and 95 percent GLUE quantiles (i.e. weighted).
fitglu <- defineFeasibleSet(fit,
threshold = 0.5,
glue.quantiles = c(0.05, 0.95)
)
## Coverage of the GLUE quantile simulations (within 0.1 mm/day)
sim <- fitted(fitglu, feasible.bounds = TRUE)
head(sim)
#> GLUE.5 GLUE.95
#> 1974-04-11 4.9134569 15.603560
#> 1974-04-12 3.9902576 12.379516
#> 1974-04-13 1.8160592 5.819653
#> 1974-04-14 1.7512514 5.715896
#> 1974-04-15 1.0651009 3.628814
#> 1974-04-16 0.7150688 2.528074
mean((sim[, 1] < observed(fitglu) + 0.1) &
(sim[, 2] > observed(fitglu) - 0.1))
#> [1] 0.8964803
## Or - keep adding parameter sets until we reach a target coverage:
## Calculate 5 percent and 95 percent GLUE quantiles (i.e. weighted).
fitglu <- defineFeasibleSet(fit,
target.coverage = 0.9,
glue.quantiles = c(0.05, 0.95)
)
## Coverage of the GLUE quantile simulations (within 0.1 mm/day)
## (not to be confused with the target.coverage to define overall feasible set)
sim <- fitted(fitglu, feasible.bounds = TRUE)
mean((sim[, 1] < observed(fitglu) + 0.1) &
(sim[, 2] > observed(fitglu) - 0.1))
#> [1] 0.800207
## Plot simulated GLUE quantiles
xyplot(fitglu, feasible.bounds = TRUE, cut = 3)
xyplot(fitglu,
feasible.bounds = TRUE, cut = 3,
scales = list(y = list(log = TRUE))
)
## Summarise size of the simulation bounds: lower as fraction of upper
summary(coredata(sim[, 1] / sim[, 2]))
#> Min. 1st Qu. Median Mean 3rd Qu. Max.
#> 0.0000 0.1608 0.2364 0.2600 0.3643 0.8062
## Simulate on a new data period
newglu <- update(fitglu,
newdata = window(Queanbeyan,
start = "1980-01-01", end = "1982-01-01"
),
glue.quantiles = c(0.05, 0.95)
)
## The new period is very dry, all model simulations overestimate flow.
xyplot(newglu, feasible.bounds = TRUE, cut = 3)
## Coverage of the GLUE quantile simulations (within 0.1 mm/day)
sim <- fitted(newglu, feasible.bounds = TRUE)
mean((sim[, 1] < observed(newglu) + 0.1) &
(sim[, 2] > observed(newglu) - 0.1))
#> [1] 0.6977848