Mike0021's picture
init: terrain diffusion demo Space
0edffc2 verified
Raw
History Blame Contribute Delete
1.46 kB
import numpy as np
def build_quantiles(values, n_quantiles=32, eps=1e-4):
"""
Build quantile values for a distribution.
Parameters
----------
values : array-like
Samples from the distribution.
n_quantiles : int
Number of quantile knots to use.
Larger -> smoother, but a bit more setup cost.
eps : float
Avoids extreme tails (0 and 1) where empirical quantiles are unstable.
Returns
-------
quantiles : np.ndarray
The quantile values (strictly increasing).
"""
v = np.asarray(values).ravel()
# Drop NaNs if present
v = v[~np.isnan(v)]
# Quantile grid (avoid exact 0/1 for stability)
q = np.linspace(eps, 1.0 - eps, n_quantiles)
# Empirical quantile function
v_q = np.quantile(v, q)
# Ensure strictly increasing (np.interp requires increasing; ties can occur with discrete/flat regions)
diffs = np.diff(v_q)
min_diff = np.min(diffs[diffs > 0]) if np.any(diffs > 0) else 1e-10
for i in range(1, len(v_q)):
if v_q[i] <= v_q[i-1]:
v_q[i] = v_q[i-1] + min_diff * 0.1
return v_q
def transform_perlin(perlin_map, source_quantiles, target_quantiles):
if len(source_quantiles) != len(target_quantiles):
raise ValueError("Source and target quantiles must have the same length")
return np.interp(perlin_map, source_quantiles, target_quantiles, left=target_quantiles[0], right=target_quantiles[-1])