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

 C++ Discussion :

Méthode Monte Carlo


Sujet :

C++

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Décembre 2013
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2013
    Messages : 2
    Points : 0
    Points
    0
    Par défaut Méthode Monte Carlo
    Bonjour,

    je dois programmer une méthode de Monte Carlo pour modéliser un problème physique. Je suis débutant et j'ai isolé un problème dans mon programme. J'ai donc essayé de le régler en programmant un programme très simple. Le problème est que je n'arrive pas à trouver ce qui cloche. Voici le programme très simple qui me pose problème :

    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
    #include <iostream>
    #include <math.h>
    #include <stdio.h>      /* printf, scanf, puts, NULL */
    #include <stdlib.h>     /* srand, rand */
    #include <time.h>
     
    # include <fstream>
     
    using namespace std;
     
    int main(){
        double S[10];
        S[0]=0.0;
     
        for (int i=0;i<10;i++){
     
            if (S[i]==0)
            {
                S[i+1]=1;
            }
     
            else {
                S[i+1]=0;
            }
        }
        for (int i=0;i<10;i++){
            cout<<S[i]<<"\n";
        }
    }
    En théorie le résultat devrait être :
    0
    1
    0
    1....
    Mais il ne m'affiche que des 0.
    D'où vient le problème?

    Je vous remercie d'avance pour vos réponses qui j'en suis sûr sauront m'être utiles

  2. #2
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Décembre 2013
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2013
    Messages : 2
    Points : 0
    Points
    0
    Par défaut
    Problème résolu tout bêtement. Le tableau S[] doit être de dimension 11!!

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Doctorant
    Inscrit en
    Novembre 2012
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2012
    Messages : 15
    Points : 25
    Points
    25
    Par défaut
    Bonjour,

    Citation Envoyé par jb62300 Voir le message
    Problème résolu tout bêtement. Le tableau S[] doit être de dimension 11!!
    Je n'aurais pas résolu le problème de cette façon. Si ton tableau S doit être de dimension 10, augmenter sa taille n'est pas la solution. Le problème vient de la manière dont tu le parcours, c'est d'ailleurs étrange que tu ne tu n'obtiennes pas un segfault en lançant ton programme initial.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    if (S[i + 1] == 0) //avec i = 9 tu veux accéder à S[10] qui n'est pas alloué
    En conséquence je pense qu'il vaudrait mieux écrire :

    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
     
    #include <iostream>
    #include <math.h>
    #include <stdio.h>      /* printf, scanf, puts, NULL */
    #include <stdlib.h>     /* srand, rand */
    #include <time.h>
     
    # include <fstream>
     
    using namespace std;
     
    int main(){
        double S[10];
        S[0] = 0.0;
     
        for (int i = 1; i < 10; ++i){
     
            if (S[i - 1] == 0)
            {
                S[i] = 1;
            } else
            {
                S[i] = 0;
            }
        }
        for (int i = 0; i < 10; ++i){
            cout << S[i] << "\n";
        }
    }

  4. #4
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    Par défaut
    Salut,
    Citation Envoyé par MisterBobo Voir le message
    Je n'aurais pas résolu le problème de cette façon. Si ton tableau S doit être de dimension 10, augmenter sa taille n'est pas la solution.
    Effectivement, la solution se trouve très certainement dans ta logique.

    Tu dois absolument veiller à ne jamais dépasser d'aucune manière le dernier élément de ton tableau!

    Or, c'est ce qui arrive et qui est si bien expliqué par MisterBobo
    Le problème vient de la manière dont tu le parcours, c'est d'ailleurs étrange que tu ne tu n'obtiennes pas un segfault en lançant ton programme initial.
    Hummm, oui et non ...

    Il n'est mis nulle part dans la norme que tu dois avoir une erreur de segmentation si tu tentes d'accéder à un élément hors limite d'un tableau.

    Au mieux, on parle d'undefined behaviour, ce qui veut dire, en gros, que la norme n'a pas pu déterminer le meilleur comportement à apporter et qu'elle laisse le soin aux développeurs du compilateur de faire "ce qu'il jugent le mieux".

    Parce que, quand on y pense, le comportement risque très fort de dépendre de ce qui se trouve en mémoire "après le dernier élément du tableau".

    Et ce qui se trouve à cet endroit peut dépendre d'énormément de choses :

    D'une décision d'alignement quelconque, par exemple, ou de la décision de laisser "un espace libre" entre le dernier élément et la variable suivante.

    Cela peut aussi dépendre carrément de la manière dont les différents segments mémoire sont organisés et / ou de l'utilisation de la pile.

    Si les différents segment de mémoire sont placés avant la pile, en considérant le même sens qu'elle pour comme base ou après, il est possible qu'un accès hors limite ira "titiller" des données auquel on ne devrait pas toucher... ou non.

    Si le tableau se trouve "presque à la fin" de la pile, on coure le même risque.

    Si une variable est déclarée après la déclaration du tableau, elle devra normalement se trouver après le dernier élément du tableau, et si elle est "de type compatible", il se peut très bien que tu ne modifies qu'une valeur que tu ne devrais pas modifier en occasionnant au passage des résultats aberrants.

    Au final, l'erreur de segmentation n'est qu'un des comportements qui sont susceptibles d'être constatés, mais il y en a une flopée d'autres, tous plus ou moins dérangeants, tous plus ou moins critique au niveau de tes données
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  5. #5
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Décembre 2010
    Messages
    734
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 734
    Points : 1 475
    Points
    1 475
    Par défaut
    Par ailleurs, moi j'éviterais des codes du style:
    Citation Envoyé par jb62300 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
        double S[10];
        S[0]=0.0;
    
        for (int i=0;i<10;i++){
    
            if (S[i]==0)
            {
                S[i+1]=1;
            }
    en effet, la définition des nombres à virgule double précision est telle que tu n'as aucune garantie de bon fonctionnement d'un test d'égalité. Des valeurs qui sous forme décimale paraissent "tomber juste" peuvent en réalité ne pas être représentables exactement au format binaire à virgule flottante. Du coup l'égalité n'est jamais vérifiée, même quand ta logique d'humain te souffle que ça tombe juste.
    Pour tester des valeurs en virgule flottante, il faut faire des tests "à epsilon près", du type:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    if(abs(a-0)<precision){
         //do thing for 0
    }else{
    }
    a est un nombre à virgule flottante, et précisionta précision d'évaluation, c'est à dire l'écart significatif minimum.
    Je dirais que c'est peut-être la raison de tes 0 partout...
    EDIT: même dans le cas de deux valeurs calculées tu ne sais jamais si l'imprécision va permettre à tes deux valeur d'être techniquement égales même si elles sont fonctionnellement égales. Pour cette raison, il faut là aussi faire des tests d'égalité à epsilon près en sélectionnant une précision raisonnable en fonction de ton domaine fonctionnel (savoir si ton incertitude de calcul est suffisamment petite pour détecter l'écart défini par ta précision est une autre question).

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

Discussions similaires

  1. Valorisation des produits dérivés par la méthode de Monte carlo
    Par aziz1015 dans le forum VB 6 et antérieur
    Réponses: 4
    Dernier message: 20/03/2015, 00h59
  2. Réponses: 1
    Dernier message: 05/02/2013, 16h36
  3. Méthode de Monté Carlo, pour le nombre Pi, sous Vba
    Par Quentin21000 dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 24/02/2012, 19h47
  4. Calcul d'intégrale par la méthode de Monte Carlo
    Par physicslover dans le forum Fortran
    Réponses: 5
    Dernier message: 29/01/2009, 11h02
  5. Simulation Monte Carlo (Analyse de risque)
    Par apoingsfermes dans le forum C++
    Réponses: 5
    Dernier message: 19/05/2006, 14h39

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