# Differential entropy ## Microsim ### Live player <div class="microsim-player"> <iframe src="https://editor.p5js.org/sciencenibber/full/89fUuxHoL" width="100%" height="620" frameborder="0" sandbox="allow-scripts allow-same-origin"></iframe> </div> <div class="microsim-fallback"> <img src="Microsims/thumbs/Differential_entropy.png" alt="Differential_entropy microsim poster" style="width:100%;border:1px solid #4445;border-radius:6px;"> <p><em>Live microsim (desktop) · <a href="https://editor.p5js.org/sciencenibber/sketches/89fUuxHoL">open sketch in the p5.js editor</a></em></p> </div> **Editor URL:** https://editor.p5js.org/sciencenibber/sketches/89fUuxHoL **Description (100 words):** This sketch lets you watch the **differential entropy** h(X) = − ∫ f(x) log₂ f(x) dx swing in real time as you reshape one of four named continuous densities — Gaussian, Uniform, Exponential, or Laplace. The two sliders rescale (sigma) and shift (mu) the chosen family; the main panel plots f(x), the side panel sweeps h(X) versus sigma so you see the underlying log-of-spread relationship, and the bottom-left readout colours h(X) **green when positive, orange when negative**. Crank sigma below about 0.4 and the Gaussian peaks above f(x) = 1 — the dashed orange "above this line, h goes negative" guide shows exactly why that happens. ```js // ===================================================================== // Differential_entropy.js -- Wikitube microsim, Information room // --------------------------------------------------------------------- // ARTICLE Differential_entropy // ROOM Information // PATTERN E -- Entropy and information measures (Information sec.10) // AUTHORED 2026-04-30 (generative pipeline, scheduled run) // // PURPOSE // Visualise how the differential entropy // // h(X) = - integral f(x) log f(x) dx (in bits, log = log2) // // varies with the shape of a continuous probability density f(x). // The reader picks one of four canonical density families // (Gaussian, Uniform, Exponential, Laplace), drags two sliders that // scale and shift the density, and watches h(X) update in real time. // The teaching beat the sketch is built around: differential // entropy is NOT discrete entropy. It can be negative when the // density spikes above 1, and rescaling X by a constant a shifts // h by exactly log|a| -- the curve of h vs sigma in the side // panel is literally a log curve, no matter which family is loaded. // // CONTROLS (DOM, top-left of canvas) // Family select Gaussian / Uniform / Exponential / Laplace // sigma slider spread parameter (sigma for Gauss/Lapl, half-width // for Uniform, 1/lambda for Exponential). // mu slider location parameter (mean for Gauss/Lapl, centre // for Uniform, offset for Exponential). // reset button snap sigma=1, mu=0, family=Gaussian. // // READOUTS (HUD bottom-left) // h(X) in bits current differential entropy, rounded to 3 dp. // units note "negative h is OK -- see article". // sigma, mu echoed live so the reader can ground their // intuition against numeric values. // // EQUATION (HUD bottom-right, ASCII) // h(X) = - integral f(x) log2 f(x) dx // // PARAMETER TABLE // FAMILIES index into closed-form differential entropies: // Gaussian: 0.5 * log2(2*pi*e * sigma^2) // Uniform: log2(2*sigma) (width = 2*sigma) // Exponential:log2(e * sigma) (mean = sigma) // Laplace: log2(2*e * sigma) // SIGMA_RANGE 0.05 .. 4.0 (slider step 0.01) // MU_RANGE -3.0 .. 3.0 (slider step 0.05) // X_RANGE -6 .. 6 (canvas plot domain) // N_PLOT_SAMPLES 720 (curve resolution; 60-fps friendly) // // FILES // Local archive : Articles/Information/Microsims/Differential_entropy.js // Editor URL : captured live from window.location.href after save. // ===================================================================== const ARTICLE = "Differential_entropy"; p5.disableFriendlyErrors = true; // ---------- palette (Information room standard, sec.10) ------------- const BG = 246; const INK = [40, 48, 60]; const BAR = [70, 130, 200]; const EDGE = [120, 130, 150]; const TOKEN = [220, 110, 60]; const ACCEPT= [80, 180, 120]; const LOWP = [200, 205, 215]; // ---------- physical / informational constants ---------------------- const BASE = 2; // Shannon entropy is in bits const LN2 = Math.log(2); const TWO_PI_E = 2 * Math.PI * Math.E; // ---------- plot domain (data coordinates, not pixels) --------------- const X_MIN = -6, X_MAX = 6; const N_PLOT_SAMPLES = 720; // Side-panel "h vs sigma" sweep: const SIGMA_SWEEP_MIN = 0.05; const SIGMA_SWEEP_MAX = 4.0; const N_SWEEP = 220; // ---------- DOM controls (created in setup) ------------------------- let familySel, sigmaSlider, muSlider, resetBtn; let family = "Gaussian"; let sigma = 1.0; let mu = 0.0; function setup() { createCanvas(windowWidth, windowHeight); textFont("Helvetica"); textSize(13); noStroke(); // family select -- the four canonical "named" densities familySel = createSelect(); familySel.position(20, 60); familySel.option("Gaussian"); familySel.option("Uniform"); familySel.option("Exponential"); familySel.option("Laplace"); familySel.changed(() => { family = familySel.value(); }); // sigma slider -- 0.05 .. 4.0 (spread) sigmaSlider = createSlider(0.05, 4.0, 1.0, 0.01); sigmaSlider.position(20, 100); sigmaSlider.style("width", "200px"); // mu slider -- -3 .. 3 (location) muSlider = createSlider(-3.0, 3.0, 0.0, 0.05); muSlider.position(20, 140); muSlider.style("width", "200px"); // reset button -- snap to canonical Gaussian(0,1) resetBtn = createButton("reset"); resetBtn.position(20, 180); resetBtn.mousePressed(() => { family = "Gaussian"; familySel.selected("Gaussian"); sigmaSlider.value(1.0); muSlider.value(0.0); }); } // ---------- pdf evaluator: f(x | family, sigma, mu) ----------------- // Each branch is the textbook density. Domain checks are inline so // that, e.g., the Exponential is exactly zero left of mu rather than // silently producing NaN under the log. function pdf(x) { switch (family) { case "Gaussian": { // standard Gaussian density const z = (x - mu) / sigma; return Math.exp(-0.5 * z * z) / (sigma * Math.sqrt(2 * Math.PI)); } case "Uniform": { // uniform on [mu - sigma, mu + sigma]; height = 1 / (2*sigma) return (x >= mu - sigma && x <= mu + sigma) ? 1 / (2 * sigma) : 0; } case "Exponential": { // shifted exponential; mean = sigma; support x >= mu if (x < mu) return 0; return Math.exp(-(x - mu) / sigma) / sigma; } case "Laplace": { // Laplace (double-exponential); scale = sigma return Math.exp(-Math.abs(x - mu) / sigma) / (2 * sigma); } } return 0; } // ---------- closed-form differential entropy h(X) in bits ----------- // These are the textbook results -- see MacKay ITILA chap.8 and any // Cover & Thomas table. Using the closed form keeps the readout // numerically stable; the integral form is only used for the curve // shading (qualitative) below. function differentialEntropyBits() { switch (family) { case "Gaussian": return 0.5 * Math.log2(TWO_PI_E * sigma * sigma); case "Uniform": // h = log2(2 * sigma) return Math.log2(2 * sigma); case "Exponential": // h = log2(e * sigma) return Math.log2(Math.E * sigma); case "Laplace": // h = log2(2 * e * sigma) return Math.log2(2 * Math.E * sigma); } return 0; } // ---------- main draw loop ------------------------------------------ function draw() { background(BG); // pull slider values once at top of draw -- the math step // references them by information-theory name. sigma = sigmaSlider.value(); mu = muSlider.value(); // layout: main plot occupies the centre, side plot occupies right. const plotX = 250, plotY = 70; const plotW = width - 520, plotH = height - 200; drawDensityPlot(plotX, plotY, plotW, plotH); drawSweepPanel(width - 250, plotY, 220, plotH); drawControlsLabel(); drawHud(); drawReadouts(); } // ---------- main density plot --------------------------------------- function drawDensityPlot(x0, y0, w, h) { // panel background and frame noStroke(); fill(255); rect(x0, y0, w, h, 4); stroke(...EDGE, 80); strokeWeight(1); noFill(); rect(x0, y0, w, h, 4); // axis: x in [X_MIN, X_MAX], y in [0, yMax] // yMax adapts to the current max density so very narrow Gaussians // remain on screen (visualising the "negative h" case). let yMax = 0.001; for (let i = 0; i < N_PLOT_SAMPLES; i++) { const x = X_MIN + (X_MAX - X_MIN) * i / (N_PLOT_SAMPLES - 1); yMax = Math.max(yMax, pdf(x)); } // give a 10% headroom so the peak does not kiss the panel top yMax *= 1.10; // grid + zero-axis line stroke(...LOWP); strokeWeight(1); for (let g = 0; g <= 4; g++) { const yy = y0 + h * g / 4; line(x0, yy, x0 + w, yy); } for (let g = 0; g <= 6; g++) { const xx = x0 + w * g / 6; line(xx, y0, xx, y0 + h); } // the height-1 line: anything above this is where f(x) > 1, and the // local contribution to h is NEGATIVE. Painting it makes the // "differential entropy can be negative" beat visible. if (yMax > 1) { const yOne = y0 + h * (1 - 1 / yMax); stroke(...TOKEN); strokeWeight(1); drawingContext.setLineDash([6, 4]); line(x0, yOne, x0 + w, yOne); drawingContext.setLineDash([]); noStroke(); fill(...TOKEN); textAlign(LEFT, BOTTOM); textSize(11); text("f(x) = 1 (above => negative entropy contribution)", x0 + 8, yOne - 2); } // x-axis ticks every integer noStroke(); fill(...INK); textAlign(CENTER, TOP); textSize(11); for (let xi = Math.ceil(X_MIN); xi <= Math.floor(X_MAX); xi++) { const px = x0 + w * (xi - X_MIN) / (X_MAX - X_MIN); text(xi.toString(), px, y0 + h + 4); } // the density curve itself, drawn as an open polyline plus a // light fill underneath (alpha so the grid still shows through). noFill(); stroke(...BAR); strokeWeight(2); beginShape(); for (let i = 0; i < N_PLOT_SAMPLES; i++) { const x = X_MIN + (X_MAX - X_MIN) * i / (N_PLOT_SAMPLES - 1); const y = pdf(x); const px = x0 + w * (x - X_MIN) / (X_MAX - X_MIN); const py = y0 + h * (1 - y / yMax); vertex(px, py); } endShape(); // shaded fill under the curve noStroke(); fill(...BAR, 40); beginShape(); vertex(x0, y0 + h); for (let i = 0; i < N_PLOT_SAMPLES; i++) { const x = X_MIN + (X_MAX - X_MIN) * i / (N_PLOT_SAMPLES - 1); const y = pdf(x); const px = x0 + w * (x - X_MIN) / (X_MAX - X_MIN); const py = y0 + h * (1 - y / yMax); vertex(px, py); } vertex(x0 + w, y0 + h); endShape(CLOSE); // mu marker -- vertical line at the mean / centre const muPx = x0 + w * (mu - X_MIN) / (X_MAX - X_MIN); stroke(...TOKEN); strokeWeight(1.5); line(muPx, y0, muPx, y0 + h); // panel title noStroke(); fill(...INK); textAlign(LEFT, BOTTOM); textSize(12); text("density f(x) -- family = " + family, x0 + 6, y0 - 4); } // ---------- side panel: h(X) as sigma sweeps ------------------------ // This is the "single-formula readout" the standards (sec.10 Pattern // E reskin) ask for: a small entropy-vs-parameter curve that shows // the current point as a highlighted dot. function drawSweepPanel(x0, y0, w, h) { noStroke(); fill(255); rect(x0, y0, w, h, 4); stroke(...EDGE, 80); strokeWeight(1); noFill(); rect(x0, y0, w, h, 4); // sweep h vs sigma over [SIGMA_SWEEP_MIN, SIGMA_SWEEP_MAX] const orig = sigma; let yMin = Infinity, yMax = -Infinity; const samples = []; for (let i = 0; i < N_SWEEP; i++) { const s = SIGMA_SWEEP_MIN + (SIGMA_SWEEP_MAX - SIGMA_SWEEP_MIN) * i / (N_SWEEP - 1); sigma = s; const hv = differentialEntropyBits(); samples.push([s, hv]); yMin = Math.min(yMin, hv); yMax = Math.max(yMax, hv); } sigma = orig; // pad y range so the line never touches the frame const span = Math.max(0.5, yMax - yMin); yMin -= span * 0.05; yMax += span * 0.05; // axes: zero line in the y range gets a stronger stroke so the // viewer can see when h crosses through zero (the "negative // entropy" boundary). if (0 > yMin && 0 < yMax) { const yZero = y0 + h * (1 - (0 - yMin) / (yMax - yMin)); stroke(...EDGE); strokeWeight(1); line(x0, yZero, x0 + w, yZero); } // the sweep curve noFill(); stroke(...BAR); strokeWeight(1.5); beginShape(); for (const [s, hv] of samples) { const px = x0 + w * (s - SIGMA_SWEEP_MIN) / (SIGMA_SWEEP_MAX - SIGMA_SWEEP_MIN); const py = y0 + h * (1 - (hv - yMin) / (yMax - yMin)); vertex(px, py); } endShape(); // the current operating point -- a filled circle const hNow = differentialEntropyBits(); const px = x0 + w * (sigma - SIGMA_SWEEP_MIN) / (SIGMA_SWEEP_MAX - SIGMA_SWEEP_MIN); const py = y0 + h * (1 - (hNow - yMin) / (yMax - yMin)); noStroke(); fill(...TOKEN); circle(px, py, 9); // panel title and axis labels noStroke(); fill(...INK); textAlign(LEFT, BOTTOM); textSize(12); text("h(X) [bits] vs sigma", x0 + 6, y0 - 4); textAlign(LEFT, TOP); textSize(10); text("sigma -->", x0 + 6, y0 + h + 4); } // ---------- HUD: title block, equation, control hints --------------- function drawHud() { // top-left title block (article + wikitube URL) noStroke(); fill(0, 200); rect(8, 8, 380, 26); fill(255); textSize(13); textAlign(LEFT, TOP); text(ARTICLE + " :: en.wikitube.io/wiki/" + ARTICLE, 16, 14); // top-right control hint strip fill(0, 160); rect(width - 280, 8, 272, 26); fill(255); textAlign(LEFT, TOP); textSize(12); text("drag sliders | switch family | reset", width - 270, 14); // bottom-right equation strip fill(0, 160); rect(width - 380, height - 32, 372, 26); fill(255); textAlign(LEFT, TOP); textSize(12); text("h(X) = - integral f(x) log2 f(x) dx", width - 370, height - 26); } // ---------- readouts (bottom-left) ---------------------------------- function drawReadouts() { const hNow = differentialEntropyBits(); noStroke(); fill(0, 160); rect(8, height - 100, 360, 92); fill(255); textAlign(LEFT, TOP); textSize(12); text("family = " + family, 16, height - 94); text("sigma = " + sigma.toFixed(3), 16, height - 78); text("mu = " + mu.toFixed(3), 16, height - 62); // entropy readout coloured by sign so the negative case is loud fill(hNow < 0 ? color(...TOKEN) : color(...ACCEPT)); text("h(X) = " + hNow.toFixed(3) + " bits" + (hNow < 0 ? " (negative -- ok!)" : ""), 16, height - 46); fill(...LOWP); textSize(10); text("differential entropy is unitless once " + "you've fixed the units of X", 16, height - 22); textSize(13); } // labels for the DOM controls that live above the canvas function drawControlsLabel() { noStroke(); fill(...INK); textAlign(LEFT, TOP); textSize(12); text("density family", 20, 44); text("sigma (spread)", 20, 84); text("mu (location)",20, 124); } function windowResized() { resizeCanvas(windowWidth, windowHeight); } ``` ## Links (Wikipedia order) <!-- injected from _registry/childlinks/Differential_entropy.json (2026-07-30T02:09:12Z) --> `Absolute_continuity` · `Almost_everywhere` · `Asymptotic_equipartition_property` · `Beta_distribution` · `Beta_function` · `Bit` · [[Calculus_of_variations]] · `Cauchy_distribution` · `Change_of_variables` · `Channel_capacity` · `Chi-squared_distribution` · `Chi_distribution` · [[Conditional_entropy]] · `Conditional_mutual_information` · `Covariance` · `Digamma_function` · `Directed_information` · `Edwin_Thompson_Jaynes` · `Elementary_Principles_in_Statistical_Mechanics` · `Encyclopedia_of_Mathematics` · [[Entropy_(information_theory)]] · `Entropy_estimation` · `Entropy_rate` · `Erlang_distribution` · `Estimator` · `Exponential_distribution` · `Gamma_distribution` · `Gamma_function` · `If_and_only_if` · [[Information_theory]] · `Invariant_measure` · `Jacobian_matrix_and_determinant` · [[Joint_entropy]] · [[Josiah_Willard_Gibbs]] · `Kullback–Leibler_divergence` · `Laplace_distribution` · `Lebesgue_measure` · `Limiting_density_of_discrete_points` · `Log-normal_distribution` · `Logarithm` · `Logistic_distribution` · `Matrix_(mathematics)` · `Maxwell–Boltzmann_distribution` · `Multivariate_normal_distribution` · `Mutual_information` · [[Nat_(unit)]] · `Noisy-channel_coding_theorem` · `Normal_distribution` · `Pareto_distribution` · `Physical_Review_E` · `PlanetMath` · [[Probability_density_function]] · `Probability_measure` · `Quantile_function` · [[Quantization_(signal_processing)]] · `Rate–distortion_theory` · `Rayleigh_distribution` · `Shannon's_source_coding_theorem` · `Shannon–Hartley_theorem` · `Stack_Exchange` · `Student's_t-distribution` · `Support_(mathematics)` · `Triangular_distribution` · `Weibull_distribution` ## From the Real GENERATIVE library ![Differential entropy](https://upload.wikimedia.org/wikipedia/commons/thumb/2/23/Binaryerasurechannel.png/100px-Binaryerasurechannel.png) *Differential entropy — placed from the Real G.E.N.E.R.A.T.I.V.E. course library (Information room). Source: Wikimedia Commons (via Wikipedia article media). [Details & license](https://commons.wikimedia.org/wiki/File:Binaryerasurechannel.png).* > Differential entropy (also referred to as continuous entropy) is a concept in information theory that began as an attempt by Claude Shannon to extend the idea of (Shannon) entropy (a measure of average surprisal) of a random variable, to continuous probability distributions. Unfortunately, Shannon did not derive this formula, and rather just assumed it was t ([Wikipedia](https://en.wikipedia.org/wiki/Differential_entropy)) <!-- REAL-GENERATIVE-MEDIA:END --> <!-- LOCAL-MEDIA-PASS:START --> ## From the vault media library !Differential entropy thumb.png *Differential Entropy — from the vault's own media holdings, placed 2026-07-09. MTN / Wikitube.io original · CC BY-SA 4.0.* <!-- LOCAL-MEDIA-PASS:END --> > **Room:** [[Information]] · **Status:** ✅ shipped ## Overview **Differential entropy** is the continuous-variable analogue of Shannon's discrete [[Entropy|entropy]]. For a real-valued random variable X with probability [[Density|density]] function f(x), its differential entropy is h(X) = − ∫ f(x) log f(x) dx, measured in bits when log is base 2 and in nats when log is the natural logarithm. Introduced by [[Claude_Shannon|Claude Shannon]] in his 1948 paper *A Mathematical Theory of Communication*, it preserves many of the structural identities of the discrete case — chain rule, conditioning never increases it, mutual information stays non-negative — but it loses two properties readers usually take for granted. First, h(X) is **not invariant** under change of variables: rescaling X by a constant a shifts h by log|a|, so a differential entropy of −3.2 bits is meaningful only relative to the units of X. Second, h(X) **can be negative**, infinite, or undefined; a sharply peaked density (a tall narrow Gaussian, a delta-like spike) produces a negative value, signalling that the density itself exceeds 1 over some region. Among all continuous distributions on the real line with a fixed mean and variance, the Gaussian achieves the maximum differential entropy — the continuous analogue of the discrete uniform's maximality. This makes the Gaussian the natural noise floor for channel-capacity arguments and the entropy-maximising prior in maximum-entropy inference. ## See also - Room hub: [[Information]] - p5.js Editor conventions: P5 JS EDITOR - Wiki root: MAIN --- *Scaffolded by `generative-microsim` from row 0 of the Information sheet on 2026-04-30T13:39:25Z.* Letters: entropy · distribution · mined_density · exponential · mined_information · discretization · flow · mined_switch <!-- REAL-GENERATIVE-MEDIA:START --> <!-- CRAFT-LINK:START g12 --> *Built to the [[WT!P5_js_Microsim_Master_Class|p5.js Master Class]].* <!-- CRAFT-LINK:END --> ## Wikipedia : Wikitube **Strict pair:** [Wikipedia](https://en.wikipedia.org/wiki/Differential_entropy) : [Wikitube](https://en.wikitube.io/wiki/Differential_entropy) ## Previous hub tags Tree parent: [[Information_theory]]. Legacy hubs: `GENERATIVE`. --- *Sources: 1 legacy note. Minted wave 1, 2026-07-30 (v1.6 order).*