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é
    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 expert
    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é
    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.

###raw>template_hook.ano_emploi###