functions as parameters

70 views
Skip to first unread message

Patrick Schmidt

unread,
May 5, 2021, 3:07:05 AM5/5/21
to nimble-users
Hi everybody,

I would like to add a user written distribution function that depends on a function. Is it possible to add a function as a parameter to a user-defined distribution? Something like

dfoo  <- nimbleFunction(
  run = function(x = double(0),
                            foo2=function(0)){
    return(foo2(x))
    returnType(double(0))
  })

My current work-around is to define the nimble function globally,

foo2 <- nimbleFunction(...)

compile it, and then use it in foo. This does not have the same flexibility, so I was wondering if I am missing something.



Daniel Turek

unread,
May 5, 2021, 7:06:45 AM5/5/21
to Patrick Schmidt, nimble-users
No, I don't believe you're missing anything here, Patrick.  In general, the only variable "types" which are supported as arguments to nimbleFunctions are "integer", "double", and "logical".  The flexibility of providing a "function" argument is not supported.

There is a more involved workaround that could perhaps help, for example using a nimbleFunctionList inside your main nimbleFunction, which contains a list of (different) nimbleFunctions.  Then, you would pass an integer-valued argument "ind" into your main nimbleFunction, and depending on the value of "ind", access and use a different member of the nimbleFunctionList (hence, using a different function inside your nimbleFunction, based upon the value of the argument "ind").  This helps somewhat, however still restricts you to the set of functions defined in the nimbleFunctionList (which must be defined prior to compilation), so it's not fully generic in that you could not pass *any* function into your function as an argument.

What you're doing, defining a separate nimbleFunction outside, then using that inside your nimbleFunction of interest is the generally supported usage of "nested nimbleFunctions".  My suggestion above allows a bit more flexibility, to using a predefined set of > 1 nimbleFunctions.  I think those are your best options that immediately come to mind.



--
You received this message because you are subscribed to the Google Groups "nimble-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nimble-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/nimble-users/fbea2ee8-a0f1-424f-a027-5f7d3ea552e8n%40googlegroups.com.

Perry de Valpine

unread,
May 5, 2021, 9:47:49 AM5/5/21
to Daniel Turek, Patrick Schmidt, nimble-users
Hmmm, I'm not sure the nimbleFunctionList solution will work.  There are two kinds of nimbleFunctions, those with setup code and those without.  The nimbleFunctionList is normally created in setup code, and we use that design a lot for MCMC samplers, for example.  But a nimbleFunction to be used as a distribution in a model can't have setup code, as of now (perhaps one day).

You could still use the solution of having an index that is passed to your function, and inside that function call another function based on the index value.  You would just need the menu of other functions to be hard-coded.

Another route is to use a nimbleRcall.  This allows you to call an R function from within compiled nimble.  You can still only pass basic objects, numeric, integer or logical, to the R function, but then within R you can use all of R's flexibility.  E.g. you could use lexical scoping to swap around which functions are called for which indices, or something like that.

I hope it helps and let us know further questions.
Perry


Reply all
Reply to author
Forward
0 new messages