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 :

écriture en C++ d'un algo d'interpolation


Sujet :

C++

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    2 051
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 2 051
    Points : 877
    Points
    877
    Par défaut écriture en C++ d'un algo d'interpolation
    Salut tous,

    désolé pour le titre pourrit mais je ne savais pas trop comment appeler ceci... :p

    Voici le contexte de mon probleme :

    j'ai un tableau (vector) dont voici les dimensions : tableau{30000,2}.
    Dans ce tableau chaque case contient une matrice vector de dimension Nx2 (avec N compris entre 0 et 2000).

    On a la première colonne de chaque matrice qui contient des "temps" et la deuxieme qui contient des résultats.

    Voici ce que je veux faire :

    j'ai une matrice qui s'appel tempsResultat qui contient dans sa première colonne aussi des temps et je voudrais écrire dans la deuxième colonne les résultats qui correspondent à ces temps (que je choppe dans la variable matrice que j'ai donné plus haut).

    Le soucis est que les temps de tempsResultat ne sont pas les même que ceux qui se trouvent dans la variable matrice

    du coup, le code que j'avais fait ne fonctionne pas (ici le code n'est pas en C++ car je fais des tests sous matlab avant de me lancer en C++) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    for g=1:1:tailleTableau
        %je stocke ma matrice qui a dans la case {g,1} ds variable
        %nommée tempsResultats
        tempsResultats=Tableau{g,1};
        %je copie les résultats qui correspondent aux temps qui m'intéressent  
        %dans le fichier texte             
        for m=1:1:length(tempsResultats(:,1))
            if (tempsResultats(m,1)==tempsMinteresse(b,1))
                fprintf(fidVTK,'%g\n',tempsResultats(m,2))
            end			
        end
    end
    Ce qu'il faut faire mais que je n'arrive pas :

    1°) pourriez vous me dire comment faire en C++ s'il vous plait pour faire l'équivalent de ceci ?

    2°) En fait ce que j'ai fais plus haut c'est chercher le temps qui m'interesse dans la matrice "tempsResultats" et copier le résutats correspondant dans le fichier texte.
    Le probleme de ceci est que ça ne marche que si les temps qui m'interessent se trouvent aussi dans la matrice "tempsResultats" or ce n'est pas toujours le cas pour moi

    du coup je ne vois pas trop comment faire de façon un peu prêt optimisée avec les outils standard
    je dis de façon un peu pret optimisée car je manipule de très gros matrices/tableau et la seul solution que je vois moi c'est réecrire toutes les matrice en y insérant mes temps qui m'intéressent pui faire une interpolation linéaire et je pourrais ensuite utiliser ce code.

    Le soucis de ceci c'est que je vais recopier toutes les matrices et à ça va demander un temps très important alors que je suis certain qu'il y a une autre méthode.
    => en fait je pense qu'il faudrait détecter qu'elles sont les valeurs qui encadrent le temps qui m'intéresse et faire direct l'interpolation sans à avoir à recopier toute la matrice...

    pourriez vous m'aidez pour faire ceci s'il vous plait ?

    merci d'avance

  2. #2
    Membre régulier Avatar de aslo92
    Homme Profil pro
    Ingénieur développement logiciels temps réel
    Inscrit en
    Février 2012
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels temps réel
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2012
    Messages : 43
    Points : 71
    Points
    71
    Par défaut
    Bonjour,

    est ce que les temps sont triés et croissants dans tes deux matrices ?

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    2 051
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 2 051
    Points : 877
    Points
    877
    Par défaut
    merci aslo de prendre le temps de m'aider !!

    Oui les temps sont bien classés par ordre croisant

  4. #4
    Membre éprouvé

    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 533
    Points : 1 086
    Points
    1 086
    Par défaut
    Les matrices fourre-tout de MATLAB n'ont pas d'équivalent en C++. Il va falloir repenser ton code sur certains aspects : S'agit-il de matrices (avec ce que ça implique mathématiquement) ou seulement de tableaux d'éléments hétérogènes ?

    La plupart du temps, l'une des dimensions de ta matrice est fixe, donc il suffit de créer un std::vector<T> où T est un objet composite (temps+résultat dans une struct, par exemple).

    Il faudra aussi réfléchir au type de tes éléments scalaires : des "temps" typé en unsigned long int se compareraient entre eux plus facilement que des types double. Les "resultats" sont-ils entiers/réels ? De quelle taille ?

    A partir de là, il sera possible d'agir sur les std::vector avec des boucles for (ou par l'utilisation conjointe de foncteurs et des algos de la STL), mais il existe des étapes préalables.

  5. #5
    Membre régulier Avatar de aslo92
    Homme Profil pro
    Ingénieur développement logiciels temps réel
    Inscrit en
    Février 2012
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels temps réel
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2012
    Messages : 43
    Points : 71
    Points
    71
    Par défaut
    Dis moi si je me trompe mais je vois les choses comme ça en C++:

    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
    // Contenu de matrice
    typedef struct
    {
        double temps;
        double res;        
    } t_res_1;
     
    // Contenu de tableau
    typedef struct
    {
        double    temps;
        t_res_1*  pres;
        int       tailleMatrice;
    } t_res_2;
     
    static int get_matrice(t_res_1** matrice, int* tailleMatrice)
    {
        *tailleMatrice = 2000;
        *matrice       = new t_res_1 [*tailleMatrice];
     
        // Pas assez de mémoire si NULL, retourne une erreur
        if (NULL == *matrice)
           return 0;
     
        // Remplissage de la matrice
        for (int i=0; i<*tailleMatrice; i++)
        {
            // Mettre un temps valide ici
            (*matrice)[i].temps = i; 
     
            // Mettre un résultat valide ici
            (*matrice)[i].res = 0; 
        }
     
        // Succès 
        return 1;
    }
     
    int main(int argc, char *argv[])
    {
        double tempsMinteresse = 10;
     
        // Définition du tableau
        int       tailleTableau = 30000;
        t_res_2   tableau[tailleTableau];
     
        // Remplissage du tableau
        for (int i=0; i<tailleTableau; i++)
        {
            // Ici mettre un temps valide
            tableau[i].temps = i;
     
            // Création de la matrice
            int      tailleMatrice = 0;
            t_res_1* matrice = NULL;
     
            if (get_matrice(&matrice, &tailleMatrice) != 0)
            {
                tableau[i].pres = matrice;
                tableau[i].tailleMatrice = tailleMatrice;
            }
        }
     
        // Recherche des temps
        for (int i=0; i<tailleTableau; i++)
        {
            t_res_2* ptableau = &tableau[i];
     
            // Recherche des temps dans matrice
            for (int j=0; j<ptableau->tailleMatrice - 1; j++)
            {
                if ((tempsMinteresse >= ptableau->pres[j].temps) && (tempsMinteresse <= ptableau->pres[j+1].temps))
                {
                   if (ptableau->pres[j].temps == tempsMinteresse)
                   {
                       // fprintf(fidVTK,'%g\n',ptableau->pres[j].res)
                   }
                   else
                   {
                       // Ici tester le résultat le plus proche
                       // fprintf(fidVTK,'%g\n',ptableau->pres[j].res)
                       // ou   
                       // fprintf(fidVTK,'%g\n',ptableau->pres[j+1].res)
                   } 
                } 
            }
        }
     
        system("PAUSE");
        return EXIT_SUCCESS;
    }
    Je remplace tes cellules MATLAB par des structures.
    La structure tableau contient un champ temps, un champ matrice (pointeur sur la matrice) et un champ qui contient la taille de la matrice.

    La matrice est aussi une structure avec un champ temps et un champ résultat.

    Le code est à adapter selon ton besoin.
    Tu peux optimiser la recherche du temps qui t'intéresse en utilisant la dichotomie ce qui aura pour effet de minimiser la boucle j.

    Il manque peut-être quelques tests mais le principe est là.
    J'espère t'avoir aidé ?

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    2 051
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 2 051
    Points : 877
    Points
    877
    Par défaut
    ouahou super aslo !!! tu m'as bien aidé là

    je vois le principe, par contre il faut que je me replonge dans le cpp
    (dans le if je pense qu'il faut mettre un <= et un strictement > pour ne pas avoir un probleme )

    merci beaucoup, ça à l'air vraiment pas mal comme cela

    par contre j'ai un peu de mal avec ce passage (surtout la double etoile et l'histoire de memoire ):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    static int get_matrice(t_res_1** matrice, int* tailleMatrice)
    {
        *tailleMatrice = 2000;
        *matrice       = new t_res_1 [*tailleMatrice];
     
        // Pas assez de mémoire si NULL, retourne une erreur
        if (NULL == *matrice)
           return 0;

  7. #7
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 704
    Points
    2 704
    Par défaut
    Citation Envoyé par 21did21 Voir le message
    par contre j'ai un peu de mal avec ce passage (surtout la double etoile et l'histoire de memoire ):
    Va falloir te pencher sur les pointeurs (et les pointeurs de pointeurs).
    Les arguments de la méthode sont en fait des valeurs de retour, d'où l'utilisation de pointeurs.

  8. #8
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    2 051
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 2 051
    Points : 877
    Points
    877
    Par défaut
    d'accord, merci

    pour commencer j'ai essayé de refaire le code ci dessus (un peu près) mais en matlab et ça donne ça :

    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
    for g=1:1:tailleTableau
    		tempsResultats=Tableau{g,1};
            tempsDetecte=0; erreur=0; m=1;
    		while ( tempsDetecte==0 && erreur==0 && m<length(tempsResultats(:,1)) )
                if ( m<length(tempsResultats(:,1)) ) %comme on a +1 ci dessous
                   if ( tempsMinteresse(b,1) >= tempsResultats(m,1) && tempsMinteresse(b,1) < tempsResultats(m+1,1) )
                        if (tempsMinteresse(b,1)==tempsResultats(m,1))
                            fprintf(fidVTK,'%g\n',tempsResultats(m,2));
                        else %interpolation linéaire (dvlpt Taylor) Y=Ya+(X-Xa).(Yb-Ya)/(Xb-Xa)
                            fprintf( fidVTK,'%g\n',tempsResultats(m,2)+(tempsMinteresse(b,1)-tempsResultats(m,1))*((tempsResultats(m+1,2)-tempsResultats(m,2))/(tempsResultats(m+1,1)-tempsResultats(m,1))) );
                        end
                        tempsDetecte=1;
                   end
                else %produit en croix pour dernière composante
                    fprintf(fidVTK,'%g\n',(tempsMinteresse(b,1)*tempsResultats(m,2))/tempsResultats(m,1));
                    tempsDetecte=1;
                end		
                m=m+1;
            end
    	end
    le soucis est qu'il semblerai que la variable tempsDetecte soit toujours nulle

    voyez vous pk ?

  9. #9
    Membre éprouvé

    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 533
    Points : 1 086
    Points
    1 086
    Par défaut
    Si tu as effectivement besoin de matrices (c'est à dire si les std::vector sont insuffisants), autant ne pas réinventer la roue : http://eigen.tuxfamily.org/dox/GettingStarted.html.

    En plus le code fourni en exemple a de grandes chances de provoquer des fuites mémoire si les données allouées L19 ne sont pas désallouées.

  10. #10
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    2 051
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 2 051
    Points : 877
    Points
    877
    Par défaut
    Citation Envoyé par cob59 Voir le message
    Si tu as effectivement besoin de matrices (c'est à dire si les std::vector sont insuffisants), autant ne pas réinventer la roue : http://eigen.tuxfamily.org/dox/GettingStarted.html.
    à merde alors, je connaissais pas ce truc : "eigen" c'est dans la librairie standard ? j'ai besoin d'installer qqch ou d'inclure un fichier .cpp dans mon projet ? (je suis débutant et je ne comprends pas tous sur le lien que tu m'as envoyé)

    si j'ai bien compris cet objet Eigen à toutes les propriétés des matrices déjà préprogrammée ?

    Citation Envoyé par cob59 Voir le message
    En plus le code fourni en exemple a de grandes chances de provoquer des fuites mémoire si les données allouées L19 ne sont pas désallouées.
    en fait le code que je viens de fournir est en matlab, du coup il n'y a pas besoin de désalouer il le fait automatiquement

  11. #11
    Membre éprouvé

    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 533
    Points : 1 086
    Points
    1 086
    Par défaut
    Eigen n'est pas dans la STL, c'est une librairie "tierce" de calculs matriciels.
    Quant à l'installation, je ne vois pas ce qu'il y a de compliqué :
    How to "install" Eigen?

    In order to use Eigen, you just need to download and extract Eigen's source code (see the wiki for download instructions). In fact, the header files in the Eigen subdirectory are the only files required to compile programs using Eigen. The header files are the same for all platforms. It is not necessary to use CMake or install anything.
    Donc tu as juste à télécharger un zip, l'extraire, inclure certains de ces headers dans ton projet C++ et le tour est joué. Pas de lib/dll à inclure, et rien à configurer. Tu crées un fichier main.cpp et tu colles ça dedans :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #include <iostream>
    #include <Eigen/Dense>
     
    using Eigen::MatrixXd;
     
    int main()
    {
      MatrixXd m(2,2);
      m(0,0) = 3;
      m(1,0) = 2.5;
      m(0,1) = -1;
      m(1,1) = m(1,0) + m(0,1);
      std::cout << m << std::endl;
    }
    Tu compiles (en précisant bien l'emplacement du répertoire parent de Eigen/ à ton compilo) puis tu testes.

    en fait le code que je viens de fournir est en matlab, du coup il n'y a pas besoin de désalouer il le fait automatiquement
    Je parlais du code de aslo92.

  12. #12
    Membre régulier Avatar de aslo92
    Homme Profil pro
    Ingénieur développement logiciels temps réel
    Inscrit en
    Février 2012
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels temps réel
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2012
    Messages : 43
    Points : 71
    Points
    71
    Par défaut
    J'ai en effet oublié de libérer la mémoire de mes matrices avec un delete avant la fin du programme.

    Le code fourni est une implémentation possible, mais ce n'est pas la seule. On peut en effet aussi utiliser STL et les vecteurs.

    Concernant to code MATLAB

    Je ne voit pas l'intérêt de L5 vu que le même test se trouve en L4.
    Si ta variable tempsDetecte reste à zéro, c'est que le test en L6 est toujours faux. L'utilisation du debugger va te permettre de comprendre pourquoi.

Discussions similaires

  1. Aide pour l'écriture d'un algos
    Par Dan99 dans le forum Algorithmes et structures de données
    Réponses: 2
    Dernier message: 13/10/2007, 15h55
  2. algo d'un filtre d'interpolation
    Par sandball22 dans le forum Algorithmes et structures de données
    Réponses: 2
    Dernier message: 11/04/2007, 10h53
  3. Algo Interpolation 3D
    Par uriotcea dans le forum Algorithmes et structures de données
    Réponses: 8
    Dernier message: 25/10/2006, 23h23
  4. Cherche l'algo crc 16 bits
    Par icepower dans le forum Algorithmes et structures de données
    Réponses: 2
    Dernier message: 21/08/2002, 13h27
  5. Recherche algo tree
    Par Anonymous dans le forum Algorithmes et structures de données
    Réponses: 10
    Dernier message: 24/05/2002, 13h44

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