IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Haskell Discussion :

Triple boucle imbriquée


Sujet :

Haskell

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    113
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 113
    Points : 64
    Points
    64
    Par défaut Triple boucle imbriquée
    Bonjour,
    Débitant en programmation en langage Haskell je n'arrive pas à traduire un petit programme de Julia set écrit en VB6.
    Ce sont les boucles x, y et i imbriquées qui me posent problème. ( je n'ai pas de problème avec les simples boucles).
    Voici le code que je voudrai traduire en Haskell :
    Code VB : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
     
    Public Function JuliaSet()
        Dim cRe As Double, cIm  As Double 
        Dim newRe As Double, newIm As Double, oldRe As Double, oldIm As Double 
        Dim zoom As Double: zoom = 1
        moveX = 0: moveY = 0 
        Dim color As Double 
        Dim maxIterations As Integer: maxIterations = 300  
        w = Me.ScaleWidth: h = Me.ScaleHeight
        cRe = -0.7
        cIm = 0.27015
        Dim x As Integer, y As Integer
        For x = 0 To w
        For y = 0 To h
            newRe = 1.5 * (x - w / 2) / (0.5 * zoom * w) + moveX
            newIm = (y - h / 2) / (0.5 * zoom * h) + moveY
            Dim i As Integer
            For i = 0 To maxIterations
                oldRe = newRe
                oldIm = newIm
                newRe = oldRe * oldRe - oldIm * oldIm + cRe
                newIm = 2 * oldRe * oldIm + cIm
                'if the point is outside the circle with radius 2: stop
                If ((newRe * newRe + newIm * newIm) > 4) Then Exit For
            Next i
            color = RGB(255 Mod (i * 30 + 1), 255 Mod (i + 1), 20 * i) '< maxIterations))
            PSet (x, y), color
        Next y, x
        Me.Refresh
    End Function
    Pourriez-vous m'aider ?
    Merci d'avance

  2. #2
    Membre chevronné

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2013
    Messages : 610
    Points : 1 878
    Points
    1 878
    Billets dans le blog
    21
    Par défaut
    Le premier conseil, c'est de ne pas vouloir traduire littéralement un programme VB en Haskell! Deux langages qui reposent sur des modèles de programmation très différents...

    Cela étant dit, les boucles imbriquées ne posent pas trop de problème:

    La double boucle extérieure sert à générer, si je comprends bien, tous les couples (x, y) compris entre (0,0) et (w, h). Pour cela, une liste en compréhension est idéale:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [(x,y) | x <- [0..w], y <- [0..h]] --produit cartésien des deux listes [0..w] et [0..h]
    Ensuite il faut appliquer aux couples ainsi obtenus la boucle intérieure sous la forme d'une fonction:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    map boucleInterieure listeCouples -- tout simplement
    Mais si tu veux faire un programme plus "haskellien", alors:
    - sépare bien les fonctions pures des fonctions IO
    - sépare les fonctions pures en le plus de fonctions simples et orthogonales (c'est-à-dire que tu peux réutiliser en les recombinant plus tard)

    N'hésite pas à partager tes tentatives en Haskell plutôt qu'en VB!

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    113
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 113
    Points : 64
    Points
    64
    Par défaut
    Merci pour votre réponse.
    Effectivement créer une liste cartésienne résout le problème des premières boucles. Le débutant en Haskell je suis tout de même épaté par la dimension de cette liste. Pour une petite image 300x300 points ca donne une liste de 90000 tuples. Mes fractales en vb6 s'affichent sur 1026x750 quasi instantanément. La liste sera de 1026x750! Tuples!!
    Votre proposition pour la boucle intérieure m'intrigue car à l'intérieur de celle-ci toutes les valeurs changent et sont substituées aux anciennes.
    A chaque passage x' est substitué a x qui au prochain passage prend la valeur de x' etc. (n -> n-1 etc).
    Pour les autres fractales du type isf, par exemple, pas de problème car il n'y a qu'une simple boucle.
    Merci pour les conseils car tout change par rapport aux langages impératifs.
    Salutation.

  4. #4
    Membre chevronné

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2013
    Messages : 610
    Points : 1 878
    Points
    1 878
    Billets dans le blog
    21
    Par défaut
    La liste sera de 1026x750! Tuples!!
    Eh oui...
    mais comme l'évaluation est paresseuse, cela n'aura pas énormément d'impact sur la performance; peut-être sur la mémoire utilisée en revanche.
    Il y a des possibilités pour améliorer cet algorithme mais il reste à voir si cela en vaut la peine. Ne pas oublier: l'optimisation prématurée est la racine de tous les maux.

    A chaque passage x' est substitué a x qui au prochain passage prend la valeur de x' etc. (n -> n-1 etc).
    En programmation fonctionnelle, la solution est de transmettre la nouvelle valeur comme un argument de la fonction, par exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    innerLoop i im re = let newIm = processI im
                                    newRe = processR re
                                 in if allRight newIm newRe || i == 300 then i else innerLoop (i+1) newIm newRe

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    113
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 113
    Points : 64
    Points
    64
    Par défaut
    J'utilise listeOfPoints avec arguments pour pictures :
    listeOfPoints 0 _ _ _ = []
    listeOfPoints n x y i = point : listeOfPoints (n-1) x' y' î. Etc...
    Merci pour toutes les explications, salutations

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème de boucles imbriquées
    Par Gnux dans le forum Algorithmes et structures de données
    Réponses: 9
    Dernier message: 09/12/2005, 20h26
  2. boucle imbriquée
    Par zhoom dans le forum C
    Réponses: 4
    Dernier message: 07/11/2005, 13h10
  3. [Débutant]Boucle imbriquée avec des bornes différentes
    Par Hayato dans le forum Algorithmes et structures de données
    Réponses: 2
    Dernier message: 29/08/2005, 16h23
  4. Boucles imbriquées
    Par Immobilis dans le forum ASP
    Réponses: 28
    Dernier message: 14/01/2005, 13h17
  5. [XSL]boucle imbriquée avec condition
    Par kor dans le forum XSL/XSLT/XPATH
    Réponses: 10
    Dernier message: 11/01/2005, 14h19

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo