2017-04-22 5 views
1

Existe-t-il un moyen de calculer le Cobb-Douglas utility function plus rapidement en Python. Je cours des millions de temps, donc une augmentation de la vitesse aiderait. La fonction soulève des éléments de quantités_list à la puissance des éléments correspondants de la liste des exposants, puis multiplie tous les éléments résultants.Python exponentiation de deux performances de la liste

n = 10 

quantities = range(n) 
exponents = range(n) 

def Cobb_Douglas(quantities_list, exponents_list): 
    number_of_variables = len(quantities_list) 
    value = 1 
    for variable in xrange(number_of_variables): 
     value *= quantities_list[variable] ** exponents_list[variable] 
    return value 

t0 = time.time() 
for i in xrange(100000): 
    Cobb_Douglas(quantities, exponents) 
t1 = time.time() 
print t1-t0 
+1

Jetez un oeil à la bibliothèque 'numpy' pour les opérations numériques rapides. – BrenBarn

+1

Numpy est un peu plus lent dans ce cas – user58925

+0

Avez-vous vu [this] (https://stackoverflow.com/questions/31027863/cobb-douglas-functions-slows-running-tremendously-how-to-expedite-a-non- linéaire) question? Il offre un potentiel d'accélération. – Darkstarone

Répondre

1

Les itérateurs sont vos amis. Je suis un 28% sur mon ordinateur speedup en changeant votre boucle à ceci:

for q, e in itertools.izip(quantities_list, exponents_list): 
    value *= q ** e 

J'ai aussi obtenu des résultats similaires lors du passage de votre boucle à un appel, il ne vaut pas functools.reduce fournir un exemple de code.


En général, numpy est le bon choix pour les opérations arithmétiques rapides, mais le plus grand type entier de numpy est de 64 bits, qui ne tiendrez pas le résultat de votre exemple. Si vous utilisez une plage numérique ou type arithmétique, numpy est roi:

quantities = np.array(quantities, dtype=np.int64) 
exponents = np.array(exponents, dtype=np.int64) 

def Cobb_Douglas(quantities_list, exponents_list): 
    return np.product(np.power(quantities_list, exponents_list)) 
# result: 2649120435010011136 
# actual: 21577941222941856209168026828800000 
+0

Merci. Moi aussi j'obtiens une accélération de 10-25% avec itertools, mais presque 5 fois le ralentissement avec numpy .. J'utilise un Mac – user58925

+1

Bizarre-même. Quel est le jeu de données sur lequel vous travaillez? Sa taille et son type de données peuvent faire la différence. –

1

quelques suggestions:

  1. Utilisez Numpy

  2. Vectorize votre code

  3. Si les quantités sont grandes et que rien ne sera nul ou négatif, travaillez dans l'espace de journal.

J'ai obtenu environ un gain de vitesse de 15% localement:

def np_Cobb_Douglas(quantities_list, exponents_list): 
    return np.product(np.power(quantities_list, exponents_list)) 

Et environ 40% en utilisant:

def np_log_Cobb_Douglas(quantities_list, exponents_list): 
    return np.exp(np.dot(np.log(quantities_list), np.log(exponents_list))) 

Last but not least, il devrait y avoir une certaine mise à l'échelle de votre Cobb -Douglas paramètres de sorte que vous ne courez pas dans les erreurs de débordement (si je me souviens de ma macro intro correctement).

+0

Merci. Pour mon application, numpy est considérablement plus lent. – user58925

+0

Peut-être que vous pouvez développer votre application/implémentation? Faire cela en utilisant des vecteurs/BLAS devrait fournir une accélération décente, ce qui est ce que je vois en utilisant le code minimal que vous avez fourni. –