1
0
forked from EHV/sejeteralo

docs : page équations mathématiques du modèle Bézier (KaTeX)

Toutes les formules du moteur de tarification : courbes paramétriques
palier 1/2, décomposition intégrale (α₁, α₂, β₂), calcul de p₀,
résolution cubique Cardano + Newton-Raphson.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Yvv
2026-04-24 20:50:56 +02:00
parent 92fb60c114
commit 65c148142c

195
docs/equations.html Normal file
View File

@@ -0,0 +1,195 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>SejeteralO — Modèle mathématique</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.css">
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.js"></script>
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/contrib/auto-render.min.js"
onload="renderMathInElement(document.body, {delimiters:[
{left:'$$',right:'$$',display:true},
{left:'$',right:'$',display:false}
]})"></script>
<style>
body { font-family: 'Georgia', serif; max-width: 860px; margin: 3rem auto; padding: 0 2rem; color: #1a1a2e; background: #fafaf8; line-height: 1.7; }
h1 { font-size: 1.6rem; border-bottom: 2px solid #3a5a8a; padding-bottom: .5rem; color: #1a2e5a; }
h2 { font-size: 1.2rem; color: #2a4a7a; margin-top: 2.5rem; border-left: 4px solid #7aacdc; padding-left: .8rem; }
h3 { font-size: 1rem; color: #3a5a8a; margin-top: 1.8rem; }
.block { background: #f0f4fb; border-radius: 10px; padding: 1.2rem 1.5rem; margin: 1rem 0; }
.cp-grid { display: grid; grid-template-columns: 1fr 1fr; gap: .3rem 2rem; font-size: .92rem; }
table { border-collapse: collapse; width: 100%; font-size: .92rem; margin: 1rem 0; }
th { background: #3a5a8a; color: #fff; padding: .4rem .8rem; text-align: left; }
td { padding: .35rem .8rem; border-bottom: 1px solid #dde; }
tr:nth-child(even) td { background: #f4f7fc; }
.note { font-size: .88rem; color: #556; font-style: italic; margin-top: .5rem; }
code { background: #e8ecf5; padding: .1rem .35rem; border-radius: 4px; font-size: .88rem; font-family: monospace; }
.sep { border: none; border-top: 1px dashed #ccd; margin: 2.5rem 0; }
</style>
</head>
<body>
<h1>SejeteralO — Modèle tarifaire Bézier</h1>
<p>Tarification participative de l'eau : les citoyens façonnent une courbe prix/volume via des points de contrôle Bézier ; le prix d'inflexion $p_0$ est calculé automatiquement pour équilibrer les recettes de la commune.</p>
<h2>1. Paramètres</h2>
<h3>Paramètres structurels (fixés par la commune)</h3>
<table>
<tr><th>Paramètre</th><th>Signification</th></tr>
<tr><td>$v_\text{inf}$</td><td>Volume d'inflexion — frontière entre les deux paliers (m³/an)</td></tr>
<tr><td>$v_\text{max}$</td><td>Volume maximum de la courbe (m³/an)</td></tr>
<tr><td>$p_\text{max}$</td><td>Prix au m³ en $v_\text{max}$ (€)</td></tr>
<tr><td>$R$</td><td>Recettes cibles totales (€/an)</td></tr>
<tr><td>$\text{abo}_P, \text{abo}_S$</td><td>Abonnements résidence principale / secondaire (€/an)</td></tr>
</table>
<h3>Paramètres de forme (votés par les citoyens, 6 valeurs dans $[0,1]$)</h3>
<table>
<tr><th>Param.</th><th>Rôle géométrique</th></tr>
<tr><td>$a$</td><td>Hauteur du 2ᵉ point de contrôle du palier 1 (courbure initiale)</td></tr>
<tr><td>$b$</td><td>Position horizontale du 3ᵉ point de contrôle du palier 1</td></tr>
<tr><td>$c$</td><td>Position horizontale du 1ᵉʳ point de contrôle du palier 2</td></tr>
<tr><td>$d$</td><td>Position horizontale du 2ᵉ point de contrôle du palier 2</td></tr>
<tr><td>$e$</td><td>Hauteur du 2ᵉ point de contrôle du palier 2</td></tr>
</table>
<h3>Variable calculée</h3>
<p>$p_0$ — prix au m³ à l'inflexion — est toujours déduit de l'équilibre de recettes (§4).</p>
<hr class="sep">
<h2>2. Courbe Bézier cubique par paliers</h2>
<p>La courbe prix/volume est définie de façon paramétrique : pour $t \in [0,1]$, on obtient un point $(v(t),\, p(t))$.</p>
<h3>Palier 1 — $v \in [0,\, v_\text{inf}]$</h3>
<div class="block">
$$v_1(t) = v_\text{inf}\,\bigl[(1-3b)\,t^3 + 3b\,t^2\bigr]$$
$$p_1(t) = p_0\,\bigl[(3a-2)\,t^3 + (3-6a)\,t^2 + 3a\,t\bigr]$$
</div>
<p>Points de contrôle :</p>
<div class="cp-grid">
<span>$P_1 = (0,\; 0)$</span>
<span>$P_2 = (0,\; a\,p_0)$</span>
<span>$P_3 = (b\,v_\text{inf},\; p_0)$</span>
<span>$P_4 = (v_\text{inf},\; p_0)$</span>
</div>
<h3>Palier 2 — $v \in [v_\text{inf},\, v_\text{max}]$</h3>
<p>Posons $w_\text{max} = v_\text{max} - v_\text{inf}$.</p>
<div class="block">
$$v_2(t) = v_\text{inf} + w_\text{max}\,\Bigl[\bigl(3(c+d-cd)-2\bigr)\,t^3 + 3(1-2c-d+cd)\,t^2 + 3c\,t\Bigr]$$
$$p_2(t) = p_0 + (p_\text{max}-p_0)\,\bigl[(1-3e)\,t^3 + 3e\,t^2\bigr]$$
</div>
<p>Points de contrôle (partagent $P_4$ avec le palier 1) :</p>
<div class="cp-grid">
<span>$P_4 = (v_\text{inf},\; p_0)$</span>
<span>$P_5 = (v_\text{inf}+c\,w_\text{max},\; p_0)$</span>
<span>$P_6 = \bigl(v_\text{inf}+w_\text{max}(1-d+cd),\; p_0+e(p_\text{max}-p_0)\bigr)$</span>
<span>$P_7 = (v_\text{max},\; p_\text{max})$</span>
</div>
<hr class="sep">
<h2>3. Facture d'un foyer</h2>
<p>La facture annuelle d'un foyer de consommation $v$ est :</p>
<div class="block">
$$\text{Bill}(v) = \text{abo} + \int_0^v p(u)\,\mathrm{d}u$$
</div>
<p>L'intégrale est calculée analytiquement par décomposition :</p>
<div class="block">
$$\int_0^v p(u)\,\mathrm{d}u = (\alpha_1 + \alpha_2)\,p_0 + \beta_2$$
</div>
<p>où les trois coefficients dépendent uniquement de la forme de la courbe (paramètres $a$$e$, $v_\text{inf}$, $v_\text{max}$, $p_\text{max}$) et de la consommation $v$, mais <em>pas</em> de $p_0$. Cela rend le calcul de $p_0$ linéaire.</p>
<h3>Résolution cubique — inversion de la courbe</h3>
<p>Pour évaluer les coefficients en un volume $v$ donné, on cherche $T$ tel que $v_i(T) = v$.</p>
<p>Palier 1 ($v \leq v_\text{inf}$) — résoudre en $T_1 \in [0,1]$ :</p>
<div class="block">
$$(1-3b)\,T_1^3 + 3b\,T_1^2 - \frac{v}{v_\text{inf}} = 0$$
</div>
<p>Palier 2 ($v > v_\text{inf}$) — posons $w = v - v_\text{inf}$, résoudre en $T_2 \in [0,1]$ :</p>
<div class="block">
$$\bigl(3(c+d-cd)-2\bigr)\,T_2^3 + 3(1-2c-d+cd)\,T_2^2 + 3c\,T_2 - \frac{w}{w_\text{max}} = 0$$
</div>
<p class="note">Ces cubiques sont résolues par la formule de Cardano avec affinement Newton-Raphson.</p>
<h3>Coefficient $\alpha_1$ — intégrale du palier 1</h3>
<div class="block">
$$\alpha_1(T_1) = 3\,v_\text{inf}\left[
\frac{-9ab+3a+6b-2}{6}\,T_1^6
+\frac{24ab-6a-13b+3}{5}\,T_1^5
+\frac{3(-7ab+a+2b)}{4}\,T_1^4
+2ab\,T_1^3
\right]$$
</div>
<p class="note">Si $v \leq v_\text{inf}$ : on utilise le $T_1$ résolu ci-dessus. Si $v > v_\text{inf}$ : $\alpha_1 = \alpha_1(1)$ (palier 1 entier).</p>
<h3>Coefficients $\alpha_2$ et $\beta_2$ — intégrale du palier 2</h3>
<p>Posons l'auxiliaire :</p>
<div class="block">
$$u(T_2) =
\frac{-3cd+9ecd+3c-9ec+3d-9ed+6e-2}{6}\,T_2^6 \\[4pt]
+\frac{2cd-15ecd-4c+21ec-2d+15ed-12e+2}{5}\,T_2^5 \\[4pt]
+\frac{6ecd+c-15ec-6ed+6e}{4}\,T_2^4
+ec\,T_2^3$$
</div>
<p>Alors :</p>
<div class="block">
$$\alpha_2 = (v - v_\text{inf}) - 3\,u(T_2)\,w_\text{max}$$
$$\beta_2 = 3\,p_\text{max}\,w_\text{max}\,u(T_2)$$
</div>
<p class="note">Si $v \leq v_\text{inf}$ : $\alpha_2 = \beta_2 = 0$.</p>
<hr class="sep">
<h2>4. Équilibre de recettes — calcul de $p_0$</h2>
<p>En substituant la décomposition $(\alpha_1+\alpha_2)\,p_0+\beta_2$ dans la somme des factures :</p>
<div class="block">
$$R = \sum_{i} \text{abo}_i + \sum_{i}\bigl[(\alpha_{1,i}+\alpha_{2,i})\,p_0 + \beta_{2,i}\bigr]$$
</div>
<p>Comme les $\alpha$ et $\beta$ ne dépendent pas de $p_0$, on obtient directement :</p>
<div class="block">
$$\boxed{p_0 = \frac{R - \displaystyle\sum_i \text{abo}_i - \displaystyle\sum_i \beta_{2,i}}{\displaystyle\sum_i (\alpha_{1,i} + \alpha_{2,i})}}$$
</div>
<p class="note">$p_0$ est calculé une fois par évaluation de la courbe. Si $\sum\alpha = 0$ (tous les foyers consomment 0), on pose $p_0 = 0$.</p>
<hr class="sep">
<h2>5. Résumé du pipeline de calcul</h2>
<ol>
<li>Les citoyens placent des points de contrôle → paramètres $(a,b,c,d,e,v_\text{inf})$.</li>
<li>Pour chaque foyer $i$, calculer $\alpha_{1,i}$, $\alpha_{2,i}$, $\beta_{2,i}$ par inversion cubique.</li>
<li>Calculer $p_0$ par la formule d'équilibre.</li>
<li>Facture de chaque foyer : $\text{Bill}_i = \text{abo}_i + (\alpha_{1,i}+\alpha_{2,i})\,p_0 + \beta_{2,i}$.</li>
<li>Vérification : $\sum_i \text{Bill}_i = R$ (à précision numérique).</li>
</ol>
<p class="note">Sources : <code>backend/app/engine/pricing.py</code> · <code>backend/app/engine/integrals.py</code> · <code>frontend/app/utils/bezier-math.ts</code></p>
</body>
</html>