Task 3 of 4
e^(−x²) — the bell curve — famously has no elementary
antiderivative. No substitution, no parts, no closed form. Monte Carlo doesn't
care: for uniform samples on [0, 1], the average of f(x) converges
to ∫₀¹ f(x) dx. Sampling beats symbolic calculus.
And here's the efficiency move over last task: instead of one kernel to evaluate and
another to reduce, fuse them. Each of 256 threads walks its own 64-sample
slice, evaluating e^(−x²) and accumulating in one pass — 16,384 evaluations,
one launch, 256 numbers back.
e^(−x²) over
its 64-sample slice of samples, so the logged mean lands on
≈ 0.7468.x owns the slice starting at this.thread.x * 64Math.exp(-x * x) for each sample — inside the loop, inside the kernelNo darts this time: the estimator is just the average height of the curve,
(1/N) Σ f(xᵢ), times the interval width (here 1). You only need
f, not a hit test.
The loop skeleton is last task's reduction. Swap what you accumulate:
const x = xs[base + i];
sum += Math.exp(-x * x);This page is an interactive exercise — the editor, the GPU runner and your saved progress need JavaScript. The text above is the full brief.