Discover · Brownian motion · Guided investigation
Measure one trial at two intervals, then ask it about probability
Choose what to measure in one recorded set of particle paths, look at it after one interval and after four times as long, then use the spreading rate you found to ask how likely a particle is to end in a given range.
The trial here is synthetic: this site computes it from a model, with the tracer and spreading instruments. It is not a historical measurement, and not a reconstruction of Einstein’s private thoughts.
01 · Choose an observable
Keep the trial. Change when you look.
Static worked example
Model note
- Temperature (
temperature), Dynamic viscosity (viscosity), Particle radius (particleRadius), Observation interval (observationInterval) and Number of tracers in the trial (ensembleSize): Host calculation, by the site's own reference code. Computed inbm01.acceptedInputs. - Boltzmann's constant (
boltzmannConstant): Host calculation, by the site's own reference code. Computed inconstants.modernSI2019. - Diffusion coefficient (
diffusionCoefficient): Host calculation, by the site's own reference code. Computed indiffusion.stokesEinsteinD. - RMS displacement (one dimension) (
rmsDisplacement1d), RMS coordinate displacement after 1 s (lambdaX1s) and RMS coordinate displacement after 60 s (lambdaX60s): Host calculation, by the site's own reference code. Computed indiffusion.rmsDisplacement. - Model total mean square (
modelSecondMoment), Model mean distance (modelMeanNorm) and Model RMS distance (modelRmsNorm): Host calculation, by the site's own reference code. Computed indiffusion.moments. - Tracer positions at the end of the interval (
tracerPositions), Coordinates along the drawn traces (traceCoordinates) and Random draws in the recording (recordingDraws): Host calculation, by the site's own reference code. Computed indiffusion.recordTracers. - Sample signed mean (
sampleMean), Mean absolute coordinate displacement (sampleMeanAbsolute), Sample mean square (sampleMeanSquare), Sample coordinate RMS (sampleRms), Sample mean distance (sampleMeanNorm), Sample total mean square (sampleMeanSquareNorm), Sample RMS distance (sampleRmsNorm), Sample apparent coordinate speed (sampledApparentSpeed), Signed coordinate mean, compared with its sampling band (signedMean) and Mean-square coordinate displacement, compared with its sampling band (meanSquare): Host calculation, by the site's own reference code. Computed indiffusion.ensembleMoments. - Model apparent coordinate speed (
modelApparentSpeed): Host calculation, by the site's own reference code. Computed indiffusion.apparentSpeed. - Times along the drawn traces (
traceTimes), Times on the comparison plot (plotTimes), Sample signed mean at each plotted time (plotSampleMean), Sample total mean square at each plotted time (plotSampleMsd), Sample RMS distance at each plotted time (plotSampleRms), Sample apparent speed at each plotted time (plotSampleApparent), Model signed mean at each plotted time (plotModelMean), Model total mean square at each plotted time (plotModelMsd), Model RMS distance at each plotted time (plotModelRms), Model apparent speed at each plotted time (plotModelApparent) and Whether the existing recording was reused (reusedRecording): Host calculation, by the site's own reference code. Computed inbm01.measure. - Edges of the histogram bins (
histogramEdges), Count in each histogram bin (histogramCounts), Share of the sample in each histogram bin (histogramFrequencies), Samples below the plotted range (underflow), Samples above the plotted range (overflow) and Kolmogorov distance (kolmogorovDistance): Host calculation, by the site's own reference code. Computed indiffusion.displacementHistogram. - Model probability of each histogram bin (
histogramModel): Host calculation, by the site's own reference code. Computed indiffusion.intervalProbability. - Sampling band for the signed coordinate mean (
meanBand), Sampling band for the total mean square (secondMomentBand), Lower edge of the sampling band for the signed mean (signedMeanLowerBand), Upper edge of the sampling band for the signed mean (signedMeanUpperBand), Lower edge of the sampling band for the mean square (meanSquareLowerBand) and Upper edge of the sampling band for the mean square (meanSquareUpperBand): Host calculation, by the site's own reference code. Computed indiffusion.ensembleMomentBands. - Seed 1905: with the same settings, the same seed replays the same trial.
- Computed from the settings last applied (settings revision 1, result 1).
- Not modeled: Molecular collisions, inertia and a physical short-time velocity.
- Show the code
The signed mean can nearly vanish while the sample spreads. Pin a completed result, predict what will change, then remeasure the same recorded paths at another interval.
Accepted trial at 1 second.
02 · Predict, then compare
Does four times as long mean four times as far?
Every prediction has access to the same evidence and explanation. The comparison below uses accepted numbers; it does not replace a finite sample with a perfect square-root curve.
These actions are anchored to the pinned baseline, not to the last button press. They use the accepted trial, not unapplied edits, and stay within the recording length. To try a shorter interval, enter a multiple of the recording resolution above; off-grid requests are refused without changing the paths.
| Quantity | Unit | Baseline | Current |
|---|---|---|---|
| Observation interval | s | 1 | 1 |
| Sample signed mean | μm | 0.0029237 | 0.0029237 |
| Sample mean square | μm² | 0.97223 | 0.97223 |
| Sample coordinate RMS | μm | 0.98602 | 0.98602 |
| Model coordinate RMS | μm | 0.92676 | 0.92676 |
| Sample apparent speed (selected dimension) | μm/s | 0.98602 | 0.98602 |
| Model apparent speed (selected dimension) | μm/s | 0.92676 | 0.92676 |
| Model diffusion coefficient | μm²/s | 0.42944 | 0.42944 |
- Observation interval
- 1 times the baseline
- Sample coordinate RMS
- 1 times the baseline
- Model coordinate RMS
- 1 times the baseline
- Model apparent speed
- 1 times the baseline
Why displacement, rather than an intrinsic Brownian speed?
For independent, zero-mean steps the mean squares add. In the diffusion model, four times the time gives twice the coordinate RMS displacement. Dividing that displacement by the interval therefore gives a smaller apparent speed. Looking more often changes that quotient; it does not reveal an interval-independent velocity.
The sample fluctuates around the model. This coarse-grained model does not resolve inertia or molecular collisions at arbitrarily short times. Its path segments are not a microscope film.
Return to the observable argument →03 · Carry a quantity into a different question
Use the same coefficient to ask about probability.
The spreading lab below offers the model diffusion coefficient of the trial you pinned above. Choose its “Copy D from the pinned trial” button to apply that coefficient once. This is not a fitted value from the sample, and later tracer changes do not silently update the spreading lab.
An executable model
From this trial to an interval probability
Choose an interval and ask how likely a tracer is to finish inside it. Changing a field only edits a request. The plot and table change together after you apply valid settings.
Read the curve as numbers, at 17 points
| RMS distances from zero | Displacement (μm) | Density (per μm) | Share of the peak height |
|---|---|---|---|
| −4 | −3.707 | 0.00014441 | 0.034% |
| −3.5 | −3.2437 | 0.00094165 | 0.22% |
| −3 | −2.7803 | 0.0047821 | 1.1% |
| −2.5 | −2.3169 | 0.018914 | 4.4% |
| −2 | −1.8535 | 0.058258 | 13.5% |
| −1.5 | −1.3901 | 0.13975 | 32.5% |
| −1 | −0.92676 | 0.26109 | 60.7% |
| −0.5 | −0.46338 | 0.37989 | 88.2% |
| 0 | 0 | 0.43047 | 100% |
| 0.5 | 0.46338 | 0.37989 | 88.2% |
| 1 | 0.92676 | 0.26109 | 60.7% |
| 1.5 | 1.3901 | 0.13975 | 32.5% |
| 2 | 1.8535 | 0.058258 | 13.5% |
| 2.5 | 2.3169 | 0.018914 | 4.4% |
| 3 | 2.7803 | 0.0047821 | 1.1% |
| 3.5 | 3.2437 | 0.00094165 | 0.22% |
| 4 | 3.707 | 0.00014441 | 0.034% |
Static worked example
Model note
- Diffusion coefficient (
diffusionCoefficient): Host calculation, by the site's own reference code. Computed indiffusion.stokesEinsteinD. - Diffusion coefficient this run used, the model's or a copied one (
activeDiffusionCoefficient), Position coordinate (field, one dimension) (positionCoordinate1d), Comparison times (comparisonTimes) and Numerical time step (gridTimeStep): Host calculation, by the site's own reference code. Computed inbm06.evaluate. - RMS displacement (one dimension) (
rmsDisplacement1d) and RMS coordinate displacement at each comparison time (comparisonRms): Host calculation, by the site's own reference code. Computed indiffusion.rmsDisplacement. - Mean-square displacement (one dimension) (
meanSquareDisplacement1d), Mean radius ⟨r⟩ in two dimensions (meanRadius2d), RMS radius √⟨r²⟩ in two dimensions (rmsRadius2d), Mean radius ⟨r⟩ in three dimensions (meanRadius3d) and RMS radius √⟨r²⟩ in three dimensions (rmsRadius3d): Host calculation, by the site's own reference code. Computed indiffusion.moments. - Interval probability (
intervalProbability): Host calculation, by the site's own reference code. Computed indiffusion.intervalProbability. - Probability density (one-dimensional) (
probabilityDensity): Host calculation, by the site's own reference code. Computed indiffusion.gaussianPropagator. - Most likely radius in two dimensions (
mostLikelyRadius2d): Host calculation, by the site's own reference code. Computed indiffusion.mostLikelyRadius2d. - Numerical density in each grid cell (
gridDensity) and Stability ratio (stabilityRatio): Host calculation, by the site's own reference code. Computed indiffusion.ftcs1d. - Probability in each grid cell, between reflecting walls (
cellMasses), Probability in each grid cell, on an unbounded line (cellProbabilities), Maximum cell-probability difference (maxCellMassDifference) and Whether the spread has reached the reflecting walls (wallContact): Host calculation, by the site's own reference code. Computed indiffusion.ftcsAnalyticComparison. - Computed from the settings last applied (settings revision 1, result 1).
- Not modeled: The ballistic short-time regime and inertia.
- Show the code
Accepted result: RMS displacement 0.92676 micrometres; selected interval probability 71.943 percent.
293.15 K · 1 mPa·s · radius 0.5 μm · elapsed 1 s
Constants: modern SI (2019). Viscosity is a declared input, not inferred from temperature. D is calculated from these physical inputs.
| Diffusion coefficient | 0.42944 μm²/s |
|---|---|
| RMS displacement | 0.92676 μm |
| Mean square displacement | 0.85888 μm² |
| Selected closed interval | [−1, 1] μm |
| Probability inside that interval | 71.943% |
Density is measured per unit length; probability is a dimensionless area. A taller curve is not a larger total probability.
One setup, three observation times
| Elapsed time | RMS displacement |
|---|---|
| 1 s | 0.92676 μm |
| 10 s | 2.9307 μm |
| 60 s | 7.1786 μm |
The same spread, as a 2D or 3D radius
A radius is not a signed coordinate: it is never negative, and the growing circumference (2D) or surface area (3D) of positions at a given distance changes which average is largest.
| Quantity | 2D radius | 3D radius |
|---|---|---|
| Mean radius ⟨r⟩ | 1.1615 μm | 1.4789 μm |
| RMS radius √⟨r²⟩ | 1.3106 μm | 1.6052 μm |
| Most likely radius | 0.92676 μm | not modeled |
The mean 2D radius ⟨r⟩ = √(πDt) is smaller than the RMS radius √⟨r²⟩ = √(4Dt): the extra factor of r in the 2D density weights larger radii more heavily than a signed 1D coordinate does, so the two averages of the same spread disagree.
The RMS 2D radius √⟨r²⟩ = √(4Dt) is the square root of the mean squared distance from the start, not the mean distance itself. Squaring before averaging always weights the tail more than averaging the radius directly.
The most likely 2D radius, where the density p(r, t) = (r/2Dt) exp(−r²/4Dt) peaks, is √(2Dt): the same number as the 1D RMS displacement. The growing circumference of available positions at radius r (proportional to r itself) exactly cancels the falling Gaussian density near the start, moving the peak away from the origin.
The mean 3D radius ⟨r⟩ = 4√(Dt/π) counts positions on a growing sphere (area proportional to r²), pulling the average distance from the start out further than the 2D circumference case.
The RMS 3D radius √⟨r²⟩ = √(6Dt) reflects three independent coordinate directions, each contributing its own 2Dt to the mean squared displacement (compare the 1D case's single 2Dt).
What this model leaves out
Dilute spherical tracers in a homogeneous Newtonian liquid; no drift or particle interactions.
Low Reynolds number and times long compared with momentum relaxation are assumed, not checked.
The analytic curve describes an unbounded line; the numerical grid has reflecting walls.
These are consequences of a model, not measurements or evidence that the model describes nature.
No FrankenSim artifact is used here.
Show which code computes these numbers, and its fingerprint
Density, interval probability and displacement come from src/physics/reference/diffusion/distributions.ts. The grid comes from src/physics/reference/diffusion/ftcs.ts. One worker operation assembles all views.
source:sha256:c649ff3318872a0745312cb8c36ff143e63024ccba89f85fd8eb4b24ec660b3c
The source link opens current main, which may differ from this build. The digest above identifies the evaluator sources used by this page.
Show the code
The site’s own reference code for this law, in TypeScript. It computes the numbers above when the page runs it, and it is what the page uses wherever a FrankenSim result is not available.
gaussianPropagator · src/physics/reference/diffusion/distributions.ts · this site’s source, as built · sha256:08378ddf8b6720db47f4949e26c3bb6de95c5ab5ba5851fe4b52b651ef62f55a
This is the function that produced the numbers shown now.
In words
On an unbounded line the probability density is a Gaussian whose width grows as the square root of elapsed time.
Implementation
export function gaussianPropagator(x: number, t: number, D: number): Evaluation {
if (!Number.isFinite(x) || !validDt(D, t))
return outside(
"probabilityDensity",
"gaussianPropagator",
"finite x, D >= 0, t >= 0",
"Use finite position and nonnegative diffusivity and time.",
);
if (D === 0 || t === 0) return pointMass("probabilityDensity", "gaussianPropagator");
const sigma = scale(D, t);
const z = x / sigma;
if (!(sigma > 0) || !Number.isFinite(sigma))
return outside(
"probabilityDensity",
"gaussianPropagator",
"representable spread",
"The spread is outside the numerical range.",
"numerical",
);
return number(
"probabilityDensity",
"gaussianPropagator",
Math.exp(-Math.log(sigma) - 0.5 * Math.log(2 * Math.PI) - 0.5 * z * z),
undefined,
undefined,
true,
);
}The site’s own reference code for this law, in TypeScript. It computes the numbers above when the page runs it, and it is what the page uses wherever a FrankenSim result is not available.
intervalProbability · src/physics/reference/diffusion/distributions.ts · this site’s source, as built · sha256:fdf333ecee819e1097ee25fb89e2caea663dd27fc5f8818d3a28cd8a15ff9a56
This function computes the listed outputs when it runs.
In words
The probability of landing between two points is the integral of that Gaussian.
Implementation
/** Closed intervals include the atom at t=0, including the interval [0,0]. */
export function intervalProbability(x1: number, x2: number, t: number, D: number): Evaluation {
const owner = "intervalProbability";
if (![x1, x2].every(Number.isFinite) || x1 > x2 || !validDt(D, t))
return outside(
"intervalProbability",
owner,
"x1 <= x2, D >= 0, t >= 0",
"Use ordered finite interval endpoints and nonnegative diffusivity and time.",
);
if (D === 0 || t === 0) return number("intervalProbability", owner, x1 <= 0 && x2 >= 0 ? 1 : 0);
if (x1 === x2) return number("intervalProbability", owner, 0);
const s = 2 * Math.sqrt(D) * Math.sqrt(t);
if (!(s > 0) || !Number.isFinite(s))
return outside(
"intervalProbability",
owner,
"representable spread",
"The spread is outside the numerical range.",
"numerical",
);
const lo = x1 / s;
const hi = x2 / s;
const width = (x2 - x1) / s;
const mid = lo + width / 2;
let p: number;
// Very narrow intervals need direct integration, even when both tails are small.
if (width > 0 && width * (1 + Math.abs(mid)) < 0.01) {
const nodes = [0.1834346424956498, 0.525532409916329, 0.7966664774136267, 0.9602898564975363];
const weights = [0.362683783378362, 0.3137066458778873, 0.2223810344533745, 0.1012285362903763];
let sum = 0;
for (let i = 0; i < 4; i++) {
const offset = (width / 2) * nodes[i]!;
sum += weights[i]! * (Math.exp(-((mid - offset) ** 2)) + Math.exp(-((mid + offset) ** 2)));
}
p = (width / (2 * Math.sqrt(Math.PI))) * sum;
} else
p =
lo >= 0
? 0.5 * (tail(lo) - tail(hi))
: hi <= 0
? 0.5 * (tail(-hi) - tail(-lo))
: 0.5 * (central(hi) - central(lo));
if (p < 0 || p > 1)
return outside(
"intervalProbability",
owner,
"probability range",
"Numerical evaluation did not produce an admissible probability.",
"numerical",
);
return number("intervalProbability", owner, p, undefined, undefined, true);
}The site’s own reference code for this law, in TypeScript. It computes the numbers above when the page runs it, and it is what the page uses wherever a FrankenSim result is not available.
erf · src/physics/reference/special/erf.ts · this site’s source, as built · sha256:58ba0038d43059073d60c1af94ee48c8052c076685e393ce5eeab85362edda77
This function computes the listed outputs when it runs.
In words
The error function is the integral that turns a Gaussian density into an interval probability.
Implementation
export function erf(x: number): number {
validate(x);
if (x < 0) return -erf(-x);
return x < 1.5 ? erfPositive(x) : 1 - erfcPositive(x);
}The site’s own reference code for this law, in TypeScript. It computes the numbers above when the page runs it, and it is what the page uses wherever a FrankenSim result is not available.
erfc · src/physics/reference/special/erf.ts · this site’s source, as built · sha256:45a75bb57d3658953e37bdc7ea1e9f0abbd6296180b6101f231d0631f5cb0922
This function computes the listed outputs when it runs.
In words
The complementary error function evaluates the Gaussian tail without subtracting from one.
Implementation
export function erfc(x: number): number {
validate(x);
return x < 0 ? 2 - erfcPositive(-x) : erfcPositive(x);
}The site’s own reference code for this law, in TypeScript. It computes the numbers above when the page runs it, and it is what the page uses wherever a FrankenSim result is not available.
radialPropagator2d · src/physics/reference/diffusion/distributions.ts · this site’s source, as built · sha256:58040898d39023e9e0e937741b8bb0885bad8976be85b6817c2b5ff3ef0916b2
This function computes the listed outputs when it runs.
In words
In two dimensions the radial density is not itself a Gaussian.
Implementation
export function radialPropagator2d(r: number, t: number, D: number): Evaluation {
return radial(r, t, D, 2);
}The site’s own reference code for this law, in TypeScript. It computes the numbers above when the page runs it, and it is what the page uses wherever a FrankenSim result is not available.
radialPropagator3d · src/physics/reference/diffusion/distributions.ts · this site’s source, as built · sha256:37f9cc144c032a6104ceaa5b2020114d14a16a314620ad493149e5ee1bfdb6e8
This function computes the listed outputs when it runs.
In words
In three dimensions the radial density is not itself a Gaussian.
Implementation
export function radialPropagator3d(r: number, t: number, D: number): Evaluation {
return radial(r, t, D, 3);
}The site’s own reference code for this law, in TypeScript. It computes the numbers above when the page runs it, and it is what the page uses wherever a FrankenSim result is not available.
ftcs1d · src/physics/reference/diffusion/ftcs.ts · this site’s source, as built · sha256:c04f80e8182597a114b7d20f492eb86053f90b4cc9e7cd299f516a6b44eb4755
This function computes the listed outputs when it runs.
In words
Advance a one-dimensional density with an explicit three-point Laplacian. Refuse when the stability ratio exceeds one half.
Implementation
export function ftcs1d(p: FtcsParameters, budget = REFERENCE_FTCS_BUDGET): Computation<FtcsFrames> {
const { n, frames, stepsPerFrame, D, dx, dt, profile } = p;
if (!integer(n, 3) || !integer(frames, 1) || !integer(stepsPerFrame, 1))
return invalid(
["n", "frames", "stepsPerFrame"],
"Use at least three cells and positive whole-number frame and step counts.",
);
if (![D, dx, dt].every(Number.isFinite))
return {
kind: "refused",
refusal: makeRefusal("nonfinite-input", { parameterIds: ["D", "dx", "dt"] }),
};
if (D < 0 || dx <= 0 || dt <= 0 || ![0, 1, 2].includes(profile))
return invalid(
["D", "dx", "dt", "profile"],
"Use nonnegative D, positive dx and dt, and profile 0, 1, or 2.",
);
// This exact operation order is part of the planned upstream conformance contract.
const r = D === 0 ? 0 : (D * dt) / (dx * dx);
if (!Number.isFinite(r) || (D > 0 && r === 0))
return numerical("The stability ratio is outside binary64 range; the grid was not advanced.");
if (r > 0.5) {
const dtMax = (dx * dx) / (2 * D);
const dxMin = Math.sqrt(2 * D * dt);
const dMax = (dx * dx) / (2 * dt);
if (![dtMax, dxMin, dMax].every((v) => Number.isFinite(v) && v > 0))
return numerical("The dimensional stability repairs are outside binary64 range.");
// Mathematical bounds can round to a value with r=0.5000000000000001.
// Preserve dtMax in the explanation; make each offered action executable.
const dtRepair = stableRepair(dtMax, false, (v) => (D * v) / (dx * dx));
const dxRepair = stableRepair(dxMin, true, (v) => (D * dt) / (v * v));
const dRepair = stableRepair(dMax, false, (v) => (v * dt) / (dx * dx));
if (dtRepair === null || dxRepair === null || dRepair === null)
return numerical(
"No representable repair was found near the dimensional stability boundary.",
);
return {
kind: "refused",
refusal: makeRefusal(
"ftcs-unstable",
{ parameterIds: ["dt", "dx", "D"] },
{
details: { ratio: r, limit: 0.5, dtMax },
rankedRepairs: [
{
label: "Reduce the time step to the explicit scheme's limit.",
action: { parameterId: "dt", value: dtRepair },
},
{
label: "Use a coarser spatial grid.",
action: { parameterId: "dx", value: dxRepair },
},
{
label: "Choose a smaller diffusivity; this changes the physical setup.",
action: { parameterId: "D", value: dRepair },
},
],
},
),
};
}
const stepCount = (frames - 1) * stepsPerFrame;
const limited = budgetCheck(n * stepCount, 8 * n * (frames + 2), budget);
if (limited) return limited;
const elapsedTime = stepCount * dt;
if (!Number.isFinite(elapsedTime) || (stepCount > 0 && elapsedTime === 0))
return numerical("Elapsed model time is outside binary64 range.");
const field = new Float64Array(n);
if (profile === 0) field[Math.floor(n / 2)] = 1 / dx;
else if (profile === 1) field.fill(1, 0, Math.floor(n / 2));
else {
field[Math.floor(n / 4)] = 0.5 / dx;
field[Math.floor((3 * n) / 4)] = 0.5 / dx;
}
if (!field.every(Number.isFinite))
return numerical("The initial cell density is outside binary64 range.");
const derivative = new Float64Array(n);
const values = new Float64Array(n * frames);
values.set(field);
for (let frame = 1; frame < frames; frame++) {
if (!advanceInPlace(field, derivative, r, stepsPerFrame))
return numerical("A cell became nonfinite or negative; no partial frames are returned.");
values.set(field, frame * n);
}
return {
kind: "accepted",
data: Object.freeze({
values,
shape: Object.freeze([frames, n] as const),
stepCount,
elapsedTime,
stabilityRatio: r,
boundary: "zero-flux",
ownerId: "diffusion.ftcs1d",
}),
};
}Your investigation notebook
1 of 12 results pinned. The notebook stays on this page only; export it before leaving. Exports include accepted settings, the exact seed, canonical units, typed statuses, source digest and snapshot identity. They are synthetic results, not experimental measurements.
- Result 1: 1 s; sample RMS 0.98602 μm; seed
1905.