[ANN] MonteCarloMeasurements.jl


As a spinoff from a homework we gave in our julia course at our department, I created a small package to do nonlinear uncertainty propagation, MonteCarloMeasurements.jl.

This package provides two types Particles <: Real and StaticParticles <: Real that represents a distribution of a floating point number, kind of like the type Measurement from Measurements.jl. The difference compared to a Measurement is that Particles represent the distribution using a vector of unweighted particles, and can thus represent arbitrary distributions and handles nonlinear uncertainty propagation well. Functions like f(x) = x² or f(x) = sign(x) at x=0, are not handled well using linear uncertainty propagation ala Measurements.jl.

The goal is to have a number of this type behave just as any other number while partaking in calculations. After a calculation, the mean, std etc. can be extracted from the number using the corresponding functions. Particles also interact with Distributions.jl, so that you can call, e.g., Normal(p) and get back a Normal type from distributions or fit(Gamma, p) to get a Gammadistribution. Particles can also be iterated, asked for maximum/minimum, quantile etc.

The README contains some examples, benchmarks and pretty plots.


Convenience. Also, the benefit of using this number type instead of manually calling a function f with perturbed inputs is that, at least in theory, each intermediate operation on a Particles can exploit SIMD, since it’s performed over a vector. If the function f is called several times, however, the compiler might not be smart enough to SIMD the entire thing. Further, any dynamic dispatch is only paid for once, whereas it would be paid for N times if doing things manually. One could perhaps also make an argument for cache locality being favorable for the Particles type, but I’m not sure this holds for all examples. Primitive benchmarks in the readme show 15x-80x speedup for the considered examples.

The package will be registered once the new registration system is robust, for now
] add https://github.com/baggepinnen/MonteCarloMeasurements.jl.git
is the way to go.



This looks like a great package! This gets rid of a lot of ad hoc Monte Carlo boilerplate for me

1 Like


Thanks! I hope it works well for you, if not, feel free to open issues as they arise!

1 Like


Wow, looks great! Let me know if you’d like MonteCarloMeasurements.jl to be hosted under JuliaPhysics :wink:



Interesting, do I understand correctly that one could work out a weighted particle-cloud type which essentially acts as particle filter which incorporates a resampling step if operations involve several particle clouds?



Great package! If I understand correctly, you are assuming different data points to be statistically independent (since you simply forward Statictics.std etc.). Maybe it’d make sense to use/integrate some features of BinningAnalysis.jl. Just a thought on my side.

1 Like


You could certainly do that and I was contemplating the same. This only becomes interesting if there is something to weight them by, such as a repeated measurement etc. I do however already have a library for particle filters and didn’t find the need to experiment with this now ^^



Different Particles are independent if you create them independently. If you create them with the constructor Particles(N, d::MultivariateDistribution), they will be correlated as one would expect based on the distribution.



I would have the hope that generalised Particles could provide uncertainty quantification of generic code in a similar way as Dual numbers provides derivatives… ping me if you ever make an attempt!

1 Like


This package actually does exactly that, but not in they way you envision. The unweighted particle cloud encodes a distribution by varying its density instead of weighting the particles. A particle filter does both, the dynamics noise alter the density of the particle cloud, whereas the measurement density function provides weights. In this setting, there are no measurements to weight by so the weighting is never carried out.



The alternative approach would be to sample particles uniformly and then weight them by the distribution, this would be suboptimal as equally many particles would be used for low-density areas as for high-density areas.



Yes, right, I was somehow jumping ahead with the measurements, which would not turn up in generic code. But it would be something one could want to include anyway, as there will be already resampling steps because of operations having several independent particle clouds as input (that is not yet included in your code, right?)



Certainly, it would be kind of cool to have a particle filter implemented using a particle type! I have no facilities for resampling of the particles at the moment since the weighting required is not a thing for uncertainty propagation, as it is for bayesian filtering (particle filtering). Having said that, the extension required would be a new type WeigtedParticles <: AbstractParticles with some additional functions for resampling as well as normalization, logsumexp etc. That would be a project for another time, I’m afraid, but a cool idea nontheless.



Thinking a bit more along those lines… This type could be used for black-box optimization with particle methods, e.g., particle-swarm optimization. The weighting would then be provided by the (inverse) cost function, and resampling would focus on promising areas of the parameter space. Maybe it would be a good idea to extract the particle type into a separate package to facilitate all these crazy ideas :stuck_out_tongue:



Not the most urgent thing to decide but Swarm.jl or ParticleSwarm.jl sounds cool.



ParticleSwarms.jl is clearer and reflects use in the literature (edited to pick up next comment). There are some repos named ParticleSwarmOptimization.jl



At the risk of exacerbating the way too early naming…if I understand the goal of the proposal correctly, I think ParticleSwarms.jl would align with the plural convention for things like Distributions.jl and StaticArrays.jl (if each subtype is a type of ParticleSwarm)



The package is now registrated and can be added with

] add MonteCarloMeasurements

(make sure to ] update first)

The readme is extended with further documentation, more plotting functions are implemented and I also added an example file where I visualize the Bode and Nyquist diagrams of an uncertain transfer-function model, as well as perform a time-domain simulation of the system and look at the uncertainties in the response.

I verified that the package works with DifferentialEquations.jl. The tutorial for solving differential equations using Measurement works for Particles as well. In the second pendulum example, I had to call solve(..., dt=0.01, adaptive=false) , otherwise the solver tried to estimate a suitable dt using the uncertain state, which created some problems.

On a side note, I implemented a very primitive CMA optimization algorithm as a proof of concept. It’s available here and seems to work okay. I do not intend to take this further though, as there is already the well developed BlackBoxOptim.jl

1 Like