-
Notifications
You must be signed in to change notification settings - Fork 422
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
Accept Number
types in distribution constructors.
#1684
Comments
I thought #1413 showed that just replacing |
That's not the impression I got - there are some errors, but a lot of things actually just work? Like these examples #1413 (comment) I guess the question is do you want to guarantee that there are never any wrong outputs. And accepting But it leaves this impasse where it is impossible to generically wrap numbers in another object and let them be useful in the ecosystem. We really need a trait-based number system in base so you could call Then these could be checked in the constructor to guarantee correct results, rather than fixing the type to |
Relatedly, for example, https://github.com/gaurav-arya/StochasticAD.jl/blob/576d4e9026e2b4c225b2aab5910f4b6148a66666/src/discrete_randomness.jl#L110 is to circumvent that the Binomials don't allow numbers @gaurav-arya |
Regarding the example, I think it's annoying if constructors "lie" about the type of the instance they return. I think it would be nice to generalize the definitions. I'm just not a fan of simple search-replace approaches, I think it deserves to take one distribution, put together a PR for this specific distribution only, and discuss it intensively to figure out all problems and fix them. That would make the overall design and potential pitfalls much clearer. Afterwards one could generalize it to other distributions. Another caveat, as you mention, is that generally we really don't want arbitrary but only real numbers as distribution parameters and arguments to e.g. |
This sounds like a solution to me. Can we switch the type to ModelParameters.jl So there are no meaningful PRs to make except this change to |
Also I may not have communicated clearly enough: The main ModelParameters.jl use case here is not with unitful units. Its just with But to also allow units in other contexts, out |
On a second thought, I assume one shouldn't expect too much from loosening types in Distributions - for many distributions, evaluations are based on functions in StatsFuns or SpecialFunctions which often only support In my experience wrapper types lead to all kind of problems and are usually less convenient to work with than the unwrapped values, even if one tries to widen function signatures. Could you automatically unwrap the parameters when constructing distributions? |
Unwrapping the parameter might introduce the need to wrap the distribution object which then causes the annoying constructor dishonesty (i. E instead of a distribution with dual parameters you get a wrapper type with a distribution and it’s dual distribution counterpart) |
A quick clarification: what we need in StochasticAD is to relax |
ModelParameters.jl They are usually stripped out of a model before use. And if not, they wont actually flow through other code after being stored in the distribution - any operation on them will be on the parent number. They just provide a way to build arbitrary nested model structures but update the parameters in an automated way. For example, by putting a somestructfield = Exponential(Param(1.0)) it can be found and rebuilt as somestructfield = Exponential(1.0) or when e.g. an optimiser wants to update it, to: somestructfield = Exponential(0.9) But currently this is not possible, because they are |
I'll have a look at the package before commenting any further on what |
Ok thanks, thats a good idea. A good place to start is this issue from a user of both of these packages: Op essentially sums up why ModelParameters.jl is useful to him and why it should work with Distributions.jl. I didn't quite understand him until I tried to do the same myself. But it would be very elegant to put a You will also notice that ParameterHandling.jl jumps through some hoops do things what would be very simple using a
|
I read through the issue and the README of the package, and the use case is a bit clearer to me now. However, to me it seems that generally ModelParameters.jl faces the same limitations as e.g. ForwardDiff by design: you can only include parameterized components in the (sub)models if the corresponding structs are written generically enough and support If you just define a function that constructs your model from a vector/named tuple/... of parameters (manually or e.g. with ParameterHandling), you don't run into such issues. As far as I can tell, the mentioned problem with |
Are you saying you don't want to relax the type to (You seem to be missing that the type is |
I'm saying that I think generally you can't expect it to "just work" but this approach requires you to change every package you want to use if it is not written generically enough. Regarding Distributions, I think we could try to change Edit: It's even worse, I missed that even for |
Ok, I'll play with doing that with The other issues may affect other The problem is just being able to construct distribution objects with |
Of course the other option is that we write a parallel It just feels like a flaw in the design of Julias number system that we have to do that kind of duplication. There should have been more reliance on traits. |
@rafaqz regarding the prospect of writing a Obviously, we're up against a Julia type system limitation, which is that we can't do I do wonder how ergonomic this hacking could be for a specific target, e.g. |
Yeah, its not the easiest situation. AbstractNumbers.jl was the easiest fix for me, although I'm the defacto maintainer these days: I use it to make My idea was to just add a new Then have I'm not sure what Symbolics.jl does. |
The constructors seem very inconsistent to me:
This is all over the place. Also, there are unnecessary constructors, like
There are many constructors that seem redundant, where it would be better to leave it to default constructors. I also wonder why the
But this is fine:
This one is strange to me:
If |
Unfortunately, many things in Distributions are not completely consistent. My impression is that this is mainly due to how the package evolved: it's an old package and older Julia versions required different syntax and implementations. So some things were just not possible to do in the initial stages and some design choices only turned out to be suboptimal later.
These checks cause overhead (noticeable eg in AD which required some special fixes) and hence it is nice to be able to skip them if not needed (e.g. in
This is mainly for historical reasons. It took quite some effort to make |
With respect to the current issue, if there is any attempt to widen the input types to
In that case But the worst inconsistency is that some have constructors
and some have
In practice, they could both simply be deleted. |
Just passing So IMO we want inner constructors without checks + outer constructors with checks (if needed). |
If it's a deliberate design decision, I won't quibble. I could imagine a different interface, though. For example |
There are many
Number
typed objects that would work just fine in a distribution but currently don't. #1413 has examples where units would already work in a lot of cases by just usingNumber
.ModelParameters.jl is a similar case. It has
Number
typed parametersParam
so that e.g. Unitful.jl units can be put in them.But then they don't work as input to Distributions.jl objects when users try to do that:
rafaqz/ModelParameters.jl#51
Embedding parametrised distributions in large nested models could be extremely easy with this method.
The alternative is we add a parallel
RealParam
object and add new types and methods to AbstractNumbers.jl to work onReal
. This is a lot of work and code duplication compared to simply swappingReal
toNumber
here.The text was updated successfully, but these errors were encountered: