[Users-fr] Racines multiples d'un polynôme.

Samuel Gougeon sgougeon at free.fr
Sam 12 Sep 18:38:23 CEST 2015


Bonjour,

Le 28/08/2015 14:11, Lucien Povy a écrit :
> Bonjour,
> Je propose un programme "mroots.sci" donnant les racines d'un polynôme 
> et les multiplicités correspondantes (ou les racines répétées autant 
> de fois qu'il faut).
> Contrairement à Matlab ou Octave, la méthode ne fait pas la moyenne 
> des racines qui semblent
> multiples (j'ai aussi programmé cette méthode, mais elle ne me 
> satisfait pas).
> L'idée est d'utiliser le programme bezout.sci sur le polynôme P(x) et 
> le polynôme dérivé dP(x)/dx.
> Ce programme peut être utile pour les fonctions scilab factors, 
> polfacts, trzeros, pfactors,.... etc, et moyennant une réécriture, de 
> règler en partie le problème posé par pfss.sci quand il y a des 
> racines multiples. Je donne en fichier attaché, le programme mroots.sci.
> Bien cordialement à tous.
> Lucien povy
.
Partageant votre insatisfaction concernant les seuls résultats bruts de 
roots(), laquelle ne permet pas d'accéder aux valeurs et multiplicités 
des éventuelles racines multiples, j'ai écrit en 2010 une première 
version de polyroots() retournant ces valeurs. J'ai retravaillé cette 
fonction au printemps dernier afin d'en améliorer les performances -- 
essentiellement lorsque l'écart entre les racines décroît --, et l'ai 
finalement publiée sur FileExchange en juin : 
http://fileexchange.scilab.org/toolboxes/362000, accompagnée d'une aide 
et d'exemples.

polyroots() est un post-traitement des racines brutes données par 
roots(). Elle met en oeuvre un algorithme d'agrégation.
A mon sens, le principal défaut en est la lenteur, dans la mesure où il 
s'agit d'une macro écrite en Scilab.
Lors de ce travail, j'ai recherché des références équivalentes en Matlab 
ou Octave, afin de comparer les performances, mais je n'ai rien trouvé. 
Si vous avez des références écrites en Matlab/Octave, je serais ravi 
d'en prendre connaissance.

Le problème de la détermination numérique des racines polynomiales est 
"inévitablement" frustrant, puisqu'il est soumis à une incertitude 
relative finale sur la valeur des racines croissant en %eps^(1/N), où N 
est le degré du polynôme traité. La méthode de résolution que vous 
proposez est-elle affranchie de cette contrainte ? Cela ne parait pas 
possible. Comme vous l'écrivez, mroots() est basée sur bezout(). 
Celle-ci n'est pas écrite en langage Scilab dans bezout.sci mais en 
Fortran (et c++) dans SCI\modules\polynomials\src\fortran\recbez.f et 
est compilée, ce qui en fait une fonction rapide, et du coup rend 
mroots() rapide. Le code de recbez.f est bien documenté, et les 
difficultés algorithmiques y sont évoquées.

Les premiers tests avec mroots() m'ont laissé enthousiaste, avant que 
des problèmes importants se manifestent, y compris sur des cas plutôt 
simples. Voir ci-dessous. Je vous laisse en explorer les causes et au 
mieux y remédier.

Quoi qu'il en soit, je pense comme vous que l'accès aux racines 
multiples pourraient/devraient être proposé dans Scilab, même si aucun 
algorithme ne peut en l'occurrence prétendre être absolument robuste et 
mener à des résultats toujours "exacts". A cette fin, roots() pourrait 
proposer de nouvelles options.

Bonne continuation
Cordialement
Samuel Gougeon
-------------
--> p = poly(2:2:30,"x")
  p  =
                                        2 3            4            
5            6            7
   - 4.285D+16 + 7.109D+16x - 5.051D+16x + 2.071D+16x - 5.544D+15x + 
1.034D+15x - 1.397D+14x + 1.399D+13x
                         8             9 10          11         12       
13     14  15
             - 1.051D+12x + 5.940D+10x - 2.514D+09x + 78393952x - 
1747200x + 26320x - 240x + x

--> mroots(p)
  ans  =
     16.
     16.
     16.
     16.
     16.
     16.
     16.
     16.
     16.
     16.
     16.
     16.
     16.
     16.
     16.

// On attend 2:2:30 == [ 2 4 6 8 ... 28 30]




Plus d'informations sur la liste de diffusion users-fr