a b/tests/testthat/test_moves.R
1
context("Test movements")
2
3
## test various movements  ##
4
test_that("Movements preserve param structure", {
5
    ## skip on CRAN
6
    skip_on_cran()
7
8
9
    ## generate inputs
10
    data(fake_outbreak)
11
    data <- with(fake_outbreak,
12
                 outbreaker_data(dates = onset,
13
                                 w_dens = w,
14
                                 dna = dna))
15
    config <- create_config(data = data)
16
17
    config_no_move <- create_config(
18
      move_alpha = FALSE,
19
      move_t_inf = FALSE,
20
      move_mu = FALSE, move_pi = FALSE,
21
      move_eps = FALSE, move_lambda = FALSE,
22
      move_kappa = FALSE,
23
      move_swap_cases = FALSE, data = data)
24
25
    data <- add_convolutions(data = data, config = config)
26
    param <- create_param(data = data, config = config)$current
27
    ll <- custom_likelihoods()
28
    priors <- custom_priors()
29
30
    moves <- bind_moves(config = config, data = data,
31
                          likelihoods = ll, priors = priors)
32
    moves_no_move <- bind_moves(config = config_no_move,
33
                                  likelihoods = ll, priors = priors)
34
35
36
    ## test moves lists ##
37
    expect_equal(length(moves_no_move), 0L)
38
    expect_equal(length(moves), 6L)
39
    expect_true(all(vapply(moves, is.function, logical(1))))
40
41
42
43
44
    ## test moves ##
45
    for (i in seq_along(moves)) {
46
47
        ## chech closure: data
48
        expect_identical(environment(moves[[i]])$data, data)
49
50
        ## make moves
51
        set.seed(1)
52
        res <- moves[[i]](param = param)
53
54
        ## check that content in param after movements has identical shape
55
        expect_equal(length(param), length(res))
56
        expect_equal(length(unlist(param)), length(unlist(res)))
57
        expect_equal(names(param), names(res))
58
59
    }
60
61
})
62
63
64
65
66
67
68
test_that("Binding of moves works", {
69
    ## skip on CRAN
70
    skip_on_cran()
71
72
73
    ## generate inputs
74
    data(fake_outbreak)
75
    data <- with(fake_outbreak,
76
                 outbreaker_data(dates = onset,
77
                                 w_dens = w,
78
                                 dna = dna))
79
    config <- create_config(data = data)
80
    data <- add_convolutions(data = data, config = config)
81
    param <- create_param(data = data, config = config)$current
82
    ll <- custom_likelihoods()
83
    priors <- custom_priors()
84
85
    ## check re-input consistency
86
    expect_identical(custom_moves(),
87
                     custom_moves(custom_moves()))
88
89
    ## check custom_moves defaults
90
    moves <- custom_moves()
91
92
    expect_length(moves, 8L)
93
    expect_true(all(vapply(moves, is.function, FALSE)))
94
    expect_named(moves)
95
    expected_names <- c("mu", "pi", "eps", "lambda", "alpha", "swap_cases", "t_inf", "kappa")
96
    expect_true(all(expected_names %in% names(moves)))
97
98
99
    ## check binding
100
    moves <- bind_moves(moves, config = config, data = data,
101
                          likelihoods = ll, priors = priors)
102
103
    exp_names <- c("custom_prior", "custom_ll", "config", "data")
104
    expect_true(all(exp_names %in% names(environment(moves$mu))))
105
106
    exp_names <- c("custom_prior", "custom_ll", "config", "data")
107
    expect_true(all(exp_names %in% names(environment(moves$pi))))
108
109
    exp_names <- c("list_custom_ll", "data")
110
    expect_true(all(exp_names %in% names(environment(moves$alpha))))
111
112
    exp_names <- c("list_custom_ll", "data")
113
    expect_true(all(exp_names %in% names(environment(moves$swap_cases))))
114
115
    exp_names <- c("list_custom_ll", "data")
116
    expect_true(all(exp_names %in% names(environment(moves$t_inf))))
117
118
    exp_names <- c("list_custom_ll", "config", "data")
119
    expect_true(all(exp_names %in% names(environment(moves$kappa))))
120
121
})
122
123
124
125
126
127
128
test_that("Customisation of moves works", {
129
    ## skip on CRAN
130
    skip_on_cran()
131
132
133
    ## generate inputs
134
    data(fake_outbreak)
135
    data <- with(fake_outbreak,
136
                 outbreaker_data(dates = onset,
137
                                 w_dens = w,
138
                                 dna = dna))
139
    config <- create_config(data = data, n_iter = 1000,
140
                            find_import = FALSE,
141
                            sample_every = 10)
142
    data <- add_convolutions(data = data, config = config)
143
    param <- create_param(data = data, config = config)$current
144
    ll <- custom_likelihoods()
145
    priors <- custom_priors()
146
147
148
    ## check custom movement for mu - outside outbreaker
149
    f <- function(param, data, config = NULL) {
150
        return(param)
151
    }
152
153
    moves <- bind_moves(list(mu = f), config = config, data = data,
154
                          likelihoods = ll, priors = priors)
155
156
    expect_identical(body(moves$mu), body(f))
157
    expect_identical(names(formals(moves$mu)), "param")
158
    expect_identical(data, environment(moves$mu)$data)
159
    expect_identical(config, environment(moves$mu)$config)
160
    expect_identical(moves$mu(param), param)
161
162
163
    ## same check, run within outbreaker
164
    out <- outbreaker(data, config, moves = list(mu = f))
165
    expect_true(all(out$mu == 1e-4))
166
167
})
168
169
170
171
172
173
174
## test swapping and temporal ordering  ##
175
test_that("Swap equally likely index cases", {
176
    ## skip on CRAN
177
    skip_on_cran()
178
179
180
    ## generate inputs
181
    data <- outbreaker_data(dates = c(50, 51, 110),
182
                            w_dens = rep(1, 100))
183
    config <- create_config(init_kappa = 1,
184
                            move_kappa = FALSE,
185
                            find_import = FALSE,
186
                            data = data)
187
188
    set.seed(1)
189
    res <- outbreaker(data, config)
190
    table(res$alpha_1)
191
    table(res$alpha_2)
192
    table(res$alpha_3)
193
194
})
195
196
197
198
199
200
201
## test kappa estimates
202
test_that("Kappa estimates are correct", {
203
    ## skip on CRAN
204
    skip_on_cran()
205
206
    ## sequence and onset data that supports kappa = c(3, 1, 1)
207
    dna <- matrix(c("t", "t", "t", "t", "t", "t", "t", "t", "t", "t", "t", "t", "t", "t", "t", "t", "t", "t",
208
                    "g", "g", "g", "g", "g", "g", "t", "t", "t", "t", "t", "t", "t", "t", "t", "t", "t", "t",
209
                    "g", "g", "g", "g", "g", "g", "c", "c", "t", "t", "t", "t", "t", "t", "t", "t", "t", "t",
210
                    "g", "g", "g", "g", "g", "g", "c", "c", "a", "a", "t", "t", "t", "t", "t", "t", "t", "t"),
211
                  byrow = TRUE, nrow = 4)
212
    dna <- ape::as.DNAbin(dna)
213
214
    dates <- c(10, 40, 50, 60)
215
216
    ## strong suport for generation time = 10 days
217
    w <- dgamma(1:20, shape = 25, scale = 0.4)
218
219
    data <- outbreaker_data(dates = dates, dna = dna, w_dens = w)
220
    config <- create_config(prior_pi = c(1, 1), prior_mu = c(0.1),
221
                            init_mu = 2/18, sd_mu = 0.1, n_iter = 5e4)
222
223
    set.seed(2)
224
    res <- outbreaker(data, config)
225
226
    ## function to get most frequent item
227
    get_mode <- function(x) {
228
      as.integer(names(sort(table(x, exclude = NULL), decreasing = TRUE)[1]))
229
    }
230
231
    kappa <- as.matrix(res[,grep("kappa", names(res))])
232
    kappa <- as.vector(apply(kappa, 2, get_mode))
233
    expect_equal(c(NA, 3, 1, 1), kappa)
234
235
})