Code
renderShapeDemo(mu1_s, sigma1_s, mu2_s, sigma2_s, lambda_s)Fréchet means in Wasserstein space
By the end of this lecture, learners should be able to:
Wasserstein barycenters are Fréchet means in Wasserstein space. They are the appropriate notion of center when the observations are probability measures and the loss is squared optimal-transport distance.
Let \((\mathcal{X}, d)\) be a complete separable metric space and let \(\mathcal{P}_2(\mathcal{X})\) be equipped with \(W_2\). If \(\Lambda\) is a probability distribution on \(\mathcal{P}_2(\mathcal{X})\) satisfying
\[ \int_{\mathcal{P}_2(\mathcal{X})} W_2^2(\mu, \mu_0)\, d\Lambda(\mu) < \infty \]
for some, hence every, \(\mu_0 \in \mathcal{P}_2(\mathcal{X})\), then a population Wasserstein barycenter of \(\Lambda\) is any minimizer
\[ \bar{\mu} \in \arg\min_{\nu \in \mathcal{P}_2(\mathcal{X})} \Phi(\nu), \qquad \Phi(\nu) = \int_{\mathcal{P}_2(\mathcal{X})} W_2^2(\nu, \mu)\, d\Lambda(\mu). \]
Equivalently, if \(M \sim \Lambda\) is a random probability measure, then \(\bar{\mu}\) minimizes \(\mathbb{E}\, W_2^2(\nu, M)\) over \(\nu \in \mathcal{P}_2(\mathcal{X})\).
In the finite weighted case, where \(\Lambda = \sum_{i=1}^n \lambda_i \delta_{\mu_i}\) with \(\lambda_i > 0\) and \(\sum_i \lambda_i = 1\):
\[ \bar{\mu} \in \arg\min_{\nu \in \mathcal{P}_2(\mathcal{X})} \sum_{i=1}^n \lambda_i W_2^2(\nu, \mu_i). \]
Taking \(\lambda_i=1/n\) gives the Fréchet mean of the measures \(\mu_1, \ldots, \mu_n\).
If \(\mu_i = \delta_{x_i}\) are point masses in Euclidean space, then the barycenter is \(\delta_{\bar{x}}\) with \(\bar{x} = \sum_i \lambda_i x_i\), so the construction extends the ordinary weighted mean.
Barycenter vs. Density Average. A key insight behind Wasserstein barycenters is that they often preserve the shape of the input distributions, whereas a naive pointwise average of densities does not in general. The figure below illustrates this with two 1D Gaussians.
bary_shape_mu1_ctrl = Inputs.range([-3, 1], {step: 0.1, value: -1, label: "μ₁"})
bary_shape_sigma1_ctrl = Inputs.range([0.3, 2.5], {step: 0.1, value: 0.7, label: "σ₁"})
bary_shape_mu2_ctrl = Inputs.range([0, 4], {step: 0.1, value: 2, label: "μ₂"})
bary_shape_sigma2_ctrl = Inputs.range([0.3, 2.5], {step: 0.1, value: 1.0, label: "σ₂"})
bary_shape_lambda_ctrl = Inputs.range([0, 1], {step: 0.05, value: 0.5, label: "λ (barycenter weight)"})
mu1_s = Generators.input(bary_shape_mu1_ctrl)
sigma1_s = Generators.input(bary_shape_sigma1_ctrl)
mu2_s = Generators.input(bary_shape_mu2_ctrl)
sigma2_s = Generators.input(bary_shape_sigma2_ctrl)
lambda_s = Generators.input(bary_shape_lambda_ctrl)
shape_controls_view = html`
<style>
.shape-slider-row { display:flex; flex-wrap:wrap; gap:6px 16px; width:100%; margin:0 0 10px; font:0.85em system-ui,sans-serif; }
.shape-slider-row > * { flex:1 1 calc((100% - 48px)/4); min-width:140px; margin:0; }
@container (max-width:680px) { .shape-slider-row > * { flex-basis:calc((100% - 16px)/2); } }
@container (max-width:420px) { .shape-slider-row > * { flex-basis:100%; } }
</style>
<div class="shape-slider-row">
<div>${bary_shape_mu1_ctrl}</div>
<div>${bary_shape_sigma1_ctrl}</div>
<div>${bary_shape_mu2_ctrl}</div>
<div>${bary_shape_sigma2_ctrl}</div>
</div>
<div class="shape-slider-row">
<div style="flex:0 1 300px">${bary_shape_lambda_ctrl}</div>
</div>`
function gaussianPDF(x, mu, sigma) {
const z = (x - mu) / sigma;
return Math.exp(-0.5 * z * z) / (sigma * Math.sqrt(2 * Math.PI));
}
function renderShapeDemo(mu1, sigma1, mu2, sigma2, lambda) {
// Wasserstein barycenter parameters (closed-form for 1D Gaussians)
const muBar = lambda * mu1 + (1 - lambda) * mu2;
const sigmaBar = lambda * sigma1 + (1 - lambda) * sigma2;
// Evaluation grid
const xMin = Math.min(mu1 - 4*sigma1, mu2 - 4*sigma2) - 0.5;
const xMax = Math.max(mu1 + 4*sigma1, mu2 + 4*sigma2) + 0.5;
const n = 400;
const xs = Array.from({length: n}, (_, i) => xMin + (i / (n-1)) * (xMax - xMin));
const pdf1 = xs.map(x => gaussianPDF(x, mu1, sigma1));
const pdf2 = xs.map(x => gaussianPDF(x, mu2, sigma2));
const pdfBarWass = xs.map(x => gaussianPDF(x, muBar, sigmaBar));
const pdfAvg = xs.map((x, i) => lambda * pdf1[i] + (1 - lambda) * pdf2[i]);
const allY = [...pdf1, ...pdf2, ...pdfBarWass, ...pdfAvg];
const yMax = Math.max(...allY) * 1.12;
const margin = {top: 15, right: 20, bottom: 40, left: 50};
const svgW = 720, svgH = 320;
const plotW = svgW - margin.left - margin.right;
const plotH = svgH - margin.top - margin.bottom;
function xS(x) { return margin.left + (x - xMin) / (xMax - xMin) * plotW; }
function yS(y) { return margin.top + plotH - (y / yMax) * plotH; }
function lineData(xArr, yArr) {
let d = "";
for (let i = 0; i < xArr.length; i++) {
d += (i === 0 ? "M" : "L") + xS(xArr[i]).toFixed(2) + "," + yS(yArr[i]).toFixed(2);
}
return d;
}
const svgNS = "http://www.w3.org/2000/svg";
function elt(name, attrs) {
const e = document.createElementNS(svgNS, name);
for (const [k, v] of Object.entries(attrs)) e.setAttribute(k, v);
return e;
}
const svg = elt("svg", {width: svgW, height: svgH, style: "border:1px solid #dee2e6;border-radius:4px;max-width:100%;height:auto;"});
// Grid lines
const xTicks = 5;
for (let i = 0; i <= xTicks; i++) {
const xv = xMin + (i / xTicks) * (xMax - xMin);
svg.appendChild(elt("line", {x1: xS(xv), y1: margin.top, x2: xS(xv), y2: margin.top + plotH, stroke: "#e9ecef", "stroke-width": "1"}));
const txt = elt("text", {x: xS(xv), y: margin.top + plotH + 16, "text-anchor": "middle", "font-size": "10", fill: "#868e96"});
txt.textContent = xv.toFixed(1);
svg.appendChild(txt);
}
for (let i = 0; i <= 4; i++) {
const yv = (i / 4) * yMax;
svg.appendChild(elt("line", {x1: margin.left, y1: yS(yv), x2: margin.left + plotW, y2: yS(yv), stroke: "#e9ecef", "stroke-width": "1"}));
const txt = elt("text", {x: margin.left - 6, y: yS(yv) + 4, "text-anchor": "end", "font-size": "10", fill: "#868e96"});
txt.textContent = yv.toFixed(2);
svg.appendChild(txt);
}
// Axes
svg.appendChild(elt("line", {x1: margin.left, y1: margin.top, x2: margin.left, y2: margin.top + plotH, stroke: "#adb5bd"}));
svg.appendChild(elt("line", {x1: margin.left, y1: margin.top + plotH, x2: margin.left + plotW, y2: margin.top + plotH, stroke: "#adb5bd"}));
const xlbl = elt("text", {x: margin.left + plotW/2, y: svgH - 4, "text-anchor": "middle", "font-size": "11", fill: "#495057"});
xlbl.textContent = "x";
svg.appendChild(xlbl);
const ylbl = elt("text", {x: 12, y: margin.top + plotH/2, "text-anchor": "middle", "font-size": "11", fill: "#495057", transform: `rotate(-90, 12, ${margin.top + plotH/2})`});
ylbl.textContent = "Density";
svg.appendChild(ylbl);
// Draw curves
// μ₁ — dashed red
const p1 = elt("path", {d: lineData(xs, pdf1), fill: "none", stroke: "#e03131", "stroke-width": "2", "stroke-dasharray": "6,3"});
svg.appendChild(p1);
// μ₂ — dashed blue
const p2 = elt("path", {d: lineData(xs, pdf2), fill: "none", stroke: "#1971c2", "stroke-width": "2", "stroke-dasharray": "6,3"});
svg.appendChild(p2);
// Density average — dotted purple (bimodal when separated)
const pAvg = elt("path", {d: lineData(xs, pdfAvg), fill: "none", stroke: "#ae3ec9", "stroke-width": "2.5", "stroke-dasharray": "2,4"});
svg.appendChild(pAvg);
// Wasserstein barycenter — solid green (Gaussian shape preserved)
const pWass = elt("path", {d: lineData(xs, pdfBarWass), fill: "none", stroke: "#2b8a3e", "stroke-width": "3"});
svg.appendChild(pWass);
// Light fill under the barycenter
const areaWass = lineData(xs, pdfBarWass) + "L" + xS(xs[xs.length-1]).toFixed(2) + "," + yS(0).toFixed(2) + "L" + xS(xs[0]).toFixed(2) + "," + yS(0).toFixed(2) + "Z";
svg.appendChild(elt("path", {d: areaWass, fill: "rgba(43,138,62,0.08)", stroke: "none"}));
// μ_bar vertical reference line
svg.appendChild(elt("line", {x1: xS(muBar), y1: margin.top, x2: xS(muBar), y2: margin.top + plotH, stroke: "#2b8a3e", "stroke-width": "0.8", "stroke-dasharray": "4,4", opacity: "0.5"}));
// Legend
const lx = margin.left + 10, ly = margin.top + 8;
const items = [
["μ₁", "#e03131", "6,3"],
["μ₂", "#1971c2", "6,3"],
["Barycenter (Wasserstein)", "#2b8a3e", null],
["Density average", "#ae3ec9", "2,4"]
];
items.forEach(([label, color, dash], i) => {
const g = document.createElementNS(svgNS, "g");
g.setAttribute("transform", `translate(${lx}, ${ly + i * 24})`);
const line = elt("line", {x1: 0, y1: 7, x2: 22, y2: 7, stroke: color, "stroke-width": i === 2 ? "3" : "2"});
if (dash) line.setAttribute("stroke-dasharray", dash);
g.appendChild(line);
const txt = elt("text", {x: 28, y: 11, "font-size": "10.5", fill: "#212529"});
txt.textContent = label;
g.appendChild(txt);
svg.appendChild(g);
});
// Annotation for bimodality when distributions are well-separated
if (Math.abs(mu1 - mu2) > 2.5 * (sigma1 + sigma2)) {
const midIdx = Math.floor(n / 2);
const annX = xS(xs[midIdx]);
const annY = yS(pdfAvg[midIdx] * 0.55);
const txtAnn = elt("text", {x: annX, y: annY, "text-anchor": "middle", "font-size": "11", fill: "#ae3ec9", "font-style": "italic", "font-weight": "600"});
txtAnn.textContent = "bimodal!";
svg.appendChild(txtAnn);
}
// Summary stats below the chart
const statsDiv = document.createElement("div");
statsDiv.style.cssText = "display:flex;gap:24px;flex-wrap:wrap;margin-top:10px;font-size:0.88em;";
statsDiv.innerHTML = `
<span><span style="color:#2b8a3e;font-weight:600;">■ Barycenter:</span> N(${muBar.toFixed(2)}, ${sigmaBar.toFixed(2)}²)</span>
<span><span style="color:#ae3ec9;font-weight:600;">··· Density avg:</span> <em>not</em> Gaussian</span>
<span style="color:#868e96;">μ<sub>bar</sub> = λμ₁ + (1−λ)μ₂,  σ<sub>bar</sub> = λσ₁ + (1−λ)σ₂</span>`;
const wrapper = document.createElement("div");
wrapper.style.maxWidth = "740px";
wrapper.style.fontFamily = "system-ui, sans-serif";
wrapper.appendChild(svg);
wrapper.appendChild(statsDiv);
return wrapper;
}When \(\mathcal{X} = \mathbb{R}\), the quantile representation gives an explicit closed-form solution. Let \(Q_\mu = F_\mu^{-1}\) denote the quantile function of \(\mu\). Since the map \(\mu \mapsto Q_\mu\) embeds \(\mathcal{P}_2(\mathbb{R})\) isometrically into the closed convex cone of nondecreasing functions in \(L^2(0, 1)\),
\[ W_2^2(\mu, \nu) = \int_0^1 \{Q_\mu(u) - Q_\nu(u)\}^2\, du. \]
The barycenter is therefore unique and has quantile function
\[ Q_{\bar{\mu}}(u) = \int_{\mathcal{P}_2(\mathbb{R})} Q_\mu(u)\, d\Lambda(\mu), \qquad 0 < u < 1, \]
provided the right side is square-integrable. In the finite case this becomes
\[ Q_{\bar{\mu}}(u) = \sum_{i=1}^n \lambda_i Q_{\mu_i}(u). \]
The pointwise average of nondecreasing quantile functions is again nondecreasing, so it defines a valid probability distribution.
This identity is the main reason univariate Wasserstein means are much simpler than their higher-dimensional analogues: the barycenter is simply the pointwise quantile average. This underlies many statistical procedures for distribution-valued data (Petersen and Müller 2016; Panaretos and Zemel 2020).
If \(\mu_i = N(m_i, \Sigma_i)\) are Gaussian measures on \(\mathbb{R}^D\), then their Wasserstein barycenter is again Gaussian, \(\bar{\mu} = N(\bar{m}, \bar{\Sigma})\), with
\[ \bar{m} = \sum_{i=1}^m \lambda_i m_i, \]
and covariance matrix determined by the Bures–Wasserstein fixed-point equation
\[ \bar{\Sigma} = \sum_{i=1}^m \lambda_i \bigl(\bar{\Sigma}^{1/2} \Sigma_i \bar{\Sigma}^{1/2}\bigr)^{1/2}. \]
This example shows that Wasserstein barycenters average both locations and distributional shapes, not just pointwise density values (Agueh and Carlier 2011; Panaretos and Zemel 2020).
For nondegenerate Gaussians \(N(m_0, \Sigma_0)\) and \(N(m_1, \Sigma_1)\), the optimal transport map is affine:
\[ T_{0 \to 1}(x) = m_1 + \Sigma_0^{-1/2} \bigl(\Sigma_0^{1/2} \Sigma_1 \Sigma_0^{1/2}\bigr)^{1/2} \Sigma_0^{-1/2}(x - m_0). \]
Theorem 1 Let \(p \ge 1\) and let \((E, d)\) be a separable locally compact geodesic space. Let \(\Lambda\) be a probability measure on \(\mathcal{W}_p(E)\) such that
\[ \int_{\mathcal{W}_p(E)} W_p^p(\mu, \mu_0)\, d\Lambda(\mu) < \infty \]
for some, hence every, \(\mu_0 \in \mathcal{W}_p(E)\). Then there exists at least one barycenter \(\bar{\mu}_\Lambda \in \mathcal{W}_p(E)\).
Uniqueness is more subtle. Wasserstein barycenters may not be unique in general — \(\mathcal{P}_2(\mathbb{R}^d)\) with \(d \ge 2\) has nonnegative Alexandrov curvature rather than the nonpositive curvature that would force strict convexity of squared distance.
Let \(M_1, M_2, \ldots\) be i.i.d. random probability measures with law \(\Lambda\), and define the empirical law
\[ \Lambda_n = \frac{1}{n}\sum_{i=1}^n \delta_{M_i}. \]
A sample Wasserstein barycenter is any minimizer
\[ \hat{\mu}_n \in \arg\min_{\nu \in \mathcal{P}_2(\mathcal{X})} \frac{1}{n}\sum_{i=1}^n W_2^2(\nu, M_i). \]
Let \(\mathsf{W}_2\) denote the Wasserstein distance on \(\mathcal{W}_2(E)\) itself (using \(W_2\) as the ground metric). By the strong law of large numbers and Villani’s Theorem 6.9,
\[ \mathsf{W}_2(\Lambda_n, \Lambda) \to 0 \qquad \text{a.s.} \]
Let \(\operatorname{Bar}_2(\Lambda_n)\) denote the set of empirical 2-Wasserstein barycenters, i.e.,
\[ \operatorname{Bar}_2(\Lambda_n) \coloneqq \arg\min_{\nu \in \mathcal{P}_2(\mathcal{X})} \frac{1}{n}\sum_{i=1}^n W_2^2(\nu, M_i). \]
Theorem 2 If the population barycenter \(\bar{\mu}_\Lambda\) is unique and sample barycenters \(\hat{\mu}_n \in \operatorname{Bar}_2(\Lambda_n)\), then
\[ W_2(\hat{\mu}_n, \bar{\mu}_\Lambda) \to 0 \qquad \text{a.s.} \]
In \(\mathbb{R}^d\), the uniqueness condition holds if \(\Lambda\) assigns positive probability to absolutely continuous ground-space distributions (Le Gouic and Loubes 2017, Proposition 6).
In \(\mathcal{W}_2(\mathbb{R})\), the quantile representation gives
\[ Q_{\hat{\mu}_n}(u) = \frac{1}{n}\sum_{i=1}^n Q_{M_i}(u), \qquad Q_{\bar{\mu}}(u) = \mathbb{E}\{Q_M(u)\}. \]
Hence
\[ \mathbb{E}\, W_2^2(\hat{\mu}_n, \bar{\mu}) = \frac{1}{n}\int_0^1 \operatorname{Var}\{Q_M(u)\}\, du, \]
so the squared error is \(O(n^{-1})\) and the distance is \(O(n^{-1/2})\). This parametric rate reflects the Hilbert-space structure of the quantile embedding — the barycenter is simply a sample mean in \(L^2(0,1)\).
\(\alpha\)-Strong Convexity and \(\beta\)-Smoothness. The convergence rate of sample Wasserstein barycenters depends on the geometric regularity of the transport maps pushing \(\bar{\mu}\) to each input measure. The key structural conditions are strong convexity and smoothness of the potentials whose gradients realize these maps.
Definition 1 Let \(\alpha > 0\). A differentiable function \(f: \mathbb{R}^d \to \mathbb{R}\) is \(\alpha\)-strongly convex if for all \(x, y \in \mathbb{R}^d\),
\[ f(y) \ge f(x) + \langle\nabla f(x),\, y - x\rangle + \frac{\alpha}{2}\|y - x\|^2. \]
Equivalently, \(\nabla^2 f(x) \succeq \alpha I_d\) (in the sense of Loewner order) wherever the Hessian exists, meaning all eigenvalues of the Hessian are bounded below by \(\alpha\).
Strong convexity quantitatively strengthens ordinary convexity (\(f(y) \ge f(x) + \langle\nabla f(x), y - x\rangle\)). The quadratic penalty \(\frac{\alpha}{2}\|y-x\|^2\) ensures the function curves at least as sharply as \(\frac{\alpha}{2}\|x\|^2\). Geometrically, the gradient map \(\nabla f\) is strictly expanding: \(\langle\nabla f(y) - \nabla f(x), y - x\rangle \ge \alpha\|y - x\|^2\), which guarantees injectivity of \(\nabla f\) and a well-behaved inverse.
Definition 2 Let \(\beta > 0\). A differentiable function \(f: \mathbb{R}^d \to \mathbb{R}\) is \(\beta\)-smooth if its gradient is \(\beta\)-Lipschitz continuous:
\[ \|\nabla f(x) - \nabla f(y)\| \le \beta\,\|x - y\|, \qquad \forall x, y \in \mathbb{R}^d. \]
Equivalently, \(\nabla^2 f(x) \preceq \beta I_d\) wherever the Hessian exists, and
\[ f(y) \le f(x) + \langle\nabla f(x),\, y - x\rangle + \frac{\beta}{2}\|y - x\|^2. \]
Whereas strong convexity provides a lower quadratic bound, smoothness provides an upper quadratic bound. Together, the two conditions sandwich \(f\) between quadratics with curvatures \(\alpha\) and \(\beta\). The ratio \(\beta/\alpha \ge 1\) is the condition number of \(f\).
When each \(\mu \in \operatorname{supp}(\Lambda)\) is the pushforward of \(\bar{\mu}\) by \(T_\mu = \nabla\phi_\mu\) — the gradient of a convex potential — the regularity of \(\phi_\mu\) controls how much the geometry of \(\mathcal{P}_2(\mathbb{R}^d)\) near \(\bar{\mu}\) resembles a Hilbert space. Brenier’s theorem (Panaretos and Zemel 2020, sec. 2.3) guarantees that optimal transport maps between absolutely continuous measures are exactly of this gradient-of-convex-potential form.
The \(\alpha\)-strong convexity defined here is the classical Euclidean notion — a lower quadratic bound on the function via its gradient. This is distinct from the geodesic \(\lambda\)-strong convexity introduced in Lecture 2, which applies to functions on arbitrary geodesic metric spaces:
\[ f(\gamma(t)) \le (1-t)f(\gamma(0)) + t f(\gamma(1)) - \lambda\,t(1-t)\,d^2(\gamma(0), \gamma(1)), \]
where \(\gamma: [0,1] \to \mathcal{M}\) is a geodesic. The two notions coincide when \(\mathcal{M} = \mathbb{R}^d\) with the Euclidean metric and \(f\) is differentiable — in that case the geodesic inequality reduces to the gradient inequality with \(\lambda = \alpha\).
In \(d \ge 2\), the Wasserstein space lacks the flat Hilbert geometry of the 1D case, and convergence rates depend on the curvature of the transport maps from the barycenter. Le Gouic et al. (2023) showed that if each \(\mu \in \operatorname{supp}(\Lambda)\) is the pushforward of \(\bar{\mu}\) by the gradient of an \(\alpha\)-strongly convex and \(\beta\)-smooth potential \(\phi_\mu\), i.e.
\[ \mu = (\nabla\phi_\mu)_{\#}\bar{\mu}, \]
then the sample barycenter attains the parametric rate, with a constant governed by the gap \(\beta - \alpha\).
Theorem 3 If \(\beta - \alpha < 1\), then
\[ \mathbb{E}\, W_2^2(\hat{\mu}_n, \bar{\mu}) \le \frac{4\sigma^2}{(1 - \beta + \alpha)^2\, n}, \]
where \(\sigma^2 = \int_{\mathcal{P}_2(\mathbb{R}^d)} W_2^2(\mu, \bar{\mu})\, d\Lambda(\mu)\) is the population variance in Wasserstein space.
For Gaussian measures, the transport maps are affine and the regularity parameters are determined by the eigenvalue spread of the covariance matrices. If all input covariances have eigenvalues in \([\kappa_0, \kappa_1]\) and we set \(\kappa = \kappa_1 / \kappa_0 \ge 1\), then:
\[ \mathbb{E}\, W_2^2(\hat{\mu}_n, \bar{\mu}) \le \frac{4\sigma^2}{(1 - \kappa + \kappa^{-1})^2\, n}, \]
provided \(\kappa - \kappa^{-1} < 1\). This is exactly the higher-dimensional bound with the transport-map regularity gap \(\beta - \alpha\) replaced by the eigenvalue condition-number gap \(\kappa - \kappa^{-1}\). The condition \(\kappa - \kappa^{-1} < 1\) (equivalently \(\kappa < \frac{1+\sqrt{5}}{2} \approx 1.618\)) requires the covariance matrices to be moderately well-conditioned — extreme anisotropy in the input measures can degrade the convergence rate.
Computing Wasserstein barycenters is substantially harder than computing Euclidean means. Three main paradigms exist, each with different trade-offs between accuracy, speed, and scalability. For a comprehensive treatment, see Peyré and Cuturi (2019), Chapters 4 and 9.
For discrete inputs, the barycenter problem is a linear program (LP) once the barycenter support locations are fixed. Suppose each \(\mu_i\) is supported on \(\{x_{i1},\ldots,x_{i n_i}\}\) with probability vector \(a_i\), and restrict the barycenter to \(\{z_1,\ldots,z_L\}\) with unknown weight vector \(b\). Let \(C_{i\ell k} = \|z_\ell - x_{ik}\|^2\) be the transport cost. The fixed-support barycenter LP is:
\[ \begin{aligned} \min_{b,\;\pi_1,\ldots,\pi_m} \quad & \sum_{i=1}^m \lambda_i \sum_{\ell=1}^{L} \sum_{k=1}^{n_i} C_{i\ell k}\,\pi_{i\ell k} \\ \text{subject to} \quad & \pi_i \mathbf{1}_{n_i} = b, \qquad \pi_i^\mathsf{T} \mathbf{1}_L = a_i, \qquad \pi_i \ge 0, \qquad i=1,\ldots,m, \end{aligned} \]
where \(b \ge 0\), \(\sum_\ell b_\ell = 1\), and \(\pi_i\) is the coupling between the barycenter and \(\mu_i\). The constraints enforce that each \(\pi_i\) has the barycenter weights \(b\) as its first marginal and the input weights \(a_i\) as its second marginal — all input measures couple to the same \(b\), which is the discrete barycenter.
Complexity. The formulation has \(L+\sum_i L n_i\) variables before eliminating \(b\), and \(\sum_i(L+n_i)\) displayed marginal equalities (with linear dependencies). Thus even writing the dense coupling variables and costs requires \(O(\sum_i L n_i)\) storage. General-purpose interior-point methods have polynomial worst-case complexity (Nesterov and Nemirovskii 1994), while transportation and network-flow structure can be exploited by specialized solvers (Ahuja and Orlin 1992). The actual running time depends strongly on sparsity and the solver, so there is no universal cubic running-time formula in \(mL\bar n\). Exact LP is consequently most useful for modest supports or as a reference solution.
Choice of the barycenter support. The LP formulation requires fixing \(\{z_\ell\}\) in advance. A grid over the convex hull or the union of the input supports gives a restricted, generally approximate barycenter. For quadratic cost, an exact discrete barycenter can be sought on the much larger candidate set of weighted averages \(\sum_i\lambda_i x_{i k_i}\), but that set can contain as many as \(\prod_i n_i\) points (Peyré and Cuturi 2019, sec. 9.2). Alternatively, one can alternate between optimizing the weights/couplings and moving a prescribed number of support locations; this is a free-support, nonconvex optimization rather than a single LP. A coarse or otherwise misspecified candidate support introduces discretization error even when the restricted LP is solved exactly.
When measures are absolutely continuous (or approximated by large discrete samples), the fixed-point iteration of Álvarez-Esteban et al. (2016) avoids discretizing the barycenter support in advance by iteratively updating the barycenter via averaged transport maps.
Input: Measures \(\mu_1,\ldots,\mu_m\), weights \(\lambda_i\), initial guess \(\nu^{(0)}\).
Repeat for \(t = 0, 1, 2, \ldots\):
Compute transport maps. For each \(i\), compute the optimal transport map \(T_i^{(t)}\) from the current iterate \(\nu^{(t)}\) to \(\mu_i\). In \(\mathbb{R}^d\), if \(\nu^{(t)}\) is absolutely continuous, Brenier’s theorem guarantees \(T_i^{(t)} = \nabla\phi_i^{(t)}\) for a convex potential \(\phi_i^{(t)}\).
Form the barycentric map. Define the weighted average \[ T^{(t)}(x) = \sum_{i=1}^m \lambda_i\, T_i^{(t)}(x). \]
Push forward. Update the iterate: \[ \nu^{(t+1)} \leftarrow T^{(t)}_{\#}\nu^{(t)}. \]
Until \(\|T^{(t)}(x) - x\|\) is sufficiently small (in \(L^2(\nu^{(t)})\)).
Why it works. At the true barycenter \(\bar{\mu}\), the first-order optimality condition is
\[ \sum_{i=1}^m \lambda_i\,T_i(x) = x \qquad \bar{\mu}\text{-a.e.}, \]
where \(T_i\) is the optimal map from \(\bar{\mu}\) to \(\mu_i\) under the absolute-continuity hypotheses above (Agueh and Carlier 2011, Proposition 3.8 and Remark 3.9). Hence \(\bar{\mu}\) is a fixed point of the update \(\nu \mapsto (\sum \lambda_i T_i^\nu)_\#\nu\). The algorithm is a generalized Procrustes procedure: at each step it computes the best way to align the current guess with each input, averages the alignments, and uses the result as the new guess.
Convergence. The rigorous result is more conditional than the fixed-point intuition suggests. Álvarez-Esteban et al. (2016), Theorem 3.6, assume that all targets are absolutely continuous, at least one has a bounded density, and the initial measure is absolutely continuous. They prove tightness of the iterates and show that every subsequential limit is a fixed point of the update. Convergence in \(W_2\) to the barycenter follows if the update operator has a unique fixed point. A fixed point need not be a barycenter in complete generality, so compact support alone does not give the convergence claim. In the Gaussian and, more generally, location-scatter settings treated in that paper, the iteration does converge to the barycenter.
Each exact step requires solving \(m\) optimal-transport problems, which can be done in parallel.
Entropic regularization (Cuturi and Doucet 2014) makes the discrete coupling subproblems strictly convex and gives them a matrix-scaling structure, enabling fast parallel implementations.
Regularized fixed-support problem. To match the iterative Bregman-projection algorithm below, define the discrete entropic transport cost using entropy relative to a fixed counting reference:
\[ \operatorname{OT}_\varepsilon(b,a_i) = \min_{\pi_i\mathbf 1=b,\;\pi_i^\mathsf T\mathbf 1=a_i} \left\{ \langle C_i,\pi_i\rangle +\varepsilon\sum_{\ell,k}\pi_{i\ell k} \bigl(\log\pi_{i\ell k}-1\bigr) \right\}, \qquad \min_{b\in\Delta_L}\sum_{i=1}^m\lambda_i \operatorname{OT}_\varepsilon(b,a_i). \]
Changing the reference measure changes terms that depend on the unknown \(b\) and therefore changes the regularized barycenter. In particular, the frequently used penalty \(\mathrm{KL}(\pi_i\|b\otimes a_i)\) is not interchangeable with the entropy above when \(b\) is being optimized.
The optimal coupling has the scaling form
\[ \pi_{i\ell k} = u_{i\ell}\, K_{i\ell k}\, v_{ik}, \]
where \(K_{i\ell k} = \exp(-\|z_\ell - x_{ik}\|^2 / \varepsilon)\) is the Gibbs kernel and \((u_i, v_i)\) are positive scaling vectors. This factorized form is the key computational advantage.
Input: Discrete measures \(\mu_i\) with supports \(\{x_{ik}\}\) and weights \(a_i\), target support \(\{z_\ell\}\), regularization \(\varepsilon > 0\), weights \(\lambda_i\).
Initialise: \(u_i\leftarrow\mathbf 1_L\) and \(v_i\leftarrow\mathbf 1_{n_i}\) for all \(i\).
Repeat:
Project onto the known input marginals. For each \(i\), \[ v_i \leftarrow \frac{a_i}{K_i^\mathsf{T}u_i}. \]
Project onto a common barycenter marginal. Compute the weighted geometric mean of the current first marginals, \[ b \leftarrow \prod_{i=1}^m \bigl[u_i\odot(K_i v_i)\bigr]^{\lambda_i}, \qquad u_i \leftarrow \frac{b}{K_i v_i}, \] where products, powers, and divisions are componentwise.
Until the marginal residuals (or the change in \(b\)) are sufficiently small (Benamou et al. 2015, sec. 3.2).
This is an instance of iterative Bregman projections: Step 1 projects all couplings onto their prescribed input marginals, and Step 2 projects them onto the constraint that their first marginals agree. Alternating KL projections converge to the regularized solution when the Gibbs kernels are positive (Benamou et al. 2015). A dense projection sweep costs \(O(\sum_i L n_i)\) arithmetic operations and has the same order of storage if all kernels are materialized. The number of sweeps is problem- and tolerance-dependent and typically increases as \(\varepsilon\) decreases; a general linear rate does not follow from the alternating-projection result.
Regularization bias. For a fixed finite problem, regularized minimizers approach unregularized minimizers as \(\varepsilon\downarrow0\) (with the usual qualification that the unregularized minimizer may not be unique). Smaller \(\varepsilon\) reduces this bias but makes the kernels more ill-conditioned and matrix scaling slower. There is no universal \(W_2(\bar\mu_\varepsilon,\bar\mu)=O(\varepsilon^{1/2})\) barycenter bound, nor a universal \(O(1/\varepsilon)\) iteration count, under only compact support. With the entropy convention above, large \(\varepsilon\) favors diffuse couplings and a high-entropy barycenter; on a fixed finite support the barycenter tends toward uniform weights as the entropy term dominates.
Practical considerations:
Log-domain stabilisation. For small \(\varepsilon\), the kernel entries \(K_{i\ell k} = \exp(-\|z_\ell - x_{ik}\|^2/\varepsilon)\) underflow to zero in floating point. The standard fix is to run Sinkhorn in log-space using the logsumexp operation (Schmitzer 2019; Peyré and Cuturi 2019, sec. 4.4).
Debiasing. Entropic OT has a nonzero self-cost and commonly produces overly diffuse or blurred barycenters. The Sinkhorn divergence corrects both arguments symmetrically: \[ S_\varepsilon(\mu,\nu) = \operatorname{OT}_\varepsilon(\mu,\nu) - \frac12\operatorname{OT}_\varepsilon(\mu,\mu) - \frac12\operatorname{OT}_\varepsilon(\nu,\nu). \] A debiased Sinkhorn barycenter minimizes \(\sum_i\lambda_iS_\varepsilon(\nu,\mu_i)\). Its important extra term is \(-\frac12\operatorname{OT}_\varepsilon(\nu,\nu)\), which depends on the candidate barycenter. Subtracting only the input self-costs would add a constant and could not alter the minimizer. Debiased barycenters require a modified scaling algorithm (Janati et al. 2020).
Scalability and GPU. The Sinkhorn algorithm uses matrix-vector products and elementwise operations, which parallelize well on GPUs. Dense kernels still require \(O(\sum_iLn_i)\) memory and work per sweep; very large supports require additional structure such as convolutional kernels on grids, low-rank approximations, sparsity, or lazy kernel evaluation.
Free-support barycenters. The Sinkhorn algorithm as stated fixes the barycenter support \(\{z_\ell\}\). When the support should also be learned, one can alternate regularized coupling solves with updates of the support locations (Cuturi and Doucet 2014, sec. 4). The joint problem is nonconvex, so this procedure generally guarantees only a stationary/local solution.
| Method | Accuracy | Speed | Support size | Key reference |
|---|---|---|---|---|
| Fixed-support LP | Exact for the chosen support (to solver tolerance) | General LP solve; coupling storage \(O(\sum_iLn_i)\) | Limited by LP variables and sparsity | Peyré and Cuturi (2019), Ch. 9 |
| Fixed-point iteration | Exact only under its continuous-map assumptions; discrete projection is approximate | Requires \(m\) OT solves per outer iteration | No fixed spatial grid; atom count chosen by the user | Álvarez-Esteban et al. (2016) |
| Entropic Sinkhorn | Solves a regularized fixed-support problem; approaches exact OT as \(\varepsilon\downarrow0\) | Dense sweep \(O(\sum_iLn_i)\); highly parallel | Limited by kernel storage unless structure is exploited | Cuturi and Doucet (2014); Benamou et al. (2015) |
dist1_type_control = Inputs.select(["normal", "uniform", "exponential", "beta"], {value: "normal", label: "Distribution 1 type"})
dist1_mu_control = Inputs.range([-3, 3], {step: 0.1, value: -1, label: "Dist 1 location"})
dist1_sigma_control = Inputs.range([0.2, 3], {step: 0.1, value: 0.8, label: "Dist 1 scale"})
dist2_type_control = Inputs.select(["normal", "uniform", "exponential", "beta"], {value: "normal", label: "Distribution 2 type"})
dist2_mu_control = Inputs.range([-3, 3], {step: 0.1, value: 2, label: "Dist 2 location"})
dist2_sigma_control = Inputs.range([0.2, 3], {step: 0.1, value: 1.2, label: "Dist 2 scale"})
lambda1_control = Inputs.range([0, 1], {step: 0.05, value: 0.5, label: "Weight λ₁ (λ₂ = 1-λ₁)"})
dist1_type = Generators.input(dist1_type_control)
dist1_mu = Generators.input(dist1_mu_control)
dist1_sigma = Generators.input(dist1_sigma_control)
dist2_type = Generators.input(dist2_type_control)
dist2_mu = Generators.input(dist2_mu_control)
dist2_sigma = Generators.input(dist2_sigma_control)
lambda1 = Generators.input(lambda1_control)
bary_controls_view = html`
<style>
.bary-slider-grid { display:flex; flex-wrap:wrap; gap:6px 20px; width:100%; margin:0 0 12px; font:0.85em system-ui,sans-serif; container-type:inline-size; }
.bary-slider-grid > * { flex:1 1 calc((100% - 40px)/3); min-width:0; margin:0; }
.bary-slider-grid input[type="number"] { width:7.5rem !important; }
@container (max-width:700px) { .bary-slider-grid > * { flex-basis:calc((100% - 20px)/2); } }
@container (max-width:480px) { .bary-slider-grid > * { flex-basis:100%; } }
</style>
<div class="bary-slider-grid">
<div>${dist1_type_control}</div>
<div>${dist1_mu_control}</div>
<div>${dist1_sigma_control}</div>
<div>${dist2_type_control}</div>
<div>${dist2_mu_control}</div>
<div>${dist2_sigma_control}</div>
<div>${lambda1_control}</div>
</div>`
function barySvgFragment(markup) {
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
svg.innerHTML = markup;
const fragment = document.createDocumentFragment();
while (svg.firstChild) fragment.appendChild(svg.firstChild);
return fragment;
}
function qml(p, typ, mu, sig) {
const pp = Math.min(1 - 1e-12, Math.max(1e-12, p));
if (typ === "normal") {
// Winitzki's inverse-erf approximation, transformed to a normal quantile.
const x = 2 * pp - 1;
const a = 0.147;
const logTerm = Math.log(1 - x * x);
const t = 2 / (Math.PI * a) + logTerm / 2;
const erfInv = Math.sign(x) * Math.sqrt(Math.sqrt(t * t - logTerm / a) - t);
return mu + sig * Math.SQRT2 * erfInv;
} else if (typ === "uniform") {
return mu - sig + 2 * sig * pp;
} else if (typ === "exponential") {
return mu - sig * Math.log(1 - pp);
} else if (typ === "beta") {
// Invert the exact Beta(2,5) CDF: F(x) = 1-(1-x)^5(1+5x).
let lo = 0, hi = 1;
for (let k = 0; k < 40; k++) {
const mid = (lo + hi) / 2;
const cdf = 1 - (1 - mid) ** 5 * (1 + 5 * mid);
if (cdf < pp) lo = mid; else hi = mid;
}
return mu + sig * ((lo + hi) / 2 - 2 / 7);
}
return mu;
}
function runBarycenterDemo(type1, mu1, sigma1, type2, mu2, sigma2, weight1) {
const nGrid = 200;
// Midpoints avoid evaluating unbounded quantile functions at u=0 or u=1.
const uGrid = Array.from({length: nGrid}, (_, j) => (j + 0.5) / nGrid);
const q1 = uGrid.map(u => qml(u, type1, mu1, sigma1));
const q2 = uGrid.map(u => qml(u, type2, mu2, sigma2));
const qBar = uGrid.map((u, i) => weight1 * q1[i] + (1 - weight1) * q2[i]);
// Compute W2 distances
let w2_12 = 0, w2_1bar = 0, w2_2bar = 0;
const du = 1 / nGrid;
for (let i = 0; i < nGrid; i++) {
w2_12 += (q1[i] - q2[i]) ** 2 * du;
w2_1bar += (q1[i] - qBar[i]) ** 2 * du;
w2_2bar += (q2[i] - qBar[i]) ** 2 * du;
}
return { uGrid, q1, q2, qBar, w2_12: Math.sqrt(w2_12), w2_1bar: Math.sqrt(w2_1bar), w2_2bar: Math.sqrt(w2_2bar) };
}
bres = runBarycenterDemo(dist1_type, dist1_mu, dist1_sigma, dist2_type, dist2_mu, dist2_sigma, lambda1);
function renderBarycenterDemo(bres, bary_controls_view, lambda1) {
return html`
<div style="font-family: system-ui, sans-serif; max-width: 850px;">
<h4>1D Wasserstein Barycenter via Quantile Averaging</h4>
${bary_controls_view}
<div style="display: flex; gap: 20px; flex-wrap: wrap;">
<!-- Quantile plot -->
<div>
<svg width="380" height="280" style="border: 1px solid #dee2e6; border-radius: 4px;">
${(() => {
const margin = {top: 20, right: 100, bottom: 35, left: 50};
const plotW = 380 - margin.left - margin.right;
const plotH = 280 - margin.top - margin.bottom;
const allQ = [...bres.q1, ...bres.q2, ...bres.qBar];
const yMin = Math.min(...allQ) - 0.5, yMax = Math.max(...allQ) + 0.5;
function xS(u) { return margin.left + u * plotW; }
function yS(q) { return margin.top + plotH - (q - yMin) / (yMax - yMin) * plotH; }
function linePath(ux, qx) {
return ux.map((u, i) => `${i === 0 ? 'M' : 'L'} ${xS(u)} ${yS(qx[i])}`).join(' ');
}
return barySvgFragment(`
<line x1="${margin.left}" y1="${margin.top}" x2="${margin.left}" y2="${margin.top + plotH}" stroke="#adb5bd"/>
<line x1="${margin.left}" y1="${margin.top + plotH}" x2="${margin.left + plotW}" y2="${margin.top + plotH}" stroke="#adb5bd"/>
<text x="${margin.left + plotW/2}" y="${margin.top + plotH + 25}" text-anchor="middle" font-size="10">u (probability level)</text>
<text x="${margin.left - 42}" y="${margin.top + plotH/2}" text-anchor="middle" font-size="10" transform="rotate(-90, ${margin.left - 42}, ${margin.top + plotH/2})">Quantile Q(u)</text>
<path d="${linePath(bres.uGrid, bres.q1)}" fill="none" stroke="#e03131" stroke-width="2"/>
<path d="${linePath(bres.uGrid, bres.q2)}" fill="none" stroke="#1971c2" stroke-width="2"/>
<path d="${linePath(bres.uGrid, bres.qBar)}" fill="none" stroke="#2b8a3e" stroke-width="3"/>
<rect x="${margin.left}" y="${margin.top}" width="${plotW}" height="${plotH}" fill="none" stroke="#dee2e6"/>
<g transform="translate(${margin.left + plotW + 5}, ${margin.top + 10})">
<line x1="0" y1="4" x2="15" y2="4" stroke="#e03131" stroke-width="2"/><text x="18" y="8" font-size="9">μ₁</text>
<line x1="0" y1="20" x2="15" y2="20" stroke="#1971c2" stroke-width="2"/><text x="18" y="24" font-size="9">μ₂</text>
<line x1="0" y1="36" x2="15" y2="36" stroke="#2b8a3e" stroke-width="3"/><text x="18" y="40" font-size="9">Barycenter</text>
</g>
`);
})()}
</svg>
</div>
<!-- Stats -->
<div style="flex: 1; min-width: 220px;">
<div style="padding: 12px; background: #f8f9fa; border-radius: 6px;">
<h4 style="margin: 0 0 8px 0;">Wasserstein Distances</h4>
<table style="width: 100%; border-collapse: collapse;">
<tr><td style="padding: 4px 8px;">W₂(μ₁, μ₂)</td><td style="padding: 4px 8px; text-align: right;">${bres.w2_12.toFixed(3)}</td></tr>
<tr><td style="padding: 4px 8px;">W₂(μ₁, barycenter)</td><td style="padding: 4px 8px; text-align: right;">${bres.w2_1bar.toFixed(3)}</td></tr>
<tr><td style="padding: 4px 8px;">W₂(μ₂, barycenter)</td><td style="padding: 4px 8px; text-align: right;">${bres.w2_2bar.toFixed(3)}</td></tr>
<tr><td style="padding: 4px 8px;"><b>Weight λ₁</b></td><td style="padding: 4px 8px; text-align: right;"><b>${lambda1.toFixed(2)}</b></td></tr>
</table>
<p style="margin-top: 8px; font-size: 0.85em; color: #868e96;">
The barycenter quantile Q(u) = λ₁Q₁(u) + λ₂Q₂(u) is exactly the pointwise weighted average of the quantile functions.
</p>
</div>
</div>
</div>
</div>
`
}Barycenter of point masses. Show that the Wasserstein barycenter of \(\delta_{x_1}, \ldots, \delta_{x_m}\) with weights \(\lambda_i\) is \(\delta_{\bar{x}}\) where \(\bar{x} = \sum \lambda_i x_i\) is the Euclidean mean. 📝 Show Solution
1D quantile formula. Derive the 1D barycenter formula \(Q_{\bar{\mu}}(u) = \sum \lambda_i Q_{\mu_i}(u)\) from the isometry \(\mu \mapsto Q_\mu\) into \(L^2(0,1)\). 📝 Show Solution
Gaussian fixed-point. For two univariate Gaussians \(N(m_1, \sigma_1^2)\) and \(N(m_2, \sigma_2^2)\), solve the Bures–Wasserstein equation to find the barycenter variance. 📝 Show Solution
Entropic bias-variance. Explain how the entropic regularization parameter \(\varepsilon\) trades bias for variance in barycenter computation. What happens as \(\varepsilon \to 0\) and \(\varepsilon \to \infty\)? 📝 Show Solution
Test your understanding of this lecture with the interactive MCQ quiz:
---
title: "Lecture 12: Wasserstein Geometry — Wasserstein Barycenters"
subtitle: "Fréchet means in Wasserstein space"
format:
html:
code-fold: true
code-tools: true
code-copy: true
pdf:
documentclass: scrartcl
pdf-engine: xelatex
toc: true
number-sections: true
geometry:
- margin=1in
colorlinks: true
bibliography: source/ref.bib
---
## Learning Goals
By the end of this lecture, learners should be able to:
- Define Wasserstein barycenters as Fréchet means in $(\mathcal{P}_2(\mathcal{X}), W_2)$ and explain how they generalize Euclidean weighted averages.
- Derive the closed-form quantile-averaging formula for 1D Wasserstein barycenters.
- Compute the Wasserstein barycenter of Gaussian measures via the Bures–Wasserstein fixed-point equation.
- State the existence and consistency theorems for sample Wasserstein barycenters.
- Summarize convergence rates in one dimension ($n^{-1/2}$) and for Gaussian barycenters.
- Describe the three main computational approaches: linear programming, fixed-point iteration, and entropic regularization.
## Definition
Wasserstein barycenters are **Fréchet means in Wasserstein space**. They are the appropriate notion of center when the observations are probability measures and the loss is squared optimal-transport distance.
Let $(\mathcal{X}, d)$ be a complete separable metric space and let $\mathcal{P}_2(\mathcal{X})$ be equipped with $W_2$. If $\Lambda$ is a probability distribution on $\mathcal{P}_2(\mathcal{X})$ satisfying
$$
\int_{\mathcal{P}_2(\mathcal{X})} W_2^2(\mu, \mu_0)\, d\Lambda(\mu) < \infty
$$
for some, hence every, $\mu_0 \in \mathcal{P}_2(\mathcal{X})$, then a **population Wasserstein barycenter** of $\Lambda$ is any minimizer
$$
\bar{\mu} \in \arg\min_{\nu \in \mathcal{P}_2(\mathcal{X})} \Phi(\nu), \qquad
\Phi(\nu) = \int_{\mathcal{P}_2(\mathcal{X})} W_2^2(\nu, \mu)\, d\Lambda(\mu).
$$
Equivalently, if $M \sim \Lambda$ is a random probability measure, then $\bar{\mu}$ minimizes $\mathbb{E}\, W_2^2(\nu, M)$ over $\nu \in \mathcal{P}_2(\mathcal{X})$.
In the finite weighted case, where $\Lambda = \sum_{i=1}^n \lambda_i \delta_{\mu_i}$ with $\lambda_i > 0$ and $\sum_i \lambda_i = 1$:
$$
\bar{\mu} \in \arg\min_{\nu \in \mathcal{P}_2(\mathcal{X})} \sum_{i=1}^n \lambda_i W_2^2(\nu, \mu_i).
$$
Taking $\lambda_i=1/n$ gives the **Fréchet mean** of the measures $\mu_1, \ldots, \mu_n$.
::: {.callout-note}
If $\mu_i = \delta_{x_i}$ are point masses in Euclidean space, then the barycenter is $\delta_{\bar{x}}$ with $\bar{x} = \sum_i \lambda_i x_i$, so the construction extends the ordinary weighted mean.
:::
**Barycenter vs. Density Average.**
A key insight behind Wasserstein barycenters is that they often preserve the **shape** of the input distributions, whereas a naive pointwise average of densities does not in general. The figure below illustrates this with two 1D Gaussians.
```{ojs}
//| output: false
bary_shape_mu1_ctrl = Inputs.range([-3, 1], {step: 0.1, value: -1, label: "μ₁"})
bary_shape_sigma1_ctrl = Inputs.range([0.3, 2.5], {step: 0.1, value: 0.7, label: "σ₁"})
bary_shape_mu2_ctrl = Inputs.range([0, 4], {step: 0.1, value: 2, label: "μ₂"})
bary_shape_sigma2_ctrl = Inputs.range([0.3, 2.5], {step: 0.1, value: 1.0, label: "σ₂"})
bary_shape_lambda_ctrl = Inputs.range([0, 1], {step: 0.05, value: 0.5, label: "λ (barycenter weight)"})
mu1_s = Generators.input(bary_shape_mu1_ctrl)
sigma1_s = Generators.input(bary_shape_sigma1_ctrl)
mu2_s = Generators.input(bary_shape_mu2_ctrl)
sigma2_s = Generators.input(bary_shape_sigma2_ctrl)
lambda_s = Generators.input(bary_shape_lambda_ctrl)
shape_controls_view = html`
<style>
.shape-slider-row { display:flex; flex-wrap:wrap; gap:6px 16px; width:100%; margin:0 0 10px; font:0.85em system-ui,sans-serif; }
.shape-slider-row > * { flex:1 1 calc((100% - 48px)/4); min-width:140px; margin:0; }
@container (max-width:680px) { .shape-slider-row > * { flex-basis:calc((100% - 16px)/2); } }
@container (max-width:420px) { .shape-slider-row > * { flex-basis:100%; } }
</style>
<div class="shape-slider-row">
<div>${bary_shape_mu1_ctrl}</div>
<div>${bary_shape_sigma1_ctrl}</div>
<div>${bary_shape_mu2_ctrl}</div>
<div>${bary_shape_sigma2_ctrl}</div>
</div>
<div class="shape-slider-row">
<div style="flex:0 1 300px">${bary_shape_lambda_ctrl}</div>
</div>`
function gaussianPDF(x, mu, sigma) {
const z = (x - mu) / sigma;
return Math.exp(-0.5 * z * z) / (sigma * Math.sqrt(2 * Math.PI));
}
function renderShapeDemo(mu1, sigma1, mu2, sigma2, lambda) {
// Wasserstein barycenter parameters (closed-form for 1D Gaussians)
const muBar = lambda * mu1 + (1 - lambda) * mu2;
const sigmaBar = lambda * sigma1 + (1 - lambda) * sigma2;
// Evaluation grid
const xMin = Math.min(mu1 - 4*sigma1, mu2 - 4*sigma2) - 0.5;
const xMax = Math.max(mu1 + 4*sigma1, mu2 + 4*sigma2) + 0.5;
const n = 400;
const xs = Array.from({length: n}, (_, i) => xMin + (i / (n-1)) * (xMax - xMin));
const pdf1 = xs.map(x => gaussianPDF(x, mu1, sigma1));
const pdf2 = xs.map(x => gaussianPDF(x, mu2, sigma2));
const pdfBarWass = xs.map(x => gaussianPDF(x, muBar, sigmaBar));
const pdfAvg = xs.map((x, i) => lambda * pdf1[i] + (1 - lambda) * pdf2[i]);
const allY = [...pdf1, ...pdf2, ...pdfBarWass, ...pdfAvg];
const yMax = Math.max(...allY) * 1.12;
const margin = {top: 15, right: 20, bottom: 40, left: 50};
const svgW = 720, svgH = 320;
const plotW = svgW - margin.left - margin.right;
const plotH = svgH - margin.top - margin.bottom;
function xS(x) { return margin.left + (x - xMin) / (xMax - xMin) * plotW; }
function yS(y) { return margin.top + plotH - (y / yMax) * plotH; }
function lineData(xArr, yArr) {
let d = "";
for (let i = 0; i < xArr.length; i++) {
d += (i === 0 ? "M" : "L") + xS(xArr[i]).toFixed(2) + "," + yS(yArr[i]).toFixed(2);
}
return d;
}
const svgNS = "http://www.w3.org/2000/svg";
function elt(name, attrs) {
const e = document.createElementNS(svgNS, name);
for (const [k, v] of Object.entries(attrs)) e.setAttribute(k, v);
return e;
}
const svg = elt("svg", {width: svgW, height: svgH, style: "border:1px solid #dee2e6;border-radius:4px;max-width:100%;height:auto;"});
// Grid lines
const xTicks = 5;
for (let i = 0; i <= xTicks; i++) {
const xv = xMin + (i / xTicks) * (xMax - xMin);
svg.appendChild(elt("line", {x1: xS(xv), y1: margin.top, x2: xS(xv), y2: margin.top + plotH, stroke: "#e9ecef", "stroke-width": "1"}));
const txt = elt("text", {x: xS(xv), y: margin.top + plotH + 16, "text-anchor": "middle", "font-size": "10", fill: "#868e96"});
txt.textContent = xv.toFixed(1);
svg.appendChild(txt);
}
for (let i = 0; i <= 4; i++) {
const yv = (i / 4) * yMax;
svg.appendChild(elt("line", {x1: margin.left, y1: yS(yv), x2: margin.left + plotW, y2: yS(yv), stroke: "#e9ecef", "stroke-width": "1"}));
const txt = elt("text", {x: margin.left - 6, y: yS(yv) + 4, "text-anchor": "end", "font-size": "10", fill: "#868e96"});
txt.textContent = yv.toFixed(2);
svg.appendChild(txt);
}
// Axes
svg.appendChild(elt("line", {x1: margin.left, y1: margin.top, x2: margin.left, y2: margin.top + plotH, stroke: "#adb5bd"}));
svg.appendChild(elt("line", {x1: margin.left, y1: margin.top + plotH, x2: margin.left + plotW, y2: margin.top + plotH, stroke: "#adb5bd"}));
const xlbl = elt("text", {x: margin.left + plotW/2, y: svgH - 4, "text-anchor": "middle", "font-size": "11", fill: "#495057"});
xlbl.textContent = "x";
svg.appendChild(xlbl);
const ylbl = elt("text", {x: 12, y: margin.top + plotH/2, "text-anchor": "middle", "font-size": "11", fill: "#495057", transform: `rotate(-90, 12, ${margin.top + plotH/2})`});
ylbl.textContent = "Density";
svg.appendChild(ylbl);
// Draw curves
// μ₁ — dashed red
const p1 = elt("path", {d: lineData(xs, pdf1), fill: "none", stroke: "#e03131", "stroke-width": "2", "stroke-dasharray": "6,3"});
svg.appendChild(p1);
// μ₂ — dashed blue
const p2 = elt("path", {d: lineData(xs, pdf2), fill: "none", stroke: "#1971c2", "stroke-width": "2", "stroke-dasharray": "6,3"});
svg.appendChild(p2);
// Density average — dotted purple (bimodal when separated)
const pAvg = elt("path", {d: lineData(xs, pdfAvg), fill: "none", stroke: "#ae3ec9", "stroke-width": "2.5", "stroke-dasharray": "2,4"});
svg.appendChild(pAvg);
// Wasserstein barycenter — solid green (Gaussian shape preserved)
const pWass = elt("path", {d: lineData(xs, pdfBarWass), fill: "none", stroke: "#2b8a3e", "stroke-width": "3"});
svg.appendChild(pWass);
// Light fill under the barycenter
const areaWass = lineData(xs, pdfBarWass) + "L" + xS(xs[xs.length-1]).toFixed(2) + "," + yS(0).toFixed(2) + "L" + xS(xs[0]).toFixed(2) + "," + yS(0).toFixed(2) + "Z";
svg.appendChild(elt("path", {d: areaWass, fill: "rgba(43,138,62,0.08)", stroke: "none"}));
// μ_bar vertical reference line
svg.appendChild(elt("line", {x1: xS(muBar), y1: margin.top, x2: xS(muBar), y2: margin.top + plotH, stroke: "#2b8a3e", "stroke-width": "0.8", "stroke-dasharray": "4,4", opacity: "0.5"}));
// Legend
const lx = margin.left + 10, ly = margin.top + 8;
const items = [
["μ₁", "#e03131", "6,3"],
["μ₂", "#1971c2", "6,3"],
["Barycenter (Wasserstein)", "#2b8a3e", null],
["Density average", "#ae3ec9", "2,4"]
];
items.forEach(([label, color, dash], i) => {
const g = document.createElementNS(svgNS, "g");
g.setAttribute("transform", `translate(${lx}, ${ly + i * 24})`);
const line = elt("line", {x1: 0, y1: 7, x2: 22, y2: 7, stroke: color, "stroke-width": i === 2 ? "3" : "2"});
if (dash) line.setAttribute("stroke-dasharray", dash);
g.appendChild(line);
const txt = elt("text", {x: 28, y: 11, "font-size": "10.5", fill: "#212529"});
txt.textContent = label;
g.appendChild(txt);
svg.appendChild(g);
});
// Annotation for bimodality when distributions are well-separated
if (Math.abs(mu1 - mu2) > 2.5 * (sigma1 + sigma2)) {
const midIdx = Math.floor(n / 2);
const annX = xS(xs[midIdx]);
const annY = yS(pdfAvg[midIdx] * 0.55);
const txtAnn = elt("text", {x: annX, y: annY, "text-anchor": "middle", "font-size": "11", fill: "#ae3ec9", "font-style": "italic", "font-weight": "600"});
txtAnn.textContent = "bimodal!";
svg.appendChild(txtAnn);
}
// Summary stats below the chart
const statsDiv = document.createElement("div");
statsDiv.style.cssText = "display:flex;gap:24px;flex-wrap:wrap;margin-top:10px;font-size:0.88em;";
statsDiv.innerHTML = `
<span><span style="color:#2b8a3e;font-weight:600;">■ Barycenter:</span> N(${muBar.toFixed(2)}, ${sigmaBar.toFixed(2)}²)</span>
<span><span style="color:#ae3ec9;font-weight:600;">··· Density avg:</span> <em>not</em> Gaussian</span>
<span style="color:#868e96;">μ<sub>bar</sub> = λμ₁ + (1−λ)μ₂,  σ<sub>bar</sub> = λσ₁ + (1−λ)σ₂</span>`;
const wrapper = document.createElement("div");
wrapper.style.maxWidth = "740px";
wrapper.style.fontFamily = "system-ui, sans-serif";
wrapper.appendChild(svg);
wrapper.appendChild(statsDiv);
return wrapper;
}
```
```{ojs}
//| label: fig-barycenter-vs-density-avg
//| fig-cap: "Wasserstein barycenter vs. pointwise density average of two 1D Gaussian distributions. The barycenter (solid green) preserves the Gaussian shape — it is itself a Gaussian. The density average (dotted purple) does not: when the two components are sufficiently separated, it becomes bimodal, demonstrating that pointwise averaging of densities destroys the distributional shape."
renderShapeDemo(mu1_s, sigma1_s, mu2_s, sigma2_s, lambda_s)
```
```{ojs}
//| output: false
shape_controls_view
```
::: {.callout-tip title="What to observe"}
- **Barycenter (solid green):** Always a single Gaussian — the Wasserstein barycenter preserves the **shape** of the input family. The mean and standard deviation are the weighted averages of the inputs.
- **Density average (dotted purple):** When the two Gaussians are well-separated (|μ₁ − μ₂| ≫ σ₁ + σ₂), the pointwise average of the densities becomes **bimodal** — it has two peaks and does not look like either input distribution.
- **Why this matters:** The Wasserstein barycenter interpolates *between distributions* by averaging their quantile functions, which respects the geometry of the space. The density average interpolates *pointwise on the x-axis*, which ignores the underlying metric structure and can produce distributions that lie far from any individual input in Wasserstein distance.
:::
## One-Dimensional Formula
When $\mathcal{X} = \mathbb{R}$, the quantile representation gives an **explicit closed-form solution**. Let $Q_\mu = F_\mu^{-1}$ denote the quantile function of $\mu$. Since the map $\mu \mapsto Q_\mu$ embeds $\mathcal{P}_2(\mathbb{R})$ isometrically into the closed convex cone of nondecreasing functions in $L^2(0, 1)$,
$$
W_2^2(\mu, \nu) = \int_0^1 \{Q_\mu(u) - Q_\nu(u)\}^2\, du.
$$
The barycenter is therefore unique and has quantile function
$$
Q_{\bar{\mu}}(u) = \int_{\mathcal{P}_2(\mathbb{R})} Q_\mu(u)\, d\Lambda(\mu), \qquad 0 < u < 1,
$$
provided the right side is square-integrable. In the finite case this becomes
$$
Q_{\bar{\mu}}(u) = \sum_{i=1}^n \lambda_i Q_{\mu_i}(u).
$$
The pointwise average of nondecreasing quantile functions is again nondecreasing, so it defines a valid probability distribution.
::: {.callout-tip title="Why 1D is special"}
This identity is the main reason univariate Wasserstein means are much simpler than their higher-dimensional analogues: the barycenter is simply the **pointwise quantile average**. This underlies many statistical procedures for distribution-valued data [@PetersenMueller2016; @PanaretosZemel2020].
:::
## Gaussian Barycenters
If $\mu_i = N(m_i, \Sigma_i)$ are Gaussian measures on $\mathbb{R}^D$, then their Wasserstein barycenter is again Gaussian, $\bar{\mu} = N(\bar{m}, \bar{\Sigma})$, with
$$
\bar{m} = \sum_{i=1}^m \lambda_i m_i,
$$
and covariance matrix determined by the **Bures–Wasserstein fixed-point equation**
$$
\bar{\Sigma} = \sum_{i=1}^m \lambda_i \bigl(\bar{\Sigma}^{1/2} \Sigma_i \bar{\Sigma}^{1/2}\bigr)^{1/2}.
$$
This example shows that Wasserstein barycenters average both **locations and distributional shapes**, not just pointwise density values [@AguehCarlier2011; @PanaretosZemel2020].
::: {.callout-note title="Optimal transport between Gaussians"}
For nondegenerate Gaussians $N(m_0, \Sigma_0)$ and $N(m_1, \Sigma_1)$, the optimal transport map is affine:
$$
T_{0 \to 1}(x) = m_1 + \Sigma_0^{-1/2} \bigl(\Sigma_0^{1/2} \Sigma_1 \Sigma_0^{1/2}\bigr)^{1/2} \Sigma_0^{-1/2}(x - m_0).
$$
:::
## Existence and Uniqueness
::: {#thm-wass-barycenter-exist .theorem title="Existence of Wasserstein barycenters (Le Gouic & Loubes 2017, Theorem 2)"}
Let $p \ge 1$ and let $(E, d)$ be a separable locally compact geodesic space. Let $\Lambda$ be a probability measure on $\mathcal{W}_p(E)$ such that
$$
\int_{\mathcal{W}_p(E)} W_p^p(\mu, \mu_0)\, d\Lambda(\mu) < \infty
$$
for some, hence every, $\mu_0 \in \mathcal{W}_p(E)$. Then there exists at least one barycenter $\bar{\mu}_\Lambda \in \mathcal{W}_p(E)$.
:::
**Uniqueness** is more subtle. Wasserstein barycenters may not be unique in general — $\mathcal{P}_2(\mathbb{R}^d)$ with $d \ge 2$ has nonnegative Alexandrov curvature rather than the nonpositive curvature that would force strict convexity of squared distance.
- In **one dimension**, uniqueness follows from the Hilbert-space quantile embedding.
- In **$\mathbb{R}^d$**, a standard sufficient condition is that at least one input measure is absolutely continuous with respect to Lebesgue measure [@AguehCarlier2011].
## Consistency of Sample Barycenters
Let $M_1, M_2, \ldots$ be i.i.d. random probability measures with law $\Lambda$, and define the empirical law
$$
\Lambda_n = \frac{1}{n}\sum_{i=1}^n \delta_{M_i}.
$$
A **sample Wasserstein barycenter** is any minimizer
$$
\hat{\mu}_n \in \arg\min_{\nu \in \mathcal{P}_2(\mathcal{X})} \frac{1}{n}\sum_{i=1}^n W_2^2(\nu, M_i).
$$
Let $\mathsf{W}_2$ denote the Wasserstein distance on $\mathcal{W}_2(E)$ itself (using $W_2$ as the ground metric). By the strong law of large numbers and Villani's Theorem 6.9,
$$
\mathsf{W}_2(\Lambda_n, \Lambda) \to 0 \qquad \text{a.s.}
$$
Let $\operatorname{Bar}_2(\Lambda_n)$ denote the set of empirical 2-Wasserstein barycenters, i.e.,
$$
\operatorname{Bar}_2(\Lambda_n) \coloneqq \arg\min_{\nu \in \mathcal{P}_2(\mathcal{X})} \frac{1}{n}\sum_{i=1}^n W_2^2(\nu, M_i).
$$
::: {#thm-wass-barycenter-consistency .theorem title="Consistency under uniqueness (Le Gouic & Loubes 2017, Corollary 5)"}
If the population barycenter $\bar{\mu}_\Lambda$ is unique and sample barycenters $\hat{\mu}_n \in \operatorname{Bar}_2(\Lambda_n)$, then
$$
W_2(\hat{\mu}_n, \bar{\mu}_\Lambda) \to 0 \qquad \text{a.s.}
$$
:::
In $\mathbb{R}^d$, the uniqueness condition holds if $\Lambda$ assigns positive probability to absolutely continuous ground-space distributions [@LeGouicLoubes2017, Proposition 6].
## Convergence Rates
### One Dimension
In $\mathcal{W}_2(\mathbb{R})$, the quantile representation gives
$$
Q_{\hat{\mu}_n}(u) = \frac{1}{n}\sum_{i=1}^n Q_{M_i}(u), \qquad
Q_{\bar{\mu}}(u) = \mathbb{E}\{Q_M(u)\}.
$$
Hence
$$
\mathbb{E}\, W_2^2(\hat{\mu}_n, \bar{\mu}) = \frac{1}{n}\int_0^1 \operatorname{Var}\{Q_M(u)\}\, du,
$$
so the squared error is $O(n^{-1})$ and the distance is $O(n^{-1/2})$. This parametric rate reflects the Hilbert-space structure of the quantile embedding — the barycenter is simply a sample mean in $L^2(0,1)$.
### Higher Dimensions
**$\alpha$-Strong Convexity and $\beta$-Smoothness.**
The convergence rate of sample Wasserstein barycenters depends on the geometric regularity of the transport maps pushing $\bar{\mu}$ to each input measure. The key structural conditions are **strong convexity** and **smoothness** of the potentials whose gradients realize these maps.
::: {#def-strong-convex .definition title="$\alpha$-Strongly Convex Function"}
Let $\alpha > 0$. A differentiable function $f: \mathbb{R}^d \to \mathbb{R}$ is **$\alpha$-strongly convex** if for all $x, y \in \mathbb{R}^d$,
$$
f(y) \ge f(x) + \langle\nabla f(x),\, y - x\rangle + \frac{\alpha}{2}\|y - x\|^2.
$$
Equivalently, $\nabla^2 f(x) \succeq \alpha I_d$ (in the sense of Loewner order) wherever the Hessian exists, meaning all eigenvalues of the Hessian are bounded below by $\alpha$.
:::
Strong convexity quantitatively strengthens ordinary convexity ($f(y) \ge f(x) + \langle\nabla f(x), y - x\rangle$). The quadratic penalty $\frac{\alpha}{2}\|y-x\|^2$ ensures the function curves *at least* as sharply as $\frac{\alpha}{2}\|x\|^2$. Geometrically, the gradient map $\nabla f$ is **strictly expanding**: $\langle\nabla f(y) - \nabla f(x), y - x\rangle \ge \alpha\|y - x\|^2$, which guarantees injectivity of $\nabla f$ and a well-behaved inverse.
::: {#def-beta-smooth .definition title="$\beta$-Smooth Function"}
Let $\beta > 0$. A differentiable function $f: \mathbb{R}^d \to \mathbb{R}$ is **$\beta$-smooth** if its gradient is $\beta$-Lipschitz continuous:
$$
\|\nabla f(x) - \nabla f(y)\| \le \beta\,\|x - y\|, \qquad \forall x, y \in \mathbb{R}^d.
$$
Equivalently, $\nabla^2 f(x) \preceq \beta I_d$ wherever the Hessian exists, and
$$
f(y) \le f(x) + \langle\nabla f(x),\, y - x\rangle + \frac{\beta}{2}\|y - x\|^2.
$$
:::
Whereas strong convexity provides a *lower* quadratic bound, smoothness provides an *upper* quadratic bound. Together, the two conditions sandwich $f$ between quadratics with curvatures $\alpha$ and $\beta$. The ratio $\beta/\alpha \ge 1$ is the **condition number** of $f$.
::: {.callout-note title="Connection to optimal transport"}
When each $\mu \in \operatorname{supp}(\Lambda)$ is the pushforward of $\bar{\mu}$ by $T_\mu = \nabla\phi_\mu$ — the gradient of a convex potential — the regularity of $\phi_\mu$ controls how much the geometry of $\mathcal{P}_2(\mathbb{R}^d)$ near $\bar{\mu}$ resembles a Hilbert space. Brenier's theorem [@PanaretosZemel2020, §2.3] guarantees that optimal transport maps between absolutely continuous measures are exactly of this gradient-of-convex-potential form.
:::
::: {.callout-tip title="Two notions of strong convexity" collapse="true"}
The $\alpha$-strong convexity defined here is the **classical Euclidean** notion — a lower quadratic bound on the function via its gradient. This is distinct from the **geodesic $\lambda$-strong convexity** introduced in [Lecture 2](lecture-02.qmd#def-convex-functions), which applies to functions on arbitrary geodesic metric spaces:
$$
f(\gamma(t)) \le (1-t)f(\gamma(0)) + t f(\gamma(1)) - \lambda\,t(1-t)\,d^2(\gamma(0), \gamma(1)),
$$
where $\gamma: [0,1] \to \mathcal{M}$ is a geodesic. The two notions coincide when $\mathcal{M} = \mathbb{R}^d$ with the Euclidean metric and $f$ is differentiable — in that case the geodesic inequality reduces to the gradient inequality with $\lambda = \alpha$.
:::
In $d \ge 2$, the Wasserstein space lacks the flat Hilbert geometry of the 1D case, and convergence rates depend on the **curvature of the transport maps** from the barycenter. @LeGouicParisRigolletStromme2023 showed that if each $\mu \in \operatorname{supp}(\Lambda)$ is the pushforward of $\bar{\mu}$ by the gradient of an $\alpha$-strongly convex and $\beta$-smooth potential $\phi_\mu$, i.e.
$$
\mu = (\nabla\phi_\mu)_{\#}\bar{\mu},
$$
then the sample barycenter attains the parametric rate, with a constant governed by the gap $\beta - \alpha$.
::: {#thm-higher-dim-rate .theorem title="Convergence rate under transport regularity (Le Gouic, Paris, Rigollet & Stromme 2023)"}
If $\beta - \alpha < 1$, then
$$
\mathbb{E}\, W_2^2(\hat{\mu}_n, \bar{\mu}) \le \frac{4\sigma^2}{(1 - \beta + \alpha)^2\, n},
$$
where $\sigma^2 = \int_{\mathcal{P}_2(\mathbb{R}^d)} W_2^2(\mu, \bar{\mu})\, d\Lambda(\mu)$ is the population variance in Wasserstein space.
:::
### Gaussian Case
For Gaussian measures, the transport maps are affine and the regularity parameters are determined by the eigenvalue spread of the covariance matrices. If all input covariances have eigenvalues in $[\kappa_0, \kappa_1]$ and we set $\kappa = \kappa_1 / \kappa_0 \ge 1$, then:
$$
\mathbb{E}\, W_2^2(\hat{\mu}_n, \bar{\mu}) \le \frac{4\sigma^2}{(1 - \kappa + \kappa^{-1})^2\, n},
$$
provided $\kappa - \kappa^{-1} < 1$. This is exactly the higher-dimensional bound with the transport-map regularity gap $\beta - \alpha$ replaced by the eigenvalue condition-number gap $\kappa - \kappa^{-1}$. The condition $\kappa - \kappa^{-1} < 1$ (equivalently $\kappa < \frac{1+\sqrt{5}}{2} \approx 1.618$) requires the covariance matrices to be moderately well-conditioned — extreme anisotropy in the input measures can degrade the convergence rate.
## Computation
Computing Wasserstein barycenters is substantially harder than computing Euclidean means. Three main paradigms exist, each with different trade-offs between accuracy, speed, and scalability. For a comprehensive treatment, see @PeyreCuturi2019, Chapters 4 and 9.
### Linear Programming on Discrete Supports
For discrete inputs, the barycenter problem is a **linear program** (LP) once the barycenter support locations are fixed. Suppose each $\mu_i$ is supported on $\{x_{i1},\ldots,x_{i n_i}\}$ with probability vector $a_i$, and restrict the barycenter to $\{z_1,\ldots,z_L\}$ with unknown weight vector $b$. Let $C_{i\ell k} = \|z_\ell - x_{ik}\|^2$ be the transport cost. The fixed-support barycenter LP is:
$$
\begin{aligned}
\min_{b,\;\pi_1,\ldots,\pi_m} \quad & \sum_{i=1}^m \lambda_i \sum_{\ell=1}^{L} \sum_{k=1}^{n_i} C_{i\ell k}\,\pi_{i\ell k} \\
\text{subject to} \quad & \pi_i \mathbf{1}_{n_i} = b, \qquad \pi_i^\mathsf{T} \mathbf{1}_L = a_i, \qquad \pi_i \ge 0, \qquad i=1,\ldots,m,
\end{aligned}
$$
where $b \ge 0$, $\sum_\ell b_\ell = 1$, and $\pi_i$ is the coupling between the barycenter and $\mu_i$. The constraints enforce that each $\pi_i$ has the barycenter weights $b$ as its first marginal and the input weights $a_i$ as its second marginal — all input measures couple to the *same* $b$, which is the discrete barycenter.
**Complexity.** The formulation has $L+\sum_i L n_i$ variables before eliminating $b$, and $\sum_i(L+n_i)$ displayed marginal equalities (with linear dependencies). Thus even writing the dense coupling variables and costs requires $O(\sum_i L n_i)$ storage. General-purpose interior-point methods have polynomial worst-case complexity [@NesterovNemirovskii1994], while transportation and network-flow structure can be exploited by specialized solvers [@AhujaOrlin1992]. The actual running time depends strongly on sparsity and the solver, so there is no universal cubic running-time formula in $mL\bar n$. Exact LP is consequently most useful for modest supports or as a reference solution.
**Choice of the barycenter support.** The LP formulation requires fixing $\{z_\ell\}$ in advance. A grid over the convex hull or the union of the input supports gives a restricted, generally approximate barycenter. For quadratic cost, an exact discrete barycenter can be sought on the much larger candidate set of weighted averages $\sum_i\lambda_i x_{i k_i}$, but that set can contain as many as $\prod_i n_i$ points [@PeyreCuturi2019, §9.2]. Alternatively, one can alternate between optimizing the weights/couplings and moving a prescribed number of support locations; this is a free-support, nonconvex optimization rather than a single LP. A coarse or otherwise misspecified candidate support introduces discretization error even when the restricted LP is solved exactly.
### Fixed-Point Iteration
When measures are absolutely continuous (or approximated by large discrete samples), the fixed-point iteration of @AlvarezEstebanEtAl2016 avoids discretizing the barycenter support in advance by iteratively updating the barycenter via averaged transport maps.
::: {.callout-note title="Algorithm: Fixed-Point Barycenter Iteration"}
**Input:** Measures $\mu_1,\ldots,\mu_m$, weights $\lambda_i$, initial guess $\nu^{(0)}$.
**Repeat for $t = 0, 1, 2, \ldots$:**
1. **Compute transport maps.** For each $i$, compute the optimal transport map $T_i^{(t)}$ from the current iterate $\nu^{(t)}$ to $\mu_i$. In $\mathbb{R}^d$, if $\nu^{(t)}$ is absolutely continuous, Brenier's theorem guarantees $T_i^{(t)} = \nabla\phi_i^{(t)}$ for a convex potential $\phi_i^{(t)}$.
2. **Form the barycentric map.** Define the weighted average
$$
T^{(t)}(x) = \sum_{i=1}^m \lambda_i\, T_i^{(t)}(x).
$$
3. **Push forward.** Update the iterate:
$$
\nu^{(t+1)} \leftarrow T^{(t)}_{\#}\nu^{(t)}.
$$
**Until** $\|T^{(t)}(x) - x\|$ is sufficiently small (in $L^2(\nu^{(t)})$).
:::
**Why it works.** At the true barycenter $\bar{\mu}$, the first-order optimality condition is
$$
\sum_{i=1}^m \lambda_i\,T_i(x) = x \qquad \bar{\mu}\text{-a.e.},
$$
where $T_i$ is the optimal map from $\bar{\mu}$ to $\mu_i$ under the absolute-continuity hypotheses above [@AguehCarlier2011, Proposition 3.8 and Remark 3.9]. Hence $\bar{\mu}$ is a fixed point of the update $\nu \mapsto (\sum \lambda_i T_i^\nu)_\#\nu$. The algorithm is a **generalized Procrustes** procedure: at each step it computes the best way to align the current guess with each input, averages the alignments, and uses the result as the new guess.
**Convergence.** The rigorous result is more conditional than the fixed-point intuition suggests. @AlvarezEstebanEtAl2016, Theorem 3.6, assume that all targets are absolutely continuous, at least one has a bounded density, and the initial measure is absolutely continuous. They prove tightness of the iterates and show that every subsequential limit is a fixed point of the update. Convergence in $W_2$ to the barycenter follows if the update operator has a **unique fixed point**. A fixed point need not be a barycenter in complete generality, so compact support alone does not give the convergence claim. In the Gaussian and, more generally, location-scatter settings treated in that paper, the iteration does converge to the barycenter.
Each exact step requires solving $m$ optimal-transport problems, which can be done in parallel.
### Entropic Regularization and Sinkhorn Scaling
Entropic regularization [@CuturiDoucet2014] makes the discrete coupling subproblems strictly convex and gives them a matrix-scaling structure, enabling fast parallel implementations.
**Regularized fixed-support problem.** To match the iterative Bregman-projection algorithm below, define the discrete entropic transport cost using entropy relative to a **fixed counting reference**:
$$
\operatorname{OT}_\varepsilon(b,a_i)
= \min_{\pi_i\mathbf 1=b,\;\pi_i^\mathsf T\mathbf 1=a_i}
\left\{
\langle C_i,\pi_i\rangle
+\varepsilon\sum_{\ell,k}\pi_{i\ell k}
\bigl(\log\pi_{i\ell k}-1\bigr)
\right\},
\qquad
\min_{b\in\Delta_L}\sum_{i=1}^m\lambda_i
\operatorname{OT}_\varepsilon(b,a_i).
$$
Changing the reference measure changes terms that depend on the unknown $b$ and therefore changes the regularized barycenter. In particular, the frequently used penalty $\mathrm{KL}(\pi_i\|b\otimes a_i)$ is **not** interchangeable with the entropy above when $b$ is being optimized.
The optimal coupling has the scaling form
$$
\pi_{i\ell k} = u_{i\ell}\, K_{i\ell k}\, v_{ik},
$$
where $K_{i\ell k} = \exp(-\|z_\ell - x_{ik}\|^2 / \varepsilon)$ is the **Gibbs kernel** and $(u_i, v_i)$ are positive scaling vectors. This factorized form is the key computational advantage.
::: {.callout-note title="Algorithm: Sinkhorn Barycenter (Iterative Bregman Projections)"}
**Input:** Discrete measures $\mu_i$ with supports $\{x_{ik}\}$ and weights $a_i$, target support $\{z_\ell\}$, regularization $\varepsilon > 0$, weights $\lambda_i$.
**Initialise:** $u_i\leftarrow\mathbf 1_L$ and $v_i\leftarrow\mathbf 1_{n_i}$ for all $i$.
**Repeat:**
1. **Project onto the known input marginals.** For each $i$,
$$
v_i \leftarrow \frac{a_i}{K_i^\mathsf{T}u_i}.
$$
2. **Project onto a common barycenter marginal.** Compute the weighted geometric mean of the current first marginals,
$$
b \leftarrow
\prod_{i=1}^m
\bigl[u_i\odot(K_i v_i)\bigr]^{\lambda_i},
\qquad
u_i \leftarrow \frac{b}{K_i v_i},
$$
where products, powers, and divisions are componentwise.
**Until** the marginal residuals (or the change in $b$) are sufficiently small [@BenamouCarlierCuturiNennaPeyre2015, §3.2].
:::
This is an instance of **iterative Bregman projections**: Step 1 projects all couplings onto their prescribed input marginals, and Step 2 projects them onto the constraint that their first marginals agree. Alternating KL projections converge to the regularized solution when the Gibbs kernels are positive [@BenamouCarlierCuturiNennaPeyre2015]. A dense projection sweep costs $O(\sum_i L n_i)$ arithmetic operations and has the same order of storage if all kernels are materialized. The number of sweeps is problem- and tolerance-dependent and typically increases as $\varepsilon$ decreases; a general linear rate does not follow from the alternating-projection result.
**Regularization bias.** For a fixed finite problem, regularized minimizers approach unregularized minimizers as $\varepsilon\downarrow0$ (with the usual qualification that the unregularized minimizer may not be unique). Smaller $\varepsilon$ reduces this bias but makes the kernels more ill-conditioned and matrix scaling slower. There is no universal $W_2(\bar\mu_\varepsilon,\bar\mu)=O(\varepsilon^{1/2})$ barycenter bound, nor a universal $O(1/\varepsilon)$ iteration count, under only compact support. With the entropy convention above, large $\varepsilon$ favors diffuse couplings and a high-entropy barycenter; on a fixed finite support the barycenter tends toward uniform weights as the entropy term dominates.
**Practical considerations:**
- **Log-domain stabilisation.** For small $\varepsilon$, the kernel entries $K_{i\ell k} = \exp(-\|z_\ell - x_{ik}\|^2/\varepsilon)$ underflow to zero in floating point. The standard fix is to run Sinkhorn in log-space using the `logsumexp` operation [@Schmitzer2019; @PeyreCuturi2019, §4.4].
- **Debiasing.** Entropic OT has a nonzero self-cost and commonly produces overly diffuse or blurred barycenters. The **Sinkhorn divergence** corrects both arguments symmetrically:
$$
S_\varepsilon(\mu,\nu)
= \operatorname{OT}_\varepsilon(\mu,\nu)
- \frac12\operatorname{OT}_\varepsilon(\mu,\mu)
- \frac12\operatorname{OT}_\varepsilon(\nu,\nu).
$$
A debiased Sinkhorn barycenter minimizes $\sum_i\lambda_iS_\varepsilon(\nu,\mu_i)$. Its important extra term is $-\frac12\operatorname{OT}_\varepsilon(\nu,\nu)$, which depends on the candidate barycenter. Subtracting only the input self-costs would add a constant and could not alter the minimizer. Debiased barycenters require a modified scaling algorithm [@JanatiCuturiGramfort2020].
- **Scalability and GPU.** The Sinkhorn algorithm uses matrix-vector products and elementwise operations, which parallelize well on GPUs. Dense kernels still require $O(\sum_iLn_i)$ memory and work per sweep; very large supports require additional structure such as convolutional kernels on grids, low-rank approximations, sparsity, or lazy kernel evaluation.
- **Free-support barycenters.** The Sinkhorn algorithm as stated fixes the barycenter support $\{z_\ell\}$. When the support should also be learned, one can alternate regularized coupling solves with updates of the support locations [@CuturiDoucet2014, §4]. The joint problem is nonconvex, so this procedure generally guarantees only a stationary/local solution.
### Summary of Methods
| Method | Accuracy | Speed | Support size | Key reference |
|--------|----------|-------|-------------|---------------|
| Fixed-support LP | Exact for the chosen support (to solver tolerance) | General LP solve; coupling storage $O(\sum_iLn_i)$ | Limited by LP variables and sparsity | @PeyreCuturi2019, Ch. 9 |
| Fixed-point iteration | Exact only under its continuous-map assumptions; discrete projection is approximate | Requires $m$ OT solves per outer iteration | No fixed spatial grid; atom count chosen by the user | @AlvarezEstebanEtAl2016 |
| Entropic Sinkhorn | Solves a regularized fixed-support problem; approaches exact OT as $\varepsilon\downarrow0$ | Dense sweep $O(\sum_iLn_i)$; highly parallel | Limited by kernel storage unless structure is exploited | @CuturiDoucet2014; @BenamouCarlierCuturiNennaPeyre2015 |
## Interactive Exploration: 1D Barycenters via Quantile Averaging
```{ojs}
//| output: false
dist1_type_control = Inputs.select(["normal", "uniform", "exponential", "beta"], {value: "normal", label: "Distribution 1 type"})
dist1_mu_control = Inputs.range([-3, 3], {step: 0.1, value: -1, label: "Dist 1 location"})
dist1_sigma_control = Inputs.range([0.2, 3], {step: 0.1, value: 0.8, label: "Dist 1 scale"})
dist2_type_control = Inputs.select(["normal", "uniform", "exponential", "beta"], {value: "normal", label: "Distribution 2 type"})
dist2_mu_control = Inputs.range([-3, 3], {step: 0.1, value: 2, label: "Dist 2 location"})
dist2_sigma_control = Inputs.range([0.2, 3], {step: 0.1, value: 1.2, label: "Dist 2 scale"})
lambda1_control = Inputs.range([0, 1], {step: 0.05, value: 0.5, label: "Weight λ₁ (λ₂ = 1-λ₁)"})
dist1_type = Generators.input(dist1_type_control)
dist1_mu = Generators.input(dist1_mu_control)
dist1_sigma = Generators.input(dist1_sigma_control)
dist2_type = Generators.input(dist2_type_control)
dist2_mu = Generators.input(dist2_mu_control)
dist2_sigma = Generators.input(dist2_sigma_control)
lambda1 = Generators.input(lambda1_control)
bary_controls_view = html`
<style>
.bary-slider-grid { display:flex; flex-wrap:wrap; gap:6px 20px; width:100%; margin:0 0 12px; font:0.85em system-ui,sans-serif; container-type:inline-size; }
.bary-slider-grid > * { flex:1 1 calc((100% - 40px)/3); min-width:0; margin:0; }
.bary-slider-grid input[type="number"] { width:7.5rem !important; }
@container (max-width:700px) { .bary-slider-grid > * { flex-basis:calc((100% - 20px)/2); } }
@container (max-width:480px) { .bary-slider-grid > * { flex-basis:100%; } }
</style>
<div class="bary-slider-grid">
<div>${dist1_type_control}</div>
<div>${dist1_mu_control}</div>
<div>${dist1_sigma_control}</div>
<div>${dist2_type_control}</div>
<div>${dist2_mu_control}</div>
<div>${dist2_sigma_control}</div>
<div>${lambda1_control}</div>
</div>`
function barySvgFragment(markup) {
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
svg.innerHTML = markup;
const fragment = document.createDocumentFragment();
while (svg.firstChild) fragment.appendChild(svg.firstChild);
return fragment;
}
function qml(p, typ, mu, sig) {
const pp = Math.min(1 - 1e-12, Math.max(1e-12, p));
if (typ === "normal") {
// Winitzki's inverse-erf approximation, transformed to a normal quantile.
const x = 2 * pp - 1;
const a = 0.147;
const logTerm = Math.log(1 - x * x);
const t = 2 / (Math.PI * a) + logTerm / 2;
const erfInv = Math.sign(x) * Math.sqrt(Math.sqrt(t * t - logTerm / a) - t);
return mu + sig * Math.SQRT2 * erfInv;
} else if (typ === "uniform") {
return mu - sig + 2 * sig * pp;
} else if (typ === "exponential") {
return mu - sig * Math.log(1 - pp);
} else if (typ === "beta") {
// Invert the exact Beta(2,5) CDF: F(x) = 1-(1-x)^5(1+5x).
let lo = 0, hi = 1;
for (let k = 0; k < 40; k++) {
const mid = (lo + hi) / 2;
const cdf = 1 - (1 - mid) ** 5 * (1 + 5 * mid);
if (cdf < pp) lo = mid; else hi = mid;
}
return mu + sig * ((lo + hi) / 2 - 2 / 7);
}
return mu;
}
function runBarycenterDemo(type1, mu1, sigma1, type2, mu2, sigma2, weight1) {
const nGrid = 200;
// Midpoints avoid evaluating unbounded quantile functions at u=0 or u=1.
const uGrid = Array.from({length: nGrid}, (_, j) => (j + 0.5) / nGrid);
const q1 = uGrid.map(u => qml(u, type1, mu1, sigma1));
const q2 = uGrid.map(u => qml(u, type2, mu2, sigma2));
const qBar = uGrid.map((u, i) => weight1 * q1[i] + (1 - weight1) * q2[i]);
// Compute W2 distances
let w2_12 = 0, w2_1bar = 0, w2_2bar = 0;
const du = 1 / nGrid;
for (let i = 0; i < nGrid; i++) {
w2_12 += (q1[i] - q2[i]) ** 2 * du;
w2_1bar += (q1[i] - qBar[i]) ** 2 * du;
w2_2bar += (q2[i] - qBar[i]) ** 2 * du;
}
return { uGrid, q1, q2, qBar, w2_12: Math.sqrt(w2_12), w2_1bar: Math.sqrt(w2_1bar), w2_2bar: Math.sqrt(w2_2bar) };
}
bres = runBarycenterDemo(dist1_type, dist1_mu, dist1_sigma, dist2_type, dist2_mu, dist2_sigma, lambda1);
function renderBarycenterDemo(bres, bary_controls_view, lambda1) {
return html`
<div style="font-family: system-ui, sans-serif; max-width: 850px;">
<h4>1D Wasserstein Barycenter via Quantile Averaging</h4>
${bary_controls_view}
<div style="display: flex; gap: 20px; flex-wrap: wrap;">
<!-- Quantile plot -->
<div>
<svg width="380" height="280" style="border: 1px solid #dee2e6; border-radius: 4px;">
${(() => {
const margin = {top: 20, right: 100, bottom: 35, left: 50};
const plotW = 380 - margin.left - margin.right;
const plotH = 280 - margin.top - margin.bottom;
const allQ = [...bres.q1, ...bres.q2, ...bres.qBar];
const yMin = Math.min(...allQ) - 0.5, yMax = Math.max(...allQ) + 0.5;
function xS(u) { return margin.left + u * plotW; }
function yS(q) { return margin.top + plotH - (q - yMin) / (yMax - yMin) * plotH; }
function linePath(ux, qx) {
return ux.map((u, i) => `${i === 0 ? 'M' : 'L'} ${xS(u)} ${yS(qx[i])}`).join(' ');
}
return barySvgFragment(`
<line x1="${margin.left}" y1="${margin.top}" x2="${margin.left}" y2="${margin.top + plotH}" stroke="#adb5bd"/>
<line x1="${margin.left}" y1="${margin.top + plotH}" x2="${margin.left + plotW}" y2="${margin.top + plotH}" stroke="#adb5bd"/>
<text x="${margin.left + plotW/2}" y="${margin.top + plotH + 25}" text-anchor="middle" font-size="10">u (probability level)</text>
<text x="${margin.left - 42}" y="${margin.top + plotH/2}" text-anchor="middle" font-size="10" transform="rotate(-90, ${margin.left - 42}, ${margin.top + plotH/2})">Quantile Q(u)</text>
<path d="${linePath(bres.uGrid, bres.q1)}" fill="none" stroke="#e03131" stroke-width="2"/>
<path d="${linePath(bres.uGrid, bres.q2)}" fill="none" stroke="#1971c2" stroke-width="2"/>
<path d="${linePath(bres.uGrid, bres.qBar)}" fill="none" stroke="#2b8a3e" stroke-width="3"/>
<rect x="${margin.left}" y="${margin.top}" width="${plotW}" height="${plotH}" fill="none" stroke="#dee2e6"/>
<g transform="translate(${margin.left + plotW + 5}, ${margin.top + 10})">
<line x1="0" y1="4" x2="15" y2="4" stroke="#e03131" stroke-width="2"/><text x="18" y="8" font-size="9">μ₁</text>
<line x1="0" y1="20" x2="15" y2="20" stroke="#1971c2" stroke-width="2"/><text x="18" y="24" font-size="9">μ₂</text>
<line x1="0" y1="36" x2="15" y2="36" stroke="#2b8a3e" stroke-width="3"/><text x="18" y="40" font-size="9">Barycenter</text>
</g>
`);
})()}
</svg>
</div>
<!-- Stats -->
<div style="flex: 1; min-width: 220px;">
<div style="padding: 12px; background: #f8f9fa; border-radius: 6px;">
<h4 style="margin: 0 0 8px 0;">Wasserstein Distances</h4>
<table style="width: 100%; border-collapse: collapse;">
<tr><td style="padding: 4px 8px;">W₂(μ₁, μ₂)</td><td style="padding: 4px 8px; text-align: right;">${bres.w2_12.toFixed(3)}</td></tr>
<tr><td style="padding: 4px 8px;">W₂(μ₁, barycenter)</td><td style="padding: 4px 8px; text-align: right;">${bres.w2_1bar.toFixed(3)}</td></tr>
<tr><td style="padding: 4px 8px;">W₂(μ₂, barycenter)</td><td style="padding: 4px 8px; text-align: right;">${bres.w2_2bar.toFixed(3)}</td></tr>
<tr><td style="padding: 4px 8px;"><b>Weight λ₁</b></td><td style="padding: 4px 8px; text-align: right;"><b>${lambda1.toFixed(2)}</b></td></tr>
</table>
<p style="margin-top: 8px; font-size: 0.85em; color: #868e96;">
The barycenter quantile Q(u) = λ₁Q₁(u) + λ₂Q₂(u) is exactly the pointwise weighted average of the quantile functions.
</p>
</div>
</div>
</div>
</div>
`
}
```
```{ojs}
//| label: fig-wass-barycenter
//| fig-cap: "Interactive: 1D Wasserstein barycenters via quantile averaging"
renderBarycenterDemo(bres, bary_controls_view, lambda1)
```
::: {.callout-tip title="Try these experiments"}
- **Equal weights (λ₁ = 0.5):** The barycenter sits halfway between the two distributions in Wasserstein space.
- **λ₁ = 0 or 1:** The barycenter collapses to one of the input distributions.
- **Different distribution types:** Mix a normal with a uniform — the barycenter quantile averages them pointwise, preserving the nondecreasing property.
- **Wasserstein vs. linear averaging:** The Wasserstein barycenter of densities is NOT the pointwise average of densities — it's the average of quantile functions. Try comparing to what a density average would look like.
:::
## Key Takeaways
- **Wasserstein barycenters** are Fréchet means in $(\mathcal{P}_2(\mathcal{X}), W_2)$ — minimizers of expected squared $W_2$ distance.
- In **1D**, the barycenter is the pointwise quantile average: $Q_{\bar{\mu}}(u) = \sum \lambda_i Q_{\mu_i}(u)$.
- **Gaussian barycenters** have closed-form means and a fixed-point equation for covariances (Bures–Wasserstein).
- **Existence** holds under moment and compactness conditions; **uniqueness** requires absolute continuity or 1D structure.
- **Sample barycenters** are strongly consistent, with $n^{-1/2}$ rate in 1D and structured rates in higher dimensions.
- **Computation** ranges from exact LP (small discrete), fixed-point iteration (smooth), to entropic Sinkhorn (large-scale regularized).
## Exercises
1. **Barycenter of point masses.** Show that the Wasserstein barycenter of $\delta_{x_1}, \ldots, \delta_{x_m}$ with weights $\lambda_i$ is $\delta_{\bar{x}}$ where $\bar{x} = \sum \lambda_i x_i$ is the Euclidean mean. <a href="javascript:void(0)" onclick="showSolution('l12-sol-1')" class="solution-link">📝 Show Solution</a>
2. **1D quantile formula.** Derive the 1D barycenter formula $Q_{\bar{\mu}}(u) = \sum \lambda_i Q_{\mu_i}(u)$ from the isometry $\mu \mapsto Q_\mu$ into $L^2(0,1)$. <a href="javascript:void(0)" onclick="showSolution('l12-sol-2')" class="solution-link">📝 Show Solution</a>
3. **Gaussian fixed-point.** For two univariate Gaussians $N(m_1, \sigma_1^2)$ and $N(m_2, \sigma_2^2)$, solve the Bures–Wasserstein equation to find the barycenter variance. <a href="javascript:void(0)" onclick="showSolution('l12-sol-3')" class="solution-link">📝 Show Solution</a>
4. **Entropic bias-variance.** Explain how the entropic regularization parameter $\varepsilon$ trades bias for variance in barycenter computation. What happens as $\varepsilon \to 0$ and $\varepsilon \to \infty$? <a href="javascript:void(0)" onclick="showSolution('l12-sol-4')" class="solution-link">📝 Show Solution</a>
<style>
.solution-link { font-size: 0.9em; text-decoration: none; white-space: nowrap; margin-left: 0.3em; }
.solution-link:hover { text-decoration: underline; }
.solution-dialog { padding: 0; max-width: 720px; }
.solution-dialog-header { display: flex; justify-content: space-between; align-items: flex-start; border-bottom: 1px solid #dee2e6; padding: 1.25rem 1.5rem 1rem; background: #f8f9fa; border-radius: 8px 8px 0 0; }
.solution-dialog-header h4 { margin: 0; font-size: 1.15rem; }
.solution-dialog-close { background: none; border: 1px solid #adb5bd; border-radius: 4px; padding: 0.2rem 0.75rem; cursor: pointer; font-size: 0.9rem; color: #495057; white-space: nowrap; flex-shrink: 0; }
.solution-dialog-close:hover { background: #e9ecef; }
.solution-original { padding: 1rem 1.5rem; background: #f1f3f5; border-left: 4px solid #868e96; margin: 1rem 1.5rem; border-radius: 4px; font-size: 0.95rem; }
.solution-answer { padding: 0.5rem 1.5rem 1.5rem; }
.solution-answer strong { color: #2b8a3e; }
dialog { border: none; border-radius: 8px; box-shadow: 0 8px 32px rgba(0,0,0,0.22); padding: 0; max-width: 750px; width: 90vw; }
dialog::backdrop { background: rgba(0,0,0,0.45); }
</style>
<dialog id="l12-sol-1"><div class="solution-dialog"><div class="solution-dialog-header"><h4>Exercise 1: Point Mass Barycenter</h4><button onclick="closeSolution('l12-sol-1')" class="solution-dialog-close">✕ Close</button></div><div class="solution-original"><strong>Exercise:</strong> Show the Wasserstein barycenter of Dirac masses is a Dirac at the weighted mean.</div><div class="solution-answer"><strong>Solution:</strong> For $\mu_i = \delta_{x_i}$, any coupling $\pi \in \Pi(\nu, \delta_{x_i})$ must have second marginal $\delta_{x_i}$, so $\pi = \nu \otimes \delta_{x_i}$. Then $W_2^2(\nu, \delta_{x_i}) = \int \|y - x_i\|^2 d\nu(y)$. The barycenter objective is $\sum \lambda_i \int \|y - x_i\|^2 d\nu(y) = \int \sum \lambda_i \|y - x_i\|^2 d\nu(y)$. For each $y$, $\sum \lambda_i \|y - x_i\|^2$ is minimized at $y = \sum \lambda_i x_i$. Hence the minimizer $\nu$ must be $\delta_{\bar{x}}$ with $\bar{x} = \sum \lambda_i x_i$.</div></div></dialog>
<dialog id="l12-sol-2"><div class="solution-dialog"><div class="solution-dialog-header"><h4>Exercise 2: 1D Quantile Derivation</h4><button onclick="closeSolution('l12-sol-2')" class="solution-dialog-close">✕ Close</button></div><div class="solution-original"><strong>Exercise:</strong> Derive the 1D formula from the quantile isometry.</div><div class="solution-answer"><strong>Solution:</strong> The map $\iota: \mu \mapsto Q_\mu$ is an isometric embedding of $\mathcal{P}_2(\mathbb{R})$ into $L^2(0,1)$. Its image is the closed convex cone of nondecreasing functions. The barycenter problem $\min_\nu \sum \lambda_i W_2^2(\nu, \mu_i)$ becomes, under $\iota$, $\min_{q \in \mathcal{C}} \sum \lambda_i \|q - Q_{\mu_i}\|_{L^2}^2$ where $\mathcal{C}$ is the convex cone. Since $\sum \lambda_i \|q - Q_{\mu_i}\|^2 = \|q - \sum \lambda_i Q_{\mu_i}\|^2 + \text{const}$ (by the Hilbert-space parallelogram law), the minimizer is the projection of $\sum \lambda_i Q_{\mu_i}$ onto $\mathcal{C}$. But the pointwise convex combination of nondecreasing functions is nondecreasing, so $\sum \lambda_i Q_{\mu_i}$ already lies in $\mathcal{C}$. Hence the minimizer is exactly $Q_{\bar{\mu}} = \sum \lambda_i Q_{\mu_i}$.</div></div></dialog>
<dialog id="l12-sol-3"><div class="solution-dialog"><div class="solution-dialog-header"><h4>Exercise 3: Gaussian Fixed-Point</h4><button onclick="closeSolution('l12-sol-3')" class="solution-dialog-close">✕ Close</button></div><div class="solution-original"><strong>Exercise:</strong> For univariate Gaussians $N(m_i, \sigma_i^2)$, find the barycenter variance.</div><div class="solution-answer"><strong>Solution:</strong> The Bures-Wasserstein equation for univariate case simplifies dramatically. For 1D, the fixed-point equation $\bar{\Sigma} = \sum \lambda_i (\bar{\Sigma}^{1/2} \Sigma_i \bar{\Sigma}^{1/2})^{1/2}$ becomes $\bar{\sigma}^2 = \sum \lambda_i \sqrt{\bar{\sigma}^2 \sigma_i^2 \bar{\sigma}^2} / \bar{\sigma} = \sum \lambda_i \sigma_i$. Actually, more carefully: $(\bar{\sigma} \sigma_i^2 \bar{\sigma})^{1/2} = \bar{\sigma} \sigma_i$. So $\bar{\sigma} = \sum \lambda_i \bar{\sigma} \sigma_i / \bar{\sigma} = \sum \lambda_i \sigma_i$. Thus $\bar{\sigma} = \sum \lambda_i \sigma_i$ — the barycenter standard deviation is the weighted arithmetic mean of the individual standard deviations. The mean is $\bar{m} = \sum \lambda_i m_i$ as always. So the Wasserstein barycenter of univariate Gaussians is $N(\sum \lambda_i m_i, (\sum \lambda_i \sigma_i)^2)$.</div></div></dialog>
<dialog id="l12-sol-4"><div class="solution-dialog"><div class="solution-dialog-header"><h4>Exercise 4: Entropic Regularization</h4><button onclick="closeSolution('l12-sol-4')" class="solution-dialog-close">✕ Close</button></div><div class="solution-original"><strong>Exercise:</strong> Explain the bias-variance tradeoff of entropic regularization.</div><div class="solution-answer"><strong>Solution:</strong> The entropic penalty replaces the exact transport cost with $C_\varepsilon(\pi) = \sum \|z_\ell - x_{ik}\|^2 \pi_{i\ell k} + \varepsilon \sum \pi_{i\ell k}(\log \pi_{i\ell k} - 1)$. **As $\varepsilon \to 0$:** The penalty vanishes. The solution approaches the exact (unregularized) barycenter. However, the Sinkhorn algorithm requires more iterations (slower convergence) because the problem becomes less strictly convex. Numerical stability degrades. **As $\varepsilon \to \infty$:** The entropy term dominates. The optimal coupling becomes uniform (maximum entropy), regardless of the transport cost. The resulting "barycenter" is not meaningful — it ignores the geometry of the ground space. **Practical guidance:** Choose $\varepsilon$ small enough that the regularized barycenter is visually close to the true one, but large enough that Sinkhorn converges in reasonable time. Cross-validation on a held-out Wasserstein distance is sometimes used.</div></div></dialog>
<script>
function showSolution(id) { const d = document.getElementById(id); if (d) { d.showModal(); if (window.MathJax && MathJax.typesetPromise) { MathJax.typesetPromise([d]).catch(function(e) { console.log('MathJax error:', e); }); } } }
function closeSolution(id) { const d = document.getElementById(id); if (d) d.close(); }
document.addEventListener('click', function(e) { if (e.target.tagName === 'DIALOG') e.target.close(); });
</script>
## Further Reading
- @LeGouicLoubes2017 — Existence and consistency theory for Wasserstein barycenters.
- @AguehCarlier2011 — Gaussian barycenters and the Bures–Wasserstein metric.
- @LeGouicParisRigolletStromme2023 — Sharp convergence rates under convexity/smoothness of transport maps.
- @CuturiDoucet2014; @BenamouCarlierCuturiNennaPeyre2015 — Entropic regularization and Sinkhorn scaling.
- @AlvarezEstebanEtAl2016 — Fixed-point computation of Wasserstein barycenters.
- @PanaretosZemel2020 — Statistical aspects of optimal transport.
## Self-Assessment Quiz
Test your understanding of this lecture with the interactive MCQ quiz:
👉 **[Lecture 12 Quiz — 10 Multiple-Choice Questions](../quizzes/lecture-12-quiz.qmd)**