User-defined constrained parameterizations - #967
Conversation
|
I renamed and tagged "WIP" because I want to go over and add a little more text background and also citations to the original threads that introduced these ideas. |
|
@WardBrian. This is now code complete, spell checked, and read over by me. Sorry, but I sort of got carried away, and as a result, it's a lot. |
WardBrian
left a comment
There was a problem hiding this comment.
Fun read. A bunch of comments below
There was a problem hiding this comment.
It might make sense to reassess https://mc-stan.org/docs/stan-users-guide/reparameterization.html#changes-of-variables and see if that should just be blended into this new chapter (or at least cross-referenced)
| real log_sigma; | ||
| } | ||
| transformed parameters { | ||
| real<lower=0> sigma = exp(log_sigma); |
There was a problem hiding this comment.
It might be worth explicitly (re)-stating that the lower= syntax only performs checks in blocks other than parameters
| if (cols(x) != N + binom(N, 2)) { | ||
| reject("cols(x) = ", cols(x), | ||
| "; but N + binom(N, 2) = ", N + binom(N, 2)); | ||
| } |
There was a problem hiding this comment.
binom is not a function; it's choose (which is correctly used in the parameters block below)
| functions { | ||
| matrix toeplitz_matrix(vector x, int M, int N) { | ||
| if (num_elements(x) != M + N - 1) { | ||
| reject("x must have M + N - 1 elements", |
There was a problem hiding this comment.
I think these rejects should be fatal_errors, since the sizes will never change there is no recovery possible
| ```stan | ||
| functions { | ||
| matrix symmetric_matrix(vector x, int N) { | ||
| matrix[N, N] y = lower_triangular_matrix(x, N); |
There was a problem hiding this comment.
| matrix[N, N] y = lower_triangular_matrix(x, N); | |
| matrix[N, N] y = lower_triangular_matrix(x, N); // defined as above |
Or any other indication that this is not a built-in and therefore this example is not fully self-contained
| ``` | ||
|
|
||
| The transform itself, which takes a vector $v$ of size $\binom{N}{2}$, | ||
| creates a skew-symmetric matrix (the `skew_symmetric` function is defined |
There was a problem hiding this comment.
| creates a skew-symmetric matrix (the `skew_symmetric` function is defined | |
| creates a skew-symmetric matrix (the `skew_symmetric_matrix` function is defined |
| * @return The `N` x `N` rotation matrix for which `v` is the basis | ||
| */ | ||
| matrix special_orthogonal_jacobian(vector v, int N) { | ||
| matrix[N, N] S = skew_symmetric(v, N); |
There was a problem hiding this comment.
| matrix[N, N] S = skew_symmetric(v, N); | |
| matrix[N, N] S = skew_symmetric_matrix(v, N); |
| { | ||
| tuple(matrix[D, D], matrix[D, D]) phi_Gamma | ||
| = stationary_var1_jacobian(raw, D); | ||
| phi = phi_Gamma.1; | ||
| Gamma = phi_Gamma.2; | ||
| } |
There was a problem hiding this comment.
We have tuple unpacking
| { | |
| tuple(matrix[D, D], matrix[D, D]) phi_Gamma | |
| = stationary_var1_jacobian(raw, D); | |
| phi = phi_Gamma.1; | |
| Gamma = phi_Gamma.2; | |
| } | |
| (phi, Gamma) = stationary_var1_jacobian(raw, D); |
| covariance `Gamma`. These need to be pulled out of the tuple. This | ||
| is one function returning a tuple because there is shared work. The | ||
| extra braces mean that `phi_Gamma` is no longer a top-level | ||
| `transformed parameters` variable and thus will not be saved in the | ||
| output (it would be redundant). The model could have been written | ||
| directly in terms of `phi_Gamma.1` and `phi_Gamma.2`, but it's easier | ||
| to follow as written. Note that `phi` is used in its transposed form |
There was a problem hiding this comment.
Which makes this explanation redundant
|
|
||
| ## Matrices matching known margins | ||
|
|
||
| Suppose $X$ is an $M \times N$ matrix $X$, the marginals of which are |
There was a problem hiding this comment.
| Suppose $X$ is an $M \times N$ matrix $X$, the marginals of which are | |
| Suppose $X$ is an $M \times N$ matrix, the marginals of which are |
SteveBronder
left a comment
There was a problem hiding this comment.
Just a few small comments on the intro
| $$ | ||
| p(\phi) | ||
| = p(\theta) | ||
| \cdot \left| \frac{\textrm{d}}{{\textrm d}\phi} \theta | ||
| \right|, | ||
| $$ |
There was a problem hiding this comment.
Should you define p before this equation?
| the natural logarithm. | ||
|
|
||
| The underlying sampler works with the unconstrained variable $\phi$ | ||
| that results from transforming the constrained parameter.. |
There was a problem hiding this comment.
| that results from transforming the constrained parameter.. | |
| that results from transforming the constrained parameter. |
| prior is uniform, but improper (i.e., the integral over its support | ||
| diverges). | ||
|
|
||
| The way this is done is by applying a change-of-variables correction. |
There was a problem hiding this comment.
I would avoid the use of this.
| The way this is done is by applying a change-of-variables correction. | |
| Enforcing a uniform implicit prior on constrained parameters requires applying a change-of-variables correction. |
| existing constrained types and transforms, as that will let Stan | ||
| automatically work out the change-of-variables. The more general | ||
| approach is to code a user-defined transform function and either | ||
| adjust for then change-of-variables or not, depending on the intended |
There was a problem hiding this comment.
| adjust for then change-of-variables or not, depending on the intended | |
| adjust for the change-of-variables or not, depending on the intended |
|
|
||
| The underlying sampler works with the unconstrained variable $\phi$ | ||
| that results from transforming the constrained parameter.. | ||
| In order for the distribution of $\theta$ to be uniform over $(0, |
There was a problem hiding this comment.
| In order for the distribution of $\theta$ to be uniform over $(0, | |
| In order for the distribution $p(\cdot)$ of $\theta$ to be uniform over $(0, |
| \begin{align} | ||
| p_\Phi(\phi) &= p_\Theta(\exp(\phi)) \cdot \left| \frac{\textrm{d}}{\textrm{d} \phi} \exp(\phi) \right| | ||
| \\[4pt] | ||
| &= p_\Theta(\exp(\phi)) \cdot \exp(\phi). |
There was a problem hiding this comment.
| &= p_\Theta(\exp(\phi)) \cdot \exp(\phi). | |
| &= p_\Theta(\exp(\phi)) \cdot \exp(\phi) |
| = p(\theta) | ||
| \cdot \left| \frac{\textrm{d}}{{\textrm d}\phi} \theta | ||
| \right|, | ||
| $$ |
There was a problem hiding this comment.
I don't love the substitution of
Though applying that through the line right after this I'm not totally understanding the equation. And what is
Wouldn't the last line reduce
Maybe I'm just not understanding something?
| be constant and thus should be included. | ||
|
|
||
|
|
||
| ## Specialized matrices | ||
|
|
||
| There are dozens if not hundreds of specialized matrix forms in use, | ||
| some of the most popular of which will be described in this section. | ||
|
|
There was a problem hiding this comment.
Kind of a 100 G-force of a transition from change of variables to bespoke matrices
This is a whole new chapter on user-defined constrained parameters with some challenging examples. I've tested that all the code actually works.
Submission Checklist
<<{ since VERSION }>>Summary
Copyright and Licensing
Please list the copyright holder for the work you are submitting (this will be you or your assignee, such as a university or company):
Simons Foundation
By submitting this pull request, the copyright holder is agreeing to license the submitted work under the following licenses: