Search code examples
smalltalkpharo

How to sample probability distributions in Pharo


I want to generate n random samples of different probability distributions (normal, lognormal, poisson, uniform). i.e. what in R are rnorm, rlnorm, rpois, runif.

How can I do that in Pharo? It would also be useful to know how to calculate densities (dnorm, dlnorm, dpois, dunif)


Solution

  • Ok, here I leave an answer for the record, using PolyMath as recomended.

    To load PolyMath execute:

    Metacello new
            repository: 'github://PolyMathOrg/PolyMath/src';
            baseline: 'PolyMath';
            load
    

    There seem to exist two different kind of objects: PMProbabilityDensity and PMNumberGenerator, both with their respective subclasses. You can use the density objects both to obtain densities and to generate random samples, or you can use the number generators to generate random samples.

    So, for normal distribution if using density objects you can sample with:

    PMNormalDistribution new random "N(0,1)"
    PMNormalDistribution new initialize: mu sigma: sigma; random
    

    Or obtain the density at point x with:

    PMNormalDistribution new initialize: 0 sigma: 1; value: x.
    

    The exact same pattern applies to log normal and uniform:

    PMUniformDistribution new initialize: from to: to; random
    PMUniformDistribution new initialize: from to: to; value: x
    
    PMLogNormalDistribution new initialize: mu sigma: sigma
    PMLogNormalDistribution new initialize: mu sigma: sigma; value: x
    

    Unfortunately I couldn't find a density object for Poisson. Now, you can still generate samples of it: with number generator objects, you can generate Poisson and Normal samples (and log normals indirectly):

    PMPoissonGenerator new lambda: lambda; next.
    
    PMGaussianGenerator new next.
    PMGaussianGenerator new standardDeviation: 2; mean: 5; next.
    (PMGaussianGenerator new standardDeviation: 2; mean: 5; next) exp. "log normal"