Skip to content

Distributions ​

A transport goes from a source, a sum of diracs, to a target, a continuous density. Both are normalized to a total mass of 1: only the ratios between masses ( or between pixel values ) count.

py
import numpy as np
import sdot

rng = np.random.default_rng( 0 )
f = sdot.SumOfDiracs( rng.random( ( 100, 2 ) ) )       # the source: diracs ( `weights`: their masses )

targets = [
    sdot.Box(),                                          # the unit square ( the dimension comes from the source )
    sdot.Box( origin = [ -1, -1 ], frame = [ 2, 2 ] ),   # [ -1, 1 ]^2 ( `frame`: the edges, or their lengths )
    sdot.Image( rng.random( ( 64, 64 ) ) ),            # 64 x 64 pixels on [ 0, 1 ]^2
    sdot.Image( rng.random( ( 32, 64 ) ) ),            # [ 0, 0.5 ] x [ 0, 1 ]: the longest side is 1
    sdot.Image( rng.random( ( 32, 64 ) ), frame = [ 1, 1 ] ),           # [ 0, 1 ]^2: `frame`, the edges of the image
    sdot.Image( rng.random( ( 32, 64 ) ), pixel_frame = [ [ 0.1, 0 ], [ 0, 0.1 ] ] ),   # pixels of 0.1
    sdot.ConvexHull( [ [ 0, 0 ], [ 1, 0 ], [ 0.5, 1 ] ] ),  # a uniform density on a convex polygon
    sdot.SumOfGaussians( [ [ 0.3, 0.3 ], [ 0.7, 0.6 ] ], sigmas = [ 0.1, 0.2 ], weights = [ 1, 2 ] ),
    sdot.Mesh( [ [ 0, 0 ], [ 1, 0 ], [ 1, 1 ], [ 0, 1 ] ], [ [ 0, 1, 2 ], [ 0, 2, 3 ] ],
               values = [ 0, 1, 2, 1 ] ),                # piecewise linear: one value per node
]
for g in targets:
    print( type( g ).__name__, sdot.w2( f, g ) )

Sources ​

Class
SumOfDiracs( positions, weights = None )diracs at positions ( [ n, d ] ), of masses weights ( [ n ], all equal by default )
SumOfDiracsOnAGrid( shape, weights = None )diracs at the centres of the cells of a regular grid, solved by a dedicated path in 2D: see Diracs on a Grid
ProjectedSumOfDiracs( points, normal, weights = None )1D diracs, the projections of shared points on a normal per item ( e.g. one per angle of a tomography ), never materialized
ProjectedSumOfTents( points, half_widths, normal, weights = None )the same with a tent of half-width half_widths instead of a dirac: a continuous source, see Projected Sources
ProjectedSumOfAnisotropicTents( points, matrices, normal, weights = None )tents whose half-width depends on the direction ( a matrix per tent ): see Projected Sources

Targets ​

The target also gives the domain of the transport: the cells of the power diagram are cut by the support it declares.

Classdensity
Box( origin = None, frame = None )uniform on a box ( the unit cube by default, in the dimension of the source ): see Convex Polytopes
ConvexHull( points )uniform on the convex hull of points ( [ n, d ] ): see Convex Polytopes
Polytope( directions, offsets )uniform on the convex polytope directions . x <= offsets
Image( values, frame = None, pixel_frame = None, origin = None )piecewise constant on a grid of pixels
Image( coeffs, degree = p )a polynomial per pixel: see Images and Splines
SplineGrid( values, degree = 3 )a B-spline on a grid of pixels: see Images and Splines
SumOfGaussians( positions, sigmas, weights = None )a mixture of isotropic gaussians: see Sums of Gaussians
Mesh( nodes, simplices, values = None )piecewise linear on a mesh of simplices ( triangles in 2D, tetrahedra in 3D ): see Meshes
Mesh( nodes, segments_or_triangles, values = None )carried by lines ( 2D, 3D ) or surfaces ( 3D ): see Lines and Surfaces

Image ​

values is indexed as [ x, y, ... ]. By default the image fits in the unit square ( cube... ): its longest side has length 1, and the proportions are kept. origin, frame ( the whole image ) or pixel_frame ( one pixel ) place it elsewhere. Polynomial pixels and splines: see Images and Splines.

SumOfGaussians ​

weights are the masses of the gaussians, not their heights. Its support is the box that holds every gaussian up to support_sigmas = 6 standard deviations, or support_box = ( lo, hi ). See Sums of Gaussians.

Mesh ​

values gives the density at the corners: [ nb_nodes ] for a continuous density ( one value per node ), or [ nb_simplices, d + 1 ] for a density discontinuous between simplices. Constant by default. See Meshes.

Dimensions ​

The dimension comes from the source: positions of shape [ n, d ]. In 1D, the plan is computed by a sort, exactly ( see plans and settings ).

SDOT — H. Leclerc, Q. Mérigot, T. Gallouët · LMO / INRIA PARMA