Un pot commun pour toutes les machines n°4 : un solveur numérique

Ici, on fait dans le petit, le LCD qui déchire sa race, on y cause même calculatrices quand on est en manque !

Modérateur : Politburo

Répondre
Avatar du membre
dprtl
Fonctionne à 1200 bauds
Fonctionne à 1200 bauds
Messages : 463
Enregistré le : 27 janv. 2013 00:26
Localisation : Strasbourg
Contact :

Un pot commun pour toutes les machines n°4 : un solveur numérique

Message par dprtl »

Hello,

Comme le forum Silicium a une audience bien supérieure à mon blog perso, je publie ici en double mon petit programme de résolution numérique d'équations qui peut rendre service sur les machines qui n'en disposent pas. Il fonctionne de manière assez similaire à la touche [solve] de la HP-15C. Je me permets de ne pas respecter tout à fait le sujet initial, car je n'ai malheureusement pas de programme "historique" à présenter, juste mes propres versions. Voici donc celle que j'ai testée sur Casio PB-1000 :

Code : Tout sélectionner

10 ANGLE1:GOTO40
20 Y=X^3-2*X-5
30 RETURN
40 PRINT"X initial="X;:INPUTX:I=1E-8
50 A=X:GOSUB20:Z=Y:X=X+I:GOSUB20
60 X=A-Z*I/(Y-Z):PRINTA;X:IFABS(X-A)>I THEN50
70 PRINT"F(X)="Z;"X="X
Usage :
  1. éditer le programme pour entrer la fonction sous la forme Y=F(X) à la ligne 20
  2. si besoin, modifier la précision qui est codée en dur à la fin de la ligne 40 (variable I)
  3. lancer le programme
  4. répondre à la question "X initial= ... ?" par exemple avec la valeur 1.
  5. le programme pour PB-1000 affiche A et X à chaque itération, et à la fin le résultat. Attention, dans certains cas particuliers, il se pourrait qu'il n'y ait pas convergence. On utilisera la touche [BRK] dans ce cas.
Le même algorithme implémenté sur Casio FX-602P, avec le programme principal en 38 pas dans P1 par exemple :

Code : Tout sélectionner

Min00 1 EXP 8 +/- MinF 
LBL0 MR00 Min01 GSBP0 Min02 MR00 + MRF = 
GSBP0 - MR02 = 1/x * MRF * MR02 = +/- + MR01 = PAUSE 
Min00 - MR01 = ABS x>=F GOTO0 MR00
Le sous-programme P0 ci-dessous doit contenir la fonction f(x) ; ici [ x^3 - 2x - 5 ] en 10 pas :

Code : Tout sélectionner

Min00 x^y 3 - 2 * MR00 - 5 =
Usage :
  1. entrer la fonction f(x) dans P0
  2. si besoin, modifier la précision, codée en dur au pas 4 (variable F)
  3. taper le X initial, par exemple 1
  4. lancer le programme P1
  5. pause et affichage de la valeur de X à chaque itération ; le résultat à la fin
Voici le lien vers mon article original : https://chipotman.blogspot.com/2019/02/ ... -602p.html. Vous verrez à la fin, en vidéo, que la HP-15C en prend pour son grade, face à une FX-602P bien plus rapide !

Enfin, n'hésitez pas à publier vos propres versions, peut-être avec de meilleurs algos ?

Sommaire des pots communs
Avatar du membre
C.Ret
Fonctionne à 9600 bauds
Fonctionne à 9600 bauds
Messages : 3405
Enregistré le : 31 mai 2008 23:43
Localisation : N 49°22 E 6°10

Re: Un pot commun pour toutes les machines n°4 : un solveur numérique

Message par C.Ret »

Oh! Oui il est vrai que l' HP15C n'est pas rapide, et de loin. Je ne sais même plus comment utiliser son solveur. Heureusement que j'ai le manuel à portée de main. Chaque utilisation nécessite de réviser, je ne me souviens jamais de la procèdure et de l'ordre des arguments à mettre dans la pile.


Bon, j'ai retrouvé ma documentation, c'est en fait très simple:

Saisir la fonction dans la zone programme en y attribuant un label (par exemple [ A ] mais ce peut être un chiffre).
Pour simplifier la saisie de la fonction, SOLVE place une copie de chaque valeur X utilisée dans les quatre registres de la pile.
On peut donc utiliser une formule de Horner pour économiser les efforts: f(x) = x^3 - 2x -5 sera écrit f(x)=(x²-2)*x-5

On lance la détermination de la racine en donnant un intervalle de recherche : par exemple 0 [ENTER] 5 [SOLVE][ A ]
L'HP-15C fait son petit running pendant quelques secondes (j'ai compté environ 20 secondes) et affiche la racine 2.0946

Code : Tout sélectionner

g P/R
f CLEAR PRGM
000-
001-42.21.11   f LBL A        //  Label à utiliser pour SOLVE
002-   43 11   g  x²          //  x²
003-       2      2          
004-      30      -           //  x²-2
005-      20      ×           //  (x²-2)*x
006-       5      5
007-      30      -           //  (x²-2)*x-5
008-   43 32   g RTN          // 
g P/R

Code : Tout sélectionner

0 ENTER
5 SOLVE A
...    running ...
 2.0946
Je me souviens aussi du programme que j'utilisais sur mon SHARP PC-1211 qui lui utilisait une méthode par dichotomie plus adaptée à l'usage de l'époque puisqu'il m'était demandé de trouver les racines dans chaque intervalle de variation déduit de l'étude de la fonction.


Je n'ai pas retrouvé le carnet où j'avais noté mes programmes de 1981 à 1988 pour mon SHARP, j'ai retrouvé celui plus récent de l' HP28S.
Peu importe, le code que j'utilisais en terminale puis en DEUG ressemblait à cela :

Code : Tout sélectionner

1:Y=XXX-2X-5:RETURN

10 "X" AREAD X:GOSUB 1:GOTO 44
20 "P" INPUT "PRES.";P:P=ABS P:IF P>1 LET P=10^-P
30 "S" INPUT "(A,B) A=";A,"B=";B:X=A:GOSUB 1:Z=Y:X=B:GOSUB 1:IF SGN ZY>0 BEEP 1:PAUSE "SIGNES !":GOTO 30
40 X=(A+B)/2:GOSUB1:IF Y<>0 LET A((3+SGN Y)/2)=X:IF ABS (B-A)>P GOTO 40
42 BEEP 3:PRINT A;B;"    X0=";X
44 PRINT X,Y:X=X+1:GOSUB 1:GOTO 44
Il y avait deux choses importantes, l'intervalle était affiché en même temps que le zéro, car trop souvent j'avais 'merdé' en ne recherchant pas la bonne solution, les fonctions étaient souvent périodiques ou avait plusieurs solutions dont seule celle sur le bon intervalle avait de sens dans l'exercice ou le domaine de validité du modèle (je me souvient de cycle de croissance bactériennes et autres oscillations de l'univer…)

La seconde est le test des signes de f(a) et f(b) aux deux bornes de l'intervalle afin de ne pas perdre trop de temps, le programme tourne sans converger si les signes ne sont pas opposés.

Par contre, à l'époque, je n'avait pas envisagé d'utiliser une autre méthode. Par exemple celle de Newton ou qui ressemble fort à celle porposée par dprtl ; cela n'entrait pas dans mes préoccupations, utiliser une méthode automatique sans avoir besoin de tracer les courbes, c'était déjà un bon point d'avance. A l'époque on traçait, consommant du papier millimétré !

D'ailleurs la ligne 10 sert justement à tracer la courbe de 1 en 1. Avoir une idée, même grossière de la fonction évitait pas mal d'erreurs et de soucis :)


Je me souviens que très vite l'HP-28S a remplacé mon SHARP car la possibilité de tracer la courbe et le solveur intégré (avec son menu automatique) est fort efficace. Et plus besoin de se souvenir de l'ordre des paramètres.

Code : Tout sélectionner

[SOLV] 'X^3-2*X-5  [STEQ] [SOLVR] {0,5 [  X  ]
.... X: { 0  5 }      ...
[shift][  X  ]
.... SOLVING FOR X    ....
.... X: 2.09455148154 ....
.... Sign Reversal    ....
1:   2.09455148154
Un peu comme l'est une bonne HP-prime ou autre calculatrice graphique ; où sans programmer, juste en saisissant la fonction on obtient très vite son étude, son graphe et la racine :
HPprime_solver.png
HPprime_solver.png (4.73 Kio) Vu 7405 fois

Enfin, il y a depuis peu de temps une CASIO sur mon bureau.
J'ai trouvé à la page 25 de la Librairie de Programmes (ouvrage livré avec la calculatrice et ses modes d'emploi) un code intitulé "Solving an equation by the midpoint method" qui, contrairement au code de notre très dévoué dprtl utilise l'avantage alphanumérique de la fx-602p et permet, comme ma méthode par dichotomie de spécifier l'intervalle de recherche:

Je retranscris ci-dessous une adaptation personnelle de ce code:
CASIO_fx602p _ midpoint solver programs.gif
CASIO_fx602p _ midpoint solver programs.gif (20.45 Kio) Vu 7384 fois
La fonction ainsi programmée en zone P0, peut comme pour le code de dprtl, être utilisée pour calculer point par point les valeurs de la fonction. Contrairement au BASIC, il n'y a pas besoin d'un sous-programme supplémentaire, bien pensé ces CASIO et la 602 une belle réussite à l'utilisation.
CASIO_fx602p _ midpoint solver usage.gif
CASIO_fx602p _ midpoint solver usage.gif (23.7 Kio) Vu 7383 fois
En prenant le même intervalle [ 0 5 ] , j'observe avec ce code un temps de résolution tout à fait équivalent à l'HP-15C: la méthode par dichotomie étant bien moins efficace que la méthode utilisant la pente globale de la fonction, ceci prouve que le coeur de l' HP-15C bat lentement.
SHARP PC-1211 PC-1360 EL-5150 PC-E500 | Commodore C=128D | Texas Instruments Ti-57LCD Ti-74BASICalc Ti-92II Ti-58c Ti-95PROCalc Ti-30XPROMathPrint | Hewlett-Packard HP-28S HP-41C HP-15C HP-Prime HP-71B | CASIO fx-602p | NUMWORKS | Graphoplex Rietz Neperlog | PockEmul | Sommaire des M.P.O. | Ma...dov'il sapone.
Avatar du membre
dprtl
Fonctionne à 1200 bauds
Fonctionne à 1200 bauds
Messages : 463
Enregistré le : 27 janv. 2013 00:26
Localisation : Strasbourg
Contact :

Re: Un pot commun pour toutes les machines n°4 : un solveur numérique

Message par dprtl »

Ce sujet, initialisé comme "un pot commun", est proche du sujet du Misez p'tit Optimisez n°89 : Algorithme de Brent. Mais l'algo de Brent est bien trop complexe pour être implémenté sur une TI-57 ; alors que la méthode de la sécante est jouable.

Moyennant quelques efforts d'optimisation, j'ai même réussi à trouver les trois solutions de l'équation proposée par C.Ret dans le mpo 89, alors je vous livre ici mon programme :

Image

La fonction f(x) dont on recherche les zéros est codée à partir du pas 27 :

Image

Mode d'emploi de ce programme :
  1. modifier si besoin f(x) à partir du pas 28. Les mémoires 3 à 6 ne sont pas utilisées dans le reste du programme.
  2. stocker le X initial dans la mémoire 0. Par exemple avec [2] [STO] [0]
  3. stocker la précision dans la mémoire 7. Par exemple [1] [EE] [8] [+/-] [STO] [7]
  4. n'oubliez pas de passer en mode radian si f(x) contient de la trigonométrie
  5. vous pouvez éventuellement calculer quelques valeurs de f(x) pour avoir une idée de la forme de la courbe : stocker X dans la mémoire 0, puis lancer [SBR] [1].
  6. [RST] puis [R/S] pour lancer la recherche d'un zéro
  7. le résultat s'affiche à l'écran
Vous trouverez un peu plus de baratin explicatif sur mon blog, et une vidéo qui prouve que ce calcul s’exécute bien sur une vraie TI-57.
Gilles59
Fonctionne à 2400 bauds
Fonctionne à 2400 bauds
Messages : 1602
Enregistré le : 27 oct. 2010 20:46

Re: Un pot commun pour toutes les machines n°4 : un solveur numérique

Message par Gilles59 »

Puisqu'on est dans le "misez petit" une petite remarque sur le programme de C.ret. On peut facilement gagner 2 pas en remplaçant :

Code : Tout sélectionner

LBL1 (MR01 + MR02 ) / 2 = Min00 GSBP0
par

Code : Tout sélectionner

LBL1 MR01 + MR02 = / 2 = GSBP0
Casio FX-502P /602P / 603P / FX180P+ / FX4000P / TI57 / TI66 / TI74 Basicalc / TI95 Procalc / HP12C / HP15C LE / DM41L / HP 30B / HP39GII / HP 48SX USA / 49G / 49g+ / 50G / 50G NewRPL / HP Prime / Oric 1 / Amstrad CPC 6128+ CM14 et MM12 / Alice 32
Gilles59
Fonctionne à 2400 bauds
Fonctionne à 2400 bauds
Messages : 1602
Enregistré le : 27 oct. 2010 20:46

Re: Un pot commun pour toutes les machines n°4 : un solveur numérique

Message par Gilles59 »

dprtl a écrit : 03 févr. 2019 16:18 (…)
Le même algorithme implémenté sur Casio FX-602P, avec le programme principal en 38 pas dans P1 par exemple :

Code : Tout sélectionner

Min00 1 EXP 8 +/- MinF 
LBL0 MR00 Min01 GSBP0 Min02 MR00 + MRF = 
GSBP0 - MR02 = 1/x * MRF * MR02 = +/- + MR01 = PAUSE 
Min00 - MR01 = ABS x>=F GOTO0 MR00
Le sous-programme P0 ci-dessous doit contenir la fonction f(x) ; ici [ x^3 - 2x - 5 ] en 10 pas :

Code : Tout sélectionner

Min00 x^y 3 - 2 * MR00 - 5 =
Bonsoir, en remplaçant PAUSE par "#" qui affiche la valeur "à la volée" sans s'arrêter , j'obtiens les temps d'exécution avec le même exemple et avec X= 1 en entrée :

Casio 602P : 9,8 sec (versus 16s. avec PAUSE)
Casio 603P : 3,6 sec (environ 2,7 fois plus rapide que la 602p)
HP15C LE : Moins d'une seconde même avec des bornes genre 1 à 1000... ( y^x fois plus rapide que la 15C)

PS : j'adore le format des HP Voyagers…
Casio FX-502P /602P / 603P / FX180P+ / FX4000P / TI57 / TI66 / TI74 Basicalc / TI95 Procalc / HP12C / HP15C LE / DM41L / HP 30B / HP39GII / HP 48SX USA / 49G / 49g+ / 50G / 50G NewRPL / HP Prime / Oric 1 / Amstrad CPC 6128+ CM14 et MM12 / Alice 32
Répondre

Retourner vers « Tous les Pockets »