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 :

Optimiser algorithme de kernel smoothing


Sujet :

MATLAB

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Juin 2010
    Messages
    319
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Juin 2010
    Messages : 319
    Par défaut Optimiser algorithme de kernel smoothing
    Bonjour à tous,

    Le titre a l'air barbare, mais le vrai problème est de pouvoir enlever la boucle "for" de l'algorithme qui est présenté ci-dessous :
    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
    function estimated = kernel_smoothing( time, diracVect, Sf, KW)
     
    Ts = 1/Sf;    %Sampling Time
    estimated = zeros(length(time), 1);
    N = length(time);
    n = 1:N;
    %check that time starts from 0 second
    rescaled_time = time - time(1);
     
    for k = 1:N
     
        inside_b = abs( k*Ts - rescaled_time(n) )/KW;
        b_res = Gaussian_kernel_func(inside_b);
     
        numerator = sum(diracVect .* b_res);
        denominator = sum(b_res);
     
        estimated(k) = numerator/denominator;
    end
     
    end
    En effet, plus le signal 1D (fourni ici dans le paramètre "diracVect") à traiter est grand, plus l'algorithme prends du temps à s'exécuter, ce qui est normal ... Mais cela peut atteindre plusieurs dizaines de minutes pour moins de 10 minutes de signal !!

    J'ai essayé plusieurs tentatives depuis hier, mais aucune ne m'a apporté satisfaction (au niveau temps ou résultat final).

    Ca serait pas mal si quelqu'un pouvait ne serait-ce que m'aiguiller vers une bonne solution


    PS : pour l'histoire, la fonction gaussienne est la suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    function r = Gaussian_kernel_func(u)
    %
    %        [ exp((-u^2)/2))    if -5 <= u <= 5
    % b(u) = {
    %        [ 0    otherwise
    %
     
    in_bound = find( (-5 <= u) & (u <= 5));
     
    r = zeros(size(u));
     
    r(in_bound) = exp((-u(in_bound).^2)/2);
    end

  2. #2
    Expert confirmé
    Avatar de duf42
    Homme Profil pro
    Formateur en informatique
    Inscrit en
    Novembre 2007
    Messages
    3 111
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Formateur en informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 111
    Par défaut
    Bonjour,

    A première vue j'ai comme l'impression que ta boucle ne sert à rien ou plutôt que tu effectue N fois le même calcul (ton N n'est pas utilisé dans la boucle)

    Il y a sans doute un truc que je n'ai pas vu mais as-tu essayé en enlevant purement et simplement la boucle.

    Duf

  3. #3
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Juin 2010
    Messages
    319
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Juin 2010
    Messages : 319
    Par défaut
    Bonjour duf42,

    En effet, N n'est pas réutilisé tel quel, et ne sert qu'à marquer l'indice du dernier point.

    Pour résumer l'action de la fonction, chaque nouveau point k du nouveau signal estimé ("estimated") est calculé par un moyennage gaussien du signal fourni en entrée ("diracVect") dans les alentours de k.

    Ainsi, ce nouveau point en k dépendra des valeurs à environ une seconde avant et après ce même point k du signal d'entrée.

    J'ai donc besoin de la boucle (dans l'état actuel des choses) pour calculer, pas à pas, les nouveaux points du signal estimé. Mais comme la boucle me prends trop de temps ...


    * Je ne sais pas si je suis suffisamment clair, demandez-moi plus de précisions si besoin *

  4. #4
    Expert confirmé
    Avatar de duf42
    Homme Profil pro
    Formateur en informatique
    Inscrit en
    Novembre 2007
    Messages
    3 111
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Formateur en informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 111
    Par défaut
    Ah oui autant pour moi, comme d'habitude j'ai lu trop vite...

    Aurais-tu un échantillon de données pour tester?

  5. #5
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Juin 2010
    Messages
    319
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Juin 2010
    Messages : 319
    Par défaut
    Bien sûr

    Compter plus de 20 secondes de calcul pour 22k5 points échantillonés ... il faut être patient


    EDIT : La pause café m'a donné une idée, qui serait d'utiliser "meshgrid" de la façon suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    %check that time starts from 0 second
    rescaled_time = time - time(1);
     
    [meshG_time, meshG_kTs] = meshgrid(n.*Ts, rescaled_time(n));
     
    inside_b = abs( meshG_kTs - meshG_time )/KW;
    b_res = Gaussian_kernel_func(inside_b);
     
    numerator = sum(diracVect * b_res, 2);
    denominator = sum(b_res, 2);
     
    estimated = numerator/denominator;

    Je pense que cette méthode devrait résoudre mon problème de temps. Cependant, MatLab me fournit une erreur de mémoire (alors que je suis en version 7.5 et que je ne dépasse pas 2^31 en taille , comme préconisé ici !!)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Maximum variable size allowed by the program is exceeded.
     
    Error in ==> meshgrid at 44
    Fichiers attachés Fichiers attachés

  6. #6
    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,
    Citation Envoyé par vampirella Voir le message
    Cependant, MatLab me fournit une erreur de mémoire (alors que je suis en version 7.5 et que je ne dépasse pas 2^31 en taille , comme préconisé ici !!)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Maximum variable size allowed by the program is exceeded.
     
    Error in ==> meshgrid at 44
    C'est spécifié que tu peux atteindre 2^31 éléments sur un système 64 bit.

    Avec meshgrid tu cherche à créer des données de tailles :
    25500*25500*8 = environ 4Gb ce qui est au-dessus de la capacité des systèmes 32 bit.
    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.

  7. #7
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Juin 2010
    Messages
    319
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Juin 2010
    Messages : 319
    Par défaut
    En effet, cela fonctionne encore un peu au ralenti, mais cela donne quelque chose.

    Pour la fin mot de l'histoire, j'ai trouvé une autre implémentation de kernel smoothing qui, je doit bien l'avouer, est plus élégante que tout ce que je pourrais essayer de bricoler ...

    J'ai tout de même repris ton idée, Magelan, et avec des calculs de kernel sur 2*Fe points (Fe = Fréquence d'échantillonnage), je tombe à moins de 15 secondes de calculs pour 25 minutes d'enregistrements à 125 Hz.

    C'est résolu pour ma part.

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

Discussions similaires

  1. Optimiser algorithme C++
    Par CliffeCSTL dans le forum Débuter
    Réponses: 8
    Dernier message: 24/04/2014, 12h42
  2. Estimation par la méthode des noyaux (kernel smoothing)
    Par mikael.jaffre dans le forum MATLAB
    Réponses: 0
    Dernier message: 20/10/2011, 14h28
  3. Optimisation Algorithme ?
    Par Deva74 dans le forum Algorithmes et structures de données
    Réponses: 1
    Dernier message: 13/03/2010, 08h51
  4. [Optimisation] Algorithme de réduction
    Par tromaltsec dans le forum Algorithmes et structures de données
    Réponses: 8
    Dernier message: 06/08/2009, 14h26
  5. Optimisation algorithme de programmation
    Par mp_moreau dans le forum Algorithmes et structures de données
    Réponses: 2
    Dernier message: 29/07/2007, 19h24

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