T4transport is an R toolbox for computational optimal transport. It provides finite and regularized transport, sliced comparisons, Gaussian calculations, orthogonal alignment, Gromov-Wasserstein methods, barycenters, medians, and interpolation. Explicit representations and ot_inspect() help identify the mathematical target, numerical outcome, and approximation in each calculation.
The 0.2.0 development series includes numerical and compatibility changes. Read the migration tutorial and NEWS before updating an existing analysis.
Installation
Install the released version from CRAN:
install.packages("T4transport")This website documents development version 0.2.0.9002. Install the current development version from GitHub:
# install.packages("remotes")
remotes::install_github("kisungyou/T4transport")The CRAN release may have a different interface. For a local checkout, use R CMD INSTALL .; for a downloaded source archive, use:
install.packages("T4transport_0.2.0.9002.tar.gz", repos = NULL, type = "source")Building from source requires a C++20 compiler and the Rcpp/RcppArmadillo build dependencies declared in the package.
Represent, compute, and inspect
A row of support is an atom; mass describes probability within one observation. Collection weights instead control the importance of whole distributions. Both kinds of weights are normalized independently.
library(T4transport)
mu <- ot_measure(c(0, 2), mass = c(1, 3))
nu <- as_ot_measure(ecdf(c(0, 0, 4)))
observations <- ot_collection(list(first = mu, second = nu), weights = c(2, 1))
comparison <- ot_distance(mu, nu, return_plan = TRUE)
ot_inspect(comparison)
#> Transport report | finite | unregularized_transport
#> Producer: ot_distance
#> Status: SUCCESS ( finite_monotone_transport )
#> distance transport_cost transport_cost_root
#> 1.732051 3.000000 1.732051
#> wasserstein_distance
#> 1.732051
#> Scope: reported stopping criterion only; interpret its reason and available checks
fit <- ot_summary(observations, target = "barycenter")
fit
#> Wasserstein barycenter | unrestricted_1d | quantile
#> Status: SUCCESS ( quantile_average )
#> Objective: 0.6666667 | estimated atoms: 3
fit$estimate
#> Finite probability measure: 3 atoms in 1 dimension(s)
#> Representation: empirical | total mass: 1
stopifnot(comparison$status == "success", fit$status == "success")For scalar finite measures, distance and barycenter calculations integrate exactly over finite quantile intervals, up to floating-point arithmetic. Medians use a collision-aware geometric median in the same quantile coordinates. A barycenter minimizes a weighted sum of squared W2 distances; a median minimizes a weighted sum of W2 distances.
observations <- lapply(c(0, 0, 0, 2, 8), ot_measure)
ordinary <- ot_summary(observations, target = "barycenter")
robust <- ot_summary(observations, target = "median")
c(barycenter = ordinary$estimate$support[1, 1],
median = robust$estimate$support[1, 1])
#> barycenter median
#> 2 0Choose the statistical target before the solver
| Task | Entry point | Main contract |
|---|---|---|
| Compare finite measures | ot_distance() |
Exact transport or explicitly regularized transport; costs and distance values are separate |
| Unrestricted scalar summary | ot_summary(..., feasible = "unrestricted_1d") |
Exact finite quantile representation; barycenter or W2 median |
| Move a prescribed number of atoms | ot_summary(..., feasible = "free_support_fixed_mass") |
Locations vary, candidate masses stay fixed; local optimization with recorded starts |
| Estimate masses on a fixed grid | ot_summary(..., feasible = "fixed_support", support = ...) |
Locations stay fixed; variable probability masses |
| Compare Gaussian distributions |
ot_gaussian() and ot_gaussian_distance()
|
Uses parameters directly, without sampling |
| Summarize Gaussian distributions | ot_gaussian_summary() |
Parameter objects; declared Gaussian-family target and covariance domain |
| Compare projections | swdist() |
Weighted measures; equally weighted directions retained for replay |
| Align coordinates |
pwdist(), pwbary()
|
Orthogonal alignment; local optimization |
| Compare relational geometry |
gwdist(), gwbary()
|
Dissimilarity matrices and explicit squared-loss convention |
| Interpolate images | imageinterp() |
Exact transported measure plus grid-projection diagnostics |
| Inspect a numerical result | ot_inspect() |
Available metadata without recomputing the fit |
Entropy regularization changes the problem. Sinkhorn results report the transport component and the full entropy-regularized objective separately; the latter can be negative and is not a distance. Regularization is currently available for pairwise transport and fixed-support barycenters, not as an implicit replacement for the unregularized median.
Use ot_inspect(result) to read available target, values, stopping scope, checks, history, and approximation metadata across these families. Reaching an iteration limit is not convergence, and a small local update is not a general global-optimality certificate. return_plan = FALSE avoids retaining a plan in the returned object; it does not promise a matrix-free solver.
Different geometries, shared objects
x <- ot_measure(rbind(c(0, 0), c(1, 0), c(0, 2)), c(1, 2, 1))
y <- ot_measure(rbind(c(0, 0), c(0, 1), c(-2, 0)), c(1, 2, 1))
projections <- rbind(c(1, 0), c(0, 1), c(1, 1))
sliced <- swdist(x, y, directions = projections)
aligned <- pwdist(x, y)
ot_inspect(sliced)
#> Transport report | sliced | finite_direction_sliced_wasserstein
#> Producer: swdist
#> Status: SUCCESS ( all_finite_1d_problems_solved )
#> distance
#> 0.9574271
#> Scope: finite projected problems solved; sphere-integration accuracy is not certified
ot_inspect(aligned)
#> Transport report | procrustes | procrustes_wasserstein_local_comparison
#> Producer: pwdist
#> Status: SUCCESS ( block_objective_tolerance )
#> distance transport_cost objective
#> 0 0 0
#> Scope: none; alternating block objective stopping is localThe coordinate comparison and the aligned comparison answer different questions. PW permits orthogonal transformations, including reflections; centering or scaling is a separate choice. Finite-direction sliced values retain their projection dependence. GW instead compares supplied within-object dissimilarities and reports an attained local squared-loss objective.
gaussians <- list(ot_gaussian(0, 1), ot_gaussian(2, 4))
gfit <- ot_gaussian_summary(gaussians, weights = c(1, 3))
gfit$estimate
#> Gaussian probability measure in 1 dimension(s)
#> Covariance domain: nonnegative variance
#> Mean: 1.5
ot_inspect(gfit)
#> Transport report | gaussian | gaussian_family_barycenter
#> Producer: ot_gaussian_summary
#> Status: SUCCESS ( mean_standard_deviation_formula )
#> objective
#> 0.9375
#> Scope: reported stopping criterion only; interpret its reason and available checksTutorials
- Choosing a geometry and inspecting results
- Transport plans and interpolation
- Distribution representations, objectives, and Gaussian parameters
- Ordinary and robust summaries, initialization, and numerical status
- Migrating legacy analyses
- Computing and displaying transport plans
Installed help is available with help(package = "T4transport") and browseVignettes("T4transport"). Tutorial examples are executable and run without external data downloads. The manuscript and its frozen replication bundle are maintained separately from this package website. Historical analyses using version 0.2.0.9001 should retain that version’s source archive and recorded configuration.