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
    Membre habitué Avatar de BioKore
    Homme Profil pro
    .
    Inscrit en
    septembre 2016
    Messages
    213
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : .

    Informations forums :
    Inscription : septembre 2016
    Messages : 213
    Points : 146
    Points
    146
    Par défaut Itération sur tenseur de dimension N linéarisé ?
    Bonjour à tous,

    Dans un fil précédent, le sujet a été abordé de ne réaliser des opérations que sur un seul vecteur plutôt que sur un vecteur multidimensionnel. Entendez par là, utiliser un vecteur[784] plutôt qu'un vecteur[28][28] par exemple. J'entends bien la méthode, qui reste triviale selon les cas que l'on aborde. Cependant, comment se passe l'itération sur un seul index ? Par exemple, admettons que je souhaite ne travailler que sur la 6ème ligne (vecteur[5]) qui contiens donc 28 colonnes, en vue d'envoyer ce vecteur résultant à une fonction quelconque ; comment dois-je concevoir l'itérateur permettant cette opération ?
    Dans le cas du vecteur multidimensionnel, la réponse est triviale : for(auto & v:vecteur[5]). Je sais ici que je ne travaillerais que sur les 28 intersections entre la ligne 5 et les 28 colonnes. Par contre, si le tenseur est linéarisé, comment puis-je faire ? Si je traite directement sur le vecteur, pas de soucis:
    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    //avec id = 5 par exemple
    for(size_t c{0}; c != 28; ++c) {
    	ret += vecteur[id * 28 + c];
    }
    Par contre, pour les itérateurs.... J'ai besoin d'éclaircissements... Suis-je vraiment obligé de me créer ma propre classe d'itérateur de type :
    Code c++ : 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
     
    template<typename T>
    class Tensor {
    private:
    	std::vector<T> mData;
    	size_t rowDim;
    	size_t colDim;
     
    public:
    	Tensor();
     
    	class Iterator {
    	private:
    		size_t mStart;
     
    	public:
    		Iterator(size_t const start): mStart{start} {}
     
    		T & begin() {
    			return mData[mStart];
    		}
    		T & end() {
    			return mData[mStart + colDim];
    		}
     
    		T & operator[](size_t const id) {
    			return mData[mStart + id];
    		}
     
    	};
     
    	Iterator & begin() {
    		return Iterator(0);
    	}
     
    	Iterator & end() {
    		return Iterator(rowDim * colDim);
    	}
     
    	Iterator & operator[](size_t const id) {
    		return Iterator(id * colDim);
    	}
     
    };
    (codé avec les pieds en 2 minutes ; pas testé).

    Car autant un tel code est envisageable pour des dimensions 2, mais dès qu'on passe en dimension N, là j'ai besoin de savoir si ça vaut vraiment le coup.
    De plus, dans cet exemple, le résultat n'est pas un std::vector mais une sous-classe perso, limitant ainsi la portabilité du code...


    Merci d'avance.

  2. #2
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    juin 2011
    Messages
    615
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : juin 2011
    Messages : 615
    Points : 2 938
    Points
    2 938
    Par défaut
    En réalité, utiliser std::vector pour une séquence dont la taille ne bouge est très limitant: ce n'est pas compatible avec std::array, ni std::string, ni tout le reste en fait, y comprit les types customs. Alors qu'une vue sur des données qui combine un bête pointeur + taille permet de manipuler tous les types de valeur continue du moment que la taille ne change pas. C++20 possède std::span, mais il n'est pas adapté pour de multiple dimension, à moins de ne vouloir que la dernière dimension.

    Il y a eu une proposition de array_view pour manipuler aisément des tableaux linéarisés comme des tableaux multi-dimensionnel, mais cela a été refusé du standard. Par contre, on peut trouver des implémentations sur github ou autres forges.

    Selon ton besoin, tu peux limiter à une fonction range(dim1,dim2, ...) qui retourne un std::span/type perso.

  3. #3
    Membre habitué Avatar de BioKore
    Homme Profil pro
    .
    Inscrit en
    septembre 2016
    Messages
    213
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : .

    Informations forums :
    Inscription : septembre 2016
    Messages : 213
    Points : 146
    Points
    146
    Par défaut
    Tu as parfaitement résumé ma question : "manipuler aisément des tableaux linéarisés comme des tableaux multi-dimensionnel"
    Merci donc pour le lien ; dès que j'ai un moment, je vais voir si c'est à ma portée.

    Merci.

Discussions similaires

  1. Itération sur une liste en JSF?
    Par toutoune60 dans le forum JSF
    Réponses: 2
    Dernier message: 26/12/2007, 09h43
  2. [Batch] itération sur les fichiers d'un dossier
    Par yelbied dans le forum Windows
    Réponses: 3
    Dernier message: 12/07/2007, 16h09
  3. itération sur les champs
    Par shnouf dans le forum Langage
    Réponses: 2
    Dernier message: 28/11/2006, 15h27
  4. reference sur tableau N dimensions
    Par harsh dans le forum C++
    Réponses: 11
    Dernier message: 28/06/2006, 18h53
  5. Tri sur tableau à 2 dimensions
    Par Poussy-Puce dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 03/03/2006, 19h36

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