Skip to content
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

Refactored Bound for v4 #4815

Merged
merged 1 commit into from
Aug 13, 2021
Merged

Refactored Bound for v4 #4815

merged 1 commit into from
Aug 13, 2021

Conversation

kc611
Copy link
Contributor

@kc611 kc611 commented Jun 28, 2021

This PR refactors the Bound distribution for v4

pymc3/distributions/bound.py Outdated Show resolved Hide resolved
pymc3/distributions/bound.py Outdated Show resolved Hide resolved
@kc611 kc611 marked this pull request as draft June 28, 2021 13:08
pymc3/distributions/bound.py Outdated Show resolved Hide resolved
pymc3/distributions/bound.py Outdated Show resolved Hide resolved
@twiecki
Copy link
Member

twiecki commented Jul 5, 2021

@kc611 How close do you think this is to merge? If there's still a ways to go, we might want to focus on the aeppl integration instead where we can get mixture almost for free. CC @brandonwillard

@kc611
Copy link
Contributor Author

kc611 commented Jul 5, 2021

I'd say we're halfway through over here. But if we're bringing in aeppl aesara-devs/aeppl#22 PR of CensoredRV can be a much better replacement for Bound logic.

cc @ricardoV94

@ricardoV94
Copy link
Member

CensoredRV is not a good replacement. We would need something like TruncatedRV but that is still some time away

@codecov
Copy link

codecov bot commented Jul 7, 2021

Codecov Report

Merging #4815 (9e6631d) into main (6a75744) will increase coverage by 0.43%.
The diff coverage is 100.00%.

❗ Current head 9e6631d differs from pull request most recent head d105682. Consider uploading reports for the commit d105682 to get more accurate results
Impacted file tree graph

@@            Coverage Diff             @@
##             main    #4815      +/-   ##
==========================================
+ Coverage   73.17%   73.61%   +0.43%     
==========================================
  Files          86       86              
  Lines       13868    13840      -28     
==========================================
+ Hits        10148    10188      +40     
+ Misses       3720     3652      -68     
Impacted Files Coverage Δ
pymc3/distributions/bound.py 100.00% <100.00%> (+67.88%) ⬆️
pymc3/model.py 83.47% <100.00%> (-0.12%) ⬇️
pymc3/backends/report.py 89.51% <0.00%> (-2.10%) ⬇️
pymc3/distributions/distribution.py 80.43% <0.00%> (-1.45%) ⬇️
pymc3/parallel_sampling.py 87.20% <0.00%> (-1.02%) ⬇️
pymc3/util.py 73.50% <0.00%> (-0.85%) ⬇️
pymc3/distributions/continuous.py 96.26% <0.00%> (+0.01%) ⬆️
pymc3/data.py 81.77% <0.00%> (+0.44%) ⬆️

@kc611 kc611 marked this pull request as ready for review July 7, 2021 14:03
@kc611 kc611 requested a review from ricardoV94 July 14, 2021 09:36
@kc611 kc611 force-pushed the add_bound branch 2 times, most recently from 0dea2c0 to 4cb2948 Compare July 20, 2021 14:39
pymc3/distributions/bound.py Outdated Show resolved Hide resolved
lower = None
if isinstance(upper, Real) and upper == np.inf:
upper = None
def __new__(cls, name, distribution, lower=None, upper=None, size=None, **kwargs):
Copy link
Member

@ricardoV94 ricardoV94 Jul 22, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we are in a modelcontext we should check here that the distribution is not in model (which would mean the user did not use .dist() and the original variable would be accounted on the model logp as well.

In addition we can add the check that it is a TensorVariable, if not, the user is probably trying to work with the old API I see you already did this. Then the first error message can also go there

@@ -232,32 +133,70 @@ class Bound:
.. code-block:: python

with pm.Model():
NegativeNormal = pm.Bound(pm.Normal, upper=0.0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we not support this use-case anymore?

Copy link
Member

@ricardoV94 ricardoV94 Jul 23, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, you have to pass a .dist(). There is a very informative error message with a code example if users do that.

This was done to simplify the implementation and also be more in line with the rest of the API (e.g when you specify distributions for Mixtures, LKJCorr priors, RWs?). Also in the future, Truncated and Censored distributions would work the same way.

I checked the original PRs for Bound and this was actually the initial intended API, but they couldn't make it work. It was not, but it came up a couple of times, e.g: #2277 (comment)

Copy link
Member

@ricardoV94 ricardoV94 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some comments, We should wrap the lower / upper with at.as_tensor_variable([floatX|intX]), probably in the .dist method of the private classes _[Discrete|Continuous]Bounded, to not interfere with the cls.set_values.

Also after #4867 that logic can probably be simplified, as we will be able to just return symbolic initvals on demand

@twiecki twiecki changed the title [WIP] Refactored Bound for v4 Refactored Bound for v4 Aug 13, 2021
@ricardoV94 ricardoV94 added this to the vNext (4.0.0) milestone Aug 13, 2021
@twiecki twiecki merged commit 2cd0850 into pymc-devs:main Aug 13, 2021
@twiecki
Copy link
Member

twiecki commented Aug 13, 2021

Thanks @kc611 and @ricardoV94!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants