# Formule

La formules est une suite d'opération mathématique permettant d'obtenir un résultat.

Dans notre cas d'utilisation cette feature permet de créer des variables par des formules mais aussi via la valeurs d'autre variables dans le dataset.

Cette feature est particulièrement utile pour modéliser des relations logiques entre tes données : calculer un prix TTC à partir d'un prix HT, dériver un score à partir de plusieurs métriques, ou encore borner une valeur dans une plage réaliste.

### Contraintes importantes

**Les variables doivent être déclarées avant le champ qui les utilise.** La formule est évaluée au moment de la génération du champ cible : seuls les champs définis au-dessus dans le YAML sont accessibles. Si tu références un champ déclaré après, il ne sera pas encore disponible et la génération échouera.

{% hint style="danger" %}
Ne pas combiner `formula` avec `saisonnality`, `correlation` ou d'autres patterns — ces features modifient la valeur générée après coup, ce qui entrerait en conflit avec le résultat de ta formule.
{% endhint %}

### Créer une formule

Pour activer ce mode de calcul, il suffit d'ajouter le champ `formula` dans la définition de ton champ YAML. La valeur est une expression mathématique sous forme de chaîne de caractères.

Les champs du dataset se référencent directement par leur `fieldName`. Si ton champ s'appelle `budget`, tu écris simplement `budget` dans ta formule — pas de syntaxe spéciale, pas de préfixe.

Le champ `rules.range` reste utilisable pour borner le résultat final si la formule peut produire des valeurs hors de la plage souhaitée. (Pas sûr en bêta)

```yaml

//Variable d'origine présente dans la formule ci-dessous
- fieldName: budget
    type: integer
    rules:
      range:
        min: -10
        max: 101
- fieldName: test_formula
    type: integer
    
    formula : "sqrt(budget)* pi"
    
```

<details>

<summary>Liste d'exemple plus complexe</summary>

**Scénario** : tu génères des profils d'emprunteurs avec un score de risque calculé à partir de plusieurs indicateurs financiers, en utilisant des fonctions logarithmiques et des racines pour modéliser des relations non-linéaires réalistes (comme en vrai scoring bancaire).

```yaml
# Revenu annuel brut (en €)
- fieldName: revenu_annuel
  type: float
  rules:
    range:
      min: 15000
      max: 200000

# Montant total des dettes en cours (en €)
- fieldName: dette_totale
  type: float
  rules:
    range:
      min: 0
      max: 150000

# Nombre d'années d'historique de crédit
- fieldName: anciennete_credit
  type: integer
  rules:
    range:
      min: 0
      max: 30

# Nombre d'incidents de paiement sur 24 mois
- fieldName: incidents_paiement
  type: integer
  rules:
    range:
      min: 0
      max: 10

# Ratio dette / revenu (DTI — Debt To Income)
# Plus il est élevé, plus le profil est risqué
- fieldName: dti_ratio
  type: float
  formula: "clamp(dette_totale / revenu_annuel, 0, 1)"

# Capacité financière — racine carrée du revenu normalisée
# Croît moins vite que le revenu : un revenu x4 ne donne pas x4 de capacité
- fieldName: capacite_financiere
  type: float
  formula: "sqrt(revenu_annuel / 1000)"

# Poids de l'historique — logarithmique
# Les premières années comptent beaucoup, les suivantes de moins en moins
- fieldName: poids_historique
  type: float
  formula: "log(anciennete_credit + 1)"

# Pénalité incidents — exponentielle inversée
# 0 incident = pénalité nulle, chaque incident supplémentaire pèse de plus en plus
- fieldName: penalite_incidents
  type: float
  formula: "1 - exp(-incidents_paiement * 0.4)"

# Score brut composite (0 à ~10)
- fieldName: score_brut
  type: float
  formula: "capacite_financiere * poids_historique * (1 - dti_ratio) * (1 - penalite_incidents)"

# Score final normalisé sur 100 avec bruit réaliste de ±3%
# et borné pour ne jamais dépasser 100 ni descendre sous 0
- fieldName: score_risque
  type: float
  formula: "clamp(round(noise(score_brut * (100 / (sqrt(200) * log(31))), 3) * 10) / 10, 0, 100)"
```

**Scénario** : tu génères des mesures acoustiques dans différents environnements (salle de concert, open space, entrepôt...) avec le niveau sonore perçu calculé selon la distance à la source, les propriétés du milieu, et l'absorption de l'air.

```yaml
# Puissance acoustique de la source en Watts (ex: 0.001W = conversation, 100W = concert)
- fieldName: puissance_source
  type: float
  rules:
    range:
      min: 0.001
      max: 100.0

# Distance entre la source et le récepteur en mètres
- fieldName: distance_metres
  type: float
  rules:
    range:
      min: 0.5
      max: 500.0

# Coefficient d'absorption de l'air selon l'humidité (0.001 à 0.01 dB/m)
- fieldName: absorption_air
  type: float
  rules:
    range:
      min: 0.001
      max: 0.010

# Indice de réverbération du milieu (0=anéchoïque, 1=très réverbérant)
- fieldName: reverb_index
  type: float
  rules:
    range:
      min: 0.0
      max: 1.0

# Intensité acoustique en W/m²
# Loi du carré inverse : I = P / (4 * pi * r²)
# Plus on s'éloigne, l'énergie se répartit sur une sphère de plus en plus grande
- fieldName: intensite_acoustique
  type: float
  formula: "puissance_source / (4 * pi * distance_metres ** 2)"

# Niveau de pression acoustique brut en dB SPL
# Formule fondamentale : Lp = 10 * log10(I / I_ref) où I_ref = 10^-12 W/m²
# log(x / 10^-12) = log(x) + 12 * log(10) = log(x) + 12 * ln10
- fieldName: spl_brut
  type: float
  formula: "10 * (log(intensite_acoustique) + 12 * ln10)"

# Atténuation atmosphérique sur la distance (en dB)
# L'air absorbe le son proportionnellement à la distance
- fieldName: attenuation_air
  type: float
  formula: "absorption_air * distance_metres"

# Gain de réverbération — le son rebondit sur les parois et s'additionne
# Modélisé comme une racine carrée pour un effet de saturation réaliste
- fieldName: gain_reverb
  type: float
  formula: "6 * sqrt(reverb_index)"

# Niveau sonore perçu final en dB SPL avec bruit de mesure ±1.5%
# On soustrait l'atténuation et on ajoute la réverbération
- fieldName: spl_percu
  type: float
  formula: "clamp(noise(spl_brut - attenuation_air + gain_reverb, 1.5), 0, 194)"
```

</details>

### Liste des variables et operateurs disponibles

#### Opérateur arythmétique&#x20;

| **Symbole** | **Nom**        | **Description**                              | **Exemple**      |
| ----------- | -------------- | -------------------------------------------- | ---------------- |
| `+`         | Addition       | Additionne deux valeurs.                     | `10 + 5` → `15`  |
| `-`         | Soustraction   | Soustrait la deuxième valeur de la première. | `10 - 5` → `5`   |
| `*`         | Multiplication | Multiplie deux valeurs.                      | `10 * 5` → `50`  |
| `/`         | Division       | Divise la première valeur par la deuxième.   | `10 / 4` → `2.5` |
| `**`        | Puissance      | Élève le nombre à la puissance indiquée.     | `2 ** 3` → `8`   |
| `%`         | Modulo         | Retourne le reste d'une division entière.    | `10 % 3` → `1`   |

#### Compariason et logiques&#x20;

| **Symbole / Mot-clé** | **Type**    | **Description**                                        |
| --------------------- | ----------- | ------------------------------------------------------ |
| `==`                  | Comparaison | Vérifie si deux valeurs sont strictement égales.       |
| `!=`                  | Comparaison | Vérifie si deux valeurs sont différentes.              |
| `<` , `>`             | Comparaison | Strictement inférieur ou strictement supérieur.        |
| `<=` , `>=`           | Comparaison | Inférieur ou égal / Supérieur ou égal.                 |
| `and` , `&`           | Logique     | Vrai si les deux conditions sont vraies.               |
| `or` , \`             | \`          | Logique                                                |
| `not`                 | Logique     | Inverse l'état (Vrai devient Faux et vice versa).      |
| `^`                   | Logique     | XOR (Vrai si une seule des deux conditions est vraie). |

#### Fonction Mathématiques avancé

| **Fonction**        | **Description**                          | **Exemple**        |
| ------------------- | ---------------------------------------- | ------------------ |
| `sqrt(x)`           | Racine carrée.                           | `sqrt(16)` → `4`   |
| `abs(x)`            | Valeur absolue (rend le nombre positif). | `abs(-5)` → `5`    |
| `log(x)`            | Logarithme népérien.                     | `log(1)` → `0`     |
| `exp(x)`            | Exponentielle.                           | `exp(0)` → `1`     |
| `sin`, `cos`, `tan` | Fonctions trigonométriques (en radians). | `sin(pi/2)` → `1`  |
| `round(x)`          | Arrondi à l'entier le plus proche.       | `round(2.6)` → `3` |
| `floor(x)`          | Arrondi à l'entier inférieur.            | `floor(2.9)` → `2` |
| `ceil(x)`           | Arrondi à l'entier supérieur.            | `ceil(2.1)` → `3`  |

#### Fonction Utilitaire

| **Fonction**         | **Description**                                     | **Exemple**                           |
| -------------------- | --------------------------------------------------- | ------------------------------------- |
| `if(cond, a, b)`     | Si la condition est vraie, retourne `a`, sinon `b`. | `if(score > 10, "Gagné", "Perdu")`    |
| `clamp(x, min, max)` | Force une valeur à rester dans une fourchette.      | `clamp(15, 0, 10)` → `10`             |
| `min(a, b, ...)`     | Retourne la plus petite valeur d'une liste.         | `min(1, 5, -2)` → `-2`                |
| `max(a, b, ...)`     | Retourne la plus grande valeur d'une liste.         | `max(1, 5, -2)` → `5`                 |
| `noise(x, pct)`      | Ajoute un pourcentage de variation aléatoire à `x`. | `noise(100, 10)` → `90` à `110`       |
| `coalesce(...)`      | Retourne la première valeur non nulle (non-None).   | `coalesce(null, "Salut")` → `"Salut"` |

#### Date et Constante

| **Constante**                                           | **Valeur Approchée** | **Description**                                                      |
| ------------------------------------------------------- | -------------------- | -------------------------------------------------------------------- |
| `golden_ratio`                                          | `1.61803...`         | Le Nombre d'Or ($$ $\phi$ $$), utilisé en design et géométrie.       |
| `sqrt2`                                                 | `1.41421...`         | Racine carrée de 2 ($$ $\sqrt{2}$ $$).                               |
| `sqrt3`                                                 | `1.73205...`         | Racine carrée de 3 ($$ $\sqrt{3}$ $$).                               |
| `ln2`                                                   | `0.69314...`         | Logarithme népérien de 2.                                            |
| `ln10`                                                  | `2.30258...`         | Logarithme népérien de 10.                                           |
| `euler_mascheroni`                                      | `0.57721...`         | Constante d'Euler ($$ $\gamma$ $$), utilisée en théorie des nombres. |
| <mark style="color:purple;">`days_between(a, b)`</mark> | Fonction (en Bêta)   | Calcule le nombre de jours entre deux dates.                         |
| <mark style="color:purple;">`add_days(date, n)`</mark>  | Fonction (en Bêta)   | Ajoute `n` jours à une date donnée.                                  |
| `pi`                                                    | π                    | La valeur π                                                          |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://dataset-generation-doc.gitbook.io/dataset-generation-doc/pattern/formule.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
