Am I creating distributions wrong in Turing?

Hello, I’m using Turing and having some issues. To reproduce this, I’ll provide about as simple of an example as I can generate. Let’s take the basic example from the docs (Probabilistic Programming in Thirty Seconds) and modify it only slightly by including a user-generated distribution, with the exact specifications from the docs (Advanced Usage). Then, all that needs to be done is to include these lines of code (defining the struct, and the two functions) and to modify the model declaration so that p ~ Beta(1,1) changes to p ~ CustomUniform(). When I run this code, I get the following error:

LoadError: MethodError: no method matching iterate(::CustomUniform)

What I know so far (disclaimer: I’m fairly new to Julia with more experience in some other languages) is that iterate is not meant to be defined for a distribution, but may be useful for something like an AbstractRNG. Is there a reason I’m getting this error? Maybe something I’ve typed in wrong? I can copy and paste my roughly 40 lines of code but they are quite literally copied and pasted from the docs… anyways, I’d really appreciate any feedback!

1 Like

What versions of libraries do you have? If they’re old, that could explain it.

According to Pkg.status I have Turing 0.13.0 installed. I do see that the latest release is 0.15.18, so this may be the underlying issue. Interestingly though, when I run ] update I don’t get a newer version. Is that maybe something wrong with what’s installed on my device or should there be another way I am updating the packages?

Might not be compatible with your Julia version. Are you on 1.3 or newer?

Try ] add Turing@0.15 to see what’s preventing the update

I’m using version 1.6. When I run that line of code it returns an error: ERROR: Could not determine command.

What exactly did you do to get that error? Can you post your REPL input and output?

OK, I figured out the versioning issue. I had another library (that I wasn’t using but was installed) that depended on an older version of Distributions, and Turing couldn’t install a new version without a newer version of Distributions. Removing the other library (I don’t need it anyway) allows me to install Turing version 15.18.

That being said, the code still does not work. Maybe there is another versioning issue? I tried ] update in the REPL in case another update was missing and it still does not work. Thoughts?

Alright, I think I’ve figured it out! I went and read more about the iterate function and found that it is called inside the maximum, mean, std, and other functions of various types. When I called maximum on my made-up distribution, the same error about not having an iterate function popped up. When I manually defined maximum and minimum as functions for my distribution type, the code now runs without errors (and appears to work properly). As a result of this, if anyone involved in the development of Turing is reading this, I would advise a modification of the docs (particularly the section on using a user-generated distribution) to indicate that in addition to rand and logpdf, maximum and minimum may also be required.

PS - if you would like, I have found that making your own iterate function also works if this is sensible for your distribution (e.g., if you have a discrete distribution maybe this makes sense). However, this is much slower than just supplying values for maximum and minimum.

2 Likes

Hey! So it’s technically already there, though given this issue I agree that it’s not clear enough and def needs improvement!

I’m referring to “Step 3” in the process of creating custom distribution for use in Turing.jl:
https://turing.ml/dev/docs/using-turing/advanced#3-define-helper-functions

In particular, it says:

Alternatively, for UnivariateDistribution we can define the minimum and maximum of the distribution

Distributions.minimum(d::CustomUniform) = 0.
Distributions.maximum(d::CustomUniform) = 1.

Hope that clears things up:)

1 Like

I see! That clears it up. Thanks so much!

2 Likes

I made this video recently on adding a distribution to Distributions.jl and then seeing if it works in Turing. I too got the iterate error, but find that implementing all the eight methods in the video makes it go away. Hope you like it :slight_smile:

3 Likes