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 :

Allocation dynamique et imbrication "paramétrée"


Sujet :

C++

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2012
    Messages : 2
    Points : 1
    Points
    1
    Par défaut Allocation dynamique et imbrication "paramétrée"
    Salut à tous !

    Mon problème est le suivant :
    Lorsqu'on veut parcourir un tableau à une dimension, on écrit une boucle "for"...
    Pour 2 dimensions, 2 boucles "for" imbriquées... Ainsi de suite. N'est-ce pas ?

    Ma question c'est donc de savoir comment généraliser cela à un tableau à n dimension, n étant un entier (>0)

    donné par l'utilisateur lors de l'exécution (pour stocker par exemple un tenseur d'ordre n).

    Clairement, 2 problèmes se posent :

    1)Comment créer dynamiquement le tableau à n dimension (hypercube de dimension n) qui va recevoir les

    composantes qui sont au nombre de L^n, si on considère que chaque dimension possède un nombre constant L de lignes/colonnes/etc. ?

    2)Comment "paramétrer" la profondeur d'imbrication des boucles "for" pour le parcours, puisqu'il faut a priori

    quelque chose du type

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    for(i)
    {
        for(j)
        {
            etc...
            //tab[i][j][k][...]
        }
    }
    C'est à dire n boucles imbriquées...

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 403
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 403
    Points : 23 787
    Points
    23 787
    Par défaut
    Citation Envoyé par ulr2012 Voir le message
    Mon problème est le suivant :
    Lorsqu'on veut parcourir un tableau à une dimension, on écrit une boucle "for"...
    Pour 2 dimensions, 2 boucles "for" imbriquées... Ainsi de suite. N'est-ce pas ?

    Ma question c'est donc de savoir comment généraliser cela à un tableau à n dimension, n étant un entier (>0)
    En général, une fonction récursive est adaptée pour cela. La question qui se pose étant alors : quelles opérations comptes-tu appliquer à chaque niveau d'imbrication des boucles ?

    Clairement, 2 problèmes se posent :

    1)Comment créer dynamiquement le tableau à n dimension (hypercube de dimension n) qui va recevoir les

    composantes qui sont au nombre de L^n, si on considère que chaque dimension possède un nombre constant L de lignes/colonnes/etc. ?

    2)Comment "paramétrer" la profondeur d'imbrication des boucles "for" pour le parcours, puisqu'il faut a priori
    Les classes template donnent de bons résultats. Mais il y a plusieurs paramètres à prendre en compte. Cette discussion traitait d'un problème similaire :

    http://www.developpez.net/forums/d12...late-heritage/

  3. #3
    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
    Pour un tableau de dimension N il existe aussi Boost.MultiArray, mais N doit être connu à la compilation. As-tu en tête un exemple où N devrait être connu à l'exécution ?

    Si c'est le cas, comme le dit Obsidian, il faut regarder du côté des fonctions récursives :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    template <typename _T, typename _DimIter>
    void workOn(_T* data0, _DimIter beg, _DimIter end) {
    if (beg==end) return;
    /* ici traitement qui varie selon std::distance(beg,end) */
    workOn(data0,beg+1,end);
    }
     
    int dims[] = { 3, 4, 5, 6 };
    double arr[3][4][5][6];
     
    workOn(&arr[0][0][0][0], dims, dims+4);

  4. #4
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2012
    Messages : 2
    Points : 1
    Points
    1
    Par défaut
    Un exemple de pb où N devrait être connu à l'exécution c'est typiquement l'acquisition d'un tenseur d'ordre N, dont on pourra faire un traitement par la suite...

  5. #5
    Membre chevronné
    Avatar de Joel F
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2002
    Messages
    918
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2002
    Messages : 918
    Points : 1 921
    Points
    1 921
    Par défaut
    une dimensionnalité connue à l'exécution est assez impractivable et donne des perfs moisies. Il vaut mieux avoir une dimensionalité maximale statique et autorisé les dimensionalité intermediaires. Ensuite, au dela de 3D, la pression sur les registre spour l'indexage va dramatiquement faire chuter les performances, empecher la vectorisation et rendre le code générer assez moche. EN gros si N = 1 faire 1 boucle, N> 1 faire 2 boucle en traitant les données nD comme des plaques 2D ordonnées proprement.

    Pour les operations elementwise, ca ne changera rien. POur les quelques opérations dependantes de la position, il faudra localement revenir de la position 2D "physique" a la dimension nD logique.

    Quant à faire une fonction récursive pour enchainer des boucle for, j'emets des doutes sur l'efficacité de la chose au final.

  6. #6
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par ulr2012 Voir le message
    Ma question c'est donc de savoir comment généraliser cela à un tableau à n dimension, n étant un entier (>0)
    donné par l'utilisateur lors de l'exécution (pour stocker par exemple un tenseur d'ordre n).
    En premier lieu, un valarray (dans la STL), et les splice qui vont avec. C'est fait pour ce type de problème. Les "pros" les méprisent un peu, parce qu'ils ont la réputation d'être inefficaces, mais ils sont souvent plus rapides que pas mal de code "fait main" écrit pour les remplacer...


    Ensuite, si le tableau n'est pas trop grand (assez petit pour tenir dans un bloc de mémoire contigue), le plus simple est d'en faire un tableau monodimensionnel de taille adaptée (L^N ici) Si on a juste besoin de parcourir tous les éléments, une boucle unique suffira (et les coordonnées de chaque élément sont assez facile à déduire de sa position)

    S'il est un peu trop grand, un tableau de tableaux comme précédemment, sur la première dimension (ou les deux premières). Ca rend le parcours et le calcul des coordonnées un peu plus complexes.

    S'il est carrément énorme, et contenant relativement peu d'éléments non nuls, on va vers des matrices creuses, et ca devient un peu spécialisé (mais il y a beaucoup de littérature sur le sujet).

    L'intérêt de l'approche est qu'elle fonctionne même si le tenseur n'est pas "hypercubique" (c'est à dire même si toutes les dimensions n'ont pas la même taille).

    Francois
    Dernière modification par Invité ; 13/04/2012 à 09h19.

  7. #7
    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
    Citation Envoyé par ulr2012 Voir le message
    Un exemple de pb où N devrait être connu à l'exécution c'est typiquement l'acquisition d'un tenseur d'ordre N, dont on pourra faire un traitement par la suite...
    Tu peux très bien passer l'ordre du tenseur en paramètre template d'une fonction.
    Tu es peut-être trop pessimiste sur la quantité d'infos qu'on peut déduire dès la compilation.

Discussions similaires

  1. [FAQ] Allocation dynamique d'un événement à un élement. Paramètres this et event.
    Par Auteur dans le forum Contributions JavaScript / AJAX
    Réponses: 5
    Dernier message: 02/12/2013, 20h46
  2. Allocation dynamique (pointeur passé en paramètre)
    Par sperca dans le forum Débuter
    Réponses: 6
    Dernier message: 03/02/2009, 15h50
  3. Réponses: 4
    Dernier message: 03/12/2002, 17h47

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