Incertitudes et unités
Périmètre
Utilisez cette compétence dès qu'un calcul porte des unités physiques ou qu'un nombre doit être accompagné d'une incertitude. Concrètement :
- la conversion entre unités, y compris les conversions nécessitant un contexte physique (longueur d'onde en énergie de photon, masse en quantité de matière, énergie en température) ;
- la propagation de l'incertitude à travers un modèle de mesure, avec ou sans entrées corrélées ;
- la construction d'un budget d'incertitude GUM à partir de certificats d'étalonnage, de spécifications et de données de répétabilité ;
- le choix d'un facteur d'élargissement et la décision de savoir si
k = 2est défendable ; - l'arrondi et l'écriture d'un résultat pour que le lecteur comprenne ce que signifie le
±; - l'extraction des incertitudes de paramètres d'un ajustement de courbe sans perdre les corrélations ;
- la relecture de code d'analyse existant pour les défauts silencieux d'unités et d'incertitudes ;
- la vérification qu'une réponse dimensionnellement cohérente est également physiquement possible — l'ordre de grandeur, le groupe sans dimension et le régime qu'il implique.
Cette compétence couvre la métrologie et les deux bibliothèques qui la mettent en œuvre. Elle ne couvre pas l'inférence statistique, la sélection de modèles ou la conception d'études — voir statistical-analysis, statistical-power et experimental-design.
Version actuelle et installation
Vérifié le 26 juillet 2026 :
- pint 0.25.3, publié le 19 mars 2026 ; nécessite Python 3.11+.
- uncertainties 3.2.3, publié le 21 avril 2025 ; nécessite Python 3.8+.
- NumPy 2.5.1 et SciPy 1.18.0 ; nécessitent Python 3.12+.
scipy.constantsdans SciPy 1.18.0 contient CODATA 2022. SciPy 1.11 et antérieur contenait CODATA 2018, et plusieurs valeurs recommandées diffèrent entre les deux.
uv venv --python 3.13
source .venv/bin/activate
uv pip install "pint==0.25.3" "uncertainties==3.2.3" "numpy==2.5.1" "scipy==1.18.0"
pint-pandas et pint-xarray ajoutent des colonnes et tableaux sensibles aux unités et s'installent séparément.
Flux de travail non négociable
- Attachez les unités à l'entrée et ne les enlevez qu'à la sortie. Convertissez aux limites des fonctions avec
ureg.wrapsoum_as("unité"), jamais en milieu de calcul. - Écrivez le modèle de mesure explicitement avant de calculer quoi que ce soit, y compris les corrections dont la valeur estimée est nulle. Une correction omise du modèle laisse son incertitude hors du budget.
- Donnez à chaque entrée quatre choses : une estimation, une incertitude-type, la distribution dont provient l'incertitude, et ses degrés de liberté.
- Convertissez les déclarations de type B avec le bon diviseur. L'incertitude élargie d'un certificat se divise par son
kindiqué ; les limites rectangulaires se divisent parsqrt(3). - Identifiez les corrélations avant de combiner. Les entrées étalonnées contre le même étalon, mesurées sur le même instrument ou issues du même ajustement sont corrélées.
- Calculez les coefficients de sensibilité, et lisez le budget à partir de
c_i * u(x_i)plutôt que des incertitudes brutes. - Vérifiez la linéarisation. Exécutez Monte Carlo en parallèle du cadre GUM et appliquez le test de comparaison de la clause 8 du JCGM 101. Rapportez le résultat de Monte Carlo lorsqu'il échoue.
- Choisissez
kà partir des degrés de liberté effectifs, pas par habitude. - Arrondissez d'abord l'incertitude, puis la valeur à la même décimale.
- Indiquez ce qu'est le
±— standard ou élargi, aveck, la probabilité de couverture, et la méthode. - Vérifiez l'ordre de grandeur avant de rapporter. Un résultat dimensionnellement cohérent peut encore être impossible. Comparez-le à une échelle connue ou à un groupe sans dimension, et confirmez que chaque hypothèse sur laquelle vous vous êtes appuyé tient toujours dans ce régime.
Les échecs que cette compétence existe pour prévenir
Chacun des exemples suivants s'exécute sans erreur et produit un nombre plausible.
Une unité dépouillée à une échelle inconnue
length = (12.7 * ureg.mm).magnitude # 12.7 -- de quoi ?
length = (12.7 * ureg.mm).m_as("m") # 0,0127 mètres, explicite
.magnitude retourne quelle que soit la valeur portée par la quantité. Nommez l'unité au point d'extraction, à chaque fois.
Calcul arithmétique de température en degrés décalés
Q(20, "degC") + Q(5, "degC") # OffsetUnitCalculusError -- correctement refusé
Q(20, "degC") + Q(5, "delta_degC") # 25 degrés Celsius
Q(25, "degC") - Q(20, "degC") # 5 delta_degC
Le degré Celsius et le degré Fahrenheit sont des échelles d'intervalles. Une incertitude sur une température est toujours une différence et appartient à une unité delta_ : convertir 20 ± 0,5 °C en Fahrenheit donne 68 °F ± 0,9 delta_°F, deux conversions différentes sur une même ligne.
Unités logarithmiques qui s'ajoutent en multipliant
Q(10, "dBm") + Q(10, "dBm") # 0,0001 kilogramme**2 * mètre**4 / seconde**6
C'est 10 mW × 10 mW, pas 20 mW ni 13 dBm. Rien ne lève d'erreur. Convertissez en unité linéaire avant toute arithmétique.
Une corrélation détruite par un aller-retour
x = ufloat(1.0, 0.1)
x - x # 0.0+/-0
x - ufloat(x.nominal_value, x.std_dev) # 0.00+/-0.14
Reconstruire une variable à partir de sa valeur nominale et de son écart-type crée une variable indépendante. Il en va de même pour toute sérialisation qui passe par une paire de flottants. Utilisez correlated_values(values, covariance_matrix) pour reconstruire un ensemble corrélé.
Une matrice de covariance redimensionnée silencieusement
popt, pcov = curve_fit(f, x, y, sigma=sigma) # défaut
popt, pcov = curve_fit(f, x, y, sigma=sigma, absolute_sigma=True)
Par défaut, pcov est redimensionné par le chi-carré réduit, de sorte que les incertitudes des paramètres absorbent la qualité de l'ajustement et correspondent à ce que vous obtiendriez en ne passant aucun sigma. Sur un ajustement linéaire synthétique, les deux donnent [0.0364, 0.2154] et [0.0477, 0.2820] — une différence de 31 %. Passez absolute_sigma=True dès que sigma contient des incertitudes-types réelles.
Une linéarisation jamais vérifiée
Pour y = x² avec x = 1.0 ± 0.5, le cadre GUM donne y = 1,0, u_c = 1,0 et un intervalle à 95 % de [-0.96, 2.96] — principalement négatif, pour une quantité au carré. Monte Carlo donne une moyenne de 1,25, u_c = 1,06 et un intervalle à 95 % le plus court de [0, 3.32]. Rien dans une bibliothèque de propagation linéaire ne vous dira que cela s'est produit.
CLI locales incluses
Tous les assistants s'exécutent hors ligne, rejettent les URL et les liens symboliques, bornent leurs entrées, écrivent la sortie de manière atomique avec des permissions privées, et refusent d'écraser sans --force.
python skills/uncertainty-and-units/scripts/propagate_uncertainty.py --help
python skills/uncertainty-and-units/scripts/uncertainty_budget.py --help
python skills/uncertainty-and-units/scripts/format_result.py --help
python skills/uncertainty-and-units/scripts/convert_units.py --help
python skills/uncertainty-and-units/scripts/audit_units.py --help
python skills/uncertainty-and-units/scripts/check_plausibility.py --help
propagate_uncertainty.py
Exécute les deux méthodes de propagation sur le même modèle et applique le test de validation de la clause 8 du JCGM 101.
python skills/uncertainty-and-units/scripts/propagate_uncertainty.py \
--expression "m / (pi * (d / 2) ** 2 * h)" \
--variable "m=250.0,0.05" \
--variable "d=20.0,0.02,rectangulaire" \
--variable "h=40.0,0.05,rectangulaire" \
--measurand density --unit "g/cm3" --format markdown
Chaque --variable est nom=valeur,incertitude_type[,distribution[,ddl]], où la distribution est normale, rectangulaire, triangulaire, arcsinus ou exacte et contrôle uniquement l'échantillonnage de Monte Carlo. Les corrélations sont entrées comme --correlation "a,b=0.9". Un fichier JSON --spec contient le même modèle pour tout ce qui est durable.
L'expression est analysée en un arbre syntaxique abstrait et réduite par une traversée explicite sur + - * / ** et une liste fixe de fonctions. Elle n'est jamais compilée ni exécutée.
Le rapport donne l'estimation, u_c, les coefficients de sensibilité, le budget en pourcentage, les degrés de liberté effectifs, k, U, les deux intervalles de couverture de Monte Carlo, et le verdict sur la possibilité de rapporter le résultat linéarisé.
uncertainty_budget.py
Combine les composants tels qu'ils sont fournis par les certificats et fiches techniques.
python skills/uncertainty-and-units/scripts/uncertainty_budget.py --template > budget.json
python skills/uncertainty-and-units/scripts/uncertainty_budget.py --spec budget.json --format markdown
Chaque composant nomme une distribution qui fixe son diviseur — elargie divise par son facteur_couverture, rectangulaire par sqrt(3), triangulaire par sqrt(6), arcsinus par sqrt(2), normale par 1 — avec une sensibilite, ddl et relative: true optionnels. L'outil calcule u_c, les degrés de liberté effectifs de Welch-Satterthwaite, k à partir de la distribution de Student, et U, et avertit lorsqu'un composant de type A n'a pas de degrés de liberté, lorsque nu_eff est suffisamment petit pour que k = 2 soit erroné, lorsqu'un composant domine, et lorsqu'un composant de type B déclaré normale est probablement une incertitude élargie non divisée.
format_result.py
python skills/uncertainty-and-units/scripts/format_result.py \
--value 12.34567 --uncertainty 0.02345 --unit mm \
--coverage-factor 2.26 --coverage-probability 0.95
Retourne 12,346 ± 0,023 mm, 12,346(23) mm, les formes scientifique et LaTeX, et la phrase qui doit accompagner le nombre. Avertit lorsqu'un seul chiffre significatif est demandé pour une incertitude commençant par 1 ou 2, et lorsque l'incertitude dépasse l'estimation.
convert_units.py
python skills/uncertainty-and-units/scripts/convert_units.py \
--value 532 --unit nm --to eV --context spectroscopie --uncertainty 0.5
python skills/uncertainty-and-units/scripts/convert_units.py \
--value 1.0 --unit g --to mol --context chimie --context-parameter "mw=180.156 g/mol"
Transmet l'incertitude à travers la dérivée locale de la conversion, ce qui est important car les conversions contextuelles sont réciproques plutôt que proportionnelles. Nomme le contexte dans le message d'erreur lorsqu'une conversion en nécessite un, et signale les unités décalées et logarithmiques. --list-contexts montre ce que le registre définit.
audit_units.py
Revue statique de code d'analyse existant. Analyse, n'importe ni n'exécute jamais.
python skills/uncertainty-and-units/scripts/audit_units.py \
--input analyse.py --format markdown --fail-on moyen
| Règle | Sévérité | Détecte |
|---|---|---|
UNIT001 | moyen | un second UnitRegistry dans un même module — ValueError inter-registre |
UNIT002 | moyen | des unités de température décalées sans unité delta_ nulle part |
UNIT003 | élevé | .magnitude sans .to(...) ou .m_as(...) précédent |
UNIT004 | moyen | des unités logarithmiques, dont le + multiplie |
UNC001 | élevé | curve_fit sans absolute_sigma |
UNC002 | moyen | np.std / np.var sans ddof |
UNC003 | moyen | des fonctions math ou numpy dans un module qui utilise uncertainties |
UNC004 | élevé | un ufloat reconstruit à partir de .nominal_value et .std_dev |
CONST001 | faible | une littérale à moins de 0.1 % d'une constante CODATA |
Le code de sortie est 1 lorsqu'une constatation atteint --fail-on (par défaut élevé), ce qui le rend utilisable comme vérification pre-commit ou CI.
Les règles sont heuristiques, donc un faux positif est supprimé par un commentaire de directive — en fin de ligne pour couvrir sa propre ligne, ou seul sur une ligne pour couvrir la suivante :
value = quantity.magnitude # audit-units: ignore UNIT003 -- déjà converti en amont
# audit-units: ignore UNC003 -- l'argument ici est un simple tableau de flottants
scaled = np.log10(counts)
# audit-units: ignore-file CONST001 couvre tout un module, et ne nommer aucune règle les supprime toutes. Les suppressions sont comptées dans le rapport plutôt que cachées, donc un fichier qui réduit tout au silence l'indique toujours.
check_plausibility.py
La cohérence dimensionnelle n'est pas la possibilité physique. Une cellule de 2 m de diamètre et un nombre de Reynolds de 4e7 dans un capillaire passent toutes les vérifications d'unités. Cet outil teste un ensemble de quantités par rapport à des groupes sans dimension, des échelles caractéristiques et des bandes de grandeurs organisées, et vérifie la dimensionalité de chaque formule avant de rapporter un nombre.
python skills/uncertainty-and-units/scripts/check_plausibility.py \
--quantity "density=1060 kg/m**3" --quantity "velocity=0.5 mm/s" \
--quantity "length=8 um" --quantity "viscosity=3.5 mPa*s" \
--group reynolds --format markdown
# Re = 0.001211 -- laminaire (tuyau circulaire, longueur = diamètre)
python skills/uncertainty-and-units/scripts/check_plausibility.py \
--quantity "diameter=2 m" --band "eukaryotic_cell_diameter=diameter"
# invraisemblable : 4,3 décades en dehors de la plage 5-100 µm
--group évalue l'un des 14 groupes sans dimension et nomme le régime dans lequel il place le système ; --scale calcule une échelle caractéristique telle qu'un temps de diffusion, une longueur de Debye ou une vitesse de sédimentation de Stokes ; --band compare une quantité fournie à une plage observée. --list imprime tout le catalogue avec les entrées dont chaque formule a besoin.
Les constantes physiques (k_B, N_A, R_gaz, g_terre, etc.) sont disponibles pour chaque formule sans être fournies, et sont lues depuis scipy.constants à l'exécution plutôt qu'écrites comme des littérales, de sorte qu'elles suivent la version CODATA livrée par SciPy.
La vérification dimensionnelle est le point essentiel. Passer une viscosité cinématique là où la formule nécessite une viscosité dynamique — toutes deux appelées "viscosité", toutes deux tabulées pour l'eau, différant d'un facteur ρ — est refusé avant qu'un nombre ne soit calculé :
erreur : la viscosité doit avoir la dimensionnalité [masse] / ([longueur] * [temps]),
mais m²/s est [longueur] ** 2 / [temps]
Le code de sortie est 1 lorsque le verdict atteint --fail-on (par défaut invraisemblable ; une valeur à moins d'une décade d'une bande est douteuse). Les seuils sont des conventions aux bords flous et supposent la géométrie pour laquelle leur corrélation a été ajustée — voir references/plausibility-scales.md pour la longueur caractéristique à utiliser dans chaque cas.
Choisir une méthode de propagation
| Situation | Méthode |
|---|---|
| Modèle linéaire ou quasi-linéaire, entrées à peu près normales, grands ddl | Cadre GUM seul |
| Toute non-linéarité sur ± 2u d'une entrée | Exécutez les deux, appliquez le test de la clause 8 |
| Incertitude relative supérieure à ~20 % sur une entrée | Exécutez les deux, appliquez le test de la clause 8 |
| Distribution fortement non normale (par exemple, rectangulaire avec plage asymétrique) | Monte Carlo comme méthode principale |
| Petits ddl sur des entrées dominantes | Exécutez les deux : le cadre GUM gère la correction Welch-Satterthwaite, mais Monte Carlo peut révéler des effets de queue |
| Modèle complexe avec transformations non monotones, ou un paramètre avec un support borné | Monte Carlo |
| Besoin d'un intervalle de couverture court à 95 % pour une distribution asymétrique | Monte Carlo, intervalle le plus court (HPD) |
| Besoin de produire des dérivées formelles (par exemple, pour une liste de contribution au budget) | Cadre GUM |
Le cadre GUM linéarise autour de l'estimation et suppose une distribution de Student pour le résultat. Monte Carlo échantillonne à partir des distributions d'entrée et n'a pas d'hypothèses paramétriques sur la sortie. Les deux sont disponibles dans propage_incertitude.py, qui applique le test de validation de la clause 8 du JCGM 101 — un échec signifie que le résultat linéarisé ne peut pas être rapporté sans réserve.
Budgétisation d'incertitude GUM
Le GUM distingue les évaluations de type A (répétabilité, statistiques) et de type B (certificats, spécifications, suppositions). Les composantes de type A obtiennent leurs degrés de liberté du nombre d'observations ; les composantes de type B sont estimées — elles reçoivent des degrés de liberté "arbitraires" (couramment 1000 pour une composante de type B ordinaire, moins pour une supposition plus lâche). Le budget d'incertitude final combine ces composantes via la propagation de la loi de l'incertitude, puis applique la formule de Welch-Satterthwaite pour les degrés de liberté effectifs et la distribution de Student pour le facteur d'élargissement.
Pourquoi k = 2 peut être faux
Un facteur d'élargissement de 2 suppose que les degrés de liberté effectifs sont suffisamment grands (≥ 30) pour que la distribution de Student approche la normale. Lorsque les degrés de liberté sont petits, le véritable facteur est plus grand : avec 5 ddl, t_95 = 2,57 ; avec 3 ddl, t_95 = 3,18. Le script budget_incertitude.py calcule la vraie valeur et avertit si k = 2 est défendu mais nu_eff < 30.
Pourquoi la linéarisation échoue
Pour y = x² avec x = 1,0 ± 0,5, l'approximation linéaire du premier ordre donne u_c ≈ |dy/dx| * u(x) = 2*1*0.5 = 1,0. En réalité, la distribution de y est asymétrique et son écart-type est plus proche de 1,06. Le cadre GUM linéarisé produit un intervalle de confiance à 95 % qui s'étend dans des valeurs négatives — impossible pour une quantité au carré. Monte Carlo corrige cela, mais seulement si vous exécutez les deux et comparez.
Ce que la compétence ne fait pas
- Inférence statistique : intervalles de confiance pour les paramètres du modèle, tests d'hypothèses, sélection de modèles — voir
statistical-analysis. - Plans d'expérience : randomisation, blocage, calcul de taille d'échantillon (voir
experimental-design). - Analyse des séries chronologiques : traitement du signal, filtrage, corrélation temporelle (voir
time-series-analysis,kalman-filters). - Apprentissage automatique : propagation de l'incertitude pour les réseaux de neurones, l'inférence bayésienne.
Références
- JCGM 100:2008, "Évaluation des données de mesure — Guide pour l'expression de l'incertitude de mesure" (le GUM).
- JCGM 101:2008, "Évaluation des données de mesure — Supplément 1 du Guide pour l'expression de l'incertitude de mesure — Propagation de distributions par une méthode de Monte Carlo."
- JCGM 104:2009, "Évaluation des données de mesure — Introduction au Guide pour l'expression de l'incertitude de mesure" et aux Suppléments.
- NIST TN 1900 (2015), "Méthodes de Monte Carlo pour l'incertitude de mesure."
- Documentation de Pint : https://pint.readthedocs.io
- Documentation d'Uncertainties : https://uncertainties-python-package.readthedocs.io