Autorisation : Membre
Nb de messages : 3767
Inscrit le : Lun 19 Oct 2009, 21:25
Posté le : Mar 28 Jui 2011, 15:59
dernière maj essentielle le 26/07/12
dernière maj mineure 16/11/2013
merci à Maxence d'espace ti dont l'introduction aux booléens m'a inspirée pour améliorer le 25/6/2013
---------- EDIT important 7/2/12 La réduction de la taille du code ne permet pas toujours d'accélérer un programme !
Il arrive parfois qu'une formule optimisée appelle des ressources plus lentes qu'un algorithme simple et (plus) long.
Il n'existe pas de règle générale, ce sera à vous de tester plusieurs possibilitées. Désolé
----------
Vous pouvez vous inspirer des règles de scrutation dégagées dans mon article sur DelVar pour éviter toute lecture innutile de portions du programme.
La présentation d'une équation logique dans un test peut influer sur le poids du code ou la rapidité.
La rapidité est plus difficile à juger que le poids, mais il arrive assez souvent qu'une formule ai un avantage sur des tests ou un algorithme.
Il est possible de pratiquer des tests sans utiliser la fonction If.
On peut aussi remplacer un test par une variable.
Ou encore stocker des tests dans des listes.
....
Je vous montrerai ici comment simplifier certains programmes en appliquant des principes généraux.
Objectifs :
-tenter d'optimiser la mémoire et/ou la vitesse (difficile à gérer)
-regrouper plusieurs actions en une seule ligne
-simplifier des raisonnements
Tous les principes montrés pour des If s'appliquent aux boucles While et Repeat.
==== Logique et Algèbre de Boole (utiliser les booléens)
Un booléen est une information BINAIRE qui représente VRAI ou FAUX avec les valeurs 1 ou 0 respectivement.
Par exemple, sur l'écran de calcul, si j'execute "1=1", ce qui est vrai, la calculatrice m'affiche "1" pour me dire que c'est vrai. Et si j'execute "1=2", elle m'affiche 0 car cela est faux.
Sachez déjà pour plus tard que la calculatrice TI supporte le nombre zéro comme faux et tout le reste comme vrai (0.1,1.2,-1,-1.2,...) lorsqu'on utilise les fonctions adéquates. .
Mais vous ne pourrez pas toujours vous en servir, les fonctions sont importantes.
L'algèbre de Boole est une manière de rassembler les booléens pour écrire la logique.
Cet algèbre admet des opérations et des propriétés particulières, mais certaines ressemblent à l'algèbre classique. Il permet de transformer des raisonnements en équations pour faciliter des raisonnements et simplifier les études théoriques avant de coder un programme.
Voici un récapitulatif des opérations et de quelques propriétés.
Code
non(0)=1
non(1)=0
"ou exclusif" peut s'abrèger en "xor"
0 et 0 = 0 0 ou 0 = 0 0 xor 0 = 0
0 et 1 = 0 0 ou 1 = 1 0 xor 1 = 1
1 et 0 = 0 1 ou 0 = 1 1 xor 0 = 1
1 et 1 = 1 1 ou 1 = 1 1 xor 1 = 0
"et" ressemble à la multiplication, on écrira "*"
"ou" ressemble à la somme, on écrira "+"
Malheureusement xor et non n'ont pas de ressemblance avec les maths classiques.
Et on peut contrarier chaque table avec la fonction "non()" pour définir d'autres tables.
Il sera parfois intéressant de se servir de calculs mathématiques à la place des fonctions booléennes.
De plus on peut dans certains cas mélanger les algèbres de Boole et Classique.
Lorqu'on écrit un raisonnement impliquant plusieurs variables, on peut souvent l'écrire sous deux formats : "tous vrai" ou "aucun faux"
Or un raisonnement peut être plus facile à écrire dans une calculatrice que l'autre.
L'équivalence est donnée par le théorème de Morgan not(A et B) == not(A) ou not(B) not(A ou B) == not(A) et not(B)
Remarque : avec la convention des produits/sommes
not(A*B) = not(A)+not(B)
not(A+B) = not(A)*not(B)
###
Quelques formules booléennes utiles pour réduire certains calculs au niveau du concept
A*(B+C)=(A*B)+(A*C)
A+(B*C)=(A+B)*(A+C) // attention : uniquement en booléen
not(A*B)=not(A)+not(B)
not(A+B)=not(A)*not(B) // théorème De Morgan
A*B+not(A)*B=B
A xor B = A*not(B)+not(A)*B
A xor A = 0
==== usages dans une TI
Tous les tests donnent 0 ou 1 comme résultat. ( 0=faux , 1=vrai )
De plus, les fonctions de test reconnaissent ces valeurs 1 et 0.
Si on donne à une opération logique le nombre 0, il est faux.
TOUT le reste est VRAI.
Code
Quand on fait un test. exemple : A=B
FAUX ==>> 0
VRAI ==>> 1
Quand on fait une opération logique (à partir de test(s)/nombre(s))
Les fonctions de tests sont les opérandes de test (>,=,<=,...) ou opérandes logiques (et,ou,...) ainsi que les fonctions des tests (If, Repeat, While).
Celles-ci sont indispensables pour supporter les valeurs NON-Binaires.
##### Ordre de priorité des opérations dans une TI :
-parenthèses simples ou parenthèses de fonctions comme non().
-calculs classiques (^,*,+,...)
-nCr et nPr
- relations (=,<,>,...)
-opérateur booléen et
-opérateurs booléens xor ("ou exclusif") / ou
Plus de détails dans le manuel, c'est encore plus compliqué sur ti82 que sur ti82stat. Je résume de mémoire.
#####
:If A
:Disp "OK
Si A=0, il ne se passe rien.
Sinon "OK" est affiché.
Et on peut même stocker le résultat d'un test. :B=2->A
:If A
:Disp "OK
Si B=2 "OK" est affiché.
Sinon, il ne se passe rien.
If A signifie If A=/=0
If non(A) signifie If A=0
If A-X signifie If A=/=X ou encore non(A=X)
While 1 et Repeat 0 seront toujours vrais. (utile pour des boucles infinie)
Pour ceux qui n'ont pas assimilé la première partie : If A ou B correspond à If A+B If A et B correspond à If AB
Quelques autres équivalences qui me semblent superflues : If A=B = If not(A-B If A>B = If iPart(A/B //S'écrit également AB^-1 // c'est plus rapide If A<B = If iPart(B/A //De même, BA^-1
EDIT 24/02/13 : j'ai remplacé "ent" par "iPart" ci-dessus, explication par Samos en page 2 et cet autre tuto
Un test sur une liste provoque ce test sur chaque élément de la liste.
Le résultat est une liste remplie de 0 ou de 1 suivant chaque test.
X={A,B,C}
teste X=A,X=B,X=C et revoie une liste remplie de 0 et de 1.
Exemple :
7={2,7,1} // vaut // {0,1,0}
Nous pouvons réaliser de nombreuses conditions en une seule fois puis les rassembler avec des calculs pour imiter des opération ET/OU.
Exemple
Code
Repeat max(codeTouche={21,22,23
End
// quitte si pression d'une des touches 2nde=21,mode=22,suppr=23
Voici quelques fonctions pour effectuer les tests multiples. MIN~~PROD~~ET
MAX~~SOMME~~OU
Attention :
-veillez à fournir des valeurs du bon domaine aux fonctions de calculs +/*/max/min
-vérifiez que les exploitations sont cohérentes au domaine des résultats
Usages classique :
-Placez tout dans un TEST pour convertir les Réels en Binaire.
-utilisez des nombres de même signe ou même positifs.
//ET
prod(-2,-3) = 6 // signe alternatif
prod(0,0) = 0
Ci-dessous des usages courants
Citer
ET
If X=A et X=B et X=C
If min(X={A,B,C})
If prod(X={A,B,C})
OU
If X=A ou X=B ou X=C
If max(X={A,B,C})
If somme(X={A,B,C})
ET (aucun zéro)
If A et B et C
If min({A,B,C})
If prod({A,B,C})
OU (au moins un non-nul)
If A ou B ou C
If max({A,B,C})
If somme({A,B,C})
///// Et avec le théorème De Morgan on en trouve d'autres et des variantes
If non(A) et non(B) et non(C)
If non(A ou B ou C)
If prod(non({A,B,C}))
If min(non({A,B,C}))
If non(somme({A,B,C})
If non(max({A,B,C})
En binaire, cela revient à dire que la liste est nulle.
If non(A) ou non(B) ou non(C)
If non(A et B et C)
If somme(non({A,B,C})
If max(non({A,B,C})
If non(prod({A,B,C}))
If non(min({A,B,C}))
En binaire, cela revient à dire qu'il y a au moins une valeur nulle dans la liste.
Quelques Applications
Citer
If A=X et B=X et C=X
If 2=somme(X={A,B,C})
//// Ici on teste un nombre précis de termes : 2 parmi 3.
exemple de l'intro : détection d'une touche parmi une liste
Code
Repeat max(codeTouche={21,22,23
End
détecte une valeur non-nulle ET LA RENVOIE, en supposant qu'une seule est non-nulle
Code
max({A,B,C
Je suis en panne d'exemple frais.
---- Un test entre deux listes de même longueur provoque ce test entre les termes de même position (le premier avec le premier, le deuxième avec le deuxième etc)
Le résultat est une liste remplie de 0 ou de 1 selon chaque test. On peut alors recueuillir de nombreux tests voire même les exploiter plus tard et séparément.
{A,B,C}={D,E,F}
teste A=D,B=E,C=F et revoie une liste de longueur 3 remplie de 0 et de 1. On peut placer ceci à l'intérieur d'une opération pour l'exploiter.
Exemple :
{2,2,2}={1,2,3} // vaut // {0,1,0}
application 1 : Pour tester l'égalité de deux listes : prod(L1=L2)
application 2 : (se rapproche des masques de la partie suivante)
Dans un jeu : max({1,2,3,4}(A={24,25,26,34->D
Si A=24, D=1
Si A=25, D=2
Si A=26, D=3
Si A=34, D=4
application 3 :
Pour tester plusieurs conditions du même type et vérifier qu'un certain nombre précis de ces tests sont vrais : If 2=somme({A,B,C}={D,E,F}
Ceci vérifie que deux égalités exactement sont vérifiées parmi A=D,B=E,C=F
----
On peut même pratiquer des opérations de masquage comme dans des microcontrôleurs, mais avec plus d'outils.
Seuls certains masquages sont utiles dans une calculatrice. Ne confondez pas L1={...} pour une calculatrice et pour nous. Pour nous c'est La liste qui est égale et pour la calculatrice c'est une série de tests.
Exemple 1 :
L1*{1,1,0,0}={2,0,0,0}
Pour que le test soit vrai, il faut L1={2,0,?,?}.
"?" signifie que l'état des termes trois et quatre n'a pas d'importance dans le test.
Le masque est {1,1,0,0}. Les deux derniers zéros servent à neutraliser les termes de L1 qu'on ne veut pas tester.
Principe :
{w,x,y,z}
*{1,1,0,0}
={w,x,0,0}
Dans la calculatrice : L1*{1,1,0,0}={W,X,0,0}
Sert à tester : L1={W,X,?,?}
Cela évite parfois d'écrire
If L1(?)=? et L1(?)=? et L1(?)=? et L1(?)=? et ...
Exemple 2 : max(L1{1,2,3}->N
Si L1={1,0,0} alors N=1
Si L1={0,1,0} alors N=2
Si L1={0,0,1} alors N=3
==== Les matrices
On ne peut pas utiliser les fonctions des listes comme somme ou max.
Les tests ne fonctionnent pas en répartissant plusieurs tests.
En revanche le test d'égalité ou de différence fonctionne et les opérations de somme et produit entre matrices fonctionnent lorsqu'elles ont les mêmes dimensions.
Code
Prompt [A],[B]
dim([A]->dim([B]
[A]+2[B] // opération entre termes de mêmes positions
0[A] // matrice nulle de même dimension que [A]
[A]=[B] // test : identiques
[A]=/=[B] // test : différentes
[A]=0[A] // test : matrice nulle
[A]=/=0[A] // test : matrice non-nulle
Astuce : pour créer une matrice carrée nulle d'ordre N, vous pouvez utiliser
Code
0identity(N
Je n'ai pas trouvé d'opération globale pour trouver la présence d'au moins un zéro.
Si vous voulez rassembler plusieurs tests/résulats dans une matrice, vous devrez vous débrouiller avec l'affectation ou des boucles.
Si vous voulez effectuer des masquages, vous devrez utiliser les fonctions de conversion en liste ou la fonction *row(valeur,matrice,ligne) mais hélas sur des lignes entières.
Pour traiter une colonne au lieu d'une ligne et vice-versa, utilisez la transposition.
[A]^t avec "^t" un petit T en exposant dans le menu matrice.
Tout test peut être intégré à un calcul entre parenthèses ou via une variable justement parce que les tests génèrent 0 ou 1.
Je commence avec des conditions exclusives les unes par rapport aux autres, je fais un paragraphe pour bien montrer ce qui se passe quand ce n'est pas exclusif.
Ci-dessous vous écrivez chaque condition et la valeur désirée. Pensez que la valeur par défaut est zéro. P*( condition1 ) +Q*( condition2 ) +R*( condition3 ) +S*( condition4 ) ... ->Z
Ci-dessous vous écrivez une valeur par défaut et les écarts à la valeur neutre.
N + (P-N)*( condition1 ) +(Q-N)*( condition2 ) +(R-N)*( condition3 ) +(S-N)*( condition4 ) ... ->Z
Les conditions peuvent être n'importe quoi, mais le plus évident pour commencer est d'utiliser des booléens.
Code
If A=1 // condition 1
P->Z
If A=2 // condition 2
Q->Z
If A=3 // condition 3
R->Z
If A=4 // condition 4
S->Z
...
N +1*( A=B )+3*( A<B )-2*( A>B et C=0 )->Z Si A=B, alors Z=N+1 =N+1*1+3*0-2*0
Si A<B, alors Z=N+3 =N+1*0+3*1-2*0
Si A>B et C=0, alors Z=N-2 =N+1*0+3*0-2*1 Sinon Z=N
Une condition peut être une opération entre des tests.
(A=0)(B=0)+2*(A=1)(B=1)->Z
Si A=0 et B=0 , Z= 1*1+2*0*0 =1
Si A=1 et B=1 , Z= 0*0+2*1*1 =2 Sinon Z=0
(dont Si A=0 et B=1 , Z= 1*0+2*0*1 =0 )
(dont Si A=1 et B=0 , Z= 0*1+2*1*0 =0 )
Attention :
On risque de ne pas prévoir tous les résultats de la formules et ainsi avoir de mauvaises surprises.
=> AU MOINS UNE condition doit être vérifiée SI ON NE VEUT PAS UNE VALEUR PAR DEFAUT
=> Il doit y avoir AU MAXIMUM UNE seule condition de vérifiée à la fois OU BIEN il faut en tenir compte dans les coefficients.
Exemple qui peut commettre un conflit entre les états :
A+1+(A=1)+2(A<2)
Si A<1 : A+1+0+2=A+3
Si A=1 : A+1+1+2=A+4
Si A>1 : A+1+0+0=A+1
On voit que des cas se superposent, il faut bien y réfléchir.
---------------------- ti82statfr: 2008, inscrit: 2009, ti84pocketfr: noël2011, ti30xbmultiview: iut 2012-2014
Perfectionniste, manque tact. Pas le temps de tout publier depuis 2011. Répond toujours aux questions. (rédigé juin 2014)
Autorisation : Membre
Nb de messages : 1387
Inscrit le : Ven 25 Mar 2011, 22:58
Posté le : Mar 28 Jui 2011, 18:27
Merci pour l'article, je pense néanmoins qu'il faut ajouter les interrets de cette technique :
1) économiser des octés
2) gagner en fluidité (un "If" prend relativement longtemps)
Sandro
PS : les "*" ne servent à rien
---------------------- mort à l'inutile, place à la mémoire libre et aux programmes
Autorisation : Membre
Nb de messages : 3767
Inscrit le : Lun 19 Oct 2009, 21:25
Posté le : Lun 11 Juil 2011, 15:21
Merci pour le compliment !
Et puis UP pour les nombreuses améliorations depuis la création du sujet.
---------------------- ti82statfr: 2008, inscrit: 2009, ti84pocketfr: noël2011, ti30xbmultiview: iut 2012-2014
Perfectionniste, manque tact. Pas le temps de tout publier depuis 2011. Répond toujours aux questions. (rédigé juin 2014)
Autorisation : Membre
Nb de messages : 178
Inscrit le : Sam 02 Avr 2011, 12:53
Posté le : Mar 12 Juil 2011, 15:15
Merci linka pour tes articles ils sont très instructif et pratique
---------------------- "Des millions de gens ont vu tomber une pomme, Newton est le seul a s'être demandé pourquoi ."
"L'urgent est fait, l'impossible est en cours.
un probléme a toujours une solution, la solution est de trouver le probléme, pour les miracles, prévoir un délai ...
"
Autorisation : Membre
Nb de messages : 3767
Inscrit le : Lun 19 Oct 2009, 21:25
Posté le : Mar 12 Juil 2011, 15:31
Le "-" est un tiret. Il n'est pas de la même couleur que les formules pour ne pas confondre.
C'est semble-t-il insuffisant.
Je l'efface pour éviter d'autres confusions.
Merci pour le compliment !
Je pense que le sujet n'est pas encore figé. Nous verrons bien.
Par exemple j'ai commencé à innover avec les masques.
---------------------- ti82statfr: 2008, inscrit: 2009, ti84pocketfr: noël2011, ti30xbmultiview: iut 2012-2014
Perfectionniste, manque tact. Pas le temps de tout publier depuis 2011. Répond toujours aux questions. (rédigé juin 2014)
Autorisation : Membre
Nb de messages : 1387
Inscrit le : Ven 25 Mar 2011, 22:58
Posté le : Mar 12 Juil 2011, 16:04
Je crois que je me suis mal exprimé : tu afiirme que "A ou B" est équivalent à "A+B" mais si A est l'oposé de B (par example A=2 et B=-2 ), "A et B"=1 alors que "A+B"=2+(-2)=0
J'espère que cette fois-ci mon message est plus clair.
Sandro
---------------------- mort à l'inutile, place à la mémoire libre et aux programmes
Autorisation : Membre
Nb de messages : 3767
Inscrit le : Lun 19 Oct 2009, 21:25
Posté le : Mar 12 Juil 2011, 17:47
Le problème réside dans les algèbres.
L'algèbre de Boole n'utilise que des données binaires 0 et 1 auxquelles on associe les valeurs "faux" et "vrai".
En algèbre de Boole, "ou" se représente avec "+".
Je dois donc insister sur le fait que la phrase concerne l'algèbre mais pas la calculatrice.
---------------------- ti82statfr: 2008, inscrit: 2009, ti84pocketfr: noël2011, ti30xbmultiview: iut 2012-2014
Perfectionniste, manque tact. Pas le temps de tout publier depuis 2011. Répond toujours aux questions. (rédigé juin 2014)
Autorisation : Membre
Nb de messages : 3767
Inscrit le : Lun 19 Oct 2009, 21:25
Posté le : Jeu 28 Juil 2011, 20:47
Mea culpa, je me suis emmêlé avec un copié-collé. Edit.
---------------------- ti82statfr: 2008, inscrit: 2009, ti84pocketfr: noël2011, ti30xbmultiview: iut 2012-2014
Perfectionniste, manque tact. Pas le temps de tout publier depuis 2011. Répond toujours aux questions. (rédigé juin 2014)
Autorisation : Membre
Nb de messages : 121
Inscrit le : Dim 13 Nov 2011, 14:26
Posté le : Mar 17 Jan 2012, 17:04
Je me permets d'uper ce topic, pour signaler qu'après une petite recherche personnelle, j'ai découvert qu'on pouvait encore plus simplifier les boléens que ce que tu as fait, en supprimant purement et simplement les opérateurs.
Ainsi, (tu l'as déja dit ça)
If A et B = If AB
If A ou B = If A+B
Mais aussi
If A=/=B = If A-B
If A=B = If not(A-B
If A>B = If ent(A/B //S'écrit également AB^-1
If A<B = If ent(B/A //De même, BA^-1
Et avec tout ça on peut vachement simplifier des conditions super grosses ^^.
----------------------
Citer
Le temps est une variable dans une boucle infinie, qu'on ne cesse d'incrémenter.
Autorisation : Membre
Nb de messages : 3767
Inscrit le : Lun 19 Oct 2009, 21:25
Posté le : Mar 17 Jan 2012, 18:25
Merci beaucoup pour ton intérêt.
L'usage du ent est maligne !
Je réfute ces équivalences en raisons de l'augmentation ou de l'invariance de la longueur du code.
Néansmoins je garde ces idées sous le coude sachant qu'elles pourraient être plus rapides que les tests...
exception : A-B (déjà présent) a pour seul avantage de se passer des symboles d'un quelconque menu.
---------------------- ti82statfr: 2008, inscrit: 2009, ti84pocketfr: noël2011, ti30xbmultiview: iut 2012-2014
Perfectionniste, manque tact. Pas le temps de tout publier depuis 2011. Répond toujours aux questions. (rédigé juin 2014)
Autorisation : Membre
Nb de messages : 3767
Inscrit le : Lun 19 Oct 2009, 21:25
Posté le : Mer 18 Jan 2012, 12:26
Je pensais que le + et le * étaient évidents, mais il vaudrait mieux en effet préciser ceci dans la seconde partie pour ceux qui n'ont pas tout lu attentivement. (surtout que les listes utilisent grosso modo cela)
J'édite.
---------------------- ti82statfr: 2008, inscrit: 2009, ti84pocketfr: noël2011, ti30xbmultiview: iut 2012-2014
Perfectionniste, manque tact. Pas le temps de tout publier depuis 2011. Répond toujours aux questions. (rédigé juin 2014)
Autorisation : Membre
Nb de messages : 3767
Inscrit le : Lun 19 Oct 2009, 21:25
Posté le : Sam 09 Jui 2012, 14:25
Merci pour le compliment.
Je ne crois pas :
D'un côté cela devrait gagner en rapidité, de l'autre cela risque de ralentir deux fois plus.
En effet une des actions les plus gourmandes en vitesse est l'écriture d'une variable.
Ce que tu proposes permet de remplacer des opérations booléennes par un mélange entre calcul et opération booléenne, dont j'ignore la réelle efficacité.
Mais tu stockes les résultats dans des variables intermédiaires, ce qui n'est pas forcément plus légers ni plus rapide. (souvent plus lent).
Je propose de tester plutôt :
Code
X-non(K-24)+non(K-26->X
Il est en réalité difficile de trouver les instructions les plus rapides, car certaines font appel à des resources internes et d'autres non.
Réduire le poids du code semble permettre d'augmenter la vitesse, mais ce n'est, hélas, pas toujours le cas !
C'est ce dont j'ai voulu avertir avec l'édit au tout début du texte.
Parfois cela se joue sur la fréquence de lecture de l'instruction.
Par exemple, dans un snake on supportera certainement de perdre de la fluidité au moment de manger une pomme plutôt qu'à chaque déplacement.
---------------------- ti82statfr: 2008, inscrit: 2009, ti84pocketfr: noël2011, ti30xbmultiview: iut 2012-2014
Perfectionniste, manque tact. Pas le temps de tout publier depuis 2011. Répond toujours aux questions. (rédigé juin 2014)
Autorisation : Membre
Nb de messages : 178
Inscrit le : Dim 27 Mai 2012, 20:38
Posté le : Sam 09 Jui 2012, 14:37
D'accord, merci, ça explique en plus pourquoi certains de mes programmes sont si lent, parce que j'utilise toutes les variables possibles et imaginables
Par contre je vais essayé le :
Code
X-non(K-24)+non(K-26->X
Qui lui pour le coup est censé être plus rapide, parce qu'on utilise pas de test.
---------------------- Il y a 10 types de personnes dans le monde : celles qui comprennent le binaire et celles qui ne le comprennent pas.