From 71ebf7348ca3a2b0681441326187e437bf4a1e18 Mon Sep 17 00:00:00 2001 From: Nicholas Tierney Date: Fri, 18 Mar 2022 13:22:25 +0800 Subject: [PATCH 01/19] implement first pass at using sd.greta_array method tests currently fail --- NAMESPACE | 3 +++ R/functions.R | 34 +++++++++++++++++++++++++++++---- R/tf_functions.R | 6 ++++++ man/functions.Rd | 5 +++-- man/overloaded.Rd | 3 +++ tests/testthat/test_functions.R | 3 +++ 6 files changed, 48 insertions(+), 6 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index 2a366cdf2..df8b1cfe3 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -116,6 +116,8 @@ S3method(rowMeans,default) S3method(rowMeans,greta_array) S3method(rowSums,default) S3method(rowSums,greta_array) +S3method(sd,default) +S3method(sd,greta_array) S3method(sign,greta_array) S3method(simulate,greta_model) S3method(sin,greta_array) @@ -232,6 +234,7 @@ export(rms_prop) export(rowMeans) export(rowSums) export(rwmh) +export(sd) export(simplex_variable) export(slice) export(slsqp) diff --git a/R/functions.R b/R/functions.R index 6e75dcf61..2a9bdfbfb 100644 --- a/R/functions.R +++ b/R/functions.R @@ -62,6 +62,7 @@ #' prod(..., na.rm = TRUE) #' min(..., na.rm = TRUE) #' max(..., na.rm = TRUE) +#' sd(..., na.rm = TRUE) #' #' # cumulative operations #' cumsum(x) @@ -77,10 +78,10 @@ #' #' # miscellaneous operations #' aperm(x, perm) -#' apply(x, MARGIN, FUN = c("sum", "max", "mean", "min", +#' apply(x, MARGIN, FUN = c("sum", "max", "mean", "min", "sd, #' "prod", "cumsum", "cumprod")) #' sweep(x, MARGIN, STATS, FUN = c('-', '+', '/', '*')) -#' tapply(X, INDEX, FUN = c("sum", "max", "mean", "min", "prod"), ...) +#' tapply(X, INDEX, FUN = c("sum", "max", "mean", "min", "sd, "prod"), ...) #' #' } #' @@ -590,6 +591,31 @@ mean.greta_array <- function(x, trim = 0, na.rm = TRUE, ...) { # nolint ) } +# need to define sd as a generic since it isn't actually a generic +#' @rdname overloaded +#' @export +sd <- function(x, ...) UseMethod("sd", x) + +# setting default and setting arguments for it so it passes package check +#' @export +sd.default <- function(x, na.rm = FALSE, ...) { + sd_result <- stats::sd(x = x, + na.rm = na.rm) + formals(sd.default) <- c(formals(sd.default), alist(... =)) + + sd_result +} + +#' @export +sd.greta_array <- function(x, na.rm = TRUE, ...) { # nolint + + # calculate SD on greta array + op("sd", x, + dim = c(1, 1), + tf_operation = "tf_sd" + ) +} + #' @export max.greta_array <- function(..., na.rm = TRUE) { # nolint @@ -1073,7 +1099,7 @@ apply.default <- function(X, MARGIN, FUN, ...) { # nolint #' @export apply.greta_array <- function(X, MARGIN, FUN = c( - "sum", "max", "mean", "min", "prod", + "sum", "max", "mean", "min", "sd", "prod", "cumsum", "cumprod" ), ...) { @@ -1169,7 +1195,7 @@ tapply.default <- function(X, INDEX, FUN = NULL, ..., # nolint start #' @export tapply.greta_array <- function(X, INDEX, - FUN = c("sum", "max", "mean", "min", "prod"), + FUN = c("sum", "max", "mean", "min", "prod", "sd"), ...) { # nolint end diff --git a/R/tf_functions.R b/R/tf_functions.R index d58b48e5f..c97ab1cc1 100644 --- a/R/tf_functions.R +++ b/R/tf_functions.R @@ -80,6 +80,12 @@ tf_mean <- function(x, drop = FALSE) { skip_dim("reduce_mean", x, drop) } +tf_sd <- function(x, drop = FALSE) { + n_dim <- length(dim(x)) + reduction_dims <- seq_len(n_dim - 1) + tf$math$reduce_std(x, axis = reduction_dims, keepdims = !drop) +} + tf_max <- function(x, drop = FALSE) { skip_dim("reduce_max", x, drop) } diff --git a/man/functions.Rd b/man/functions.Rd index aa97c9494..b3d7c9500 100644 --- a/man/functions.Rd +++ b/man/functions.Rd @@ -87,6 +87,7 @@ precision than R's equivalent. prod(..., na.rm = TRUE) min(..., na.rm = TRUE) max(..., na.rm = TRUE) + sd(..., na.rm = TRUE) # cumulative operations cumsum(x) @@ -102,10 +103,10 @@ precision than R's equivalent. # miscellaneous operations aperm(x, perm) - apply(x, MARGIN, FUN = c("sum", "max", "mean", "min", + apply(x, MARGIN, FUN = c("sum", "max", "mean", "min", "sd, "prod", "cumsum", "cumprod")) sweep(x, MARGIN, STATS, FUN = c('-', '+', '/', '*')) - tapply(X, INDEX, FUN = c("sum", "max", "mean", "min", "prod"), ...) + tapply(X, INDEX, FUN = c("sum", "max", "mean", "min", "sd, "prod"), ...) } } diff --git a/man/overloaded.Rd b/man/overloaded.Rd index 41f92950c..4062a0ecc 100644 --- a/man/overloaded.Rd +++ b/man/overloaded.Rd @@ -6,6 +6,7 @@ \alias{\%*\%} \alias{chol2inv} \alias{cov2cor} +\alias{sd} \alias{identity} \alias{colMeans} \alias{rowMeans} @@ -28,6 +29,8 @@ chol2inv(x, size = NCOL(x), LINPACK = FALSE) cov2cor(V) +sd(x, ...) + identity(x) colMeans(x, na.rm = FALSE, dims = 1L) diff --git a/tests/testthat/test_functions.R b/tests/testthat/test_functions.R index a08df9c46..9eff87dfb 100644 --- a/tests/testthat/test_functions.R +++ b/tests/testthat/test_functions.R @@ -22,6 +22,7 @@ test_that("simple functions work as expected", { check_op(mean, x) check_op(sqrt, exp(x)) check_op(sign, x) + check_op(sd, x) # rounding of numbers check_op(ceiling, x) @@ -230,6 +231,7 @@ test_that("apply works as expected", { check_apply(a, margin, "prod") check_apply(a, margin, "cumsum") check_apply(a, margin, "cumprod") + check_apply(a, margin, "sd") } }) @@ -243,6 +245,7 @@ test_that("tapply works as expected", { check_expr(tapply(x, rep(1:5, each = 3), "mean")) check_expr(tapply(x, rep(1:5, each = 3), "min")) check_expr(tapply(x, rep(1:5, each = 3), "prod")) + check_expr(tapply(x, rep(1:5, each = 3), "sd")) }) test_that("cumulative functions error as expected", { From 1ccf56ba52c272e665be3fe218c87f1a0c7f52a9 Mon Sep 17 00:00:00 2001 From: Nicholas Tierney Date: Mon, 21 Mar 2022 08:41:14 +0800 Subject: [PATCH 02/19] export `is_mac_arm64()` --- NAMESPACE | 1 + R/utils.R | 5 +++++ man/is_mac_arm64.Rd | 11 +++++++++++ 3 files changed, 17 insertions(+) create mode 100644 man/is_mac_arm64.Rd diff --git a/NAMESPACE b/NAMESPACE index 2a366cdf2..575f30f85 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -198,6 +198,7 @@ export(install_greta_deps) export(install_tensorflow) export(inverse_gamma) export(iprobit) +export(is_mac_arm64) export(joint) export(l_bfgs_b) export(laplace) diff --git a/R/utils.R b/R/utils.R index 052d13209..c0108ef7a 100644 --- a/R/utils.R +++ b/R/utils.R @@ -930,6 +930,11 @@ greta_sitrep <- function(){ } # adapted from https://github.com/rstudio/tensorflow/blob/main/R/utils.R +#' Is the operating system M1? +#' +#' This is used to check if the operating system is M1 mac +#' +#' @export is_mac_arm64 <- function() { if (nzchar(Sys.getenv("GRETA_M1_MESSAGE_TESTING"))) { return(TRUE) diff --git a/man/is_mac_arm64.Rd b/man/is_mac_arm64.Rd new file mode 100644 index 000000000..3866c25d5 --- /dev/null +++ b/man/is_mac_arm64.Rd @@ -0,0 +1,11 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/utils.R +\name{is_mac_arm64} +\alias{is_mac_arm64} +\title{Is the operating system M1?} +\usage{ +is_mac_arm64() +} +\description{ +This is used to check if the operating system is M1 mac +} From 069043a527d055927562e04aead984ad014ce3a8 Mon Sep 17 00:00:00 2001 From: Nicholas Tierney Date: Mon, 21 Mar 2022 08:42:41 +0800 Subject: [PATCH 03/19] downgrade check for M1 from an error to a message --- R/checkers.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/R/checkers.R b/R/checkers.R index fdb1f7db2..399bfdd06 100644 --- a/R/checkers.R +++ b/R/checkers.R @@ -26,14 +26,14 @@ check_tf_version <- function(alert = c("none", if (is_mac_arm64()) { - msg <- cli::format_error( + msg <- cli::format_message( c( "{.pkg greta} does not currently work with Apple Silicon (M1)", "We are working on getting this resolved ASAP, see {.url https://github.com/greta-dev/greta/issues/458} for current progress." ) ) - stop( + message( msg, call. = FALSE ) From d57b83e97feba19d9e411e4036eb9ee86e15eeed Mon Sep 17 00:00:00 2001 From: Nicholas Tierney Date: Mon, 21 Mar 2022 08:44:04 +0800 Subject: [PATCH 04/19] only evaluate if not an M1 mac --- vignettes/example_models.Rmd | 2 +- vignettes/get_started.Rmd | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/vignettes/example_models.Rmd b/vignettes/example_models.Rmd index e9d98fc69..54f654d58 100644 --- a/vignettes/example_models.Rmd +++ b/vignettes/example_models.Rmd @@ -9,7 +9,7 @@ vignette: > ```{r setup, include = FALSE} knitr::opts_chunk$set(comment = NA, - eval = greta:::check_tf_version("message"), + eval = !greta::is_mac_arm64(), cache = TRUE) library (greta) ``` diff --git a/vignettes/get_started.Rmd b/vignettes/get_started.Rmd index 38f7f643a..e473622c8 100644 --- a/vignettes/get_started.Rmd +++ b/vignettes/get_started.Rmd @@ -10,7 +10,7 @@ vignette: > ```{r setup, include = FALSE} knitr::opts_chunk$set(echo = TRUE, - eval = greta:::check_tf_version("message"), + eval = !greta::is_mac_arm64(), cache = TRUE, comment = NA, progress = FALSE) From 65095c46fca6b13c07d3c38778713c7c9106280d Mon Sep 17 00:00:00 2001 From: Nicholas Tierney Date: Mon, 21 Mar 2022 12:19:21 +0800 Subject: [PATCH 05/19] change back to error not message --- R/checkers.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/R/checkers.R b/R/checkers.R index 399bfdd06..fdb1f7db2 100644 --- a/R/checkers.R +++ b/R/checkers.R @@ -26,14 +26,14 @@ check_tf_version <- function(alert = c("none", if (is_mac_arm64()) { - msg <- cli::format_message( + msg <- cli::format_error( c( "{.pkg greta} does not currently work with Apple Silicon (M1)", "We are working on getting this resolved ASAP, see {.url https://github.com/greta-dev/greta/issues/458} for current progress." ) ) - message( + stop( msg, call. = FALSE ) From 83140c2d245d7c64bf6c29b14684155082bc6ce3 Mon Sep 17 00:00:00 2001 From: Nicholas Tierney Date: Mon, 21 Mar 2022 14:17:59 +0800 Subject: [PATCH 06/19] remove documentation for is_mac_arm64; add `is_not_cran()` function --- NAMESPACE | 1 - R/utils.R | 9 ++++----- man/is_mac_arm64.Rd | 11 ----------- 3 files changed, 4 insertions(+), 17 deletions(-) delete mode 100644 man/is_mac_arm64.Rd diff --git a/NAMESPACE b/NAMESPACE index 575f30f85..2a366cdf2 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -198,7 +198,6 @@ export(install_greta_deps) export(install_tensorflow) export(inverse_gamma) export(iprobit) -export(is_mac_arm64) export(joint) export(l_bfgs_b) export(laplace) diff --git a/R/utils.R b/R/utils.R index c0108ef7a..ac23c7f0d 100644 --- a/R/utils.R +++ b/R/utils.R @@ -930,11 +930,6 @@ greta_sitrep <- function(){ } # adapted from https://github.com/rstudio/tensorflow/blob/main/R/utils.R -#' Is the operating system M1? -#' -#' This is used to check if the operating system is M1 mac -#' -#' @export is_mac_arm64 <- function() { if (nzchar(Sys.getenv("GRETA_M1_MESSAGE_TESTING"))) { return(TRUE) @@ -954,3 +949,7 @@ create_temp_file <- function(path){ file.create(file_path) return(file_path) } + +is_not_cran <- function(){ + identical(Sys.getenv("NOT_CRAN", unset = "true"), "true") +} diff --git a/man/is_mac_arm64.Rd b/man/is_mac_arm64.Rd deleted file mode 100644 index 3866c25d5..000000000 --- a/man/is_mac_arm64.Rd +++ /dev/null @@ -1,11 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/utils.R -\name{is_mac_arm64} -\alias{is_mac_arm64} -\title{Is the operating system M1?} -\usage{ -is_mac_arm64() -} -\description{ -This is used to check if the operating system is M1 mac -} From 981abca8723a7d1ef1ec28c5a49c46369377b543 Mon Sep 17 00:00:00 2001 From: Nicholas Tierney Date: Mon, 21 Mar 2022 14:18:21 +0800 Subject: [PATCH 07/19] evaluate code depending on whether this is being assessed on CRAN --- vignettes/example_models.Rmd | 2 +- vignettes/get_started.Rmd | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/vignettes/example_models.Rmd b/vignettes/example_models.Rmd index 54f654d58..e4ddd8909 100644 --- a/vignettes/example_models.Rmd +++ b/vignettes/example_models.Rmd @@ -9,7 +9,7 @@ vignette: > ```{r setup, include = FALSE} knitr::opts_chunk$set(comment = NA, - eval = !greta::is_mac_arm64(), + eval = greta:::is_not_cran(), cache = TRUE) library (greta) ``` diff --git a/vignettes/get_started.Rmd b/vignettes/get_started.Rmd index e473622c8..48930b6d1 100644 --- a/vignettes/get_started.Rmd +++ b/vignettes/get_started.Rmd @@ -10,7 +10,7 @@ vignette: > ```{r setup, include = FALSE} knitr::opts_chunk$set(echo = TRUE, - eval = !greta::is_mac_arm64(), + eval = greta:::is_not_cran(), cache = TRUE, comment = NA, progress = FALSE) From 76f54757694d605aefbf630cf77f02e0c14f35b9 Mon Sep 17 00:00:00 2001 From: Nicholas Tierney Date: Mon, 21 Mar 2022 15:50:44 +0800 Subject: [PATCH 08/19] use message instead of stop --- R/checkers.R | 4 ++-- tests/testthat/_snaps/check-m1.md | 7 +++++-- tests/testthat/test-check-m1.R | 5 +++-- vignettes/example_models.Rmd | 2 +- vignettes/get_started.Rmd | 2 +- 5 files changed, 12 insertions(+), 8 deletions(-) diff --git a/R/checkers.R b/R/checkers.R index fdb1f7db2..399bfdd06 100644 --- a/R/checkers.R +++ b/R/checkers.R @@ -26,14 +26,14 @@ check_tf_version <- function(alert = c("none", if (is_mac_arm64()) { - msg <- cli::format_error( + msg <- cli::format_message( c( "{.pkg greta} does not currently work with Apple Silicon (M1)", "We are working on getting this resolved ASAP, see {.url https://github.com/greta-dev/greta/issues/458} for current progress." ) ) - stop( + message( msg, call. = FALSE ) diff --git a/tests/testthat/_snaps/check-m1.md b/tests/testthat/_snaps/check-m1.md index 791639442..f50cd8164 100644 --- a/tests/testthat/_snaps/check-m1.md +++ b/tests/testthat/_snaps/check-m1.md @@ -1,5 +1,8 @@ # check_tf_version fails when M1 mac detected - greta does not currently work with Apple Silicon (M1) - We are working on getting this resolved ASAP, see for current progress. + Code + check_tf_version("error") + Message + greta does not currently work with Apple Silicon (M1) + We are working on getting this resolved ASAP, see for current progress.FALSE diff --git a/tests/testthat/test-check-m1.R b/tests/testthat/test-check-m1.R index 9aff18c31..26b97a013 100644 --- a/tests/testthat/test-check-m1.R +++ b/tests/testthat/test-check-m1.R @@ -1,7 +1,8 @@ test_that("check_tf_version fails when M1 mac detected", { skip_if_not(check_tf_version()) withr::local_envvar("GRETA_M1_MESSAGE_TESTING" = "on") - expect_snapshot_error( - check_tf_version("error") + expect_snapshot( + x = check_tf_version("error"), + cnd_class = FALSE ) }) diff --git a/vignettes/example_models.Rmd b/vignettes/example_models.Rmd index e4ddd8909..e9d98fc69 100644 --- a/vignettes/example_models.Rmd +++ b/vignettes/example_models.Rmd @@ -9,7 +9,7 @@ vignette: > ```{r setup, include = FALSE} knitr::opts_chunk$set(comment = NA, - eval = greta:::is_not_cran(), + eval = greta:::check_tf_version("message"), cache = TRUE) library (greta) ``` diff --git a/vignettes/get_started.Rmd b/vignettes/get_started.Rmd index 48930b6d1..38f7f643a 100644 --- a/vignettes/get_started.Rmd +++ b/vignettes/get_started.Rmd @@ -10,7 +10,7 @@ vignette: > ```{r setup, include = FALSE} knitr::opts_chunk$set(echo = TRUE, - eval = greta:::is_not_cran(), + eval = greta:::check_tf_version("message"), cache = TRUE, comment = NA, progress = FALSE) From c1fbc4f2885cc132c1a3ecd28eaf25250eb09475 Mon Sep 17 00:00:00 2001 From: Nicholas Tierney Date: Tue, 22 Mar 2022 07:56:40 +0800 Subject: [PATCH 09/19] change to 0.4.2 --- DESCRIPTION | 4 ++-- NEWS.md | 6 +++++- cran-comments.md | 5 +++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 829dc60ff..cc5d0dfc8 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Type: Package Package: greta Title: Simple and Scalable Statistical Modelling in R -Version: 0.4.1.9000 -Date: 2022-03-14 +Version: 0.4.2 +Date: 2022-03-22 Authors@R: c( person("Nick", "Golding", , "nick.golding.research@gmail.com", role = "aut", comment = c(ORCID = "0000-0001-8916-5570")), diff --git a/NEWS.md b/NEWS.md index 76e701a5b..972e65a78 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,4 +1,8 @@ -# greta 0.4.1.9000 (development version) +# greta 0.4.2 + +## Fixes + +* workaround for M1 issues (#507) # greta 0.4.1 (2022-03-14) diff --git a/cran-comments.md b/cran-comments.md index c9fb85763..d5fd6506c 100644 --- a/cran-comments.md +++ b/cran-comments.md @@ -1,5 +1,5 @@ ## Test environments -* local R installation, R 4.1.3 +* Mac OSX (Intel) local R installation, R 4.1.3 * ubuntu 16.04 (on travis-ci), R 4.1.3 * win-builder (devel) @@ -7,7 +7,8 @@ 0 errors | 0 warnings | 1 notes -* Maintainer has changed from Nick Golding to Nicholas Tierney. +* Days since last update: 6 +* Package has been resubmitted based on request to fix error on install of M1. This has now been resolved ## revdepcheck results From 924c6ea34e759f1eb77122f86bf15c4643a7ace2 Mon Sep 17 00:00:00 2001 From: Nicholas Tierney Date: Tue, 22 Mar 2022 08:10:45 +0800 Subject: [PATCH 10/19] update codemeta --- codemeta.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/codemeta.json b/codemeta.json index c5dfa3ecd..ec223d517 100644 --- a/codemeta.json +++ b/codemeta.json @@ -6,8 +6,8 @@ "name": "greta: Simple and Scalable Statistical Modelling in R", "codeRepository": "https://github.com/njtierney/greta", "issueTracker": "https://github.com/greta-dev/greta/issues", - "license": "Apache License 2", - "version": "0.4.1", + "license": "https://spdx.org/licenses/Apache-2.0", + "version": "0.4.2", "programmingLanguage": { "@type": "ComputerLanguage", "name": "R", @@ -515,7 +515,7 @@ }, "SystemRequirements": "Python (>= 2.7.0) with header files and shared\n library; TensorFlow (v1.14; https://www.tensorflow.org/); TensorFlow\n Probability (v0.7.0; https://www.tensorflow.org/probability/)" }, - "fileSize": "1326.582KB", + "fileSize": "1320.891KB", "citation": [ { "@type": "ScholarlyArticle", From afaef4ede116ebc7c256bf3a85eb3a0c86a88212 Mon Sep 17 00:00:00 2001 From: Nicholas Tierney Date: Tue, 22 Mar 2022 08:11:20 +0800 Subject: [PATCH 11/19] update cran-comments --- cran-comments.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cran-comments.md b/cran-comments.md index d5fd6506c..504e71b0c 100644 --- a/cran-comments.md +++ b/cran-comments.md @@ -5,9 +5,9 @@ ## R CMD check results -0 errors | 0 warnings | 1 notes +0 errors | 0 warnings | 0 notes -* Days since last update: 6 +* Days since last update: 7 * Package has been resubmitted based on request to fix error on install of M1. This has now been resolved ## revdepcheck results From 6426e2f0c3961499601e1b93dd3b44b721b4c92a Mon Sep 17 00:00:00 2001 From: Nicholas Tierney Date: Tue, 22 Mar 2022 08:13:42 +0800 Subject: [PATCH 12/19] remove `is_not_cran()` function --- R/utils.R | 4 ---- cran-comments.md | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/R/utils.R b/R/utils.R index ac23c7f0d..052d13209 100644 --- a/R/utils.R +++ b/R/utils.R @@ -949,7 +949,3 @@ create_temp_file <- function(path){ file.create(file_path) return(file_path) } - -is_not_cran <- function(){ - identical(Sys.getenv("NOT_CRAN", unset = "true"), "true") -} diff --git a/cran-comments.md b/cran-comments.md index 504e71b0c..9c79e71d4 100644 --- a/cran-comments.md +++ b/cran-comments.md @@ -1,5 +1,5 @@ ## Test environments -* Mac OSX (Intel) local R installation, R 4.1.3 +* local R installation, R 4.1.3 * ubuntu 16.04 (on travis-ci), R 4.1.3 * win-builder (devel) From 45657cd0c1978defdd1e6ba54ba79047c866baff Mon Sep 17 00:00:00 2001 From: Nicholas Tierney Date: Wed, 23 Mar 2022 16:41:05 +0800 Subject: [PATCH 13/19] Increment version number to 0.4.2.9000 --- DESCRIPTION | 2 +- NEWS.md | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index cc5d0dfc8..f143707de 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Type: Package Package: greta Title: Simple and Scalable Statistical Modelling in R -Version: 0.4.2 +Version: 0.4.2.9000 Date: 2022-03-22 Authors@R: c( person("Nick", "Golding", , "nick.golding.research@gmail.com", role = "aut", diff --git a/NEWS.md b/NEWS.md index 972e65a78..4d871b5d4 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,5 @@ +# greta (development version) + # greta 0.4.2 ## Fixes From ef1069d3ced553cf0d13a9faaf563f68d6fe048b Mon Sep 17 00:00:00 2001 From: Nicholas Tierney Date: Wed, 30 Mar 2022 10:53:25 +0800 Subject: [PATCH 14/19] first attempt at using tensorflow to make different calculations of standard deviation --- R/tf_functions.R | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/R/tf_functions.R b/R/tf_functions.R index c97ab1cc1..24452af69 100644 --- a/R/tf_functions.R +++ b/R/tf_functions.R @@ -80,12 +80,25 @@ tf_mean <- function(x, drop = FALSE) { skip_dim("reduce_mean", x, drop) } -tf_sd <- function(x, drop = FALSE) { - n_dim <- length(dim(x)) - reduction_dims <- seq_len(n_dim - 1) - tf$math$reduce_std(x, axis = reduction_dims, keepdims = !drop) +tf_sd <- function(x, n_minus_1 = TRUE){ + if (n_minus_1){ + # replace these parts with tf_sum and friends? + x_mean_sq <- tf_mean(x) * tf_mean(x) + total_ss <- tf_sum(x - x_mean_sq) + var <- total_ss / (length(x) - 1) + sd_result <- sqrt(var) + # total_ss <- sum((x - mean(x))^2) + # var <- (total_ss / (length(x) - 1)) + # sd_result <- sqrt(var) + } else if (!n_minus_1) { + n_dim <- length(dim(x)) + reduction_dims <- seq_len(n_dim - 1) + sd_result <- tf$math$reduce_std(x, axis = reduction_dims, keepdims = !drop) + } + return(sd_result) } + tf_max <- function(x, drop = FALSE) { skip_dim("reduce_max", x, drop) } From 7b9c5b934c2780770e56ec67487492eba3a2203a Mon Sep 17 00:00:00 2001 From: Nicholas Tierney Date: Thu, 31 Mar 2022 14:35:11 +0800 Subject: [PATCH 15/19] implement using correct tensorflow dimensions etc --- R/tf_functions.R | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/R/tf_functions.R b/R/tf_functions.R index 24452af69..7a01e833f 100644 --- a/R/tf_functions.R +++ b/R/tf_functions.R @@ -80,22 +80,22 @@ tf_mean <- function(x, drop = FALSE) { skip_dim("reduce_mean", x, drop) } -tf_sd <- function(x, n_minus_1 = TRUE){ - if (n_minus_1){ - # replace these parts with tf_sum and friends? - x_mean_sq <- tf_mean(x) * tf_mean(x) - total_ss <- tf_sum(x - x_mean_sq) - var <- total_ss / (length(x) - 1) - sd_result <- sqrt(var) - # total_ss <- sum((x - mean(x))^2) - # var <- (total_ss / (length(x) - 1)) - # sd_result <- sqrt(var) - } else if (!n_minus_1) { - n_dim <- length(dim(x)) - reduction_dims <- seq_len(n_dim - 1) - sd_result <- tf$math$reduce_std(x, axis = reduction_dims, keepdims = !drop) - } - return(sd_result) +# need to create a "reduce_sd" function +# which + +tf_sd <- function(x, drop = FALSE){ + + n_dim <- length(dim(x)) + reduction_dims <- seq_len(n_dim - 1) + + # replace these parts with tf_sum and friends? + x_mean_sq <- tf_mean(x, drop = drop) * tf_mean(x, drop = drop) + total_ss <- tf_sum(x - x_mean_sq, drop = drop) + n_denom <- prod(dim(x)[reduction_dims + 1]) + var <- total_ss / fl(n_denom - 1) + sd_result <- tf$math$sqrt(var) + + sd_result } From 0ebf81dde43cb678b00902689e993803a3680c50 Mon Sep 17 00:00:00 2001 From: Nicholas Tierney Date: Fri, 18 Mar 2022 13:22:25 +0800 Subject: [PATCH 16/19] implement first pass at using sd.greta_array method tests currently fail --- NAMESPACE | 3 +++ R/functions.R | 34 +++++++++++++++++++++++++++++---- R/tf_functions.R | 6 ++++++ man/functions.Rd | 5 +++-- man/overloaded.Rd | 3 +++ tests/testthat/test_functions.R | 3 +++ 6 files changed, 48 insertions(+), 6 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index 2a366cdf2..df8b1cfe3 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -116,6 +116,8 @@ S3method(rowMeans,default) S3method(rowMeans,greta_array) S3method(rowSums,default) S3method(rowSums,greta_array) +S3method(sd,default) +S3method(sd,greta_array) S3method(sign,greta_array) S3method(simulate,greta_model) S3method(sin,greta_array) @@ -232,6 +234,7 @@ export(rms_prop) export(rowMeans) export(rowSums) export(rwmh) +export(sd) export(simplex_variable) export(slice) export(slsqp) diff --git a/R/functions.R b/R/functions.R index 6e75dcf61..2a9bdfbfb 100644 --- a/R/functions.R +++ b/R/functions.R @@ -62,6 +62,7 @@ #' prod(..., na.rm = TRUE) #' min(..., na.rm = TRUE) #' max(..., na.rm = TRUE) +#' sd(..., na.rm = TRUE) #' #' # cumulative operations #' cumsum(x) @@ -77,10 +78,10 @@ #' #' # miscellaneous operations #' aperm(x, perm) -#' apply(x, MARGIN, FUN = c("sum", "max", "mean", "min", +#' apply(x, MARGIN, FUN = c("sum", "max", "mean", "min", "sd, #' "prod", "cumsum", "cumprod")) #' sweep(x, MARGIN, STATS, FUN = c('-', '+', '/', '*')) -#' tapply(X, INDEX, FUN = c("sum", "max", "mean", "min", "prod"), ...) +#' tapply(X, INDEX, FUN = c("sum", "max", "mean", "min", "sd, "prod"), ...) #' #' } #' @@ -590,6 +591,31 @@ mean.greta_array <- function(x, trim = 0, na.rm = TRUE, ...) { # nolint ) } +# need to define sd as a generic since it isn't actually a generic +#' @rdname overloaded +#' @export +sd <- function(x, ...) UseMethod("sd", x) + +# setting default and setting arguments for it so it passes package check +#' @export +sd.default <- function(x, na.rm = FALSE, ...) { + sd_result <- stats::sd(x = x, + na.rm = na.rm) + formals(sd.default) <- c(formals(sd.default), alist(... =)) + + sd_result +} + +#' @export +sd.greta_array <- function(x, na.rm = TRUE, ...) { # nolint + + # calculate SD on greta array + op("sd", x, + dim = c(1, 1), + tf_operation = "tf_sd" + ) +} + #' @export max.greta_array <- function(..., na.rm = TRUE) { # nolint @@ -1073,7 +1099,7 @@ apply.default <- function(X, MARGIN, FUN, ...) { # nolint #' @export apply.greta_array <- function(X, MARGIN, FUN = c( - "sum", "max", "mean", "min", "prod", + "sum", "max", "mean", "min", "sd", "prod", "cumsum", "cumprod" ), ...) { @@ -1169,7 +1195,7 @@ tapply.default <- function(X, INDEX, FUN = NULL, ..., # nolint start #' @export tapply.greta_array <- function(X, INDEX, - FUN = c("sum", "max", "mean", "min", "prod"), + FUN = c("sum", "max", "mean", "min", "prod", "sd"), ...) { # nolint end diff --git a/R/tf_functions.R b/R/tf_functions.R index d58b48e5f..c97ab1cc1 100644 --- a/R/tf_functions.R +++ b/R/tf_functions.R @@ -80,6 +80,12 @@ tf_mean <- function(x, drop = FALSE) { skip_dim("reduce_mean", x, drop) } +tf_sd <- function(x, drop = FALSE) { + n_dim <- length(dim(x)) + reduction_dims <- seq_len(n_dim - 1) + tf$math$reduce_std(x, axis = reduction_dims, keepdims = !drop) +} + tf_max <- function(x, drop = FALSE) { skip_dim("reduce_max", x, drop) } diff --git a/man/functions.Rd b/man/functions.Rd index aa97c9494..b3d7c9500 100644 --- a/man/functions.Rd +++ b/man/functions.Rd @@ -87,6 +87,7 @@ precision than R's equivalent. prod(..., na.rm = TRUE) min(..., na.rm = TRUE) max(..., na.rm = TRUE) + sd(..., na.rm = TRUE) # cumulative operations cumsum(x) @@ -102,10 +103,10 @@ precision than R's equivalent. # miscellaneous operations aperm(x, perm) - apply(x, MARGIN, FUN = c("sum", "max", "mean", "min", + apply(x, MARGIN, FUN = c("sum", "max", "mean", "min", "sd, "prod", "cumsum", "cumprod")) sweep(x, MARGIN, STATS, FUN = c('-', '+', '/', '*')) - tapply(X, INDEX, FUN = c("sum", "max", "mean", "min", "prod"), ...) + tapply(X, INDEX, FUN = c("sum", "max", "mean", "min", "sd, "prod"), ...) } } diff --git a/man/overloaded.Rd b/man/overloaded.Rd index 41f92950c..4062a0ecc 100644 --- a/man/overloaded.Rd +++ b/man/overloaded.Rd @@ -6,6 +6,7 @@ \alias{\%*\%} \alias{chol2inv} \alias{cov2cor} +\alias{sd} \alias{identity} \alias{colMeans} \alias{rowMeans} @@ -28,6 +29,8 @@ chol2inv(x, size = NCOL(x), LINPACK = FALSE) cov2cor(V) +sd(x, ...) + identity(x) colMeans(x, na.rm = FALSE, dims = 1L) diff --git a/tests/testthat/test_functions.R b/tests/testthat/test_functions.R index a08df9c46..9eff87dfb 100644 --- a/tests/testthat/test_functions.R +++ b/tests/testthat/test_functions.R @@ -22,6 +22,7 @@ test_that("simple functions work as expected", { check_op(mean, x) check_op(sqrt, exp(x)) check_op(sign, x) + check_op(sd, x) # rounding of numbers check_op(ceiling, x) @@ -230,6 +231,7 @@ test_that("apply works as expected", { check_apply(a, margin, "prod") check_apply(a, margin, "cumsum") check_apply(a, margin, "cumprod") + check_apply(a, margin, "sd") } }) @@ -243,6 +245,7 @@ test_that("tapply works as expected", { check_expr(tapply(x, rep(1:5, each = 3), "mean")) check_expr(tapply(x, rep(1:5, each = 3), "min")) check_expr(tapply(x, rep(1:5, each = 3), "prod")) + check_expr(tapply(x, rep(1:5, each = 3), "sd")) }) test_that("cumulative functions error as expected", { From da46fdd87d0d03141a4e731d611492d39baf26c7 Mon Sep 17 00:00:00 2001 From: Nicholas Tierney Date: Wed, 30 Mar 2022 10:53:25 +0800 Subject: [PATCH 17/19] first attempt at using tensorflow to make different calculations of standard deviation --- R/tf_functions.R | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/R/tf_functions.R b/R/tf_functions.R index c97ab1cc1..24452af69 100644 --- a/R/tf_functions.R +++ b/R/tf_functions.R @@ -80,12 +80,25 @@ tf_mean <- function(x, drop = FALSE) { skip_dim("reduce_mean", x, drop) } -tf_sd <- function(x, drop = FALSE) { - n_dim <- length(dim(x)) - reduction_dims <- seq_len(n_dim - 1) - tf$math$reduce_std(x, axis = reduction_dims, keepdims = !drop) +tf_sd <- function(x, n_minus_1 = TRUE){ + if (n_minus_1){ + # replace these parts with tf_sum and friends? + x_mean_sq <- tf_mean(x) * tf_mean(x) + total_ss <- tf_sum(x - x_mean_sq) + var <- total_ss / (length(x) - 1) + sd_result <- sqrt(var) + # total_ss <- sum((x - mean(x))^2) + # var <- (total_ss / (length(x) - 1)) + # sd_result <- sqrt(var) + } else if (!n_minus_1) { + n_dim <- length(dim(x)) + reduction_dims <- seq_len(n_dim - 1) + sd_result <- tf$math$reduce_std(x, axis = reduction_dims, keepdims = !drop) + } + return(sd_result) } + tf_max <- function(x, drop = FALSE) { skip_dim("reduce_max", x, drop) } From 908be4833e34a2ac5418c0a65f9a19428aa3029e Mon Sep 17 00:00:00 2001 From: Nicholas Tierney Date: Thu, 31 Mar 2022 14:35:11 +0800 Subject: [PATCH 18/19] implement using correct tensorflow dimensions etc --- R/tf_functions.R | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/R/tf_functions.R b/R/tf_functions.R index 24452af69..7a01e833f 100644 --- a/R/tf_functions.R +++ b/R/tf_functions.R @@ -80,22 +80,22 @@ tf_mean <- function(x, drop = FALSE) { skip_dim("reduce_mean", x, drop) } -tf_sd <- function(x, n_minus_1 = TRUE){ - if (n_minus_1){ - # replace these parts with tf_sum and friends? - x_mean_sq <- tf_mean(x) * tf_mean(x) - total_ss <- tf_sum(x - x_mean_sq) - var <- total_ss / (length(x) - 1) - sd_result <- sqrt(var) - # total_ss <- sum((x - mean(x))^2) - # var <- (total_ss / (length(x) - 1)) - # sd_result <- sqrt(var) - } else if (!n_minus_1) { - n_dim <- length(dim(x)) - reduction_dims <- seq_len(n_dim - 1) - sd_result <- tf$math$reduce_std(x, axis = reduction_dims, keepdims = !drop) - } - return(sd_result) +# need to create a "reduce_sd" function +# which + +tf_sd <- function(x, drop = FALSE){ + + n_dim <- length(dim(x)) + reduction_dims <- seq_len(n_dim - 1) + + # replace these parts with tf_sum and friends? + x_mean_sq <- tf_mean(x, drop = drop) * tf_mean(x, drop = drop) + total_ss <- tf_sum(x - x_mean_sq, drop = drop) + n_denom <- prod(dim(x)[reduction_dims + 1]) + var <- total_ss / fl(n_denom - 1) + sd_result <- tf$math$sqrt(var) + + sd_result } From 7321aa08f52bf5ca5450368d990f876ab4e23453 Mon Sep 17 00:00:00 2001 From: Nicholas Tierney Date: Thu, 31 Mar 2022 14:53:40 +0800 Subject: [PATCH 19/19] might need to explore how things are happening with skip dim and the dimension that is being returned --- R/tf_functions.R | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/R/tf_functions.R b/R/tf_functions.R index 7a01e833f..e02c33013 100644 --- a/R/tf_functions.R +++ b/R/tf_functions.R @@ -89,8 +89,10 @@ tf_sd <- function(x, drop = FALSE){ reduction_dims <- seq_len(n_dim - 1) # replace these parts with tf_sum and friends? - x_mean_sq <- tf_mean(x, drop = drop) * tf_mean(x, drop = drop) - total_ss <- tf_sum(x - x_mean_sq, drop = drop) + x_mean <- tf_mean(x, drop = drop) + x_sub <- x - x_mean + x_mean_sq <- x_sub * x_sub + total_ss <- tf_sum(x_mean_sq, drop = drop) n_denom <- prod(dim(x)[reduction_dims + 1]) var <- total_ss / fl(n_denom - 1) sd_result <- tf$math$sqrt(var)