3 ms·
Probability monad is a really novel way to experiment with stochastic processes. I saw one in scala few weeks back. To get insight into 128-bit strings, you can
by totekp 11y ago
Probability monad is a really novel way to experiment with stochastic processes. I saw one in scala few weeks back. To get insight into 128-bit strings, you can transform/group the sample space such as finding the P(1st bit is 1) or get a histogram of P(# 1s in string). Otherwise, each bitstring will be almost unique. The code is really concise and execution is less than a second.
val d: Podel[Vector[Int]] = Bernoulli(p = 0.5).repeat(128).map(_.toVector)
println(d.probability(bits => bits(0) == 1))
println(d.map(bits => bits.count(_ == 1)).hist(sampleSize = 10000, optLabel = Some("Number of 1s in 128 bits")))
output:
/*
0.5054
Number of 1s in 128 bits
42 0.01%
45 0.09%
48 0.43%
51 1.53% #
54 4.49% ####
57 9.84% #########
60 16.21% ################
63 20.46% ####################
66 19.62% ###################
69 14.76% ##############
72 7.86% #######
75 3.49% ###
78 0.89%
81 0.23%
84 0.07%
87 0.01%
90 0.01%
*/
- amelius 11y agoI can imagine a simple scheme by which this works: simply keep a "distribution" with every single variable. However, I guess this stops working correctly when there is correlation. For example, imagine that somewhere in the program, I generate a variable X with 50% probability of being 1 and 50% of being 0. Then I generate Y = -X. And finally, I compute Z = X + Y. Now, if the program does not keep track of the fact that Y and X are correlated, then Z will falsely contain nonzero values in its distribution.
- totekp 11y agoPerhaps this example is what you describe? flatMap (used by the for comprehension) enables monads to combine in powerful ways. The first part shows uncorrelated X,Y such that Y ~ -X, then the second part shows correlated Y = -X such that every y = -x { val X: Podel[Int] = Bernoulli(p = 0.5) val Y: Podel[Int] = X.map(-1 * _) val Z: Podel[Int] = X + Y val d: Podel[Int] = for { x <- X y <- Y z <- Z } yield { z } d.hist(sampleSize = 10000, optLabel = Some("Uncorrelated X, Y")) } { val X: Bernoulli = Bernoulli(p = 0.5) val d: Podel[Int] = for { x <- X y = - 1 * x z = x + y } yield { z } d.hist(sampleSize = 10000, optLabel = Some("y = -x")) } /* Uncorrelated X, Y -1 25.52% ######################### 0 49.60% ################################################# 1 24.88% ######################## y = -x 0 100.00% #################################################################################################### */ So far, the weakness I find with probability monad, and simulation, is lack of precision. This makes them useless when the probability you want to find is precise such as 5.324e-11. Only formulas can give you the answer.