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 :

Gardes <0, >=0 et en plus otherwise !?


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 Gardes <0, >=0 et en plus otherwise !?
    Bonjour,
    Voici un petit bout de code sensé dessiner "fern" bien connu.
    Code : 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
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    import Data.Monoid
    import System.IO
    import System.Random
    import Graphics.Gloss
     
    main = do
    	  let f = mkStdGen 17
    	  let [e] = take 1 (randomStuff f)
    	  let g = e
    	  affiche g
    	  main
     
    affiche g = display  
    	 (InWindow
    	       "Fougere - Fern" 	 -- window title
    		(513, 375) 	 -- window size
    		(10, 10)) 	 -- window position
             black                   -- background color
             (picture g)     -- picture to display
    Au
    picture g = pictures (listOfPointsq n g a c r w x y p q)
       where
          n = 60000
          a = 0
          c = -1 
          r = sqrt(2*(1/sqrt(2))^2) :: Float
          w = (atan(1)) :: Float
          x = 1/sqrt(2)
          y = 1/sqrt(2)
          p = r*cos(w - c/6 * pi/2)
          q = r*sin(w - c/6 * pi/2)
     
     
    listOfPoints 0 _ _ _ _ _ _ _ _ _ = []
    listOfPoints n g a c r w x y p q = point : listOfPoints (n-1) g' a' c' r' w' x' y' p' q'
      where
     	g' = g
            a' = (g' !! (n-1))/10
    	c' = calcc  c n 
    	r' = sqrt(x*x+y*y)
            w' = calcw x y
    	p' = calcp c' r' w'
    	q' = calcq c' r' w'     
           	x' = choix a' r' p' q'
    	y' = choiy a' r' p' q'
     	point =  translate (x') (y'-150) (color (green) (circle 1.0))
     
    calcp c' r' w'
    	|w' < 0 = -r'*cos(w' - c'/6*pi/2)
    	|w' >= 0 = r'*cos(w' - c'/6*pi/2)
    	|otherwise  = r'*cos(w' - c'/6*pi/2)
     
    calcq c' r' w'
    	|w' < 0 = -r'*sin(w' - c'/6*pi/2)
    	|w' >= 0 = r'*sin(w' - c'/6*pi/2)
    	|otherwise  = r'*sin(w' - c'/6*pi/2)
     
    calcw x y
    	|x /= 0 && y /= 0 = (atan(y/x))
    	|x == 0 && y == 0 = 0
    	|x == 0 && y /= 0 = 0
     
    calcc c n
    	|(n-1)`mod`2 == 0 = -1
    	|otherwise = 1
     
    choix a' r' p' q'
    	|a' > 0.15 = 0.85 * p' + 0.04 * q'
    	|a' <= 0.15 && a' > 0.07 = -0.15 * p' + 0.28 * q'
    	|a' <= 0.07 && a' > 0.01 = 0.2 * p' - 0.26 * q'
    	|a' <= 0.01 = 0
     
    choiy a' r' p' q' 
    	|a' > 0.15 = -0.04 * p' + 0.85 * q' + 1.6
    	|a' <= 0.15 && a' > 0.07 = 0.26 * p' + 024 * q' + 0.44
    	|a' <= 0.07 && a' > 0.01 = 0.23 * p' + 0.22 * q' + 1.6
    	|a' <= 0.01 = 0.16 * q'
     
    randomStuff :: RandomGen f => f -> [[Float]]
    randomStuff f = work (randomRs ( 0.0, 10.0) f)
     
    work :: [Float] -> [[Float]]
    work (r:rs) = 	
    	let n = truncate (r * 10.0) + 60000
                (xs,ys) = splitAt n rs
            in xs : work ys
    Hélas il ne dessine que ça :
    Nom : fern Err2.jpg
Affichages : 181
Taille : 21,7 Ko

    Si j'enlève odtherwise dans le calcul de p' ou q' j'ai le message :

    <interactive>: Fern1.hs48,1)-(50,41): Non-exhaustive patterns in function calcp

    De plus si j'ajoute otherwise dans le calcul du w' j'ai ça :

    [ATTACH=CONFIG]173977[/ATTACH

    Donc le cas otherwise existe!
    A quoi correspondent ces otherwise après <0 et >= 0 ?; non déterminé ?. Portant tout est déterminé,alors je ne trouve pas.
    Images attachées Images attachées  

  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
    En effet, c'est énigmatique...
    Essaie peut-être de déclarer le type de ces fonctions?

    En revanche je vois un pattern non exhaustif dans la fonction en dessous:
    calcw x y
    |x /= 0 && y /= 0 = (atan(y/x))
    |x == 0 && y == 0 = 0
    |x == 0 && y /= 0 = 0
    Et si x /= 0 && y == 0?

    Peut-être est-ce un ricochet?

  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
    Oui c'est pour ça que j'ai gardé otherwise pour le calcul de w'

  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
    Cela étant, l'idiome conseillé dans ce cas est :
    calcp a b c
    | c > 0 = blabla
    | otherwise = bloblo

    pas la peine d'inventorier le cas restants en fait

  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
    C'était mon code au départ. Pour w j'ai vérifier mon code VB6 d'origine : seul les deux premiers cas sont testés, donc otherwise w' = w. tout ça ne change pas l'image qui est identique à la première!

  6. #6
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    otherwise est simplement un synonyme pour True (littéralement, il est défini ainsi dans l'un des modules à la base de GHC).

    La raison pour laquelle GHC se plaint de "non-exhaustive pattern" lorsque tu as deux gardes ">0" et "<=0" est simplement que GHC ne sait pas vérifier que ces gardes couvrent tous les cas possibles. En toute généralité c'est impossible et même ici où cela semble vrai, une instance étrange de Ord pourrait en fait rendre cela faux... Néanmoins GHC sait que si l'une des gardes est True (ou otherwise), le pattern est forcément exhaustif.

    On recommande donc généralement d'utiliser plutôt les gardes ">0" et "otherwise" pour éviter le warning (note qu'il ne s'agit pas d'une error à proprement parler) et accessoirement un test inutile.

    --
    Jedaï

  7. #7
    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
    @Jedai : je plussoie ta réponse très intéressante, mais qui n'explique pour autant pas pourquoi l'affichage du programme est différent selon la présence d'otherwise après deux tests qui couvrent l'ensemble des possibles. Une idée là-dessus?

  8. #8
    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
    Et surtout, pourquoi après avoir terminé toutes les gardes par otherwise a la place de la dernière condution, j'ai toujours le même resultat (voir première image) ?
    J'ai certainement comis une erreur, mais où ?

  9. #9
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    w est un Double. Son instance Ord fait donc partie des instances étranges dénoncées ci-dessus, plus précisément NaN (Not a Number) n'est ni inférieur ni supérieur ou égal à 0...
    Néanmoins cela ne devrait en aucun cas résulter en un dessin différent (ça devrait juste planter si NaN apparaissait mais aucun des calculs effectués ne semble susceptible de donner ce résultat qu'on obtient par exemple avec (log (-1)))...

    Pour diagnostiquer ce qui se passe, je suggère que vasilpapa nous donne les deux versions de son code précisément, que nous puissions reproduire le comportement chez nous.

    --
    Jedaï

  10. #10
    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
    Pour la 1ere image la plupart des variantes dont voici la plus expurgée :
    Code : 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
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
     
    import Data.Monoid
    import System.IO
    import System.Random
    import Graphics.Gloss
     
    main = do
    	  let f = mkStdGen 186000
    	  let [e] = take 1 (randomStuff f)
    	  let g = e
    	  affiche g
    	  main
     
    affiche g = display  
    	 (InWindow
    	       "Fougere - Fern" 	 -- window title
    		(513, 375) 	 -- window size
    		(10, 10)) 	 -- window position
             black                   -- background color
             (picture g)     -- picture to display
     
    picture g = pictures (listOfPoints n g a c r w x y p q)
       where
          n = 60000
          a = 0
          c = -1 
          r = sqrt(2*(1/sqrt(2))^2) :: Float
          w = (atan(1)) :: Float
          x = 1/sqrt(2)
          y = 1/sqrt(2)
          p = r*cos(w - c/6 * pi/2)
          q = r*sin(w - c/6 * pi/2)
     
     
    listOfPoints 0 _ _ _ _ _ _ _ _ _ = []
    listOfPoints n g a c r w x y p q = point : listOfPoints (n-1) g' a' c' r' w' x' y' p' q'
      where
     	g' = g
            a' = (g' !! (n-1))/10
    	c' = calcc  c n 
    	r' = sqrt(x*x+y*y)
    	w' = calcw x y w
    	p' = calcp c' r' w'
    	q' = calcq c' r' w'     
           	x' = choix a' p' q'
    	y' = choiy a' p' q'
     	point =  translate (x') (y'-150) (color (green) (circle 1.0))
     
    {-calcr n x y x' y'
    	|n == 60000 = sqrt(x*x+y*y)
    	|otherwise = sqrt(x'*x'+y'*y')-}
     
     
    calcp c' r' w'
    	|w' < 0 = -r'*cos(w' - c'/6*pi/2)
    	|otherwise = r'*cos(w' - c'/6*pi/2)
     
    calcq c' r' w'
    	|w' < 0 = -r'*sin(w' - c'/6*pi/2)
    	|otherwise = r'*sin(w' - c'/6*pi/2)
     
    calcw x y w
    	|x /= 0 && y /= 0 = atan(y/x)
    	|x == 0 && y == 0 = 0
    	|otherwise = w -- atan(x) ???
     
    calcc c n
    	|(n-1)`mod`2 == 0 = -1
    	|otherwise = 1
     
    choix a' p' q'
    	|a' <= 0.01 = 0
    	|a' <= 0.07 && a' > 0.01 = 0.2 * p' - 0.26 * q'
    	|a' <= 0.15 && a' > 0.07 = -0.15 * p' + 0.28 * q'
    	|otherwise = 0.85 * p' + 0.04 * q'
     
     
    choiy a' p' q' 
    	|a' <= 0.01 = 0.16 * q'
    	|a' <= 0.07 && a' > 0.01 = 0.23 * p' + 0.22 * q' + 1.6
    	|a' <= 0.15 && a' > 0.07 = 0.26 * p' + 024 * q' + 0.44
    	|otherwise = -0.04 * p' + 0.85 * q' + 1.6
     
    randomStuff :: RandomGen f => f -> [[Float]]
    randomStuff f = work (randomRs ( 0.0, 10.0) f)
     
    work :: [Float] -> [[Float]]
    work (r:rs) = 	
    	let n = truncate (r * 10.0) + 60000
                (xs,ys) = splitAt n rs
            in xs : work ys
    pour la 2eme image :

    Code : 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
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
     
    import Data.Monoid
    import System.IO
    import System.Random
    import Graphics.Gloss
     
    main = do
    	  let f = mkStdGen 186000
    	  let [e] = take 1 (randomStuff f)
    	  let g = e
    	  affiche g
    	  main
     
    affiche g = display  
    	 (InWindow
    	       "Fougere - Fern" 	 -- window title
    		(513, 375) 	 -- window size
    		(10, 10)) 	 -- window position
             black                   -- background color
             (picture g)     -- picture to display
     
    picture g = pictures (listOfPoints n g a c r w x y p q)
       where
          n = 60000
          a = 0
          c = -1 
          r = sqrt(2*(1/sqrt(2))^2) :: Float
          w = (atan(1)) :: Float
          x = 1/sqrt(2)
          y = 1/sqrt(2)
          p = r*cos(w - c/6 * pi/2)
          q = r*sin(w - c/6 * pi/2)
     
     
    listOfPoints 0 _ _ _ _ _ _ _ _ _ = []
    listOfPoints n g a c r w x y p q = point : listOfPoints (n-1) g' a' c' r' w' x' y' p' q'
      where
     	g' = g
            a' = (g' !! (n-1))/10
    	c' = calcc  c n 
    	r' = sqrt(x*x+y*y)
            w' = calcw x y w
    	p' = calcp c' r' w'
    	q' = calcq c' r' w'     
           	x' = choix a' p' q'
    	y' = choiy a' p' q'
     	point =  translate (x') (y'-150) (color (green) (circle 1.0))
     
    calcp c' r' w'
    	|w' < 0 = -r'*cos(w' - c'/6*pi/2)
            |w' >= 0 = r'*cos(w' - c'/6*pi/2)
    	|otherwise = 0
     
    calcq c' r' w'
    	|w' < 0 = -r'*sin(w' - c'/6*pi/2)
    	|w' >= 0 = r'*sin(w' - c'/6*pi/2)
    	|otherwise = 0
     
    calcw x y w
    	|x /= 0 && y /= 0 = atan(y/x)
    	|x == 0 && y == 0 = 0
    	|x /= 0 && y == 0 = atan(x)
    	|x == 0 && y /= 0 = atan(x)
     
    calcc c n
    	|(n-1)`mod`2 == 0 = -1
    	|otherwise = 1
     
    choix a' p' q'
    	|a' > 0.15 = 0.85 * p' + 0.04 * q'
    	|a' <= 0.15 && a' > 0.07 = -0.15 * p' + 0.28 * q'
    	|a' <= 0.07 && a' > 0.01 = 0.2 * p' - 0.26 * q'
    	|a' <= 0.01 = 0
     
    choiy a' p' q' 
    	|a' > 0.15 = -0.04 * p' + 0.85 * q' + 1.6
    	|a' <= 0.15 && a' > 0.07 = 0.26 * p' + 024 * q' + 0.44
    	|a' <= 0.07 && a' > 0.01 = 0.23 * p' + 0.22 * q' + 1.6
    	|a' <= 0.01 = 0.16 * q'
     
    randomStuff :: RandomGen f => f -> [[Float]]
    randomStuff f = work (randomRs ( 0.0, 10.0) f)
     
    work :: [Float] -> [[Float]]
    work (r:rs) = 	
    	let n = truncate (r * 10.0) + 60000
                (xs,ys) = splitAt n rs
            in xs : work ys
    Et toujours pas de fern !

  11. #11
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Le 1er code contient la ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    | otherwise = w -- atan(x)
    dans calcw alors que l'équivalent dans le 2e code utilise bien atan(x) et pas w.

    Il y a aussi une ligne douteuse partagées par les deux codes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    |a' <= 0.15 && a' > 0.07 = 0.26 * p' + 024 * q' + 0.44
    Je suppose que ce 024 aurait dû être 0.24 ?

  12. #12
    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
    Bravo et merci pour le point décimal omis. Plus on regarde un code moins on voie les erreurs. w ou atan(x) donnent le même résultat, mais le problème de otherwise ou pas est disparu pour le calcul de w'. Je doit aussi trouver pourquoi le fern est double :
    Nom : ferndouble.jpg
Affichages : 154
Taille : 52,9 Ko
    Une autre ligne est modifiée:
    point = translate (30*x') (30*y'-150) (color (green) (circle 1.0))

  13. #13
    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
    Eh bien, les questions continuent a se poser!
    Normalement dans le calcul de dérivée angulaire partielle ( p et q) on utilise pi/2. Dans le VB6 pas de problème. Pour se qui concerne Haskell, au lieu de diviser pi par 2 il faut diviser pi par 133 pour faire coïncider les deux images. Ne me demandez pas pourquoi, j'ai obtenu ça empiriquement. D'autre part il ne faut pas utiliser atan(x) mais bien ancienne valeur w.
    Voici l'image finale :
    Nom : fern.jpg
Affichages : 159
Taille : 41,3 Ko
    Le code définitif est disponible sur mon site des fractales Haskell http://haskellaskvasil.wordpress.com

  14. #14
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Je ne sais vraiment pas comment tu aboutis à tes codes... Se référant à la description sur Wikipedia de "Barnsley's fern", j'ai obtenu ceci en 15 minutes par une traduction directe de la transformation mathématique :
    Code Haskell : 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
    31
    32
    33
    34
    35
    36
    37
    38
    39
     
    import Graphics.Gloss
    import System.Random
     
    main = do
      g <- newStdGen
      let rs = randomRs (0,1.0) g
      display (InWindow "Barnsley's Fern" (600,1000) (10,10)) black (fern rs)
     
    fern :: [Double] -> Picture
    fern = pictures . map point . take n . randomTransforms (0,0)
      where
        n = 30000
        point (x,y) = translate (100*x) (100*y-500) . color green $ circle 1
     
    transforms =
      [(0.01, f [(0, 0), (0, 0.16)] (0,0))
      ,(0.86, f [(0.85, 0.04), (-0.04, 0.85)] (0,1.6))
      ,(0.93, f [(0.2, -0.26), (0.23, 0.22)] (0, 1.6))
      ,(1   , f [(-0.15, 0.28), (0.26, 0.24)] (0,0.44))
      ]
      where
        -- affine transformation
        f m v x = m *. x .+. v
        [(a11, a12), (a21, a22)] *. (x,y) = (a11*x + a12*y, a21*x + a22*y)
        (x,y) .+. (x',y') = (x+x', y+y')
     
     
    ------------------------------------------
    -- Fonctions auxiliaires
    ------------------------------------------
    randomTransforms orig (r:rs) = orig : randomTransforms new rs
      where
        new = choice r transforms $ orig
     
    choice p [] = error $ "choice : too short a list or too much proba : " ++ show p
    choice p ((p', x): ps)
      | p <= p'   = x
      | otherwise = choice p ps

    Tous les paramètres intéressants sont dans fern et transforms, on peut facilement obtenir l'une des variétés mutantes en modifiant transforms, ou augmenter la densité, changer la couleur, etc en changeant n et point dans fern.

    --
    Jedaï

  15. #15
    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
    Voilà des réponses q'un debutant aimerait toujours avoir.
    Un debutant en Haskell ne peut crée les codes q'avec les connaissances qu'il a déjà assimilées.
    Une bonne réponse le met sur la voie qu'il cherchera à approfondir et il poura progresser.
    J'ai bien compris la composition des functions et la partie qui corresponds à mon calcul des x et y par les gardes mais je n'arrive pas a bien comprendras la partie après where f m ...
    Pourriez-vous m'expliquer cette partie, notamment m* ... Etc.
    Merci d'avance.

  16. #16
    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
    f m v x = m *. x .+. v
    [(a11, a12), (a21, a22)] *. (x,y) = (a11*x + a12*y, a21*x + a22*y)
    (x,y) .+. (x',y') = (x+x', y+y')
    Ce petit bout de code paraît assez impressionnant, en fait c'est simplement que tu n'as pas l'habitude de la syntaxe très concise d'Haskell!

    1. Les clauses de where peuvent se faire référence entre elles.
    2. Les opérateurs *. et .+. sont définis juste après (ligne 2 et 3) avec un pattern-matching assez dense
    3. (.+.) est un opérateur qui permet l'addition membre à membre de deux paires
    4. (*.) est une sorte de produit matriciel entre une liste de deux paires (argument à gauche) et une paire (à droite).

  17. #17
    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, c'est clair.

  18. #18
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Citation Envoyé par stendhal666 Voir le message
    4. (*.) est une sorte de produit matriciel entre une liste de deux paires (argument à gauche) et une paire (à droite).
    C'est exactement le produit d'une matrice 2x2 par un vecteur colonne 2x1. "f m v" construit la transformation affine dont la partie linéaire a pour matrice "m" à partir du point de coordonnées "v".

    Pour connaître les transformations affines appropriées, consultez simplement la page Wikipédia de la fougère de Barnsley, cette page renvoie également vers d'autres propositions pour des variétés différentes de fougères.
    --
    Jedaï

  19. #19
    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 la précision. J'ai visité le site de wilkipedia. Bon, il ont remplace les équations algébrique par le calcul matriciel et pour les mutants jouent sur les coefficients. Très scientifique, ça manque de folie créative. Voici mes mutantes :
    Images attachées Images attachées  

  20. #20
    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
    Nom : mutante.JPG
Affichages : 137
Taille : 31,9 Ko

    Mutante... indeed!

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Les PC sont de plus en plus bruyants que faire
    Par plichtal dans le forum Ordinateurs
    Réponses: 260
    Dernier message: 23/12/2011, 12h28
  2. Réponses: 9
    Dernier message: 10/03/2010, 07h53
  3. propriété ne garde plus sa valeur
    Par safisafi dans le forum Services Web
    Réponses: 7
    Dernier message: 25/03/2009, 14h59
  4. propriété ne garde plus sa valeur
    Par safisafi dans le forum Services Web
    Réponses: 0
    Dernier message: 23/03/2009, 18h27
  5. [Datareport] Etat plus large que le papier
    Par SpaceFrog dans le forum VB 6 et antérieur
    Réponses: 5
    Dernier message: 09/09/2002, 11h45

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