Posté le 21/10/2020 11:13
Planète Casio v4.3 © créé par Neuronix et Muelsaco 2004 - 2024 | Il y a 167 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements
Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd
Citer : Posté le 21/10/2020 11:23 | #
La calculatrice apprécie tout ce qui passe à e^(b ln a) en complexes, donc tous les a non nuls vont passer, y compris (-27)^π pourvu que tu sois en complexes.
Si tu es en réels, le résultat n'est accepté que si c'est un réel : soit a>0, soit b est un entier.
Si tu es en complexes, le résultat est accepté dès qu'il existe : pour tous a≠0 et b.
Quand a=0, le calcul est valide seulement si b>0. 0^0 est refusé alors que c'est défini comme 1 en général parce que c'est ce qui se comporte bien.
Citer : Posté le 21/10/2020 13:04 | #
Ah d'accord merci énormément pour ces explications
Si je récapitule bien, voici le code pour tester si a^b existe (en mode Real) :
A Or B⇒Not A And B>0 Or (A⇒Not ImP A^B
Et ne donnera jamais d'erreur je pense
Merci !
Citer : Posté le 21/10/2020 13:37 | # | Fichier joint
Ça m'a l'air correct. Une autre variation pour avoir le résultat en réels dans Ans serait
si j'en crois ce diagramme réalisé en 25 secondes.
Edit : Ça oublie le cas A=0, B<0.
Citer : Posté le 21/10/2020 15:11 | #
Merci pour ton aide !
En utilisant ta méthode, en rajoutant le cas A=0, B<0 et en optimisant au max (j'espère ) j'obtiens ceci :
C'est bien compact tout ça et "⇒" me sert juste à enlever 3 parenthèses et à remplacer le "And"
Et puis, si jamais il y a une parenthèse à la fin de l'expression ça ne m'envoie pas d'erreur syntaxe donc tant mieux haha
Ceci sera utilisé dans un programme que je suis en train de commencer, et je vais bientôt faire une annonce de projet (parce que le programme m'a l'air faisable mais très très long....). On va voir ce que ça va donner
Édit :
Mince on a complètement oublié ce cas-ci : (-27)^(1/3)=-3........ Je regarde si on peut en tirer une condition particulière ou non
Et chose encore plus étonnante : le résultat peut changer en fonction du mode dans lequel on est ! Je m' explique : si on est en mode imaginaire (a+bi), (-1)^(1/3)=.5+sqrt(3)/2 tandis qu'en mode Real on obtient bien évidemment -1 donc ma première méthode en utilisant la partie imaginaire n'est pas bonne non plus bon je fais une petite pause haha
Citer : Posté le 22/10/2020 14:27 | #
Hmm alors si tu utilises ⇒ je garantis pas que la valeur de Ans soit 0 quand le test est faux.
Sinon effectivement je me suis planté dans mon énumération de cas initiale, je n'a pas réalisé que la calculatrice acceptait aussi les racines de nombres négatifs.
Sauf qu'en réel elle renvoie parfois des résultats faux, ma Graph 75+E vient par exemple de me sortir sans broncher que (-27)^(0.4) = 3.737, ce qui est complètement impossible puisque 3.737^2.5 = 27 et non pas -27. En complexe ça renvoie le bon résultat, et 3.737 est le module de ce résultat. La calculatrice a sans doute cru que le résultat était réel et renvoyé le module sans réaliser que la partie imaginaire était non nulle.
Donc je crois que la bonne chose à faire est de commencer par faire le calcul uniquement en complexes pour éviter ces résultats faux.
Citer : Posté le 29/10/2020 18:38 | #
Par contre je pense que ton exemple est faux (je suis peut-être à côté de la plaque, mais) il me semble que (-27)^(0.4)=5*√(-27)^2 ce qui fait bien +3.737 (étant donné que dans n'importe quel cas de priorité des opérations, on doit qd même mettre au carré ce qui donne un nombre positif). Lorsqu'on fait le contraire : 3.737^2.5=√3.737^5 et là nous avons 2 solutions : ±27 car la racine carrée fait apparaître 2 solutions
J'ai bien testé le code de mon précédant message et on obtient bien Ans=0 (que ce soit la première ou la 2e condition qui renvoie faux).
Citer : Posté le 29/10/2020 19:05 | #
Right, bien vu pour l'analyse. En fait ça revient à un problème que j'ai réalisé mais pas mentionné la dernière fois, qui est la multiplicité des racines complexes. Toute racine complexe a ses solutions multiples et on a simplement la définition canonique pour attribuer une valeur numérique à (-27)^0.4 alors qu'il y a plusieurs racines. Par contre, la racine canonique est bien complexe.
Citer : Posté le 29/10/2020 20:18 | #
Ouah merci pour le super site !
J'ai essayé pas mal d'exemples et je pense avoir trouvé un "truc" : prenons comme exemple A^B en restant dans le problème des (-27)^.4 (j'ai pas essayé pour voir si mon astuce fonctionne pour la A positifs et B entiers mais passons). On calcule du coup A^B en mode complexe (appelons cette valeur C). Ce qui m'intéresse est l'argument de cette valeur (=θ) car c'est grâce à ça qu'on va pouvoir obtenir toutes les racines imaginables (et imaginaires aussi du coup ). Appelons cette valeur T. Le truc, c'est que j'ai remarqué que (en tout cas si C possède une partie imaginaire) |C|*e^(3T) est toujours aussi une racine (avec les cas que j'ai testé), où |C| est le module de C. On remarquera de nouveau que |C|*e^(5T) est solution aussi etc etc
On peut donc grâce à cette technique, non seulement obtenir toutes les racines, mais en plus ne les obtenir qu'une et une seule fois ! Il suffit d'arrêter "l'incrémentation" de l'argument lorsque sa valeur revient à la même chose que celle de base (ex T=2+2π=2) et pendant la boucle (où on fait à chaque fois argument+2T) on teste la nouvelle valeur de l'argument pour voir si elle est vaut 0 ou π (autrement dit ce le nombre avec le nouvel argument n'a plus de partie imaginaire), et si c'est le cas cela vaut dire qu'une des racines est réelle et donc par conséquent que A^B n'a pas de condition d'existence dans les réels !
J'ai écrit ça sur le tas donc excuse-moi car ça doit être assez brouillon mais je pense que je suis bon (ou sur une piste ).
Édit : il y a peut-être moyen de faire plus simple mais je ne sais pas trop.... En tout cas ce que je peux affirmer c'est que l'argument sera (plutôt "pourra" car il y a plusieurs racines donc plusieurs arguments possibles) toujours égal à B*π
Citer : Posté le 29/10/2020 20:40 | #
Ce que tu as (re)découvert s'appelle parfois la formule de De Moivre, mais ça ne marche que pour les exposants rationnels que tu peux voir comme des racines. Si ton exposant est irrationnel ça ne te permettra pas de t'en tirer parce que l'exponentielle n'obéit pas aux mêmes règles.
En fait tout ça est lié au problème du logarithme complexe qui est un objet assez curieux, assez en tous cas que mon prof de maths en prépa refuse catégoriquement qu'on l'utilise.
Si ta base est a=re^(iθ), ses logarithmes sont les ln(r)+i(θ+2kπ) pour k entier. De là tu peux calculer toutes les valeurs de a^b comme e^(b ln a). En supposant dans un premier temps que b est réel (ce qui est déjà pas mal), la partie imaginaire de b ln a est bθ + 2kbπ. Tant que b est rationnel, l'ensemble {2kbπ : k entier} ne couvre qu'un nombre fini de réels modulo 2π et tu obtiens un ensemble fini de racines (si b s'écrit p/q sous forme irréductible, q racines). Mais si b est irrationnel {2kbπ : k entier} couvre tout ℝ/2πℝ et l'ensemble des valeurs de e^(b ln a) est un cercle tout entier du plan complexe.
Je pense que c'est pour ça qu'il y a un résultat "canonique", celui qui est pris avec k=0. Et c'est ce résultat avec k=0 qui te donne "la" valeur de (-27)^(2/5) = e^(2ln(-27)/5) = e^(2ln(-27)/5 + 2iπ/5) = sth·e^(2iπ/5) qui n'est pas la racine réelle.
Sans être une énorme révélation, peut-être que ça peut aider de préciser ce que tu veux savoir exactement avec ton programme en tenant compte de ce comportement complexe.
Citer : Posté le 01/11/2020 18:50 | #
Oui dit comme ça c'est vrai que je passe un peu pour un idiot... ^^'
En effet j'utilise la formule de Moivre, mais au lieu "d'augmenter" l'angle par 2, je le fais par 3 pour être sûr de tomber sur un argument valable (voir b=1/4).
Le problème revient donc à trouver un naturel N qui vérifie cette condition :
Pour le moment j'ai réussi à définir une méthode pour cette condition mais elle utilise une boucle (elle s'arrête lorsque B(2N+1) revient à la valeur B). Malheureusement celle-ci prend énormément de temps si B possède des décimales de + en + petites (ex B=0.0001) vu que ce que fait la boucle c'est lire tous les arguments possibles jusqu'à trouver celui qui est nul ou =±π (le problème reste toujours pour les B irrationnels comme ln 2 ou π... ). Je suis en train d'essayer de trouver des conditions (sans boucle) qui feraient le même taf que cette boucle pour un résultat "instantané".
En tout cas je voulais te remercier pour toute ton aide déjà fournie (aussi bien que future )
Citer : Posté le 01/11/2020 20:34 | #
Je ne te suis plus trop là - en partie parce que je ne sais pas ce que tu essaies de faire. L'existence de a^b est facile dans les complexes, le fait qu'il y ait souvent plusieurs solutions quand b est un rationnel négatif n'y change pas grand-chose. Il faudrait remettre le tout dans le contexte de ton programme.
Citer : Posté le 02/11/2020 12:59 | #
Ça me fait super plaisir que tu m'aides autant
Le message ici est un pavé, alors si tu ne lis pas la 2e partie il n'y a aucun problème (surtout qu'elle est fausse ).
Ah autant pour moi (je dois dire que tu m'as aussi un peu perdu avec le logarithme complexe mais je pense avoir plus ou moins compris - en tout cas, l'essentiel - que quand B est irrationnel - et A négatif - la réponse sera toujours complexe. Je ne suis qu'en première année à l'unif donc la partie du "plan complexe" ou "surface de Riemann" je ne sais même pas de quoi on parle...).
Donc je clarifie mon raisonnement en reprenant depuis le début (comme ça moi aussi je pourrai me comprendre ) :
Mon objectif étant de trouver un code me permettant si oui ou non la calto pourra trouver une réponse réelle à A^B sans me donner de message d'erreur. Pour ça, une chose qu'on pourrait faire : balayer tous les résultats complexes de A^B jusqu'à :
1- trouver un résultat qui n'a pas de partie imaginaire (donc A^B existe dans les réels);
2- avoir parcouru toutes les réponses possibles et être revenu à la toute première réponse.
Pour toutes ces réponses, il n'y a que l'argument (=θ) qui change de valeur, ce sera donc la seule valeur à laquelle on va s'intéresser. Et je peux affirmer (sûrement de nouveau un théorème que je ne connaissais plus - ou la formule de Moivre ) qu'une des réponses de A^B aura θ = B*π. Nous avons donc le premier θ, il faut encore balayer tous les autres (en prenant des multiples impairs de B*π : 3Bπ, 5Bπ, ..., (2N+1)Bπ. Impairs car comme dit juste avant 2Bπ ne donne pas une valeur acceptable quand B=0.25). Si durant ce balayage on tombe sur un θ = kπ, k ∈ Z, on arrête tout et le programme nous dit que A^B existe bel et bien dans les réels, autrement on arrête lorsque nième argument θn = (2N+1)Bπ = Bπ = θ0 (= tout premier argument).
En résumé, si ∃N ∈ N : (2N+1)*B*π = k*π où k ∈ Z ⇒ A^B ∈ R\{0}.
En simplifiant cette expression : si ∃N ∈ N : (2N+1)*B ∈ Z ⇒ A^B ∈ R\{0}. Et pour valider cette "condition" il faut juste que (2N+1)*B soit entier, autrement dis qu'il n'ait pas de décimale. D'où mon dernier commentaire
J'espère que c'est bien plus clair maintenant (en tout cas ça l'est pour moi haha ), et désolé pour ce pavé ^^'. Le seul problème maintenant c'est le temps que ça prend pour trouver si un N vérifie la condition, car tout ce que j'ai fait pour le moment c'est une boucle qui balaye chaque θ... Donc soit j'essaie de transformer cette condition-ci afin de trouver "direct" le N, soit je vais devoir trouver une tout autre condition.
Ceci était juste un essai, mais ne fonctionne pas comme voulu :
En parlant de "tout autre condition", j'aurais déjà une idée (dis-moi si je me trompe car j'ai l'impression d'aller un peu vite) : on doit trouver un entier (2N+1)*B, donc nécessairement sin((2N+1)*B*π)=0. Ceci m'intéresse tout parliculièrement car on a une égalité, non plus une appartenance à Z ou autre. Je vais donc développer (c'est pas vraiment ce terme là que j'utiliserais mais bon tant pis) :
sin((2N+1)*B*π)=0
⇔(2N+1)*B*π = arcsin(0)
⇔(2N+1)*B*π = 0
⇔N = -1/2 ⚠Nouvelle condition : B≠0 et en plus N ∈ N...⚠
Ce qui est totalement faux... Sûrement à cause du fait que je perds le paramètre k ∈ Z quand je fais arcsin(0)=0.... Bref je suis à court d'idées pour le moment, donc je fais une petite pause... (encore )
Citer : Posté le 02/11/2020 21:01 | #
Mais qu'est-ce que tu veux faire avec les racines non canoniques ? Elles n'obéissent pas aux règles sur les puissances de réels. Typiquement avoir (-1)^0.4 = 1 ça ne t'avance à rien, tu as 1^2.5 = 1 et tu te retrouves avec (a^p)^q ≠ a^pq. Je ne vois honnêtement pas comment ce cas peut t'intéresser.
L'argument des racines est B(arg(A)+2kπ) (pour k entier). Si A est positif, tu annonces qu'un certain k donne 2Bkπ = Bπ, ce qui ne risque pas d'arriver (tu n'as pas de k=1/2). Ici les arguments sont exactement les multiples de 2Bπ. Exemple : B=0.4, les racines ont pour argument 0, 2π/5, 4π/5, -2π/5 et -4π/5. Ce sont tous des multiples de 2Bπ.
Tu supposes (sans le réaliser peut-être vu comment tu décris le cas B = 0.25) A négatif, auquel cas B·arg(A) = Bπ vient s'en mêler et k=0 fournit le témoin que tu cherches. C'est d'ailleurs la solution canonique, et pour moi c'est la seule à observer (ce qui trivialise la décision, tu noteras - les puissances non-entières n'auront jamais de racines canoniques réelles quand A < 0).
Ta méthode repose fondamentalement sur la rationnalité de B. Avec la représentation irréductible B = p/q les arguments des résultats sont les 2kpπ/q (plus constante si A est négatif) et donc tu as la garantie qu'il y a un nombre fini d'arguments possibles puisque les valeurs se répètent sur un cycle de longueur q.
Mais comme je l'ai dit, si B est irrationnel, il y a une infinité d'arguments différents. Si tu regardes les πarg(a) + 2Bkπ pour k entier, tu ne trouveras pas k₁ ≠ k₂ avec des arguments égaux modulo 2π, parce que la différence sera 2B(k₂-k₁)π et B(k₂-k₁) ne peut pas être entier puisque B est irrationnel. Ta boucle peut donc tourner un très long moment avant que les erreurs de calcul ne donnent l'illusion que le résultat est atteint.
(Erratum : j'ai dit à un moment que tous les arguments étaient possibles si B est irrationnel. C'est faux. Il y a une infinité dénombrable d'arguments possibles oui, mais ℝ/2πℝ est indénombrable donc ça ne couvre manifestement pas tout.)
La conclusion de tout ça c'est que cette formule ne marche que pour B rationnel et A < 0. Pas si vite !
Supposons B rationnel et A < 0. Tu notes B = p/q sous sa forme irréductible. L'ensemble des arguments de racines c'est (1+2k)Bπ, tu en veux un qui soit ou bien π ou bien 0, c'est-à-dire (1+2k)p/q entier. La question est donc de savoir s'il y a un multiple de q dans les multiples impairs de p. Tu remarques par exemple que c'est le cas pour 2/5 (2×15 ≡₅ 0) mais pas pour 1/4 (1×n ≡₄ 0 → n pair).
Ici, il faut réfléchir quelques instants mais l'idée qu'il faut voir est si 2p et q sont premiers entre eux. S'ils le sont, alors en vertu de la relation de Bézout les multiples de 2p couvrent tout ℤ/qℤ, donc les multiples impairs de p aussi (translater ℤ/qℤ de p ne change rien aux valeurs couvertes), et le tour est joué. S'ils ne le sont pas, alors leur PGCD est 2, p était impair et q était pair, ce que tu peux écrire p = 2p'+1 et q = 2q'. Ton multiple impair de p qui est multiple de q s'écrit soudain (1+2k)(2p'+1) = u(2q'), ce qui est impossible par parité.
Conclusion : pour B = p/q irréductible et A < 0, il y a une racine réelle si et seulement si 2p∧q = 1.
Bien sûr ce calcul repose sur la représentation rationnelle de B et le fait que cette fraction est irréductible... mais c'est ce qu'une preuve constructive de rationalité de B est. Si tu n'as pas ça alors tu ne peux pas être sûr que les prérequis pour ton algorithme sont réunis. Ce qui amène, doucement mais sûrement, à la question subtile de déterminer si la valeur que tu as dans ton programme est rationnelle.
Mais encore une fois je ne sais pas ce que tu veux faire avec des racines réelles qui ne sont pas "la" puissance A^B.
Eh oui, c'est pour ça. Si j'enlève la ligne du milieu l'erreur est encore plus évidente.
Contrairement aux apparences premières c'est bien un problème d'arithmétique.
Citer : Posté le 03/11/2020 14:33 | #
Eh bien en fait, au début on ne cherchait que des cas de conditions d'existence simples (sur A^B) comme dire que 0^(-1) est impossible. Est arrivé un problème de taille (pour moi en tout cas), que faire lorsque A<0 et B réel (avec une partie décimale) ? Je n'avais pas trouvé de lien entre les cas valides ou non, alors quand tu m'as montré le site de WolframAlpha (représentation graphique de plusieurs racines complexes), je me suis (très) bêtement dit "suffit de balayer toutes les racines"...
En fait je n'en fais absolument rien des racines complexes (seul une racine réelle m'intéresse). Malheureusment, en mode imaginaire, la calto envoie une racine complexe alors qu'une réelle existe (mais il n'y en a pas forcément une réelle, voilà pourquoi je me suis dis que j'allais passer pas les complexes)... Je ne sais pas trop si j'ai réussi à te répondre mais j'espère.
En effet, inconsciemment. Je m'explique : la seule condition que ce code ne prennait pas en compte...
...c'était justement A<0 et B réel (avec une partie décimale). Donc je dois dire que je n'ai que regardé pour ces valeurs "précises".
Je me trompe peut-être, mais si A est négatif et si A^B possède bien une réponse dans les réels, alors l'argument θ est nécessairement égal à π non ? (À moins que je n'ai pas compris... Du coup k serait ≠0 ?)
Eh ben, tout ça est bien joli, conci est clair (en gros quelque chose que je n'aurais pas trouvé moi-même ).
Mais "∧" veut bien dire PGCD, et non produit vectoriel ? (Je suis - quasi - sûr que non car un produit vectoriel de 2 scalaires n'a aucun sens...) Il y a quelque annotations mathématiques que je n'ai pas comprises comme "1×n ≡₄ 0", mais vu que j'ai compris le français je pense que c'est le principal .
Maintenant il ne resterait plus qu'à trouver quelque chose sur les irrationnels. Mais toute première chose : la calculatrice arrondi ces irrationnels !... En supposant qu'elle les arrondissent au max avec 14 chiffres significatifs (comme la valeur de π), on peut par conséquent transformer n'importe quelle valeur de B en p/q avec p et q entiers (encore faut-il que cette fraction soit simplifiée au max, ce qui je pense reste faisable avec un petit bout de code en plus) Alors oui, je pense que ce n'est pas très légal, mais ça à l'air de marcher .
Je viens tout juste de tester avec π (le seul test jusqu'à présent) :
donc nous avons p = 31415926535898 (14 chiffres significatifs de π donnés par la calto) et q = 1E13. On simplifie la fraction par 2, et le dernier chiffre de p devient 9, donc on ne peu pas simplifier plus (j'ai pas envie de tout réécrire haha). nous cherchons maintenant le PGCD de 2p/q, où 2p = 31415926535898 et q = 5E12. Leur PGCD vaut 2, donc (quand A<0 et) quand B = π, l'exponentielle ne donne pas de réponse réelle \o/
Ça m'a l'air beaucoup trop bien comme formule, mais comme le dit ma signature lorsque l'on trouve une solution, un nouveau problème arrive : Les valeurs 2p (ou même juste p) et q sont bien trop grande pour être utilisées dans la fonction GCD() de ma Casio qui m'envoie une erreur argument carrément... Je pourrais du coup utiliser l'algorithme d'Euclide pour calculer ce PGCD, mais de nouveau un problème : une boucle (ce n'est pas forcément un problème en soi, c'est juste que j'aurais préféré des "simples" conditions...). Je me pencherais plus dessus demain
P.S.
Tu as dû très certainement le remarquer, mais ça fait plusieurs fois que je te parle de "simples" conditions, et je pensais utile de te dire pourquoi. Le programme que je suis en train de faire utilisera une fonction insérée par l'utilisateur, et j'ai besoin de connaître les conditions d'existence de cette fonction pour ne pas obtenir d'erreur (et que l'utilisateur ne s'ennuie pas à devoir chaque fois les mettre lui-même). Il est donc possible qu'il y ait plusieurs conditions, et celles-ci sont toutes stockées dans une String (sous forme de "cond1⇒cond2⇒cond3"). Dans ce cas-ci il est donc assez difficile de mettre une boucle dedans...
Citer : Posté le 03/11/2020 15:37 | #
Aha donc voilà ce que j'attendais de savoir. Honnêtement je comprends pas pourquoi la calculatrice sort les racines réelles quand le résultat est complexe. Mais bon je peux admettre que tu laisses l'utilisateur se démerder avec ce résultat et vérifier que la valeur lui convient.
Par contre c'est 100% du calcul formel ce que tu fais là, si on commence à faire dépendre A et B de variables tu ne pourras quasiment plus rien décider...
Si A est négatif son argument est π oui. Mais A^B peut avoir une racine réelle positive. Il n'y a qu'à voir (-1)^0.4 dont la racine réelle est 1 (d'argument 0). k=0 te fournit la racine complexe d'argument Bπ dont tu disais avoir besoin pour initialiser ta recherche, pas la racine réelle quand elle existe. (Même si je pense que si la racine réelle existe pour k ≠ 0 elle n'est pas intéressante.)
Oui donc "∧" c'est une notation pour le PGCD en arithmétique, tout comme "∨" est une notation pour le PPCM (les symboles sont souvent réutilisés). Pour "≡₄", le "≡" signifie congru et l'indice est souvent utilisé pour caser le modulo. Il faut comprendre le "1×n ≡₄ 0" comme "1×n multiple de 4".
Non seulement ce n'est pas légal mais en plus les résultats que tu auras seront insensés. D'abord il est facile de voir que la majorité des irrationnels te donneront ce résultat. Comme les irrationnels ont un développement infini en base 10 (sinon il y aurait une fraction triviale), si tu prends n'importe irrationnel r (disons 0 ≤ r ≤ 1 pour simplifier) tu vas toujours de retrouver avec p = r·10^14 et q = 10^14. Et là, comme q est divisible par 2^14, soit tu pries pour que les décimales de r donnent un résultat divisible par 2^14 (une propriété qui apparaît et disparaît comme le vent si tu rajoutes des décimales et qui n'arrive presque jamais), soit après normalisation q sera toujours pair et son PGCD avec 2p sera 2. Conclusion tu auras quasiment toujours un PGCD de 2.
Bien sûr cette analyse marche avec tous les nombres. Donc si je balance une constante avec un développement en base 10 un poil long, ton programme pensera qu'il n'y pas de racine réelles à cause de problèmes terre-à-terre de représentation en BCD. En fait si tu tires des décimales au hasard, tu as 99.99% des nombres entre 0 et 1 qui ne seront pas divisibles par 2^14 et pour lesquels tu concluras à l'absence de racines réelles.
Ce qui est vraiment dommage c'est que des fractions toutes gentilles qui ont des développements infinis en base 10 il y en a beaucoup. Prends 1/3, par exemple. Tu te retrouves avec p = 33333333333333 et q = 1e14, c'est irréductible, q est pair, 2p∧q = 2, pas de racine réelle. Alors que la racine cubique est une bijection sur R. Tu te rends compte à quel point c'est faux ? ^^"
Et puis je te parles pas de la différence entre :
• 31415926535898/1e13 = π
• 314159265358979/1e14 = 4·atan(1)
et autres erreurs de calculs qui vont venir gêner tes résultats.
Donc avant même de parler de la fonction GCD() il faut prendre un moment pour voir que détecter la rationalité c'est pas un plan viable.
Citer : Posté le 16/11/2020 16:56 | #
Désolé pour ce long moment sans réponse, mais je devais faire le point et revoir tout depuis le début pour être sûr de ne pas dire n'importe quoi (et essayer de faire un maximum de choses légales ).
Donc je reprends le contexte dans lequel on se trouve : A négatif et B réel avec une partie décimale (pour A^B). Tu m'as montré qu'il fallait démontrer que B pouvait s'écrire sous la forme p/q (forme irréductible) et que 2p∧q = 1 (qui représente le PGCD) pour que l'exponentielle est - au moins - une réponse réelle. Et ces 2 conditions doivent être repectées. Je vais décomposer ces conditions en plusieurs étapes :
1. B peut s'écrire sous la forme p/q (pas nécessairement irréductible)
Peut être encore "facile", si on demande explicitement à l'ulisateur d'utiliser la fonction racine Nième (ex : 5*√2^2, où p/q = 2/5). Mais ce genre de cas est très rare, car le principe d'un fonction est d'insérer des "x" , donc x^(0.3*x+1) deviendrait très problématique... Je n'ai vu qu'une seule solution à ce problème : créer un programme qui retournera les valeurs de p et q séparément, ce qui me paraît une solution assez viable, mais seulement si on s'assure qu'on ne convertit pas sans s'en rendre compte des irrationnels "purs" (la calculatrice considère équivalent 80143857/25510582 et π, et je pense préférable d'éviter ces réponses invoulues). Voici donc la plus grosse cause de ce message tardif : je viens tout juste de finir (et publier) un programme capable de faire ce travail-là Number to Fraction. J'utiliserai le Programme 1 (mode réel) - autrement appelé R2FRC - et la partie la plus intéressante d'en retenir est qu'il répond très bien (sur des tests que j'ai fait, donc constatation non-absolue) : ne trouve pas de réponse avec comme entrée "ln 2", "sin 3" ou encore "π", mais bien pour "12345/987654". Il m'a l'air assez fiable (plus de tests seront sûrement nécessaires).
2. Si p/q est trouvé, trouver sa forme irréductible.
Eh bien cette étape-ci est quasi instantanément passée : si on considère que le programme est fiable à 100% (ce qui me paraît à démontrer ), les couples p et q renvoyés seront toujours irréductibles.
3. Si p/q trouvé et irréductible, 2p∧q = 1.
Cela reviendrait à dire que q n'est pas multiple de 2, encore autrement dit que q/2 possède une partie décimale.
Peut-être vais-je de nouveau beaucoup trop vite (encore une fois...) ? Mais tout ceci me paraît plus ou moins correct
Citer : Posté le 17/11/2020 00:55 | #
D'abord quelques remarques sur ton programme. J'ai analysé que R2FRC parce que ça m'a déjà pris un bon moment et qu'il y a déjà pas mal de problèmes potentiels.
Pourquoi pas juste Frac Ans÷(E3+Int Ans) ?
Cette condition est bizarre parce que si tu multiplies ton réel par une puissance positive de 10 (ce qui ne change pas le caractère irrationnel) la valeur de C diminue et donc la boucle dure plus longtemps. En plus les grands nombres sont casse-pieds à représenter comme des entiers, donc on sait d'emblée que ce sera facile à abuser.
• π×10¹³ renvoie 3.141592654·10¹³/1. Le numérateur n'est même pas un entier !
• Ça marche avec tous les multiplieurs plus grands évidemment.
Les entiers sur la calculatrice s'arrêtent autour de 10¹⁴, au-delà tu n'as plus la précision exacte. C'est exactement le moment où les fonctions sur les entiers, comme MOD() ou GCD(), commencent à cracher des erreurs. Si tu dépasses ce seuil les calculs seront faux donc inutile d'aller plus loin (notamment toutes les parties fractionnaires sont nulles, ce qui remet pas mal en cause l'usage de Int B dans la suite puisque Int B = B).
Pour la même raison, tous les nombres représentés dans la calculatrice s'écrivent comme des rationnels avec un dénominateur d'au plus 10¹⁴ ou 10¹⁵, comme on l'a vu avec π l'autre fois, donc si tu autorises des B plus grand que ça tu vas rien filtrer du tout. De ce que j'ai compris de ton algo ton B croissant atteint de telles valeurs surtout parce qu'il rate des dénominateurs qui fonctionnent.
Ce test-là passe pour A=π et B=10¹⁵ (les deux termes sont égaux), en fait il passe pour n'importe quelle valeur de A≥1 et B=10¹⁵ puisque Int B=B et AB est trop grand pour que .5 rentre dans la précision du BCD, chiffres cachés inclus. Donc c'est clairement pas là que tu élimines les irrationnels.
Tu rates aussi des nombres parfaitement rationnels.
• 1÷3-10⁻⁴ renvoie 9997/30000, mais...
• 1÷3-10⁻⁵ ne renvoie rien alors qu'il existe 99997/300000, une fraction parfaitement raisonnable.
Fun fact, c'est aussi le stade (dans la séquence des puissances de 10) où RUN/MAT arrête de renvoyer des valeurs fractionnaires, mais ça n'excuse pas pour autant que tu passes à côté.
Frac Ans⁻¹
Donc en fait l'algo c'est ça. Tu espères que Ans (qui est initialisé avec la valeur de A) est un rationnel p/q. Si on regarde ce que ça donne sur les premiers tours :
1. Au premier tour tu obtiens B = q/p et un reste de la forme q'/p (q' < p).
2. Au deuxième tour, tu as B = q/q' et un reste de la forme p'/q' (p' < q').
3. À l'étape suivante, B = q/p' et un reste de la forme q''/p' (q'' < p').
4. Ensuite, B = q/q'' et on commence à comprendre où ça va.
En fait tu regardes des valeurs de B = q/x avec des x de plus en plus petits en espérant que x se rapproche suffisamment de 1 pour que ça te sorte la valeur de q. Et pour tester ça tu compares la valeur de Ans, dont x est le numérateur, avec un seuil minimal heuristique C. Mais comme Ans n'est pas x mais plutôt x divisé par la valeur de x au tour précédent, heuristiquement ton algo s'arrête si x descend beaucoup en une étape plutôt que si x est petit. Donc prouver que ça converge même quand le calcul est exact, que l'entrée est rationnelle et que la détection de Ans peut être faite formellement sans s'appuyer sur un seuil heuristique... n'est pas évident.
J'ai cherché si c'est un algorithme classique mais je n'ai rien trouvé. Les théorèmes habituels genre Dirichlet/Liouville ne donnent pas d'algo explicite et toutes les approximations en fractions continues que j'ai croisées font de l'algèbre linéaire quelque part.
-
Conseil méta, si je peux me permettre : ta documentation du code est bien mais très incomplète. Tu expliques pas mal ce que fait chaque instruction, mais tu n'as pas indiqué les invariant et variant de ta boucle, donc dès qu'on veut obtenir une vue d'ensemble de plusieurs lignes ça tombe dans le reverse-engineering. Il m'a fallu une bonne heure avant de pouvoir dire que Ans est le "reste à approximer" et je ne vois toujours pas d'invariant clair.
De même, tu n'expliques pas comment fonctionne l'algo (sur quoi tu itères, jusqu'à quand, et quel grandeur tu calcules), donc ça aussi il faut le deviner. Enfin, les choses comme le "respectivement" sont vraiment pas claires pour tout le monde (je ne l'ai compris qu'après la première demi-heure d'analyse) donc préfère être redondant et te répéter que laisser un doute.
-
Y'a plein d'autres trucs à dire, je verrai plus tard...
Citer : Posté le 21/11/2020 23:05 | #
Ouh la, moi qui croyais être "tranquille" (je plaisante bien évidemment ). Je commente ta réponse, puis j'écrirai quelques "petites" lignes.
Je dois dire que c'est la toute dernière chose que j'ai modifiée dans le prog, donc très certainement "un peu" vite (il était minuit et je "peaufinais" pour que le prog renvoie un résultat - juste... - dans un maximum de cas). Donc il faudra que je change ça. Pour expliquer un peu plus cette valeur (C) : au début, je la laissais constante (E-6). Avec cette valeur je n'obtenais pas de réponse pour 1234567.26, la changer à E-7 me renvoie comme réponse 61728363÷50. Tandis que 123456.726 me donnait déjà une bonne réponse avec E-6, j'ai donc supposé que cette valeur était inversement proportionnelle au nombre de chiffre(s) de la partie entière (notons E nbr de chiffres Int). Même test avec cette fois 0.123456, et on remarque qu'il faut une valeur plus grande (au moins E-6) pour obtenir une réponse ⇒ inversement proportionnel au nombre de chiffre(s) (je dirais pas nécessairement significatifs) de la partie décimale. Encore un exemple, avec 12.012345 il faut au minimum la valeur de E-6, et min. E-7 pour 12.0123456. Aussi, E-6 comme E-3 suffit aussi bien pour 0.123 que pour 123.123 . Ma nouvelle supposition (car basée sur seulement quelques exemples, et ceci sera donc à changer dans le prog sur le site) est donc que C=10^(-D-E). Malheureusement ça ne marche pas pour 12.012345. Une idée saugrenue me tombre du ciel : ne prenons que le max de D ou E ! ⇒ C=10^(-Max({D/3,E})) (D/3 pour obtenir des réponses avec 1÷3 etc). Miraculeusement ça fonctionne, avec 1÷3, π×10¹³ ou tout autre multiplicateur (le prog ne nous renvoie toujours ce qu'on voudrait). Donne la bonne réponse pour 123456789012.2 Par contre, 3.141592654·10¹³ est bien un entier sur la calto, car elle n'enregistre que 14 chiffres significatifs pour π. Mais bon nous ne devons plus vraiment nous attarder dessus car le prog répond ce qu'on espère de lui.
C'est donc pour ça que GCD() et ces autres fonctions envoie direct une erreur math dès qu'un de leurs arguments est égal ou supérieur à 10¹⁰
Permets-moi de désapprouver : si j'ai bien compris, tu dis qu'il serait mieux de changer la condition en B>E15 (environ) ? Ceci ne m'arrange pas trop car diminuer cette valeur enlève des résultats que le prog aurait pu trouver avec une valeur plus grande (ex quand on entre A=E-20 ne donnerait plus de réponse avec B>E15...). Et avec pas mal de tests, je n'ai pas encore constaté qu'augmenter cette valeur enlève des résultats possibles.
Eh bien oui... En plus je sais que ça ne fait pas très joli cette condition afin de limiter les faux résultats que le prog pourrait renvoyer... Pour t'expliquer un peu comment elle est arrivée là, c'est quand j'utilisais une valeur constante pour C (par ex E-6). J'ai remarqué qu'avec certaines entrées le prog nous renvoyais un mauvais résultat, mais depuis que C=10^(-Max({D/3,E})) (peut-être d'autres choses ont changé) je n'ai plus vu que cette condition était nécessaire... Faudrait-il mieux l'enlever ou non ?
J'ai beau essayer de modifier les quelques valeurs du prog, je n'arrive jamais à obtenir une réponse... "Correction" : en fait, je n'obtiens jamais cette réponse avec le prog R2FRC, mais bien avec R2FRCERR. Ce 2e programme est à éviter pour l'utilisation qu'on veut en faire car va toujours donner une réponse (même pour π)... Donc j'ajoute ça dans la TODO list pour R2FRC car il me semble en effet possible qu'il trouve une réponse pour 1÷3-10⁻⁵.
Haha tu m'as démasqué Je me suis dis au début de la création du prog que ceci serait une bien grosse supposition, mais comme je n'avais pas trop d'idée vers où partir d'autre...
En effet, pas très évident. Je dois bien avouer, que ce soit des programmes que je fais pour moi ou même destinés à l'utilisation/compréhension d'autres personnes (mon cours d'info, mon job d'étudiant en info aussi), je n'ai jamais essayé de prouver leur convergence (qu'ils renvoient un résultat attendu). J'ai toujours utiliser des exemples (j'essaie quand même d'en trouver des qui pourraient poser problème), et si ils fonctionnent tous je me dis "ce prog est validé !" Je sais que je mériterais franchement d'être tapé... (sur les doigts hein)
Ah ok je vais retravailler cette partie-là aussi Je viens seulement d'apprendre les invariants de boucle il y a 2 semaines dans mon cours d'info, donc ça va sûrement être compliqyé mais ce sera l'occasion pour moi de mettre en application ce que j'ai appris (en tout cas j'essaierai un max de trouver un invariant de boucle). Je vais aussi donner plus d'explications que "ligne par ligne"
Petite question : je sais ce qu'est un invariant de boucle (du genre I: 0≤i≤longueuret ∀ k∈[0, i−1] :t1[k]=t2[k] - en langage de programmation C et avec des tableaux), mais c'est quoi ton "variant de boucle" ?
Dernière petite question : maintenant que l'on prend C=10^(-Max({D/3,E})), comment peut-on trouver D -nbr de chiffres partie décimale- autre ment qu'avec une nouvelle boucle (en gros où on regarderait si 10A possède toujours une partie décimale, puis 100A et ainsi de suite) ?
Citer : Posté le 21/11/2020 23:58 | #
Bon je vois que ça cogite vite et fort ton histoire ! Impeccable. Voyons ce que je peux en dire...
Comme je le pensais, c'est quelque chose que tu as obtenu de façon heuristique (ce qui est parfaitement acceptable). Mon conseil dans ce cas serait d'attaquer ce que tu as deviné en tentant de le mettre en défaut. Ici, on pouvait voir que ta valeur de C dépend de la position du point flottant alors que la rationalité non. Mais en fait ton idée se tient : le nombre de chiffres significatifs joue. Une première étape serait donc sans doute de ramener ton nombre entre 1 et 10 comme ça tu ne prends pas le risque de travailler avec des exposants gênants.
Si tu n'arrives pas à mettre en défaut ce que tu as deviné, c'est sans doute qu'il y a une bonne propriété derrière. Dans ce cas, tu peux tenter de prouver que ton seuil marche toujours si ton nombre s'écrit avec ≤ 5 décimales, si c'est un rationnel avec p/q avec q ≤ 100, ou je ne sais quel autre cas favorable. Ça te montrera que tu es parti dans la bonne direction.
Tu as dû rater une étape parce que tu n'as pas mentionné ce que sont D et E ! Ils ne sont pas utilisés dans R2FRC et tu ne les as pas définis dans ton message.
C'est vrai, mais comme je l'ai dit tous les nombre de la calto sont des rationnels. C'est peut-être le moment de réfléchir à ce que tu veux.
• Est-ce que tu veux tout les nombres qui s'écrivent comme un rationnel p/q dans la calculatrice ? Ça c'est vite vu, tous les nombres le sont.
• Est-ce que tu veux tout les nombres qui s'écrivent comme un rationnel p/q avec q qui fait moins de 10 chiffres ?
• Est-ce que tu veux tout les nombres qui ne sont pas un multiple rationnel de π, √2 ou ln 3 ?
Peu importe quelle est l'entrée x = a·10^n du problème (1 ≤ a < 10), tu peux toujours répondre p = a·10^(n+14) et q = 10¹⁴ (ou je ne sais quel nombre de chiffres significatifs, je mélange toujours), le résultat sera juste, p sera un entier si par chance il n'est pas trop grand, et le programme aura répondu ce qu'on espère de lui. Il est donc vraiment important que tu prennes le temps de préciser ce que tu espères du programme. Parce que tant que tu ne fais que quelques tests plus au moins au hasard tu resteras coincé dans une définition "par la pratique" de l'algo qui ne te mènera à aucun résultat fiable.
Accessoirement cet argument que 3.141592654·10¹³ est un entier ne tient pas la route, car comme je l'ai expliqué ça marche avec les multiplieurs plus grands aussi. Envoie π·10²⁰, le programme répond 3.141592654·10²⁰, et ne va pas me faire croire que ça c'est un entier. :P
Je dis que tout seuil supérieur à 10¹⁵ est inutile. Ça ne t'arrange peut-être pas mais c'est bien le cas : si tu autorises B≥10¹⁵ tu peux écrire tous les nombres sous forme de rationnel. Tu devrais avoir l'intuition que décomposer 10⁻²⁰ en rationnel ce n'est pas différent de décomposer 1. C'est ce dont j'ai parlé tout à l'heure avec l'histoire de ramener à un nombre entre 1 et 10 avant de commencer l'analyse.
Pour caricaturer (un peu méchamment) : ça ne t'arrange pas parce que ton algo est faux. Le problème n'est pas que B < 10¹⁵ est une limite trop stricte, le problème c'est que ton algo échoue à trouver les solutions qui satisfont B < 10¹⁵. Ton algo est écrit comme si il devait trouver une décomposition p/q avec q ≤ 10⁶⁰ si une telle décomposition existe, sauf que ce n'est pas le cas. Il y a deux étapes ici : (1) donner une vraie garantie sur ce que ton algo fait, et (2) fixer une limite qui répond à ton besoin (par exemple 10¹⁰ si tu ne veux que les dénominateurs qui ont moins de 10 chiffres).
Indice : est-ce que tu as vérifié que B est vraiment croissant ?
Il existe des algorithmes comme ça qui vérifient d'une façon ou d'une autre si la solution est correcte. Mais c'est des cas assez rares et souvent c'est détourné. À mon avis il faudrait voir si tu remanies le principe de l'algo si oui ou non cette condition est nécessaire. Et ça tu le sauras quand tu auras des garanties sur ce que tu calcules.
Vois ça comme l'effet inéluctable qu'un algo sérieux a besoin d'une preuve plus que d'un test, aussi exhaustif soit-il !
Haha tu m'as démasqué Je me suis dis au début de la création du prog que ceci serait une bien grosse supposition, mais comme je n'avais pas trop d'idée vers où partir d'autre...
Attends quoi. Dans cette explication je ne faisais que décrire le comportement de l'algo pour les entrées qui marchent, histoire d'en tirer une idée générale. Mais c'était sans oublier que dans certains cas A n'est pas un rationnel p/q.
Si toi tu as écrit le programme dans l'hypothèse que A est un rationnel alors tu peux renvoyer Oui sans rien calculer à la limite, et juste prendre le PGCD de A et n'importe quelle dénominateur puissance de 10 qui le rende entier. x)
Ici tu ne peux rien prouver pour l'instant parce que :
1. De toute façon tout est rationnel dans la calculatrice.
2. Tu n'as pas exprimé formellement ce que ton programme doit faire.
Je t'invite vraiment vraiment vraiment à faire ça au plus vite parce que si tu ne sais pas où tu veux aller tu ne peux pas aller bien loin.
Le variant c'est une quantité qui décroit strictement à chaque tour (selon un ordre bien fondé... disons que ça doit pas être capable de descendre à l'infini). Comme elle décroit à chaque tour et qu'elle peut décroître qu'un nombre fini de fois, elle doit ultimement tomber à un minimum et la boucle s'arrête. C'est utilisé pour prouver que la boucle termine !
Par exemple dans un algo de factorisation tu auras une boucle while où tu cherches des facteurs. Si tu divises ta cible à chaque nouveau facteur, tu peux prendre la cible comme variant, elle finit par tomber à 1 et là tout s'arrête. Sinon, tu peux prendre la cible moins le facteur candidat comme variant, ça décroît à chaque tour et si ça tombe à 0 tu sais que tu as fini tous les candidats sérieux.
L'invariant exprime pourquoi la boucle est correcte, le variant exprime pourquoi la boucle fait progresser le calcul.
Ici ton variant c'est Ans et ton but c'est qu'il tombe sous un seuil C. Alors en vérité c'est pas un vrai variant au sens du terme puisqu'il peut descendre à l'infini sans jamais tomber à 0 (l'ordre sur les réels n'est pas un ordre bien fondé). Mais ce que je veux te faire dire c'est qu'est-ce que tu attends de la valeur de Ans, comment est-ce qu'elle doit évoluer, et quand est-ce que tu sais que tu as fini ?
Définis D et E à l'occasion... trouver le nombre de chiffres de la partie décimale d'un nombre X ne peut pas être évident. D'abord ça suppose une base d'écriture. Ensuite c'est pas une fonction continue. Disons pour commencer que X est strictement entre 2 et 3.
Le résultat de ce calcul est très sensible à l'ajout de décimales, par exemple 2.374584 contre 2.374584001, même si ça ne change quasiment rien à la valeur. Sauf que sur ]2;3[, à peu près toutes les fonctions usuelles (Int, Frac, inverse, log, etc) sont uniformément continues. Ça signifie qu'un changement minimal sur la valeur d'entrée ne peut produire qu'un changement minimal sur la valeur de sortie (à un facteur près). Toi tu voudrais qu'un changement sur la 10ème, la 100ème, la 1000ème décimale fasse varier le résultat de 1. Ça ce sera impossible tant que tu utiliseras des fonctions uniformément continues.
Honnêtement te casse pas la tête et code la boucle. x)
Insight : J'ai cru un moment pouvoir calculer le truc avec log(1÷Frac X), mais ça marchait pas. J'ai remarqué que ma quantité changeait pas de valeur sous l'effet des petites décimales, et comme ça me paraissait perdu d'avance j'ai tenté de prouver que ça ne marcherait pas. Pour ça j'avais besoin de continuité uniforme, donc je me suis restreint à ]2;3[, et là la preuve a marché.
Citer : Posté le 22/11/2020 21:21 | #
Je te réponds assez rapidement, car je n'ai pas bcp là maintenant (et ça permettra de bien faire avancer les choses).
Ça simplifierait pas mal le calcul du C, mais aussi les tests
C'est-à-dire que la première fois que j'ai écrit le message je ne l'avais pas oublié mais j'ai eu un problème avec mon navigateur et perdu ce message... Le bout qui manque est donc : D le nombre de chiffres de la partie décimale et E le nbr de chiffres de la partie entière ^^'
• Est-ce que tu veux tout les nombres qui s'écrivent comme un rationnel p/q avec q qui fait moins de 10 chiffres ?
• Est-ce que tu veux tout les nombres qui ne sont pas un multiple rationnel de π, √2 ou ln 3 ?
Au début, je suis parti du principe que l'on allait considérer π, ln 2 et √5 comme irrationnel sur la calto. Je suis énormément tenté par les considéré comme rationnels, et comme ça l'affaire est dans le sac. Posons H∈R (irrationnel comme rationnel), il sera donc rationnel sur la calto (15 chiffres significatifs). Mais est-ce que changer sa forme décimale en quotient "p/q" ne changerait pas la valeur de (-27)^H? Je veux dire par là serait-il possible de trouver une réponse réelle à ce calcul alors que H est irrationnel (rationnel à 15 chiffres sur la calto) donc n'aurait pas de solution réelle ? S'il n'y a aucune différence ni aucun risque alors bien sûr je vais foncer direct là dedans.
Je préfère garder q sans condition. Malheureusement s'il dépasse 10^99 on obtient une erreur math je me suis dis "limitons-le à 10^60 comme ça pas d'erreur de math et on a aucune chance de sauter de 10^60 à plus de 10^99". Donc voilà haha
J'ajoute ça aussi à la TODO list, pas trop le temps la maintenant...
Comme dit précédemment (je ne sais pas vraiment comment bien expliquer), on recherche avec une entrée A une sortie p/q. Si on pose directement que A peut s'écrire en quotient, l'algo (en tout cas de mon point de vue/de mon côté) devient plus facile à gérer et il devient dès lors facile de dire que A n'est finalement pas un quotient. Un peu comme une démonstration par l'absurde si tu veux (où il n'y a pas encore de documentation suffisante mais ça viendra )
Il me semble que j'ai réussi à répondre à ceci juste au-dessus (dans ce message-ci), même si j'ai répondu avec une question
Pourquoi toujours utiliser des termes alors que leur signification est si simple ? Mais OK je ferais ça en même temps que l'invariant. Est-ce que prouver que le variant tend (et atteint) une valeur finale suffit ? (n'importe quelle valeur finale, et peut être utiliser une combinaison de plusieurs variants ?)
OK on va faire ça haha
Oufti... Le "petit" message a légèrement muté on dirait même si je suis encore loin de pouvoir rivaliser avec toi