diff --git a/R/pmt.R b/R/pmt.R index 845abe3..7e18e0c 100644 --- a/R/pmt.R +++ b/R/pmt.R @@ -96,7 +96,7 @@ pmts <- function( #' @rdname pmt #' #' @param inherit a character string specifying the type of permutation test. -#' @param statistic definition of the test statistic. See Details. +#' @param statistic definition of the test statistic. See details. #' @param rejection a character string specifying where the rejection region is. #' @param scoring one of: #' - a character string in `c("none", "rank", "vw", "expon")` specifying the scoring system @@ -114,19 +114,25 @@ pmts <- function( #' - R: a function returning a closure that returns a double. #' - Rcpp: a character string defining a captureless lambda (since C++11) returning another lambda that captures by value, accepts parameters of the same type, and returns a double. #' -#' When using `Rcpp`, the parameters for different `inherit` are listed as follows. Note that the parameter names are for illustration only. +#' The purpose of this design is to pre-calculate certain constants that remain invariant during permutation. #' -#' - `"twosample"`: `(const NumericVector& sample_1, const NumericVector& sample_2)` -#' - `"ksample"`: `(const NumericVector& combined_sample, const IntegerVector& one_based_group_index)` -#' - `"paired"`: `(const NumericVector& sample_1, const NumericVector& sample_2)` -#' - `"rcbd"`: `(const NumericMatrix& block_as_column_data)` -#' - `"association"`: `(const NumericVector& sample_1, const NumericVector& sample_2)` -#' - `"table"`: `(const IntegerMatrix& contingency_table)` +#' When using Rcpp, the parameters for different `inherit` are listed as follows. Note that the names can be customized, and the types can be replaced with `auto` (thanks to the support for generic lambdas in C++14). See examples. #' -#' Defining the test statistic using R follows a similar approach. The purpose of this design is to pre-calculate certain constants that remain invariant during permutation. +#' | `inherit` | Parameter 1 | Parameter 2 | +#' |:---------------:|:-------------------------------------------:|:--------------------------------------------:| +#' | `"twosample"` | `const NumericVector& sample_1` | `const NumericVector& sample_2` | +#' | `"ksample"` | `const NumericVector& combined_sample` | `const IntegerVector& one_based_group_index` | +#' | `"paired"` | `const NumericVector& sample_1` | `const NumericVector& sample_2` | +#' | `"rcbd"` | `const NumericMatrix& block_as_column_data` | | +#' | `"association"` | `const NumericVector& sample_1` | `const NumericVector& sample_2` | +#' | `"table"` | `const IntegerMatrix& contingency_table` | | + +#' +#' When using R, the parameters should be the R equivalents of these. #' #' @note -#' The data is permuted in-place. Therefore, modifications to the data within `statistic` may lead to incorrect results. Since R has copy-on-modify semantics but C++ does not, it is recommended to pass const references when using Rcpp in `define_pmt`. +#' - `statistic` should not cause errors or return missing values. +#' - The data is permuted in-place. Therefore, modifications to the data within `statistic` may lead to incorrect results. Since R has copy-on-modify semantics but C++ does not, it is recommended to pass const references when using Rcpp in `define_pmt`, as shown in the table above. #' #' @examples #' x <- rnorm(5) @@ -146,8 +152,7 @@ pmts <- function( #' #' \donttest{ #' r <- define_pmt( -#' inherit = "twosample", -#' n_permu = 1e5, +#' inherit = "twosample", n_permu = 1e5, #' statistic = function(x, y) { #' m <- length(x) #' n <- length(y) @@ -155,18 +160,30 @@ pmts <- function( #' } #' ) #' +#' #' rcpp <- define_pmt( -#' inherit = "twosample", -#' n_permu = 1e5, -#' statistic = "[](const NumericVector& x, const NumericVector& y) { -#' R_xlen_t m = x.size(); -#' R_xlen_t n = y.size(); -#' return [=](const NumericVector& x, const NumericVector& y) -> double { +#' inherit = "twosample", n_permu = 1e5, +#' statistic = "[](const auto& x, const auto& y) { +#' auto m = x.size(); +#' auto n = y.size(); +#' return [=](const auto& x, const auto& y) { #' return sum(x) / m - sum(y) / n; #' }; #' }" #' ) #' +#' # equivalent +#' # rcpp <- define_pmt( +#' # inherit = "twosample", n_permu = 1e5, +#' # statistic = "[](const NumericVector& x, const NumericVector& y) { +#' # R_xlen_t m = x.size(); +#' # R_xlen_t n = y.size(); +#' # return [=](const NumericVector& x, const NumericVector& y) -> double { +#' # return sum(x) / m - sum(y) / n; +#' # }; +#' # }" +#' # ) +#' #' options(LearnNonparam.pmt_progress = FALSE) #' system.time(r$test(x, y)) #' system.time(rcpp$test(x, y)) diff --git a/man/pmt.Rd b/man/pmt.Rd index ef20cb9..6da93ce 100644 --- a/man/pmt.Rd +++ b/man/pmt.Rd @@ -35,7 +35,7 @@ define_pmt( \item{inherit}{a character string specifying the type of permutation test.} -\item{statistic}{definition of the test statistic. See Details.} +\item{statistic}{definition of the test statistic. See details.} \item{rejection}{a character string specifying where the rejection region is.} @@ -68,20 +68,26 @@ The test statistic can be defined using either R or Rcpp, with the \code{statist \item Rcpp: a character string defining a captureless lambda (since C++11) returning another lambda that captures by value, accepts parameters of the same type, and returns a double. } -When using \code{Rcpp}, the parameters for different \code{inherit} are listed as follows. Note that the parameter names are for illustration only. -\itemize{ -\item \code{"twosample"}: \verb{(const NumericVector& sample_1, const NumericVector& sample_2)} -\item \code{"ksample"}: \verb{(const NumericVector& combined_sample, const IntegerVector& one_based_group_index)} -\item \code{"paired"}: \verb{(const NumericVector& sample_1, const NumericVector& sample_2)} -\item \code{"rcbd"}: \verb{(const NumericMatrix& block_as_column_data)} -\item \code{"association"}: \verb{(const NumericVector& sample_1, const NumericVector& sample_2)} -\item \code{"table"}: \verb{(const IntegerMatrix& contingency_table)} +The purpose of this design is to pre-calculate certain constants that remain invariant during permutation. + +When using Rcpp, the parameters for different \code{inherit} are listed as follows. Note that the names can be customized, and the types can be replaced with \code{auto} (thanks to the support for generic lambdas in C++14). See examples.\tabular{ccc}{ + \code{inherit} \tab Parameter 1 \tab Parameter 2 \cr + \code{"twosample"} \tab \verb{const NumericVector& sample_1} \tab \verb{const NumericVector& sample_2} \cr + \code{"ksample"} \tab \verb{const NumericVector& combined_sample} \tab \verb{const IntegerVector& one_based_group_index} \cr + \code{"paired"} \tab \verb{const NumericVector& sample_1} \tab \verb{const NumericVector& sample_2} \cr + \code{"rcbd"} \tab \verb{const NumericMatrix& block_as_column_data} \tab \cr + \code{"association"} \tab \verb{const NumericVector& sample_1} \tab \verb{const NumericVector& sample_2} \cr + \code{"table"} \tab \verb{const IntegerMatrix& contingency_table} \tab \cr } -Defining the test statistic using R follows a similar approach. The purpose of this design is to pre-calculate certain constants that remain invariant during permutation. + +When using R, the parameters should be the R equivalents of these. } \note{ -The data is permuted in-place. Therefore, modifications to the data within \code{statistic} may lead to incorrect results. Since R has copy-on-modify semantics but C++ does not, it is recommended to pass const references when using Rcpp in \code{define_pmt}. +\itemize{ +\item \code{statistic} should not cause errors or return missing values. +\item The data is permuted in-place. Therefore, modifications to the data within \code{statistic} may lead to incorrect results. Since R has copy-on-modify semantics but C++ does not, it is recommended to pass const references when using Rcpp in \code{define_pmt}, as shown in the table above. +} } \examples{ pmt("twosample.wilcoxon") @@ -105,8 +111,7 @@ t$print() \donttest{ r <- define_pmt( - inherit = "twosample", - n_permu = 1e5, + inherit = "twosample", n_permu = 1e5, statistic = function(x, y) { m <- length(x) n <- length(y) @@ -114,18 +119,30 @@ r <- define_pmt( } ) + rcpp <- define_pmt( - inherit = "twosample", - n_permu = 1e5, - statistic = "[](const NumericVector& x, const NumericVector& y) { - R_xlen_t m = x.size(); - R_xlen_t n = y.size(); - return [=](const NumericVector& x, const NumericVector& y) -> double { + inherit = "twosample", n_permu = 1e5, + statistic = "[](const auto& x, const auto& y) { + auto m = x.size(); + auto n = y.size(); + return [=](const auto& x, const auto& y) { return sum(x) / m - sum(y) / n; }; }" ) +# equivalent +# rcpp <- define_pmt( +# inherit = "twosample", n_permu = 1e5, +# statistic = "[](const NumericVector& x, const NumericVector& y) { +# R_xlen_t m = x.size(); +# R_xlen_t n = y.size(); +# return [=](const NumericVector& x, const NumericVector& y) -> double { +# return sum(x) / m - sum(y) / n; +# }; +# }" +# ) + options(LearnNonparam.pmt_progress = FALSE) system.time(r$test(x, y)) system.time(rcpp$test(x, y))