13.2. Algorithme de calcul « 4DVAR »¶
13.2.1. Description¶
Cet algorithme réalise une estimation de l’état d’un système dynamique, par une
méthode de minimisation variationnelle de la fonctionnelle
d’écart
classique en assimilation de données :

qui est usuellement désignée comme la fonctionnelle « 4D-Var » (voir par exemple [Talagrand97]). Les dénominations « 4D-Var », « 4D-VAR » et « 4DVAR » sont équivalentes. Cet algorithme d’optimisation mono-objectif est naturellement écrit pour une estimation unique sur une fenêtre temporelle de simulation. Il est bien adapté aux cas d’opérateurs d’observation et d’évolution non-linéaires, son domaine d’application est comparable aux algorithmes de filtrage de Kalman et en particulier l”Algorithme de calcul « ExtendedKalmanFilter » ou l”Algorithme de calcul « UnscentedKalmanFilter ».
13.2.2. Quelques propriétés notables des méthodes implémentées¶
Pour compléter la description on synthétise ici quelques propriétés notables, des méthodes de l’algorithme ou de leurs implémentations. Ces propriétés peuvent avoir une influence sur la manière de l’utiliser ou sur ses performances de calcul. Pour de plus amples renseignements, on se reportera aux références plus complètes indiquées à la fin du descriptif de cet algorithme.
Les méthodes d’optimisation proposées par cet algorithme effectuent une recherche non locale du minimum, sans pour autant néanmoins assurer une recherche globale. C’est le cas lorsque les méthodes d’optimisation de recherche locale présentent de plus des capacités permettant d’éviter de rester bloquées par le premier minimum local trouvé. Ces capacités sont parfois heuristiques.
Les méthodes proposées par cet algorithme requièrent la dérivation de la fonction objectif ou de l’un des opérateurs. Cela nécessite que l’un au moins des opérateurs d’observation ou d’évolution soit différentiable voire les deux, et cela implique un temps de calcul supplémentaire dans le cas où les dérivées sont calculées numériquement par de multiples évaluations.
Les méthodes proposées par cet algorithme ne présentent pas de parallélisme interne, mais utilisent la dérivation numérique d’opérateur(s) qui est, elle, parallélisable. L’interaction potentielle, entre le parallélisme de la dérivation numérique, et le parallélisme éventuellement présent dans les opérateurs d’observation ou d’évolution intégrant les codes de l’utilisateur, doit donc être soigneusement réglée.
Les méthodes proposées par cet algorithme atteignent leur convergence sur un ou plusieurs critères de résidu ou de nombre. En pratique, il peut y avoir plusieurs critères de convergence actifs simultanément.
Le résidu peut être une mesure standard basée sur un écart (« écart calculs-mesures » par exemple), ou une valeur remarquable lié à l’algorithme (« nullité d’un gradient » par exemple).
Le nombre est fréquemment un élément remarquable lié à l’algorithme, comme un nombre d’itérations ou un nombre d’évaluations, mais cela peut aussi être par exemple un nombre de générations pour un algorithme évolutionnaire.
Il convient de régler soigneusement les seuils de convergence, pour limiter le coût calcul global de l’algorithme, ou pour assurer une adaptation de la convergence au cas physique traité.
13.2.3. Commandes requises et optionnelles¶
Les commandes générales requises, disponibles en édition dans l’interface graphique ou textuelle, sont les suivantes :
- Background
Vecteur. La variable désigne le vecteur d’ébauche ou d’initialisation, usuellement noté
. Sa valeur est définie comme un objet
de type « Vector » ou « VectorSerie ». Sa disponibilité en sortie est
conditionnée par le booléen « Stored » associé en entrée.
- BackgroundError
Matrice. La variable désigne la matrice de covariance des erreurs d’ébauche, usuellement notée
. Sa valeur est définie comme
un objet de type « Matrix », de type « ScalarSparseMatrix », ou de type
« DiagonalSparseMatrix », comme décrit en détail dans la section
Conditions requises pour décrire des matrices de covariance. Sa disponibilité en sortie est
conditionnée par le booléen « Stored » associé en entrée.
- EvolutionError
Matrice. La variable désigne la matrice de covariance des erreurs a priori d’évolution, usuellement notée
. Sa valeur est
définie comme un objet de type « Matrix », de type « ScalarSparseMatrix », ou
de type « DiagonalSparseMatrix », comme décrit en détail dans la section
Conditions requises pour décrire des matrices de covariance. Sa disponibilité en sortie est
conditionnée par le booléen « Stored » associé en entrée.
- EvolutionModel
Opérateur. La variable désigne l’opérateur d’évolution du modèle, usuellement noté
, qui décrit un pas élémentaire d’évolution
dynamique ou itérative. Sa valeur est définie comme un objet de type
« Function » ou de type « Matrix ». Dans le cas du type « Function »,
différentes formes fonctionnelles peuvent être utilisées, comme décrit dans
la section Conditions requises pour les fonctions décrivant un opérateur. Si un contrôle
est inclus dans le modèle d’observation, l’opérateur doit être appliqué à une
paire
.
- Observation
Liste de vecteurs. La variable désigne le vecteur d’observation utilisé en assimilation de données ou en optimisation, et usuellement noté
. Sa valeur est définie comme un objet de type « Vector »
si c’est une unique observation (temporelle ou pas) ou « VectorSerie » si
c’est une succession d’observations. Sa disponibilité en sortie est
conditionnée par le booléen « Stored » associé en entrée.
- ObservationError
Matrice. La variable désigne la matrice de covariance des erreurs a priori d’ébauche, usuellement notée
. Cette matrice est
définie comme un objet de type « Matrix », de type « ScalarSparseMatrix », ou
de type « DiagonalSparseMatrix », comme décrit en détail dans la section
Conditions requises pour décrire des matrices de covariance. Sa disponibilité en sortie est
conditionnée par le booléen « Stored » associé en entrée.
- ObservationOperator
Opérateur. La variable désigne l’opérateur d’observation, usuellement noté
, qui transforme les paramètres d’entrée
en
résultats
qui sont à comparer aux observations
. Sa valeur est définie comme un objet de type
« Function » ou de type « Matrix ». Dans le cas du type « Function »,
différentes formes fonctionnelles peuvent être utilisées, comme décrit dans
la section Conditions requises pour les fonctions décrivant un opérateur. Si un contrôle
est inclus dans le modèle d’observation, l’opérateur doit être appliqué à une
paire
.
Les commandes optionnelles générales, disponibles en édition dans l’interface graphique ou textuelle, sont indiquées dans la Liste des commandes et mots-clés pour un cas d’assimilation de données ou d’optimisation. De plus, les paramètres de la commande « AlgorithmParameters » permettent d’indiquer les options particulières, décrites ci-après, de l’algorithme. On se reportera à la Description des options d’un algorithme par « AlgorithmParameters » pour le bon usage de cette commande.
Les options sont les suivantes :
- Bounds
Liste de paires de valeurs réelles. Cette clé permet de définir des paires de bornes supérieure et inférieure pour chaque variable d’état optimisée. Les bornes doivent être données par une liste de liste de paires de bornes inférieure/supérieure pour chaque variable, avec une valeur
Nonechaque fois qu’il n’y a pas de borne. Les bornes peuvent toujours être spécifiées, mais seuls les optimiseurs sous contraintes les prennent en compte. Si la liste est vide, cela équivaut à une absence de bornes.Exemple :
{"Bounds":[[2.,5.],[1.e-2,10.],[-30.,None],[None,None]]}
- ConstrainedBy
Nom prédéfini. Cette clé permet d’indiquer la méthode de prise en compte des contraintes de bornes. La seule disponible est « EstimateProjection », qui projette l’estimation de l’état courant sur les contraintes de bornes.
Exemple :
{"ConstrainedBy":"EstimateProjection"}
- CostDecrementTolerance
Valeur réelle. Cette clé indique une valeur limite, conduisant à arrêter le processus itératif d’optimisation lorsque la fonction coût décroît moins que cette tolérance au dernier pas. La valeur par défaut est de 1.e-7, et il est recommandé de l’adapter aux besoins pour des problèmes réels. On peut se reporter à la partie décrivant les manières de Contrôler la convergence pour des cas de calculs et algorithmes itératifs pour des recommandations plus détaillées.
Exemple :
{"CostDecrementTolerance":1.e-7}
- EstimationOf
Nom prédéfini. Cette clé permet de choisir le type d’estimation à réaliser. Cela peut être soit une estimation de l’état, avec la valeur « State », ou une estimation de paramètres, avec la valeur « Parameters ». Le choix par défaut est « State ».
Exemple :
{"EstimationOf":"State"}
- GradientNormTolerance
Valeur réelle. Cette clé indique une valeur limite, conduisant à arrêter le processus itératif d’optimisation lorsque la norme du gradient est en dessous de cette limite. C’est utilisé uniquement par les optimiseurs sans contraintes. Le défaut est 1.e-5 et il n’est pas recommandé de le changer.
Exemple :
{"GradientNormTolerance":1.e-5}
- InitializationPoint
Vecteur. La variable désigne un vecteur à utiliser comme l’état initial autour duquel démarre un algorithme itératif. Par défaut, cet état initial n’a pas besoin d’être fourni et il est égal à l’ébauche
.
Sa valeur doit permettre de construire un vecteur de taille identique à
l’ébauche. Dans le cas où il est fourni, il ne remplace l’ébauche que pour
l’initialisation.Exemple :
{"InitializationPoint":[1, 2, 3, 4, 5]}
- MaximumNumberOfIterations
Valeur entière. Cette clé indique le nombre maximum d’itérations internes possibles en optimisation itérative. Le défaut est 15000, qui est très similaire à une absence de limite sur ce nombre d’itérations. Il est ainsi recommandé d’adapter ce paramètre aux besoins pour des problèmes réels. Pour certains optimiseurs, le nombre de pas effectif d’arrêt peut être légèrement différent de la limite à cause d’exigences de contrôle interne de l’algorithme. On peut se reporter à la partie décrivant les manières de Contrôler la convergence pour des cas de calculs et algorithmes itératifs pour des recommandations plus détaillées.
Exemple :
{"MaximumNumberOfIterations":100}
- Minimizer
Nom prédéfini. Cette clé permet de changer le minimiseur pour l’optimiseur. Le choix par défaut est « LBFGSB », et les choix possibles sont « LBFGSB » (minimisation non linéaire sous contraintes, voir [Byrd95], [Morales11], [Zhu97]), « TNC » (minimisation non linéaire sous contraintes), « CG » (minimisation non linéaire sans contraintes), « BFGS » (minimisation non linéaire sans contraintes), Il est fortement conseillé de conserver la valeur par défaut.
- ProjectedGradientTolerance
Valeur réelle. Cette clé indique une valeur limite, conduisant à arrêter le processus itératif d’optimisation lorsque toutes les composantes du gradient projeté sont en-dessous de cette limite. C’est utilisé uniquement par les optimiseurs sous contraintes. Le défaut est -1, qui désigne le défaut interne de chaque optimiseur (usuellement 1.e-5), et il n’est pas recommandé de le changer.
Exemple :
{"ProjectedGradientTolerance":-1}- StoreSupplementaryCalculations
Liste de noms. Cette liste indique les noms des variables supplémentaires, qui peuvent être disponibles au cours du déroulement ou à la fin de l’algorithme, si elles sont initialement demandées par l’utilisateur. Leur disponibilité implique, potentiellement, des calculs ou du stockage coûteux. La valeur par défaut est donc une liste vide, aucune de ces variables n’étant calculée et stockée par défaut (sauf les variables inconditionnelles). Les noms possibles pour les variables supplémentaires sont dans la liste suivante (la description détaillée de chaque variable nommée est donnée dans la suite de cette documentation par algorithme spécifique, dans la sous-partie « Informations et variables disponibles à la fin de l’algorithme ») : [ « Analysis », « BMA », « CostFunctionJ », « CostFunctionJAtCurrentOptimum », « CostFunctionJb », « CostFunctionJbAtCurrentOptimum », « CostFunctionJo », « CostFunctionJoAtCurrentOptimum », « CurrentIterationNumber », « CurrentOptimum », « CurrentState », « EnsembleOfSimulations », « EnsembleOfStates », « IndexOfOptimum », ].
Exemple :
{"StoreSupplementaryCalculations":["CurrentState", "Residu"]}
13.2.4. Informations et variables disponibles à la fin de l’algorithme¶
En sortie, après exécution de l’algorithme, on dispose d’informations et de
variables issues du calcul. La description des
Variables et informations disponibles en sortie indique la manière de les obtenir, par la
méthode nommée get, depuis la variable « ADD » du post-processing en
interface graphique, ou depuis le cas en interface textuelle. Les variables
d’entrée, mises à disposition de l’utilisateur en sortie pour faciliter
l’écriture des procédures de post-processing, sont décrites dans un
Inventaire des informations potentiellement disponibles en sortie.
Sorties permanentes (non conditionnelles)
Les sorties non conditionnelles de l’algorithme sont les suivantes :
- Analysis
Liste de vecteurs. Chaque élément de cette variable est un état optimal
en optimisation, une interpolation ou une analyse
en assimilation de données.Exemple :
xa = ADD.get("Analysis")[-1]
- CostFunctionJ
Liste de valeurs. Chaque élément est une valeur de fonctionnelle d’écart
choisie.Exemple :
J = ADD.get("CostFunctionJ")[:]
- CostFunctionJb
Liste de valeurs. Chaque élément est une valeur de fonctionnelle d’écart
, c’est-à-dire de la partie écart à l’ébauche. Si cette partie
n’existe pas dans la fonctionnelle, sa valeur est nulle.Exemple :
Jb = ADD.get("CostFunctionJb")[:]
- CostFunctionJo
Liste de valeurs. Chaque élément est une valeur de fonctionnelle d’écart
, c’est-à-dire de la partie écart à l’observation.Exemple :
Jo = ADD.get("CostFunctionJo")[:]
Ensemble des sorties à la demande (conditionnelles ou non)
L’ensemble des sorties (conditionnelles ou non) de l’algorithme, classées par ordre alphabétique, est le suivant :
- Analysis
Liste de vecteurs. Chaque élément de cette variable est un état optimal
en optimisation, une interpolation ou une analyse
en assimilation de données.Exemple :
xa = ADD.get("Analysis")[-1]
- BMA
Liste de vecteurs. Chaque élément est un vecteur d’écart entre l’ébauche et l’état optimal.
Exemple :
bma = ADD.get("BMA")[-1]
- CostFunctionJ
Liste de valeurs. Chaque élément est une valeur de fonctionnelle d’écart
choisie.Exemple :
J = ADD.get("CostFunctionJ")[:]
- CostFunctionJAtCurrentOptimum
Liste de valeurs. Chaque élément est une valeur de fonctionnelle d’écart
. A chaque pas, la valeur correspond à l’état optimal trouvé depuis
le début.Exemple :
JACO = ADD.get("CostFunctionJAtCurrentOptimum")[:]
- CostFunctionJb
Liste de valeurs. Chaque élément est une valeur de fonctionnelle d’écart
, c’est-à-dire de la partie écart à l’ébauche. Si cette partie
n’existe pas dans la fonctionnelle, sa valeur est nulle.Exemple :
Jb = ADD.get("CostFunctionJb")[:]
- CostFunctionJbAtCurrentOptimum
Liste de valeurs. Chaque élément est une valeur de fonctionnelle d’écart
, c’est-à-dire de la partie écart à l’ébauche. A chaque pas, la
valeur correspond à l’état optimal trouvé depuis le début. Si cette partie
n’existe pas dans la fonctionnelle, sa valeur est nulle.Exemple :
JbACO = ADD.get("CostFunctionJbAtCurrentOptimum")[:]
- CostFunctionJo
Liste de valeurs. Chaque élément est une valeur de fonctionnelle d’écart
, c’est-à-dire de la partie écart à l’observation.Exemple :
Jo = ADD.get("CostFunctionJo")[:]
- CostFunctionJoAtCurrentOptimum
Liste de valeurs. Chaque élément est une valeur de fonctionnelle d’écart
, c’est-à-dire de la partie écart à l’observation. A chaque pas,
la valeur correspond à l’état optimal trouvé depuis le début.Exemple :
JoACO = ADD.get("CostFunctionJoAtCurrentOptimum")[:]
- CurrentIterationNumber
Liste d’entiers. Chaque élément est l’index d’itération courant au cours du déroulement itératif de l’algorithme utilisé. Il y a une valeur d’index d’itération par pas d’assimilation correspondant à un état observé.
Exemple :
cin = ADD.get("CurrentIterationNumber")[-1]
- CurrentOptimum
Liste de vecteurs. Chaque élément est le vecteur d’état optimal au pas de temps courant au cours du déroulement itératif de l’algorithme d’optimisation utilisé. Ce n’est pas nécessairement le dernier état.
Exemple :
xo = ADD.get("CurrentOptimum")[:]
- CurrentState
Liste de vecteurs. Chaque élément est un vecteur d’état courant utilisé au cours du déroulement itératif de l’algorithme utilisé.
Exemple :
xs = ADD.get("CurrentState")[:]
- EnsembleOfSimulations
Liste de vecteurs ou matrice. Chaque élément est une collection ordonnée de vecteurs d’état physique ou d’état simulé éventuellement observé
. Ce sont des sorties d’opérateur
,
c’est-à-dire des états d’observation simulés (nommés « snapshots » en
terminologie de bases réduites). A chaque index de pas, il y a 1 état par
colonne si cette liste est sous forme matricielle, ou 1 état par élément si
c’est effectivement une liste. Important : la numérotation du support ou des
points, sur lequel ou auxquels sont fournis une valeur d’état dans chaque
vecteur, est implicitement celle de l’ordre naturel de numérotation du
vecteur d’état, de 0 à la « taille moins 1 » de ce vecteur.Exemple :
{"EnsembleOfSimulations":[y1, y2, y3...]}
- EnsembleOfStates
Liste de vecteurs ou matrice. Chaque élément est une collection ordonnée de vecteurs d’état physique ou d’état paramétrique
. Ce sont
des entrées d’opérateur
, c’est-à-dire des états courants avant
observation. A chaque index de pas, il y a 1 état par colonne si cette liste
est sous forme matricielle, ou 1 état par élément si c’est effectivement une
liste. Important : la numérotation du support ou des points, sur lequel ou
auxquels sont fournis une valeur d’état dans chaque vecteur, est
implicitement celle de l’ordre naturel de numérotation du vecteur d’état, de
0 à la « taille moins 1 » de ce vecteur.Exemple :
{"EnsembleOfStates":[x1, x2, x3...]}
- IndexOfOptimum
Liste d’entiers. Chaque élément est l’index d’itération de l’optimum obtenu au cours du déroulement itératif de l’algorithme d’optimisation utilisé. Ce n’est pas nécessairement le numéro de la dernière itération.
Exemple :
ioo = ADD.get("IndexOfOptimum")[-1]