• Aucun résultat trouvé

2.5 Contrôle numérique

2.5.3 Algorithme GRAPE

Méthode

L’algorithme GRAPE fonctionne exactement de la même manière. Sa particularité in-tervient dans le calcul des gradients ∂J/∂u. Pour le comprendre, on considère le problème standard du contrôle d’un système à deux niveaux. Dans cet exemple, l’état du système est décrit par un vecteur |λ(t)i composé de deux coordonnées complexes. Sa dynamique est gouvernée par l’équation de Schrödinger suivante:

d

dt|λ(t)i = −iH(t) |λ(t)i , (2.41) où l’on a posé ~ = 1. L’opérateur Hamiltonien s’écrit sous la forme:

H(t) = H0+ u(t)Hc. (2.42)

H0 représente l’interaction du système avec le champ statique ~B0 et u(t)Hc l’interaction avec le champ de contrôle radiofréquence. Supposons que l’on souhaite minimiser une fonctionnelle de coût de la forme:

J = g(|λ(tf)i) +Z tf

t0

f0(u(t), t), (2.43) où g et f0 sont des fonctions arbitraires et tf est fixé (problème de type Mayer-Lagrange). Le principe est d’optimiser le champ u(t) de façon à minimiser J.

La première étape consiste à discrétiser le problème, en introduisant un ensemble d’instants de la forme:

où N est un entier arbitraire. Ainsi, le contrôle u(t) se décompose en N paramètres

u(tn) = un. Il s’agit donc d’une fonction constante par morceaux de longueur dt = tn+1−tn. A chaque itération k, on souhaite appliquer la relation (2.39) sur l’ensemble des un de manière à ce que J(k+1) < J(k). Le champ de contrôle et l’opération (2.39) sont illustrés sur la figure 2.4.

0

t

u

t

n

dt

ǫ∂J/∂u

n

t

f

u

n

Figure 2.4 – Champ de contrôle en fonction du temps discrétisé. Le programme ajoute à chaque itération la quantité ǫ∂J/∂un pour tout n.

Résolution numérique des équations du mouvement

A l’instant t1 = t0+dt, l’état du système peut être calculé car le champ étant constant sur l’intervalle [t0, t0+ dt], la solution |λ(t0+ dt)i est connue et elle est donnée par:

|λ(t0+ dt)i = e−iH1dt

|λ(t0)i . (2.45) où H1 = H0+ u1Hc est l’opérateur Hamiltonien entre les instants t0 et t1. Ainsi, l’état du système est connu de proche en proche jusqu’à l’instant tf = tN, puisqu’il vérifie:

|λ(tN)i = UN · UN −1· · · U1|λ(t0)i , (2.46) avec Un = e−iHndt. Un est donc une exponentielle de matrice qui coûte cher en temps de calcul. De plus, nous allons voir que le calcul des gradients nécessite de calculer la dérivée de la matrice Un par rapport aux champs de contrôle. Il est donc indispensable de trouver une forme plus appropriée de Un. Pour un système à deux niveaux sans relaxation, l’opérateur Un peut être calculé analytiquement, ce qui permet d’améliorer la vitesse de la propagation numérique et de calculer les gradients sans problème. Mais pour être plus général, nous allons introduire dans un prochain paragraphe plusieurs méthodes pour développer Un.

État adjoint

Dans la section 2.3, nous avons vu que le PMP stipule qu’il existe un vecteur adjoint, et que dans un problème de type Mayer ou Bolza la minimisation implique la condition de transversalité (2.13). On introduit l’état adjoint du système |χ(t)i. La condition de transversalité (2.13), prise pour p0 = −1, s’écrit sous la forme:

|χ(tf)i = − ∂g(|λ(tf)i) ∂|λi |λi=|λ(tf)i . (2.47) Par exemple, supposons que la fonction g soit donnée par g(|λ(tf)i) = 1 − | hλc|λ(tf)i |2, où λc est un état cible. On a alors:

|χ(tf)i = − ∂|λ(tf)i " 1 − hλ(tf)|λci hλc|λ(tf)i # = hλ(tf)|λci ∂[x cx(tf)+y cy(tf] ∂x(tf) ∂[x cx(tf)+y cy(tf)] ∂y(tf) = hλ(tf)|λci x c y c . (2.48) Cette condition nous donne donc la valeur de l’état adjoint à l’instant final, i.e. |χ(tf)i. Celui-ci peut être connu pour tout t, en résolvant les équations d’Hamilton appliquées au pseudo-Hamiltonien du système donné par Hp = hχ|d

dt|λi, c’est-à-dire:

d

dt|χi = −∂Hp

∂|λi. (2.49)

Calcul des gradients

On rappelle que pour que le coût diminue à chaque itération, l’algorithme doit procéder selon l’équation (2.39), ce qui nécessite de calculer le gradient ∂J/∂un. Or, en considérant un coût qui ne dépend que de l’état final, ce gradient vérifie:

∂J

∂un = ∂J

∂|λ(tN)i·

∂|λ(tN)i

∂un . (2.50) On rappelle que tN = tf. Le coût J donné par l’équation (2.43) montre que seule la fonction g dépend de |λ(tN)i. Par conséquent, le premier facteur du gradient est donné par ∂J

∂|λ(tN)i = ∂g

∂|λ(tN)i. Cette équation correspond à la condition de transversalité (2.13) imposée par le PMP. Ce terme correspond au vecteur adjoint à l’instant final, que l’on note |χ(tN)i. Le second facteur du gradient s’écrit sous la forme:

∂|λ(tN)i

∂un = UN· · · Un+1 ∂Un

∂unUn−1· · · U1|λ(t1)i . (2.51) Le gradient ∂J/∂un est donc le produit scalaire entre l’état adjoint à l’instant final et cette équation, c’est-à-dire:

∂J ∂un = hχ(tN)| UN· · · Un+1 | {z } hχ(tn+1)| ∂Un ∂un Un−1· · · U1|λ(t1)i | {z } |λ(tn−1)i . (2.52)

L’algorithme nécessite donc de calculer hχ(tn+1)| et |λ(tn−1)i. Le premier s’obtient en faisant une propagation arrière à partir de hχ(tN)|. Le second s’obtient grâce à une pro-pagation avant suivant l’équation (2.46). Pour connaître ces deux objets pour tout tn, il est nécessaire de faire une propagation avant et une arrière. Ainsi, pour chaque itération, le programme nécessite deux propagations.

On rappelle que le propagateur Unest donné par Un= e−iHndt. Comme nous l’avons dit plus haut, la dérivée partielle ∂Un/∂un nécessite que la matrice Un soit exprimée sous une autre forme afin de pouvoir calculer la dérivée. Nous donnons ci-dessous trois méthodes qui permettent de calculer ∂Un/∂un.

Gradient exact. Cette méthode est valable uniquement pour un système à deux

ni-veaux. On rappelle que les champs de contrôle sont constants sur chaque intervalle de longueur dt. On considère que la dynamique du système entre les instants tn et tn+1 est gouvernée par un opérateur hamiltonien de la forme:

Hn= −12 δ ux,n− iuy,n ux,n+ iuy,n −δ . (2.53) On définit le vecteur normé suivant:

~ωn = q 1 δ2+ u2 x,n+ u2 y,n ux,n uy,n δ . (2.54) Le Hamiltonien Hn peut s’écrire en fonction des matrices de Pauli suivant la formule

Hn = −1 2

q

δ2 + u2

x,n+ u2

y,n~ω· ~σ, où les composantes de ~σ sont les matrices de Pauli. En posant Ωn=qδ2+ u2

x,n+ u2

y,n, on peut montrer que le propagateur Un s’écrit:

Un = e−iHndt= cos ndt 2 ! 1+i sin ndt 2 ! (~ω · ~σ). (2.55) Finalement, en dérivant cette expression par rapport aux champs de contrôle, on obtient:

∂Un

∂ux,n =−iσxdtUn ∂Un

∂uy,n =−iσydtUn.

(2.56)

Suivant la relation (2.52), les gradients sont donnés par:

∂J

∂ux,n = −idt hχ(tn+1)|σx|λ(tn)i ,

∂J

∂uy,n = −idt hχ(tn+1)|σy|λ(tn)i .

(2.57) Les formules (2.55), (2.56), et (2.57) sont exactes. Par conséquent, l’unique approximation est d’avoir considéré un champ constant par morceaux, ce qui est de toute façon le cas dans les expériences de RMN [25].

Split opérator. Celui-ci s’applique pour des systèmes linéaires de la forme ˙~x = M~x, où

M = M0+Pm

k=1umMm[91]. Pour simplifier les explications, on considère le même système que précédemment, c’est-à-dire un système à deux niveaux dont l’opérateur Hamiltonien est donné par (2.53). Celui-ci peut se réécrire sous la forme Hn=−1

2



ux,nσx+uy,nσy+δσz



. Si dt est suffisamment petit, on peut montrer que le propagateur Un est de la forme:

Un = e−iHndt = e−iδdtσze−iux,ndtσxe−iuy,ndtσy + O(dt2). (2.58) Il est possible de développer ce terme jusqu’à des ordres supérieurs afin que le reste soit d’ordre plus élevé en dt. Si les matrices dans les exponentielles sont hermitiennes, on peut développer chacun de ces termes analytiquement. Dans notre cas, cela donne:

e−iδdtσz = e−iδdt 0 0 eiδdt , e−iux,ndtσx =

cos(ux,ndt) −i sin(ux,ndt) −i sin(ux,ndt) cos(ux,ndt)

,

e−iuy,ndtσy =

cos(uy,ndt) − sin(uy,ndt) sin(uy,ndt) cos(uy,ndt)

.

(2.59)

D’une manière générale, une matrice Hermitienne M peut s’écrire sous la forme M =

P diag[x1,· · · , xn]P, où les xn sont les valeurs propres de M et P la matrice de pas-sage vers la base propre de la matrice M. Son exponentielle est alors donnée par: eM =

P diag[ex1,· · · , exn]P. Le propagateur Un étant donné par (2.58), on peut calculer ses dérivées partielles par rapport aux champs de contrôle. On obtient la même formule que dans l’équation (2.56). Il en va de même pour les gradients ∂J/∂ux,n et ∂J/∂uy,n. Ici l’erreur commise est de l’ordre de dt2. Cette méthode est donc d’autant plus efficace que

dt est petit, c’est-à-dire que le nombre de pas de temps N choisi est grand. Cependant, plus le paramètre N est grand et plus les propagations sont longues, car on rappelle que le programme nécessite la connaissance des états |λ(t)i et |χ(t)i. Le propagateur est un produit de trois matrices, ce qui prend un temps important à calculer.

Développement de Taylor. Pour un système du type ˙~x = H(t, u(t))~x, le propagateur

Un = eHdt peut se développer comme une série de Taylor. On considère de nouveau le système à deux niveaux d’énergie. Le développement de Taylor du propagateur vérifie:

Un = e−iHndt = XM m=0 (−i)mdtmH m n m! + O(dt M +1), (2.60) où M est un paramètre arbitraire qui contrôle la précision de l’approximation. M. Lapert a remarqué que l’algorithme de propagation peut s’écrire, entre les instants tn et tn+1, sous la forme:

|λ(tn+1)i = e−iHndt

|λ(tn)i = XM

m=0

avec |Λm+1i = dt/(m + 1) |Λmi et |Λ0i = |λ(tn)i. Cela permet d’éviter de calculer des puissances de matrice qui prennent beaucoup de temps numériquement. Il faut faire at-tention car l’erreur n’est pas simplement en o(dtM +1). Le développement de Taylor fait perdre l’unitarité du propagateur et il faut donc choisir M suffisamment grand pour que l’approximation soit bonne. Dans le programme, on introduit un seuil ǫm, qui permet de sortir de la boucle (2.61) si la condition suivante est satisfaite:

m+1m+1i + hΛmmi < ǫm. (2.62) Dans notre modèle, on a ∂Hn/∂ux,n = σx et ∂Hn/∂uy,n = σy. En exprimant les dérivées partielles du propagateur par rapport aux champs de contrôle, on obtient les mêmes gradients que ceux de l’équation (2.57).

Algorithme

Nous allons maintenant détailler la construction de l’algorithme. Pour simplifier, consi-dérons de nouveau un système contrôlé par deux champs ux(t) et uy(t). Le temps est discrétisé en N pas. Les variables discrètes sont données par:

t∈ {t0,· · · , tN}, ux(tn) = ux,n, uy(tn) = uy,n. (2.63) On rappelle qu’à chaque itération k, le programme réalise l’opération suivante:

uk+1x,n = uk x,n+ ǫ ∂J ∂ux ux=ux,n , uk+1y,n = uk y,n+ ǫ ∂J ∂uy uy=uy,n . (2.64) On prend un exemple où le coût J est défini par:

J = 1 − ℜ(hλc, λ(tN)i), (2.65) où |λci est un état cible et |λ(tN)i l’état du système à l’instant final. A l’instant tf = tN, le vecteur adjoint vérifie:

|χ(tN)i = ∂J

∂|λ(tN)i = −ℜ(|λci). (2.66) L’algorithme se déroule de la façon suivante:

Initialisation des champs de contrôle ux,net uy,npour tout n et choix d’un paramètre

ǫ qui détermine la vitesse de convergence.

Pour k allant de 1 à kmax:

Propagation en avant de l’état |λi à partir de |λ(t0)i suivant la formule: |λ(tn)i = Un· · · U1|λ(t0)i ,

où Un est le propagateur développé selon une méthode au choix (par exemple le split operator). Sauvegarde de chacun des |λ(tn)i.

Propagation en arrière de l’état adjoint à partir de |χ(tN)i, suivant: hχ(tn)| = hχ(tN)| UN· · · Un,

et sauvegarde des hχ(tn)| pour tout n.

Calcul des gradients donnés par:

∂J

∂ux,n = −idt hχ(tn+1)|σx|λ(tn)i , ∂J

∂uy,n = −idt hχ(tn+1)|σy|λ(tn)i .

Mise à jour des champs de contrôle en appliquant la formule (2.64).

Fin de la boucle