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 :

déclaration d'une matrice a trois dimensions


Sujet :

C++

  1. #1
    Nouveau membre du Club
    Femme Profil pro
    Inscrit en
    Mars 2011
    Messages
    76
    Détails du profil
    Informations personnelles :
    Sexe : Femme

    Informations forums :
    Inscription : Mars 2011
    Messages : 76
    Points : 35
    Points
    35
    Par défaut déclaration d'une matrice a trois dimensions
    Bonjour mes chers
    SVP j'ai besoin de votre aide

    En fait, j'ai une matrice a trois dimensions que j'ai obtenu par un programme en MATLAB ( n matrices chacune de dimension A*A), elles sont binaires, je vais les utiliser comme input pour un programme en C++. Pour les matrices de petite taille, je peux les déclarer sans problème comme suit:
    int M[8][8][4]={0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,...}.
    Alors que pour les matrices de tres grande taille M(500,500, 100), ca sera impossible. Dans ce cas, j'ai cherché seulement les valeurs qui sont égales à 1 sur le programme initial sur matlab, il m'affiche les numéros des éléments dans la matrice exemple:
    309
    537
    97876
    ..
    Normalement, juste je vais copier ce résultat sur le programme de C++; Comment SVP je peux les déclarer , j'ai pas d'autres solutions que de les copier dans la déclaration

    Merci beaucoup d'avance

  2. #2
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 565
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 565
    Points : 7 648
    Points
    7 648
    Par défaut
    Bonjour,

    Ta question n'est pas très claire.
    Est-ce que ton problème est de comment définir mon tableau pour mieux gérer les tableaux "quasiment vides"?
    Est-ce que c'est juste: Comment initialiser un élément précis de la matrice à partir un unique indice?

    Tout d'abord la déclaration que tu donnes est un tableau en langage C. Et tu es dans un forum C++. En C++, on ne definit pas nu tableau multidimensionnel comme ça. Dans ton cas j'utiliserai 3 types différents de tableaux pour les 3 étages. Ça donne std::vector<std::array<std::bitset<100>,500>>. Le std::array est le plus adapté pour les tableaux, le std::vector en premier est une optimisation de la mémoire automatique et le std::bitset en dernier permet de diminuer sensiblement la taille pour des données binaires.
    Ensuite en C++, dès que l'on besoin d'un type, on crée le type.
    Si le problème est la conversion de coordonnées je te donne un exemple.
    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
    #include <iostream>
    #include <bitset>
    #include <array>
    #include <vector>
    #include <tuple>
     
    // Le type pour stocker les matrices 500x500x100 de booléens
    class XMatrice {
    	static constexpr std::size_t  SZ1{500}, SZ2{500}, SZ3{100};
    public:
    	XMatrice() : data(SZ1) {}
     
    	// pour les accès par les 3 coordonnées [x][y][z]
    	std::array<std::bitset<SZ3>,SZ2>&  operator[](std::size_t i) { return data[i]; }
    	std::array<std::bitset<SZ3>,SZ2>const&  operator[](std::size_t i)const { return data[i]; }
     
    	// pour les accès par un indice unique
    	void  set( unsigned long coords ) {
    		std::size_t  x, y, z;
    		std::tie(x,y,z) = to_xyz( coords );
    		data[x][y][z] = true;
    	}
    	void  reset( unsigned long coords ) {
    		std::size_t  x, y, z;
    		std::tie(x,y,z) = to_xyz( coords );
    		data[x][y][z] = false;
    	}
    	bool  get( unsigned long coords )const {
    		std::size_t  x, y, z;
    		std::tie(x,y,z) = to_xyz( coords );
    		return  data[x][y][z];
    	}
     
    private:
    	// conversion d'une localisation indexée vers les 3 coordonnées tableaux
    	static std::tuple<std::size_t,std::size_t,std::size_t>  to_xyz( unsigned long c ) {
    		// conversion peut être à adapter
    		std::size_t  x = static_cast<std::size_t>(c / (SZ3*SZ2));
    		c -= x * (SZ3*SZ2);
    		std::size_t  y = static_cast<std::size_t>(c / SZ3);
    		c -= y * SZ3;
    		std::size_t  z = static_cast<std::size_t>(c);
    		return  {x, y, z};
    	}
     
    	std::vector<std::array<std::bitset<SZ3>,SZ2>>  data;
    };
     
    void  test() {
    	XMatrice  m;
    	m[0][0][0] = true;  // accès par les 3 coordonnées
    	m.set( 97876 );      // accès par un indice unique
    	std::cout << m[0][0][0] << ' ' << m[1][478][76] << ' ' << m.get(0) << ' ' << m.get(97876) << '\n';
    }

  3. #3
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    De manière générale, il faut te rendre compte que, si tu as affaire à une matrice pleine, une matrice peut être "simplement" considérée comme étant un tableau à une seule dimension et contenant un nombre d'éléments correspondant au produit de la taille de chaque dimension.

    Ainsi, si tu as besoin d'une matrice deux dimensions de -- mettons -- 10 lignes et 5 colonnes, ce que tu veux avant tout, c'est donc être en mesure de représenter ... 10 * 5 = 50 éléments.

    Tu peux donc "assez facilement" décider de créer un tableau de 50 éléments et l'utiliser pour représenter les différentes valeurs de ta matrice, bien qu'il y ait une petite astuce pour convertir le tout:

    Il faut en effet
    • appliquer la formule (position_linge * taille_colonne) + position_colonne= indice pour obtenir l'indice de l'élément qui se trouve en position_ligne, position_colonne et
    • appliquer les formule indice / taille_colonne = position_ligne et indice modulo taille_colonne = position_colonne pour obtenir respectivement les position_ligne et position_colonne à partir de l'indice dans le tableau

    Une logique similaire peut donc parfaitement être appliquée pour les matrices à 3 dimensions, à ceci près qu'il faudra adapter les formules sous la forme de
    • indice = (position_d1 * taille_d2 * taille_d3) + position_d2 * taille_d3) + position_d3 et
    • position_d3 = indice modulo taille_d3, position_d2 = (indice -taille_d3) /(taille_d2 * taille_d3) et position_d1 = indice - ( (taille_d2*taille_d3)+position_d3 ) / (taille_d2 * taille_d3) pour obtenir les positions dans les différentes dimensions sur base de l'indice dans le tableau

    A partir de là, il ne reste alors plus que le problème de pouvoir représenter un nombre d'éléments suffisant en mémoire. Etant donné la taille en mémoire que cela peut représenter (à titre d'exemple, une matrice 8*8*4 va permettre la représentation de ... 256 éléments. Si les éléments sont ne serait-ce que de type int) cela nécessite donc 1ko en mémoire. On se rend donc compte que l'espace mémoire va augmenter rapidement) et le fait que la taille de la pile d'appels (l'espace mémoire dans lequel sera représenter un tableau pour lequel nous n'aurons pas eu recours à l'allocation dynamique de la mémoire, comme la matrice que tu nous montre ici) est particulièrement limitée et -- a priori -- utilisée par bien d'autres choses que par ta matrice tout au long du programme.

    Pour les matrices plus importantes, il faut donc envisager de les placer "sur le tas", en ayant recours à l'allocation dynamique de la mémoire.

    Par chance, la bibliothèque standard nous propose une classe idéale pour ce genre de tableaux: la classe std::vector qui nous permet -- entre autre -- de préparer directement l'instance de la classe que nous allons créer pour recevoir un nombre bien particulier d'éléments (qui correspondra donc, dans le cas présent, au produit de la taille des différentes dimensions) au travers des fonctions resize() et reserve().

    Après, il faut voir l'utilisation exacte que tu vas faire de ta matrice à trois dimensions, car, selon tes explications, il semblerait que ton but soit surtout de pouvoir représenter "un certain nombre" (variable) de matrices à deux matrices dont les dimensions sont -- elles -- clairement définies.

    L'idéal pourrait donc être (selon tes besoins, bien sur) de partir sur une structure personnalisée représentant la matrice à deux dimension (le code devrait pouvoir se trouver sur le forum, c'est le genre de choses que l'on présente de manière régulière) et d'utiliser un tableau dynamique pour maintenir toutes les matrices "ensembles" afin d'en faciliter le traitement. Tu te retrouverais donc avec un tableau proche de std::vector<LaMatrice2D> lesMatrices; dont tu pourrais -- ou non (selon tes besoins ) -- définir directement le nombre de matrices que ce tableau doit contenir (à l'aide des fonctions resize() ou reserve() )
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  4. #4
    Nouveau membre du Club
    Femme Profil pro
    Inscrit en
    Mars 2011
    Messages
    76
    Détails du profil
    Informations personnelles :
    Sexe : Femme

    Informations forums :
    Inscription : Mars 2011
    Messages : 76
    Points : 35
    Points
    35
    Par défaut
    Bonjour
    Merci beaucoup pour votre réponse, je m'excuse, oui il en C juste je suis débutante

    En fait tout simplement je veux déclarer un ensemble des données comme suit exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    int M[1][4][2]=1
    int M[1][5][2]=1
    int M[2][6][3]=1
    ..
    ..etc
    Mais au lieu de [i][j][k] :les numéros de ligne colonne et la matrice, j'ai l'indice de l'élément, on a par exemple l'indice 109 pour dire l'élément [1][4][2]. Ma question comment déclarer ces données en fonction de l'indice sachant ces données sont tous =1. et si possible de mettre toutes ces données ensemble en un vecteur, autrement pour ne pas déclarer chaque donnée toute seule.

    Encore merci beaucoup

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  6. #6
    Membre chevronné Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 043
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 043
    Points : 2 234
    Points
    2 234
    Par défaut
    Bonjour,

    Si j'ai bien compris, ce que tu veux c'est une liste contenant les indices à 1 présents dans tes matrices MATLAB.

    Premièrement, passer des indices matlab à c++ en supposant que le layout mémoire est le même me paraît dangereux. l'indice 109 d'un tableau 3D matlab n'est pas forcément le même que le 109 d'un tableau 3D C++ ( c'est peut être vrai, mais c'est... Peut-être).

    Ensuite, j'ai l'impression que le faite de garder la valeur 1 n'a pas d'importance. Ce qui t'intéresse se sont leurs indices.

    Ce que je ferais ( si j'ai bien compris) , c'est d'avoir une liste d'indices dans un tableau 2D. ( j'ecris sur mon téléphone alors pas code dsl :p)
    Donc une "struct Indices" contenant un std::vector<Indice2D> et l'index du tableau 2D associé.
    Indice2D est une structure contenant 2 usize_t 'x' et 'y' à 1 ( tu peux y ajouter la valeur de l'indice de ta matrice si c'est autres que 1
    Homer J. Simpson


  7. #7
    Membre éprouvé
    Femme Profil pro
    ..
    Inscrit en
    Décembre 2019
    Messages
    562
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 94
    Localisation : Autre

    Informations professionnelles :
    Activité : ..

    Informations forums :
    Inscription : Décembre 2019
    Messages : 562
    Points : 1 253
    Points
    1 253
    Par défaut
    Salut,

    Citation Envoyé par sophielow Voir le message
    pour ne pas déclarer chaque donnée toute seule.
    Le plus simple selon moi serait d'exporter le tableau (dans son format brut 1D, bin et en uint8)
    dans un fichier depuis matlab pour ensuite l'importer dans ton application C ou C++.

    Très sommairement :

    matlab:
    fwrite(bin_file, reshape(A, 1, []), 'uint8')
    C:
    /*pour A[x][y][z]*/
    uint8_t (*A)[y][z]= malloc(len)
    fread(A, 1, len, bin_file)

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Parcours d'une matrice/tableau à deux dimensions
    Par yal001 dans le forum Mathématiques
    Réponses: 5
    Dernier message: 20/11/2008, 14h59
  2. Déclaration d'une matrice (m,n)
    Par dudemec dans le forum MATLAB
    Réponses: 6
    Dernier message: 08/11/2007, 18h00
  3. Implémentation XOR d'une matrice de 3 dimensions
    Par hutch dans le forum MATLAB
    Réponses: 4
    Dernier message: 04/11/2007, 18h01
  4. Moindres carres pour une droite en trois dimensions
    Par shindara dans le forum Traitement d'images
    Réponses: 4
    Dernier message: 27/06/2007, 23h08
  5. Réponses: 5
    Dernier message: 07/06/2007, 12h22

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