* fichier : identifi.dgibi ************************************************************************ ************************************************************************ * * soit le polynome du 3eme degre y=a*x*x*x + b*x*x + c*x + d * * on suppose connue la valeur d'une fonction G pour les * abscisses x= 1, 2, 3, 4 et 5 .On recherche les coeffiecients a b c d * de la fonction Y (polynome du troisieme degré) qui ajuste au mieux la * fonction G sur les points connus. * poly est une procédure calculant la fonction Y pour des valeurs de * a b c d données en argument et pour les valeurs expérimentales de x debp poly a*flottant b*flottant c*flottant d*flottant; x=1 ; f1=(a*x*x*x) + (x*x*b) + ( c * x ) + d ; x=2; f2=(a*x*x*x) + (x*x*b) + ( c * x ) + d ; x=3; f3=(a*x*x*x) + (x*x*b) + ( c * x ) + d ; x=4; f4=(a*x*x*x) + (x*x*b) + ( c * x ) + d ; x=5; f5=(a*x*x*x) + (x*x*b) + ( c * x ) + d ; finpro ll; * Nous choisissons la base connue de G corerspondant à un polynome du * 3eme degré avec a=2 b=3 c=4 d=5 . Nous devons donc retrouver ces * valeurs pour a b c d. fG = poly 2. 3. 4. 5.; * on cherche par l'opérateur MOCA les valeurs de a b c d * on suppose un point de départ a=1 b=-1. c=10; d=8. a=1.; b=-1.; c=10.; d = 8.; fdep = poly a b c d ; * calcul de la fonction y pour ces paramètres et pour les abscisses * calcul des "dérivées partielles" par rapport à : a , b , c , d par * différence finie debproc deriv a*flottant b*flottant c*flottant d*flottant fdep*listreel; deri_a= ((poly (a*1.01) b c d) - fdep)/( a*0.01); deri_b= ((poly a (b*1.01) c d) - fdep)/ (b*0.01); deri_c =((poly a b (c*1.01) d) - fdep)/(C*0.01); deri_d =((poly a b c (d*1.01)) - fdep)/(D*0.01); finproc deri_a deri_b deri_c deri_d ; deri_a deri_b deri_c deri_d = deriv a b c d fdep; list ss; er = abs ( ss - sol); * remarque : l'opérateur MOCA cherche à minimiser l'écart en moyenne * quadratique entre la base expérimentale et la fonction F(a,b,c,d), * supposée linéaire en a b c d. Le polynome Y étant bien linéaire * en a b c d, il trouve la "bonne" solution. * * envisageons maintenant que la fonction Y soit y= a + bx + cx**d * * on peut utiliser la procedure ajuste * parametres lineaires a b c * parametre non lineaire d * on peut ecrire la fonction sous la forme: * y = a * f1 + b* f2 + c* f3; * avec f1= 1 f2 = X f3 = x**d debp fct xtab*table p*listreel; tab1=table; tab2=table; x = xtab . 1; * fonction f1 tab1.2 = x; tab2.'F'= tab1; finproc tab2; debproc deri xtab*table p*listreel; tab1=table; tab2=table; tabg=table; tabf=table; tab=table; x = xtab . 1; * df1/dp1 * df2/dp1 * df3/dp1 tabf . 1 = tab1; tab. 'F' = tabf; finproc tab; * fabriquons un cas "experimental" en * posant a =1 b=-6 c=4 d=3 e et en prenant pour base des abscisses x * on va calculer nos "resultats experimentaux" : fobj bx = -6. * X; cxpd= 4*( X ** 3); fobj= ct + bx + cxpd; * preparation des données pour appel ajuste k=1; L=3; xtab=table; xtab. 1= x; tab1=table; tab1.'X' = xtab; tab1. 'F' = fobj; tab1. 'K'= k; tab1.'L'= L; temps; temps; ltrou= p et q; era= abs (ltrou - sol2); * * on peut aussi tenter de resoudre le probleme à l'aide de MOCA * Comme la fonction n'est pas linéaire en fonction du parametre d * la solution fournie ne sera pas la bonne. on utilise le résultat * trouvé pour nous donner une direction de descente le long de laquelle * on cherche un minimun de la "distance" entre Fcalculée et Fobjectif * une approche par itération est necessaire * * procedure pour calculer la fonction ff= fa + fb + fc; finproc ff; * procedur pour calculer les derivees partielles fderb= x * 1; finproc fdera fderb fderc fderd; * procedure pour calculer le critère de distance debproc criter fcalc*listreel fobjec*listreel ; cri= 0.; fin aa; finproc cri; * schema iteratif temps; repeter iter 500; * * on teste la convergence ( coutnouv - coutanc ) / coutanc < 1.e-4 * si ( &iter. ega 1) ; crianc = crii; sinon; cri_conv= ( crianc - crii ) / crianc; crianc= crii; si ( cri_conv < 1.e-4) ; quitter iter; finsi; finsi; * list fobj;list fdep; list fdera ; list fderb; list fderc; list fderd; * list nouvpara; * * recherche le long de la direction donnée par nouvpara - para * imu=1; repe ide 30; fnou= fcal nouvpara x; cria= criter fnou fobj; si ( cria > crii ); si ( imu ega 1) ; si (&ide < 6) ; desc = desc / 10.; iterer ide; sinon; mess ' pas de longueur trouvée le long de la descente'; quitter iter; finsi; finsi; * recherche d'un min par approximation parabilique aa = cri2 + cria - (2.*crii) / 2.; bb= cria - cri2 / 2.; xx = bb / -2. / aa ; iies= xx - 1. ; quitter ide; sinon; si ((imu ega &ide ) et (imu ega 9)) ; finsi; imu=imu+1 ; cri2=crii; crii=cria; finsi; fin ide; fin iter; temps; * * * utilisation de l'opérateur levmar * * il faut définir la procédure feval qui evalue la fonction * à minimiser et qui calcule les derivées partielles * y= aa1 + ( b1 * x ) + ( c1 * ( x ** d1)) ; fderb= x * 1; ia=0; repe baa n; fin baa; finp y l_dy; temps; temps; erc = abs ( a0 - sol2); message ' erreur pour moca ' ermax1; message ' erreur pour ajuste ' ermax2; message ' erreur pour moca ' ermax3; message ' erreur pour levm ' ermax4; si ( (ermax1 + ermax2 + ermax3 + ermax4 ) > 1.e-4); erreur 5; 'SINON'; 'ERREUR' 0 ; finsi; fin;
© Cast3M 2003 - Tous droits réservés.
Mentions légales