Feature request: Jacobians of unconstraining transform

I get the big picture, but still don’t understand what you
want exposed in the way of API calls from the compiled model
in C++.

If you can propose new member functions for the C++ model class,
that’d be a huge help.

I’m assuming you don’t want the whole Jacobian matrix from
unconstrained to constrained parameters. That’s going to be
enormous. We never try to build the Jacobian matrix, even
for a single parameter — we just go straight to the log determinant
because all the transforms are either diagonal or triangular.

  • Bob

If you can propose new member functions for the C++ model class, that’d be a huge help.

I have only a cursory understanding of how the prob_grad (i.e., Stan model) class works, but I can take a stab at suggesting a redesign that would serve this long-term goal.

Perhaps the generated parameters block be treated as something similar to the prob_grad class, except instead of a log_prob scalar-valued function it would return an vector<__T> valued-vector containing the transformed parameters. Let’s call such a class the generated_params class. Every Stan model with a generated model block would have, as a member, an object of the type generated_params class. Instead of defining generated values as double types in the model, it would populate them using semantics similar to how the log_prob reads from a context using readers and writers.

Specifically, just like log_prob, the generated_params class would have a method, say, generate_params that would take as an argument the vector<T__>& params_r__ vector and read it with a stan::io::reader<T__> object. Every generated parameter (i.e. parameters declared in the generated parameters block) would be an attribute of the generated_params class, just like parameters declared in the parameters block are declared as parameters of the prob_grad-derived class. constrained_param_names() would be replaced with generated_param_names().

Very little would have to change in a prob_grad class. Instead of calculating generated parameters inline, it would calculate them with a generated_params class method. In order to avoid decoding the stan::io::var_context twice, you could overload the generate_params() method to take as an input either a pre-decoded Stan model or a vector vector<T__>& params_r__. In either case, the generated_params method would return a vector of generated parameters, whose entries would be enumerated by the generated_param_names() method.

You could then drop a functor that wraps the generate_params() function directly into stan::math::jacobian and get exactly what you need to implement the high-level features I described above.

Note again that, for the full functionality, this would also require that either the unconstrained variables or the constraining functions be made available through the Stan model interface, which is basically the same as them being made available in C++ outside the reader and writer classes.

Does that make sense?

I’m assuming you don’t want the whole Jacobian matrix from unconstrained to constrained parameters.

Right, you generally only really want this for specific parameters. That’s why the ability to take the Jacobian of generated parameters, plus access to the constraining funcitons or unconstrained parameters, makes more sense.