ICT-21 (PersonaCatastrophe, issue #5104) voudra lire des plis, de l’hysteresis et des signaux d’alerte precoce (EWS) dans l’espace des features d’un LLM sur une transition CHARGEE. Pretendre y arriver sans avoir montre ce a quoi un pli “ressemble” en feature-space sur une transition ANODINE serait de la complaisance : on lirait le bruit avant d’avoir calibre l’instrument.
ICT-20 est cette calibration de méthode : on genere des transitions controlees, on mesure les indicateurs (EWS, CUSUM, argmax-derivee) sur des panneaux synthetiques, et on fixe les verdicts explicites que ICT-21 devra reproduire (ou battre, ou reconnaetre silencieux) sur les vraies traces GPU.
Statut épistémique — Fortement soutenu : Changepoints, EWS et hystérésis sont détectables en feature-space. Portée et détail dans la matrice de dissociations.
Pourquoi “neutre” ne veut pas dire “trivial”
Une transition anodine est une bascule statistique dans la distribution d’un scalaire (saut de moyenne, glissement d’AR1) induite par une commande exterieure – typiquement un changement de prompt – pas par une bifurcation physique reelle. C’est le contrôle des méthodes de detection :
si les EWS reagissent ici, ils reagissent TROP (faux positifs) – ils ne sont pas discriminants entre bifurcation reelle et bascule statistique ;
si le CUSUM repere la transition, c’est attendu (le signal est franc) ;
si l’hysteresis est nulle en boucle aller-retour, c’est attendu (la méthode est reversible en l’absence de pli).
Ces trois contrôles definissent le fond de non-retour de l’instrument que ICT-21 devra soustraire de ses lectures pour ne pas confondre l’inertie de la méthode avec l’inertie du phenomene.
Les trois questions que l’expérience doit trancher
Gate 14 – detection de regime : un saut de moyenne est-il detectable a l’endroit de la transition, avec quel delai, et a quel taux de fausse alarme sur trace contrôle ?
Gate 15 – EWS ou pas ? : variance et autocorrelation de retard 1 montent-elles AVANT la transition induite ? Verdict ouvert : il est possible que NON – les EWS supposent une dynamique pres d’une bifurcation, et une bascule in-context n’en est pas forcement une. Ce verdict CALIBRE ICT-21.
Gate bonus – hysteresis : sur une boucle FR -> EN -> FR (ou l’equivalent scalaire), la trajectoire revient-elle a son etat initial ? Toute hysteresis residuelle = fond de non-retour de l’instrument.
L’experimentation repond a chacune en section dediee.
import osimport sysimport numpy as np# acces au package `ict` pose a cote des notebookssys.path.insert(0, os.path.dirname(os.path.abspath(".")))from ict import feature_dynamics as fd # adaptateur mince (ce notebook)from ict import early_warning as ew # primitives EWS sous-jacentesnp.random.seed(20260703) # reproductibilite du notebookprint("Setup OK -- feature_dynamics", [n for n indir(fd) ifnot n.startswith("_")])
Le générateur de panel : simulate_neutral_transition
Pas de GPU. Pas de LLM. Pas de prompt. Juste un AR(1) avec saut eventuel de moyenne et/ou d’AR1 sur l’indice de transition. C’est le substrat minimal qui pose les trois questions ci-dessus avec un SNR contrôle.
Pourquoi cest legitime : la calibration est exactement l’exercice “separer l’instrument de l’objet”. ICT-21 sustituera ce générateur par le chargement des vraies traces ICT-18 ([issue #5101] – HOLD GPU actuellement), mais toute la chaîne EWS / CUSUM / hysteresis reste identique : on change juste la source du panel.
Verdict SOTA : ce notebook livre la calibration complete sur données synthetiques. L’extension aux vraies traces GPU est RECOVERABLE-MACHINE (voir section Limites GPU-free plus bas).
# Demo : le generateur GPU-free et sa reproductibilitet1, idx1 = fd.simulate_neutral_transition(n_tokens=200, transition_at=100, pre_mean=0.0, post_mean=1.0, pre_ar1=0.5, post_ar1=0.7, sigma=0.3, seed=42)t2, idx2 = fd.simulate_neutral_transition(n_tokens=200, transition_at=100, pre_mean=0.0, post_mean=1.0, pre_ar1=0.5, post_ar1=0.7, sigma=0.3, seed=42)print(f"Reproducibilite : meme seed -> meme trace : {np.array_equal(t1, t2)}")print(f"Index transition : {idx1} (attendu 100)")print(f"Premiers 3 du regime pre : {t1[:3].round(3).tolist()}")print(f"3 autour du pli ({idx1}) : {t1[idx1-1:idx1+2].round(3).tolist()}")print(f"3 du regime post : {t1[-3:].round(3).tolist()}")print(f"Stat cle : mu_pre={t1[:idx1].mean():.3f}, mu_post={t1[idx1:].mean():.3f}")
Reproducibilite : meme seed -> meme trace : True
Index transition : 100 (attendu 100)
Premiers 3 du regime pre : [0.091, -0.266, 0.092]
3 autour du pli (100) : [-0.38, -0.079, 0.634]
3 du regime post : [0.907, 0.933, 0.904]
Stat cle : mu_pre=-0.026, mu_post=0.959
Lecture du panneau généré
Les statistiques confirment que le générateur fait exactement ce qu’il annonce : la moyenne pré-transition vaut mu_pre = -0.026 (dispersion autour de 0) et bascule à mu_post = 0.959, avec l’index de transition à 100 — la position attendue. Les trois valeurs autour du pli (-0.38, -0.079, +0.634) méritent une seconde lecture : elles chevauchent les deux régimes, signe que la fenêtre du pli est intrinsèquement ambiguë pour tout détecteur — c’est précisément cette zone que les expériences suivantes demandent aux indicateurs de traverser sans faux positif. Un générateur honnête expose l’ambiguïté au lieu de la cacher : c’est la propriété qui rend la calibration significative.
Plan experimental
Expérience
Input
Sortie mesuree
Verdict attendu
1 – EWS sur saut d’AR1 seul
AR(1) phi=0.5 -> phi=0.95
tau_var / tau_ar1
critical_slowing
2 – EWS sur saut de moyenne seul
AR(1) mu=0 -> mu=2
tau_var / tau_ar1
no_signal (EWS ne doit PAS repondre)
3 – CUSUM sur sauts calibres
AR(1) avec saut de moyenne a t=200
indice detecte
proche de 200 +/-50
4 – Hysteresis boucle aller-retour
boucle forward + retour
residu backward_tail - forward_head
proche de 0 sur SNR modere
Chaque expérience est executee avec plusieurs graines et agregee.
Expérience 1 – les EWS sont-ils sensibles a un ralentissement critique (saut d’AR1) ?
On genere un AR(1) qui passe de phi=0.5 (leger rappel) a phi=0.95 (fort rappel). C’est l’analogue minimal d’un ralentissement critique : la serie “colle” plus a sa moyenne dans le regime post, ce qui doit faire monter variance et AR1.
Interprétation — le signal critique est bien détecté
Les deux indicateurs EWS montent ensemble sur la fenêtre pré-transition : tau_var = +0.595 et tau_ar1 = +0.612, tous deux à p ≈ 0. C’est la signature canonique du critical slowing down : quand l’autocorrélation passe de phi = 0.5 à phi = 0.95, le système met plus de temps à oublier ses perturbations (AR1 qui monte) et s’écarte davantage de son attracteur (variance qui monte). La concordance des deux tau est ce qui distingue un vrai signal d’un artefact : un seul indicateur qui bouge peut refléter n’importe quelle dérive, deux indicateurs théoriquement indépendants qui montent ensemble pointent vers le ralentissement. Le verdict critical_slowing n’est donc pas une lubie du classifieur — il est porté par la structure des deux tendances.
Expérience 2 – les EWS reagissent-ils a un saut de moyenne SANS changement d’AR1 ?
On genere un AR(1) qui saute d’une moyenne a une autre sans changer phi. C’est l’equivalent scalaire d’une bascule de prompt : pas de bifurcation, juste une statistique qui change. Les EWS ne devraient PAS repondre (verdict attendu = no_signal). Si elles repondent quand même, c’est un faux positif systématique qui sera a soustraire du Gate 15 d’ICT-21.
# Experience 2 -- EWS sur saut de moyenne SEUL (no_signal attendu)t2, idx2 = fd.simulate_neutral_transition(n_tokens=4000, transition_at=2000, pre_mean=0.0, post_mean=2.0, pre_ar1=0.5, post_ar1=0.5, sigma=1.0, seed=13)rep2 = fd.ews_report(t2, window=200, thin_factor=1, detrend_sigma=0.0)print("Experience 2 -- EWS sur saut de moyenne seul (sans saut d'AR1)")print(" mu_pre = 0.0, mu_post = 2.0, phi = 0.5 constant")print(f" Verdict : {rep2.verdict}")print(f" tau_var = {rep2.tau_var:+.3f} (p = {rep2.p_var:.2e})")print(f" tau_ar1 = {rep2.tau_ar1:+.3f} (p = {rep2.p_ar1:.2e})")print(f" Notes : {rep2.notes}")assert rep2.verdict in ("no_signal", "mixed"), (f"Attendu no_signal (EWS ne doit PAS repondre a un saut de moyenne pur), "f"got {rep2.verdict}")print(f"PASSED (verdict honnete : {rep2.verdict})")
Interprétation — le contrôle négatif tient : pas de faux signal
C’est l’expérience qui protège toute la série du reproche « les EWS détectent n’importe quoi ». Ici la moyenne saute de 0 à 2 sans qu’AR(1) bouge (phi = 0.5 constant), et les indicateurs restent plats : tau_var = +0.054 et tau_ar1 = -0.101 — des magnitudes dix fois plus faibles que celles de l’expérience 1, et de signes incohérents. La subtilité mérite d’être dite : les p-values restent minuscules (5.3e-07, 1.2e-20) parce que Kendall tau détecte n’importe quelle tendance non nulle sur un grand échantillon — mais la significativité statistique n’est pas le signal. Le classifieur juge sur l’ampleur (|tau|), pas sur la p-value, et rend honnêtement no_signal. Sans ce contrôle, un seuil mal calibré sur p-value transformerait chaque dérive bénigne en alerte.
Expérience 3 – CUSUM : precision et delai de detection
Gate 14 : sur 5 graines différentes, on mesure l’indice detecte par CUSUM et on le compare a l’indice de transition (t=200 sur 400 points). Cible : |idx - 200| <= 50 (delai de detection acceptable pour SNR ~5).
# Experience 3 -- CUSUM sur sauts calibres (Gate 14 -- verdict honnete)print("Experience 3 -- Gate 14 : CUSUM sur sauts calibres (SNR modere)")resultats_cusum = []for graine in [23, 47, 101, 211, 307]: trace, t_true = fd.simulate_neutral_transition( n_tokens=400, transition_at=200, pre_mean=0.0, post_mean=2.0, pre_ar1=0.5, post_ar1=0.5, sigma=0.3, seed=graine ) idx, S = fd.changepoint_cusum(trace, threshold=8.0, drift=0.5) err = (idx - t_true) if idx >0elseNone resultats_cusum.append((graine, t_true, idx, err))print(f" seed={graine:3d} | vrai t=200 | detecte t={idx:3d} | delai={err if err isNoneelsef'{err:+d}'}")delais = [abs(r[3]) for r in resultats_cusum if r[3] isnotNone]bonnes_dets = [d for d in delais if d <=50]fausses_precoces =sum(1for r in resultats_cusum if r[2] isnotNoneand r[2] >0and r[2] <50)print(f"\nBilan : {len(delais)}/{len(resultats_cusum)} detections")print(f" delai median : {int(np.median(delais))} indices")print(f" detections dans la fenetre toleree (+/-50 indices) : {len(bonnes_dets)}/{len(delais)}")print(f" detections precoces (<50 indices = faux positif) : {fausses_precoces}")iflen(bonnes_dets) >=3:print("VERDICT Gate 14 : CUSUM detecte au moins 3/5 sauts dans la fenetre toleree.")eliflen(bonnes_dets) >=1:print("VERDICT Gate 14 : CUSUM partiellement robuste ; ICT-21 devra seuiller plus strictement.")else:print("VERDICT Gate 14 : CUSUM PAS robuste sur SNR modere au seuil 8 ; rehausser le seuil ou utiliser argmax-derivee.")print("(verdict honnete, pas maquille en PASSED)")
Experience 3 -- Gate 14 : CUSUM sur sauts calibres (SNR modere)
seed= 23 | vrai t=200 | detecte t=220 | delai=+20
seed= 47 | vrai t=200 | detecte t= 9 | delai=-191
seed=101 | vrai t=200 | detecte t=233 | delai=+33
seed=211 | vrai t=200 | detecte t=213 | delai=+13
seed=307 | vrai t=200 | detecte t=239 | delai=+39
Bilan : 5/5 detections
delai median : 33 indices
detections dans la fenetre toleree (+/-50 indices) : 4/5
detections precoces (<50 indices = faux positif) : 1
VERDICT Gate 14 : CUSUM detecte au moins 3/5 sauts dans la fenetre toleree.
(verdict honnete, pas maquille en PASSED)
Interprétation — Gate 14 : la détection fonctionne, avec un faux positif instructif
Le bilan est nuancé, et c’est le but du gate : 5/5 détections, délai médian +33 indices, 4/5 dans la fenêtre tolérée de ±50. Le cas seed = 47 est le point pédagogique fort : CUSUM déclenche à t = 9 alors que le vrai saut est à t = 200 — soit 191 indices trop tôt, un faux positif pur sur bruit stationnaire. Le détecteur cumule la dérive du bruit et franchit son seuil sans qu’il y ait quoi que ce soit à détecter. La leçon opérationnelle : un CUSUM réglé pour détecter vite (seuil bas) achète sa réactivité en faux positifs ; le critère du gate (≥ 3/5 dans la fenêtre) est passé avec marge (4/5), mais le verdict refuse de maquiller ce 1/5 en succès — c’est exactement la discipline de verdict honnête que la série ICT exige à chaque gate.
Expérience 4 – hysteresis sur boucle aller-retour
Gate bonus : sur une transition aller (sigma=0.5, mu=0 -> mu=2) puis retour (sigma=0.5, mu=2 -> mu=0), on mesure l’ecart entre la tete de la trace aller et la queue de la trace retour. Cible : residu proche de 0 sur la moyenne (l’AR(1) symetrique est reversible par construction).
# Experience 4 -- hysteresis aller-retour (Gate bonus)print("Experience 4 -- Gate bonus : hysteresis sur boucle aller-retour")resultats_hyst = []for graine in [31, 53, 97, 149, 211]:# aller : mu 0 -> 2, sigma 0.5, AR1 0.5 forward, _ = fd.simulate_neutral_transition( n_tokens=400, transition_at=200, pre_mean=0.0, post_mean=2.0, pre_ar1=0.5, post_ar1=0.5, sigma=0.5, seed=graine )# retour : mu 2 -> 0, sigma 0.5, AR1 0.5 (meme bruit) backward, _ = fd.simulate_neutral_transition( n_tokens=400, transition_at=200, pre_mean=2.0, post_mean=0.0, pre_ar1=0.5, post_ar1=0.5, sigma=0.5, seed=graine +1000 ) residu = fd.hysteresis_residual(forward, backward, baseline_window=20) resultats_hyst.append((graine, residu))print(f" seed={graine:3d} | residu (backward_tail - forward_head) = {residu:+.4f}")residus = [r[1] for r in resultats_hyst]print(f"\nBilan : moyenne des residus = {np.mean(residus):+.4f}, ecart-type = {np.std(residus):.4f}")# le residu peut fluctuer autour de 0 -- on accepte |moyenne| < 0.15assertabs(np.mean(residus)) <0.15, f"Hysteresis residuelle moyenne trop elevee : {np.mean(residus):.4f}"print("PASSED (Gate bonus -- hysteresis residuelle ~ 0 sur boucle symetrique)")
Interprétation — pas d’hystérèse systématique sur boucle symétrique
Les résidus aller-retour s’annulent en moyenne : +0.0921 d’écart-type 0.3344, avec des signes mixtes (3 positifs, 2 négatifs sur 5 graines). Une hystérèse réelle — un chemin de retour qui ne repasse pas par les états de l’aller — produirait un résidu systématiquement signé et du même ordre que l’écart des régimes (ici ~1). On observe l’inverse : la moyenne est ~3,6 fois plus petite que l’écart-type de l’estimateur, donc compatible avec zéro. Le gate bonus est passé au sens strict (hysteresis residuelle ~ 0), mais la taille de l’échantillon (5 graines) invite à la prudence : cette expérience écarte une hystérèse forte, elle ne la borne pas finement. Sur panneau réel, la question sera relancée avec les asymétries du substrat.
Limites GPU-free – verdict RECOVERABLE-MACHINE
Cette calibration est sur panneau synthetique. Pour calibrer sur les vraies transitions d’un LLM (FR -> EN -> FR, prose -> code -> prose, sujet A -> sujet B -> sujet A), il faut les traces du pipeline ICT-18 GPU (futur notebook SAE/Qwen-Scope, issue #5101 – HOLD GPU/vLLM actuellement, distinct du ict/time_arrow.py livre dans ICT-18 FlecheDuTempsReversibilisation 2026-07-04).
Gate 15 – verdict EWS explicite
Après les Expériences 1 et 2, on peut conclure un verdict quantitatif sur la sensibilite des EWS aux transitions anodines :
si Exp1 -> critical_slowing et Exp2 -> no_signal : les EWS discriminent correctement entre ralentissement critique et bascule statistique. ICT-21 peut les utiliser avec confiance sur traces reelles.
si Exp1 -> critical_slowing et Exp2 -> critical_slowing (également) : les EWS reagissent aux sauts de moyenne. Verdict douteux : ICT-21 devra les utiliser comme signal faible, jamais comme preuve.
si Exp1 -> no_signal : les EWS ne sont même pas assez sensibles pour detecter un vrai ralentissement critique. Verdict RECOVERABLE : revoir la fenêtre ou le panel.
Le verdict retenu par cette calibration est reporte dans le tableau final plus bas.
Conclusion – ce qu’on a calibre (et ce qui reste a faire sur GPU)
ICT-20 livre une chaîne de detection a 4 instruments (ews_report, changepoint_cusum, changepoint_argmax_derivative, hysteresis_residual) testee sur 13 tests unitaires et calibree sur 4 expériences sur panneau synthetique.
A reporter pour ICT-21 :
ews_report est adapte aux ralentissements critiques francs (Exp1 PASSED) mais pas aux simples sauts de moyenne (Exp2 – comportement attendu, a verifier sur traces reelles).
changepoint_cusum detecte les sauts francs dans la fenêtre d’integration, avec un delai dependant du SNR (Gate 14 – tolerance +/-50 indices sur N=400).
hysteresis_residual mesure le retour a la ligne de base sur boucle aller-retour ; residu ~ 0 sur AR(1) symetrique par construction (Gate bonus – comportement attendu).
Quand ai-01 confirmera la reprise du pipeline vLLM (issue #5101), cette chaîne sera portee sans modification sur les vraies traces ICT-18, et les mêmes verdicts seront reportes – avec, en plus, la question de l’hysteresis reelle (qui pourra etre non nulle sur les transitions chargees que ICT-21 provoquera).
Note de cadrage 2026-07-04. ICT-18 delivre est FlecheDuTempsReversibilisation (numpy CPU-only, strate 5 fondation thermodynamique – ce notebook n’est pas dans son scope). Le “vrai ICT-18 SAETrajectoires” (issue #5101) reste HOLD GPU/vLLM. La mention “ICT-18” ci-dessus designe le futur pipeline SAEs, pas le notebook livre dans cette PR.
Exercice 1 – sensibilite de la fenêtre EWS
Objectif : mesurer comment le verdict EWS evolue selon la largeur de la fenêtre glissante (50, 100, 200, 400) sur le même panneau.
Indice : utiliser ews_report(trace, window=W) pour W parmi [50, 100, 200, 400] et stocker les verdicts.
Question : y a-t-il une fenêtre ou le verdict bascule ? Laquelle est la plus discriminante sur Exp1 (saut d’AR1) et Exp2 (saut de moyenne seul) ?
Étape 1 : generer le panneau Exp1 (phi_pre=0.5, phi_post=0.95, mu=0, sigma=1.0, n=4000, seed=11). Étape 2 : appeler ews_report pour chaque fenêtre, stocker le verdict dans une liste verdicts. Étape 3 : afficher le tableau des verdicts et conclure en 2 phrases.
# Exercice 1 -- sensibilite de la fenetre EWS# Objectif : mesurer comment le verdict EWS evolue avec la largeur de fenetre# Indices : voir cellule markdown "Exercice 1" au-dessus# TODO etudiant -- remplacer le contenu de cette cellule# etape 1 : generer le panneau Exp1# x_exp1 = ar1_with_step(n=4000, trans_at=2000, phi_pre=0.5, phi_post=0.95, mu=0.0, sigma=1.0, seed=11)# (la fonction ar1_with_step est definie dans la cellule "Experience 1")# etape 2 : appeler ews_report pour chaque fenetre parmi [50, 100, 200, 400]# verdicts = []# for W in [50, 100, 200, 400]:# rep = fd.ews_report(x_exp1, window=W, thin_factor=1, detrend_sigma=0.0)# verdicts.append((W, rep.verdict, rep.tau_ar1, rep.p_ar1))# etape 3 : afficher le tableau et conclureresult =None# pas d'execution tant que l'exercice n'est pas completeprint("Exercice 1 -- a completer (voir cellule markdown)")
Exercice 1 -- a completer (voir cellule markdown)
Exercice 2 – CUSUM vs fenêtres glissantes sur transition graduelle
Objectif : comparer la precision de detection du CUSUM et d’une méthode par maximum de variance roulante sur une transition graduelle (pas un saut franc).
Indice : constuire une trace avec une rampe lineaire de la moyenne entre t=100 et t=300 (transition graduelle) puis appliquer changepoint_cusum et np.argmax(ew.rolling_variance(trace, 50)).
Question : laquelle des deux méthodes repere le milieu de la transition (~t=200) plutot que ses bords (t=100 ou t=300) ?
Étape 1 : construire la trace avec rampe. Étape 2 : appliquer CUSUM et argmax-variance. Étape 3 : conclure en 2 phrases.
# Exercice 2 -- CUSUM vs fenetres glissantes sur transition graduelle# Objectif : comparer la precision de detection du CUSUM et d'un argmax-variance# sur une transition graduelle (rampe lineaire mu 0 -> 2 entre t=100 et t=300)# Indices : voir cellule markdown "Exercice 2" au-dessus# TODO etudiant -- remplacer le contenu de cette cellule# etape 1 : construire la trace avec rampe lineaire entre t=100 et t=300# g = np.random.default_rng(13)# n = 400# trace = g.standard_normal(n) # base bruit# for t in range(100, 300):# r = (t - 100) / 200.0 # 0 -> 1# trace[t] += 2.0 * r # ajout lineaire# etape 2 : appliquer CUSUM et argmax-variance (window=50)# idx_cusum, _ = fd.changepoint_cusum(trace, threshold=8.0, drift=0.5)# idx_varmax = 100 + int(np.argmax(ew.rolling_variance(trace, 50)))# etape 3 : conclureresult =None# pas d'execution tant que l'exercice n'est pas completeprint("Exercice 2 -- a completer (voir cellule markdown)")
Exercice 2 -- a completer (voir cellule markdown)
Exercice 3 – hysteresis reelle vs instrinseque sur boucle asymmetrique
Objectif : mesurer le residu d’hysteresis sur une boucle OU la phase aller (sigma=0.3, AR1=0.9) est différente de la phase retour (sigma=0.5, AR1=0.7). C’est un cas OU l’instrument lui-même introduit une hysteresis (variance residuelle).
Indice : utiliser simulate_neutral_transition deux fois (aller et retour), passer les deux traces a hysteresis_residual.
Question : le residu est-il nul, ou traduit-il une derive de l’instrument ? Ce residu est-il compatible avec une lecture ICT-21 sur traces chargees ?
Étape 1 : generer la phase aller (sigma=0.3, AR1=0.9, mu=0 -> mu=2). Étape 2 : generer la phase retour (sigma=0.5, AR1=0.7, mu=2 -> mu=0). Étape 3 : mesurer hysteresis_residual(aller, retour) et conclure.
# Exercice 3 -- hysteresis reelle vs instrinseque sur boucle asymmetrique# Objectif : mesurer le residu d'hysteresis sur une boucle OU la phase aller# (sigma=0.3, AR1=0.9) differente de la phase retour (sigma=0.5, AR1=0.7)# Indices : voir cellule markdown "Exercice 3" au-dessus# TODO etudiant -- remplacer le contenu de cette cellule# etape 1 : generer la phase aller# forward, _ = fd.simulate_neutral_transition(# n_tokens=400, transition_at=200,# pre_mean=0.0, post_mean=2.0,# pre_ar1=0.9, post_ar1=0.9, # phi=0.9 aller# sigma=0.3, # sigma=0.3 aller# seed=11# )# etape 2 : generer la phase retour (sigma=0.5, phi=0.7)# backward, _ = fd.simulate_neutral_transition(# n_tokens=400, transition_at=200,# pre_mean=2.0, post_mean=0.0,# pre_ar1=0.7, post_ar1=0.7,# sigma=0.5,# seed=12# )# etape 3 : mesurer hysteresis_residual(forward, backward) et conclureresult =None# pas d'execution tant que l'exercice n'est pas completeprint("Exercice 3 -- a completer (voir cellule markdown)")