Problème et étude de fonction.
Posté le 04/04/2017 11:45
Bonjour !
Alors voilà, j'ai un petit problème dans un de mes programmes...
Je définis une liste au préalable, mettons la List1, par {1,78}→List1 et je rentre au-fur-et-à-mesure des valeurs entières comprises entre 1 et 78 exclus dans ma liste jusqu'à ce que DimList1=78.
Les valeurs de la liste 1 sont toujours réparties dans l'ordre croissant avec la fonction "SortA(".
L'expression Σ(1-Int((1/(List1[X+1]-List1[X]))),X,1,-1+DimList1) donne le nombre de différences strictement supérieures à 1 entre deux termes consécutifs de la liste.
Posons Σ(1-Int((1/(List1[X+1]-List1[X]))),X,1,-1+DimList1)→A
Je cherche le X tel que List1[X+1]-List1[X] soit la Nième différence strictement supérieures à 1 de la liste 1 pour un N entier tel que 1≤N≤A et pour X variant de 1 à -1+DimList1.
Pour ça, on pourrait simplement poser la boucle suivante :
0→B~C
Do
Isz B
C+(1-Int((1/(List1[B+1]-List1
))))→C
Lpwhile C≠N
B→X
Mais ça me dérange et j'ai cherché un moyen plus rapide... Bon, j'avais de l'espoir alors j'ai essayé ça :
Solve(Σ(1-Int((1/(List1[X+1]-List1[X]))),X,1,-1+DimList1)=N,X) mais bon ça n'a pas marché sans surprise...
Du coup, j'me suis rabattu sur les graph. J'ai fait "1-Int((1/(List1[X+1]-List1[X])))"→Y1 et Solve(Y1=1,X mais bon, erreur argument sans surprise puisque la dimension de ma liste 1 n'est définie que sur l'ensemble discret de réels [2;78]...
Du coup, j'me demandais s'il n'était pas possible de restreindre l'étude de la fonction par la calculatrice à un ensemble discret de réels définit par qqch dans le style [1;-1+DimList1]... Ou si vous avez une autre solution pour éviter cette boucle de malheur !
Merci à vous !
Citer : Posté le 04/04/2017 16:19 | #
Quelques remarques rédigées rapidement au fur et à mesure de la lecture de ton post :
Le calcul des différences
Ton calcul du nombre de différences peut être simplifié ; en effet, les expressions booléennes (résultat d'un test) comme « A > B » prennent la valeur 1 si la condition est vraie et 0 sinon. La structure de contrôle « If », pour décider si une condition est vérifiée, se contente de la « calculer » et teste si le résultat est non-nul. Ainsi ton code peut se simplifier en :
La fonction Solve()
La fonction Solve() résout a priori des équations sur des réels par approximation dichotomique ; ce que tu as écrit n'est pas stupide mais la fonction que tu lui as donnée n'est pas continue ; elle est constante par morceaux, et il n'y a pas de garantie que ça marchera.
Un calcul plus efficace
Tu peux faire plus simple. Tu t'intéresses aux différences entre tes éléments, donc il est intéressant de les calculer. Si tu n'as plus besoin de tes valeurs d'origine après le calcul dont il est question ici, tu peux écraser la liste 1 et la remplacer par la liste des différences ; sinon, tu utilises une autre liste (ici la liste 2) quitte à utiliser plus de place en mémoire (78 valeurs, c'est pas énorme). Ainsi tu calcules les différences avec :
0→I // Position à laquelle on cherche
While S<N
Isz I
S+=List 2[I]>1
WhileEnd
Autre optimisations
Selon l'utilisation que tu fais de tes données, il peut y avoir d'autres optimisations : par exemple, si tu veux utiliser très souvent la position où se trouve la n-ème différence supérieure à 1, il sera intéressant de calculer toutes les positions en bloc au début pour éviter d'exécuter plein de fois la même recherche avec une boucle. Quelques éclaircissements pourraient nous être utiles.
Ah oui, je n'ai pas testé le code que j'ai écrit, il peut y traîner un bug (dans le principe, ça marche).
Citer : Posté le 04/04/2017 20:01 | #
Un grand merci pour ta réponse très complète !
Oui, effectivement, merci d'avoir grandement optimisé ma formule de somme ! Je ne savais pas que l'on pouvait introduire des expressions booléennes dans l'expression d'une somme !
Pour ce qui est de ta proposition comme quoi il serait intéressant de calculer les différences, je ne peux pas écraser la liste 1 et l'idée de créer une seconde liste spécialement destinée au valeurs des différences me gêne un peu vis-à-vis de la quantité de données envoyées en mémoire...
Merci aussi de m'avoir éclairé à propos de la fonction "Solve()" ! (je ne connais pas encore très très bien les fonctions...)
Je pense que calculer toutes les solutions en bloc au début comme tu l'as suggéré ne serait pas spécialement utile pour le programme que j'entends réaliser.
Encore un énorme merci pour ton aide !
Ajouté le 04/04/2017 à 20:04 :
(Oops... j'ai répondu depuis un autre compte... )
Citer : Posté le 05/04/2017 19:59 | #
Les expressions booléennes marchent partout ! Écrire « A > B » n'est pas différent de « A + B » ni de « List1[A] », et de nombreuses techniques de programmation Basic utilisent de tels procédés.
Pour ce qui est du poids en mémoire, le calcul est rapide : chaque élément de liste prend 12 octets de place ; 77 éléments nécessitent donc 924 octets. C'est pas négligeable, mais ça reste correct.
Ne serait-ce que parce qu'un tel calcul doit nécessairement observer tout élément de ta liste en l'absence de prétraitement, tu ne peux échapper à la fois à la boucle While et à la génération d'une liste annexe. Je serai donc tenté de penser qu'on ne peut pas faire bien mieux qu'une optimisation booléenne de ta boucle d'origine :
1→I
While S<N
Isz I
S+List1[I+1]-List1[ I]>1→S
WhileEnd
Mais ça sera quand même relativement long. Pourquoi ne pas donner des précisions sur le fonctionnement de ton programme ? J'ai pas mal d'autres idées en tête, mais elles ne s'appliquent quand dans des cas assez spécifiques. x)
(Ah et, envoie-moi un message pour régler cette histoire comptes en double.)