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

R Discussion :

Plus de 100000 fonctions à calculer rapidement


Sujet :

R

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Août 2009
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 7
    Par défaut Plus de 100000 fonctions à calculer rapidement
    Question : est-il possible d'accélérer ce calcul ?

    A chaque élément x[i] d'un vecteur de valeurs numériques, j'associe l'élément [i] correspondant d'un vecteur composé de fonctions simples de la seule variable x. Ces fonctions sont données sous forme d'une chaine de caractères de la forme "<expression>". Difficulté : ces fonctions sont toutes différentes (le calcul avec une même fonction est instantané).

    Après plusieurs tentatives -utilisation de la fonction outer par exemple - je n'ai pas trouvé plus rapide que l'écriture triviale :
    (calcul très long car il prend 23.5s pour 100000 valeurs)

    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
    #-------------------------------------------
    #test 
    rm(list=ls(all=TRUE))
    long1=100000 #nombre de lignes
    #
    #génération de valeurs et de fonctions pour test
    x1<-double(long1)
    x1<-seq(1.1,110,length=long1)
    #fonctions simples entre ""
    sexpr0<-character(long1)
    for (i in 1:long1) {
    sexpr0[i]<-paste("x*x+", as.character(i), ".0", sep="")
    }
    sexpr0[1] # "x*x+1.0"
    sexpr0[long1-1] # "x*x+99999.0"
    sexpr0[long1]# "x*x+100000.0"
    #
    y1<-double(long1)
    #-------------------------------
    #calcul de chaque valeur 
    system.time(for (i in 1:long1) {
    x<-x1[i]
    y1[i]<-eval(parse(text=sexpr0[i]))
    })
     
    x1[1]
    y1[1]		#2.21
    x1[long1-1]
    y1[long1-1]	# 112098.8
    x1[long1]	
    y1[long1]	# 112100
    La solution devrait être dans la vectorisation des expressions mais je n'ai pas trouvé !

  2. #2
    Membre Expert
    Avatar de pitipoisson
    Homme Profil pro
    Chercheur
    Inscrit en
    Septembre 2006
    Messages
    1 942
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Chercheur
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Septembre 2006
    Messages : 1 942
    Par défaut
    Bonjour et bienvenue,

    Pour la première boucle, la vectorisation est simple, dommage que ce ne soit pas la plus longue ! Pour la seconde, je pense que tu peux accélérer la chose avec un sapply (quoique, après test je ne vois pas de différence marquée... sont pourtant sensées être optimisées ces fonctions) :
    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
    ##-------------------------------------------
    ## test
    rm(list=ls(all=TRUE))
    long1 <- 100000 #nombre de lignes
    #
    ## génération de valeurs et de fonctions pour test
    x1 <- double(long1)
    x1 <- seq(1.1,110,length=long1)
    
    
    ## fonctions simples entre ""
    sexpr0 <- paste("x*x+", as.character(1:long1), ".0", sep="")
    
    
    sexpr0[1]                               # "x*x+1.0"
    sexpr0[long1-1]                         # "x*x+99999.0"
    sexpr0[long1]                           # "x*x+100000.0"
    
    ##-------------------------------
    ## calcul de chaque valeur
    
    ## Sensé être plus rapide, mais c'est pas hyper probant :
    eval1 <- function(i)
    {
        return(eval(parse(text=sexpr0[i]), envir=list(x=x1[i])))
    }
    #
    system.time(y1 <- sapply(1:long1, eval1))
    
    x1[1]
    y1[1]                                   # 2.21
    x1[long1-1]
    y1[long1-1]                             # 112098.8
    x1[long1]
    y1[long1]                               # 112100
    Edit: c'est la fonction parse qui induit des temps de calculs aussi longs. Si tu la déplace dans la première boucle (pour le coup, il faut utiliser un sapply), celle-ci devient horriblement longue alors que la seconde passe à 2s.

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Août 2009
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 7
    Par défaut Vectorisation dela fonction parse()
    Merci pour cette réponse très rapide. Belle écriture sans boucle ! On ne peut que constater que pour la fonction parse(), la vectorisation ne donne pas de gain de vitesse significatif. Une solution plus rapide serait peut être d'utiliser un parser spécialisé du type "calculette scientifique" ; à trouver...

  4. #4
    Membre Expert
    Avatar de pitipoisson
    Homme Profil pro
    Chercheur
    Inscrit en
    Septembre 2006
    Messages
    1 942
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Chercheur
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Septembre 2006
    Messages : 1 942
    Par défaut Comment gagner 30s
    Citation Envoyé par BPStA Voir le message
    On ne peut que constater que pour la fonction parse(), la vectorisation ne donne pas de gain de vitesse significatif.
    Je ne pense pas qu'on puisse réellement parler de vectorisation dans ce cas, je vois ça plutôt comme une boucle déguisée (la fonction parse est rappelée pour chaque valeur de i).

    En revanche, c'est tout bête, mais on peut réellement vectoriser l'appel à parse et là pour le coup, on gagne un temps fou :
    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
    ## Liste d'expressions :
    system.time(
                sexpr0 <- parse(text=as.expression(paste("x*x+", as.character(1:long1), ".0", sep="")))
               )
    
    sexpr0[[1]]                               # x*x+1
    sexpr0[[long1-1]]                         # x*x+99999
    sexpr0[[long1]]                           # x*x+100000
    
    ##-------------------------------
    ## calcul de chaque valeur
    
    ## Sensé être plus rapide, et c'est hyper probant :
    eval1 <- function(i)
    {
        return(eval(sexpr0[i], envir=list(x=x1[i])))
    }
    ##
    system.time(y1 <- sapply(1:long1, eval1))
    
    x1[1]
    y1[1]                                   # 2.21
    x1[long1-1]
    y1[long1-1]                             # 112098.8
    x1[long1]
    y1[long1]                               # 112100
    Pour info, en mettant parse dans le calcul sexpr0, je passe de >31s avec un sapply à ~2.5s comme ça !

    Edit: en exécutant tout le script, je passe de plus de 33s à moins de 5 ! Le titre est donc à peine exagéré.

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

Discussions similaires

  1. Calcul rapide de percentiles
    Par benj63 dans le forum Algorithmes et structures de données
    Réponses: 6
    Dernier message: 08/12/2006, 14h50
  2. Calcul rapide d'une exponentielle ?
    Par progfou dans le forum Algorithmes et structures de données
    Réponses: 1
    Dernier message: 13/04/2006, 21h12
  3. Fonction : calculer le dividende net à payer
    Par Bernard123 dans le forum Access
    Réponses: 5
    Dernier message: 27/10/2005, 14h45
  4. [Optimisation][Fonction]calcul du nombre de jours ...
    Par m-mas dans le forum MS SQL Server
    Réponses: 6
    Dernier message: 26/10/2005, 14h39
  5. Réponses: 18
    Dernier message: 15/11/2004, 11h07

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