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 :

optimisation d'un bout de code


Sujet :

MATLAB

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite
    Avatar de ol9245
    Homme Profil pro
    Chercheur
    Inscrit en
    Avril 2007
    Messages
    985
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Avril 2007
    Messages : 985
    Billets dans le blog
    1
    Par défaut optimisation d'un bout de code
    Bonjour à tous,

    J'ai la tête un peu dasn le pâté, donc je fais appel à vos lumières en cas de solution simple et triviale :
    Je voudrais supprimer la boucle dans le code suivant. Note importante : le vecteur index possède des répétitions, comme dans le bout de code d'exemple.

    Merci++ de votre aide.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    index = [1 2 3 2 5 2 6] ; % c'est un exemple. dans la réalité index fait jusqu'à 10000 valeurs.
    M = zeros(1, 10) ; % c'est un exemple. dans la réalité M est une matrice 1000 x 1000
    a = 0.2 ;
    for k=1:numel(index)
       M(index(k)) = M(index(k)) + a ;
    end

  2. #2
    Membre émérite
    Avatar de ol9245
    Homme Profil pro
    Chercheur
    Inscrit en
    Avril 2007
    Messages
    985
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Avril 2007
    Messages : 985
    Billets dans le blog
    1
    Par défaut
    en attendant vos lumières, j'ai écrit cette hideuse béquille :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    function M = ajouter (M, idx, a)
    % ajoute à M la valeur a pour tous les index idx (avec répétition)
    idx = sort(idx(:)) ; % trie les index à traiter
    while numel(idx)>0
        df = [1; diff(idx)] ; % repère les doublons
        unefois = idx(df>0) ; % sélectionne les index sans doublons
        M(unefois) = M(unefois)+a ; % ajoute a à M sur les index non doublonnés
        idx = idx(df==0) ; % supprime les éléments traités
    end
    qui marche comme ça par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >> M = zeros(1,10) ;
    M = ajouter (M, [5 4 3 2 1 5 1 2 3 2 3 4 4 5 5 6], 1)
     
    M =
     
         2     3     3     3     4     1     0     0     0     0
    peut-on faire plus élégant ? et plus rapide (éviter le tri, en particulier) ?
    merci

  3. #3
    Modérateur

    Homme Profil pro
    Ingénieur en calculs scientifiques
    Inscrit en
    Août 2007
    Messages
    4 639
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Ingénieur en calculs scientifiques

    Informations forums :
    Inscription : Août 2007
    Messages : 4 639
    Par défaut
    Salut,

    pour éviter la boucle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    index = [1 3 2 2 5 2 6] ;
    M = zeros(1, 10) ;
    a = 0.2 ;
     
    [B,I,J] = unique(index);
    h = hist(J,length(B));
    MM(B) = M(B)+a.*h;
    Par contre je vois pas comment tu pourrais éviter le tri (ici c'est la fonction unique qui s'en charge).
    Pour une bonne utilisation des balises code c'est ici!
    Petit guide du voyageur MATLABien : Le forum La faq Les tutoriels Les sources


    La nature est un livre écrit en langage mathématique. Galilée.

  4. #4
    Membre émérite
    Avatar de ol9245
    Homme Profil pro
    Chercheur
    Inscrit en
    Avril 2007
    Messages
    985
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Avril 2007
    Messages : 985
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par magelan Voir le message
    Salut,

    pour éviter la boucle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    index = [1 3 2 2 5 2 6] ;
    M = zeros(1, 10) ;
    a = 0.2 ;
     
    [B,I,J] = unique(index);
    h = hist(J,length(B));
    MM(B) = M(B)+a.*h;
    Par contre je vois pas comment tu pourrais éviter le tri (ici c'est la fonction unique qui s'en charge).
    Bonne pioche. Ton code est plus de 10 fois plus rapide que le mien sur mes données

    Je laisse le fil ouvert quelques heures au cas ou ...

  5. #5
    Rédacteur/Modérateur

    Avatar de Jerome Briot
    Homme Profil pro
    Freelance mécatronique - Conseil, conception et formation
    Inscrit en
    Novembre 2006
    Messages
    20 317
    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 317
    Par défaut
    N'arrivant pas bien à comprendre avec exactitude la forme des données de ton problème, voici quelques petites suggestions...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    index = [1 2 3 2 5 2 6] ;
    a = 0.2 ;
    M = histc(index,1:10)*a;
    ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    index = [1 2 3 2 5 2 6] ;
    M = zeros(1,10);
    a = 0.2 ;
    v = 1:max(index);
    M(v) = histc(index,v)*a;
    ou encore

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    index = [1 2 3 2 5 2 6] ;
    a = 0.2 ;
    M = histc(index,1:max(index))*a;
    Pour bien comprendre, la variable index contient les indices linéaires de certains éléments de la matrice M (1000x1000), c'est ça ?

  6. #6
    Membre émérite Avatar de tubaas
    Homme Profil pro
    Acousticien
    Inscrit en
    Août 2009
    Messages
    641
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Acousticien
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2009
    Messages : 641
    Par défaut
    salut
    une proposition différente mais moins efficace (en même temps c'est normal qu'une fonction comme HISTC soit plus optimisée...)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    function M=toto(index,a)
    M=a*arrayfun(@(x)countInd(x,index),1:10);
     
    function y=countInd(x,index)
    y=sum(index==x);
    j'ai essayé différentes façons de compter mais les temps d'exécution restent similaires sur ton petit exemple

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

Discussions similaires

  1. Optimisation d'un bout de code
    Par Décembre dans le forum MATLAB
    Réponses: 6
    Dernier message: 13/10/2011, 23h47
  2. Réponses: 9
    Dernier message: 02/10/2010, 12h43
  3. Optimiser un bout de code VB
    Par ted the Ors dans le forum Macros et VBA Excel
    Réponses: 7
    Dernier message: 10/07/2008, 21h48
  4. Optimisation d'un bout de code
    Par Lost in dans le forum MATLAB
    Réponses: 3
    Dernier message: 29/04/2008, 22h58

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