Bonjour,
J'aurais aimé savoir si quelqu'un parmi vous s'y connaissait en Matlab?
Bien cordialement
AR
Bonsoir
je m'y connais en Octave, un logiciel similaire à Matlab, gratuit
peut-être que je peux aider
Je suis débutant en Matlab et je dois ecrire une fonction qui prend en entrée un point x et un vecteur d, et qui calcule le minimum de cette fonction:
où
en utilisant la méthode de Newton.
On me précise aussi qu'il faudra calculer f'(t)=⟨∇J(x+td),d⟩ et f''(t)=⟨Hess(J(x+td))d,d⟩.
Merci par avance
x est sensé être un vecteur (x1;x2) c'est ça ?
De manière générale quand t'as une fonction a deux variables si tu regardes où son gradient s'annule tu vas savoir où se situe l'extrêmum, disons en (a,b).
Pour savoir si c'est un minimum ou maximum, tu calcules (la "dérivé seconde" de ta fonction a 2 variables) c'est-à-dire le Hessien du gradient déjà trouvé.
Tu calcules donc le Hessien et tu appliques ce dernier au point (a,b) et tu vérifie la définie-posivité de ta matrice. Si elle est définie posivite alors ça correspond à une dérivé double positive, donc a une croissance au voisinage droite de (a,b). Donc c'est un minimum.
Si elle n'est pas défini positive c'est l'inverse.
Si c'est semi défini positive il faut augmenter l'ordre de dérivation, et vérifier.
Maintenant toi il définisse f' avec un produit scalaire (parce que f=J(x+dt)), pour être honnête je suis pas suffisamment matheux pour savoir d'où ça sort. Maintenant ça semble être encore plus simple du coup, vu que tu vas travaillé avec non plus 1 vecteur et 1 matrice mais 1 scalaire et 1 vecteur (car produit scalaire).
Sur MATLAB commencé par crée ta fonction (t'as un outil qui te donne le squelette d'un fonction si jamais t'as novice dans l'IDE. Tu met en entrée x1,x2 et d. Tu calcules le J associé.
Ensuite pour f tu dois utiliser dt, c'est le pas des subdivisions de ta variable t ? Ce terme me paraît un peu flou ...
Pour l'instant t'as proposé quoi?
(Désolé mon msg est grv pas structuré mais je suis sur mobile ^^)
Bonjour
@Euhlair, je ne pense pas avoir compris la même chose que toi d'après ce que @arthurhonda a écrit. Je précise:
est une fonctionnelle qui admet un minimum absolu (facile à voir ,i i.e
). Mais ce n'est pas cela qu'on demande (même si il me semble que l'objectif final sera cela).
En entrée il y a un vecteur (x_1,x_2) et un vecteur d=(d_1,d_2) (d comme descente, il s'agit d'une direction de descente) .
On définit à partir de J,x, d la fonction à une variable t :
. C'est
qu'il faut minimiser. Donc ça demande à résoudre
f'(t)=0 que l'on fera avec la méthode de Newton.
En fait je suis assez persuadé que c'est une première étape pour Minimiser J par une méthode de descente. Par exemple à chaque étape on prendra
mais c'est pour plus tard.
Donc si on applique la méthode de Newton à l'équation f'(t)=0
cela va faire intervenir la fonction
et bien entendu f'(t) et f'(t) s'expriment en fonction de et Hess J (comme cela est dit dans l'indication)
C'est aussi ce que j'ai compris @XZ19. Pour ce qui est de la méthode, je l'ai comprise mais je n'ai jamais fait de Matlab et je ne vois absolument pas comment transformer cela en code...
Merci de votre aide
Bon, d'ici quelques minutes je ne vais plus être libre. Mais vu le confinement, si personne ne prend le relais, je serai libre demain.
D'autre part j'ai utilisé Matlab mais je ne l'ai pas chez moi. Donc ça va être compliqué car on ne programme pas sans avoir le logiciel avec soi.
Je ne connais pas Octave par contre j'ai Scilab (gratuit) qui est très très proche
Si tu travailles sur Scilab c'est possible éventuellement. En un premier temps.
Bon c'est OK avec scilab
Avec Scilab un fichier fonction admet une extension .sci (.sce pour éxécutable)
c'est une différence avec matlab.
Pour simplifier le fichier fonction demandé va appeler d'autres fonctions (gradJ , Hesse, g(t) ) que l'on pourrait définir dans d'autres fichiers.sci mais je propose de les mettre dans ce fichier principal pour avoir un seul fichier.
voici la structure
// Miminimisation de f(t)=J(x+ d t ) par la méthode de Newton.
function y=findmin(x,d)
///////////////////////définitions des fonctions grad J , Hess, g ////////////////////////////
compléter
///////////////////////fin - définitions des fonctions /////////////////////
//////////////////////résolution de f'(t)=0 par la méthode de Newton/////////
t1=0; //on fait le choix de t=0 comme valeur initiale
epsilon=10^(-3) ; // précision
erreur=1 ; // erreur initiale pour entrer dans la boucle
k=0 // compteur pour compter le nombre de boucles et stopper si pb ou cv
while (erreur>epsilon ) & (k<20)
..... compléter
end
//////retour du résultat et vérification //////
endfuntion // fin de la fonction
Je te laisse commencer.
Un principe personnel:
ne jamais croire qu'un programme s'écrit d'une seule traite même si on est habitué.
Donc par exemple tu crées dans ta fonction principale
tu définis la fonction grad J et c'est tout. Tu testes et corrige jusque cela si marche bien et ainsi de suite.
En tout cas c'est comme cela que je fais.
Merci beaucoup pour cette réponse, je suis en train d'essayer mais je ne vois absolument pas comment exprimer grad J par exemple ...
J'obtiens pour le gradient de J:
avec
pour la première composante et
pour la deuxième... mais je ne suis vraiment pas sûr
function y= findmin(x,d)
t=2
function gradJ = gradJ(x,d)
v = x+td
gradJ = [2*v(1)+40*v(1).^3-40*v(2)*v(1)-2; -20*v(1).^2+20*v(2)]
end
end
j'essaye mais c'est pas concluant aha
Oui c'est à peu près ça mais attention maintenant aux écritures:
On posera dons sans précision ultérieure v=(v_1,v_2), x=(x_1,x_2), d=(d_1,d_2)...
Alors mathématiquement on écrit
et plus tard la cette fonction étant définit si on veut la valeur de cette fonction au point on cela s'écrira
et c'est tout
Par exemple avec scilab ou matlab quand tu auras bien défini la fonction grad J
qu'on va appeler par exemple gradJ on l'utlisera comme ceci
x=[2, 3]
gradJ(x)
ou encore
si x=[2,3] , d=[4,5 ] et t=3;
gradJ(x+t*d)
voila la premère étape à réaliser.
Ensuite avec la Hessienne pratiquement ça sera la même chose.
donc tu mets ça dans ta fonctio findmin
///////////////////////définitions des fonctions ////////////////////////////
// définition de la fonction grad J
function z=gradJ (x)
z=[-2+2* x(1)+40* x(1)^3-40* x(1)* x(2),-20 *x(1)^2+20* x(2)] ;
endfunction
et pour tester (on va ajouterajouter ceci à retirer ensuite)
x=[1,2]
y= gradJ(x) (puisque y étant l'argument de sortie de findmin il va afficher
gradJ(x)
function y= findmin(x,d)
function z=gradJ(x)
z=[-2+2* x(1)+40* x(1).^3-40* x(1)* x(2),-20 *x(1).^2+20* x(2)];
endfunction
endfunction
J'ai tapé ça mais il me dit qu'il ne connaît pas la fonction gradJ quand je lance (gradJ[1,1])...
En fait tu tapes findmin(x,1) ( 1 pour d pour l'instant ça joue aucun rôle)
Attention avec scilab il faut recompiler la fonction à chaque fois que tu la modifie.
En fait voilà le fichier findmin.sci (provisoire )
// Miminimisation de f(t)=J(x+ d t ) par la méthode de Newton.
function y=findmin(x,d)
///////////////////////définitions des fonctions ////////////////////////////
// définition de la fonction grad J
function z=gradJ (x)
z=[-2+2* x(1)+40* x(1)^3-40* x(1)* x(2),-20 *x(1)^2+20* x(2)] ;
endfunction
/////////////////////////////
y gradJ(x)
endfunction
*************************
ensuite
ensuite dans l'editeur sci note tu cliques sur le triangle compiler et exécuter.
ça veut dire qu'il va compiler et si il n' y pas d'erreur il findmin sera une fonction qu'il reconnaitra.
On va la teste maintenant sur la console il faut 2 argument x et d (d on mets n'importe quoi pour le moment
et x est un vecteur
donc taper
x=[1,2]
puis findmin(x,1) (ici d=1)
donc normalement il va sortir grafdJ(x)
function y= findmin(x,d)
function z=gradJ(x)
z=[-2+2* x(1)+40* x(1).^3-40* x(1)* x(2),-20 *x(1).^2+20* x(2)];
endfunction
x=[1,2]
y=gradJ(x)
endfunction
Je ne vois pas la différence avec ce que j'ai, moi rien ne ressort de ce code
tu as mis un point à x(1) je vois pas trop l'intérêt je crois pas que c'est une faute mais retire le pour le moment.
sinon c'est bon
donc ton problème est
1 dans la compilation qu'est ce qu'il dit?
les puissances en Matlab je crois qu'il faut un point
Quand je compile il me dit qu'il connait pas gradJ ou alors il ne me retourne rien
Bon je crois que tu n'as pas compris
le fichier findmin.sci c'est un fichier fonction. la fonction gradJ est une fonction définie inline (c'est à dire qu'elle est définie à l'intérieur de la fonction findmin)
donc scilab après compilation de la fonction findmin connaitra findmin comme nouvelle fonction mais ne connait pas ce qu'il y a à l'intérieur.
Alors pour l'instant 2 étapes seulement
compiler et exécuter findmin (cliquer sur le triangle c'est fait ? ) et dit moi la réponse
de scilab sur la console.
Je vais réessayer et vous tiens au courant.
Par contre, quand je définis ma fonction J tout au début j'ai toujours le même message d'erreur qui s'affiche "not enough input argument", la fonction marche mais j'ai ce message d'erreur ...
Attention au vocabulaire car comme ça sur internet je ne comprends pas
"Je définis la fonction J" ne je comprends pas parce que on ne l'a pas défini.
D'autre part il y a bien un message d'erreur mais comment je peux comprendre l'origine ?
C'est à la compilation-(exécution)
où après sur la console quand tu exécutes l'instruction .
x=[1, 2] puis findmin(x,0) ??
Moi comme ça je ne peux pas deviner.
parce que si tu as écris exactement ce que j'ai mis tout marche.
(personnellement en // je l'ai fait).
function [pos,val] = Newtonmin(prec,x,d) %prec = précision de l'approximation
function z1 = Jfst(t)
X = x + t*d;
z1 = (2*X(1)+40*X(1).^3-40*X(1)*X(2))*d(1)+(-20*X(1).^2+20*X(2))*d(2);
end
function z2 = Jsc(t)
X = x + t*d;
z2 = ((2+120*X(1).^2-40.*X(2))*d(1) - 40*X(1)*d(2))*d(1)+(-40*X(1)*d(1)+20*d(2))*d(2);
end
t = 0;
while Jfst(t) > prec
t = t - Jfst(t)./Jsc(t);
end
pos = t;
X = x+t*d;
val = (X(1)-1).^2 + 10*(X(1).^2-X(2)).^2;
end
J'ai essayé de faire un peu différemment mais quand je compile j'ai plusieurs erreurs:
- Not enough input arguments.
- ligne 3: X = x + t*d;
- ligne 11: while Jfst(t) > prec
J'espère être plus clair...
Bonjour,
Désolé de vous déranger.
Avez-vous pu regardé un peu dans le code ce qui clochait svp?
Arthur
Bon moi ça tourne sauf que je n'ai pas ici le temps de vérifier ce que calcule ton programme.
Avec un essai il retourne pos=0 mais pos c'est t (d'ailleurs je vois pas pourquoi cet argument de sortie tu l'appelles pos)
Donc il faut vérifier ligne par ligne.
Il aurait mieux valu faire comme j'ai dit. Programmer pas à pas et vérifier à chaque fois.
Vous devez être membre accéder à ce service...
Pas encore inscrit ?
1 compte par personne, multi-compte interdit !
Ou identifiez-vous :