Published
Edited
Aug 1, 2021
8 stars
Also listed in…
Plot
Insert cell
Insert cell
n = 1e5 // number of iterations
Insert cell
// Monte Carlo
πMC = {
const values = new Float64Array(n);
const random = d3.randomUniform.source(d3.randomLcg(142))();
let q = 0;
for (let i = 0; i < n; ++i) {
q += random() ** 2 + random() ** 2 < 1;
values[i] = (q / (i + 1)) * 4;
}
return values;
}
Insert cell
// Quasi Monte Carlo
πQR = {
const values = new Float32Array(n);
// see https://observablehq.com/@fil/rd-quasi-random-sequences
const phi2 =
Math.pow(1 / 2 + Math.sqrt(69) / 18, 1 / 3) +
Math.pow(1 / 2 - Math.sqrt(69) / 18, 1 / 3);
const a = [1.0 / phi2, 1.0 / (phi2 * phi2)];
let p = [0.5, 0.5]; // arbitrary root
let q = 0;
for (let i = 0; i < n; ++i) {
p = [(p[0] + a[0]) % 1, (p[1] + a[1]) % 1];
q += p[0] ** 2 + p[1] ** 2 < 1;
values[i] = (q / (i + 1)) * 4;
}
return values;
}
Insert cell
πIDEAL = {
const values = new Float32Array(n);
for (let i = 0; i < n; ++i) {
values[i] = (Math.round(((i + 1) * Math.PI) / 4) * 4) / (i + 1);
}
return values;
}
Insert cell
Insert cell
Plot.plot({
y: { type: "log", grid: true, label: "↑ precision", reverse: true },
// x: { domain: [33100, 33300] }, // witness the miracle
marks: [
Plot.line(
{ length: n },
{ x: (_, i) => i, y: error(πIDEAL), strokeWidth: 0.25 }
),
Plot.line({ length: n }, {
x: (_, i) => i,
y: error(πQR),
stroke: "orange",
strokeWidth: 0.5
}),
Plot.line({ length: n }, {
x: (_, i) => i,
y: error(πMC),
stroke: "steelblue",
strokeWidth: 0.25
})
],
width
})
Insert cell
Insert cell
Insert cell
k = 20
Insert cell
Plot.plot({
y: { type: "log", grid: true, label: "↑ precision", reverse: true },
marks: [
Plot.line(
{ length: n },
Plot.windowY({
x: (_, i) => i,
y: error(πIDEAL),
k,
reduce: "max"
})
),
Plot.line(
{ length: n },
Plot.windowY({
x: (_, i) => i,
y: error(πQR),
stroke: "orange",
k,
reduce: "max"
})
),
Plot.line(
{ length: n },
Plot.windowY({
x: (_, i) => i,
y: error(πMC),
stroke: "steelblue",
k,
reduce: "max"
})
)
],
width
})
Insert cell
function error(values) {
return values.map((x) => Math.abs(x - Math.PI));
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more