I bet that this is easy but I’m having a bit of trouble. I have a function that is defined in a .stan
file but it is not wrapped in functions { }
because I may have a bunch of these I want to reference in my stan program like
functions {
#include my_fun.stan
}
data {
...
and in cmdstanr
I run the program as
fp <- file.path("./full_program.stan")
mod <- cmdstan_model(fp, include_paths = "./function_file_path/")
Can I expose stan functions using rstan
on the my_fun.stan
function?
Hey there!
Are you looking for something like this?
Cheers,
Max
If the contents of my_fun.stan
is not enclosed in functions {}
it will not compile.
I think the easiest solutions here are:
- concat new Stan code by enclosing my_fun.stan in a
functions {}
block
- auto-format the
full_program.stan
to generate a model with #includes replaced with the code from the files and use the experimental rstan 2.26 (it will work with that).
1 Like
Can you give some more detail on solution 2?
Sure.
Say we have my_fun.stan
:
real foo(real a, real b) {
return a + b;
}
real goo(real a, real b) {
return a - b;
}
and full.stan
:
functions {
#include "my_fun.stan"
}
parameters {
real y;
}
model {
y ~ std_normal();
}
library(cmdstanr)
library(rstan)
auto_format <- function(stan_file, include_paths = NULL) {
if(isTRUE(.Platform$OS.type == "windows")) {
stanc <- file.path(cmdstan_path(), "bin", "stanc.exe")
} else {
stanc <- file.path(cmdstan_path(), "bin", "stanc")
}
stancflags_val <- NULL
if (!is.null(include_paths)) {
include_paths <- paste0(include_paths, collapse = ",")
include_paths_flag <- " --include-paths="
include_paths_flag <- " --include_paths="
stancflags_val <- trimws(paste0(include_paths_flag, include_paths, " "))
}
args = c(
"--auto-format",
stan_file,
stancflags_val
)
processx::run(
stanc,
args = args,
echo_cmd = TRUE
)$stdout
}
setwd("~/Desktop/testing/standalone/")
fp <- file.path("full.stan")
p <- auto_format(fp, include_paths = ".")
full_temp_file <- write_stan_file(p)
expose_stan_functions(full_temp_file)
> foo(2,3)
[1] 5
> goo(2,3)
[1] -1
The auto-format parts could be done with rstan I think, but I had the auto format thing ready for cmdstanr for other purposes. Will update if I have time to explore rstan a bit.
The rstan I used is the development version from our repo:
install.packages("StanHeaders", repos = c("https://mc-stan.org/r-packages/", getOption("repos")))
install.packages("rstan", repos = c("https://mc-stan.org/r-packages/", getOption("repos")))
Actually, ignore the above. You can just do:
fp <- file.path("full.stan")
expose_stan_functions(fp, includes = ".")
and you get all the functions exposed.
install.packages("StanHeaders", repos = c("https://mc-stan.org/r-packages/", getOption("repos")))
install.packages("rstan", repos = c("https://mc-stan.org/r-packages/", getOption("repos")))
You might get a redefined something warning, but ignore it.
1 Like