# How do I emulate DiscreteUniformDistribution in Mathematica?

How do I define a function from scratch that emulates DiscreteUniformDistribution?
As shown below, attempting to use ProbabilityDistribution does not preserve the condition that the distribution should be unique.

unif = DiscreteUniformDistribution[{0, 1}];
mine = ProbabilityDistribution[1/2, {x, 0, 1, 1}];
PDF[unif, 0.5]
PDF[mine, 0.5]

Out[65]= 0
Out[66]= 1/2


I suppose my real question is how do I enforce the condition that x should be discrete while using ProbabilityDistribution?

By the way, I originally asked this on stackoverflow.

Update: After going back and forth between Wolfram support, this is their official response:

"I have consulted with our developers and this function is working as designed. There is no reason for evaluating a discrete distribution with non-integer values. The program recognizes the distribution as discrete and properly calculates such things as mean a variance. If you us the built-in functions rather than defining your own you will get the behavior you want. To fully implement the suggestions you have made would significantly impact the performance of the program both in memory usage and in speed. The function is working as designed and this case is closed."

-
Does this work for you? EmpiricalDistribution@Range[0, 1] – Rojolalalalalalalalalalalalala Aug 27 '13 at 14:06
Yes that works, but is there a way to define the distribution in terms of its pdf, while keeping it discrete? – jp.rider63 Aug 27 '13 at 14:37

I would use Piecewise.

pdist = ProbabilityDistribution[Piecewise[Map[{1/2, x == #1} &, {0, 1}], 0], {x, 0, 1, 1}]
PDF[pdist, {0.5, 0, 1}]

(*{0, 1/2, 1/2}*)

-
Cool that seems to do what I need. Thanks! – jp.rider63 Aug 27 '13 at 15:17

mine = ProbabilityDistribution[1/2, {x, 0, 1, 1}];


... appears to be valid to define a discrete pmf using Mathematica's ProbabilityDistribution function. As such, this appears to be a bug in Mathematica.

The problem you have identified occurs with the PDF function ... for instance:

PDF[mine, 1/3]


1/2

(whereas the answer should of course be 0), but it also occurs with other functions such as the Probability function which also gets it wrong:

Probability[x == 1/3, Distributed[x, mine]]

1/2

Another way to work around this (without using Piecewise) is to explicitly force the discreteness using Boole, as per:

mine2 = ProbabilityDistribution[Boole[x == 0 || x == 1] 1/2 , {x, 0, 1, 1}];


This will then work correctly, ... but it really should not be necessary:

PDF[mine2, 1/3]


0

Probability[x == 1/3, Distributed[x, mine2]]


0

Another approach is to use the mathStatica add-on to Mathematica, which you can set up exactly as you desired:

f = 1/2;        domain[f] = {x, 0, 1}  &&  {Discrete};


and which fully understands the discrete nature of the pmf:

Prob[x == 1/3, f]


0

etc ...

-
Thanks for letting me know about the mathStatica add-on. Also, I submitted this as a bug so we'll see what wolfram says. – jp.rider63 Aug 28 '13 at 1:15

I see you have got the correct answer -- just to point out it appears the distribution is actually properly discrete, its just PDF[] that is not returning the correct discrete form:

ListPlot[#/{1, 100} & /@
Tally@Table[
RandomVariate[
ProbabilityDistribution[1/4, {x, 0, 3, 1}]] , {100}],
PlotRange -> {0, 1/2}, Filling -> Axis, PlotStyle -> PointSize[.02],
Epilog -> {Line[{{0, 1/4}, {3, 1/4}}]}]


I won't use the "b" word but this strikes me as something that should be fixed -- nothing in the docs indicates that you should need to supply a discrete function to ProbabilityDistribution to use its discrete form.

-
Yes, it looks like RandomVariate is working, but PDF isn't. I've submitted this as a bug. – jp.rider63 Aug 28 '13 at 1:17

Another way (perversely) to get around this bug, is to get the desired distribution by transforming another discrete uniform distribution.

p = ProbabilityDistribution[1/2, {x, -1, 1, 2}]
pt = TransformedDistribution[(x + 1)/2, x \[Distributed] p]


Testing:

PDF[pt, {1/3, 0, 1}]


yields:

{0, 1/2, 1/2}


However, there seem to be issues using discrete plot and RandomVariate cannot be used on this binary discrete distribution. However, this is equivalent to BernoulliDistribution[0.5] and can be sampled.

-
Your suggested transform might give the correct result for given values such as $x=1/3$, 0 or 1, but if you look at the output given by your proposal: PDF[pt, y], .... it returns the horribly messy: $$(1/2)*KroneckerDelta[Mod[1 + 2*(-(1/2) + y), 2]]* UnitStep[1 - 2*(-(1/2) + y)]* UnitStep[1 + 2*(-(1/2) + y)]$$ as the pmf when all we want is: 1/2 ... at $x=0$ or $x=1$. – wolfies Aug 28 '13 at 17:16
@wolfies thank you for edification. Agree this is ugly. I guess (as "perversely" suggests) I found that merely changing limits of the (binary) discrete uniform distribution and transforming works and not a comment regarding the relative merits. It strikes me that using BernoulliDistribution[0.5] is perhaps the easiest approach to instantiate distribution for use (am prepared to be corrected). Questioner is pointing out a bug (which I found instructive). My point was the perversity of a why changing limits and transforming 'works' (however messily) when what appears to be correct form does not. – ubpdqn Aug 29 '13 at 7:47