From 547ed8e9f1132bf8eff36dc789019a523cbc2a90 Mon Sep 17 00:00:00 2001 From: Ralf Stubner Date: Sun, 30 Jul 2023 16:36:15 +0000 Subject: [PATCH] Feature/weighted sampling (#47) Weighted sampling * Move sampling code to separate header file * Add weighted sampling methods * Document sampling algorithm * Add vignette on sampling methods --- DESCRIPTION | 9 +- LICENSE | 1 + NEWS.md | 3 + R/dqsample.R | 7 +- README.Rmd | 32 +++- README.md | 74 ++++++-- inst/include/dqrng_generator.h | 14 ++ inst/include/dqrng_sample.h | 107 +++++++++++ man/dqrng-package.Rd | 3 +- man/dqsample.Rd | 2 +- src/dqrng.cpp | 68 +------ tests/testthat/test-sample.R | 71 +++++-- vignettes/.gitignore | 2 + vignettes/cpp-api.Rmd | 2 +- vignettes/data/no-replacement-high.RDS | Bin 0 -> 1404 bytes vignettes/data/no-replacement-long.RDS | Bin 0 -> 1737 bytes vignettes/data/no-replacement-low.RDS | Bin 0 -> 60371 bytes vignettes/data/no-replacement-medium.RDS | Bin 0 -> 19534 bytes vignettes/data/replacement.RDS | Bin 0 -> 55362 bytes vignettes/data/weighted-no-replacement.RDS | Bin 0 -> 1276 bytes vignettes/data/weighted-replacement.RDS | Bin 0 -> 1445 bytes vignettes/dqrng.Rmd | 16 +- vignettes/parallel.Rmd | 45 ++--- vignettes/sample.Rmd | 211 +++++++++++++++++++++ 24 files changed, 527 insertions(+), 140 deletions(-) create mode 100644 inst/include/dqrng_sample.h create mode 100644 vignettes/.gitignore create mode 100644 vignettes/data/no-replacement-high.RDS create mode 100644 vignettes/data/no-replacement-long.RDS create mode 100644 vignettes/data/no-replacement-low.RDS create mode 100644 vignettes/data/no-replacement-medium.RDS create mode 100644 vignettes/data/replacement.RDS create mode 100644 vignettes/data/weighted-no-replacement.RDS create mode 100644 vignettes/data/weighted-replacement.RDS create mode 100644 vignettes/sample.Rmd diff --git a/DESCRIPTION b/DESCRIPTION index f3d3b97..7fc7502 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: dqrng Type: Package Title: Fast Pseudo Random Number Generators -Version: 0.3.0.1 +Version: 0.3.0.2 Authors@R: c( person("Ralf", "Stubner", email = "ralf.stubner@gmail.com", role = c("aut", "cre")), person("daqana GmbH", role = "cph"), @@ -19,10 +19,13 @@ Description: Several fast random number generators are provided as C++ numbers according to a uniform, normal and exponential distribution are included. The latter two use the Ziggurat algorithm originally proposed by Marsaglia and Tsang (2000, ). - These functions are exported to R and as a C++ interface and are + The fast sampling methods support weighted and unweighted sampling both with + and without replacement. For weighted sampling a stochastic acceptance method + suggested by Lipowski and Lipowska (2012, ) + is used. These functions are exported to R and as a C++ interface and are enabled for use with the default 64 bit generator from the PCG family, Xoroshiro128+ and Xoshiro256+ as well as the 64 bit version of the 20 rounds - Threefry engine (Salmon et al., 2011 ) as + Threefry engine (Salmon et al., 2011, ) as provided by the package 'sitmo'. License: AGPL-3 | file LICENSE Depends: R (>= 3.1.0) diff --git a/LICENSE b/LICENSE index 6ea7597..ea6e636 100644 --- a/LICENSE +++ b/LICENSE @@ -16,4 +16,5 @@ License: AGPL-3 Files: * Copyright: 2018-2019 Ralf Stubner (daqana GmbH) + 2022-2023 Ralf Stubner License: AGPL-3 diff --git a/NEWS.md b/NEWS.md index da5c90f..d495c98 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,6 +1,9 @@ # dgrng (unreleased) * new method `dqrrademacher` for drawing Rademacher weights (Kyle Butts in [#50](https://github.com/daqana/dqrng/pull/50 fixing [#49](https://github.com/daqana/dqrng/pull/49)) +* Implement weighted sampling with and without replacement. + Move sampling methods to separate header file, allowing for parallel usage. + ([#47](https://github.com/daqana/dqrng/pull/47) fixing [#18](https://github.com/daqana/dqrng/issues/18) and [#26](https://github.com/daqana/dqrng/issues/26)) # dqrng 0.3.0 diff --git a/R/dqsample.R b/R/dqsample.R index 601dca6..abd2170 100644 --- a/R/dqsample.R +++ b/R/dqsample.R @@ -4,7 +4,7 @@ ##' @param size a non-negative integer giving the number of items to choose. ##' @param replace should sampling be with replacement? ##' @param prob a vector of probability weights for obtaining the elements of the vector being sampled. -##' @seealso \code{\link{sample}} and \code{\link{sample.int}} +##' @seealso \code{vignette("sample", package = "dqrng")}, \code{\link{sample}} and \code{\link{sample.int}} ##' @export dqsample <- function(x, size, replace = FALSE, prob = NULL) { if(length(x) == 1L && is.numeric(x) && is.finite(x) && x >= 1) { @@ -19,10 +19,7 @@ dqsample <- function(x, size, replace = FALSE, prob = NULL) { ##' @rdname dqsample ##' @export dqsample.int <- function(n, size = n, replace = FALSE, prob = NULL) { - if (!is.null(prob)) { - warning("Using 'prob' is not supported yet. Using default 'sample.int'.") - sample.int(n, size, replace, prob) - } else if (n <= .Machine$integer.max) + if (n <= .Machine$integer.max) dqsample_int(n, size, replace, prob, 1L) else dqsample_num(n, size, replace, prob, 1L) diff --git a/README.Rmd b/README.Rmd index 2765f22..8787ff9 100644 --- a/README.Rmd +++ b/README.Rmd @@ -35,12 +35,13 @@ install.packages("dqrng") ``` Intermediate releases can also be obtained via -[drat](https://cran.r-project.org/package=drat): +[r-universe](https://rstub.r-universe.dev/dqrng): ```r -if (!requireNamespace("drat", quietly = TRUE)) install.packages("drat") -drat::addRepo("daqana") -install.packages("dqrng") +options(repos = c( + rstub = 'https://rstub.r-universe.dev', + CRAN = 'https://cloud.r-project.org')) +install.packages('dqrng') ``` ## Example @@ -89,6 +90,29 @@ bm[, 1:4] Note that sampling from `10^10` elements triggers "long-vector support" in R. +It is also possible to use weighted sampling both with replacement: + +```{r sampling3} +m <- 1e6 +n <- 1e4 +prob <- dqrunif(m) +bm <- bench::mark(sample.int(m, n, replace = TRUE, prob = prob), + dqsample.int(m, n, replace = TRUE, prob = prob), + check = FALSE) +bm[, 1:4] +``` + +And without replacement: + +```{r sampling4} +bm <- bench::mark(sample.int(m, n, prob = prob), + dqsample.int(m, n, prob = prob), + check = FALSE) +bm[, 1:4] +``` + +Especially for weighted sampling without replacement the performance advantage compared with R's default methods is particularly large. + In addition the RNGs provide support for multiple independent streams for parallel usage: ```{r parallel} diff --git a/README.md b/README.md index c7001f4..af011c3 100644 --- a/README.md +++ b/README.md @@ -29,12 +29,13 @@ install.packages("dqrng") ``` Intermediate releases can also be obtained via -[drat](https://cran.r-project.org/package=drat): +[r-universe](https://rstub.r-universe.dev/dqrng): ``` r -if (!requireNamespace("drat", quietly = TRUE)) install.packages("drat") -drat::addRepo("daqana") -install.packages("dqrng") +options(repos = c( + rstub = 'https://rstub.r-universe.dev', + CRAN = 'https://cloud.r-project.org')) +install.packages('dqrng') ``` ## Example @@ -57,11 +58,11 @@ They are quite a bit faster, though: N <- 1e4 bm <- bench::mark(rnorm(N), dqrnorm(N), check = FALSE) bm[, 1:4] -#> # A tibble: 2 x 4 +#> # A tibble: 2 × 4 #> expression min median `itr/sec` #> -#> 1 rnorm(N) 598.9µs 670µs 1414. -#> 2 dqrnorm(N) 85.5µs 89µs 9663. +#> 1 rnorm(N) 612µs 685.2µs 1397. +#> 2 dqrnorm(N) 86µs 88.6µs 10388. ``` This is also true for the provided sampling functions with replacement: @@ -75,13 +76,13 @@ bm <- bench::mark(sample.int(m, n, replace = TRUE), dqsample.int(1e3*m, n, replace = TRUE), check = FALSE) bm[, 1:4] -#> # A tibble: 4 x 4 +#> # A tibble: 4 × 4 #> expression min median `itr/sec` #> -#> 1 sample.int(m, n, replace = TRUE) 6.94ms 7.52ms 131. -#> 2 sample.int(1000 * m, n, replace = TRUE) 8.8ms 9.64ms 101. -#> 3 dqsample.int(m, n, replace = TRUE) 304.75µs 444.96µs 2207. -#> 4 dqsample.int(1000 * m, n, replace = TRUE) 397.96µs 675.24µs 1502. +#> 1 sample.int(m, n, replace = TRUE) 6.88ms 7.63ms 114. +#> 2 sample.int(1000 * m, n, replace = TRUE) 8.72ms 9.55ms 96.1 +#> 3 dqsample.int(m, n, replace = TRUE) 482.21µs 810.29µs 1254. +#> 4 dqsample.int(1000 * m, n, replace = TRUE) 492.79µs 822.86µs 1275. ``` And without replacement: @@ -93,21 +94,56 @@ bm <- bench::mark(sample.int(m, n), dqsample.int(m, n), dqsample.int(1e3*m, n), check = FALSE) -#> Warning: Some expressions had a GC in every iteration; so filtering is disabled. +#> Warning: Some expressions had a GC in every iteration; so filtering is +#> disabled. bm[, 1:4] -#> # A tibble: 5 x 4 +#> # A tibble: 5 × 4 #> expression min median `itr/sec` #> -#> 1 sample.int(m, n) 38.59ms 51.73ms 19.6 -#> 2 sample.int(1000 * m, n) 11.98ms 15.34ms 63.9 -#> 3 sample.int(m, n, useHash = TRUE) 9.94ms 12.73ms 71.5 -#> 4 dqsample.int(m, n) 942.04µs 1.05ms 755. -#> 5 dqsample.int(1000 * m, n) 1.86ms 2.44ms 315. +#> 1 sample.int(m, n) 40.1ms 42.54ms 23.5 +#> 2 sample.int(1000 * m, n) 12.19ms 14.38ms 67.8 +#> 3 sample.int(m, n, useHash = TRUE) 9.43ms 11.17ms 81.9 +#> 4 dqsample.int(m, n) 1.22ms 1.35ms 638. +#> 5 dqsample.int(1000 * m, n) 1.98ms 2.51ms 358. ``` Note that sampling from `10^10` elements triggers “long-vector support” in R. +It is also possible to use weighted sampling both with replacement: + +``` r +m <- 1e6 +n <- 1e4 +prob <- dqrunif(m) +bm <- bench::mark(sample.int(m, n, replace = TRUE, prob = prob), + dqsample.int(m, n, replace = TRUE, prob = prob), + check = FALSE) +bm[, 1:4] +#> # A tibble: 2 × 4 +#> expression min median `itr/sec` +#> +#> 1 sample.int(m, n, replace = TRUE, prob = prob) 22.02ms 23.82ms 41.7 +#> 2 dqsample.int(m, n, replace = TRUE, prob = prob) 5.05ms 5.41ms 183. +``` + +And without replacement: + +``` r +bm <- bench::mark(sample.int(m, n, prob = prob), + dqsample.int(m, n, prob = prob), + check = FALSE) +bm[, 1:4] +#> # A tibble: 2 × 4 +#> expression min median `itr/sec` +#> +#> 1 sample.int(m, n, prob = prob) 13.63s 13.63s 0.0734 +#> 2 dqsample.int(m, n, prob = prob) 5.16ms 5.63ms 175. +``` + +Especially for weighted sampling without replacement the performance +advantage compared with R’s default methods is particularly large. + In addition the RNGs provide support for multiple independent streams for parallel usage: diff --git a/inst/include/dqrng_generator.h b/inst/include/dqrng_generator.h index ad3d2a0..66ccf92 100644 --- a/inst/include/dqrng_generator.h +++ b/inst/include/dqrng_generator.h @@ -1,4 +1,5 @@ // Copyright 2018-2019 Ralf Stubner (daqana GmbH) +// Copyright 2023 Ralf Stubner // // This file is part of dqrng. // @@ -73,6 +74,7 @@ class random_64bit_wrapper : public random_64bit_generator { public: random_64bit_wrapper() : gen() {}; random_64bit_wrapper(result_type seed) : gen(seed) {}; + random_64bit_wrapper(result_type seed, result_type stream) : gen(seed, stream) {}; virtual result_type operator() () {return this->bit64();} virtual void seed(result_type seed) {cache = false; gen.seed(seed);} virtual void seed(result_type seed, result_type stream) {throw std::runtime_error("Stream handling not supported for this RNG!");} @@ -189,6 +191,18 @@ typename std::enable_if::value, rng generator (uint64_t seed) { return std::make_shared(seed); } + +template +typename std::enable_if::value, rng64_t>::type +generator (uint64_t seed, uint64_t stream) { + return std::make_shared>(seed, stream); +} + +template +typename std::enable_if::value, rng64_t>::type +generator (uint64_t seed, uint64_t stream) { + return std::make_shared(seed, stream); +} } // namespace dqrng #endif // DQRNG_GENERATOR_H diff --git a/inst/include/dqrng_sample.h b/inst/include/dqrng_sample.h new file mode 100644 index 0000000..2f8f47b --- /dev/null +++ b/inst/include/dqrng_sample.h @@ -0,0 +1,107 @@ +// Copyright 2018-2019 Ralf Stubner (daqana GmbH) +// Copyright 2022 Ralf Stubner +// +// This file is part of dqrng. +// +// dqrng is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// dqrng is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with dqrng. If not, see . + +#ifndef DQRNG_SAMPLE_H +#define DQRNG_SAMPLE_H 1 + +#include +#include +#include +#include +#include + +namespace dqrng { +namespace sample { +template +inline Rcpp::Vector replacement(std::function selector, INT m, INT n, int offset) { + using storage_t = typename Rcpp::traits::storage_type::type; + Rcpp::Vector result(Rcpp::no_init(n)); + std::generate(result.begin(), result.end(), + [m, offset, selector] () {return static_cast(offset + selector(m));}); + return result; +} + +template +inline Rcpp::Vector no_replacement_shuffle(std::function selector, INT m, INT n, int offset) { + using storage_t = typename Rcpp::traits::storage_type::type; + Rcpp::Vector tmp(Rcpp::no_init(m)); + std::iota(tmp.begin(), tmp.end(), static_cast(offset)); + for (INT i = 0; i < n; ++i) { + std::swap(tmp[i], tmp[i + selector(m - i)]); + } + if (m == n) + return tmp; + else + return Rcpp::Vector(tmp.begin(), tmp.begin() + n); +} + +template +inline Rcpp::Vector no_replacement_set(std::function selector, INT m, INT n, int offset) { + using storage_t = typename Rcpp::traits::storage_type::type; + Rcpp::Vector result(Rcpp::no_init(n)); + SET elems(m, n); + for (INT i = 0; i < n; ++i) { + INT v = selector(m); + while (!elems.insert(v)) { + v = selector(m); + } + result(i) = static_cast(offset + v); + } + return result; +} + +template +inline INT roulette_wheel_selection(const dqrng::rng64_t &rng, INT m, Rcpp::NumericVector probs, double max_probs) { + while (true) { + INT index = (*rng)(m); + if (dqrng::uniform01((*rng)()) < probs(index) / max_probs) + return index; + } +} + +template +inline Rcpp::Vector sample(const dqrng::rng64_t &rng, + INT m, + INT n, + bool replace, + Rcpp::Nullable probs = R_NilValue, + int offset = 0) { + std::function selector = [rng] (INT m) {return (*rng)(m);}; + if (probs.isNotNull()) { + Rcpp::NumericVector tmp = probs.as(); + double max_probs = Rcpp::max(tmp); + selector = [rng, tmp, max_probs] (INT m) {return roulette_wheel_selection(rng, m, tmp, max_probs);}; + } + if (replace || n <= 1) { + return dqrng::sample::replacement(selector, m, n, offset); + } else { + if (!(m >= n)) + Rcpp::stop("Argument requirements not fulfilled: m >= n"); + if (m < 2 * n) { + return dqrng::sample::no_replacement_shuffle(selector, m, n, offset); + } else if (m < 1000 * n) { + return dqrng::sample::no_replacement_set(selector, m, n, offset); + } else { + return dqrng::sample::no_replacement_set>(selector, m, n, offset); + } + } +} +} // sample +} // dqrng + +#endif // DQRNG_SAMPLE_H diff --git a/man/dqrng-package.Rd b/man/dqrng-package.Rd index 372c193..49c3c7a 100644 --- a/man/dqrng-package.Rd +++ b/man/dqrng-package.Rd @@ -6,7 +6,7 @@ \alias{dqrng-package} \title{dqrng: Fast Pseudo Random Number Generators} \description{ -Several fast random number generators are provided as C++ header only libraries: The PCG family by O'Neill (2014 \url{https://www.cs.hmc.edu/tr/hmc-cs-2014-0905.pdf}) as well as Xoroshiro128+ and Xoshiro256+ by Blackman and Vigna (2018 \href{https://arxiv.org/abs/1805.01407}{arXiv:1805.01407}). In addition fast functions for generating random numbers according to a uniform, normal and exponential distribution are included. The latter two use the Ziggurat algorithm originally proposed by Marsaglia and Tsang (2000, \doi{10.18637/jss.v005.i08}). These functions are exported to R and as a C++ interface and are enabled for use with the default 64 bit generator from the PCG family, Xoroshiro128+ and Xoshiro256+ as well as the 64 bit version of the 20 rounds Threefry engine (Salmon et al., 2011 \doi{10.1145/2063384.2063405}) as provided by the package 'sitmo'. +Several fast random number generators are provided as C++ header only libraries: The PCG family by O'Neill (2014 \url{https://www.cs.hmc.edu/tr/hmc-cs-2014-0905.pdf}) as well as Xoroshiro128+ and Xoshiro256+ by Blackman and Vigna (2018 \href{https://arxiv.org/abs/1805.01407}{arXiv:1805.01407}). In addition fast functions for generating random numbers according to a uniform, normal and exponential distribution are included. The latter two use the Ziggurat algorithm originally proposed by Marsaglia and Tsang (2000, \doi{10.18637/jss.v005.i08}). The fast sampling methods support weighted and unweighted sampling both with and without replacement. For weighted sampling a stochastic acceptance method suggested by Lipowski and Lipowska (2012, \doi{10.1016/j.physa.2011.12.004}) is used. These functions are exported to R and as a C++ interface and are enabled for use with the default 64 bit generator from the PCG family, Xoroshiro128+ and Xoshiro256+ as well as the 64 bit version of the 20 rounds Threefry engine (Salmon et al., 2011, \doi{10.1145/2063384.2063405}) as provided by the package 'sitmo'. } \seealso{ Useful links: @@ -27,6 +27,7 @@ Other contributors: \item Melissa O'Neill \email{oneill@pcg-random.org} [contributor] \item Sebastiano Vigna \email{vigna@acm.org} [contributor] \item Aaron Lun [contributor] + \item Kyle Butts \email{kyle.butts@colorado.edu} [contributor] } } diff --git a/man/dqsample.Rd b/man/dqsample.Rd index 4c9a386..24dc4bd 100644 --- a/man/dqsample.Rd +++ b/man/dqsample.Rd @@ -24,5 +24,5 @@ dqsample.int(n, size = n, replace = FALSE, prob = NULL) Unbiased Random Samples and Permutations } \seealso{ -\code{\link{sample}} and \code{\link{sample.int}} +\code{vignette("sample", package = "dqrng")}, \code{\link{sample}} and \code{\link{sample.int}} } diff --git a/src/dqrng.cpp b/src/dqrng.cpp index 4533141..72295b7 100644 --- a/src/dqrng.cpp +++ b/src/dqrng.cpp @@ -1,4 +1,5 @@ // Copyright 2018-2019 Ralf Stubner (daqana GmbH) +// Copyright 2022 Ralf Stubner // // This file is part of dqrng. // @@ -19,12 +20,12 @@ #include #include #include +#include #include #include #include #include #include -#include namespace { dqrng::rng64_t init() { @@ -167,67 +168,6 @@ Rcpp::IntegerVector dqrrademacher(size_t n) { return res; } -// code for sampling -namespace dqrng { -namespace sample { -template -inline Rcpp::Vector replacement(INT m, INT n, int offset) { - using storage_t = typename Rcpp::traits::storage_type::type; - Rcpp::Vector result(Rcpp::no_init(n)); - std::generate(result.begin(), result.end(), - [m, offset] () {return static_cast(offset + (*rng)(m));}); - return result; -} - -template -inline Rcpp::Vector no_replacement_shuffle(INT m, INT n, int offset) { - using storage_t = typename Rcpp::traits::storage_type::type; - Rcpp::Vector tmp(Rcpp::no_init(m)); - std::iota(tmp.begin(), tmp.end(), static_cast(offset)); - for (INT i = 0; i < n; ++i) { - std::swap(tmp[i], tmp[i + (*rng)(m - i)]); - } - if (m == n) - return tmp; - else - return Rcpp::Vector(tmp.begin(), tmp.begin() + n); -} - -template -inline Rcpp::Vector no_replacement_set(INT m, INT n, int offset) { - using storage_t = typename Rcpp::traits::storage_type::type; - Rcpp::Vector result(Rcpp::no_init(n)); - SET elems(m, n); - for (INT i = 0; i < n; ++i) { - INT v = (*rng)(m); - while (!elems.insert(v)) { - v = (*rng)(m); - } - result(i) = static_cast(offset + v); - } - return result; -} - -template -inline Rcpp::Vector sample(INT m, INT n, bool replace, int offset) { - if (replace || n <= 1) { - return dqrng::sample::replacement(m, n, offset); - } else { - if (!(m >= n)) - Rcpp::stop("Argument requirements not fulfilled: m >= n"); - if (m < 2 * n) { - return dqrng::sample::no_replacement_shuffle(m, n, offset); - } else if (m < 1000 * n) { - return dqrng::sample::no_replacement_set(m, n, offset); - } else { - return dqrng::sample::no_replacement_set>(m, n, offset); - } - } -} -} // sample -} // dqrng - - // [[Rcpp::export(rng = false)]] Rcpp::IntegerVector dqsample_int(int m, int n, @@ -236,7 +176,7 @@ Rcpp::IntegerVector dqsample_int(int m, int offset = 0) { if (!(m > 0 && n >= 0)) Rcpp::stop("Argument requirements not fulfilled: m > 0 && n >= 0"); - return dqrng::sample::sample(uint32_t(m), uint32_t(n), replace, offset); + return dqrng::sample::sample(rng, uint32_t(m), uint32_t(n), replace, probs, offset); } // [[Rcpp::export(rng = false)]] @@ -250,6 +190,6 @@ Rcpp::NumericVector dqsample_num(double m, #else if (!(m > 0 && n >= 0)) Rcpp::stop("Argument requirements not fulfilled: m > 0 && n >= 0"); - return dqrng::sample::sample(uint64_t(m), uint64_t(n), replace, offset); + return dqrng::sample::sample(rng, uint64_t(m), uint64_t(n), replace, probs, offset); #endif } diff --git a/tests/testthat/test-sample.R b/tests/testthat/test-sample.R index 55671ad..858eeec 100644 --- a/tests/testthat/test-sample.R +++ b/tests/testthat/test-sample.R @@ -73,9 +73,10 @@ test_that("dqsample_int w/o replacement works with low rate", { test_that("dqsample_num w/ replacement works", { skip_if(.Machine$sizeof.pointer <= 4, "No long-vector support") dqset.seed(seed) - n <- 1e10 - k <- 1e5 - result <- dqsample(n, k, replace = TRUE) + # use a shorter vector and internal function for performance reasons + n <- 1e5 + k <- 1e2 + result <- dqrng:::dqsample_num(n, k, replace = TRUE, offset = 1L) expect_equal(length(result), k) expect_lte(length(unique(result)), k) expect_true(all(result >= 1) && all(result <= n)) @@ -96,9 +97,10 @@ test_that("dqsample_num w/o replacement works with high rate", { test_that("dqsample_num w/o replacement works with low rate", { skip_if(.Machine$sizeof.pointer <= 4, "No long-vector support") dqset.seed(seed) - n <- 1e10 - k <- 1e5 - result <- dqsample(n, k, replace = FALSE) + # use a shorter vector and internal function for performance reasons + n <- 1e5 + k <- 1e2 + result <- dqrng:::dqsample_num(n, k, replace = FALSE, offset = 1L) expect_equal(length(result), k) expect_equal(length(unique(result)), k) expect_true(all(result >= 1) && all(result <= n)) @@ -107,20 +109,65 @@ test_that("dqsample_num w/o replacement works with low rate", { test_that("dqsample_num w/o replacement works with medium rate", { skip_if(.Machine$sizeof.pointer <= 4, "No long-vector support") dqset.seed(seed) - n <- 1e10 - k <- 1e8 - result <- dqsample(n, k, replace = FALSE) + # use a shorter vector and internal function for performance reasons + n <- 1e5 + k <- 1e4 + result <- dqrng:::dqsample_num(n, k, replace = FALSE, offset = 1) expect_equal(length(result), k) expect_equal(length(unique(result)), k) expect_true(all(result >= 1) && all(result <= n)) }) -test_that("sampling with weights gives warning", { +test_that("dqsample_int w/ replacement and w/ weights works", { dqset.seed(seed) n <- 1e5 k <- 1e3 - expect_warning(dqsample(n, k, replace = TRUE, prob = dqrunif(n)), - "Using 'prob' is not supported yet. Using default 'sample.int'.") + result <- dqsample(n, k, replace = FALSE, prob = dqrunif(n)) + expect_equal(length(result), k) + expect_lte(length(unique(result)), k) + expect_true(all(result >= 1) && all(result <= n)) +}) + +test_that("dqsample_int w/o replacement and w/ weights works with high rate", { + dqset.seed(seed) + n <- 1e5 + k <- 6e4 + result <- dqsample(n, k, replace = FALSE, prob = dqrunif(n)) + expect_equal(length(result), k) + expect_equal(length(unique(result)), k) + expect_true(all(result >= 1) && all(result <= n)) +}) + +test_that("dqsample_int w/o replacement and w/ weights works with medium rate", { + dqset.seed(seed) + n <- 1e5 + k <- 1e3 + result <- dqsample(n, k, replace = FALSE, prob = dqrunif(n)) + expect_equal(length(result), k) + expect_equal(length(unique(result)), k) + expect_true(all(result >= 1) && all(result <= n)) +}) + +test_that("dqsample_int w/o replacement and w/ weights works with low rate", { + dqset.seed(seed) + n <- 1e5 + k <- 1e1 + result <- dqsample(n, k, replace = FALSE, prob = dqrunif(n)) + expect_equal(length(result), k) + expect_equal(length(unique(result)), k) + expect_true(all(result >= 1) && all(result <= n)) +}) + +test_that("dqsample_num w/ replacement and w/ weights works", { + skip_if(.Machine$sizeof.pointer <= 4, "No long-vector support") + dqset.seed(seed) + # use a shorter vector and internal function for performance reasons + n <- 1e5 + k <- 1e2 + result <- dqrng:::dqsample_num(n, k, replace = TRUE, prob = dqrunif(n), offset = 1L) + expect_equal(length(result), k) + expect_lte(length(unique(result)), k) + expect_true(all(result >= 1) && all(result <= n)) }) test_that("error cases", { diff --git a/vignettes/.gitignore b/vignettes/.gitignore new file mode 100644 index 0000000..097b241 --- /dev/null +++ b/vignettes/.gitignore @@ -0,0 +1,2 @@ +*.html +*.R diff --git a/vignettes/cpp-api.Rmd b/vignettes/cpp-api.Rmd index 44df95c..15069d3 100644 --- a/vignettes/cpp-api.Rmd +++ b/vignettes/cpp-api.Rmd @@ -107,7 +107,7 @@ Rcpp::NumericVector dqrng::dqsample_num(double m, double n, bool replace = false : should sampling be with replacement? `prob` -: a vector of probability weights for obtaining the elements of the vector being sampled (currently ignored) +: a vector of probability weights for obtaining the elements of the vector being sampled `offset` : sample from range `[offset, offset + m)` diff --git a/vignettes/data/no-replacement-high.RDS b/vignettes/data/no-replacement-high.RDS new file mode 100644 index 0000000000000000000000000000000000000000..4a990ead565523da485a6df44c30d4701411cd0b GIT binary patch literal 1404 zcmV-?1%vt@iwFP!000001MOISP*hbEf3P30%R(BMg_t%uPJa*(GnHkv3zkuqrm2Hj zy&k)7*_UtMZg1c6VNAgSiVJ~hNmC9(liDwPM*!+1W6esBQf@HhJbFqFnxpNxo``yei>DMSzaA%L?bYE)`cGC zfso9k0vIN2<{4MGu)cs5%r=@Waf%8@&2ug(Of|v6y38WylsJbF*&CjoDhZDnTMxBd zLJ!9BzSO$FOtk*VolBgZRXA~i+s=xdImB4!I`JnHGFH88?NIc_C@^Nq7|X3&zQ|_U z>>0TEp!5`Rl9SKBhE3<>KYKkD*-3)zq@Ywn+dhRCYGmb}RT~FPx75GQ_q=dXP8o=Q zy7H6d6ki0%Y)sn0k>+N!A~>4!#o8c&smj|yH4Jz zwN?9J?r&WnlMgnVI>{@cBp6%7@RK~p<7e6-khLV-lOs5UQoF8`z;H!;P^|GZR}_q zJ%JvKN0JKD$}#3$+=B6NW&e+u-?8c4T#TK}=O)bW_%QEvOt=0~b}wN28l2b0F50>j zzIg0t6*Y^Jk^LQf}k@8N3KrTY}GYe3m87 zY+KJ&_acO7ClbH-uXEIi;(x}KNudUusM}c!#}F!xlf+C{ph4E5HjxfK#cB)9LBkr< zaZ7u1%W#nR4*+x}GmDBs^1 K{x=6f82|u-0KRDe literal 0 HcmV?d00001 diff --git a/vignettes/data/no-replacement-long.RDS b/vignettes/data/no-replacement-long.RDS new file mode 100644 index 0000000000000000000000000000000000000000..7cecb1639f4a407dbd6e546273027d7b31ad1c9f GIT binary patch literal 1737 zcmV;)1~&O0iwFP!000001MOLRY!h`Hzpd>Udyqwp;7}d`aq<`ir=l|3@tg>e5Y(Y2 z-Szrwd+pt|y}L3-cua#Ji4}>W-Q++? z7cw!Lq|6DdlB}HJBogO!kjX(gDlrSZq9&PUx`@Kbd{E^B(zU(O@Jt=(nr+T>#iiZY zN{5`>5Q`)&(z0`v7fDpoP6~@e=D7s0MF$*>6wLeWHst9qnkla0@9Ld$c)`$KEwX!A!>XUy>|p8BbUq}MN&X27XxACsT-Jff@vAAdL3bf$PO{d)i{}jXny2aZ?&5HwFi?JZOEYh91t5x1myrn6vg3@1L0tP z{8Dzp(v6eOGW6ZNaGeGuh}s(6*66lI|F0TNj~R<`%orzwxy;KNt+vD;eHK+_Ig&Ih zw3h>A`Nmv=Q?EjMi$o$b7UWPwD!>u$yrrozi)|UmF7Y=IH{+ zyEbj0bnd$H3D94+x&rbp?A??aGk@i}wtJ$ z?V!s?AlR}QhY^&Jc{oUEaQ&`#Ddj(G{Ekv_O>fARS(Tu^&kKO-JaZZA9`#k=vZICr z*I9Z3{tI1ofQjwFvyjyJ6=mVoTv?T?6c*UvzAxpET)yf26fzZ0_2(!Si)> zx__c}r_^h20G|8HIlz&9UD3Qr1skwVKHY)1T#NgHm-qdNCi^b@0lg`|?naZ;N4_Y5 zym~#FA?7RqF0qH8Pt+rb&)aV&Ug><0(m?r1*tySb!n&`%K*uX^ zBQE)X?-JIZoeQ43xC!>Y7c6>R?%I-vc+QvN;Rv2qk$<3YAmR?cUxRuHyT>6euJWF7 zsNYv(5SK7!WDfGWZw~Tey@L=>^gE?3^yGHrDUI&~f8_WT;Bsf`^*VL*L(Wy~LENr~ zR_XQK(No9mRRi46=}VBaTk`Zid@~p{_@WE`h&31cU{ZO1`1NL1A?{G^%q`##sd|08 zyaZf##WwWcw>${y&f|e6T%L$^e%M~*NhT7+=YDtu@X2QbpyxR@2zI2n8{!hC=O8aN zwGe)!4`jrl6zze&f7j2j7kdtep3nIV{E$Qa5vN@IGWJXP>`v&HP`e8C2==m|AD-GD zfa`Cphuo8~74`GpyA|PxNQ9utUGhp=y~^W!QMZym)?gNVZ;@h zDuQ|r4nn=T{lDn_stkfx+S&18S9YpK*Lz}=ZvXg3y^pg}f$y6AJ?h4FTLJ3Ny3k$6 zU8?u3$645UHgAHQ+jj)ukd>{Y#A~3jN0{8kEQzw`n4A@vOnM<5hWp z68kZwy+}ky{Qoa$9xiU#A~`gD;};Fd;fehSqXtw~h#xxBv;e|_dex~Ikjo9rIK5O2 fqvhH(CzacrIN*w`?Egm%V4D91Hx}2BSsefX7A<_t literal 0 HcmV?d00001 diff --git a/vignettes/data/no-replacement-low.RDS b/vignettes/data/no-replacement-low.RDS new file mode 100644 index 0000000000000000000000000000000000000000..5d5eef33beca8d52c613a8b3fb9d7246cca4ad34 GIT binary patch literal 60371 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 M7x11%r=36jFPhdrCIA2c literal 0 HcmV?d00001 diff --git a/vignettes/data/no-replacement-medium.RDS b/vignettes/data/no-replacement-medium.RDS new file mode 100644 index 0000000000000000000000000000000000000000..dee5361b34779fc58cce4ba6ab7cfd39fe00d221 GIT binary patch literal 19534 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 K9ZDO-#r_Q_pz^W+ literal 0 HcmV?d00001 diff --git a/vignettes/data/replacement.RDS b/vignettes/data/replacement.RDS new file mode 100644 index 0000000000000000000000000000000000000000..f580b8c44fbea352c11595a5357832651d700fa6 GIT binary patch literal 55362 zcmZ^JX*3jW9PYn_O3{X_Q%Q=Lq>=_x*(#wzvQ8zb$iB^(B~(P3BqYm(BTYg8>*fyzaaRK@WS)!!nHEHeTn z1^~{upQ?uS{arMYJU%A4BZ(+Ul4<6O!4afSMhX@Zr*4QTFkTV?_G?H&M@l9iW$>T0 zEE6UgD4#&o1r*@Y4^PR{r)NY8|D7A%1k1aaO`ORz4qyB29U9Ho?I6(x@gr`#cxCIOe&0Zyq!G4S-ne)jbZ zHq6~4Cu^6;8KG7ATw-+cxzzx8B*{uYB;<6bxQJ48Vtj1>4Oh}sYkKpvUa8+ekfgV{ zhZq2^y~$hK7>odHeihMe3KtV{By2RzRbwE*TB@VMk@hIt(*cAu75=QUU?i^wmt$z%g{B& zE6{lKS4o5;!mfAJZhn$}J@+hHwo$^WeYEsFGqs2=7J}nz8*#q9eYwWa4u40`+S=F( zbSOzl9PexQaBa;uhWMcQMCjiDyR(A{irgYX*J$Utge7Ta5z%!1LsvZT1L13v03|$8 zPj--S;v!Z>uGKW5%k~@ee$A@2!^{6)kUV_QYs3)8q5T!|ID23Uc@pKLEU-N8;rt)J z2Vo{_3B}e+$0YqGqYtKI%lz=Ukt43BBn@lxnc_}`(V+D;$?90`GDq?gG6EL{T=DJA zF(G|B?Y;E9c+yvYWYY4Ddb6be@FR$b_NM9O9KoQAMRH9p~**;8I$PS$4w;eCGlntCM|~lH;7PKWjqj=qJK60-@vE%tCPT*4e@`Yui*Y4kSL^HkWj9g z@gSec7Gg$~~hebB6lAvtt!#A3jD>UHl%#BBuz)ybO zXmEGV4fkUUE=kwUjk3-8H&>HKZA7L~E&NPq*%%#uw@$t4s0%g3`hh@i6;cFir;bKk zvr#XJK&l-wg`ct{a!|G+yZy)>`#X8T2yPRe&U?);3~I>*yO%|f)xK=dFf6jrsEUyB zF!v9$v!kSC`Al20-e-PNsxuNBoL(lhT3v%*pEFio=6!tD?HAx8v5)TO*!LI0H+@uT z1D|q9v7FUVY2w?#e{Y~0u2TS;nRvf`BhcEr^3oxSW8ls;^5mw7+F2}I-y#wRS#Cn` zzlLSaz>Z;!EM+s4(O0_8D}e2=MxL0ml8wL$L#9rm>Xz-_Q z%uyRD)ZYdf3^J@PXIhl?U|9;=bjTej_%p}>wYz9Tz-8;kA1=M@pmoxUDiNs;}fji4(dgu zxs81~C0k!M8DvdIj6*1AQMU+S=L%R9Zmc}j{5bS}IT<{+zs(W(wcB9)Ih{28aNXn- z%_rHffZ?)1Ju}qo`H63qa#TKFUFCLtTcuu5GIlrQg1aN{2VtQxGjz z=3Xj0A?3^ot~xEIMwf!j;Sp>egEv{d*#-a{jzTw_9uMH1TFe?Seon8_0GD70pB1jv zdFq@`H~)wr_*b#U-j2KZc7lYN)8Bhim}mN=kb{vuWEWiRY+cRVS(unxyM*m(i;e8^ z;+x@P*3Gk?)<1~n-n-$N;g4hOoi2Qk%z$jHKP|xywm5zyZxO$h5IKFrvYt0n%F%G) zvOlOmwxY`%Fa!xPVf+eSlDwJw-ZR^`1pIbIWO@{F!;2qWr_PV>0Oix5qa5q!6$dn5 z7Cnz&4!F(hxj9Oc%5o{i`99CMl#=z=%c9p;8>M-aJASl!uJtNrxw&kJp@3oE9-Z<| z_B$J*D7?kMP28qvc;x8Eo9V)K1ODpCbxx&?K5y`e(|VB~na6U5hFH~MHYUWXkwv;` zfa^VC^Pm{k&(>o^Ifv=`7nCEt8QPJCgtC2-_d;GnE=3Z*(COsJf}H32QqSZHDu(Ic zE-yVOT^CXB{jK`~4zjUgKNLAxiUi+PSAM$39OGBPE+G#KdII_d3Z`HA{FGRUMSo@3 zN7m!fmzPE2#Z5kb(Yk*%;|VTuYFTK0NfZFLk5YfF5#$RoBVhCJ==o*dWNT$|glZhR zNZ}7NnK9aF#}#`F)%W((9U}I%5EHSsr4L-vWS(QHl)z$U>WBv@!0^WS$=se&NM9WU|JB-Oc5B-1 zk3J}X(g9Qk>X_&jSv2Br67;}tdX=3FBeSFWpAOwqrKu?_a>xwtmZGt%lNIYNy`~(` zkLwc(x%0*F>MT6Hvn3PA(y&$|by?A#tZq6~JbE4kgA`*@)%OE+1mSj_F>n^o(NOQwo^0(S!nIo5BM@8VmWal;*R*bce@ zA;xUk0lY-57npllo1#dwO;Mp+#(P*siMS2%#CN33Is&Wp~=dBxU8Zpk|P)W1(v(%d~RQ$@zjY4pu z0T6-Fwl0>GS<$wOGRJVjW+6q|0&fVtKReIa^9P?ocx_C}rjSfJ4AvI;2JG z{BTwc6f_o zJs6|m`xr3F(_Zeo0TuoAH#v1$S0HGmSV=Zq2Ox#*%6@Q1>Jl9>nyIa@8XK^&|9u(H zcJB75Ks)?hYL$2BHp&gIu<%GScHTOTO58_Q?g`Koa(zene=>C*OslZF)kgVKBmaI` zGT?9W=(KQbEws&e^}#f*={h5_P2rm-Gqj67qF0J{$^iL?_)w1sQ%4)04fAtu&CMH!3apLaW4Uf;os$=Qq z(L3O~hncR?zCAI7YlL(T-kpknO7TZ9e5#CPHC&Ih*g5zt&uN^IC|uL(1a_fLF_Mpn zkeByQug2#sMP_l!Rz$~^B!X+3G|VyX6c)*Fva|Jj>b3*s(gsM{V52|;(9DIs5Y{#Xz}302ox610 z6w+J54y+Py3sUC*x})%%T#Tq@%;YlMgmI;}xe%If<4QT5CfgIBOQGwut&0@+;&(=y zlg;DLiR+90u47`0w)GJMTs>)&kH48a<`*10h5u62-CriPj2w!@_5g2H*)ch9Wi!Dt zJH!JBAKH7N>CH`~MeFkRWM9qY(Jo-IC}IjR{&Wc?%@$;>vT#M=H@c{uOb@QEYiYR0 zXja(|ixH45fh6E+U8^$$l&2GlW|?2fkbVC|lV;v#Uuzy^3A%q&Q7ZmS@31WHv_(`_ zGU^G*2H_sKA=2(HV36wO{; z%&G#+VUL#&@IRH6Gt3uC6qh0=4v5SzB4ghXY7Kym(9#9yYsQTxWhTjX!#GXY#}~TJ z7N^XY#>l?z`tC@!4sofvx}02P2Q1C8Ug)h=_3eUujJN&4)dmb-sGl_w?jZewoQ@JH zkFvYL8IlTk1FQc}2DW?HCL0k|N0~N$Md*fr&I|t4gFp96pr0g9-$Ls{MQ+ab;KX#?iO z5{cX#-5^UBJlG0qr%2I3SAy(>$CJ=i;G;Hk!MwxWO^LbM%fLcOG)w3?7N|w|{%L6P z1<{J1+;VjGa}1*$WLfX^j<%s=|ChPGfzF6n`ocz;SOk%Q&7Z?sX)y5;1cuxN zTlib*wARbtoV?bydY@xOaWN^j^l5Vbr~2zqN^cG$>|G?BssOdAS8u>@DUF&6U6d!R z%s*qLZR0!G8SDkW3Hv0pD2(^>hyz9bPa>~PTheKCT}2o)f33-yI)}1aTm=;4cS_n} zqjK7qJi1pZ1>d5=Uv=R*_Pndj|1nzSeXZ_Q?wnS9qC8j7LsTZqK&p<*5nFrTF=L3B zLXK*6pJt_HkkYSQAn*VoEpo60+;9_RCUIJh*;t#AY)JW*zBVsrH+A=^hh?+ITdkB! zCJpV`ytiNGZ{EdvOy|W2l`H^5Tv@L~K-I~DV8tH5sc$(eWqW;p0WPfIYDXhp zt}+ul5DT&}iYw-6(Tdkv6Gc(qXEjCs0QnX_gr4Qq%~yED+g`|Qu1vG633{% zR1Jvv4P?*2nJ`Z@9_B2@4D=;AqwEAqK7gI%s=>MV7;k0D}b)sJggkIYX}Yy{qQ;^RCy$$Zj`WWd~wln#2A zvElQN$belH7;&m6SCX!_qWZAAkNDj~tzLD4BmC;JN9w}svi}6y)a7*F%XqNt-TC-dg{fOd zu+@*{s!c<`!uPu4PmF>l-dl}|kG<)iXN}N4Kkvx){D8pfI=y`wIpKWPHA=5%mQ`-* zU|9^e%&PUSc$E1R8-uZepuj-Z?tjqbWrcDK52X0~W^68Ll*>E8GdWRS8ccooWOAsox< zPQNv#s6X4H3cixGRH7Xc;^bw1hk!Eh4R0TH3%k8q-dk;0@IzPUNwAk;Y0MN1cP&VG zoaQ^%Lo3Ze?%pKt)px=GsmPV+n8u~rnpGKlSwi7;ow*5^jv z$0~I=Q40A5kR?Hy>_dSX^Tq2=h9K-fWch&yH^LWN^8KS5Kfcy|8R-a?^*ddjZ9u!; zt{gItZVW7+V%99)8FlMpC$5hjRT~UWTk?!AK6wkA){O5#g2nv?C6aZYe+}VSsNRWp zIl}erS@_yuk#$tDfV|I3@~%3{{}$YE{=CViuEX0wZx;I@EHLr)e4><2De`Artd>pz z4e)q>^L@!#m{%TMPkvX4I zcYry={5@`E{i4cn%6gETUq50c<|;OdvV^1OUt&u5{gwVE6-lhN592k(pmmwWjP=NC zbmwH`sd0z);E%Jq$DRaV_|nVuHxXA=SBab_ny(UkEh+t|?2=&3LtJaZg&T9kfh=d{ z*-Z3fiVb}(ft>bO`l-`T%V&ma)uQ?sLDuTnK605%Fa~Vqlr?aERi_~O`t?-Whs6+NvI)fc_ME-`7hU`J{hq-WL22u!YvUaKzN708h#c2Q z*X`rGQ^sb$X6v*#mFL{bS|!w;L+S0DRsYJ6A8NSWwZk*m?Gl^QkJ`Ki!am)HE7hED zuD2>OxB04`bzq|C(KR7*-(-`;k4@@5U#0D8yblidw!4<9hHt0;IeaYF^(h$wi%7mb%E>8m3=+fxPHJB zL$8~|9*ju+8z2#On5lJ^;Jhn+5PKhB0_~6o6eDk)ChH9-mm*VM*Ckf3IfBZuL(BpP z5?3H9rU$B*^BY4{U0%cQP#cs@2)DB?EAG|r?lfp|q;HDkTm1T6Z)%yjLAM&q0ZCsj zx9R73e?7DjfW280||?BXMsa2p9X_B~H1->YQxEuH;$WZ1>P_(v|VsUvfY0oM-36 zm-ZoUoOwlW-8j~@oH2H09OW|)PkXAJ;eG6ye5ZPu)xd{ior@gi9IG@68kigiHfhwW z$ViR)EvhQ$$PP-%CBRT@+`6dZ7u(nPjLX@y)TWu!Pv>vf0K3x*z~qyBjjy~<_bF5- z@J0Kv%3e!Cw^7OFqz~~?i=#GHQTh16nvHK4(p>EOnOzI(j{mwkU}NN@c_-^}{yOp) zP4FCw9rl?92|k|`>lr@^Ex!LQ8>IMHpWPAh;Sg8BuMByid-P_%UDhu}of8KuH%2N( z#T|X`L(4-dvK76vj&ps4zcO80UYkLZIt>Q{dd)Em=o=*PJ@eCs-MX)jngjRI&|!D% zMM8&V+(sMg2L~q`wBEBoXi(mI~YjK{LEkEy= z^fQtC(LonI)Z)}{%?@gRG^*wOg|m-Lg5)C11H`hbwD7Ts;)$pI{1lyXSCd#K(0XcRs7-B=_Qoi=bsp@(yg@T z0*>>(9>h+4OO*LVlX*Jhr2hF+hi;_P(>mnuQ?;PW{4XV(`4ceuwKi}iW@<9zEqT23 z4)sHUogh&>cBbUR*WNFQF0vIJOrz}50)l6 zsh8OOOw9RCS->jRn2S}Ox?NX&56LLU_Rp_=aIV63cx<0AD&%wokhr?X&fGG&d`V3) z^)sg9dP;S{%(uJ}ow*kEL1oZ`e%1c+()kyOWPO(Ci1g|jC;Objv2diLXjM?bHL{$K1uWwF zwzYY9q)5fpVmJaL%X&(dmX3Un6ord(L<@}naaCu z5SfxKI#+IvSN(dV|1QpNc6#ToKk~l$sYj0gK-7%9ncul126KR?Z0ceCvf8Pz{*29> z?6{Noq=J1IWOV|T`(YAv^(W(v^U*6|KxkFI9SboVW)%XHWws{<`mYvvAz-(yU9)Nrt9-MO9|D3Ar~UF-q%MY1Vt2S=Y9d33q}` z^NE>b8_lop(=Y39#o3UGvkx8Huz%~=I(`&g68YTzktN<+ooK^?^B>lN-1Z7n0&BG9 z%sjT`e*WB|Y$Z#Fx6N%Tnzf{Fm|6$k`23;%o5yO|`;?XN;i!D)R_8Cj-aYb#D&cT> z<7T7*h~pGOMffTcCmThVUVr7XTRiq3{nT_j$iuqY_*Ms+6dl*S8gkzXub65>et#pn zXeW902u>N(&YW{}%H4wK%gB6-sQ}4oQ?ye{=eOYAGgL=UCkN{t=>s|LZSs=R zf0AE+d|*iJ^fuE2mu#TV3*x4WUT5znhqb9e9fYe07h6HT#cbx2A@r=kqLd{xnI`!i zYfLn4zPR~fD)im!$5`quk+{BN@9K_8`)!hYv-FGHCyk~vWVx35i`!`WKaM+cl@FtS>03c{8y%x*EhSqN3$&3G$>!!l{9sP9mlr68M&y!>9VU&fSOf<&ZOF4=8Ecj{IB04d?! zN`AS}eUd>{ZY(>v9zNm4U;D7vT)kTRy*i6DR!cj7#^3d?!`^JDemlg9T08P82Q5xM z5{Uh0&OW2$t8NOmuzEFrk9t;&FBXPpyrzX%AflqY=dFx;yMyk-Q41`$_ zwO&l?+u1+a#Xk^{5qK55?J@!iVP5`Jy0C0|h!hpXwz$ zOUyGpPzTRKI4}Ghd{l7FeyeX%Ma(7i*IhduVj8%ujUHja=XQc)c13{#8<&!OuqL1d zY-KKp_{&`G%=?^Kc#2eR+qm;bm#sNVPW!s1;l~Olcy_Q~i+U|4J#7+`nrcVp&7-=! zL{b9rKIX*f6YTu?Vy&{iO`wP0OeTqsIc`5#f@mFva(4%KvxmV$ZJbh$z^3w9r zz*nb}fn>{#l&D*)KGu5gfY6pBo{rvUvBxL_@OMwN@Ye#R-)yP|R#oDYG>SR*qr28# zgMnr#Q5GSo=iTAyC;MA+Sf5??0j>g$dVR^+Kj-lVs5m)8(u+MNuAT+mI%GB<@m5_L zO^OVtU>t-O+0TvLH$%U|PI%48MOHBOF01!9_$HVK498aqn!zW0AHnU;0J!w-2df~^K zRARxSJNlitk+)r*5qfn64*g8*-+T)s}|{t>#5%E!+XTSJZZV zMX(joCpVyIJN`eW&mkEESrKK@^YTCRHQ(&9VDtO<5C<9asnNQ3>sN?6UW3Aet$n+m z%P=%4%9jBylox{S3T^b~gel!=EpFq2T8k@uIXzJ`fRvDn`UC|wxJCuV@y)nJQ}TE{ zSo0gMepE3-b>gVGoUX51X4a)QM@nQR!`z9kcHJJ=B7c(U!4gHvEZ$R}JH9A#s^#0> z_QL^uMH(o(5XB~&u(0tY$;AEjU`8Z&K{X-#)MMLP zGP+xH$90d2s+0xIUz$JpHunAT0Aex8{?mVguVx`BKwbp7KYChE+GPWGKe-t#lv>MM z5D>Ou+$&D!7C{YfW^DtwKUOxGcs)6|l^c1D04jaUA^btpq#}1VfNx0b)76`M!bj3Z z9Ajh_2A{si=9A>?2uyNKyRLg|C-zg4jiC86Hr3}3^S@l6^xE1&uk$ij9+}z2MM|R? zeuorr2s_19qcx2M+OPXl53>XPZ$r1k&N-Fx$4i%}G*6_05e5f(v7QgkXNq2Ws#q0IvAmA?!z^Bxx4|_+uMY#xK!STAD8!JEc#N|Su@S!m+)1u3?d}tH^EP> z`lur`NEMR1qxoR;1kaW~QtbXqz=)P26YOB8Z~T`FR`UD-D4k>&jqIRKp`$+pq8?5> zj1TlRpOAx}yO*u^nIdHz%elNl_j8qnTQ)D~_#T5R|A)7+tpDp$Rzw_V*h+soO!rkT z6{fFiFF8rJz%jBK>6ayLE9ld+hZ6AJ_cS=NR4aUru@+pG;J;1c;3(c9K?2Qp1cjX0 zGy1dPCn~05p%#>)CVOG_k$Oza6A?ZwxaPUouF^NckP>JO@O>oN${J8&Ojt$9MGQpA zjs8r)9TSY^#F?4ipzbz5iqlllLd91v?qSG!RaMGK7|LOM8PK}yVhp2K6(v;5xpEC& z5dLuLD)-(&p_=<00#0oTGohMR-fCMQb+Epa6Ywxc-Npdqt#Ix>j=KjQ5Yek(ZPS04 ze3^-gItH7v>sZ(3di0#v*&&J96R|x0-Qv_6Bu@>2G7uW>6M4MCFUfnlU7`UivpS?m z_FN>0)$~5%-|iw4&)38^Z!sNhN@HJ_m=Nwd&|jGUe6yW(xkB?Z`N&q!Ht*88e=|_z z`opqPH^2R(IR*`}E(c2C&fFbdUxORu*^|~QSo?R&Q&0GUSK&A1hMh$`amZrr)TSzC z{03_`(A$*$*elGyhTvfl{V*OZr3tzlPkW-?7yf76VOlHX9T#jGWE55A2-RbM>nGS# zL&?RrqOE=lcDItOVu61=sdmVhkeJQbYLy10v}AX`q>Lif8$+32pZ_hzv7i_gXOVxP zX5m{Q6PI|-<9yMXOW-$F=1b2gEDq&&^%n)HcY!pY`ONb68VkZGu5EH|OPNC5R*KF- zOqLP}E4eN@!D#O11|=?yFVdukwE;)a`!j7aF2z^BjgQQeWDY$k0>f5;v$Mc4LEF3| z>l72iWL`sb!n%1*LS^WGk{|r=5=tkGd#1~VaUj{K!70qa<0#7Z&&}w*g5N~&BTW|R z#S1Ilg4c1-;o<5&r+&k!(?IK%=32FPjNtSb&cHeFGc&hkN$=;S-R$6JfOONxxlAsaPuKSDN${5e>5?6G+F z`}vE?T%0_QpUDBX=KBAF>D(w9U^SHkKi&g;6jQcqX2=0~Cstk?wnR$vzwY5z#6VEz zvE(RWIH{;6@+9+)Ja=I0IEVT{9F%(*Xtt*q4akb`1x`HmL!8IAt;GX!^wEFS2!S+6 z&jqS;$G`LjW`XqbPjFamF1CL21!L8;tA!Cvg{?{_#(>p~Dx1m5re_}F+L{I%cR*Vq z)D=t2bVg*vCqTfDwI7fxMR6&RfT+7PeaO30dH5EsbSbkJ z##CkBlkBLi(5`rJ?hEqMDZy6mnJWV3G}ZT0b2*ccCbX7G@R~MYD2R<|b}K0gP|0CD zB_Y>ucdn{Y;F(!Y@9X*(jQtDpWb_t7q!E7puf(!KEi0!3E-q!v^$gu+rT5xoy%psA z1saKD$ai!==$(O;C&mJIqW?q7D#rxQe%r!l+Oh7V*6*Eh5%e#bk4Zw-U1VO-L$Z>P z)5v@a|HD*5^=+S>{4?dZRW1Wb_b9?&4dyavmElyBfehrVuH>ab;D~AchX_}C`3w8P z_NiCvxRhknz6A4F}@pfAsWtf+%Xh3edZqi_(`2puSkxx^iqcVs){ zxZhC_ZN~)0qrRoWFPO?hJdPj^5M-Mpq}kUsgzu{DH+N5=MTAzn8QMhMYrAa@B&QG-5L!X|Qin z%VFqY4~vr@T~n4A{I|Ge2i`o6_nkEr*ecSD=-9Qet{fGR==qB9ix&sYyUo3F=2(UQ zn=xk7Bjl?xC4iN0$y$y!GHF7qq2<*_4%2>*#7a()t~h$Q30fHrBfBx6G&yVvrae9- z`Yh4rM`CKCslx<0kZ-WDD;R`cXpDS2#bMtE1OfW>RreBLtJ`cIWX;InOl#?BiGeus z&%(4F;FJrS)S(j2F0L*}ofO-$8^QxmOU@U4FFN~1*fD_R(XXOw@8oe?mB2|}FMx~C zdw|VB{%+o3_ceX!)5?sQ;~SmJ&@Z?6L(wl9@(NhF#>vp{3lsofc-Vy9t->+>`P9<} zJ{i$rbO)}9+uNjZ0=n_U)h6;`i{C2>Y)g}80b460;1gmYxP|pXx#adJ_Rd`S&!@@n zknD;h$RN$&uT-As%&H&EF=7AeAv2}&5+9GBk&}7n_;M_z4mp zhi)3giXDvJq`tsB3Ts@_PalepzphU1C2p84lb-XF{2!o#PYL1_t^`66uWWO6l4bUH z-ezx)x^4P&R*K*J^8D}S7=hkmW!SA?dugeoo&CK(Z<4Q1IO#0LjU){e^b;&I7DV46 zHH416f=kG`k?rda^YXnqnRy#p+I_KThZDD;^&N|5#}SIrE)1JdhXhzGXv|i4K!WGm{z<_Ws^%O#Qfz`{*w|RfPoxHF8 zY}D!*Le!|y$z~Kl$81$U7Dar~NBTtSvv82tdV~FOp_Z@%irj^(wh9g)A4vWIik1(1 zhGvYznA_0pS&C3ug42tWM}a68UQDsD?;P4oTx|XbOhNc?0g!s5Z$@$LOL&FY=W!SAE2R z(c`$KoU#UkEZKq|uj-L04PAbVoio0XrzCeKN^^h*<-s}ec#wJ%>I?5&)zeBOMJJ!q zX@L%9nQrKD!IxMp`xFn@&p7Dr1i^$gs^^b_XTJ^Y2N1GV67$ZRewjPFYaL_bVKW=q zWd$#tHDwpDZmhgGVn*NMdH-kQ?N%GVKWKoiSD#$OHsoT@!Y&2@!*Vsv%JQzCWZWw6 z&YLNXZL0#ho!sjIwLSAD-%&B}&fB--6WnVXA0odnMm8+Uy?5q>h{OfC%GssjB>M?t z_m7@wc*wfOt5-8|!-%sE_54dJ4K1oH{`o$W7S@Sr65sbCV7s^zRR6gB(iJ!FtRe<$_hWk$=(orFYNJ7Hr!x&qHiYJU1z*$oFmzf zQG;A+=?tIotuN?Mn=lZ{qFNzUR{TS7G(R+9ITR1P4HZ00>j`xdCt@CjC-a{sct&Te zJf>+*-TB@$H*+Kn{f*q*{E^M@twbw5>TBw_hZwP@Zc?v%{UBqi?B`@#0Nyy#^YGSl z!hoN0CMa7VUp$R%8!yiHYd|yJ`Wu*0k%ti~UN11e+0^tu=F2`{%|A0J^gYi_V`RPp z%k$7q^V~g}TlMb%%{%#@^r8$U^6N(P*dY5taaG4tao;beO)9LmgtJwi9i6>6PstSXzf&L=nvqv%5ww#e^_Sx1l-$t)_;CS53i*Y_B4-aiT~? z$hN4^@AFk#9(CpJI2kbKBGlGccNcxsV|fbRD`FHNn24S z{~WfAR*2`pBH3K>9^>{ zdemX5%ZQ}ZwMXI|tkPAjx^`3yTn5$(4E#jsO3 z+#?N_s1fc@Ch7Kj)TgC*_}%c$LWbfaAHFOqyIoJ%E-2j=Ipb9Bp8YRT4bN`R{2=K= ztNrrIe$T{;zUn}+q=!QQ8*|tZW3}sOD)1UZe1!FRHES|foq#5{5;U%~%7*_+YTv)tw(|oe;ottz|C5~9T-ZOY+m)s^ z+;H0WSKrQ56~hL{)uzKZK+9G5ez$Fqr{%Yzl>#5Ee^+urc3m)YD9yQOF_eStFSyhz z*Y`viagMmB=mD2Sy*>3W?X;o<4j{Ap<@Zudh_NJMzYTo^zKik^UxyHx&cAq^@6w^w z7ar8ueQw124P&aaXD?Nmv~CfxMsmeZ_AZeZP8#B+uVI7RA*xZ`up3 zk4gidD;4gKUfC(ctWFKqe;|y;2bo&}N11ZVA6~VrKQOnuj)-$jjbT`lP@5YRmvz-_b~h^ zW-22cc1x&6KNLj;$Pr)V4A^vORtZvvHuh^f3|%>c}+gH=yYH{DX#MsJ(lEB3cnSi;*lqgL&;IvlC+6!r&-gt`A}DW=hNfjux6%M zem#<*GzF83T6=)2@?h=EJ>0kxdF!8pI-iqkDp6_Ph|I0V@7A;earzZ#N6HWq^&w8I zPLo@NF9WSBB0ELNi(6Zi-g)g5A2XMmsSh6iC#h8lLvgOcP` z!)08UWo+J0!wh|`;eFW-3epW}L*kVOn$9ENFU%yTd(N3hnK6uueg=#kYm69AAWj|+ z13l;9Q%oD=e*W8)9VNDv-YyZ|;G1(_OhuZIRNx1BXL0R~&o6ps(N!o`zl$J7ctQ#V z($6^;nA>`xug_%<=HQjCijB=L2#1z8MtN5XJNeHMp}u?O;(iIL7mEGmQ?pU!Uaq!Oiilp$ z^ffV_YH4XPpQuxSDlI?9{Yf23%Cm`CKAH?>RWB%dN=ejpz}81wIT^NCX~%rWyXlO5 z=MM;`tXT_wf94b!57tkIeu&p>$M?>UOia>?euI=Cm6|xOyUQj>i8}HkoiBK+mM5X( zVwBB-3l|g#u$=DqY&DM={7KYxMqi1)iur+N;tb-pw*!7B#8gi#x2wHktz0ZMaezjZ zs1EPup2&teev)OHu@l=(xWOsomHQzX9vu(2cFHeAJl5b|tmv~KqXxv!dud7(wMRdj zo*{0~3|6}Kz<=?_c(Lq=8A>a0w&p(0akpf&iP)!qw$lLm*=??VWCxL&vEwjW`_Jaw z-c5o)J&JzMb6~rvxq`+=3zR~$v>9!DOIg;x`T5)ViF@B8@1Ba#UN@XC3ObhWU`{gw z)pK`8Rh>Vcgqq2|)mlD8kEm$xBkqx`roS)sKPIa13wd_G0iqm(t-eO6N@0CjZJxhVz)O-R4`&sE=3Z_;z#~ za}&wxoB|VcxUnv;$Q1?jiSx|iT;Q$JM!B$?&GUp! zVsfpe{dIcCn^vA91!OVpp5*;7CxBL|^_VwDO|I>GJ=~4aY*B4&RurSKZj?;aMj-1X z4Ux0^7bp2OXd78cx%dp<;5j{Hs>u1h?B)2vDY_1KsqREqVz08Tl1D6z;ERz zv69M$s&Zcd>JKw152h(k^EsCt|F|gWG^B^ew=ZJ%P4w+A^9B!b`Wk;z>7OVky`Cb| z@N{{v-`HqXWZal)+PnnQbwNR(b!sQhwxtQ6+}qT~O9)q^je2KXL2s*Yub?Rr#XG{L zTHd18d`#IxdcU>kttge1aw9-7g?N2X(ps6g?xAfGaUQsTySI+`3s0MM7(aD~A#H(JA){ znxEJr?x_85wRzM9)#kfqj4E;XLnFx)smgT6yw3K|FeA+c&Q9hho(}4V*a&=gf7@OY zn~0kaUiFa*)t-P)WpEd!&a*})KT@=$YUs)d761^3wToqUPj&HcKYhYjM0L zaOtHM%&YDEtNKu{=a5zPUoH!>^9Y&_cS>)?lsOo-l^&7XIzJts*Yj|e`f#f0HJ|z? z11|qimPbpL{}d2h|MMy+D@6)qTpP3Q-twSrXmdUM^oGz>)TSKMHv-L3DOyM8Bwg5Z zUg4&sA6qMSz-x)#-;?M>#4=JW=28ZN8(+ktct_p=d7ySeZk z`2p*z=`ECKLWH}*pc(YxKjNU-b=`Sc=JFl_&2-0PFELp}#k!jmsYW{r%BEidhJVBp zBpf-muNEURFs)mz60qvQdC6bi0x_R=`8P6Tg(^_LmN`F0nt*8cX!$2A-a=2^_|Mbm zSKjKf#_MhMrpEHKz-bF19@%nQe3hoc zN6EEtUQqDQfuxwgL5sS+@>X&uWodBPo~q13=M>b#Z25dMTJI8A;9*5sLrXA=itJm3~%`qAt=* z)&m=|77mzR;|4RIV}lO1Ow`;eTr}(RIjAWLC2?YlXl+S3f^VBso~@B98+?XuXu8BP zUjm-kC9LsYrjQa4&vlRBkW=EOA;t z6TETzXmw*uWJW5ZAmX-}v%V`(e%u3y9Lv>kVHZ!>5 zyMf@w|6u6c|C!+5F#au}BT6V?m82Xi^*GH|Nh(F9%z2ecC6?oi*+N1NOCD6%ipo=D zNgCN9$B{B}4%^Ha4Lh>U4!-__&o7_X>%QODeO=eQT-0jOYxW5|N!&!fr8<|bhfCya z!y|+@mJLeF%zy+DZL||zXzR%T=PVi_*=FDRD?Bf!RerMwzS0Ul3q`!vKG>N`$d}k} ztr$L`JPk4^B?(#&8^04IQt!Cz@T*M9yMrA}4Zb+Jc={Pc2i!)cL7^v$ZnRzB zU*m0BeEWa)Qge{SAL%`&9*X4i-36*(m!1UPDVW(MJGpEQf-uZBslzw9t3)x_!4~V# zd!$Pb9&kc7=%Xi(64*TU zLYq~G6)Mbv)gzI89RP&7Y;WUwo<4kTUK?Pahg$S}98n;ooWd3YzH{9u6}k{on!{}4 zQ_L1tZ3lsWLPOT*EBKfJJo z<`Lvi#WST~|M@pV2T_NWuf^Ac&&1yolu3aiwS;NCiP~!h%dawspNfZWbq&%EHlVqM z;bMikz^xcL;_Q~l6=tQN{(|dHE?fJ*k8hqCnKGn#ju-^zPA9k0f1B5AXmo~TJTu~5q@yl zDG@#Zj@rF^8l@9NQt^{6M(J1&IS?x|z~l{1xKEcUoDDeo-5-!yM486~_p|ejVJ^Ln zMeT5AazP}{$D89_s*mvX3EwBjei^hbvLI)&_whsm7N-@u4DxP4*5)F$Lc;=k+p3Bv zYjcnAU5r5=Pb@UP;w+f~=9_*)diS?lb6$A`jd;;7xLH8#a--X9gEzX2{7>P=hAwvd ztmKsrugU2lIDgtD{DPHq|4wM`(kW6LND$fla__9jB(Hh+C0q&n+Z1L?N;+W#5*h}H|i1S3Pmep%lvu7d_+&>6Ypbmm4m{ zZ=ml6YG~_GG_`eIQZ4UYjq*<9-}*D(EYUuT*X#rv2ilT1`240b`qA6TsaOilew zk)2ObtPZM(}?1SxLh`8WN4PJH&3usL)7OeAK@g?i71lr5o*M`4J1-QGe zU`Busq15isqqj@gzczlUzDjD@Uf{iB$g3EETPCmKA%*2tjXy0^_z}Rz)CGO7JBXJ* z@f|Ydam^O(7;Y*cCkep0`4?_m(du>ViqNET8~BmIp%oWvCzYv#Dg z!7fW?RkG)_fhn(0ls9);;xKWrXKlhT;@@3)tKQYn?LbhMT$DGO(~};(w>#ij@%N9z zYSKkDhcH}gGjWHI zHw9j;NzSh7&}#txbrsEDfrYnd7TW(}1$!OOwWhtEcikEa=rRSIiKxL&0<@26z&w6M zl!KStF5uOV^h|6OZ%{!vx3QFq)z9j8hi-{KN@Bc>#N`@;kkMabCJl>LZE3Yh^Gxq% zFa8?A3+HnT^X8KLpVw84SDYrwCm5)eY+R;F#a+k651+-~4P4lmV~RY$e+d9heX5jmnWYI`n=Yx+?lc0bj6xsk>tMu)AL6SZhM#&Zy;&(_KGb zte%|+AnD;gGM5KhCurj9V{(DBDuR=kj zEzP^%#)mM-dr)zj)Bgoq0Nrlj52M(8P`gV3BEcAWBl3T2@5t(#bVB`)q25N=;QM`e zQk#o|@?ga(WHw#?rpaJz2=3s{{yZK5NJj6!VK7V{Pb?a0Nw@pzGas2t?Y!Sz*t^9L zwt$$KIwx(c3Y?;*Sk|259t$;C9uwAw7&s0cQVqRs$?Or`5DzH%@7tRGsHRWzr8<+o z`y5K=g6NH1nlfeL9~bBYC-WX#S^VBhf~2R5DCu@-D)RVO@D!(Zj~5;=^mzmE{F9+_ zTO%M`NICi z#2rcDOZfoGHN;i}k8aZ55oH9}MKXEKTI79TRps4vFaMJ*i6Hl}78H9O(v5Ra6p8(4=o3<5Bn5W|CdFD(Y*(SuL%$%PyHl`=S4WkCIMvy2`ga zLQ6JJnD5Y`r@G%Gc5=C&Z~Z58azXpkS_=4;Q?sTNtSGa6*Yk8N)8v1gYtlQL<1n*k z&hY!3sg80kkSZrN=`MM{D*D*xBLqbyZH)N}gwuX^f9yz`lFPqtB$k8cjFhututEF_ zPH83*{({e8*e1J7-#_6MjosIfFE9jH*Y@F=qt_{dzo(? zB*bXIH&FH{io0jUtB%c(NOmFa*NcYdf@|*QTghSF@%QPUM7%NQY4N{UEy$DVrj~t> zg|=lEhl}xcXx}otLfC2fMO&8=DEG*8?f1N&PS5)2j$f&k+5B@wpmn&rrq%XYNo!O+ z=YA&N2v@PBJ0{7GUnMpMw`gC6tsKvolqGz4JM-_IvvRLHMwupm?9Y1ksDe`J`TIB@ zo&|kj{OjP&GfUWriwK<<2>~BL9g#zeGPU0CoNGkALPg1cfHn-y%9$R+?<@VlBy*A; z60&riziW1jUm)1fzN z=$ybWFw8dF1qS@4B-M|yDxd!J40;Uus?ZNDH!wehMxH=u(teq|LW50yDvp8iR}kiL zm2K9b%;1-?2&F_IA911~GGsIB|AZ#(nn?}fV*}7*d|Yjr|5RQTp!yV#ycnVUE%arm zjpw#iOHJf#-?@@TX3;J;z$hkr-#%LR)Ubj35gTVX9H_7h88?dIrL+^B-_iO@dX$An1)`GitqFA^3L=qGm&X0B z%U#Rx49F(_ar&QgHwD@)>>+D2z!%Rq{#5hWSux^F>s^6}yHI|s>ZJ)W;MPKNvnxIM zvu&9jU!*c4u@-ET^npIo4XbHEEq!iq=t=-q0lRkvdxv{p9JFhuJ|*^NJ~L70t*oIz z@&ig8Zuqy(Fda?NpO;B)JcBniWD6qJL8qa9?<1EvTRV$+ymDVq+BtDqDd#JvwwJ+n zme95s=aRw%?0*=3C7-5pripR?I8EY~aX<>UnoLXfxa2mf; zy99rO8clm&`$(nrR#}&r-%BB*i`vhX{P6I-~@F~++boJc{fAs|F0;!v-T*R2tG#s$!X0W+ndl9r&R`K zSp)Ko0i=xhw|cDy7uCILUw07!bj&# zJ9o)8XJw4;#ovA;b;TP*KJd6pv5Wky4|7SE)@Q!tkxU1IZycGYcYx$Mt*Pjf z#J{JcLX9Sa;^V5pay^DVw>&oR=n3rTrge}x|IRSQKBn*0|Do~>vWn;T5Z&o%!H_H! z-Hv4d1OHOX>uR;1h4fbw{Dk@=p1{#O=B;P!(c+JYAG^N!@sie~u#W-we5}|%3qzXy zt=7A#(=x$Gc0uzSb5}#-|LRXCQx6C*t!k$m(g%to*Tm$HPs9!>c7_MO;RIyvntLzX zFEn}(jU8|f6yB5_G_}=14{3mQ9;q}z5p$n;!$9#Q1C^7e%xYivyfI4+U*$cr6X_LL zwbYo(csPio3oIr_+o&}yHz939mbr(8W|6s&v*fbq8TkJqd%|CNSWk}cN8YXv?Un~B z-GjHOSkS+Sm{jH+84!`xNx2_cDPYLRh6rO1I_Dqf8Gu8C-}}#M!f&36xm&Ngu6N8k zv-nas#@xLbaKby>J3h`edw*(`bsIl=ENu1y!oPoyG2@G+~O}s2vqA zA*SFBCNQm-vHwKd@}Q3Py;qm22@geTwnspdErIQ#jR^^+9G#_P{Gc!>pvjtA6!DmM?d+-%wza3Ye*dJcWoZ97^j{DAPb{JX! ze&nptZX6K`7JC&%bGD8f$MzB(=eX)Gub~4_m%3M$5o@d{y#>TjL;$WOm_YRUYJ1wq zQ+j2>Mfx8KGxm}9n|E$uyyDGDiu7bWt}kAycgKCDwZy9Kp`Q6;Gj}*9 zu-l}290zoW@qI~gRi$?+5~z~;9083Mu}f;ujI+;|_D@3MAH2oFL&o%~VDLL7sNf3= z6M~^)29w~F8GF}O%GMdYFpXm=5_Yd2i}Mm&^8pA?wO>EDgfN+|yvB3NGq~5C;(4jlr2`fCY8(^0o12hj za14D%FWw$et4M3@lgWLm@|8eL>xw)|Iruw4Dx3scV+KM8hPmqpWrFdJkG`3o8vt^+LDY&>CCp-(xj z#-=Wf{-m{&Fw+3-nBNW|RmE$yCk;M{_;9tAsq`M32SG6imwKaxopHgTKy6oi>H%0X zb{blnf4xfNeguE$yLxEhqYRhDm`VGY^zo9&=SBJmNgF9WE_qjqM!v@(w*{O zh%~`>boYMjDCxhkayHQvq)q6PMA#|zXhmM2xekTiEUq zhUQcc)&B^xb4v1MrDmA+D|8OcvXC?rywAZJf9nD7UP0FZ+E$|`?MHa#i85F`_Ad&= zgFjWvS{Ze8n-cH`sK=Jag&#h)QEnl8tpSh6G46_6yEVW0n%IjPNp*p5r{Fd5b%LL; zX|3-Mf3nCf$>`1|T%`7U(Pl-1?R+t1 zNO)cKT2KtCC2m4t1G=bZg5MwFo-G3Y*Hk1Hd*^<{sVJ`5W z-CHd30ebFz8|%y3BQt(BW>E5zW7KK)tcbm(**mIW@KPp~KV-9KrM2`Kr!}uRJ+XEf z^AylL`aU*IzH}}}w5@l@3}n9aP`dZ))ul@;|G``6t@xgk$U?)4*nm0n!92oxiol;7 zV2<23!dd@I4P3IR7FdfiX&ilz`E>~)>0<`OuSfY+3xfoZPqSR2dD1E?748hQcbl4R z6Pr6}G@yTmZ$tz4sW!1V>$TS9_O-4|B;Gq_Gnf{U_y-+ZdTvFvjRa5}pVvflJ46-* ztBbYI$WYV3ce$RjXr$gxyTnv(Q}3Z{{FTh}5F|b*oOv-<#nWwILoNF1)kM7jeatmZ zYHm}6z5Ln>{@mDGREbAF`p6!j=7*<=wa!|{DbG#5DiETlv|BUk-R@GE9Zi?4NXptd zGuhYcZM#Pjr;RXMek2E#jK0ux!0DT;F_|Zhjg-Oa0iw*d-fixjLndfO&tN6y8Z}7` zsE=RXpv2{x1pMGNKBrh!ho_B%BdN-kWS`-;yguI6SRxh9OZMuLP=*>8CqOTS&-NCK ztt>Ds!JFmH!sh$8OYbC%2|cW7m+s0-pohV@Uk-}IyHb@_dw3*itat%w>-5O$IHvT# zx5umJ54DNbIJ(QQpb(r>pX+xVW{L|BLh+)>NVH{>h)O2|bPneq21y-zVk5rjym$G+!%EQCg3a z3>q%0tT{Pf7x_$1Z(X9P({Uc>6`>8{8*Ik9sg#GE-e8;jAP2Rw85CGt{&_p_Db%6I zkT{Ca?2aBGZPiB`(9Ie|i~ZrvkOu=(%o7PVNqGwYh2Aocm^X^5vDN!*@1EYRa+aDbF&{Rgyb`^bUtj4tH8rOFfW$nXU4%ZmvtM=PM){I0Yv-Rm zwr7G3Cd{Kq%NtxQUDzaZg}J+JIeM{(Wg;JQe#*eqsHv=e6c$S8IfwB)|EkZaba;co z7|BnRpJ>5-6Y@yXdZ5?tCt@x9)t@co4u$ghNc3>Qe2wHsn^%NuXKFx>5|NIjj^@Fp zZDq~G`Vt{_LSNxN{1zv|*b!6u`J^b`!z`6p{)o>(^ype3!I{D6C&$>=P9%+{o} zvMGys;B1g(vL-1aE_uo}$w1yso1}f?4Yi5Y6s@Cj$*V8Gl%*bY@po+j427(i!eK5^ zUP^9195Nn$T~dCw%FNa(F5(&)TO1TB`7MhKl6<^9X7Ot!9OaY+sgqZgwfR?=Y4tnY zVE=mJ>|fM2WJI>R;@W zplsv53vq6*bmaWYii48%05UeKNn(FPv%9VOv%Iv!oLBX|8X2=uc?6HM`6i9Jhm4R| zMSA{`Kow7dLS!KLK`a%4D>fqJ(!tt_&h2eoph7C z(b?Afk!t1XQpeEz`D-pqxqr0R{k>u@tMr!V!8_&g2RRwoTi`g)JS^oS>b@!mSSDy- zzux@i&Cw(WorGajr!LT3H9{bCaKmKpl?r?bqz1_7_8ghlw}o-yl!n&G4=**F?u^@1{vpm7?4}1kaTZlf2(H1UPUKrM1SS3wmAH?9{nX5p#M?dK-0t ztpwcVoR&6qTLz3N|6v-c5|SJ`08^a2!-;4Ip?yHiMu+TC1=j1F2@CE)c^3gOdX~6@ z|I~I*&(8RI$S*MD2f3I+t`V*0rKE@L(3We(dA&t1Or2^El_0RRgp$Nzg<_zJrZ)cC zmZPbN)eyA)v!c1N7Y;cwG|R`7V%h-r1s!>Pj|i*MiN}fL_MNiIK;8u4tk-SqZt_3U zylMNP0^~Y*2;BS;p{KZqu|$oaqQXDOS_#hYJm^Zf)jaA%R||5hLgFm7Lz7BFWoITg zWT$|5A)$GcuGMjB&vHhR1sF9fj5x$t=U=wsXd9L=JOtN=Qd~tobK4gID4hnQgFv~g z@Yliw9l(hA18{gjutqsV63CM3t>Du>TOp^A=f&}D(QfqpDwvKSFo_LW;(I4hGr@bI z7ODfnb%GGyQwD!+uleT-Dt3oc4%o1-p7@Z(XBA8(1n-fSmDuG5m&e|UdCxriv9%iE zJDJn119clZ!*gTwEgxR));QO@NA-H{T}Q&4@q(+s=^**25EO}+gCiIg!FIwe0x(V& zZ&w(PbI%NOz96cZO3xXCRxHC?M~o`t8#;Eiu8Lnsj;;ZRbHXgbI!Z6@T4E<|>T0gy zfRdS$`QJX;gPXdM?51>z2bMo7PMS!tr-Jnu@y4CdcpZc#^SA5&iG%OGSjOP{>sgXJ zW3p0p*pV-ujKuBL@Fn8c0VWt*2k{JxH1I*X^F1BQ@_?wL3 z1`XcEiNl~^#mk11%dZBuP2KgZ{?JvJRw}RyHdWot(}C6k?se_~TJ*$U`g(~ORJ zCqA7`?CD*!ti5&O<1|H4-wqk}PH5ztb^2Yeo4MFQ4(&2X!xxqx<>|*k8wxcpF8R;n=o_M(ICfwR(@HQPFq%WPwklCo5_;>yANtoll$( z+kii6NHp;z9+K=rs6>?MiaXqv-+&0mvgY>c~eIGu;l4PJbtyCZSu)^GwVjHhc;dQ~2)`jwO_ZGy# z7|N`xH{8`b6Ah92iBqv{<5a$DtKlYCB!?Dg@T01qQcVv1$& zDFt?TuL~#6;SESZorDE!Dk;Rk%_&f)RKWxou-_qN)u?V>7X4Jder)<#I+O6(UWxpU z6Dn=i636i_v9cuZDfcP z*h8G{ViMmf37|MHjV`{(p^q~gR#WCJ3Sh1n&TFcb^uhj^`W+}H(Tg9${v&jyrFMsA zFec1Rd6p<^axhvg343Na0oGhMhK95H8||hU~_NeYnoc3g4n1*v#na zBdb|`X8v5_Rpg857wn*y70-B;%KkGGdyZY0Ja26J?G1S=_-*iY%96u`y{c^Hrs(e9 zJ-v1VM2CQP_{z&k*y*nR#W~CaJW>9Ro)ue2#y~AmPa2+i6SBmS4@i75Ug^qKqNENR z>6Axw^u}N~I%o9bZ=wXz9iSt*EH9Ka$7iV7FGQCeE_nv0xqaGu!d~i6xCo zyd;=51?~>Be++GqbTBmQltsl8gyQF%m)_lPOX&j^0j3mM3jtHc!?7GykFOOfR{HZO zmwWBw$F~ztq{P{kL(K92md1_5%^Bg} z-R1U&86`~)4nsOsZg?Xq&%>;!N%Lt-Z}#N3r~+*}x~YC8@#zvqPnlBO)H3B}A-MrG zFK3{x1%FYlsCV#6f#_7(Mv`8MwkjMu2359Vs1XUs+8@Ouoolj3;NGxW)lz5o4zPlw?(PqoMG2x z{H5xvO8q&=C>VWavJQxw=-k?y7X50%)C@gMRSvoQ(Vf+d&xFGl@V|M=Htp_-XGLc; zKk`_slg=6X>sW~RVpDN;4L0zktaK2c>Ft*eK2TrAc@lxJ8;GbXp8?=1V=oAGX6M;H zA9?xi))41QA5$lbo`3}Qv1I37$oyNtz%q?nT@T>hp0Fjl#%C>9qRzCY(R$o}hVoi? z=3&GMlfSmh+fc=MFU{AQGYMaldNrPTud-xEou=TL`ff^^d#LWxlPUYJ(bpdHf}R05 z@ChpG5z)Iad%UL$egsQpqH16d4np|U<=BNt6V>IV(mtqwu zVT^W1j#nYd%$XwZ3EJFelq9i~SwYDg`qjbpWOpx}7$IE1rjX-Nwb%fl1!9X*v5E>% zQ8sB_j<6Yy%U9s}$1v79Wl|{Xn8M+taQaV@70Tqh2=d`e65DGBt~8N}O+6%YPlacI zUIa`HWt6lk&S7hJBX*^*?K6I*qgtEX&`(PzKxGM1tKKe}T=74}4bE08sHtR&GbCKi zhTr9q5l8QoothMg*0?m7C^p)lap9U#s$)o(3}un|1Z>nGNn3SxHT!CZxPC*tX9~E( zb^#d9y)EVb@Mk82t#YYbUFH-oqIV&0B3nSw%!}gLO7AP_wv!%jLdWbEgM{Y?KMtZQ zoC;bq)ivx;UFbgR^d;{nQrWLwf>R4w91cbkj$xTEBT;BRvNBQ)ng=WEff`BBG% zU6b}tWW5VPvXa>G?^D^ui?~wl&qP8TURKbv=+_=5D{Rnw{lHp&Gu@+FO}orIV{%cX z6|J2Wy?$AAusvL2ozLi^mB+4GWmb1&oG3|SpEKXFh9;vNwv43=n=0P?{0NfzC31^HWMg8 zvQ0if>#W`^K0(v+0T)77nIV9(o-{v3E^VnzETFql3_gHEx6IESk61p8i$c4-GPt#g zjZr#exf7ySJiBfTG^Dp6pwc*-58D*lnYJR6-M0OULeq5`>vIpt&bXqRaQfO|h>~Kf zA^B~>i==kt;be`Ds~gEEJyOl;HQ17qGD5P|7u4X@7Mi?%`3Jjyp`00*CEA2U9umRy zM76&F)H2DO$@WGwrW?lo}|(r+?XlP z{RxlLZYVXVTm0N+9}v88PIO#NIuk@5b)!hWEso0bWFjN>?D_T($?lSLW0*u@b-gst z_x-mvJ8PZbQtr_EFN#Uc!?u#sP+t&uVU2K7VvYIGcGtx_-`do+%p6)&5}=wq{sh6* zcsq2)KWG0PtDwZMX!_{gs@?qOpp zRNop_CA0Kuvn5xD6Uz?~;l~Nr1*L%GRlxR`s6dgQ;~z2x+iViTq4ZiHkqyyuaQ!>c zMdN|DyL{0CS#3=k&;1NmJ24Z%(HI6l2-YK)WKE?1`XV|q8L$C64|?MMQ+r>-Axb_P z=C*~45<1Hf2XN(3;g)r4f8qg076SRF=}@%l6R=VPKNV2=<#Nn!#;4KC(oW}d0?)h) z%v;AM_o(_DU!pqg*;Md09#@g9yob2e?MCk$nzlN=;C0J{333C|>SU7{_PJZG2cNYA zbq5p&uKQyO9?nb-n8id3lChAX$^g~xJDP3w`z&t(sAQeM8lGPIHgs^59tl_9U^fN! znyW;G*hiXhcjVZg1xBWb&L4!U(T**&KIpuT+#(bH?f1O#RD1{cE=j3B6joXo@Xb#d z*GGLr6Rz=xW`xeMRT)uV`mnD*Av9TNc~Vww5{ET~A-@ z*+{AR;yYzQmj4@DC9C*JXM^^L@-?1iw@7=0PRblQVr{)A2i|DkBs?N^%k|?ZxF!e4 zqZ*Xcy}Gf3HVP~Td)#IY1gxD@gI7|%|8L@O&$@5E#P7fMn`cuO!ibM#4e!|wmoMd8 zhvSYM#ws$s!WcimUiPQvsdlY7M&?A#{YU7W+j>oAcoro+kM|R2>7Vl?@;b^B)FaRI-K7jg)vf$9 zk3NBFfjXw2q@U}O7=|Boig(HEk{_SEF!ov^BIvA$O$BI5FJ?+t;mWmwEp1n-+K&90 zXw>^aaN)N(5?6foo|r_gKeB_cr4wwWKYt}z>z$b>CWCrouGpb&&-;` z)^Hz*dBV|Y`%8(Lub*-6n0|CO9a^P9-?S$w&Sjr7fQ3bCsP0VJq0W4Wo5_Hxbg~Mo^tGA zJ0feScUFE(mV~p7ez_Myfm3IodUb=MJI|6H6Lxy(2`}w;aw8j{_JUtmWavuX9m(~a z!_>Jmf-D;_S}E0ikBZp&Wnt4NW=9pyW_Wcs7K8XY!Uc(-=&alks6yIS@)%E38w}lV zIxjO%)Nx8TL+ASyfAz`%(`BI>kK#@_dg(epslVcEk1Czn2KE&p|DK;C?Pc%vuM}Ps zl*97|yMm!f1`~=Zi59YkvAs^Re|ho{Q=VPV%w>m|xFVFI!nW){f zses@6fJKAtix5WqO3X9vNOW%Va|_0&f?CgFgUUHPHFt<0hfsicEG_HE;^)m4wYPo1 z^oTk{W!~)YiDNBFr!-y&Z+erhHLcKP{6?d+;@a3iMvg5Mik!i#tnM;gt`Led*k1SsE+lA$9!xGR}+LlUEFoX^O>O@D!Y zJt8lWw?<_$Vms{%M$e0&5sAG+!r@2M5c`+7JO#cp@t76^aMEN$g^{zO$*F+wiH!UC zP4vIH6(G6GbH#DRi5l4Mlq`R!c6g!*94cv;nZ`%Y0gp*^)n8iqD5D0C#o-5FRgDY( zv+2?`2sQ3aUR2nebEcfbZdoy!)gSZ=^D8n+M?aTC)^6cz4qkmvr0h^IsnXKe^H~{x zxkZ)q?b6~&_w}iG17GNflC`O+#aTM?jp-%3tXxL8juh2I=XQ7grO~uw4s)k3FB5<# zDkg1fk(t+-_a3iw2=B1$2@d~jM0d^!`wcr|>)*B;BcaF=hci(+i9T_zDsD-r-)ZD^ z-+5|c7(HXE3s6$E6>8o+Af6lq6phcZinPe)q{;SUFm-^{<%SbT);|V}M)k7v#4>u;I9}GL zOj+XjI5(-YYKMK3aEW#7y*?H$lb|ZWH@jBNCd%I{3xG?q7c&5&k3zS^!f^xLO155g zV6|Jda7+`d9~`JHz5Ja*^k4iWcK_r#sl~Ytt-8EgF1%0DFc)Cf@{;zO0K0&*TszwV$KWgtkZ;6>tx+buQ3Orf=o-v38?!`AiPIw*JfG z6!YKN(Z~~m)u#vz<=D<9dGgz<&zLW%ox z&F+)hE6M1vGX>}RBy5~WGMan61SXW9oZi%kjsPt$?U6=rXCy%@gj%Z$TL}1okNh7> zUg*IwpZWIcZNM5y1}ET6Y^cI<$j^M2E1Bo_qwo6?P7K`sUBVNi<%mp)1 zF6fKg|JWm+8(E>9^mE(KfN#F6BuQ_K!0)okO)cNRn@!Us9rO}4wAux=EwAP)}NUW^uKHiwS!+$xNJS+s^$-NaH+!OteWxpN0OB zeV==r@nct5KS<6&t@ax;IciJ{;C=Df1VoGN;aL*)2CU{X3pa~uBW)~%IrWgv#WoV| z@8l_SgRVzzFyCvBzi$4VQc~Z3@xA!#l(*;y6Q1wUWoLI;^lYke6L`O~b-kH7kD z=2AO_PvTE`UJsrqfkc&v3%Xo%l1~iWLxZ@VPW)^%Jx0FMbdG--;k1-9ZW+F`L)KzE z?Ue-+iXf$_K2-AIq`=*=lCsX;@g1Y-01sl$K=P z5BV5pKB`ze4Qqstv1YAM-`pGi8q6d$622q!on^=W)X3jaUPnaw{zRinWKKDjJzG%? znQ@+LwCz1$%kt?s3YQ@clhLd}$wbFaGyYJ)_v^wY<$vAbUux~+*{W-tW78M1B*Fg+ zjN|=P8u{W}lM;b(Q=&0jd2Ay<7U8zg6+} zK)~aL3LN5li!#^q1xh=8n zW17>^ytFpI>-Z6r|Eo1Ijb6eXJJjjgrM{~l%x&1Eglku?mSYCayG0#JrO`CSM#AfY zw^c*d+Er*MC-h%T6MD>Y@~0a)69-34IwHzc1+cJ&zw8rVll(_v7^82VQ@TR;wjaJj z!?G?*KlgznIOnR6h^vhe=O?#RTV6(_U^PQ4SD3|R#e@u^j(unKlchpXE|o1g_x24y z*S^-oFDCEYLV%Z7Pr_l@6MELdGaUU_9?0WLEq>esiDeTXEF5Jv<}I3Vekr2y_yIvl z>=6m0hI~ZB5yalwDFOBax?rNN0G}`y&TBFrYsHbpw*+SwEUP$}K9Mv~JV;&5 z#x*8J_Z?Tgr8SDDV-c;oBVeZRA%Rd(S5IKwCroHAp>WJ}V(08SoWCe37zE%}so;+^*2!A~5#y~hJLh@YkUb0qihNK#H8}$thKw3rK zO|F>%^rgCrf{=p4AKZy2qY;>jLIKC!>o?62dOC%Y5f zsSJ|=4pkoOri`Y>HL1Z>2ncx`AKN-LMe}>M( zAL>7j<875+l!{7RvNBIb_FYjS<%)!i3rXhL9Ote`k|KM%C`m%H*PShU?>*1H$?dzJ zf8q0ed_Ir&_w#wZo=@Uo|Ak@FAy8w;THp#Mn-I|q*?e8ZbAH~C<8ZWsFFN+sJoQ?U z^wEk5*k~o6qG>1nHtzDaZke@c`&{W>PkUQ1Hfd69VVotqR`r6t)AJ4^k}9-~=&Py6 zrs9Q_VfT*5mL1pl13-j$DX^D#0{fgm*eG}c`^tQY`_>U{AXh9PYL?s1e#)sSaNTB> z=EmXy6Hkgs{wo6{{_I?MH&{AqUZds|r}u|jCvh3Z(#c1a*_8)@>YTflf~4%FC)r1n zBPU600Wj{zLS4rurLKra9tDCE|CT-P!;T5}S@%p|{AXrOWB3jN&%TA!VB43**>Lt` z+b2|3m-oV!1HqL;j~svqRt1Z(Cu-$l8G(deYR7ns^H<*GW)6jIW_>xoZGMs+9LsBm zdx_ERT?sPNWzmtr!(jS)+U@|3+_tyAQc@SJVnQ0=xjtcx8=jB+H*Pjz9lc=Ojj#WY zGj#`b5I^e>2Rb2=)#I6O+(Ys5BSG<+g#NN2{aSvwQ0j}c{t zo+p2q-P#jDgo=`3iS!T5vsr2X6sTy;*cRs**aB|y_uXQTxxcRZJHq8;Vc#e>qg^kjo` zM_&$?xv9(la5yAcXmTtCc~xvng5-i*QJs5)TdND;o||Ns*qbb8qWEHXe)MLlvp;n5 zI`?OFCcGjG_GZ<**r&{*c5e}ccd~nwquIu7zOjjaYL*Ml9e&rG6Km5o3J-ApP`xHW zL93sCGCOx<=#1+C()6S;3DEqZ?ta3bY1>xs{6UE0x!Ii-s?p7q>GXhQ<>xa3kL*0( zzEd8#{qF(myOEY3HdVt%CGv&z2SZOwJrU4TJ$%ghzqa}J@i23xyRY9Qz7PEUiLdJT z@}nW{t#m`;a>&s%TIcH%4?Lo(bjG|m-?Rwt=n}gc6J%t|~+4WBU zG%H#!w8*T_rx%+@npjjFr%gug3yfsIUR*s`Kif{)F24!1vxl2%d_kzqB z^~US3gyz-W6`%j{vRfjOH(pJiFaLF!@+8FTyQe@_0wjLqd&Dh^c$YyH|Hv?(c=~BQ zqY5)GQ<9*jv03b|*_EQJn^3VJv)*-p2TazLff!2&!J5=BN`t+PdG^O9Fv?s5BO0lcjLE+(NE=km*L9M z(bKsPM8t#hwH_GdO`Y6*dXu)v=qk&Bs0SB`O* z1?-W*(*nko1!fI4%O=?;Ma&vUW2nIR1Z_Iy^ME<&iRvR(da%LrgW@-kTe7LjMgsU1 zareJqd9D29Xjnp0n98UDLqSuImB>BS^d(ZCt4SD61~&nk&^)h|O=chbt;<-a`VzLI zu<={vGKmst_hl_I9u=4{6uGLMFgb`%a$q(gu3hHKeKt{nW>&nX+ zCG+}WaxL~$itHee`*IKJmrj^t;JPWylx73uw@vp+pZW!u_Ja(xhmdTlH1}{PYLMop ziuvqg@*R?KM|((p!=8t5V5l$im&GP!8(A2|43jVTWnhZsf)Y88>e8R8=*BHWqW4%9 zv?czx*g$NNm6E{^Dj1`W~gk@6j^c>vyA4=envfi z*I2oK;OSz2#&_ac`>&__rgb$Th1i*Ohona-rXP1}?1{#^N*K3dxVTR>!=L{w=sNI* zq3qzJplGnHG}JC+W4tG4^$N;2{z1gO*jDS)qDBq(yvQB#CH0*{(P^#+;k=u{`2-_^ zyl$NO8wpF}lexAZPk}B~r)ej^(T1sv^>;)bkjARb zf=a~6fudyVM7TDf?#FFHjc!HtzineBsMyZu)ZD)p$un=ap6<8AOh(evC4ipB+m|v+ zFd|P|S)#v}Lc$~GW3BjY8pjXF-o_fXicx;r4w0>?^R^3Hdd!g3pXKn$?I?lmO2G+0 zXeoATbP%}T7(^Hqs0&~5@`Mt4rNT1m>ycUA0<%vhY7GQ)uts z^MZ3yw`+s)D0kOSEXpx5+S6EWrHl!UG5MtM`ux2HJ+Gct-bW^u{06>v)goT zyn4vmaF-FY0#d!_6&d_NF=xMg{t-*i)x6LLn9Z+osJhVtN|<~WtoC$qEHVVTs6L|S z$LnvI|CfK~YAgQo#`3_sz^y^aL`6B0@rr1Ski$954lD-~{>?t)#5cVr~7PKiz{fp%IY4 z@3iKfFhu-zhetT_8m;qD6l_+oemsI>6u-Hf=Uu~d676}F-eb@=NcF@JcDuz>Ff|DS z;GNdkx%-;uY!u`CRDOpTzFNC=2jEqcQq(=uyei97+Rc?|Ufvm!Ryc7ob`U6u&*5Fj z7fYYlZ%EA#_-de)8~G5hcN=)?Sd2!H?IFZUOIbJuHRz^q}f*ciS30I&Zt{PG8hu95P6Rx2>JeFt~p+#-aV5vH&V;G8wMi z#q$2TGPYLe^&F83`HLeU!@ze1A|69mYTwUiH1i)6#B=6c$K|d~0bQQy;ddKC=`j7rD2XC0$(=N0cgDcK!)`{_6%1}gzXt(wkq>yW7K4gnzscG zasdmmE47|SLcWQUkw@Ubv-OI(`FGCS-8pICGMnAryXJ`cd%(}CuEdL6S&F6 z^Gc|_(TkRaQgysAI9=C)!xwKq?X>8r$xfRSKAkP_um8KlRMgL_C$ov+$GPprTSt-4 z!>W{t7UjZ`4X^&pEuOWV8LkC-pO3`W_+29%@v(Zty2SMl+a0#hlcr2vBG?DGcE=oy zUhRuK!`yJbpRwcD2ivxQ@KYjh8py#Ol|6N)^AW_YHa7`Kl<}&8FYFyUfiQ`QHcxNZ zI3(n=xO;piE619j;IyC9Ie(cT9m$yCY$?D$I&iVbm&)tb zd{MPKTo2A4e0Li@uJ(>=}dL5PI6UxzXVcgppiXKm9l7S+5FwDpGVHq$Jk}tjA5{gdK@05&IY=!`CTcRE%Rb z?Jg5K&o}#$jEOEJ_~K2?J3)quII0k_d;g1W>ci4G^dX&=74--HDVb8hL)nh4uueXS zjyhh{mJYp+H1+{mGysI(8;aa;ewPyVZ4dcFd&@vk_u&CYFRk|8zCFpCP-#Sa6z`|D z_jNtf<^z{6A2 ztT{@1N>IQU?v5o*2i5&Yb@(|Yj=z1vLu;&xp9ITZ6Q z>o3+26JN46+A;iqU^w)X(tj@L$-22X*eO?4lUj`}=W-Q5f1RVby}P8YOY7 zlPzH&!{RF_U=;schW*MX2pu5Fj7s6@tmLnCxP|ef#PE^?uwsol4RY>XqL%5Mpw8}y zk`dK)dM?W~pc78Iw1O996wDm5p#&afIWVvHyKoFKMf+yoh*b&lYDpGFq#HXZ38)pH z-7iYLG_uVzKH(*pon1Q@PaPRjj2!sYI1C%W-&hcqW&&#-kTSJWL-T}MI|`s}JQ2dj zAt#WJc7Pf&TGU+>@#eEUMJ7Ax;CBy*Ul$)*K_Cb z@pCSBOg|-?H$%E@h`w4(h9`$^MO}P)eSi1kxH&zKCe}qQDUPRFG zZtPUia~euU2ZchPu+UObw;5!3af(df+k#%U?*|k z6XH^mZE)l3)OwL-M~pN(8Efjb>P@%jh&SqH6Kxe65>bAiyRy@{BtWvw3P3UBI#zcX z9{&BX&0J!?lLlQf7d5vPAIsAIo=@WZ>Pjw3AN`0)OKgWH(0+PV(yIT&(SEc!blM`H zlZ`p1L@3huvpBlDpA_jf*9mLZT6yntP)ZftPpH3$ln*sCJo_R#+5Zzi>)~OjL`e@S zT|((t+Zwbx2pDt*@wy(~ahjV3Zp4Ylm#|cv@ZTY$i0r`gTc5?-^3!$?La^&98U__?zA>SSZo?ar&6HI!bfrLP5`fowT*IBQ=A4rDL}Zy2`f@NXDst z^CVty*`mC*b zfom?bDDL-X``^G>Vz~NYjeYxi7uHqLt*M_y3181g=CStBMJ+mG_tvEU_&-wIIrAR2 zpQ{_6Lf<-)fUaDaWa%m7r0jtGzk-*o`4pHmHPqP@DH>A4STu8IAE48Mt?VnuWxWQw zQ112V&{~#ad!P+M%L{}CJXZ-EB@*l|hcr$u{Dk;(yt*wVF5@Mz!{TSdKdC)H?GsAO z?-SfLY0q$0>U=wEy=_3@jIQ=p2=7>+T#m6E>*((eh0EU{RZ4kufIGC80@>=7RmgUw zv@(KjVk_x#OB6J0YtbiZ`85`du=l>Zmg2{|nKb9U3G_=`;D2PUol~e5v%Z=hIpn;> ze7O99(6{PZ(DLk8y&d_<`+>Y1gMqs8b7Py<#(zto zF=G%}@g5mz9= zfTkTg{@Kc?x!r<)g&W7o(@yUUP*AZ~$SbrlR>5VKTqW!!XH1n*_k}*Q-{QN`zi&?3 zC`qB03XTIx=tl2P_H$UX`Ib%wlw^8rFV~&(M~U_+2QB*_$2I9zfBKBD=tIE%atJv# z1Em~EtjYxsQ&&Hgc$^EmV-lh)O72L{8a&L_IKlevoO6R z`h1W(*JJS`|5J(K($7NtLkleyCs{(^k1K5kKv&kYEn3TOcdOK3Zjq`-)g@={r zG30h5&go>|8@oq7t53cqEggKd4GEA*%Ik)Udn-a@&k@E9?-KNez)V`cd4Gs0yLNgp z^4XBSC)Yo*=jd9;t@;V1ecegFaA@5fC>foO%`m>@kxjx?6$+7UDE-!k@jvY+ARWB? zyD!3d>c*EMd;3&5YIRxw?N(N9<$UHr$-UL1B}jp9Y(JFxmOB9;voUKa71j3SaEq3H zK?}34>fY>me$LIBTlA}s!1oAAZM;6<;7U&w4eQEnNvs~Db;><$#S7{BlX9DM zf)zx6&Lgzu0_xs=tlc>rRh4Z?S#)10vuO358?HslzftE9M7RdUtp6Dsw zU`lzyla$|ywfVQmes(XNs$v~waIkH>@4Q`61Bzn|0qv|RBPM*KxTmgHZMXUG5_U{3 zy?_hrKF*&)k%&!3<-LBho&I0suOaOf)Wh>tb0oe&P2b1IDQD+}JmbJW{8OrqSr}A| zzj8Hh2+Ul$;hRrLbdhKn*+edu`r~1H90)DcKiYNe%Le~5SwL>cinNpKB!3VjLVJku&P@F@MsYtQ9R^vvmp7J2;XA%64 zBQq2?rD1^WR{BzjV8*?1%Jfoq&*YHw#^^{%8yb6w`TJS0xJpn>mznCEU`N#4J%!>S z-?gNNdUzp4C-9OFf%+!e8H~?U2PQP!u-tA+S#qOSRGy>2UyqrL}&}stj9P4okn%q zPF0n_3*5@Wi?h=J+UItxVGxYjf!xF)Ho^rRTT3>KHo;`IWw0ID{?(i9A&Pb`755jplm89I%uDdNXDSfqkG#wuPxrQ!WcPu^%(h-lM` zKXj>*UtkDJyS+5#O>Ua5D{1EfJ@QTsX32wSBnDw8zR*Wopp3?Ot1l43+$23R);)dVRn1h+DYW@nuDz zT$2}0D_lV8*Q(ll%q3YLM!bFhG1Sop{t`;TFhK7W3gx z$@#4=c$m}z*L^!pwlgoK?p%Fk(Rhh<%&;TVKyiP@7s=b7u+cYWCtr+5U3gE zZOyU_Y=?2)+$mS-V+9jZ+T8eZd-Awuc`zT%)-BO@SFI5#ZAbg8j1HOooi^-CoFWxykA|iuG|(DUcls;ke;^ZA&WtWNma)bldRiVD^sOMD0ev97+^!7|tJ! z^-eBa@%n?W0`sz=r$9z)t_+=kvbFhoPAe?)8(f`INmFS>`o2E4YIh~@XFg47 ziWi&H{T;8@>ih1*GBiViEm|9cTYd*Kj!&z8wr{`bKY1~(Z_3#i?Ya{MX$Y5aKBrjr zv3DHgw0)%4>_Gkn%*0yF@03vW+V08noPy@WHQr3zvsRh2ZpL36Z8YE>eRog`q9}W7 zVvVAuUSGLxCe)DbhGvPAqGrFSHP9+8Co6UhWYQ_WsC0TNh0qDb|d$Q zL(u`uLDYNvY4J}&I{tPtjL(Nr5EAEK(twBB&Kp!bK62klbh}GK`;Q_-54{f|gXaBH zbl#;Oa@NOe^)Lq=k_4gC@2PdBf(LdCi4u|BLP-A8N1^rphd}$j`t}UD3xLQI`uy?g z5w#z(iSM@4M{=&97;=kclE~qDUI}&jd;waJY7g);nE%5~aRBt##(*lTM=s#gz#ZF3 zr?<18O*r3KJCi{@U78{f8rr`{w3eJ7Whjm5Z5565w{Fc8`dh5sDiWUw8R%Z)@wkqt zyZL$CqYp30bt9MV2v;oYYNPCt*N3|W^Igd*ILlDfh0d~>vjGwGD1$dbWT=&PfL-$v z|8RK~D(1m7j|w<{v72R0E764ns}Z9x##tw_jbhd-?_#GpP~&aH$U2^X5kpduD_n#GP4uadUntU;pTLb<#(* zl6RW8_-f;Q2Zu)Jnh$h5Y&6X?Om@II*wYiW*JJj#Udo=pR&IykMdw= z0ly5g4fWfvZV-ILcpQFh8(0Uc=f`|NC{1D_Ko;4zPkTZoJa2|I^^gSJJw#IN#nDppv z9NAheC9?`{Nrq(fl7JOc5T7TM!UZ?sv$IonKYiDV0z-4C)M7LEfhnR}HRf5j1nM50 z6j<>RfN8@mbxwJuYe9jOtSlBcA*j2)3XoH$}8caYv_&@~_yGg^?NTy`{c>VzW zy=w*fU{4HL5!*iPQ=6TiVGLMNkOZ_l(Qa0M($s`5oA`@!C=j9*$*EValh<{R`8Ga! zMZeK##%-`kXp5@-E>@y*+q7bdyK-)Q(*EG?!Ff>A|IG5$b|!li$(j2bIAyc{ZmM5i z;D8E|zo5MP)UDHzq`IhUe#b_pGc~?H0p`dk6)bm2O7<-7i3!ROUyPoN+-Y5ei{rF-mb_d3(PQo`_4 zRz&}i{uhfaOBx9!WoRv%+>c z(H0Qv$Vm;iGUBxf#al|QufiL|swyq|q48bIh94?1mUX z#t0lZ0P3W1k^&E7{%FXT8T1ruC`8VC=!Qcjn|;gXwH;8tm%rB?)5^jeu!`*0|Fe^i zA^!B2RWKPO8Cr>+oCW|HIijKU`742^X5}?V{RfU}iCJFVuG(~(cx?9>1Zor8A(E!;RON^-gvOxBy7_;-~SCxvCSCHFtW zRe<^F+Mt<33oq&g58^?Y#QRSJN*r}4JlNxbhb{D+2-1Y%{}@&};aN}#WIGrD3rhPB z)M>Wdp_v})ifi`(bg=#j8o1(QcWf}ky4Ayfd>P34kCYND)}AT4hEoMC*GGjY(MSW! ztyUqC-I&uJ=5;wO5$FLwmUJkwrQ$w6K#r!T;`{V@_6LDQxmL~WfsHm<=_PC_>m2)T zAQ{{y{B<0PYvBCG^66o0h=IE%osb(s8bU`5gN6j~SQ4xSK%)Qmao=a$pNduLq1lh9n4?MVdH{ znxuvfPPi=b;BPK!y3>z9QbbS2^-Q5tYIKxUPjeS!7D|q>Y(7JCOmHI2t;F{l>KA@Z zJOjkqHcf+;<{#f&Mqo@<^%ro5Xx{)qivptqht1yM9{uisjcLivK4NGF6ir2mL_uke zP3P*KnU4Edpp>zB<#4fCJc zCA58l39@vuycYub&F?+!v(6_SUTFA!g4L`Z-k3snjD3%$z6W`HkJR(XGtisO8P6@- zT*iB?j|$bE?HAq^3l-3Mx^o|Tf$eanyf`4%Vb1ams7k{pI#va2^PYMlmn+W~+uc1Q z@SrSQ8KEu;Zj@(vC=AXA@M+2FUhGd05tWKHQf;euLh_TvO`JG?sw)>8UFeVQA5Gc8 zS~v(zBiwO%J$)*urDNMX(IL9w@SY`k4=w_>T`CdWptgLi;EypY5-lCg@>%r(&i=fe0(gP64+Qn$Oa-C<)HwH_DA*x%$D(D)m z1-L=I3u$v{`{9QDS9B3kBg6}cV>f0@MkVua{p^+P1-|sYkT=jEpz~ZOEGt8aD}-xr z@XTbYhn8Cg?WMcTZsH_MX`Pq$yN)l6Z?_D&9t>YEm`D)z2t;MUvr%XM&n1mT-{`tq zA+nwL0J~OFb{e+!0`d==EJ~=GwBLC{RbshBHuDRPyW{p1pwoxBug0e|uZNci6Ra^w zKZuNF6_6U!Uy0VQ!i*!HbzozrX$W@&|N z{=gh(>y1!dJMAYRsGRn8f1!oc@}FLe^>w_oSm27Jm(U&QX#nbEy*22BwuKMha_L@9 z(NP7ioAb)dzVEiphb&)BKy@$7jo8wmtk`Yrr!+rZBiD_y{*?Lb51+{6Z$p$XZ50`a zhdMxUA*OITVv_K zmK2-x1)Pj#N^Q~ky6ZwV0V%Zxlm}{OSsOJ|u_hNwfz)41e)9Zon|^&2UNx4R8m#7S z0x$TEjy(M8P%kk=v{u);GW)0ZivLAXecm+Sg>~K;;w>or_!Q8lNpzTO>&za) z76@Mg;5HKqHB&H;7~-S55PS&x+%qG%3 zdLj%C529n<@>g6SDn|oH_OgLowVF-_&o>HJ|z`9`gXy zj>jfIugkCpazni<-7U%w5*~B1*wC$uS$~}vR|rS}WM75aFMwD>x|Ss?8}Tf_>(>z! z@z_Sv2zkMtWxEg;VDeT}6FnMU_w%MV1?Q6Wf_byEiqO($c@mVDp8y@*po9Kanc8fo zt_WbCLfW|n3lGkmfDQ+7MM#%2`7j1u*$O_A77E%6{d3XynpXLW@e83;O+OE4o(~@- z_*BizKO|IqoAq|6q_f2mrPHFp_X5$<>TJYvFNlpxc~TF)3}!oSA657w5{Gz7xHy}c zp`cRu9b#>+b0Vu1=Bq_jWaNJmRN_y-wo|FzHMywW1dSgQ%g!=m4lGcEY%=PT6wo)> zmp38VTp0^eGFY8k_a|qhHvHjVwV$|n(DOsaAKh@CPb!B6py~dCg{s)toqTG3d5|Sb zcTRAp?tRQC>)d29T(eiw4z7M0Nay(wOAh?dPez^R@a~QVS2U86Z7Z#IY@2Fpg*a~o zn~i^}W3B5S!NzuOX7ejNgCE)|&b}ub`S6L=vv0~VS#wc)m*`jZrCn{JzS1;qWz5f; zgJl%WJCAj%#jsxr{QwVR^rRrpE!0V;Hmiq*utE)t>_jo*x4$geXBi53|ln z?MkT{(e}E8oQ=ujR@oP*zYgeHSBZ}|9o3-6P&n-r(&KIUx|AHrfSB3&7w}$rjPg6y zq$X;5ULAgo>)<7Hu&l=wiW`?4_XTH=HvY%z+~xO+iXab49Th~I#^mN6Bn9l2Nt4`g zg}r?e#UPq6qlxrk5?&!Sk+N1&;mry;2;6y1fTG%>-v60@1W5&z`sbDe_MlE*9WHfN zF!^!Z-?~a1ie#-xOqEvqMhmM|E5Ir@WV*={rO%xL7p~)7<|-z30?C-w2sN!V0Qm6% zHe;o?#DT-#ZII4`dH;v=$3KD|xpTE_!=u~y1%1gK)!oN_Zezyhm5OqZr&WbK_ypX^ zR6vN#{0jCGLhLjHE;CB&&#WY!;oLz9_Gd{lcmHboRn&_lM~)I;xQHE{w{&_Z^DHV2 z9vssyJXLPhFMT>T?d(3i<}cUG`DF2keP;9(#h{_-f79VeMaysy!pbK;5J0!S#mmRf zb#jN1D7Vgv=86*_4+XO2QMRuuX$qt-+nQCG-jT7fppWv)Y zlU}~eqpRTQb!~a8k!Cf{V5&;tYZlr_X%n1eqNB=63+c^74a{1)jB|!_f_slJZfR4s z0Z8EQ20G9k6!7gJ+LKL*J1fohef!~1l)1dFD%G_sF^@2u}bHp9HPb`_= z7J410`30pj{(Ft+G%bs+fQUk6L62bPMU=5_p-CCMI?3EQmR>Tdk#x#$nR@P1g6{() z=gIK&8ovtm(+*@B;YiFlg^~MaJ8cl|*`)BVp^ZpAfzlnY7K98$!ztBC1Ls(24X-)! zWN<2Y_3QI?i{C?3=3q?cTl$lwg_eD}!i5wiujiTJ8`{$cPXnc>RC@XSy)*xcvO3fo zU|v&nujp^Oml{0ikozQd?n%NhcGWElfd~yclbu6>(F==A<|Ock7ZvF(Xg|@kw`(gxtXP>^&ckAjZD$d&12*x>cfIuSBM}Gpa&g(IylF_x8T8 z7Nj1X?dg97r#%Av;VzRqZ)95|7sMtUjeAODbQtiE^tZs}qp`TvfjF8KbZ+X7be%@8n(lS#b(+%+{3J*lp5CA{IIDe` z4mbf#ogKVXExtKE?j{I+iOYKbt;C%>w{*Ct?=QXiptM>Kz8%EtDP%X)a@^VP2kZR? zJ(IaCnl-=-o)5Xr$^R#@18D~h)PgA03;YU#(7Ud2>d`HKbeL-+!xga}1b zm2_cSDMy>~SHtJ|k)=8lmHj?vSNEEsB*nc18%3_|rqj|Pg_5_c)(z=F&8939gJoE4 zbkI-?&3j+SE(nhN8?`WvgCKdJ>>)%rF3#!jaK1aI;Nd`R>d8p$Bu0W^r*fG8Ut9bULiPDva z!TIN5^h%oQMMquk>Tr2~u=V?cV_@&rLI)UKl}e3DzzBn9ooG#>$+~u`6-N-SIYtfo z2L!(bkMgmtPTVRU@~HSpLl|-9Mx8W0k&x{wg*3tR(PRtGtEbOMu}yky@4C7~8SKl0HNCGpAzLQt($6n; ziW&#D0_Z2%s3<^kx02cLf+LIFss4_d8=EL3ruO53(;4O!wCmg+`TfZKcq)H1_K=#1XBh3uDQHjA17)nWXrdY1scOP-T8DkoWdb#@UE%P&W-~JH;iVWnT zUZ=T_e6F+TU-pfa!zs2u3fG$aw22m5t6jqbYoiGimejr#vb`Vl&2q0-?H8Vxi}+5L zrHlKhriP}~(DIqH&jGRGZ-;jm-3(almMMr~p8?=$Gxq$XMYVb^L#%b0e-L4M;S0wj zG=?ybC^uDnh;xm;U?Adpk0@85OFr5^{`C?ymmo} zJnMBcuvTh~dg-nN>Q^`0?Z>?DMn_ShppFx*2GfXKf8K^)XUG15iP~d=>~^G~L!1ZY zYVZZwd)UVZFDrhxRzt&7RPT_4e_dqjMH9X7$vNADuU>xQf-CBDOV2p4PX1b7w*5h$?t=zP8v$$0 zUiWWXcZ<7jozh0n0T5R~lGakYh2|mn60;BkZ&9!GO-~@fp4jYkAYKz1eGn~PQT?uX z!Z)BKVzu<|-rFqj-#zSV#NX-}@r6QtOMXjM*v^)<-3^joUi-UJ+;S^ zYk}9RMTO971|ujxEo60M^w$>K0jJU~P#9SC1nT{4WTl~>Nzr2_++)vf?!uysnh{eC zerD?_-xy6`D-Z0bzZbglvPl^J%#SecGHivN2vrx1)Xz5JBITmD?ibtkrF{2^`)2S3 zw-`1Z+oDvX0ya?Gkx=yv1XAMKa1&aAm-Z_Ux|1dvmCDw^nT~Bty(Gib`T9%nO5ei) z$bJ&_y zuKv#3`sz1&M=#`{cs6uY*NuL|J@hp_Y652Djn58o@eb9gydOJ7KTehlaHvm4Pmq3F zUQM2L7I=@^!CadL|E)%8gI%c}Q=#$6{X;DOvDlrKRMh;^*1!3cjy%5P%y;*CPF>$_;d1cUY`=w(n+lJBS}F zjfl(^Kn~-KA@}E#W>Q5`uJr1R9oEk9H%TS$gHD;*Jvu9_ zjR39{f`-O(Cioi<+hpC?5$#oMbn!ltjH_1XjMaS!Z~4=YzE-l4bx`vMylGRIf}iU) zbLFJx^auyUqO;CxB?oL@6{dS#hu)k6NP?4{+udU4(pq(1!>i>Lr_n-hT1W(Wc~ci$ z^^RR{+`7v!SY1gpBXB2sK{!I4>N=I7H@gOzE~(V1(iJK!XZua_R3I)>H>j+PsA%yR zaNvK8=6%~*6>O{l)TW(Q6^^xPbmo|4ptY9qTSpPA<^%R_p|umB?Wlz|R>GM#^L>sD z^;WBhxia>t?r*LKd$gt!?+n-2*3F=rN zz@e)Wm@A<AN3TuLzO#txnHoQV4Ilu%xKpANJJf203+6thw|YPiAfIZP^iS^1jt zP`VS}R4X6)VLeIHmX*4z0P4@|XYEH2(m3((-)~ps%PiU7g}&s+GuxC!E})W-He_ec zIoaqb(C_)uSQXr#>?;NS_tz$$hgO{g%X`OfxKPH0!0zIq=#*m^>2gIw@OuDNZG%pc zW+;ZLz=70JjbZ#U*t!Xh7H*@a&0HUK<2wrL5>LlK$d6wo(-drvv8YiPm%bJ!4Q?Fh zZFP~s!66$FRyTU5EB|r%0nOgZD|$iU=SY3}_{nO3B(|wAzUn`m%rNXDc*uFU-}XR{ zB@gej5vLnkyq>FK`EKkFann@3cAsZ}$ZG6|raG2C)VD@0zNhp8vRHPU8o!6EES9%z z<--cen7xxraAO||v*S089DyFew31J>b--mp(c=Qx4SyQ1`YB9L!C&9g**RE|Q3l7j z6W*=7K@6*;P}^Uzk>P9Hm3f9PJ%W%dE1=U^G{oNtyE{K((5x@}9u52%5HH-BP-Ya6 zhE~tn@)?B+AR=N5*(>)B#uNV`6jEnLEEh^@m2-ieBpi;UYfC@CN~n+j+C2-dEkB6k zEZIC91a%3;)qY_eDx&WmCc-waG$mb@f*UuOWPgrYShQRED@Wkz|AO(LSFRII=eik_zWGY4ye!7TW0M)K^$eH6$0sJnAntmhrVv7Sz z@dI;*7ji0Pt$##)Gqjb&JTy6{J0!i7U&FK|7+qa@I7T&B`3hXUz&dB3$5s3k9dc<{ zb5orz%|hIQi(m$kcQ^0TqoezP0=Af81ejXp-rV!oQo1kAXZL2{w}n2o4Xwv%zD+yL z*V2s`sj$N4-Lqp@4ysg1l2zd;3P|xl!7Vb=YJRU#G*mHOfgBSjN|jwPIE|HJtppBh zTt}URzCD~{c+S2Mj)0?^@k?!bDlD5hQG)9svp7?=DK;l z-7cMxZAzFn+o>`B)6s*5-=sBEe!#mvoqrSh()-pLkCjY_OrYgB1E0oKQMu}xk9)B{%!XW`)e2}2EkS;S2SykEsTZo8 z_du@xx7>_hIU|_e47JanKc=f7`a)v4qW(#!!5hG~CYcvUX5G%t$b!+2$-}Z2N4Fiw z+BFjg5643p{&DnW1!P;_XZvv`vAhxm!#!2N>P$$-9| zrO!K=U+Hq+2Kq@KtmaNx^E{tP9PHSwDE0jmh zmresRP`{5NUgAV|GObkzp17^{QslY`H(+jX>B)cd0ia1z#58@icwmBQe!d&A=irFbtyP1X7PqPiy)K~4u^{4lR`wwv|fezj;1=ZbglpWUJ&mH?> z^1H)JV;`s_qN}&LAb0a0s8Z+Dobgot!~B=|t=+9Ccp;}`zfV`|*XG=^`1fn6nrVyP zeGm2Y1g<~35M_h7c0oMs+Kv0SOFzDQ_umJp+xm@D&p*d*6$Z62^bm`CPo_VH4cH~Q zK5?&Ts9YU07+3JfD=P9gxBXfDU^HI4lgiZfA3@b_eoH}u-J1H+(tP{oux!rGJjdfx z-4NIJ)M^{Gd-owTqJuzoya?M*(du}>izWQt1djVfvOIGne-jkk&CeG<^iMcxeC}ZDPqUr6g{Bq7$0*~S! zfTc8Fhko4goMM_55-H&+3G!y!4>IdY_ ziIk12?}Iv!PVLtKVUzzNCt@ooqt8n)?{+}_Mf_cZ{oPRWZEp3n&4zBUD`R>CrAanp zyxwS#Ru&~yJ#4U0`bYx3!D^>(EY=L&*%NrTEJF=X#o$s=UCu>?fEb3z)~rR{{<;=Wz%+LlfS*{+B-5*IO4GlkP@>c(ydzJFhSg0hV5j9 zTq64~1xZuLU^O+JpDS_OR1q#B`1$S>9G5_N0(#B{@nc5i$x6i4blqn%*j z*3VKL2c54`3Al3K5Z*2H;{9D|=so7RKP9r!ccf(&vFlK2twLihi&1~_Q{6?Zf5uR&fVG;wXA%D;{ zVFBsOGV{0%YVP?xh5F?EOo%D}Mg#>3hzbajcEKPh7*Lk1DhdNA5di_&WNA=Q zf~+EhD6}jA5?Lc_WC?*l2qYvS8+kZA^QPaN^Ul2U{;Bg--MaVw>fSovA60dJ_nmJD zGIYuFz{C+~JfnP(+OH;V8QuM?oRu(!%}v#)exXta+GDlqAINlj-53)3mIu|PxS#@R zLVhCB4gX6?^%;I7)5eGREbIdd^H@-jbFXy}O?f8k{#=oP-^9E9J_FMiyLe?`k53F~ z9`D`fnot3Daic~8ISfR%CSFJM)JLMBYF9uWOF^5*nf_b5hv_1v`hr}*ehE0ruLz5Y z@}2s~ukIvZdnnGJfzn*(Taovr1%cZ4lx-{5SO3kd1Q0G-qT2$32q( zj%JRAuNp{PJZ%y@t!}mK*?~@&1i(Mxr%^8fFW{9=Ln;u{r?_au71f<}a|nbjEIE0n z?@Glv;*ESG&h_Q`^~#$emMnNQRljYK--xCW@9Y@rkXM%?>qxR^qB=fj7R4-ubiuu4 zmdWE+gBQnJdlgDGN5tXd#Ef=x7-<(U3A~`VD)mt;gJxC1g>~Al$nw&XWAxUMNBqa_ zB(?#6g$AI*r!a89MzNfX@j*5&WX)a%B-Y2~&L$Rco~UZ3>ySbZ9&#dbmkkFNx=$vw zMK(q3xbuV9Zq4b+pPCCd(SMb>7n`tz^Y~eg-T2mNH}b@L)W)`paV#gZLUfs8wLdGD zE`K`W%AqqjlCJKP!F%y!`n^8uAG-!=2QSFc>jJV9aB*{Nxuto%UMdYXsY5$0Ztij~ z%hUpXUi!jvSWp$}Ao?tLM997I%l*JWWGWryD)VFRQZfP3dIxFd?gUk_iRy|@@O0{t z;2b-Ahn%52Zvtf=DKNI!pu8!&Gv|)k$XFjVs+cZ!^f1rhb!uDZz<}dXzfJo*5U`#{ zLC%m|M^Ghu+qHS{;JhKtLHg1mXp$#Fd_~6I<4n++i8ug#A;7O@TPCm&mzJH!B>7(O zb3ttFXacALVU9_bhU&LP&7NIhI>ZVLx{H*5d!1_I;Ud)g-ANwwd+_zUK3DJ=3WQcU z)KMs}zoOoie(-XAyPeJbZp(4u^-R_g3rZKio{?Q?)gd^5_dhh)xmBIDb@1Xz1R0|% zSH9$gE*WJJP36E2cjG?Q_Sy|O`FLUgpaAq(Y3EMAU}o(jZJO742Iwcdpsez1c4R5f zU-n7H8?bHeurynEU`OJ-`yYYd^k>(BUys=3@A{|8kN))`OxTI%eI>KxGVUQ*<`y8<2~B6bMoC+t6yWtq4!Ud*sqWTHKcbAEKGIWT)n~iZUgeOwc6>CnJ znPDYfHyFEUa+5+k*;Xl_2ZomRle!rZhF&pG3eT<(y?QSxF|?$x z3FY}OW`nL@!+-A9SI;5i!0FR{vimaqeyA@VFUUObcKEG70|sv<|$livYWCI-KUwWwlb+%9+S)kL7YT(?*qsg8V9RkY)IJO=!#)GP z9N$~p_)=5I9oz0qTC5mQf#P{J3Wq>AjCWpc)~Eng8TZM`==|P@@nbYMPC|=|#HSCC zlGNy_Swnpju}Ub!P3A9l3&LOEl8hqvb|G;#ZLzcPt0WxAPL$I{4H)^-w3OAR05VuB zWq4;U0dClvz=!obrXZ9#ZpKmuC0ZeTO-)>R7Du|hTuM)Mg_kTmp*y74KM)ie(8qC? zOJw1`fx~CT#-yNYHfcbMexvIK46*5eI_CaPjjz>^2($M5a`=P#LVgM*S*s>Nc^DW*)<{8^5NycOHlTP_z@@`Kd?0-kGu#)xz@sS$PkJkT+zv zsBWoKa~?-rvwQ(tIe%7EhZr1#-`~kZ=NB`-U06O*6rvIvn`o!+;>J9m2lxBg=bLhP z{+vb)#qu_;Hr1UW3Hr=Y`m@psvS-(AtnQw>4G~z|LbG1;gB7@Fw5*5M4uC%HlakvLgRMZJJ8oYoxDlR6@E1 zoeZb|xFrx^Og=?vs~zrL2; zAwes@kwx!e@$&Tt?eVW8FKKm2@BFb3tRdQw@sV#a*jbX&NB_)$@Xc$rq^Z*dBk3Yb z;gVY238fe0?cl1$M76b@4BJB-;Y{Do9zt_`Cw(n=lj@tvqrm&+ZbA2%J7T`+Pf6}O zbn+clTX5@@-nayD8;+WODHsC*h3U&?7yYR@Pdoa=Lmpww|>6X-Q zkB8&vIx?i)4wR#Sz{Ha?u zHd^gYdmy%)3fq?ifFmNOAbE+8SSB#y>VeJ|aSU+WLQmxIB1(VIyM;WL65Ftp`H`b( zUu$@LKT4ntN@8b)-T(dVlkir*9@O*@w7>FfuFoPrb|JDfZkkyWP|>Cvv0Em(H<(7Q zsMXkQ%!)E~=4^G^6qK7;Scc1{E8ZLOb?5gseM;Z+#ps&lP9#n53w;gM4zn(MBlW~* zLj$um&GQ&+2djY5CH+zc;(uPqon3P~AxohXko_h!kBvATmRJT%0Xp^TFLLB#c)5XD zpsHHo8BlLVdES)!Jf_VoOVLUroaR9M>-K}UPwy!pXZ*30aIF6G^6|p}t)>}IZej%h zfguclW3YBc(`IPJLHLcB!`biZsy#o3 z(NL-!NsiQQa>YYFzjbNjCD=*C0qQLQ^P}=fS${#9FFHxCrO#aDa0F-c|->JVW{fxd}yWJ{k~zu9N@!%J%HL4Ecvir#pt zfDuZ#1#L=XQx0izCA*stpI7ee!+UoY_!^7V58$&DB{W1dy(raJ;Mix@-(PixZtQ6^ zwXU{oU3SvIXXO@9#Wq-Vwxrc8mR70I48WuJ3sW%nCdglw&mNq4%wbG?n0h$NOmKj7 z7kd&o#^+ZSM)|0`;yhqF|3r&BDeHJO%Iu7VOexRvDj|; z!Yh!=&3pqh6sF`4xqEQ=NGn0U=^6N~q?P!tkDPFYq7%buk~#CjpBPF4qAw6Vuw>=x zuK2#PI&Pf?FBp&#RHfgwb>yz3ASci00mn6Z<`Dd}U*ArAYDisG()d`E^<2RC`}pzE zr}a<5WsK4oQy3|vo3Q4s1^x7nt!}DJb8@N9N&<9!!G!WEC~s$?O?)M3w4zXJLyVIQcQP|>zqLScco63kfusf_;v?XzXuMc>pD7c z5$$BJEOAX+_-kvu5snp;@Q?Y@rGKb<>#1IPn8KpKq`fqrEk%hojS zFpI^D>46LQs%Xr|;zO$aIWg$tcm5Wd8BpRCKcl`dlB@q4-~($OIF8ZeqD7JOQEmi) zpyoa%+E%p4kgpZBH|G+flLpcOWOM2(zCoP4p;ECNIe}WT;sKEjR@N&7y$5zC`PXDvc*udN{9CaWgggbGvk-M|O?qo<`PV*=G6H21fz;-3tQK3M1= zS`OJ5@O<8D@bE1mh8p=JvgRA`DU|h4WjaeJEqX_>*{VFXxOyP=T9 z8~)M%7OyN6s`f7vxXhoo#?qc6z+3(@(kidejP=I>;DSw|DgDv zrr>n!p<7}pU?H(Upu+5q+kzKdB8v;3MNdlWxarif9DIiUpg!O^tMBXc#<%#|pwp8o z(Nv3y*)MG{TllxU^tLFFwL;J$zrI-hsy_j7W?NGlHG=}<{q$!Hgoj4omHZu1zx#sc zpJAPS74hcJT_ZjV>H8m%RS`X_{~@{x8TnJR!Xm-f`yPWdXnM&)3FF>>THyB_3QJkr z{`a`Syl|TT-@N?8yTWdp$nj_KT)QffrkY7NIkngtLm9}pp!b|3e2rR;BZ_YZ-3W&G z6TGhkYF3MRAC9K0nEA#kB#HyH`S;!Z_b9T$!_V+L@aU7?LDO9izF$WyFJBKbGLu(KUeMR`zMwS|<*PnP;mk1h2ehcNwe92ew5H=Z z-Z^*fW@o$GXrd5h2X@ar=braDcjn9tgb_kMN}PZqSr;nwHYZ=K)a)%%=qpk^wj7gn z=?%!dgf+5=fB+?;60BfOh`d(G9FAi-k>;?KQJJrzpy?H&O-ZaJR3W1aid@^8?VhjI z-ixjEJ~BRuP}Ep;c4x_xhGKQ&x*%bP(jXfWR)s`WW!criyB4nufwJhy_n$88Zyk?e zWAnLo?=8$oPwMJMTXpP*0|?bN(nO8Kb2>?TZ7Yrn6pM^aw*MNwNZZQk5rnqhz{eJq zAy3U7IWoQYkXauW+&J{N&r#-Q?ZJzplK86#4ZzRR)${zm{Q#fbcL)L+zsw?P0~^%V z9aYYf({d9$Ardl458NEg*Uuh-L*n%^4b2xil{)MXa*AHQ77c z1x<*HOnIA4dYA+#$b*~R+(9bsU?Gxn!o#IxhtOi%GI$+x2_jzG*G9(2)Cw|}6xh*g zCYT^+484pNz{HMPDmcmgE^=BiD@WM2#{roILGCpPtZCe!su-Eh@~sxv*1|zIGyaqy z-lPC7QoYdiLe~pjFLb@o|Gh%nLq?Dd89r8*Y?^1K4wMf*0bS)2xMETasYZ4cfFD8jZCFN#frWyF1Bw=!!~VEXQE%qn^1pr&j&|;Ba7(J`H3%WXgwz6(fpfH z)LQ8u1vrN-8=7-}4A{_!`o01Dbsp%}w*CyrJ@Lynk+=Gvh$da%U01fPK^Nh4_p$A40sA?_2O=X!0Dy z>%2Zkb05V(zj<%pdfkbyc9RA9ANl-8 z+wKxyS4($%`y6@@y=tsohS*6D>T!`vrX0*iuxf|&X2<=8n@3Q@CKlJbuzOtC2IPKR z*;@P2^1D0>vn;Etn!n36xBrK$p4)%z`loMJ$Ci4ta!I!^yY|OmGI818dL5_8pvlA~ zoD_J5H3+)8PAd(9AuXJ&VyJT$~Ku@>VCEHuG1KI$W>u_kIFMXf2Z{n7fUHEklPNp0E^ zOQe-(Wxe;@z01zJ6w4!#WG5NUJ@=mbo#)&=Gi|gF+$BTf@6vO8yjO$JcBN)%t?F*4GI8+Ofm_YBJ2^lP^z%Kk(WJw zmX8D#YQHFi)Re6bFCX$KLQoX~^32+>dFFh)=ISl|{yZAE)bXE!2}^Qf>6NR3#MAi7 zn#3!D#{ky%T=XRjrg!^`<_^XHnET;K@yW8WayNhciw{e1qKJ}e-{g7>?fzvC!_2J2 zL6kH`RTTCcXmKCj{w4qJh?`k|m+h#vlT;&=mIK{e5_0ztU9Kx}rPSqZ|7AGA;ipBM*;-ISyu_<-v(!!1G@j;(&#QtGc0kH_*qs`yh<_6CM?U4x+0#%_A7E zI$r0*G~*mRW&<*H(D6XE9FU_@Knrb{W$SX-8WvPPtA%)l^>eaU3iQ#-L!2N7 zH8p9@$|F5WBH<|Z&FE?6X*%p!9}Cme33UE=_)v&#QUY4AB6-PaSeo7GJSy)K#2X~Q zFqKJkCefKhXA+%B^wLW-ZZfiIlVPTL3Hv#kYHM=iV^tOCgbkfyt`Z1W(5@7Eo-Xt! z7K>e~zr@ zJMl~*X9}6@vd2>DHa6F~O*GrMM2lPl^>-XZ16Tj$s<$wG{d7SCrh7eQ6`0aDrvC8q zN}!h<*Fo;wks3?~+V8E!w6Ec*2~78GA2|zr{N-psa*Tp}seKamAASMkdM^&10G{pL z4Se`G;OyOeG!OW8`!#rS=KhAZ)uo*ZUMe{B@_XVzL@f%#=uiN8-5L6Tb!4d-Cm`P+k#)Sb6G!N1n~zlQnnvI=7V z=YQS}`&RGi13U6Mh`uu%_^CTq5&ykJuI-j1Bf$5ph(O$aeB(6WjSquek*~5yo?~Ss zkGE|GJ0m4N62Bi#fF0WJQxJ!?x=k;_{{7*1VBXmRc-qHxkf*S-o7h|W7>OG*Na9#q z19JL>kDwm(x=&$Uf9Mg2dt}$E;E%pB7wnEa`YYr!T-ZtC`22ZN2g>^(AO9SIaPlLN z*?GNICw`gmd4a!7n3(A+-S}oH#a-xYk#G&cq^GV;Z4_CrFV2|}m+rt!d-PtO;UKq( zyv~c22CmA$tznF<14iAt@D4BfWtv^&e{(I>7%!zO6XQj{7Wxo7FyBMWu-i%X;t%$y zE5_gB<3^#E0lHn{y#hzMY(Z64hZ4 // [[Rcpp::depends(dqrng, BH, sitmo)]] #include -#include +#include // [[Rcpp::plugins(cpp11)]] // [[Rcpp::depends(RcppParallel)]] #include struct RandomFill : public RcppParallel::Worker { - RcppParallel::RMatrix output; + RcppParallel::RMatrix output; uint64_t seed; - dqrng::normal_distribution dist{0.0, 1.0}; - RandomFill(Rcpp::NumericMatrix output, const uint64_t seed) : output(output), seed(seed) {}; + RandomFill(Rcpp::IntegerMatrix output, const uint64_t seed) : output(output), seed(seed) {}; void operator()(std::size_t begin, std::size_t end) { - pcg64 rng(seed, end); - auto gen = std::bind(dist, std::ref(rng)); + auto rng = dqrng::generator(seed, end); for (std::size_t col = begin; col < end; ++col) { - RcppParallel::RMatrix::Column column = output.column(col); - std::generate(column.begin(), column.end(), std::ref(gen)); + auto sampled = dqrng::sample::sample(rng, 100000, output.nrow(), true); + RcppParallel::RMatrix::Column column = output.column(col); + std::copy(sampled.begin(), sampled.end(), column.begin()); } } }; // [[Rcpp::export]] -Rcpp::NumericMatrix parallel_random_matrix(const int n, const int m, const int ncores) { - Rcpp::NumericMatrix res(n, m); +Rcpp::IntegerMatrix parallel_random_matrix(const int n, const int m, const int ncores) { + Rcpp::IntegerMatrix res(n, m); RandomFill randomFill(res, 42); RcppParallel::parallelFor(0, m, randomFill, m/ncores + 1); return res; @@ -179,24 +180,24 @@ symnum(x = cor(res), cutpoints = c(0.001, 0.003, 0.999), Head of the random matrix: - [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] - [1,] 0.7114429 1.2642926 -0.47149983 0.4277034 -0.3709571 0.4336255 0.8185977 0.3505209 - [2,] 0.8721661 -1.1908067 1.10411136 0.4160170 -1.3276661 -0.4182534 -1.2437521 1.0084814 - [3,] -1.4959624 -0.1726986 -0.54343828 -0.5635330 -1.1779352 0.7539401 -0.4341252 -1.2256560 - [4,] 0.5087201 0.1116120 0.19007581 -0.8220532 0.9672267 -1.1246750 -0.5283977 -1.3198088 - [5,] -0.8191448 -1.1856318 -0.03458304 0.8027613 1.0594094 -0.4456480 -0.5456669 0.2593546 - [6,] 1.2289518 -0.2576456 0.40222707 0.9757078 -0.5796549 -1.0148114 2.8961294 0.6391352 + [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] + [1,] 67984 16279 69262 7126 21441 37720 51107 51045 + [2,] 69310 21713 82885 81157 54051 5261 91165 17833 + [3,] 76742 31232 78953 4626 94939 29416 85652 78296 + [4,] 76349 47427 1770 37957 33888 59134 94591 65793 + [5,] 85008 89224 43493 7925 60866 2464 14080 10763 + [6,] 38017 88509 51195 73086 1883 68193 75259 62216 Correlation matrix: [1,] 1 [2,] 1 - [3,] ? 1 - [4,] ? ? ? 1 + [3,] ? 1 + [4,] ? 1 [5,] 1 - [6,] ? 1 - [7,] ? ? 1 - [8,] ? ? 1 + [6,] ? ? ? 1 + [7,] ? 1 + [8,] ? 1 attr(,"legend") [1] 0 ‘ ’ 0.001 ‘?’ 0.003 ‘!’ 0.999 ‘1’ 1 diff --git a/vignettes/sample.Rmd b/vignettes/sample.Rmd new file mode 100644 index 0000000..d267257 --- /dev/null +++ b/vignettes/sample.Rmd @@ -0,0 +1,211 @@ +--- +title: "Fast sampling methods" +author: "Ralf Stubner" +date: "`r Sys.Date()`" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{Fast sampling methods} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +evaluate <- FALSE +require(bench) +``` + +Random sampling from a fixed set is used in many areas of statistical computing. +The performance of this operation can be critical, especially when the sampled set is large. +The fast RNGs provided in this package make very fast sampling possible when combined with suitably fast algorithms. + +## Benchmarks + +By combining fast RNGs with a fast methods for creating [integers in a range](http://www.pcg-random.org/posts/bounded-rands.html) one gets good performance for sampling with replacement: + +```{r replacement, eval=evaluate} +library(dqrng) +m <- 1e6 +n <- 1e4 +bm <- bench::mark(sample.int(m, n, replace = TRUE), + sample.int(1e4*m, n, replace = TRUE), + dqsample.int(m, n, replace = TRUE), + dqsample.int(1e4*m, n, replace = TRUE), + check = FALSE) +``` +```{r, echo=FALSE} +if (evaluate) { + saveRDS(bm, "data/replacement.RDS") +} else { + bm <- readRDS("data/replacement.RDS") +} +knitr::kable(bm[, 1:5]) +``` + + + + +Note that sampling from `10^10` integers triggers "[long-vector support](https://stat.ethz.ch/R-manual/R-devel/library/base/html/LongVectors.html)" in R. + +When sampling _without_ replacement one has to consider an appropriate algorithm for making sure that no entry is repeated. When more than 50% of the population are sampled, dqrng shuffles an appropriate part of the full list and returns that. The algorithm used in R is similar but dqrng has the edge with respect to performance: + +```{r no-replacement-high, eval=evaluate} +library(dqrng) +m <- 1e6 +n <- 6e5 +bm <- bench::mark(sample.int(m, n), + dqsample.int(m, n), + check = FALSE, min_iterations = 50) +``` +```{r, echo=FALSE} +if (evaluate) { + saveRDS(bm, "data/no-replacement-high.RDS") +} else { + bm <- readRDS("data/no-replacement-high.RDS") +} +knitr::kable(bm[, 1:5]) +``` + +For lower sampling ratios a set based rejection sampling algorithm is used by dqrng. In principle, R can make use of a similar algorithm based on a hashset. However, it is only used for larger input vectors even though it is faster than the default method. The algorithm in dqrng, which is based on a [bitset](https://lemire.me/blog/2012/11/13/fast-sets-of-integers/), is even faster, though: + +```{r no-replacement-medium, eval=evaluate} +library(dqrng) +m <- 1e6 +n <- 1e4 +bm <- bench::mark(sample.int(m, n), + sample.int(m, n, useHash = TRUE), + dqsample.int(m, n), + check = FALSE) +``` +```{r, echo=FALSE} +if (evaluate) { + saveRDS(bm, "data/no-replacement-medium.RDS") +} else { + bm <- readRDS("data/no-replacement-medium.RDS") +} +knitr::kable(bm[, 1:5]) +``` + +As one decreases the sampling rate even more, dqrng switches to a hashset based rejection sampling. Both hashset based methods have similar performance and are much faster than R's default method. + +```{r no-replacement-low, eval=evaluate} +library(dqrng) +m <- 1e6 +n <- 1e2 +bm <- bench::mark(sample.int(m, n), + sample.int(m, n, useHash = TRUE), + dqsample.int(m, n), + check = FALSE) +``` +```{r, echo=FALSE} +if (evaluate) { + saveRDS(bm, "data/no-replacement-low.RDS") +} else { + bm <- readRDS("data/no-replacement-low.RDS") +} +knitr::kable(bm[, 1:5]) +``` + +For larger sampling ranges R uses the hashset by default, though `dqsample.int` is still faster: + +```{r no-replacement-long, eval=evaluate} +library(dqrng) +m <- 1e10 +n <- 1e5 +bm <- bench::mark(sample.int(m, n), + dqsample.int(m, n), + check = FALSE) +``` +```{r, echo=FALSE} +if (evaluate) { + saveRDS(bm, "data/no-replacement-long.RDS") +} else { + bm <- readRDS("data/no-replacement-long.RDS") +} +knitr::kable(bm[, 1:5]) +``` + +The same algorithms but combined with a different selection method are used to obtain weighted sampling, both with replacement: + +```{r weighted-replacement, eval=evaluate} +m <- 1e6 +n <- 1e4 +prob <- dqrunif(m) +bm <- bench::mark(sample.int(m, n, replace = TRUE, prob = prob), + dqsample.int(m, n, replace = TRUE, prob = prob), + check = FALSE) +``` +```{r, echo=FALSE} +if (evaluate) { + saveRDS(bm, "data/weighted-replacement.RDS") +} else { + bm <- readRDS("data/weighted-replacement.RDS") +} +knitr::kable(bm[, 1:5]) +``` + +And without replacement: + +```{r weighted-no-replacement, eval=evaluate} +bm <- bench::mark(sample.int(m, n, prob = prob), + dqsample.int(m, n, prob = prob), + check = FALSE) +``` +```{r, echo=FALSE} +if (evaluate) { + saveRDS(bm, "data/weighted-no-replacement.RDS") +} else { + bm <- readRDS("data/weighted-no-replacement.RDS") +} +knitr::kable(bm[, 1:5]) +``` + +Especially for weighted sampling without replacement the performance advantage compared with R's default methods is particularly large. + + +## Technicalities + +The following methods are used for sampling without replacement. The algorithms are presented in R-like pseudo code, even though the real implementation is in C++. For sampling rates above 50%, a partial [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle) is used: + +```{r, eval=FALSE} +no_replace_shuffle <- function(m, n) { + tmp <- seq_len(m) + for (i in seq_len(n)) + swap(tmp[i], tmp[i + random_int(m-i)]) + tmp[1:n] +} +``` + +where `random_int(m-i)` returns a random integer in `[0, m-i]`. Since the full population is kept in memory, this method is only suitable for high selection rates. One could expect that [reservoir sampling](https://en.wikipedia.org/wiki/Reservoir_sampling) should work well for lower selection rates. However, in my tests set based algorithms were faster: + +```{r, eval=FALSE} +no_replace_set <- function(m, n) { + result <- vector(mode = "...", length = n) # integer or numeric + elems <- new(set, m, n) # set object for storing n objects out of m possible values + for (i in seq_len(n)) + while (TRUE) { + v = random_int(m) + if (elems.insert(v)) { + result[i] = v + break + } + } + result +} +``` + +Here `elems.insert(v)` returns `TRUE` if the insert was successful, i.e. `v` was not in `elems` before, and `FALSE` otherwise. There are different strategies for implementing such a set. For intermediate sampling rates (currently between 0.1% and 50%) dqrng uses a bitset, i.e. a vector of `m` bits each representing one of the possible values. For lower sampling rates the memory usage of this algorithm is to expensive, which is why a hashset^[For the specialists: Open addressing with a power-of-two size between 1.5 and 3 times `n`, identity hash function for the stored integers and quadratic probing.] is used, since there the used memory scales with `n` and not with `m`. One could expect that [Robert Floyd's sampling algorithm](https://stackoverflow.com/a/2394292/8416610) would be superior, but this was not the case in my tests, probably because it requires a final shuffling of the result to get a random _permutation_ instead of a random _combination_. + +So far only un-weighted sampling was considered. +However, the same algorithms can be used for weighted sampling, when `random_int(m)`, which uniformly selects one of `m` elements, is replaced with a function that selects one of `m` elements based on their weights. +One such algorithm is [stochastic acceptance](https://doi.org/10.1016/j.physa.2011.12.004), which is particularly well suited in combination with fast RNGs: + +> 1. Select randomly one of the individuals (say, $i$). The selection is done with uniform probability $1/N$, which does not depend on the individual’s fitness $w_i$. +> 2. With probability $w_i/w_\max$, where $w_\max = \max\{w_i\}_{i=1}^N$ is the maximal fitness in the population, the selection is accepted. Otherwise, the procedure is repeated from step 1 (i.e., in the case of rejection, another selection attempt is made). + +For sampling with replacement the above algorithm can be directly applied. +For sampling without replacement, one might consider updating $w_\max$ whenever the element with the maximum weight has been selected. +However, this is not necessary since one can stick to the original $w_\max$ at the cost of a slightly reduced acceptance rate.