Skip to content

Commit c89010b

Browse files
committed
Basic docs for jacobian +=
1 parent 17d4097 commit c89010b

File tree

7 files changed

+82
-9
lines changed

7 files changed

+82
-9
lines changed

src/reference-manual/deprecations.qmd

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,14 @@ would use Cholesky factors rather than full correlation matrix types.
5252

5353
*Scheduled Removal*: Stan 3.0 or later.
5454

55+
## Use of `_lp` functions in `transformed parameters`
56+
57+
*Deprecated*: Using [functions that end in `_lp`](user-functions.qmd#log-probability-access-in-functions)
58+
in the `transformed parameters` block.
59+
60+
*Replacement*: Use `_jacobian` functions and the `jacobian +=` statement instead. These allow for change-of-variable
61+
adjustments which can be conditionally enabled by Stan's algorithms.
62+
5563
## New Keywords
5664

5765
*Deprecated*: The following identifiers will become reserved in the language in the specified version.

src/reference-manual/grammar.txt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@
2424

2525
<identifier> ::= IDENTIFIER
2626
| TRUNCATE
27-
| <future_keyword>
28-
29-
<future_keyword> ::= JACOBIAN
3027

3128
<decl_identifier> ::= <identifier>
3229
| <reserved_word>
@@ -86,6 +83,7 @@
8683

8784
<unsized_type> ::= ARRAY <unsized_dims> <basic_type>
8885
| ARRAY <unsized_dims> <unsized_tuple_type>
86+
| <basic_type> <unsized_dims>
8987
| <basic_type>
9088
| <unsized_tuple_type>
9189

@@ -115,7 +113,9 @@
115113
<id_and_optional_assignment(rhs,
116114
<decl_identifier_after_comma>)>)*
117115

118-
<decl(type_rule, rhs)> ::= <higher_type(type_rule)>
116+
<decl(type_rule, rhs)> ::= type_rule <decl_identifier> LBRACK <expression>
117+
(COMMA <expression>)* RBRACK
118+
| <higher_type(type_rule)>
119119
<id_and_optional_assignment(rhs,
120120
<decl_identifier>)>
121121
[<remaining_declarations(rhs)>] SEMICOLON
@@ -272,6 +272,7 @@
272272
| <expression> TILDE <identifier> LPAREN [<expression>
273273
(COMMA <expression>)*] RPAREN [<truncation>] SEMICOLON
274274
| TARGET PLUSASSIGN <expression> SEMICOLON
275+
| JACOBIAN PLUSASSIGN <expression> SEMICOLON
275276
| BREAK SEMICOLON
276277
| CONTINUE SEMICOLON
277278
| PRINT LPAREN <printables> RPAREN SEMICOLON

src/reference-manual/statements.qmd

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,38 @@ including arrays of vectors and matrices. For container arguments,
361361
their sum will be added to the total log density.
362362

363363

364+
## Increment log density with a change of variables adjustment
365+
366+
367+
A variant of the `target +=` statement described above is the
368+
`jacobian +=` statement. This can be used in the transformed parameters block
369+
or in functions ending with `_jacobian` to mimic the log Jacobian
370+
adjustments accrued by built-in variable transforms.
371+
372+
Similarly to those implemented for the built-in transforms, these Jacobian adjustment
373+
may be skipped for optimization.
374+
375+
For example, here is a program which re-creates the existing
376+
[`<upper=x>` transform](transforms.qmd#upper-bounded-scalar) on real numbers:
377+
378+
```stan
379+
functions {
380+
real upper_bound_jacobian(real x, real ub) {
381+
jacobian += x;
382+
return ub - exp(x);
383+
}
384+
}
385+
data {
386+
real ub;
387+
}
388+
parameters {
389+
real b_raw;
390+
}
391+
transformed parameters {
392+
real b = upper_bound_jacobian(b_raw, ub);
393+
}
394+
```
395+
364396
### Accessing the log density {-}
365397

366398
To access accumulated log density up to the current execution point,

src/reference-manual/syntax.qmd

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ The raw output is available [here](https://raw.githubusercontent.com/stan-dev/do
300300
| <expression> TILDE <identifier> LPAREN [<expression>
301301
(COMMA <expression>)*] RPAREN [<truncation>] SEMICOLON
302302
| TARGET PLUSASSIGN <expression> SEMICOLON
303+
| JACOBIAN PLUSASSIGN <expression> SEMICOLON
303304
| BREAK SEMICOLON
304305
| CONTINUE SEMICOLON
305306
| PRINT LPAREN <printables> RPAREN SEMICOLON
@@ -476,6 +477,9 @@ of other user defined functions which end in `_lp`.
476477
Sampling statements (using `~`) can only be used in the `model` block or in the
477478
bodies of user-defined functions which end in `_lp`.
478479

480+
`jacobian +=` statements can only be used inside of the `transformed parameters` block
481+
or in functions that end with `_jacobian`.
482+
479483
### Probability function naming {-}
480484

481485
A probability function literal must have one of the following

src/stan-users-guide/reparameterization.qmd

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -441,10 +441,10 @@ parameters {
441441
transformed parameters {
442442
real<lower=0> y;
443443
y = 1 / y_inv; // change variables
444+
jacobian += -2 * log(y_inv); // Jacobian adjustment
444445
}
445446
model {
446447
y ~ gamma(2,4);
447-
target += -2 * log(y_inv); // Jacobian adjustment;
448448
}
449449
```
450450

@@ -476,7 +476,7 @@ transformed parameters {
476476
matrix[K, K] J; // Jacobian matrix of transform
477477
// ... compute v as a function of u ...
478478
// ... compute J[m, n] = d.v[m] / d.u[n] ...
479-
target += log(abs(determinant(J)));
479+
jacobian += log(abs(determinant(J)));
480480
// ...
481481
}
482482
model {
@@ -505,7 +505,7 @@ transformed parameters {
505505
vector[K] J_diag; // diagonals of Jacobian matrix
506506
// ...
507507
// ... compute J[k, k] = d.v[k] / d.u[k] ...
508-
target += sum(log(J_diag));
508+
jacobian += sum(log(J_diag));
509509
// ...
510510
}
511511
```
@@ -596,10 +596,10 @@ parameters {
596596
}
597597
transformed parameters {
598598
vector[N] alpha = L + exp(alpha_raw);
599+
jacobian += sum(alpha_raw); // log Jacobian
599600
// ...
600601
}
601602
model {
602-
target += sum(alpha_raw); // log Jacobian
603603
// ...
604604
}
605605
```

src/stan-users-guide/user-functions.qmd

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,32 @@ transformed parameters {
287287
}
288288
```
289289

290+
## Functions implementing change-of-variable adjustments
291+
292+
Functions whose names end in `_jacobian` can use the
293+
`jacobian +=` statement. This can be used to implement a custom
294+
change of variables for arbitrary parameters.
295+
296+
For example, here is a program which re-creates the built-in
297+
`<upper=x>` transform on real numbers:
298+
299+
```stan
300+
functions {
301+
real upper_bound_jacobian(real x, real ub) {
302+
jacobian += x;
303+
return ub - exp(x);
304+
}
305+
}
306+
data {
307+
real ub;
308+
}
309+
parameters {
310+
real b_raw;
311+
}
312+
transformed parameters {
313+
real b = upper_bound_jacobian(b_raw, ub);
314+
}
315+
```
290316

291317
## Functions acting as random number generators
292318

src/stan-users-guide/using-stanc.qmd

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -647,7 +647,9 @@ Warning:
647647
Left-hand side of distribution statement (~) may contain a non-linear
648648
transform of a parameter or local variable. If it does, you need
649649
to include a target += statement with the log absolute determinant
650-
of the Jacobian of the transform.
650+
of the Jacobian of the transform. You could also consider defining
651+
a transformed parameter and using jacobian += in the transformed
652+
parameters block.
651653
```
652654

653655
### Pedantic mode limitations {-}

0 commit comments

Comments
 (0)