Sampling algorithms for probability distributions on manifolds using Riemannian geometry. Generates samples from arbitrary curves and surfaces by performing pullback on the input density.
Sampling on
We want to uniformly sample random points from a compact orientable
Lets consider the special case of sampling from curves. A natural approach would be to parametrize
the curve by
The generalization of this notion to higher dimensions is the volume-preserving parametrization. A
coordinate system
Evidently, not all coordinate systems are volume-preserving; however, given an arbitrary coordinate
system
must be equal to
which is a Monge-Ampere type PDE if you assume that
The second approach I came up with was much simpler than the first, and I am surprised that I didn't
think of it first. As before suppose that our manifold is parametrized by the coordinate
system
where the first equality follows because
The core computation that we need to perform is sampling from
- The parameter space
$U$ is a bounded open rectangle. This is done to simplify the representation on the computer. - The coordinate system
$\varphi : U \to M$ is an almost-everywhere parametrization. This reasonable assumption (see first paragraph) is made to avoid dealing with an atlas. In particular, since those points of the manifold that aren't in$\varphi(U)$ form a set of measure zero, no one will notice if the sampler ignores them. - The function
$f$ is bounded on$U$ . This is not the case in general (e.g., parametrizing$(0,1)$ using$\sqrt{x}$ , in which case$f(x) = x^{-1/2}/2$ is not bounded), but will hold if$\varphi$ can be extended continuously to some compact set containing$U$ . I am not sure if this assumption is always compatible with (1), though I cannot produce a counterexample. I believe that it is reasonable.
Since
To compile python bindings run make python. To compile C++ demos run make ellipse or make torus.
To install the R package:
cd src/R
R CMD INSTALL .See demo.ipynb for detailed examples and applications to Monte Carlo integration and estimating the mean Hausdorff distance between compact manifolds.
from saman import Manifold
import numpy as np
class Ellipse(Manifold):
def __init__(self):
super().__init__(2, 1, 2.5, np.array([0.0]), np.array([2.0 * np.pi]))
def coord(self, t):
return np.array([2*np.cos(t[0]), np.sin(t[0])])
def pushforward(self, t):
return np.array([[-2*np.sin(t[0])], [np.cos(t[0])]])
ellipse = Ellipse()
samples = ellipse.sample(n_samples=100)library(saman)
coord = function(t) c(2 * cos(t[1]), sin(t[1]))
pushforward = function(t) matrix(c(-2 * sin(t[1]), cos(t[1])), 2, 1)
ellipse = saman.manifold(2, 1, 2.5, c(0), c(2*pi), coord, pushforward)
samples = ellipse$sample(100)If you want to work with C++ directly see the examples/ folder.
- Move core logic to C++
- Create python bindings
- Create R bindings
- Demo library by computing mean Hausdorff distance.
- Write expository article about how this is done.
