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

cannot use tan_half link in custom family #1634

Open
venpopov opened this issue Mar 23, 2024 · 1 comment
Open

cannot use tan_half link in custom family #1634

venpopov opened this issue Mar 23, 2024 · 1 comment
Labels
Milestone

Comments

@venpopov
Copy link
Contributor

venpopov commented Mar 23, 2024

I tried to specify a link in a custom family as tan_half, but the stancode did not compile because the tan_half, inv_tan_half functions were not defined. I can define them myself and include in the stanvars, but it would be nice to be able to use the builtin functionality for that.

I noticed that this happens for some special link functions, but not for others. For example, adding a cauchit link works. logm1 doesn't.

I tracked this down to the fact that special link functions are loaded in one of two places:

  1. stan_global_defs: all the "if(any(links = ...." include statements there are link functions that you can use in a custom family, because brms recognizes the link and includes the code
  2. as explicit include arguments to the .family_* functions. for the von_mises, the fun_tan_half.stan is loaded here and cannot be used by custom functions

My suggestion is to make it consistent how "#include" statements are added for special links and load them just from one place.

since the file names match the link labels, instead of this:

  if (any(links == "cauchit")) {
    str_add(out$fun) <- "  #include 'fun_cauchit.stan'\n"
  } else if (any(links == "cloglog")) {
    str_add(out$fun) <- "  #include 'fun_cloglog.stan'\n"
  } else if (any(links == "softplus")) {
    str_add(out$fun) <- "  #include 'fun_softplus.stan'\n"
  } else if (any(links == "squareplus")) {
    str_add(out$fun) <- "  #include 'fun_squareplus.stan'\n"
  } else if (any(links == "softit")) {
    str_add(out$fun) <- "  #include 'fun_softit.stan'\n"
  } else if (any(links == "tan_half")) {
    str_add(out$fun) <- "  #include 'fun_tan_half.stan'\n"       # I added this just to test it
  }

you could have something along the lines of (a rough idea; alternatively have a function/variable that defines which link functions require external files and check against that)

for (link in links) {
  file <- paste0("fun_", link, ".stan")
  file <- file.path(system.file("chunks", package = "brms"), file)
  if (file.exists(file)) {
  str_add(out$fun) <- .....
}
@venpopov
Copy link
Contributor Author

The intermediate solution for my usecase tuned out simple though - I added #include 'fun_tan_half.stan' to the stanvars function block I pass to brm with my custom family. I wasn't sure if it would work, but it did! So I didn't have to copy paste the functions separately :)

@paul-buerkner paul-buerkner added this to the brms 2.22.0 milestone Mar 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants