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

Implement Chi distribution helper #239

Merged
merged 2 commits into from
Nov 1, 2023
Merged

Conversation

tvwenger
Copy link
Contributor

Following the discussion here and obsolete PRs here and here, I have attempted to implement a Chi distribution helper class using CustomDist.

The distribution is functionally correct in that it is able to reproduce the scipy chi PDF.

There is an issue with adding this distribution to a pymc model, however. For example:

import pymc as pm
from pymc_experimental.distributions import Chi
with pm.Model() as model:
    pm.Chi("x", df=1)
print(model.initial_point())

results in

TypeError: Cannot convert Type Scalar(float64, shape=()) (of Variable Exp.0) into Type Vector(float64, shape=(1,)). You can try to manually convert Exp.0 into a Vector(float64, shape=(1,)).

I can't quite narrow down this issue, so any help would be appreciated!

Comment on lines 193 to 203
class TestChi(BaseTestDistributionRandom):
pymc_dist = Chi
pymc_dist_params = {"nu": 3.0}
expected_rv_op_params = {"nu": 3.0}
reference_dist_params = {"df": 3.0}
reference_dist = seeded_scipy_distribution_builder("chi")
tests_to_run = [
"check_pymc_params_match_rv_op",
"check_pymc_draws_match_reference",
"check_rv_size",
]
Copy link
Member

Choose a reason for hiding this comment

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

This test isn't needed

@ricardoV94
Copy link
Member

Your snippet is usingpm.Chi which shouldn't exist

Comment on lines 178 to 189
@pytest.mark.parametrize(
"nu, size, expected",
[
(1, None, 1),
(1, 5, np.full(5, 1)),
(np.arange(1, 6), None, np.arange(1, 6)),
],
)
def test_chi_moment(self, nu, size, expected):
with pm.Model() as model:
Chi("x", nu=nu, size=size)
assert_moment_is_expected(model, expected)
Copy link
Member

Choose a reason for hiding this comment

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

No need for this. We are adding default moments to CustomDist in pymc-devs/pymc#6873

@ricardoV94 ricardoV94 added the enhancements New feature or request label Sep 13, 2023
@tvwenger
Copy link
Contributor Author

@ricardoV94 Thanks for your help! I've removed those superfluous tests.

Also thanks for catching the issue with my snippet! Here's the correct snippet:

import pymc as pm
from pymc_experimental.distributions import Chi
with pm.Model() as model:
    Chi("x", nu=1)
print(model.initial_point())

results in

Traceback (most recent call last):
  File "/home/twenger/science/python/pymc-experimental/test.py", line 5, in <module>
    print(model.initial_point())
          ^^^^^^^^^^^^^^^^^^^^^
  File "/home/twenger/miniconda3/envs/pymc-experimental-test/lib/python3.11/site-packages/pymc/model/core.py", line 1090, in initial_point
    fn = make_initial_point_fn(model=self, return_transformed=True)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/twenger/miniconda3/envs/pymc-experimental-test/lib/python3.11/site-packages/pymc/initial_point.py", line 140, in make_initial_point_fn
    initial_values = make_initial_point_expression(
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/twenger/miniconda3/envs/pymc-experimental-test/lib/python3.11/site-packages/pymc/initial_point.py", line 284, in make_initial_point_expression
    graph.replace_all(replacements, import_missing=True)
  File "/home/twenger/miniconda3/envs/pymc-experimental-test/lib/python3.11/site-packages/pytensor/graph/fg.py", line 527, in replace_all
    self.replace(var, new_var, **kwargs)
  File "/home/twenger/miniconda3/envs/pymc-experimental-test/lib/python3.11/site-packages/pytensor/graph/fg.py", line 491, in replace
    new_var = var.type.filter_variable(new_var, allow_convert=True)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/twenger/miniconda3/envs/pymc-experimental-test/lib/python3.11/site-packages/pytensor/tensor/type.py", line 272, in filter_variable
    raise TypeError(
TypeError: Cannot convert Type Scalar(float64, shape=()) (of Variable Exp.0) into Type Vector(float64, shape=(1,)). You can try to manually convert Exp.0 into a Vector(float64, shape=(1,)).

@tvwenger
Copy link
Contributor Author

Alright, I fixed one problem and found another. I was passing the nu parameter to CustomDist as a tuple instead of as parameter. That fixes that error, but introduces a new one for the provided code snippet. The initial logp for the distribution is -inf:

import pymc as pm
from pymc_experimental.distributions import Chi
with pm.Model() as model:
    Chi("x", nu=1)
print(model.initial_point())
# {'x_log__': array(-inf)}

@ricardoV94
Copy link
Member

ricardoV94 commented Sep 13, 2023

That will be solved by the linked PR which implements initial values for CustomDist.

For now we can provide a maxwell_moment function to the moment kwarg of CustomDist. Probably it's good enough to set the moment to ones. In that case we should reintroduce the moment test that was commented out

@ricardoV94
Copy link
Member

Do you also want to add a helper for the Maxwell distribution?

@ricardoV94
Copy link
Member

The failing tests should be fixed by #240

@ricardoV94
Copy link
Member

Rebased from main, tests should now pass and we can merge

@ricardoV94 ricardoV94 changed the title Implementation of a Chi distribution helper Implement Chi distribution helper Nov 1, 2023
If tests are concerned about float32 they should manually set it with `pytensor.config.change_flags`
@ricardoV94 ricardoV94 merged commit 24eb34e into pymc-devs:main Nov 1, 2023
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancements New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants