Re: Expose Stan functions to R

68 views
Skip to first unread message

Ben Goodrich

unread,
Mar 4, 2015, 5:32:21 PM3/4/15
to stan...@googlegroups.com
I think we agree that if we can get by without (or with fewer regexps), then that would be good. But they work at the moment, so that is good enough for rstan. The next question is whether you can somehow make the entirety of the transformed parameters block, the model block, etc. into a function defined in the functions block so that you can then call it exactly in R?

Ben

On Wed, Mar 4, 2015 at 5:27 PM, Bob Carpenter <ca...@alias-i.com> wrote:
[is there a reason this isn't on stan-dev?]

Sebastian's e-mail seems to missing the juicy bits.

I would really rather not expose a pass-by-value vs. pass-by-reference
distinction in Stan --- it's one of the things users find really
confusing.

Regexes are not the long-term solution here --- we need to either

  1.  generate wrapper functions

  2.  code generate what's needed inside language/generator.hpp

Regexes are very very very brittle and will make it hard to put tests
into Stan to make sure we don't break them on the R side.

As a wise man (Jamie Zawinski apparently), once said,

  If you have a problem and think regexes are the solution,
  now you have two problems.

  http://blog.codinghorror.com/regular-expressions-now-you-have-two-problems/

- Bob

> On Mar 5, 2015, at 2:54 AM, Ben Goodrich <goodri...@gmail.com> wrote:
>
> I still think this would be hard, but perhaps as a first step in that direction, is it feasible to liberalize the syntax for functions so that they could take non-const references (perhaps with an explicit & in the Stan program) to arguments, as in
>
> void foo(matrix& x, matrix& y, matrix z) {
>   // modify x and y but not z
> }
>
> Then the user could implement their transformed parameters block as
>
> transformed parameters {
>   matrix[K,K] x; matrix[J,J] y;
>   foo(x, y, z);
> }
>
> I'm not sure within the Stan language how we could catch / prevent someone from passing a const thing like data or parameters to a non-const argument of a user-defined function, but then again I'm not sure how the parser currently catches / prevents a lot of things.
>
> Ben
>
>
> On Tue, Mar 3, 2015 at 7:32 AM, Weber, Sebastian <sebasti...@novartis.com> wrote:
> Hi Bob!
>
>
>
> I saw the expose Stan functions thing is being reconsidered – this is a great feature, really! When you redesign this, could you consider to include functions like
>
>
>
> Transformed_data
>
> Transformed_parameters
>
> Model
>
>
>
> As output of these specially parsed Stan models? Ben said this is close to impossible by the regex approach, but if you think it would be easily possible when you parse the program, then this would be a great thing (Aki liked the approach a lot).
>
>
>
> I see that this might be difficult, as the functions would need to return a ragged structure, but if there is a way to do it, I think it would be fanatastic.
>
>
>
> Best,
>
>
>
> Sebastian Weber
>
> Senior Statistical Methodologist, Novartis Oncology
>
> Biometrics and Data Management
>
> Novartis Pharma AG
>
> Postfach
>
> CH-4002 Basel
>
> SWITZERLAND
>
>
>
> Phone    +41 61 3246217
>
> Fax         +41 61 6961710
>
> sebasti...@novartis.com
>
> www.novartis.com
>
>
>
>


Bob Carpenter

unread,
Mar 4, 2015, 6:52:13 PM3/4/15
to stan...@googlegroups.com
Sure --- I could do that.

- Bob

> On Mar 5, 2015, at 9:32 AM, Ben Goodrich <goodri...@gmail.com> wrote:
>
> I think we agree that if we can get by without (or with fewer regexps), then that would be good. But they work at the moment, so that is good enough for rstan.

Agreed.

> The next question is whether you can somehow make the entirety of the transformed parameters block, the model block, etc. into a function defined in the functions block so that you can then call it exactly in R?

Maybe. They'd have to run on an instantiated model though
with initialized parameters, because

* transformed data depends on data
* transformed params depend on data, transformed data, parameters
* model depends on everything

- Bob

Jonah

unread,
Mar 4, 2015, 6:55:56 PM3/4/15
to stan...@googlegroups.com
That would be really cool.

Ben Goodrich

unread,
Mar 4, 2015, 7:12:24 PM3/4/15
to stan...@googlegroups.com
On Wednesday, March 4, 2015 at 6:52:13 PM UTC-5, Bob Carpenter wrote:
> The next question is whether you can somehow make the entirety of the transformed parameters block, the model block, etc. into a function defined in the functions block so that you can then call it exactly in R?

Maybe.  They'd have to run on an instantiated model though
with initialized parameters, because

  * transformed data depends on data
  * transformed params depend on data, transformed data, parameters
  * model depends on everything

But you pass the arguments to the user-defined functions back from the interface. So couldn't you just call your functions in the correct sequence?

Ben

Bob Carpenter

unread,
Mar 5, 2015, 2:05:13 AM3/5/15
to stan...@googlegroups.com
I'm afraid I don't understand what you mean. What signature(s)
do you need from C++?

- Bob
>

Ben Goodrich

unread,
Mar 5, 2015, 4:15:47 AM3/5/15
to stan...@googlegroups.com
On Thursday, March 5, 2015 at 2:05:13 AM UTC-5, Bob Carpenter wrote:
> But you pass the arguments to the user-defined functions back from the interface. So couldn't you just call your functions in the correct sequence? 

I'm afraid I don't understand what you mean.  What signature(s)
do you need from C++?

I guess it is possible to do the inputs automatically but I don't know how we could output multiple things without supporting tuples or doing pass by reference.
  • For a transformed data function, the inputs would be everything in data and the output would be everything in the transformed data block.
  • For a transformed parameters function, the inputs would be everything in data, transformed data, and parameters and the output would be everything in the transformed parameters block. 
  • For a model function, the inputs would be everything in data, transformed data, parameters, and transfomed parameters and void for output I guess.

Ben

Bob Carpenter

unread,
Mar 5, 2015, 9:38:14 AM3/5/15
to stan...@googlegroups.com
OK, I think I see waht you're asking for. Is it for
testing purposes? That'd make sense.

We could expose those functions in C++ using const refs
for the inputs and non-const refs for the outputs.

Is that enough to get them through to R?

- Bob
> --
> You received this message because you are subscribed to the Google Groups "stan development mailing list" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to stan-dev+u...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Allen B. Riddell

unread,
Mar 5, 2015, 9:42:30 AM3/5/15
to stan...@googlegroups.com
On 03/05, Ben Goodrich wrote:
> On Thursday, March 5, 2015 at 2:05:13 AM UTC-5, Bob Carpenter wrote:
> >
> > > But you pass the arguments to the user-defined functions back from the
> > interface. So couldn't you just call your functions in the correct
> > sequence?
> >
> > I'm afraid I don't understand what you mean. What signature(s)
> > do you need from C++?
> >
>
> I guess it is possible to do the inputs automatically but I don't know how
> we could output multiple things without supporting tuples or doing pass by
> reference.
>
> - For a transformed data function, the inputs would be everything in
> data and the output would be everything in the transformed data block.
> - For a transformed parameters function, the inputs would be everything
> in data, transformed data, and parameters and the output would be
> everything in the transformed parameters block.
> - For a model function, the inputs would be everything in data,
> transformed data, parameters, and transfomed parameters and void for output
> I guess.

This what I was thinking of when I suggested using JSON or Protocol
Buffers for input in this case as well. One could define a schema (and
serialization) for these inputs and then serialize them in R/Python,
passing them to Stan. They are small enough that we do not need to pass
by reference. We already have a "schema" for data and initialization
values (i.e., `var_context`) -- it's just currently treated as a special
case and has its own C++ class (but one could change this).

Ben Goodrich

unread,
Mar 5, 2015, 9:49:28 AM3/5/15
to stan...@googlegroups.com
On Thursday, March 5, 2015 at 9:38:14 AM UTC-5, Bob Carpenter wrote:
OK, I think I see waht you're asking for.  Is it for
testing purposes?  That'd make sense.

Yes, but also Sebastian and Aki have talked about using that for posterior predictive simulations, when they don't know everything that they want to simulate at build time.
 
We could expose those functions in C++ using const refs
for the inputs and non-const refs for the outputs.

Is that enough to get them through to R?

Not entirely sure. At least in the R case, there is another possibility of returning a list of outputs to R.

Ben

Bob Carpenter

unread,
Mar 5, 2015, 9:52:13 AM3/5/15
to stan...@googlegroups.com
I think I see. Are you imagining something like this:

void transformed_data(std::istream& data,
std::ostream& transformed_data);

So we'd read the data out of the input stream, run the data
transform, then write to the transformed data output stream.
All using JSON or protocol buffers?

And then for transformed data we could do this

void transformed_data(std::istream& data,
std::istream& parameters,
std::ostream& transformed_parameters);

Where it'd create the transformed data internally in this second call?
Or should it also have the transformed data as output? I wouldn't
want to allow transformed data as input to avoid inconsistencies.

That's definitely possible, but it'd take a while to refactor all
the code generation (which would probably be useful in and of itself).

- Bob


Allen B. Riddell

unread,
Mar 5, 2015, 9:58:09 AM3/5/15
to stan...@googlegroups.com
Yes, this is the idea. Only having to worry about those very simple
signatures on the Python/R side would make life much easier.

(And if one had already replaced `var_context` with something like this
-- well, we'd have the schema already -- or most of it.)
Reply all
Reply to author
Forward
0 new messages