This page provides documentation for the source code used in the paper A fast approach to optimal transport: The back-and-forth method [1]. The original code was written in C and we provide here a MATLAB wrapper to the C code.
We are interested in the optimal transport problem
on the unit square . Here
and
are two densities on
, and
.
The code solves the dual Kantorovich problem
over functions satisfying the constraints
Requirements: FFTW (download here), MATLAB.
Download the C MEX file w2.c here or by cloning the GitHub repository.
Compile it: in a MATLAB session run
mex -O CFLAGS="\$CFLAGS -std=c99" -lfftw3 -lm w2.c This will produce a MEX function that you can use in MATLAB. You may need to use -I and -L to link to the FFTW3 library. See this page for more information on how to compile MEX files.
In a MATLAB session, run the command
[phi, psi] = w2(mu, nu, numIters, sigma);Input:
muandnuare twoarrays of nonnegative values which sum up to the same value.
numItersis the total number of iterations.sigmais the initial step size of the gradient ascent iterations.
Output:
Let us first compute the optimal transport between the characteristic function of a disk and its translate. We discretize the problem with ~1 million points ( ).
n = 1024;
[x, y] = meshgrid(linspace(0.5/n, 1-0.5/n, n));
mu = zeros(n);
idx = (x-0.25).^2 + (y-0.25).^2 < 0.125^2;
mu(idx) = 1;
mu = mu * n^2/sum(mu(:));
nu = zeros(n);
idx = (x-0.75).^2 + (y-0.75).^2 < 0.125^2;
nu(idx) = 1;
nu = nu * n^2/sum(nu(:));
subplot(1,2,1)
imagesc(mu, 'x',[0,1], 'y',[0,1]);
title('Initial density')
subplot(1,2,2)
imagesc(nu, 'x',[0,1], 'y',[0,1]);
title('Final density') Here the densities are renormalized so that
Note that is the translate of
by the vector
, and therefore
numIters = 10;
sigma = 8.0 / max(max(mu(:)), max(nu(:)));
tic;
[phi, psi] = w2(mu, nu, numIters, sigma);
tocOutput:
FFT setup time: 0.01s
iter 0, W2 value: 2.414694e-01
iter 5, W2 value: 2.500000e-01
iter 10, W2 value: 2.500000e-01
Elapsed time is 3.432973 seconds.
Let's compute the optimal transport between the MATLAB peaks function and the uniform measure, on the 2d domain .
We discretize the problem with ~1 million points ( ) and plot the densities.
n = 1024;
[x, y] = meshgrid(linspace(0,1,n));
mu = peaks(n);
mu = mu - min(mu(:));
mu = mu * n^2/sum(mu(:));
nu = ones(n);
s = 16; % plotting stride
subplot(1,2,1);
surf(x(1:s:end,1:s:end), y(1:s:end,1:s:end), mu(1:s:end,1:s:end))
title('Initial density')
subplot(1,2,2);
surf(x(1:s:end,1:s:end), y(1:s:end,1:s:end), nu(1:s:end,1:s:end))
title('Final density')Then run the back-and-forth solver:
numIters = 20;
sigma = 8.0 / max(max(mu(:)), max(nu(:)));
tic;
[phi, psi] = w2(mu, nu, numIters, sigma);
tocOutput:
FFT setup time: 0.02s
iter 0, W2 value: -1.838164e-02
iter 5, W2 value: 9.791770e-04
iter 10, W2 value: 9.793307e-04
iter 15, W2 value: 9.793364e-04
iter 20, W2 value: 9.793362e-04
Elapsed time is 10.016858 seconds.
Finally consider the optimal transport map
and display the displacement as a vector field.
[mx, my] = gradient(-psi, 1/n);
figure;
imagesc(mu,'x',[0,1],'y',[0,1]);
axis square
set(gca,'YDir','normal')
hold on
s = 64;
quiver(x(1:s:end,1:s:end), y(1:s:end,1:s:end), ...
mx(1:s:end,1:s:end), my(1:s:end,1:s:end), ...
0, 'Color','k');[1] Matt Jacobs and Flavien Léger. A fast approach to optimal transport: The back-and-forth method. Numerische Mathematik (2020): 1-32.


