changed Stan interval syntax

17 views
Skip to first unread message

Bob Carpenter

unread,
Aug 7, 2012, 3:26:15 PM8/7/12
to stan...@googlegroups.com
I changed Stan's syntax for intervals so that they match
mathematical notation (sort of -- open intervals in theory
become closed due to floating point rounding).

Variable bounds which used to look like

BAD: real(0,1) theta;

now look like:

GOOD: real[0,1] theta;

For consistency, dimension declarations for vectors/matrices
which used to look like:

BAD: vector(3) x[2,4];

now look like:

GOOD: vector[3] x[2,4];

Also for consistency, truncation, which used to look like

BAD: y ~ normal(0,1) T(0,);

now looks like:

GOOD: y ~ normal(0,1) T[0,];

I fixed the test models, but the BUGS models need to be updated,
too (I just edited out the tests for them in test/gm/parser_test.cpp).
So while the unit tests pass, the model tests will fail.

I'll fix the models and add their tests back into our unit
later tonight. I'll also patch the manual and post a new
version on the site -- I just copy-edited it all and added
some new material (nothing about RStan yet).

- Bob

Andrew Gelman

unread,
Aug 7, 2012, 3:31:37 PM8/7/12
to stan...@googlegroups.com
Thanks!

Marcus Brubaker

unread,
Aug 7, 2012, 3:45:25 PM8/7/12
to stan...@googlegroups.com
On Tue, Aug 7, 2012 at 3:26 PM, Bob Carpenter <ca...@alias-i.com> wrote:
I changed Stan's syntax for intervals so that they match
mathematical notation (sort of -- open intervals in theory
become closed due to floating point rounding).

For consistency, dimension declarations for vectors/matrices
which used to look like:

  BAD:  vector(3) x[2,4];

now look like:

  GOOD:  vector[3] x[2,4];


I wasn't planning on mentioning this as it's low priority, but since this change of syntax may impact it I'll at least ask.

Would it be hard to allow for vectors/matrices of bound constrained variables?  For instance, a vector or matrix of [0,1] or [0,] variables can be quite useful in multivariate timeseries models.  Right now I'm doing the transforms using unconstrained vectors/matrices and then defining transformed parameters manually.  (I know I could do real[0,1] x[4], but that ends up using a std::vector instead of an Eigen vector which impacts what can be done with the variable.)  However if we come up with a better way of handling bound constraints (eg, bouncing) the above approach no longer works.

It would be really nice to somehow allow this in the syntax and the above change in notation for vector sizes may make this hard or require another change of notation down the line if it's ever implemented.

Cheers,
Marcus

Jiqiang Guo

unread,
Aug 7, 2012, 3:53:32 PM8/7/12
to stan...@googlegroups.com
Thanks.  I think I just need to change a few examples that I am using. 
I could change the bugs example as well, I guess, manually one by one.  
But if you could have them changed automatically, please do it. 

--
Jiqiang 

On Tue, Aug 7, 2012 at 3:26 PM, Bob Carpenter <ca...@alias-i.com> wrote:
nothing about RStan yet

Bob Carpenter

unread,
Aug 7, 2012, 7:59:01 PM8/7/12
to stan...@googlegroups.com


On 8/7/12 3:45 PM, Marcus Brubaker wrote:

> Would it be hard to allow for vectors/matrices of bound constrained variables?

I don't think it'll be that hard to implement (maybe a couple
of days including tests). And we definitely want to maintain
backward compatibility later for models.

And I think it's a good idea.

Right now, we allow unconstrained vector/matrix declarations

matrix[5,4] x; // 5x4-matrix
vector[4] y; // 4-vector
vector[4] z[3,2]; // 3x2 array of 4-vectors

and constrained real declarations:

real[0,] a; // positive real
real[0,] b[5,6,7]; // 5 x 6 x 7 array of positive reals

I'm not sure how to mix the syntax. Here are some
ways we might write a 3-vector of positive values and
of values in [-1,1]:

Option 1.

vector[0, : 3] v; // 3-vector of positive values
vector[-1, 1 : 3] rho; // 3-vector of values in [-1,1]

YUCK!


Option 2.

vector[0,][3] v;
vector[-1, 1][3] rho;

YUCK! And a pain to parse because of lookahead issues.
As Marcus pointed out, there are parsing ramifications.

Option 3.

vector[0, ](3) v;
vector[-1, 1](3) rho;

This would be easy to code and most like what
we currently have (if I change vector and matrix
dimension declarations back to parens).

Option 4.

vector[0, ] v[3];
vector[-1, 1] rho[3];

Option 4 moves all vector and matrix dimensions next
to the variable, so that what now looks like:

matrix[5,4] x; // 5x4-matrix
vector[4] y; // 4-vector
vector[4] z[3,2]; // 3x2 array of 4-vectors

would look like:

matrix x[5,4];
vector y[4];
vector z[3,2,4];

I think it's a tossup between 3 and 4 as to which
most clearly indicates usage. 3 makes it very clear
which dimension belongs to the vector, whereas 4 shows
you the index ranges for the use of the variables.

In retrospect, we probably should've built our own
multidimensional array objects and then used an Eigen::Map
to read them as matrices or vectors where necessary.
This whole matrix vs. 2D array thing is likely to confuse
people used to something like R or BUGS.

- Bob

Marcus Brubaker

unread,
Aug 7, 2012, 8:34:23 PM8/7/12
to stan...@googlegroups.com
This syntactic issue is precisely why I mentioned it now.  If we're going to have to touch every model lets at least make sure that the syntax would allow this feature in the future.

One option (call it option 5) would be do so something C++-like:

matrix<3,4,real[0,1]> x;

This makes some measure of sense since a 3x4 matrix is a type itself which is, in this case, made up of real[0,1] variables.  A multidim vector of matrices (ie a std::vector of Eigen::Matrix) can be declared as

matrix<3,4,real[0,1]> x[5];

It could also assume that the type is always unconstrained real, making the normal syntax something like:

matrix<3,4> x;

which isn't terrible.

The one down side of this is it implies a level of flexibility that seems unlikely to be used (e.g., replacing real with something else) but I suppose that's not the worst price to pay for clarity.

Alternatively, a more palatable variation of your Option 3 might be:

matrix<3,4>[0,1] x;

I'll think on it and see if I come up with anything else...

Cheers,
Marcus

Bob Carpenter

unread,
Aug 7, 2012, 9:32:30 PM8/7/12
to stan...@googlegroups.com
Actually, the more I think about it, the more I like
the reverse of option 2 or 3,

Option 5.

vector[3][0,] v;
vector[3][-1, 1] rho;


Option 6.

vector(3)[0,1] v;
vector(3)[-1,1] rho;

It somehow seems easier to read with parens and brackets,
but then it means that you have to remember which goes
where.

Somehow prefixes look really goofy even though that's
how we name them and write them in papers:

Option 7.

(4)simplex theta;
(3)vector[0,1] v;
(4,2)matrix[-1,1] rho;

- Bob

Bob Carpenter

unread,
Aug 7, 2012, 9:54:14 PM8/7/12
to stan...@googlegroups.com
Everyone (especially Andrew):

I'm now waiting for feedback on how to proceed on the syntax
for matrix/vector dimensions and constraints. There's a list
of options at the bottom of the message, though I'm open to
other suggestions.

Marcus is absolutely right that we want to make a choice now
that we won't have to change later.

On 8/7/12 8:34 PM, Marcus Brubaker wrote:
> This syntactic issue is precisely why I mentioned it now.
> If we're going to have to touch every model lets at least
> make sure that the syntax would allow this feature in the future.

That's exactly why I stopped mid-model-munging!

I'll wait until Andrew has a chance to weigh in at least.

> One option (call it option 5) would be do so something C++-like:
>
> matrix<3,4,real[0,1]> x;
...

I do like the explicitness -- you can pretty much figure
out what it does by looking at it.

A multidim vector of matrices (ie a std::vector of Eigen::Matrix) can be declared as
>
> matrix<3,4,real[0,1]> x[5];
...

That's where we're at now, but with matrix[3,4].

> The one down side of this is it implies a level of flexibility that seems unlikely to be used (e.g., replacing real with
> something else) but I suppose that's not the worst price to pay for clarity.

Agreed. It's also very clunky and I don't like the mixing
of the indices and type. Another possibility would be

matrix<real[0,1]>[3,4] x;

Then the unconstrained form would be:

matrix<real>[3,4] x;

and that could be simplified to be written just as:

matrix[3,4] x;

> Alternatively, a more palatable variation of your Option 3 might be:
>
> matrix<3,4>[0,1] x;

Right -- our messages crossed on that one.

Another option would be to have a different syntax, such as

bounded_matrix[0,1][3,4];

We need to decide so I can carry on refactoring the
models!. Let me renumber the standing proposals:

1. a. matrix<3,4,real[0,1]> x;
b. matrix<real[0,1]>[3,4] x;

2. a. matrix<3,4>[0,1] x;
b. matrix(3,4)[0,1] x;
c. matrix[3,4][0,1] x;

3. a. matrix_bounded[0,1]<3,4>;
b. matrix_bounded[0,1](3,4);
c. matrix_bounded[0,1][3,4];

Now that I finished the message, I'm leaning toward 1.b. myself
as a first choice, and 3c. as a second.

- Bob

Michael Betancourt

unread,
Aug 7, 2012, 10:05:01 PM8/7/12
to stan...@googlegroups.com
1 (a or b) is the easiest to understand from my perspective. The explicit declaration of "real" to distinguish between bounds and sizes seems like the most natural for someone using the language for the first time -- 3c is just asking for a new user to mix up the indices and start sampling a scalar with support between 3 and 4.

Jiqiang Guo

unread,
Aug 7, 2012, 10:27:19 PM8/7/12
to stan...@googlegroups.com
Yeah. In 1b, bounds go with just real or supposedly int, which makes it easy to remember.
Am I repeating what has been said:)?

Jiqiang

Bob Carpenter

unread,
Aug 8, 2012, 12:26:54 AM8/8/12
to stan...@googlegroups.com


On 8/7/12 10:27 PM, Jiqiang Guo wrote:
> Yeah. In 1b, bounds go with just real or supposedly int, which makes it easy to remember.
> Am I repeating what has been said:)?

No -- it's really a matter of preference here.

But Michael's right (in the previous e-mail)
in that any of 2 or 3 is just asking for arguments
to get reversed. It's always a problem with functions
w/o named arguments with repeated types.

I'll patch everything like I said last time and then
we can go with 1b. when the time comes.

- Bob

Andrew Gelman

unread,
Aug 8, 2012, 10:42:56 AM8/8/12
to stan...@googlegroups.com
Hi all. I defer to the rest of you on this one. Sometimes my instincts aren't so good on these things. Here are my thoughts, but again I'm not the expert on designing software. Remember the mess I made of R2winbugs…

- I agree with Bob that we should go with all parentheses or all brackets. Mixing parens and brackets is a recipe for disaster. I think it's ok to go either way. I don't even feel so stronly about closed vs open brackets, although as you know from my earlier conversation I liked the closed brackets for discrete integer variables that go from 0 to 1 or from -1 to 1 or from 1 to 10 or whatever.

For similar reasons, I worry that angle brackets will be confusing. Again, one more thing for the user to remember: "use square brackets everywhere, except for bounds where you need angle brackets." I prefer the R-style convention of indicating arguments via names rather than punctuation.

- Possibly because of my Fortran backrgound, I'm not thrilled with the "matrix" type. My inclination is to have scalars and arrays, which can be 1-way, 2-way, 3-way, etc. I recognize that certain functions will work in certain ways with 1-way and 2-way arrays (inner product, outer product, matrix multiply, transpose, matrix "solve", probably some other things), but I assume the parser can figure that out since everything is declared anyway.

- Thus, I prefer something like this:
real[3,4] x;
or
real[3,4][floor=0,ceiling=1] x;
or
real[3,4][bounds=[0,]] x;
or
something clever that someone comes up with,

rather than

matrix[3,4] x;
or
matrix<real[0,1]>[3,4] x;
etc.

To me, it just sems redundant to label variables as scalar or vector or matrix or array. I like the parallelism of:
real x;
real[3] x;
real[3,4] x;
real[3,10,4] x;
etc.

I do recognize that then this makes it trickier to add bounds, but I think that's ok. Bounds are special and I don't mind using somewhat of a clunky notation for them.

See you
A
Reply all
Reply to author
Forward
0 new messages