feat(cpp/datascience): CPU stats + MCMC primitives
Nuevo dominio cpp/functions/datascience con primitivas puras CPU para post- proceso de samples Monte Carlo y diagnostico de cadenas MCMC. Diseñadas como gemelas CPU de los kernels GPU (rng pareja con gpu_rng_glsl, MH 1D/ND con mc_metropolis_hastings_gpu) para validar numericamente y para datasets pequeños donde el dispatch GPU no compensa. - rng: xoshiro256++ con uniform / normal (Box-Muller) / below (Lemire) / categorical. Determinista bit-exacto dado seed. - stats_summary: sum (Kahan), mean, var/std (Welford one-pass), min, max, quantile / percentile (R type-7). - autocorr: r(k), ACF, tau_int (Sokal) — diagnostico ACF y ESS. - rhat_ess: Gelman-Rubin clasico y split + ESS basico (multi-chain). - beta_dist: lgamma (Lanczos), beta_pdf, beta_cdf (continued fraction), beta_quantile, mean/var/std — para inferencia Beta-Binomial. - drawdown: max_dd absoluto/pct + underwater series para sesiones simuladas y backtests. - samples_to_grid_2d: binning 2D CPU para alimentar heatmap_cpp_viz / contour_cpp_viz desde samples (x[], y[]). - metropolis_hastings: MH 1D y ND con target log-pdf como std::function (no normalizada). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
---
|
||||
name: samples_to_grid_2d
|
||||
kind: function
|
||||
lang: cpp
|
||||
domain: datascience
|
||||
version: "1.0.0"
|
||||
purity: pure
|
||||
signature: "void samples_to_grid_2d_counts(const double* x, const double* y, size_t n, double xmin, double xmax, double ymin, double ymax, int nx, int ny, unsigned int* out_counts); void samples_to_grid_2d_density(...float* out_density); void counts_to_density(const unsigned int* counts, int nx, int ny, float* out_density)"
|
||||
description: "Binning 2D CPU para alimentar heatmap_cpp_viz / contour_cpp_viz / surface_plot_3d desde un set de samples (x[], y[]). Variante counts (uint, acumulable) y density (float [0,1] normalizado a max). Pareja CPU del gpu_histogram_2d."
|
||||
tags: [binning, histogram_2d, density, heatmap, contour, datascience]
|
||||
uses_functions: []
|
||||
uses_types: []
|
||||
returns: []
|
||||
returns_optional: false
|
||||
error_type: ""
|
||||
imports: [cstddef, cmath, vector]
|
||||
tested: false
|
||||
tests: []
|
||||
test_file_path: ""
|
||||
file_path: "cpp/functions/datascience/samples_to_grid_2d.cpp"
|
||||
params:
|
||||
- name: samples_x
|
||||
desc: "Array de coordenadas X de los samples."
|
||||
- name: samples_y
|
||||
desc: "Array de coordenadas Y de los samples."
|
||||
- name: n
|
||||
desc: "Numero de samples (longitud de samples_x y samples_y)."
|
||||
- name: xmin
|
||||
desc: "Limite inferior X. Samples con x fuera de [xmin, xmax) se descartan."
|
||||
- name: xmax
|
||||
desc: "Limite superior X."
|
||||
- name: ymin
|
||||
desc: "Limite inferior Y."
|
||||
- name: ymax
|
||||
desc: "Limite superior Y."
|
||||
- name: nx
|
||||
desc: "Bins en X."
|
||||
- name: ny
|
||||
desc: "Bins en Y."
|
||||
- name: out_counts
|
||||
desc: "Buffer destino unsigned int[nx*ny] row-major (idx = y*nx + x). NO se inicializa: el caller decide si poner a cero (acumular sobre llamadas previas)."
|
||||
- name: out_density
|
||||
desc: "Buffer destino float[nx*ny] normalizado a max=1.0. Variante density auto-rellena."
|
||||
- name: counts
|
||||
desc: "(counts_to_density) input uint[nx*ny]."
|
||||
output: "out_counts incrementado con los conteos; out_density normalizado [0, 1]. Si todos los counts son 0, density se llena con 0."
|
||||
---
|
||||
|
||||
# samples_to_grid_2d
|
||||
|
||||
Binning 2D para densidades de muestras (joint posteriors, walks 2D, scatter density). Versión CPU canónica — usar GPU `gpu_histogram_2d` cuando los samples ya viven en GPU.
|
||||
|
||||
## Patron tipico (mcmc-visualizer / mcmc-full)
|
||||
|
||||
```cpp
|
||||
constexpr int NX = 128, NY = 128;
|
||||
std::vector<float> density(NX * NY);
|
||||
|
||||
fn::ds::samples_to_grid_2d_density(
|
||||
chain_x.data(), chain_y.data(), chain_x.size(),
|
||||
-5.0, 5.0, -5.0, 5.0,
|
||||
NX, NY,
|
||||
density.data()
|
||||
);
|
||||
|
||||
fn::viz::heatmap(density.data(), NX, NY, /*...*/);
|
||||
```
|
||||
|
||||
## Acumulado a lo largo de iteraciones
|
||||
|
||||
Para visualizar la cadena creciendo en vivo sin recomputar todo:
|
||||
|
||||
```cpp
|
||||
std::vector<unsigned int> counts(NX * NY, 0u);
|
||||
|
||||
// Cada iteracion del MCMC:
|
||||
fn::ds::samples_to_grid_2d_counts(
|
||||
new_x.data(), new_y.data(), new_x.size(),
|
||||
-5.0, 5.0, -5.0, 5.0,
|
||||
NX, NY,
|
||||
counts.data() // sigue acumulando
|
||||
);
|
||||
|
||||
std::vector<float> density(NX * NY);
|
||||
fn::ds::counts_to_density(counts.data(), NX, NY, density.data());
|
||||
fn::viz::heatmap(density.data(), NX, NY, /*...*/);
|
||||
```
|
||||
|
||||
## Notas
|
||||
|
||||
- Samples fuera del rango `[xmin, xmax) x [ymin, ymax)` se descartan, no se clampean. Si quieres clamp, pre-clamp los samples antes de llamar.
|
||||
- O(n) sobre samples + O(nx*ny) para to_density. Para n = 10^7, nx=ny=256: ~70 ms CPU. Para refresh interactivo a 60 FPS, downsample a n=10^5 o usar la version GPU.
|
||||
- Layout row-major idx = y*nx + x — coincide con lo que esperan `heatmap_cpp_viz` y `contour_cpp_viz`.
|
||||
Reference in New Issue
Block a user