<!-- canonical: https://jmrplens.github.io/phonometry/es/guides/gum-uncertainty/ -->
Source: https://jmrplens.github.io/phonometry/es/guides/gum-uncertainty/

Todo resultado de medida está incompleto sin una declaración de su
incertidumbre. La *Guía para la expresión de la incertidumbre de medida* ofrece
dos formas de propagar las incertidumbres de las entradas de un modelo de
medida $y = f(x_1, \dots, x_N)$ hacia la salida: la **ley de propagación de la
incertidumbre** (**ISO/IEC Guía 98-3:2008**, la GUM, cláusula 5) y el **método
de Monte Carlo** (**ISO/IEC Guía 98-3-1:2008**, Suplemento 1, cláusula 7). La
primera combina las incertidumbres típicas analíticamente a través de los
coeficientes de sensibilidad; el segundo propaga numéricamente las
distribuciones de probabilidad completas. Coinciden para modelos lineales y
divergen, de forma reveladora, cuando el modelo es no lineal o las entradas se
alejan de la gaussiana.

## 1. La ley de propagación de la incertidumbre (GUM, cláusula 5)

Para un modelo $y = f(x_1, \dots, x_N)$ con entradas no correlacionadas, la
incertidumbre típica combinada es la suma en cuadratura de las contribuciones de
las entradas $u_i(y) = |c_i|\,u(x_i)$ ponderadas por los coeficientes de
sensibilidad $c_i = \partial f / \partial x_i$:

$$
u_c^2(y) = \sum_{i=1}^{N} \left(\frac{\partial f}{\partial x_i}\right)^2 u^2(x_i).
$$

`combine_uncertainty` evalúa las sensibilidades por diferencias centradas, de
modo que funciona cualquier modelo invocable, sin derivadas parciales a mano.
Las magnitudes de entrada se describen con una `Quantity` (mejor estimación,
incertidumbre típica, PDF, grados de libertad). Las evaluaciones de Tipo B a
partir de una semianchura $a$ se construyen con `rectangular` ($a/\sqrt{3}$),
`triangular` ($a/\sqrt{6}$) y `u_shaped` ($a/\sqrt{2}$) (GUM, cláusula 4.3).

```python
from phonometry import metrology

# Nivel ponderado A: una lectura más correcciones de calibración, de
# instrumento y de posición de media cero. El modelo es su suma.
quantities = [
    metrology.Quantity(74.0, 0.0, name="Reading"),
    metrology.rectangular(0.0, 0.20, name="Calibration"),
    metrology.rectangular(0.0, 0.30, name="Instrument"),
    metrology.Quantity(0.0, 0.35, dof=9, name="Position (Type A)"),
]
result = metrology.combine_uncertainty(lambda a, b, c, d: a + b + c + d, quantities)

print(round(result.value, 2))                 # 74.0
print(round(result.combined_uncertainty, 3))  # 0.407 dB
print(result.contributions.round(3))          # [0.    0.115 0.173 0.35 ]
print(round(result.effective_dof, 1))         # 16.5

k, U = result.expanded(0.95)
print(round(k, 2), round(U, 2))               # 2.11 0.86  ->  Y = 74.0 ± 0.9 dB
```

La **incertidumbre expandida** $U = k\,u_c$ escala la incertidumbre combinada
por un factor de cobertura $k = t_p(\nu_\text{ef})$ de la distribución $t$ con
los **grados de libertad efectivos** dados por la fórmula de Welch–Satterthwaite
(Anexo G.4). Aquí la única entrada de Tipo A (9 grados de libertad) hace bajar
$\nu_\text{ef}$ hasta unos 16, de modo que $k = 2{,}11$ en lugar del 1,96 de
gran muestra. Las entradas correlacionadas se tratan pasando una matriz de
correlación; una suma totalmente correlacionada se suma entonces linealmente en
vez de en cuadratura. La correlación es el error silencioso clásico de un
balance: dos correcciones trazables al *mismo* calibrador, o dos canales que
comparten un instrumento, no se promedian como lo harían términos
independientes, y combinarlas en cuadratura como si no estuvieran
correlacionadas suele subestimar $u_c$ (con sensibilidades de signo opuesto el
sesgo puede apuntar al revés). Como la GUM define Welch–Satterthwaite solo
para entradas *independientes*, un presupuesto correlacionado con grados de
libertad finitos en sus entradas no tiene grados de libertad efectivos en
absoluto: `effective_dof` es NaN, se emite un aviso y `expanded()` exige un
`coverage_factor_override` explícito (p. ej. $k = 2$) en lugar de inventarse
uno. Solo cuando todas las entradas son de Tipo B con grados de libertad
infinitos un presupuesto correlacionado conserva $\nu_\text{ef} = \infty$ y
usa el factor de cobertura de la distribución normal. Esta cadena reproduce de
principio a fin los ejemplos resueltos de la propia GUM: el presupuesto del
calibre del anexo H.1 ($u_c = 31{,}7$ nm, $U_{99} = 92$ nm frente a los 32/93
impresos) y la medida correlacionada de resistencia del anexo H.2
($u_c(R) = 0{,}071\ \Omega$, $u_c(X) = 0{,}295\ \Omega$,
$u_c(Z) = 0{,}236\ \Omega$ de la Tabla H.3).

## 2. El método de Monte Carlo (Suplemento 1)

Cuando el modelo es no lineal o las entradas son marcadamente no gaussianas, la
hipótesis gaussiana de la GUM para la salida puede ser inexacta. `monte_carlo`
en cambio muestrea cada entrada de su PDF, evalúa el modelo sobre todos los
ensayos y reporta la media, la desviación típica y el **intervalo de cobertura
simétrico en probabilidad** (igual probabilidad en cada cola, cláusula 7.7).
Las entradas se muestrean de forma independiente; la vía gaussiana
multivariante del Suplemento para magnitudes no independientes (6.4.8) no está
implementada, así que los presupuestos correlacionados corresponden a
`combine_uncertainty`. El número de ensayos es fijo (sin el procedimiento
adaptativo de 7.9, mínimo 2 ensayos) y el intervalo es el simétrico, no el
intervalo más corto de 5.3.4.

```python
from phonometry import metrology

quantities = [
    metrology.Quantity(74.0, 0.0, name="Reading"),
    metrology.rectangular(0.0, 0.20, name="Calibration"),
    metrology.rectangular(0.0, 0.30, name="Instrument"),
    metrology.Quantity(0.0, 0.35, dof=9, name="Position (Type A)"),
]
mc = metrology.monte_carlo(lambda a, b, c, d: a + b + c + d, quantities,
                    trials=1_000_000, coverage=0.95, seed=1)

print(round(mc.value, 2))                 # 74.0
print(round(mc.standard_uncertainty, 3))  # 0.407 dB  (coincide con la uc de arriba)
print([round(x, 2) for x in mc.interval]) # [73.2, 74.8]
```

Para este modelo casi lineal la incertidumbre típica de Monte Carlo reproduce el
$u_c$ de la GUM con tres cifras y el intervalo al 95 % coincide con $Y \pm U$.
Ambos métodos se validan frente a los ejemplos resueltos de las propias Guías: el
modelo aditivo de cuatro entradas unidad da $u_c = 2{,}0$ (Suplemento 1,
cláusula 9.2), y cuatro entradas rectangulares dan un intervalo de Monte Carlo de
$[-3{,}88,\, 3{,}88]$ (Suplemento 1, cláusula 9.2.3).

¿Cuándo compensa el coste extra del método de Monte Carlo? Siempre que falle
alguna de las dos simplificaciones de la GUM: el modelo se sustituye por su
desarrollo de primer orden, y la distribución de salida por una gaussiana (o
una $t$). Ambas se cumplen bien en el modelo aditivo de niveles de arriba, y
por eso los dos métodos coinciden con tres cifras. Dejan de cumplirse cuando
el modelo es fuertemente no lineal en el rango de las incertidumbres de
entrada (conversiones energía-nivel con entradas anchas, productos y
cocientes con incertidumbres relativas grandes), cuando una sola entrada no
gaussiana domina el balance (un término rectangular grande hace la salida
casi rectangular, y un intervalo gaussiano $\pm\,2u_c$ la sobrecubre), o
cuando la salida queda cerca de un límite físico (un coeficiente de absorción
cerca de 0 o 1, una corrección de nivel que no puede cruzar el cero), donde
el intervalo de cobertura verdadero es asimétrico y ninguna afirmación
$Y \pm U$ puede representarlo. En esos regímenes el intervalo de Monte Carlo
es la referencia: el propio Suplemento 1 (cláusula 8) considera el marco de
la GUM validado precisamente cuando coincide con el resultado de Monte Carlo,
y superado por este cuando no coincide.

<details>
<summary>Mostrar el código de esta figura</summary>

```python

from phonometry import metrology

quantities = [
    metrology.Quantity(74.0, 0.0, name="Reading"),
    metrology.rectangular(0.0, 0.20, name="Calibration"),
    metrology.rectangular(0.0, 0.30, name="Instrument"),
    metrology.Quantity(0.0, 0.35, dof=9, name="Position (Type A)"),
]
model = lambda a, b, c, d: a + b + c + d
result = metrology.combine_uncertainty(model, quantities)
mc = metrology.monte_carlo(model, quantities, trials=1_000_000, coverage=0.95, seed=1,
                    keep_samples=True)
k, U = result.expanded(0.95)

# En una línea por panel — las barras del balance, y el histograma de Monte
# Carlo con su intervalo (la figura del repositorio superpone además la
# gaussiana del GUM):
result.plot(language="es")
mc.plot(language="es")
plt.show()

# A mano, ambos paneles — las barras del balance y la distribución de salida de Monte Carlo:
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12.5, 5.4))
ax1.barh(result.names, result.contributions)
ax1.axvline(result.combined_uncertainty, ls="--",
            label=f"$u_c$ = {result.combined_uncertainty:.3f} dB")
ax1.invert_yaxis(); ax1.legend()

rng = np.random.default_rng(1)
samples = model(np.full(200_000, 74.0),
                rng.uniform(-0.20, 0.20, 200_000),
                rng.uniform(-0.30, 0.30, 200_000),
                rng.normal(0.0, 0.35, 200_000))
ax2.hist(samples, bins=120, density=True, alpha=0.35, label="Monte Carlo")
ax2.axvspan(*mc.interval, alpha=0.12, label="95 % coverage interval")
ax2.set_title(f"Y = {result.value:.2f} dB,  U = {U:.2f} dB (k = {k:.2f})")
ax2.legend()
plt.show()
```

</details>

El `UncertaintyResult` lleva el `value`, la `combined_uncertainty`, las
`sensitivities`, las `contributions` por entrada y los `effective_dof`; su
`.plot()` dibuja el balance y `.expanded(coverage)` devuelve el par $(k, U)$. El
`MonteCarloResult` lleva el `value`, la `standard_uncertainty`, el `interval` de
cobertura y su `coverage`; con `keep_samples=True` conserva además las
muestras de salida (`samples`), y su `.plot()` dibuja el histograma de salida
con el intervalo de cobertura marcado (el panel derecho de arriba). La incertidumbre de acústica de la edificación de
ISO 12999-1, que combina términos de reproducibilidad para una magnitud de
número único, es un balance aparte, específico de ese dominio.

Un presupuesto es tan honesto como el registro que hay detrás: toda entrada
promediada supone estacionariedad, y
[Calificación de datos](/phonometry/es/guides/data-qualification/) trae los
tests de Bendat y Piersol que lo comprueban antes de empezar la propagación.

## Dónde consume la librería esta maquinaria

Las páginas de dominio llevan sus propias cláusulas de incertidumbre
prescritas por norma, y cada una es una instancia de la suma de la
cláusula 5 que esta página implementa en forma general; usa esta página
siempre que tu modelo de medición no sea uno de esos casos normalizados:

- **Calibración.** La tolerancia de clase del calibrador y la cota de
  deriva pre/post de [Calibración](/phonometry/es/guides/calibration/) son
  entradas de tipo B de libro: propágalas
  (`Quantity(..., "rectangular")`) a través del modelo del nivel en lugar
  de citar la tolerancia sola.
- **Niveles ambientales.** La incertidumbre combinada de ISO 1996-2 de la
  página de [Niveles](/phonometry/es/guides/levels/) es la Fórmula (2) de
  esa norma: la misma suma en cuadratura con los coeficientes de
  sensibilidad propios de la norma.
- **Acústica de la edificación.** Las incertidumbres por banda y de número
  único de las
  [mediciones de aislamiento in situ](/phonometry/es/guides/insulation-field/)
  aplican los términos de reproducibilidad tabulados de ISO 12999-1, un
  balance normalizado para un modelo concreto.
- **Absorción.** La [página de materiales](/phonometry/es/guides/materials/)
  lleva la incertidumbre de absorción de ISO 12999-2, la misma construcción
  para el método de cámara reverberante.
- **Exposición laboral.** La incertidumbre de ISO 9612 de las
  [mediciones laborales](/phonometry/es/guides/occupational-exposure/)
  presupuesta las contribuciones de muestreo, instrumento y posición
  exactamente de esta manera.

## Véase también

- [Calificación de datos](/phonometry/es/guides/data-qualification/): las comprobaciones de estacionariedad que toda entrada promediada asume en silencio.
- [Calibración](/phonometry/es/guides/calibration/): las entradas de tolerancia y deriva de toda cadena calibrada.
- Referencia de la API: [`metrology.uncertainty`](/phonometry/es/reference/api/metrology/uncertainty/).
