_lupdf functions - where/how to doc them?

We are exposing the unnormalized form of distributions for the 2.25 version (see Stan 2.25 release candidate! for more info). I am writing some basic information on that but need some guidance, help.

For now, two questions:

Cc: @mitzimorris @bbbales2

by docs you mean the Functions Reference Manual?

I guess. I am not sure actually where the best place in the Stan documentation world would be.

I think you’re right, that it goes in the Stan Reference manual - looking at this chapter - https://mc-stan.org/docs/2_24/reference-manual/sampling-statements-section.html

but we need more elsewhere that links into this chapter - I’ll take a look at the User’s Guide.

we should skim out the relevant parts of discussions referenced here: Request for final feedback: User controlled unnormalized (propto) distribution syntax

and add a chapter on use cases for unnormalized vs. normalized distribution

I think we add to the Sampling Notiation section here: https://mc-stan.org/docs/2_24/functions-reference/conventions-for-probability-functions.html

(And move that whole section out of discrete distributions – it also applies to continuous distributions)


Yeah, changes to https://mc-stan.org/docs/2_24/reference-manual/sampling-statements-section.html#log-probability-increment-vs.-sampling-statement make sense as well.


I went looking for docs on how to do a user-specified distribution today and this was all I found which seemed rather lacking: https://mc-stan.org/docs/2_24/stan-users-guide/examples.html

Is this doc’ed anywhere else? Separately from this I think we need more docs.


Does defining a user defined myprob_lpdf also define a myprob_lupdf?


do we need to add the _lupdf form to docs for all distributions

I think so, unfortunately lol. If people search for normal_lupdf they should end up on the normal_lpdf page. I guess it can all be boilerplate copy-paste “normal_lpdf but dropping normalization constants” kinda text.


I am updating the reduce_sum tutorial now to use them.

1 Like

Also thanks for looking at this.

If it helps I can take a pass at writing the sampling statement section or _lupdf ing normal or something simple so we can decide how to do the rest.

Does reduce_sum support _lupdfs? I thought that was still a work in progress?

Oh, I just assumed. Lemme go find out.

how many functions are gonna get changed here? wondering if we could do something for SEO and indexing w/out having to go to wholesale duplication of entries.

Agreed. Thanks for the feedback!

Can’t promise a user guide chapter till the release but will have time to make a PR for the function reference definitely.

Yes, writing myprob_lupdf is not allowed actually. Those are the type of thing that will be shown in examples.

Fair. And a great point.

1 Like

All lpdfs/lpmfs get the lupdf/lupmf form that is equal to the use of ~.

Ah yes, it does not. This one slipped through. Thanks for bringing that up. Will fix this today.

I got an error

Functions with names ending in _lupdf and _lupmf can only be used in the model block or user-defined functions with names ending in _lpdf, _lpmf or _lp.

Which seems like a good error message.

Then I changed the reducer function name to _lpmf and it compiled and ran.

Should the recommendation for now should be for users to call their reducer functions _lpxf s so they can use _lupmf/_lupdf, or did I get an unintended behavior?

You can not use _lupdf/_lupmf it the UDF is not _lpdf/_lpmf. This will be a requirement for the foreseeable future because of the way transformed parameters are done.

This is the example that will hopefully explain how all this will work.

functions {
    real foo_lpdf(real y, real x) {
        return normal_lupdf(y| x, 1);
    }
    real goo_lpdf(real y, real x) {
        return normal_lpdf(y| x, 1);
    }
}
parameters {
    real y;
}
model{
    target += foo_lpdf(y| x); // normal_lpdf would be normalized
    target += foo_lupdf(y| x); // normal_lpdf would be unnormalized
    target += goo_lpdf(y| x); // normal_lpdf would be normalized
    target += goo_lupdf(y| x); // normal_lpdf would be normalized
}

So you need the lupdf in the UDF + call the UDF with lupdf. I didnt push the stanc3 PR for a long time because this is not ideal, but there is just no other way.

Will separate the reduce_sum lupdf/lupmf discussion outside of this thread.

Oh I see. And this compiles and runs because reduce_sum is using the template signature without the propto, which sets propto = FALSE, which passes on to everything else (edit: I looked at the generated code – not extrapolating from what you said here). So reduce_sum doesn’t do lupmf yet effectively, though it can compile in cases. Works for meee

Lets continue that discussion at https://github.com/stan-dev/stanc3/issues/727

@nhuurre please take a look if you have a few min.

agreed - Functions Reference Manual needs to add _lupdf to all distributions.
I think it should be possible to write a Python munge script - more fun than doing it by hand.

@jonah was asking about the docs for this today at the Stan meeting.

For a basic sampling statement, we’ll have:

y ~ normal(0, 1);
target += normal_lpdf(y | 0, 1);
target += normal_lupdf(y | 0, 1);

And then we’ll have the implications for user-defined functions.

I think even separately from the user-defined functions Jonah wanted to talk about how we are gonna put the info out there in a way that it gets understood what’s happening.

Edit: Oh yeah here’s the function reference doc: https://github.com/stan-dev/docs/pull/277, which is gonna be lots of boring stuff

This is what is in the user’s guide and I think that could use a revamp: https://mc-stan.org/docs/2_24/stan-users-guide/examples.html

2 Likes

Yeah I just wanted to make sure that when we add new things like this that there’s a way for people to understand when they should use them. For example, I think the useful offset and multiplier functionality is barely used by anyone because there’s no case study or other user friendly introductions to using it. The same thing could easily happen with this. To be clear, I’m not expecting anyone in particular to write the case studies or blaming anyone for the lack of them, I just know that people are working hard implementing this stuff so I want to make sure users actually know how and when to use the great stuff that’s getting implemented!

1 Like