Spaces:
Running on Zero
Running on Zero
| 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]) |