2017-04-22 4 views
1

파이썬에서 Cobb-Douglas utility function을 더 빠르게 계산할 수있는 방법이 있습니까? 수백만 시간을 실행하므로 속도가 향상됩니다. 이 함수는 수량 목록의 요소를 지수 목록의 해당 요소의 지수로 올린 다음 모든 결과 요소를 곱합니다.두 개의 파이썬 지수가 지수를 나열합니다.

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

빠른 숫자 연산을위한'numpy' 라이브러리를보십시오. – BrenBarn

+1

Numpy는이 경우 더 느립니다. – user58925

+0

[이] (https://stackoverflow.com/questions/31027863/cobb-douglas-functions-slows-running-tremendously-how-to-expedite-a-non- 선형) 질문? 잠재적 인 속도 향상을 제공합니다. – Darkstarone

답변

1

반복자는 친구입니다. functools.reduce 전화로 루프를 전환 할 때

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

가 나는 또한 비슷한 결과를 가지고, 그래서 코드 샘플을 제공하는 가치가 없어 : 나는이에 루프를 전환하여 내 컴퓨터의 28 %의 속도 향상을 얻었다. 일반적으로


, numpy 빠른 연산에 최적의 선택이 될 것입니다,하지만 numpy의 가장 큰 정수 유형은 예를 들어 결과를 저장하지 않습니다 64 비트입니다. 제안

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

감사합니다. 저도 itertools로 10-25 %의 속도 향상을 얻었지만 numpy로 거의 5 배의 속도 저하를 보았습니다. Mac을 사용하고 있습니다 – user58925

+1

이상합니다. 당신이 계산하고있는 실제 데이터 세트는 무엇입니까? 크기와 데이터 유형이 차이를 만들 수 있습니다. –

1

커플 : 다른 숫자 범위 나 산술 형식을 사용하는 경우, numpy은 왕

  • 벡터화 코드

    1. 사용 NumPy와

    2. 수량이 크고 아무 것도 0이거나 음수가 아닌 경우 로그 공간에서 작업하십시오. 사용

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

      약 40 % :

    나는 사용하여 로컬 15 %의 속도 향상에 대해 가지고

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

    마지막으로, 당신의 콥의 ​​일부 스케일링이 있어야한다 -Douglas 매개 변수를 사용하면 오버 플로우 오류가 발생하지 않도록 할 수 있습니다 (내 소개 매크로를 올바르게 기억하고있는 경우).

  • +0

    감사합니다. 내 응용 프로그램의 경우 numpy는 상당히 느립니다. – user58925

    +0

    응용 프로그램/구현이 확장 될 수 있습니까? 벡터/BLAS를 사용하여이 작업을 수행하면 알맞은 속도 향상을 제공해야하는데, 이는 사용자가 제공 한 최소 코드를 사용하여 볼 수 있습니다. –