The C++ programming language provides various random number generator for a specific distribution. For example, uniform distribution, normal distribution, and gamma distribution. The problem is, their domain is floating-point numbers. They are not really continuous!
I want the domain be some countable dense subset of $ℝ$. Say, $ℤ[½]$. The CDF over $ℤ[½]$ would be exactly the same to that over $ℝ$, regarding the monotonicity of a CDF.
Does this mean the distribution over $ℝ$ and that over $ℤ[½]$ (or any countable dense subset of $ℝ$, such as $ℚ$, $ℚ(e)$ or the computable numbers) are actually the same distribution? If so, does a deterministic algorithm that is an RNG for such distributions exist?
EDIT: I attempted to implement unifrom distribution over $[0,1) \cap ℤ[0.1]$. I have the following datatype that represents every computable number, in Haskell:
data Computable = Exact Rational | Inexact (Word -> Integer)
Exact labels every rational number. Inexact labels every Cauchy sequence whose limit is a computable number, like this (using lambda calculus):
$$ \text{Inexact}^{-1}(x) = \lambda n.\lfloor x \times 10^n \rceil $$
My implementation goes as (typeclass from System.Random):
instance Random Computable where
random g = (Inexact $ \n -> let
(m, _) = randomR (0, 10 ^ n - 1) g
in fromInteger m
, snd (next g))
random is the unifrom distribution over $[0,1) \cap ℤ[0.1]$. It has g as an argument, which is a uniform RNG for arbitrary range of consecutive integers (randomR invokes it).
This RNG exploits that we will need a finite number (here n) of digits anyway. Though I'm unsure whether this should be considered cheating. Is this a valid implementation of uniform distribution over $[0,1)$?
EDIT 2: Here are some demonstrations of above implementation:
*Main> (randomIO :: IO Computable) >>= printf "%.10f\n"
0.3262603172
*Main> (randomIO :: IO Computable) >>= printf "%.10f\n"
0.3403967450
*Main> (randomIO :: IO Computable) >>= printf "%.100f\n"
0.9936260281178909626196416839104245487197517214117589458461696555250759264208337183187442235136905901
*Main> (randomIO :: IO Computable) >>= printf "%.100f\n"
0.5219990231813949459630646837792033907565924036630170372162638275931417874219363290725289123121942905
*Main> (randomIO :: IO Computable) >>= printf "%.100f\n"
0.7672947758151983385289808102387963496390862559263475666364045942540881408976619844216572264017856792
Partial answer
The implemantation above has a major flaw. The sequence it outputs is not a Cauchy sequence, so it must not be labeled
Inexact.I fixed this problem this way:
Now
Inexactlabels a Cauchy sequence.Also, the domain of this RNG is indeed $[0,1]$ itself.