Le problème consiste à calculer le spectre résultant d'une certaine combinaison (α) du spectre de III2, connu, et d'un spectre X, inconnu (éq. 46) :
ελInt = α ελIII2 + (1 − α) ελX
afin de le comparer au spectre mesuré expérimentalement, dans quatre expériences différentes.
La variable indépendante, ind[i]
, correspondra à la longueur
d'onde λ (de 350 à 500 nm, avec un incrément de 2 nm, soit m = 76
points). Les valeurs du spectre inconnu,
ελX, seront représentées par les
paramètres p[0]
à p[75]
. Et les valeurs de α
correspondant à chaque expérience par p[76]
à p[79]
.
Le fichier expérimental sera constitué d'une première colonne contenant les longueurs d'onde, suivie des quatre colonnes correspondant aux quatre expériences, et une sixième colonne contiendra le spectre du III2, connu. La programmation, extrêmement simple, repose sur cette utilisation astucieuse du fichier expérimental.
Précisons d'abord un point : les variables globales ind[
]
et ca[ ][ ]
ont des sœurs jumelles index[
]
et ex[ ][ ]
respectivement, destinées à recevoir les
valeurs lues dans le fichier expérimental, en accord avec les variables cochées
obs dans l'onglet Variables. Ainsi, la première colonne du
fichier expérimental sera affectée à index[ ]
, puis, par exemple,
si la nième variable cochée obs est le numéro m, les
valeurs de la (n+1)ième colonne seront affectées à ex[m][
]
, qui sera la valeur expérimentale ca[m][ ]
.
Les variables index
et ex
sont dimensionnées
exactement comme leurs sœurs jumelles ind
et ca
, c'est-à-dire : index[NPT]
, ex[NVAR][NPT]
,
NPT
et NVAR
étant les nombres maxima de points et de
variables, respectivement. L'idée sous-jacente est que toute variable d'un
modèle peut être une variable observée expérimentalement.
Dans le cas présent, pourvu que les variables 0 à 4, compris, soient cochées
obs au moment de la lecture, le spectre du III2
sera affecté à ex[4][ ]
, qui pourra donc être utilisée comme
n'importe quelle variable globale (ligne 5) :
//----------------------------------------------------------------------------
1 void fappel
2 {
3 for (int k = 0; k < 4; k++) // boucle sur
le nombre d'expériences
4 for (int i = 0; i < npt; ++i) // boucle
sur le nombre de longueurs d'onde
5 ca[k][i] = p[76+k]*ex[4][i] + (1 -
p[76+k])*p[i];
6
7 if (flag[0]) // recopie des spectres de III-2 et X dans ca
8 for (int i = 0; i < npt; ++i) {
9 ca[4][i] = ex[4][i];
10 ca[5][i] = p[i];
11 }
12 }
//---------------------------------------------------------------------------
Le programme pourrait ne comporter que les trois lignes 3 à 5. Mais il est
pratique de disposer, une fois l'optimisation effectuée, du spectre inconnu X
sous la même forme que les spectres expérimentaux, c'est à dire en regard d'une
colonne de longueurs d'onde. Pour cela, on le recopie dans la variable
ca[5][ ]
, ligne 10. On en profite pour recopier également le
spectre du III2 dans ca[4][ ]
, ligne 9,
simplement pour avoir une table homogène. Cette recopie pourrait être effectuée
systématiquement, toutefois elle n'est pas nécessaire pendant l'optimisation.
C'est pourquoi elle a été rendue optionnelle : elle ne sera effectuée que si la
variable flag[0]
est vraie, c'est à dire si le commutateur 0 (en
haut de la fenêtre Infos) est coché. Noter, dans la fonction
Identification
, la ligne qui rend ce commutateur utilisable, tout
en donnant la légende qui sera affichée dans son info-bulle :
//----------------------------------------------------------------------------
void Identification(Modele& modele)
{
...
flag_text[0] = "Recopie spectres dans ca";
}
//----------------------------------------------------------------------------
flag_text[i]
(i = 0... 9) est un tableau de chaînes de
caractères, vides par défaut, de sorte que le programme ignore la variable
booléenne flag[i]
correspondante, associée au commutateur i.
L'affectation d'une chaîne non vide à
flag_text[i]
rend le commutateur i actif : son info-bulle affiche
la chaîne et vous pouvez le cocher (flag[i] = true
) ou le
décocher (flag[i] = false
) de manière interactive.
Télécharger specMnIV.cpp Télécharger specMnIV.sac Télécharger specIV-III.exp
A. Etant donné l'utilisation non habituelle de Sa dans cet exemple, il importe de contrôler rigoureusement l'enchaînement des opérations :
- Faites lire le fichier specMnIV.sac. Il contient des valeurs de
p[0]
à p[75]
(εX) toutes égales à
103, des valeurs de α égales à 0.5, sauf celle correspondant
au spectre a de la figure
VI.16, fixée à 0.9 et que l'on maintiendra non-ajustable. Ces valeurs
peuvent être utilisées comme valeurs de départ de l'optimisation.
- Assurez-vous que les variables 0 à 4 comprise sont cochées obs avant de faire lire le fichier expérimental specIV-III.exp. Vérifiez que ses colonnes ont été correctement affectées dans l'onglet Données Exp. Assurez-vous également que le commutateur 0 n'est pas coché.
- Une fois le fichier expérimental lu, dé-cochez la case obs de la variable 4 (spectre du III2) afin de ne pas l'inclure dans le calcul de l'erreur.
- Lancez l'optimisation.
- Celle-ci effectuée, revenez en mode Simulation, cochez le commutateur 0, et relancez le calcul.
Les spectres du III2 et de X sont alors disponibles, vous pouvez les tracer comme les spectres ajustés et obtenir directement avec Sa une figure identique à la figure VI.16. Vous disposez également d'un fichier specMnIV.sad contenant toutes ces données de façon directement exploitables.
En cas de problème, vous pouvez utiliser le fichier suivant, contenant le
résultat de l'optimisation :
Télécharger specMnIVopt.sac
B. Vous pouvez vérifier que si on laisse ajuster toutes les valeurs de α, l'optimisation ne converge pas vers une solution unique. On ne peut donc pas dire que le spectre de X soit entièrement déterminé. Toutefois, le choix de 0.9 pour αa, correspondant à un spectre expérimental très proche de celui du III2, semble raisonnable et permet d'affirmer qu'au moins la forme du spectre de X est bien estimée.