Monte Carlo estimation of Pi
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import kotlin.math.PI | |
import kotlin.math.abs | |
import kotlin.math.sqrt | |
import kotlin.random.Random | |
import kotlin.time.ExperimentalTime | |
import kotlin.time.measureTimedValue | |
object MonteCarlo { | |
fun estimatePi(nrPicks: Int = 1_000_000_000) = | |
generateSequence { pickRandomPoint() } | |
.take(nrPicks) | |
.filter { it.distanceFromCenter <= 1 } | |
.count() | |
.toDouble() | |
.let { it / nrPicks * 4 } | |
private fun pickRandomPoint() = | |
UnitSquarePosition( | |
Random.nextDouble(-1.0, 1.0), | |
Random.nextDouble(-1.0, 1.0), | |
) | |
private data class UnitSquarePosition(private val x: Double, private val y: Double) { | |
init { | |
if (x !in -1.0..1.0) error("X coordinate outside the unit square: $x") | |
if (y !in -1.0..1.0) error("Y coordinate outside the unit square: $y") | |
} | |
val distanceFromCenter = sqrt(x * x + y * y) | |
} | |
} | |
/* | |
* Sample output: | |
* | |
* Running the estimation with 500.000.000 picks... | |
* Monte Carlo: 3,14144 | |
* Real value: 3,14159 | |
* The estimation took 14 seconds to complete | |
* The estimation was 99,99504% close to Pi | |
*/ | |
@OptIn(ExperimentalTime::class) | |
fun main() { | |
val nrPicks = 500_000_000 | |
println("Running the estimation with ${"%,d".format(nrPicks)} picks...") | |
val estimation = measureTimedValue { MonteCarlo.estimatePi(nrPicks) } | |
val proximity = 100 * (1 - abs((PI - estimation.value) / PI)) | |
println("Monte Carlo: ${"%.5f".format(estimation.value)}") | |
println("Real value: ${"%.5f".format(PI)}") | |
println("The estimation took ${estimation.duration.inWholeSeconds} seconds to complete") | |
println("The estimation was ${"%.5f".format(proximity)}% close to Pi") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment