Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement min / max for arrays #293

Open
thibautjombart opened this issue May 10, 2023 · 3 comments
Open

Implement min / max for arrays #293

thibautjombart opened this issue May 10, 2023 · 3 comments

Comments

@thibautjombart
Copy link
Contributor

Context

I am trying to retrieve the largest value of an array in odin. It seems min/max accept comma-separated, atomic numbers, but do not process arrays. I feel I must be missing something obvious... any tip welcome.

Reprex

This is not my actual use-case, but a minimal example generating a vector of Poisson-distributed values and reporting the sum, or maximum value for each iteration.

library(odin)

# The following using `sum` works as intended:

toy_expl <- "
  n_patches <- user()
  dim(x) <- n_patches
  initial(x[]) <- 0
  update(x[]) <- rpois(n_patches)
  y <- sum(x[])
  output(y) <- TRUE
"

set.seed(1)
odin(toy_expl)$new(n_patches = 3)$run(1:6)
#> Loading required namespace: pkgbuild
#> Generating model in c
#> ℹ Re-compiling odin18839483 (debug build)
#> ── R CMD INSTALL ───────────────────────────────────────────────────────────────
#> * installing *source* package ‘odin18839483’ ...
#> ** using staged installation
#> ** libs
#> gcc -I"/usr/local/lib/R/include" -DNDEBUG   -I/usr/local/include   -fpic  -g -O2  -UNDEBUG -Wall -pedantic -g -O0 -c odin.c -o odin.o
#> gcc -I"/usr/local/lib/R/include" -DNDEBUG   -I/usr/local/include   -fpic  -g -O2  -UNDEBUG -Wall -pedantic -g -O0 -c registration.c -o registration.o
#> gcc -shared -L/usr/local/lib/R/lib -L/usr/local/lib -o odin18839483.so odin.o registration.o -L/usr/local/lib/R/lib -lR
#> installing to /tmp/RtmpOPXyVT/devtools_install_1faa2a55c8ae/00LOCK-file1faa3d715d55/00new/odin18839483/libs
#> ** checking absolute paths in shared objects and dynamic libraries
#> * DONE (odin18839483)
#> ℹ Loading odin18839483
#>      step x[1] x[2] x[3]  y
#> [1,]    1    0    0    0  0
#> [2,]    2    1    4    2  7
#> [3,]    3    5    3    4 12
#> [4,]    4    3    3    4 10
#> [5,]    5    0    3    4  7
#> [6,]    6    4    3    5 12


# This generates an error, which I think is intended as 'max' does need
# several arguments, and is not designed for arrays:

toy_expl <- "
  n_patches <- user()
  dim(x) <- n_patches
  initial(x[]) <- 0
  update(x[]) <- rpois(n_patches)
  y <- max(x[])
  output(y) <- TRUE
"

set.seed(1)
odin(toy_expl)$new(n_patches = 3)$run(1:6)
#> Error: Expected 2 or more arguments in max call, but recieved 1
#>    y <- max(x[]) # (line 6)


# Trying a workaround to have 'y' return the maximum of all values in x[], but
# issues of self-referencing:

toy_expl <- "
  n_patches <- user()
  dim(x) <- n_patches
  initial(x[]) <- 0
  update(x[]) <- rpois(n_patches)
  y <- 0 # reasonable default here
  y <- if (x[i] > y) x[i] else y
  output(y) <- TRUE
"

set.seed(1)
odin(toy_expl)$new(n_patches = 3)$run(1:6)
#> Error: Self referencing expressions not allowed (except for arrays)
#>    y <- if (x[i] > y) x[i] else y # (line 7)

Created on 2023-05-10 with reprex v2.0.2

@richfitz
Copy link
Member

Sorry, missed this. This is not terrible to do tbh. I doubt I'll get it done in a short period of time, but it's certainly something that won't break anything.

In the meantime you can do this in odin.dust with custom C code I believe: https://github.com/mrc-ide/odin.dust/blob/master/tests/testthat/test-odin-dust.R#L424-L439 and https://github.com/mrc-ide/odin.dust/blob/master/tests/testthat/include.cpp -- I'm not sure offhand if OG odin allows passing a vector in like this. If you need to have it sweep across array dimensions though that will be unsatisfying.

@richfitz
Copy link
Member

This is now supported in odin2 (which will become odin in due course): mrc-ide/odin2#72

@thibautjombart
Copy link
Contributor Author

Great, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants