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

  1. #1
    Nouveau Candidat au Club
    Recherche de trajectoires périodiques
    Bonjour,

    Dans le cadre de mon apprentissage du langage C je souhaite écrire un programme me permettant de determiner les trajectoires périodiques dans un billard de forme quelconque.
    Ce que j'appelle trajectoire est la donnée des coordonnées des points situés sur la bande.
    Pour ce qui est des mathématiques je me sers du poly suivant : http://www.numdam.org/article/TSG_19...3__1__A3_0.pdf .

    Pour résumer rapidement, une trajectoire est périodique si et seulement si les dérivées de la longueur totale de la trajectoire par rapport à chacun des angles est nulles.

    Ainsi je dispose de plusieurs fonctions : ( mes points sont définis avec des coordonnées polaire .. )

    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
     
     
    double Li(double theta1, double theta2, double a, double b) // Calcule la longueur de la section entre les deux points en paramètre ( a et b sont des constantes du problème ... )
    {
      double rho1 = rho(a,b,theta1); // on fait le passage en cartésien
      double rho2 = rho(a,b,theta2);
      double x1 = rho1*cos(theta1);
      double y1 = rho1*sin(theta1);
      double x2 = rho2*cos(theta2);
      double y2 = rho2*sin(theta2);
      return sqrt(pow(x1-x2,2)+pow(y1-y2,2)); // Pythagore pour avoir la longeur du segment
    }
     
    double dli_dsi(double *Theta, double L, double a, double b,int i,double ds,int n) // On calcule la dérivée par rapport à l'angle. ( n = nombre de points ) 
    {
      double AncienTheta = Theta[i];
      Theta[i] += ds; // ds est un angle infinitésimale ( je le prends égale à 1e-4 ... )
      double L_di = l(Theta,n,a,b);
      Theta[i] = AncienTheta;
      return (L_di - L)/ds; // ((f(a+h) - f(a))/h ...
    }
     
    double Xhi(double *Theta, double a, double b, double n, double ds) // Fonction qui calcule finalement la somme des dérivées au carré pour obtenir une sorte de fonction d'erreur ...
    {
      double somme = 0;
      double L = l(Theta,n,a,b);
      for(int i=0;i<n; i++)
      {
            somme += pow(dli_dsi(Theta,L,a,b,i,ds,n),2);
      }
      return somme;
    }


    Ensuite pour essayer de minimiser la la valeur de Xhi je commence par générer un tableau avec N angles et ensuite je calcule la valeur de Xhi pour ce tableau. Ensuite, je me donne aléatoirement des tableaux contenant des valeurs d'angles et je compare la valeur de Xhi avec la valeur précédente et je fais ça environ 200.000 fois et je garde le tableau m'ayant donné la plus petite valeur de Xhi.

    voici le code qui correspond à cette partie :

    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
     
    Generation(Theta,n); // Renvoie un tableau avec n angles.
     
      double sum = Xhi(Theta,a,b,n,ds);
      double check;
     
      // On cherche les points qui minimisent le sum
     
      for(int j = 0; j<N;j++)
      {
        Generation(ThetaBis,n);
        check = Xhi(ThetaBis,a,b,n,ds);
     
        if(check < sum)
        {
          sum = check;
          Theta = ThetaBis;
          cout << " check : " << check << endl; // Pour être sur que la valeur du sum diminue effectivement.
        }
      }


    Cependant lorsque j'exporte les valeurs dans un fichier et que je plot avec python les trajectoires sont tout sauf périodique et je désespère de ne pas savoir pourquoi.
    Si une âme charitable pourrait m'apporter un coup de pouce je lui en serrai reconnaissant.

    Merci d'avance.

  2. #2
    Expert éminent sénior
    Bonjour

    Déjà voir du cout montre que ce n'est pas du C mais du C++ donc pas le bon forum. Ok, ça n'a pas d'influence ici donc passons.

    Toutefois ton souci est plus une question de maths que de C. Tu convertis un algo en C puis tu exportes ces valeurs dans mathplotlib. Est-ce que l'algo est ok ? Est-ce que ta façon de convertir cet algo est ok ? Par exemple tu dis que tu travailles en coordonnées polaires (position d'un point avec l'angle que fait la droite reliant ce point à l'origine par rapport à l'axe [0x) plus distance de ce point à l'origine) mais tu calcules en ligne 11 la distance entre 2 points par la formule de norme du vecteur reliant ces deux points (ce que tu nommes "Pythagore" dans ton commentaire). Est-ce que cette formule s'applique aux coordonnées polaires ? Quelque chose me dit que non... Et ensuite si tes calculs sont ok, est-ce que ton export est ok dans mathplotlib ? Par exemple est-ce que mathplotlib prend bein en compte les coordonnées polaires ? Question C il ne semble y avoir aucune erreur mais toutefois si tu ne types pas tes variables "Theta" et "n" en paramètres de "Generation()" alors elles seront int par défaut (est-ce correct ? et même si c'est oui peut-être que tu devrais les typer quand-même de façon explicite pour qu'un lecteur annexe ne se pose pas de questions à leurs propos). Il y a quand-même un truc concernant le C: justement à propos de ton calcul de norme en ligne 11, il te faut absolument inclure "math.h" sinon les fonctions "pow" et "sqrt" seront considérées int par défaut et leur résultat (encodé float) sera alors incompréhensible (un codage float n'est pas compatible int).
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site

  3. #3
    Nouveau Candidat au Club
    Bonjour,

    Merci pour la réponse !

    Il est vrai que j'emploie des méthodes du C++ pour tout ce qui touche à l'affichage cependant pour tout le reste je suis sensé du moins me servir exclusivement des méthodes du C.

    Les paramètres de ma fonction "Generation" sont respectivement un tableau de n doubles et un entier.

    A la ligne 11 je calcule effectivement une norme de vecteur. Ceci étant cela ne pose aucun problème puisqu'aux lignes précédentes j'obtiens les coordonnées cartésiennes de mes points.

    Le header math.h fait effectivement parti des fichier que j'inclus.

    La question que je me pose maintenant est de savoir si en déclarant mes deux tableaux comme ceci :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    double *Theta = (double*)malloc(n*sizeof(double));
      double *ThetaBis = (double*)malloc(n*sizeof(double));


    puis en écrivant Theta = ThetaBis; tout les éléments de Theta sont bien stockés dans mon tableau Theta ...

  4. #4
    Expert confirmé
    Citation Envoyé par Mathosaurus Voir le message
    Bonjour,
    La question que je me pose maintenant est de savoir si en déclarant mes deux tableaux comme ceci :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    double *Theta = (double*)malloc(n*sizeof(double));
      double *ThetaBis = (double*)malloc(n*sizeof(double));


    puis en écrivant Theta = ThetaBis; tout les éléments de Theta sont bien stockés dans mon tableau Theta ...
    Mauvaise pioche . En C tu ne copies pas de cette manière. Ici tu écrases l'adresse du tableau Theta par celle de ThetaBis. Autrement dit tu as une belle fuite mémoire puisque tu ne peux plus accéder au tableau Theta initiale.

    Pour copier tu peux utiliser memcpy ().
    Utilisation de Glade avec Gtk+ - N'oubliez pas de consulter les FAQ Gtk et les cours et tutoriels Gtk

  5. #5
    Expert éminent sénior
    Citation Envoyé par Mathosaurus Voir le message
    La question que je me pose maintenant est de savoir si en déclarant mes deux tableaux comme ceci :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    double *Theta = (double*)malloc(n*sizeof(double));
      double *ThetaBis = (double*)malloc(n*sizeof(double));


    puis en écrivant Theta = ThetaBis; tout les éléments de Theta sont bien stockés dans mon tableau Theta ...
    Tu écris Theta=malloc(...) puis Theta=ThetaBis. La logique devrait te souffler la réponse. Tu ne peux pas écrire Theta=truc puis Theta=autre chose sans perdre "truc" récupéré précédemment et ça c'est vrai dans tous les langages mais plus spécifiquement en C car en C on doit (comme tu l'as fait) commencer par allouer la mémoire et récupérer cette zone allouée mais une fois cette zone récupérée, tu ne dois la perdre sous aucun prétexte.

    En C (et je pense aussi en C++), un tableau ne peut se copier que élément par élément. Bon gerald3d est passé avant moi et a mentionné memcpy() qui fait ce travail pour toi => Theta=malloc(...); memcpy(Theta, ThetaBis, n * sizeof(double)).

    PS: perso je suis contre le fait de caster malloc mais il y a aussi de très bon arguments pour cette pratique donc si tu le fais en toute conscience et pour de bonnes raisons alors pas de souci.
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site