# Revue de code — Implémentation CPG (Chaos Polynomial Généralisé)

## Résumé

Le code implémente correctement les grandes étapes d'une méthode de chaos polynomial non-intrusive :
génération des polynômes de Legendre, construction de la grille de Gauss–Legendre par produit
tensoriel, génération de la base de chaos multi-dimensionnelle, et transformation des variables
incertaines. Plusieurs problèmes bloquants et améliorations sont identifiés ci-dessous.

---

## 1. Bugs bloquants

### 1.1 `cpg_modes.m` — syntaxe incomplète

```matlab
% Code actuel (cassé)
for i = 1:          % <- borne supérieure manquante → erreur de syntaxe
end
```

La fonction est vide et génère une erreur de parsing. C'est l'objet principal des fichiers
fournis (`cpg_modes_regression.m` et `cpg_modes_nisp.m`).

---

### 1.2 `cpg.m` — appel à `method_lambda` commenté, section modes vide

```matlab
%[lambda_cpg] = method_lambda(X_cpg);   % <- commenté, rien n'est calculé
%% Stochastic modes
                                          % <- section vide
```

La fonction ne fait rien d'utile au-delà de la construction de la grille.
Le fichier `cpg.m` corrigé est fourni.

---

### 1.3 Répertoire `save/` non garanti

`save(filename)` échoue si le dossier `save/` n'existe pas. Corriger avec :

```matlab
if ~exist('save', 'dir'), mkdir('save'); end
save(filename)
```

---

## 2. Problèmes de cohérence

### 2.1 `method_XiToX.m` — signe inversé

```matlab
% Code actuel
X(i,:) = (P(3,i) + P(2,i))/2 - xi(i,:)*(P(3,i)-P(2,i))/2;
%                              ^--- signe moins
```

La convention standard est :

```
X = (Xmin + Xmax)/2 + ξ * (Xmax - Xmin)/2
```

avec ξ = +1 → X = Xmax et ξ = −1 → X = Xmin.

Le code actuel **inverse** cette orientation : ξ = +1 → Xmin, ξ = −1 → Xmax.
Pour une distribution uniforme symétrique, les statistiques (moyenne, variance) sont
inchangées, mais les graphiques et les comparaisons point-à-point avec la Monte Carlo
seront logiquement inversés. Corriger le signe.

---

### 2.2 `parameters.m` — `X_base` surdimensionné

```matlab
r = 2;
X_base = [ 0.5  1e8  1e8  0.001 ];   % 4 éléments, mais r=2
```

Seuls les deux premiers éléments de `X_base` sont utilisés (la boucle s'arrête à `i=r=2`).
Les valeurs `1e8` et `0.001` sont silencieusement ignorées.
Aligner `X_base` sur `r`, ou vérifier que `length(X_base) >= r` avec une assertion.

---

### 2.3 `cpg_polyChaos.m` — initialisation 1D

```matlab
alpha = [0:p]';        % vecteur colonne [p+1 × 1] pour r=1
```

Pour `r=1`, la boucle `for d = 2:r` ne s'exécute pas, et `alpha` reste un vecteur colonne.
L'indexation `alpha(n,:)` donne correctement un scalaire, donc le comportement est juste,
mais le cas `r=1` n'est pas testé explicitement et la forme de `alpha` diffère de `r>=2`
(colonne vs matrice). Ajouter un test unitaire pour `r=1`.

---

## 3. Points de vigilance

### 3.1 Explosion combinatoire de la grille de Gauss

La grille de collocation est un **produit tensoriel** : `Q = (p+1)^r` points.
Le nombre de modes est `A = C(p+r, r)` (nettement inférieur).

| r | p | Q = (p+1)^r | A = C(p+r,r) | Ratio Q/A |
|---|---|-------------|---------------|-----------|
| 2 | 4 | 25          | 15            | 1.7       |
| 3 | 4 | 125         | 35            | 3.6       |
| 4 | 4 | 625         | 70            | 8.9       |
| 5 | 4 | 3125        | 126           | 24.8      |

Pour `r >= 5`, le coût explose. Pour la régression, ce sur-échantillonnage est bénéfique
(système sur-déterminé). Pour NISP, le produit tensoriel reste exact mais coûteux.
Les grilles creuses (Smolyak) constituent l'alternative pour les grandes dimensions.

### 3.2 Sorties multiples du modèle

`model_main` retourne `[calc_rms; calc_std; calc_kurtosis]`, soit un vecteur `[3 × 1]`.
`method_lambda` accumule correctement ces sorties : `lambda_out` est `[3 × Q]`.
Les fonctions `cpg_modes_regression` et `cpg_modes_nisp` gèrent ce cas multi-sorties.

### 3.3 Polynômes de Legendre — convention de normalisation

`cpg_polyLegendre` calcule la norme sans le facteur 1/2 de la mesure uniforme :

```
PP(j) = 2 / (2*(j-1)+1)    % = ∫_{-1}^{1} L_{j-1}²(ξ) dξ
```

La variance du développement en chaos doit donc inclure le facteur `1/2^r` :

```
Var[λ] = Σ_{k>0}  λ̂_k²  ×  PsiPsi(k) / 2^r
```

Cette convention est explicitée dans les fonctions fournies.

---

## 4. Méthode de régression — principe mathématique

### Développement en chaos polynomial

On approche la quantité d'intérêt par :

```
λ(ξ) ≈ Σ_{k=0}^{A-1}  λ̂_k  Ψ_k(ξ)
```

où `Ψ_k(ξ) = Π_{j=1}^r L_{α_{k,j}}(ξ_j)` sont les polynômes de chaos
et `α_k ∈ ℕ^r` les multi-indices avec `|α_k| ≤ p`.

### Matrice de collocation

On construit la matrice `Φ ∈ ℝ^{Q×A}` :

```
Φ(q, k) = Ψ_k(ξ^(q))
```

### Résolution par moindres carrés (régression)

```
λ̂ = argmin ||Φ λ̂ - f||²  →  λ̂ = Φ \ f
```

où `f` est le vecteur des évaluations du modèle aux points de collocation.
Pour `Q > A` (cas usuel avec grille produit tensoriel), le système est sur-déterminé.

### Statistiques du développement

```
E[λ]   = λ̂_0                                    (coefficient de Ψ_0 = 1)
Var[λ] = Σ_{k=1}^{A-1}  λ̂_k²  ×  PsiPsi(k) / 2^r
```

---

## 5. Méthode NISP — principe mathématique

La projection spectrale non-intrusive calcule directement les coefficients par quadrature :

```
λ̂_k^NISP = <λ, Ψ_k> / <Ψ_k, Ψ_k>
           = (Σ_q  W_q  λ(ξ^(q))  Ψ_k(ξ^(q)))  /  PsiPsi(k)
```

où `W_q = Π_j w_{i_j}` sont les poids de quadrature de Gauss–Legendre en produit tensoriel.

Les poids 1D sont calculés par :

```
w_j = 2 / ((1 − ξ_j²)  [L'_{p+1}(ξ_j)]²)
```

**Avantage de NISP** : si le modèle est exactement représentable dans la base polynomiale,
l'intégration est exacte (la quadrature de Gauss est exacte pour les polynômes jusqu'au
degré `2p+1`).

**Avantage de la régression** : plus robuste au sur-échantillonnage et au bruit, meilleure
conditionnement numérique lorsque `Q >> A`.

---

## 6. Fichiers fournis

| Fichier                   | Description                                    |
|---------------------------|------------------------------------------------|
| `cpg.m`                   | Fonction principale corrigée                   |
| `cpg_modes_regression.m`  | Modes stochastiques par régression (nouveau)   |
| `cpg_gauss_weights.m`     | Poids de Gauss–Legendre (nouveau)              |
| `cpg_modes_nisp.m`        | Modes stochastiques par NISP (nouveau)         |
| `method_XiToX.m`          | Transformation ξ → X corrigée                 |

---

*Revue réalisée le 12 mai 2026*jk
