blue_sampler package
Submodules
blue_sampler.api module
Public API.
blue.sample_points is the main entry point of the package. It provides a high-level interface for generating large point sets on the periodic unit hypercube [0, 1)^D with sub-Poisson density fluctuations (so-called blue noise).
The package also exposes utilities to sample tessellations (2D only) and balanced clusters (arbitrary dimension). tessels or clusters are sampled with following balance property: uniform area repartition if no target is given or uniform atoms repartition if target atoms are given.
Clusters and tessellations can subsequently be converted into low-discrepancy point sets using `blue.from_geometry’ which internally solves a moment-matching problem
- type blue_sampler.api.NDArray = ndarray[_AnyShape, dtype]
- class blue_sampler.api.ProgressLogger(D, verbose)[source]
Bases:
objectHierarchical -based progress display for nested pipeline levels.
- blue_sampler.api.from_geometry(geometry, gtype, p=3, **kwargs)[source]
Convert tessels or clusters into low-discrepancy point set.
Each tessel or cluster is replaced by n points by solving a moment-matching problem (Levenberg-Marquardt) via momentum_fit.
- Parameters:
geometry (
NDArray) –Batch of tessels or clusters to convert. - gtype=”polygons” : quadrilaterals of shape (N, 4, 2),
e.g. the quad output of sample_tessels.
gtype=”clusters” : point sets of shape (N, K, D), e.g. the output of sample_clusters, or the atoms output of sample_tessels(…, return_atoms=True).
gtype (
str) – Geometry type. “polygons” only supports D = 2.p (
int) – Maximum total moment order to match (centroid plus central moments up to order p).**kwargs – Additional arguments passed to momentum_fit (e.g., n_restarts, random_state, tol).
- Returns:
n points per tessel or cluster, matching its moments up to order p.
- Return type:
NDArray
- blue_sampler.api.im2points(image='anything.jpg', N=100000)[source]
simple wrapper for image stippling
- blue_sampler.api.momentum_fit(distribution, distribution_type='clusters', p=3, weights=None, n_restarts=1, restart_tol=1e-30, n_iter=100, lambda0=0.01, tol=1e-30, random_state=None)[source]
Fit n points X_1, …, X_n whose centroid and central moments (q = 1, …, p-1) match those of distribution.
n is determined automatically (see required_n): it is not a parameter. When p == 2, only the centroid (q = 1) is requested; no central moments and no LM solve are needed, so the n = 1 target centroid is returned directly.
- blue_sampler.api.plot(points, auto_zoom=False, max_points=30000, ax=None, return_fig=False, figsize=(8, 8), **scatter_kw)[source]
Scatter plot of a 2-D or 3-D point set.
- If auto_zoom is set to True:
For large point sets the view is automatically zoomed so that at most max_points points are displayed.
- Parameters:
points (
NDArray) – Point coordinates, with D in {2, 3}. Higher-dimensional arrays are silently projected onto the first 3 axes.auto_zoom (
bool) – Whether to apply auto_zoom for large point sets.max_points (
int) – Maximum number of points to draw used for auto_zoom.ax (
Axes|None) – Existing axes to draw into. If None, a new figure is created.return_fig (
bool) – If True, returns (fig, ax). If False, displays the figure and returns None.**scatter_kw – Extra keyword arguments forwarded to ax.scatter.
- Return type:
tuple[Figure,Axes] |None
- blue_sampler.api.sample_clusters(N=32768, D=2, targets=None, n_per_cluster=16)[source]
Recursively partition a point set into N balanced clusters.
At each recursion step, every cluster is split into two equal halves using a random median hyperplane. After log2(N) recursion levels, exactly N clusters are obtained.
- Parameters:
N (
int) – Number of final clusters. Must be a power of two.D (
int) – Ambient dimension.targets (
NDArray|None) – Initial atoms to clusterise. If omitted, a Sobol low-discrepancy sequence containing K = N * n_per_cluster atoms is generated automatically.n_per_cluster (
int) – Number of atoms per final cluster. Only used when targets is not provided.
- Returns:
Collection of balanced clusters.
- Return type:
NDArray
Notes
The recursive splitting procedure requires the total number of atoms K to be divisible by N.
- blue_sampler.api.sample_points(N=32768, D=2, bruteforce=False, warmstart=None, n_iter=6, targets=None, verbose=1)[source]
Generate N stealthy (blue-noise) points in [0, 1)^D.
- Parameters:
N (
int) – Number of output points.D (
int) – Spatial dimension.bruteforce (
bool) – Use the bruteforce O(N^2) algorithm instead of the recursive one. Gives a better sample but is intractable for N >= 50_000. Automatically forced to True when N <= 2_000.warmstart (
str|NDArray|None) –Initial point configuration. - None : default random/recursive initialisation. - “Sobol” : initialise with a Sobol low-discrepancy sequence
(requires scipy.stats.qmc.Sobol).
ndarray : use given points as the starting configuration.
n_iter (
int) – Number of solver iterations. Each iteration runs 10 gradient steps plus a structural gridification step (neighbor lookup). More iterations = better quality but slower.targets (
NDArray|None) – Atoms describing a target density. can also be a path to an image, e.g. targets = “zebra.jpg”verbose (
int) – 0 = silent, 1 = live progress.
- Returns:
points – The sampled point coordinates in [0, 1)^D.
- Return type:
NDArray
- blue_sampler.api.sample_tessels(N=32768, D=2, targets=None, return_atoms=False)[source]
Recursively split the unit square into N random quadrilaterals.
If targets is None, splits are computed to achieve equal areas. If targets is provided, splits are computed to achieve a median separation of the atoms.
- Parameters:
N (
int) – Number of final tessels. Must be a power of 2.targets (
NDArray|None) – Coordinates of atoms to split, in the [0, 1)^2 unit box. K must be a multiple of N. The more targets provided, the better the approximation, but the slower the computation (K/N should be at least 100 for a decent tessellation). A typical use case is adaptive tessellation, e.g. with targets being i.i.d. points sampled from a target density.
- Return type:
NDArray|tuple[NDArray,NDArray]- Returns:
quad (ndarray of shape (N, 4, 2)) – A tessellation composed of N quadrilaterals with equal area or equal number of atoms.
atoms (ndarray of shape (N, K/N, 2)) – The input target atoms, redistributed among their final quadrilateral. Only returned if targets was provided and return_atoms is set to True.
Notes
Only supports 2D geometry and a power-of-two number of tessels (N).
- blue_sampler.api.tile(x, repeat, flatoutput=True)[source]
Tile points on the unit torus to cover [0, 1)^D periodically.
Each of the repeat**D copies of x is rescaled by 1/repeat and shifted to its own sub-cube, so that the copies together pave the unit torus again. For example in 2D with repeat=2: tile (0, 0) holds x/2, tile (1, 1) holds x/2 + 0.5, etc.
- Parameters:
x (
NDArray) – Points in [0, 1)^D (unit torus).repeat (
int) – Number of repetitions per axis. The output therefore contains Nfinal = N * repeat**D points.flatoutput (
bool) – If True, reshape the output to (Nfinal, D). If False, keep the tile structure as leading axes.
- Returns:
Tiled version of x, periodized over [0, 1)^D.
- Return type:
NDArray
blue_sampler.datasets module
- blue_sampler.datasets.generate_dataset(size=(1000, 2), dataset='barbara', plot_data=True, list_method=True)[source]
- blue_sampler.datasets.samplepoints(method='gaussian', size=(1000000, 2), plot_points=False)[source]
Generate point clouds using various sampling strategies.
- Parameters:
method (str) –
Sampling method. Supported values:
General methods (any dimension D): - “square” : uniform in [-1, 1]^D - “ball” : uniform in the unit ball - “ring” : Gaussian with radial offset - “gaussian” : standard normal distribution - “spiky” : L^alpha ball (alpha < 1) - “holy” : hypercube with spherical holes
Dataset-based methods (fixed dimensions): - “barbara”, “lena”, “france”, “germany” : 2D datasets - “everest” : 3D dataset (elevation-based sampling)
size (tuple of int) – (N, D) where N is the number of points and D the dimension. Note: D must match the dataset dimension for dataset-based methods.
plot_points (bool, optional) – If True, display the generated points.
- Returns:
Array of shape (N, D) containing sampled points.
- Return type:
numpy.ndarray
blue_sampler.math module
Low-level mathematical helpers
- blue_sampler.math.clean_grad(x)[source]
Replace NaN gradient contributions (fictive points) with 0.
- Return type:
Array
- blue_sampler.math.drop_symmetric(directions)[source]
Keep only one representative from each direction pair {v, -v}.
The canonical representative is the one whose first non-zero component is positive.
- Parameters:
directions (
ndarray)- Return type:
ndarray
- blue_sampler.math.grid_shape(N, D)[source]
Smallest D-hypercube grid that contains at least N points.
- Return type:
tuple[tuple[int,...],int,tuple[int,...]]- Returns:
IJK (shape tuple e.g. (32, 32) for D=2)
total (total number of grid slots (I^D))
axes (tuple(range(D)))
- blue_sampler.math.integers_in_half_ball(radius, D)[source]
Return all non-zero integer lattice vectors inside a sphere of radius, keeping only one vector per direction pair.
- Parameters:
radius (
float)D (
int)
- Return type:
ndarray
- blue_sampler.math.prepare_points(x, N_asked, IJK, D)[source]
Pad N_asked real points to fill the I^D grid.
Fictive slots receive a NaN coordinate so gradients ignore them.
- Parameters:
x (
ndarray|None)N_asked (
int)IJK (
tuple[int,...])D (
int)
- Return type:
Array
- blue_sampler.math.prepare_wave_vectors(Ks)[source]
Build JAX arrays for the spectral gradient.
- Parameters:
Ks (
ndarray)- Return type:
tuple[Array,Array]- Returns:
K_w (complex array of shape (M, D) — phase multipliers)
K_ (complex array of shape (M, D) — normalised duals)
- blue_sampler.math.simplex(D)[source]
Vertices of a regular simplex centred at the origin in R^D.
- Return type:
ndarray
- blue_sampler.math.structure_factor(points, resolution=2000)[source]
Estimate the radial structure factor S(k) via scattering intensity.
- Parameters:
points (
ndarray)resolution (
int)
- Return type:
tuple[ndarray,ndarray]- Returns:
k ((M,) float array — exact wave-vector magnitudes.)
S ((M,) float array — exact S(k) values.)
Note
beyond a radius fixed to capture 1/4 of the “resolution” budget, ALL allowed wavevectors are sampled to get maximal precision on low frequencies. Remaining budget is shared evenly accross all pertinent frequency scales.
blue_sampler.progress module
Just some progress loging staff used when verbose is set to 1 in the solver
blue_sampler.viz module
Visualisation helpers: plot display a 2-D or 3-D point set plot_structure_factor display the structure factor estimated through
scattering intensity
plot_tessels display a tessellation at up to 12 recursion depths plot_clusters display a cluster partition at up to 12 recursion depths
- type blue_sampler.viz.NDArray = ndarray[_AnyShape, dtype]
- blue_sampler.viz.back_merge_clusters(clusters)[source]
Inverse operation of a recursion level.
` Merge sibling clusters back together following the ordering convention used by ``fair_random_split.
- blue_sampler.viz.back_merge_tessels(quads, eps=1e-07)[source]
Invert one step of the tesselation tree by pairing brother quads and identifying the split orientation using cyclic vertex permutation. 100% vectorized.
- blue_sampler.viz.plot(points, auto_zoom=False, max_points=30000, ax=None, return_fig=False, figsize=(8, 8), **scatter_kw)[source]
Scatter plot of a 2-D or 3-D point set.
- If auto_zoom is set to True:
For large point sets the view is automatically zoomed so that at most max_points points are displayed.
- Parameters:
points (
NDArray) – Point coordinates, with D in {2, 3}. Higher-dimensional arrays are silently projected onto the first 3 axes.auto_zoom (
bool) – Whether to apply auto_zoom for large point sets.max_points (
int) – Maximum number of points to draw used for auto_zoom.ax (
Axes|None) – Existing axes to draw into. If None, a new figure is created.return_fig (
bool) – If True, returns (fig, ax). If False, displays the figure and returns None.**scatter_kw – Extra keyword arguments forwarded to ax.scatter.
- Return type:
tuple[Figure,Axes] |None
- blue_sampler.viz.plot_clusters(clusters, return_fig=False)[source]
Display a cluster partition across up to 12 recursion steps.
- Return type:
tuple[Figure,NDArray] |None
- blue_sampler.viz.plot_structure_factor(points, resolution=2000, smoothed=True, ax=None, return_fig=False, **plot_kw)[source]
Log-log plot of the radial structure factor S(k).
S(k) is estimated using standard scattering intensity.
- Parameters:
points (
NDArray) – Point coordinates in [0, 1)^D.resolution (
int) – Number of sampled wave vectors used to estimate sf.smoothed (
bool) – If True, apply a local log-log average. If False, plot raw values.ax (
Axes|None) – Existing axes to draw into. If None, a new figure is created.return_fig (
bool) – If True, returns (fig, ax).**plot_kw – Extra keyword arguments forwarded to ax.loglog.
- Return type:
tuple[Figure,Axes] |None
blue_sampler.warm_start module
Module contents
blue_sampler
Generate stealthy point patterns — low-discrepancy, spectrally isotropic samples on the unit torus [0, 1)^D.
Quick start
>>> import blue_sampler as blue
>>> x = blue.sample(N=10_000, D=2) # (10000, 2) array
>>> blue.plot(x)
>>> blue.plot_structure_factor(x)
- blue_sampler.from_geometry(geometry, gtype, p=3, **kwargs)[source]
Convert tessels or clusters into low-discrepancy point set.
Each tessel or cluster is replaced by n points by solving a moment-matching problem (Levenberg-Marquardt) via momentum_fit.
- Parameters:
geometry (
NDArray) –Batch of tessels or clusters to convert. - gtype=”polygons” : quadrilaterals of shape (N, 4, 2),
e.g. the quad output of sample_tessels.
gtype=”clusters” : point sets of shape (N, K, D), e.g. the output of sample_clusters, or the atoms output of sample_tessels(…, return_atoms=True).
gtype (
str) – Geometry type. “polygons” only supports D = 2.p (
int) – Maximum total moment order to match (centroid plus central moments up to order p).**kwargs – Additional arguments passed to momentum_fit (e.g., n_restarts, random_state, tol).
- Returns:
n points per tessel or cluster, matching its moments up to order p.
- Return type:
NDArray
- blue_sampler.generate_dataset(size=(1000, 2), dataset='barbara', plot_data=True, list_method=True)[source]
- blue_sampler.plot(points, auto_zoom=False, max_points=30000, ax=None, return_fig=False, figsize=(8, 8), **scatter_kw)[source]
Scatter plot of a 2-D or 3-D point set.
- If auto_zoom is set to True:
For large point sets the view is automatically zoomed so that at most max_points points are displayed.
- Parameters:
points (
NDArray) – Point coordinates, with D in {2, 3}. Higher-dimensional arrays are silently projected onto the first 3 axes.auto_zoom (
bool) – Whether to apply auto_zoom for large point sets.max_points (
int) – Maximum number of points to draw used for auto_zoom.ax (
Axes|None) – Existing axes to draw into. If None, a new figure is created.return_fig (
bool) – If True, returns (fig, ax). If False, displays the figure and returns None.**scatter_kw – Extra keyword arguments forwarded to ax.scatter.
- Return type:
tuple[Figure,Axes] |None
- blue_sampler.plot_clusters(clusters, return_fig=False)[source]
Display a cluster partition across up to 12 recursion steps.
- Return type:
tuple[Figure,NDArray] |None
- blue_sampler.plot_structure_factor(points, resolution=2000, smoothed=True, ax=None, return_fig=False, **plot_kw)[source]
Log-log plot of the radial structure factor S(k).
S(k) is estimated using standard scattering intensity.
- Parameters:
points (
NDArray) – Point coordinates in [0, 1)^D.resolution (
int) – Number of sampled wave vectors used to estimate sf.smoothed (
bool) – If True, apply a local log-log average. If False, plot raw values.ax (
Axes|None) – Existing axes to draw into. If None, a new figure is created.return_fig (
bool) – If True, returns (fig, ax).**plot_kw – Extra keyword arguments forwarded to ax.loglog.
- Return type:
tuple[Figure,Axes] |None
- blue_sampler.plot_tessels(tessels, return_fig=False)[source]
Display a tessellation across up to 12 recursion steps.
- Return type:
tuple[Figure,NDArray] |None
- blue_sampler.sample_clusters(N=32768, D=2, targets=None, n_per_cluster=16)[source]
Recursively partition a point set into N balanced clusters.
At each recursion step, every cluster is split into two equal halves using a random median hyperplane. After log2(N) recursion levels, exactly N clusters are obtained.
- Parameters:
N (
int) – Number of final clusters. Must be a power of two.D (
int) – Ambient dimension.targets (
Optional[NDArray]) – Initial atoms to clusterise. If omitted, a Sobol low-discrepancy sequence containing K = N * n_per_cluster atoms is generated automatically.n_per_cluster (
int) – Number of atoms per final cluster. Only used when targets is not provided.
- Returns:
Collection of balanced clusters.
- Return type:
NDArray
Notes
The recursive splitting procedure requires the total number of atoms K to be divisible by N.
- blue_sampler.sample_points(N=32768, D=2, bruteforce=False, warmstart=None, n_iter=6, targets=None, verbose=1)[source]
Generate N stealthy (blue-noise) points in [0, 1)^D.
- Parameters:
N (
int) – Number of output points.D (
int) – Spatial dimension.bruteforce (
bool) – Use the bruteforce O(N^2) algorithm instead of the recursive one. Gives a better sample but is intractable for N >= 50_000. Automatically forced to True when N <= 2_000.warmstart (
Union[str,NDArray,None]) –Initial point configuration. - None : default random/recursive initialisation. - “Sobol” : initialise with a Sobol low-discrepancy sequence
(requires scipy.stats.qmc.Sobol).
ndarray : use given points as the starting configuration.
n_iter (
int) – Number of solver iterations. Each iteration runs 10 gradient steps plus a structural gridification step (neighbor lookup). More iterations = better quality but slower.targets (
Optional[NDArray]) – Atoms describing a target density. can also be a path to an image, e.g. targets = “zebra.jpg”verbose (
int) – 0 = silent, 1 = live progress.
- Returns:
points – The sampled point coordinates in [0, 1)^D.
- Return type:
NDArray
- blue_sampler.sample_tessels(N=32768, D=2, targets=None, return_atoms=False)[source]
Recursively split the unit square into N random quadrilaterals.
If targets is None, splits are computed to achieve equal areas. If targets is provided, splits are computed to achieve a median separation of the atoms.
- Parameters:
N (
int) – Number of final tessels. Must be a power of 2.targets (
Optional[NDArray]) – Coordinates of atoms to split, in the [0, 1)^2 unit box. K must be a multiple of N. The more targets provided, the better the approximation, but the slower the computation (K/N should be at least 100 for a decent tessellation). A typical use case is adaptive tessellation, e.g. with targets being i.i.d. points sampled from a target density.
- Return type:
Union[NDArray,tuple[NDArray,NDArray]]- Returns:
quad (ndarray of shape (N, 4, 2)) – A tessellation composed of N quadrilaterals with equal area or equal number of atoms.
atoms (ndarray of shape (N, K/N, 2)) – The input target atoms, redistributed among their final quadrilateral. Only returned if targets was provided and return_atoms is set to True.
Notes
Only supports 2D geometry and a power-of-two number of tessels (N).
- blue_sampler.structure_factor(points, resolution=2000)[source]
Estimate the radial structure factor S(k) via scattering intensity.
- Parameters:
points (
ndarray)resolution (
int)
- Return type:
tuple[ndarray,ndarray]- Returns:
k ((M,) float array — exact wave-vector magnitudes.)
S ((M,) float array — exact S(k) values.)
Note
beyond a radius fixed to capture 1/4 of the “resolution” budget, ALL allowed wavevectors are sampled to get maximal precision on low frequencies. Remaining budget is shared evenly accross all pertinent frequency scales.
- blue_sampler.tile(x, repeat, flatoutput=True)[source]
Tile points on the unit torus to cover [0, 1)^D periodically.
Each of the repeat**D copies of x is rescaled by 1/repeat and shifted to its own sub-cube, so that the copies together pave the unit torus again. For example in 2D with repeat=2: tile (0, 0) holds x/2, tile (1, 1) holds x/2 + 0.5, etc.
- Parameters:
x (
NDArray) – Points in [0, 1)^D (unit torus).repeat (
int) – Number of repetitions per axis. The output therefore contains Nfinal = N * repeat**D points.flatoutput (
bool) – If True, reshape the output to (Nfinal, D). If False, keep the tile structure as leading axes.
- Returns:
Tiled version of x, periodized over [0, 1)^D.
- Return type:
NDArray