-
-
Notifications
You must be signed in to change notification settings - Fork 30
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
use comprehensions instead of For(1:N)
?
#14
Comments
I would be tempted to use broadcasting for this, with the advantage of conveying paramter values and shape information at same time. x ~ Cauchy.(zeros(N), 100)
y ~ Normal.(x, (1.0:5.0)') # N × 5 matrix of normal variables
z ~ Poisson.(y) |
From Slack:
Regarding @hessammehr: broadcast syntax does seem very nice for this. Is there some reason that an array of distributions can't be the actual representation of a multidimensional conditionally independent distribution? That would make |
I guess the answer may be that |
@StefanKarpinski My question as well, since in a way broadcast already works nicely with a lot of things θ = (zeros(5), abs.(rand(3))')
d = LogNormal.(θ)
rand.(d)
logpdf.(d, ans) |
@StefanKarpinski Thank you for opening this issue. Great to see others getting involved. @hessammehr Really good point about broadcasting. Yes, that should work as-is. As it stands, anything on the right of In general, I could imagine having This is especially the case when we get to composability: If we have m1 = @model begin
mu ~ someDist
sigma ~ anotherDist
end (no arguments or observes), then this will be usable from another model as m2 = @model begin
a ~ m1
y ~ Normal(a.mu, a.sigma)
end |
Oh wait, I just realized the broadcasting trick hits the same problem. Here's an example: julia> Normal.(zeros(3))
3-element Array{Normal{Float64},1}:
Normal{Float64}(μ=0.0, σ=1.0)
Normal{Float64}(μ=0.0, σ=1.0)
Normal{Float64}(μ=0.0, σ=1.0)
julia> rand(Normal.(zeros(3)))
Normal{Float64}(μ=0.0, σ=1.0) Since Seems like it could make more sense to have another function for the product measure. This is easy enough to do, maybe it could be |
@cscherrer I see. How about something like this where broadcasting is used everywhere? x = Normal.(zeros(3))
rand.(x) # gives an Array{Float64,1}
# for scalar sampling
x = Normal.(0)
rand.(x) # gives a Float64 |
@hessammehr Interesting, so the idea is to have sampling and inference be in terms of That could be convenient. I think the biggest concern is to be sure we have consistent semantics. As it is, Is there a performance advantage to broadcasting vs the existing |
@cscherrer I agree that I would say intuitive, concise notation and playing nicely with the rest of the Julia idioms/eco-system make broadcasting an attractive option. Will get back to you re. performance. |
Writing |
Yep, that's the idea. I think with this, the biggest thing to be careful of is the potential for hidden dependence. |
@StefanKarpinski I was just looking into implementing this, running into some trouble. Guessing it's due to nonstandard use of julia> :(x ~ Normal())
:(x ~ Normal())
julia> :(x .~ Normal())
ERROR: syntax: missing comma or ) in argument list Another potential concern is confusion between |
Right, it seems like |
|
I think we could handle this by translating x .~ dists into x ~ For(size(dists)) do j
dists[j]
end A remaining question is, what if foo = dists
x ~ For(size(foo)) do j
foo[j]
end Both of these have the downside that the user will see the expanded code. As I write this, this last idea seems the most promising. But it will take a few core edits. |
How about mimicking how Julia handles this? x .~ Dists gets translated into something like Broadcast(~, x, Dists) |
Soss needs the body of a model to be of the form begin
line_1
⋮
line_n
end Each line is syntactically translated into a x ~ Normal(μ,σ) becomes Sample(:x, :(Normal(μ,σ))) Next, all of the Because all of this is entirely syntactic, translating into another form only helps when its done on the right side of |
Would it perhaps be more natural to use comprehensions to express multidimensional sampling? In other words, instead of writing
you would write
Is there something about this construct that I'm missing?
The text was updated successfully, but these errors were encountered: