Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ragged Structures #7

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open

Ragged Structures #7

wants to merge 3 commits into from

Conversation

bob-carpenter
Copy link
Collaborator

Ragged structures

@syclik
Copy link
Member

syclik commented Aug 7, 2019

@bob-carpenter, I just looked at the ragged structures (and not the closures) doc.

It looks great! Really great.

One question: will we continue to have arrays be declared the way it currently is? As a concrete example:

real x[2, 3];

and

real[{ {3}, {3} }] x;

should be equivalent. It seems like we'd want to keep the old syntax because it makes rectangular things pretty easy, but I can see how we might want to move the brackets before the variable instead of its current position.

@bob-carpenter
Copy link
Collaborator Author

bob-carpenter commented Aug 8, 2019

Yes, I still want to keep rectangular declarations for convenience. I want to deprecate

real x[2, 3];

and replace with

real[2, 3] x;

so that the character sequence for the type is contiguous, i.e., real[2, 3]. We already have that without the sizes for function argument types.

@jgabry
Copy link
Member

jgabry commented Sep 21, 2019

This looks great. Thanks for writing this up @bob-carpenter!

@bob-carpenter
Copy link
Collaborator Author

bob-carpenter commented Sep 21, 2019 via email

@wds15
Copy link
Contributor

wds15 commented Sep 21, 2019

This looks great. Two questions:

  • How do you envision to declare regular arrays of matrices/vectors in the future?
  • Will it be possible to declare a ragged array dimensions using another ragged array of ints?

Sebastian

@bob-carpenter bob-carpenter changed the title Ragged Ragged Structures May 23, 2020
Copy link
Member

@rok-cesnovar rok-cesnovar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of questions and suggestions to update the doc now that we support the array[] T syntax.

example is:

```
real[{3, 4}] x = {{a, b, c}, {d, e, f, g}};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
real[{3, 4}] x = {{a, b, c}, {d, e, f, g}};
array[{3, 4}] real x = {{a, b, c}, {d, e, f, g}};

We write the unsized type of `x` the same way as for rectangular two-dimensional arrays,

```
x : real[ , ]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
x : real[ , ]
x : array[ , ] T

```

Declarations for ragged arrays are made up of the sizes of their
elements. Declaring `x` of type and size `real[{3, 4}]` declares `x`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
elements. Declaring `x` of type and size `real[{3, 4}]` declares `x`
elements. Declaring `x` of type and size `array[{3, 4}] real` declares `x`

element in the sizing is the sizing of a ragged two-dimensional array.

```
real[{ {2, 3}, { 1, 2, 3 } }] y
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
real[{ {2, 3}, { 1, 2, 3 } }] y
array[{ {2, 3}, { 1, 2, 3 } }] real y

y[2] == {{h}, {i, j}, {k, l, m}}
```

The type of both `y[1]` and `y[2]` is `real[, ]`, the type of a
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The type of both `y[1]` and `y[2]` is `real[, ]`, the type of a
The type of both `y[1]` and `y[2]` is `array[, ] real`, the type of a

probabilities, we can use

```
real<lower = 0, upper = 1>[{3, 4}] x = {{a, b, c}, {d, e, f, g}};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
real<lower = 0, upper = 1>[{3, 4}] x = {{a, b, c}, {d, e, f, g}};
array[{3,4}] real<lower = 0, upper = 1> x = {{a, b, c}, {d, e, f, g}};

We can declare a ragged array of simplexes as

```
simplex[{3, 2, 2}] theta
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
simplex[{3, 2, 2}] theta
array[3] simplex[{3, 2, 2}] theta

Ragged containers will play nicely with unsized local variables and
function arguments.

This proposal as written depends on allowing type declarations like:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was implemented in Stan 2.25 where we now have array[...] real x, array[...] vector[N] a, etc. so we can remove the text below.

Comment on lines +253 to +256
cov_matrix[2][3] x
= { [[1, 0], [0, 1]],
[[3.1, -0.2], [-0.2, 3.1]],
[[15.2, 0.1], [0.1, 15.2]] };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
cov_matrix[2][3] x
= { [[1, 0], [0, 1]],
[[3.1, -0.2], [-0.2, 3.1]],
[[15.2, 0.1], [0.1, 15.2]] };
array[3] cov_matrix[2] x
= { [[1, 0], [0, 1]],
[[3.1, -0.2], [-0.2, 3.1]],
[[15.2, 0.1], [0.1, 15.2]] };

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question:

Do we also want to support

array[2] cov_matrix[{2, 2, 3}] x
  = { [[1, 0], [0, 1]],
      [[3.1, -0.2], [-0.2, 3.1]],
      [[15.2, 0.1, 0.1], [0.1, 15.2, 0.1], [0.1, 0.1, 15.2]] };

@@ -0,0 +1,608 @@
- *Feature Name:* closures-fun-types
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This wasnt intended for this PR I guess?

@rok-cesnovar
Copy link
Member

I also dont see any mention if Stan Math functions should support ragged arrays?
For example

array[{3, 4}] real x = {{a, b, c}, {d, e, f, g}};
array[{3, 4}] real y = sin(x);

Should this work? If yes then I think adding tests for this in Stan Math should be mentioned somewhere in the docs.

@bob-carpenter
Copy link
Collaborator Author

I also dont see any mention if Stan Math functions should support ragged arrays?

I think that's an independent question. It'd be great if we could extend unary function vectorization to them. I would not try to do arithmetic, but reductions like sum() might make sense. The trickier thing will be structured operations like append_row, which should work, but append_col, which wouldn't make sense.

@rok-cesnovar
Copy link
Member

Ok, that does make stuff a bit easier then for Stan Math, but a bit more for stanc as we need to keep track at whats ragged and whats not. Thanks.

@WardBrian
Copy link
Member

@bob-carpenter and I just discussed this and I'd like to suggest an alternate syntax that makes the dimensionality of the final array much clearer. Based on how we do function argument typing, I think we could have a syntax like:

array[3] int sizes = {3, 2, 3};

array[ , sizes] real = ...;

We could even optionally allow array[3, sizes], with the 3 obviously being redundant.

Why? Because if I show you, array[sizes], you have no idea how many dimensions this array has without chasing down where sizes comes from, which might not always be right there. By contrast, array[,sizes] tells you immediately that the array has 2 dimensions but is ragged. In general this would also work for things like array[,,,sizes_3d] real four_D_ragged;

@bob-carpenter
Copy link
Collaborator Author

I'd like to change the spec to work like @WardBrian suggests.

@nhuurre
Copy link

nhuurre commented Sep 9, 2021

@WardBrian I like that idea. It also clarifies the situation with array[] vector[sizes] (array is mandatory)

And since we're likely to get tuples before ragged arrays I suggest matrix dimensions are given as 2-tuples and not two-element arrays.

-matrix[{ {2, 3}, {3, 2}, {1, 2} }] v
+matrix[{ (2, 3), (3, 2), (1, 2) }] v
 = { [[a, b, c], [d, e, f]],
     [[g, h], [i, j], [k, l]],
     [[m, n]] };

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants