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

MATLAB Discussion :

faciliter le calcul grâce à ind2sub


Sujet :

MATLAB

  1. #1
    Futur Membre du Club
    Homme Profil pro
    ingénieur optique / photonique
    Inscrit en
    Juin 2016
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : ingénieur optique / photonique

    Informations forums :
    Inscription : Juin 2016
    Messages : 9
    Points : 5
    Points
    5
    Par défaut faciliter le calcul grâce à ind2sub
    Bonjour à tous!

    J'ai un problème de temps de calcul dans un programme et je ne comprends pas mon erreur de raisonnement, et comment l'améliorer si possible

    Voilà, mon but est de créer un tableau ayant pour chaque pixel d'une image la coordonnée d'abscisse d'un sur la première colonne, la coordonnées d'ordonnée sur la seconde et enfin la valeur de ce pixel (en nuance de gris) sur la troisième et dernière colonne.

    1 1 valeur
    2 1 valeur
    1 2 valeur
    2 2 valeur

    Voilà ce que ca donne pour une matrice 2x2.

    J'ai commencé par le faire de façon un peu bourrin:
    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
     
    coord_intens=zeros(1310720,3);  % je créé la matrice finale à la bonne taille (1024 * 1280 pixel = 1310720 lignes)
     
    %remplissage de la seconde colonne
    a=-1280;
    for i = 1:1024
        a=a+1280;
        coord_intens(1+a:1280+a,2)=1+a/1280;
    end
     
    % remplissage de la première colonne
    for j = 1:1280
        for n = 0:1023                       
            coord_intens((j+(n*1280)),1)=j;  
        end
    end
     
    % Remplissage de la dernière colonne avec les valeurs d'intensité 
    for k = 1:1310720
            coord_intens(k,3)=image(coord_intens(k,1),coord_intens(k,2));
    end
    %on utilise les coordonnées déjà enregistrées dans les deux première colonnes pour remplir la troisième.
    Avant tout: il fonctionne.
    En analysant un peu, j'ai deux boucles simples, dont une avec plus d'un million d'éléments, et une double boucle.
    Je me suis dis que je pouvais faire bien mieux. Alors j'ai utilisé les indexages intelligent de matlab et la fonction ind2sub pour n'avoir plus qu'une seule simple boucle.
    Voilà ce que ça donne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    coord_intens=zeros(1310720,3); %idem, on créé en avance la matrice finale
     
    for i=1:1310720  %une seule simple boucle 
        [ligne, colonne]=ind2sub(size(img),i);
     
        coord_intens(i,1)=ligne; %Pour chaque ligne, on rempli ligne et colonne
        coord_intens(i,2)=colonne; 
        coord_intens(i,3)=img(coord_intens(i,1),coord_intens(i,2)); 
    % et enfin on rempli la dernière colonne en utilisant les deux 1ere, comme avant
    end
    Là je me suis dis: Génial j'ai carrement gagné en complexité! Et en plus il fonctionne lui aussi
    Mais en pratique, quand j'applique le programme, le premier fonctionne en quelques secondes (3 ou 4) quand le second (celui qui est censé être malin) fonctionne en 30 ou 40 secondes!

    Qu'est ce qui peut bien se passer? Pourquoi ça ne fonctionne pas? Et surtout que devrais-je faire? Garder ma première version alors qu'elle me paraît moche ou travailler pour améliorer encore la seconde?

    En espérant avoir été assez clair dans mes explications, je vous remercie d'avance pour votre aide

    Simon

  2. #2
    Rédacteur/Modérateur

    Avatar de Jerome Briot
    Homme Profil pro
    Freelance mécatronique - Conseil, conception et formation
    Inscrit en
    Novembre 2006
    Messages
    20 302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance mécatronique - Conseil, conception et formation

    Informations forums :
    Inscription : Novembre 2006
    Messages : 20 302
    Points : 52 882
    Points
    52 882
    Par défaut
    Citation Envoyé par cimon Voir le message
    Voilà, mon but est de créer un tableau ayant pour chaque pixel d'une image la coordonnée d'abscisse d'un sur la première colonne, la coordonnées d'ordonnée sur la seconde et enfin la valeur de ce pixel (en nuance de gris) sur la troisième et dernière colonne.
    Je ne vois pas très bien l'intérêt de la démarche…

    À quoi va donc servir ce tableau (si ce n'est prendre inutilement trois fois plus de mémoire) ?
    Ingénieur indépendant en mécatronique - Conseil, conception et formation
    • Conception mécanique (Autodesk Fusion 360)
    • Impression 3D (Ultimaker)
    • Développement informatique (Python, MATLAB, C)
    • Programmation de microcontrôleur (Microchip PIC, ESP32, Raspberry Pi, Arduino…)

    « J'étais le meilleur ami que le vieux Jim avait au monde. Il fallait choisir. J'ai réfléchi un moment, puis je me suis dit : "Tant pis ! J'irai en enfer" » (Saint Huck)

  3. #3
    Futur Membre du Club
    Homme Profil pro
    ingénieur optique / photonique
    Inscrit en
    Juin 2016
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : ingénieur optique / photonique

    Informations forums :
    Inscription : Juin 2016
    Messages : 9
    Points : 5
    Points
    5
    Par défaut
    Le but de ce tableau est de simplifier les calculs que je vais faire par la suite car sinon je me perds dans les indexages pour les formules que je veux utiliser.
    Il est probable que ce ne soit pas la façon ultime de procéder mais pour l'instant, j'ai besoin de ce tableau

    Comme justement c'est déjà de la prise de mémoire et de calcul, je voudrais bien simplifier tout ça

  4. #4
    Rédacteur/Modérateur

    Avatar de Jerome Briot
    Homme Profil pro
    Freelance mécatronique - Conseil, conception et formation
    Inscrit en
    Novembre 2006
    Messages
    20 302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance mécatronique - Conseil, conception et formation

    Informations forums :
    Inscription : Novembre 2006
    Messages : 20 302
    Points : 52 882
    Points
    52 882
    Par défaut
    Un exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    m = 2;
    n = 3;
     
    M = rand(m,n)
     
    [column, row] = meshgrid(1:n, 1:m)
     
    [row(:) column(:) M(:)]
    Ingénieur indépendant en mécatronique - Conseil, conception et formation
    • Conception mécanique (Autodesk Fusion 360)
    • Impression 3D (Ultimaker)
    • Développement informatique (Python, MATLAB, C)
    • Programmation de microcontrôleur (Microchip PIC, ESP32, Raspberry Pi, Arduino…)

    « J'étais le meilleur ami que le vieux Jim avait au monde. Il fallait choisir. J'ai réfléchi un moment, puis je me suis dit : "Tant pis ! J'irai en enfer" » (Saint Huck)

  5. #5
    Futur Membre du Club
    Homme Profil pro
    ingénieur optique / photonique
    Inscrit en
    Juin 2016
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : ingénieur optique / photonique

    Informations forums :
    Inscription : Juin 2016
    Messages : 9
    Points : 5
    Points
    5
    Par défaut
    Merci!
    Ta solution permet de simplifier mon travail.

    Mais j'aimerais quand même bien comprendre pourquoi mon programme "malin" fonctionnait aussi lentement.
    Si quelqu'un a la réponse, ca me permettrait de mieux comprendre ce que je fais à l'avenir.

    Merci

  6. #6
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2011
    Messages
    265
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 265
    Points : 352
    Points
    352
    Par défaut
    Citation Envoyé par cimon Voir le message
    Bonjour à tous!

    J'ai un problème de temps de calcul dans un programme et je ne comprends pas mon erreur de raisonnement, et comment l'améliorer si possible

    Voilà, mon but est de créer un tableau ayant pour chaque pixel d'une image la coordonnée d'abscisse d'un sur la première colonne, la coordonnées d'ordonnée sur la seconde et enfin la valeur de ce pixel (en nuance de gris) sur la troisième et dernière colonne.

    1 1 valeur
    2 1 valeur
    1 2 valeur
    2 2 valeur

    Voilà ce que ca donne pour une matrice 2x2.

    J'ai commencé par le faire de façon un peu bourrin:
    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
     
    coord_intens=zeros(1310720,3);  % je créé la matrice finale à la bonne taille (1024 * 1280 pixel = 1310720 lignes)
     
    %remplissage de la seconde colonne
    a=-1280;
    for i = 1:1024
        a=a+1280;
        coord_intens(1+a:1280+a,2)=1+a/1280;
    end
     
    % remplissage de la première colonne
    for j = 1:1280
        for n = 0:1023                       
            coord_intens((j+(n*1280)),1)=j;  
        end
    end
     
    % Remplissage de la dernière colonne avec les valeurs d'intensité 
    for k = 1:1310720
            coord_intens(k,3)=image(coord_intens(k,1),coord_intens(k,2));
    end
    %on utilise les coordonnées déjà enregistrées dans les deux première colonnes pour remplir la troisième.
    Avant tout: il fonctionne.
    En analysant un peu, j'ai deux boucles simples, dont une avec plus d'un million d'éléments, et une double boucle.
    Je me suis dis que je pouvais faire bien mieux. Alors j'ai utilisé les indexages intelligent de matlab et la fonction ind2sub pour n'avoir plus qu'une seule simple boucle.
    Voilà ce que ça donne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    coord_intens=zeros(1310720,3); %idem, on créé en avance la matrice finale
     
    for i=1:1310720  %une seule simple boucle 
        [ligne, colonne]=ind2sub(size(img),i);
     
        coord_intens(i,1)=ligne; %Pour chaque ligne, on rempli ligne et colonne
        coord_intens(i,2)=colonne; 
        coord_intens(i,3)=img(coord_intens(i,1),coord_intens(i,2)); 
    % et enfin on rempli la dernière colonne en utilisant les deux 1ere, comme avant
    end
    Là je me suis dis: Génial j'ai carrement gagné en complexité! Et en plus il fonctionne lui aussi
    Mais en pratique, quand j'applique le programme, le premier fonctionne en quelques secondes (3 ou 4) quand le second (celui qui est censé être malin) fonctionne en 30 ou 40 secondes!

    Qu'est ce qui peut bien se passer? Pourquoi ça ne fonctionne pas? Et surtout que devrais-je faire? Garder ma première version alors qu'elle me paraît moche ou travailler pour améliorer encore la seconde?

    En espérant avoir été assez clair dans mes explications, je vous remercie d'avance pour votre aide

    Simon
    pour la lenteur tu as quand même une boucle for sur plus d'un million de points avec des accès à une image. la lenteur ne m’étonne pas.
    après tu peux remplacer ta dernière boucle par le code ci dessous et la je pense que ce sera bien plus rapide

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    coord_intens=zeros(1310720,3); %idem, on créé en avance la matrice finale
     
    ind=1:size(img,1)*size(img,2);%
     [ligne, colonne]=ind2sub(size(img),ind);
     coord_intens(:,1)=ligne; %Pour chaque ligne, on rempli ligne et colonne
     coord_intens(:,2)=colonne; 
     coord_intens(:,3)=img(ind);% (je me demade si img(:) ==img(ind), il me semble que oui, à tester)

Discussions similaires

  1. Calcul de rendement grâce au solveur
    Par delma dans le forum Macros et VBA Excel
    Réponses: 0
    Dernier message: 22/02/2011, 10h24
  2. Faire une boucle pour facilité le calcul
    Par r_dani dans le forum Macro
    Réponses: 2
    Dernier message: 25/03/2009, 12h52
  3. [TP7] Calculer sin, cos, tan, sqrt via le FPU
    Par zdra dans le forum Assembleur
    Réponses: 8
    Dernier message: 25/11/2002, 04h09
  4. Récupérer 10 nb différents avec un calcul aléatoire
    Par BXDSPORT dans le forum Langage
    Réponses: 3
    Dernier message: 04/08/2002, 02h35
  5. Algo de calcul de FFT
    Par djlex03 dans le forum Traitement du signal
    Réponses: 15
    Dernier message: 02/08/2002, 17h45

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