Compile errors with derivatives

6 views
Skip to first unread message

Christopher Jackson

unread,
10:24 AM (7 hours ago) 10:24 AM
to nimble-users
Hi,

I am keen to use derivative-based algorithms in NIMBLE, but am having trouble getting models to compile with buildDerivs turned on in user-defined functions.

A minimal example of the kind of thing that breaks is below.  It works with the integer() argument changed to a double().  But the manual had given me the impression that the auto-differentiator would just ignore any integer arguments?   What have I missed?

Thanks,
Chris


fn <- nimbleFunction(
  run = function(mu = double(),
                 x = integer()){
    return(0.0)
    returnType(double())
  },
  buildDerivs = TRUE
)

ncode <- nimbleCode({
  y <- fn(mu, x)
})

nmod <- nimbleModel(code = ncode, data=list(mu=1,x=0), buildDerivs=TRUE)
nmodc <- compileNimble(nmod)
printErrors()

[...snip]

P_61_ncode_MID_53_nfCode.cpp: In member function 'virtual CppAD::AD<double> y_L1_UID_1256::calculate_ADproxyModel(const indexedNodeInfo&) const':
P_61_ncode_MID_53_nfCode.cpp:73:28: error: cannot convert 'std::conditional<true, CppAD::AD<double>, void>::type' {aka 'CppAD::AD<double>'} to 'int' in assignment
73 | Interm_4081 = stoch_ind_get((**ADproxyModel_x), 0);

Perry de Valpine

unread,
11:13 AM (6 hours ago) 11:13 AM
to Christopher Jackson, nimble-users
Hi Chris,

Thanks for the question. 

The answer is in section 16.5.2.2 of the User Manual, but I get it that it might have been hard to find there. Also that is a newer section of the User Manual, I believe only in our latest version (1.2.0). The documentation of programming with AD is a bit hard to organize with a balance of high-level messages and low-level details. Suggestions welcome. Maybe we can bullet-point some of TL;DR tips.

Here is the story. It's true that declaring an argument to be of type integer will mean it will not have derivatives tracked. However, if the function is going to be called from a model, that won't work because all model variables are implemented as doubles, even when they will actually only ever take integer values. Therefore all arguments should be declared as double and the ADbreak method should be used if you want to stop derivative tracking. This should work:

fn <- nimbleFunction(
  run = function(mu = double(),
                 x = double()){
   x2 <- ADbreak(x) # now use x2 instead of x

    return(0.0)
    returnType(double())
  },
  buildDerivs = TRUE
)

HTH,
Perry

--
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/1e2f66cc-7b41-4998-9ee8-19a7d27057a5n%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages