clementi / estimate-pi

Implementations in several languages of an algorithm to estimate the value of π by using pseudorandom numbers. The algorithm is based on the process given by Matt Parker of Standup Maths at https://www.youtube.com/watch?v=RZBhSi_PwHU

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

estimate-pi

π

Introduction

This repository contains implementations in several programming languages of an algorithm to estimate the value of π by using pseudorandom numbers. The algorithm is based on the process given by Matt Parker of Standup Maths.

Matt Parker

The formula for approximating π that is used here is

Approximating pi

where p is the probability that two randomly selected large integers are coprime. Matt Parker explains this formula and gives a proof for it in the video above.

The Algorithm

Each example computes the average of 100 estimates of π. The estimation algorithm is as follows:

* Generate 1000000 pairs of random "large" integers.
* Count how many of these pairs are coprime.
* Calculate the proportion of the pairs of random integers that are coprime.
* Calculate π ≈ sqrt(6 / proportion).

In the implementations in this repository, the algorithm above comes in two general forms. First, there is the straightforward form that is best exemplified in the C example. This form utilizes mutable state, and it maps most directly to the algorithm described above. The other form is one that does not use mutable state, either because the language doesn't easily support it, such as the Haskell example, or the best practices of the language discourage the use of mutable state, or that the algorithm could be more naturally expressed in the language without using mutable state. I may produce versions in these languages that make use of mutable state, and I may make versions that are optimized for tail recursion, and see how the performance changes.

To determine coprimality, I used the language's standard library gcd function (or coprimality function) if it existed and I was aware of it; otherwise I supplied a simple recursive implementation, shown here in pseudocode:

function gcd(a, b)
    if b = 0
        return a
    else
        return gcd(b, a mod b)

For Javascript, I used this iterative version:

function gcd(a, b)
    while b ≠ 0
        t := b
        b := a mod b
        a := t
    return a

Performance

As would be expected, there is a wide variance of performance with different languages. The chart below illustrates performance stats that I've gathered.

Performance stats

About

Implementations in several languages of an algorithm to estimate the value of π by using pseudorandom numbers. The algorithm is based on the process given by Matt Parker of Standup Maths at https://www.youtube.com/watch?v=RZBhSi_PwHU


Languages

Language:Scheme 11.6%Language:Scala 9.5%Language:Elixir 6.2%Language:Clojure 5.6%Language:JavaScript 5.4%Language:Haskell 4.9%Language:Python 4.5%Language:OCaml 3.9%Language:C# 3.7%Language:Java 3.6%Language:Racket 3.5%Language:Erlang 3.4%Language:C++ 3.3%Language:C 3.2%Language:D 3.2%Language:Kotlin 2.7%Language:Rust 2.7%Language:F# 2.6%Language:Nim 2.4%Language:Go 2.4%Language:Lua 2.3%Language:Swift 2.2%Language:Ruby 1.8%Language:Crystal 1.8%Language:Groovy 1.8%Language:Julia 1.6%