-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Fixed DiscreteUniform to produce correct density and cdf #18614
Conversation
✅ Hi, I am the SymPy bot (v149). I'm here to help you write a release notes entry. Please read the guide on how to write release notes. Your release notes are in good order. Here is what the release notes will look like:
This will be added to https://github.com/sympy/sympy/wiki/Release-Notes-for-1.6. Note: This comment will be updated with the latest check if you edit the pull request. You need to reload the page to see it. Click here to see the pull request description that was parsed.
Update The release notes on the wiki have been updated. |
Please review, failing test on Travis but locally it passes:
|
I guess it's a random test failing. |
Codecov Report
@@ Coverage Diff @@
## master #18614 +/- ##
=============================================
+ Coverage 75.533% 75.597% +0.063%
=============================================
Files 644 644
Lines 167360 167545 +185
Branches 39440 39492 +52
=============================================
+ Hits 126413 126659 +246
+ Misses 35426 35367 -59
+ Partials 5521 5519 -2 |
I wonder what about sanitizing the inputs when creating the classes. |
I haven't use it because according to this comment DiscreteUnifromDistribution was made to handle general things. |
Should the result for |
I think the DiscreteUniform here was made to work general in the sense to work fine with not only numbers but also symbols. Following the wikipedia, It has an interval as a input, but the current implementation is a bit different from that in wikipedia. Also, IMO input set here tries to indicate the probability distributed unifromly over the unique elements of the input set (finite set), with density as |
May be the following can be overridden in class SingleFiniteDistribution(Basic, NamedArgsMixin):
def __new__(cls, *args):
args = list(map(sympify, args))
return Basic.__new__(cls, *args) The above can reduce the amortized cost of computing results. |
What type of object would you use to give a distribution that has probabilities I would have made this change diff --git a/sympy/stats/frv_types.py b/sympy/stats/frv_types.py
index d5b3560..61e72ec 100644
--- a/sympy/stats/frv_types.py
+++ b/sympy/stats/frv_types.py
@@ -97,7 +97,10 @@ def p(self):
@property # type: ignore
@cacheit
def dict(self):
- return dict((k, self.p) for k in self.set)
+ d = {k: 0 for k in self.set}
+ for k in self.args:
+ d[k] += self.p
+ return d to give >>> from sympy.stats import *
>>> Z = DiscreteUniform('Z', [1, 1, 1, 2, 2, 3, 3, 3, 4])
>>> dict(density(Z).items())
{1: 1/3, 2: 2/9, 3: 1/3, 4: 1/9} |
sympy/stats/frv_types.py
Outdated
@@ -92,7 +92,7 @@ def FiniteRV(name, density): | |||
class DiscreteUniformDistribution(SingleFiniteDistribution): | |||
@property | |||
def p(self): | |||
return Rational(1, len(self.args)) | |||
return Rational(1, len(set(self.args))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return Rational(1, len(set(self.args))) | |
return Rational(1, len(self.set)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, I will make that change.
I still think that the issues will ultimately remain if values like |
are you commenting on the right issue? |
Yes. How would the density like this be. |
I think this should not work this way because, in
|
On the current branch it produces density as diff --git a/sympy/stats/frv_types.py b/sympy/stats/frv_types.py index a0500228d8..3c112e01dd 100644 --- a/sympy/stats/frv_types.py +++ b/sympy/stats/frv_types.py @@ -18,8 +18,8 @@ import random -from sympy import (S, sympify, Rational, binomial, cacheit, Integer, - Dummy, Eq, Intersection, Interval, +from sympy import (Basic, S, sympify, Rational, binomial, cacheit, Integer, + Dummy, Eq, Intersection, Interval, simplify, Symbol, Lambda, Piecewise, Or, Gt, Lt, Ge, Le, Contains) from sympy import beta as beta_fn from sympy.external import import_module @@ -90,9 +90,14 @@ def FiniteRV(name, density): return rv(name, FiniteDistributionHandmade, density) class DiscreteUniformDistribution(SingleFiniteDistribution): + def __new__(cls, *args): + args = list(map(sympify, args)) + args = list(set(map(simplify, args))) + return Basic.__new__(cls, *args) + @property def p(self): - return Rational(1, len(set(self.args))) + return Rational(1, len(self.set)) @property # type: ignore @cacheit From this diff, I get the following results:
If this change is good and should I commit it? |
I would definitely advise against this. A distribution should be over things and those things should be math-agnostic. Seeing that there is a way to give a distribution for a multiset via FiniteRV then I would raise an error in DiscreteUniform if len(set(args)) != len(args) and advise them to use FiniteRV, something like: ValueError(filldedent('''
Repeated args detected but set expected. If you want a
distribution that has different weightings for each item
consider using DiscreteFinite(%s, %s)''' % symbol, multiset(args)) |
Sure! Then I would change accordingly. |
Okay, I’d agree to this direction, to raise errors for some weird usage |
Your suggestion in the error string would not have helped them get a weighted distribution. |
Thanks @smichr for adding the error message. The build is failing some irrelevant error |
The error message still looks bad unless the newline is inserted afterwards. Now it looks like this:
instead of
|
Thanks @smichr |
Fixed DiscreteUniform to produce correct density and cdf
References to other Issues or PRs
Fixes #18611
Brief description of what is fixed or changed
Other comments
Release Notes
DiscreteUniform
raises ValueError for duplicate args