νμ΄μ¬μμ
μ¬κΈ°μ μ λ ν¬κΈ°μ numpy λ°°μ΄ μ΄λ©° ν¬κΈ°μ numpy λ°°μ΄μ λλ€ . ν¬κΈ° μ μ΅λ μ½ 10000 μΌ μ μμΌλ©°μ΄ ν¨μλ μ¬λ¬ λ² νκ° λ λ΄λΆ 루νμ μΌλΆμ΄λ―λ‘ μλκ° μ€μν©λλ€.
μμ€
μμ΄
μ
μΌμ΄
μΓμ
μ
μ΄μμ μΌλ‘λ for 루νλ₯Ό νΌνκ³ μΆμ§λ§ μΈμμ λμ΄ μλ€λ©΄ μΈκ³μ λμ΄ μλλΌκ³ μκ°ν©λλ€. λ¬Έμ λ λͺ κ°μ μ€μ²© 루νλ₯Ό μ¬μ©νμ§ μκ³ μ΄λ»κ² ν΄μΌνλμ§ μμ§ λͺ»νλ€λ κ²μ΄λ―λ‘ λ€μ λλ €μ§ μ μμ΅λλ€.
λꡬλ μ§ ν¨μ¨μ μ΄κ³ μ½κΈ° μ¬μ΄ λ°©μμΌλ‘ numpyλ₯Ό μ¬μ©νμ¬ μμ λ°©μ μμ νννλ λ°©λ²μ λ³Ό μ μμ΅λκΉ? λ μΌλ°μ μΌλ‘, μ΄λ° μ’ λ₯μ κ²μ μ κ·Όνλ κ°μ₯ μ’μ λ°©λ²μ 무μμ λκΉ?
λ΅λ³
μ¬κΈ° Numba μ루μ μ΄ μμ΅λλ€. λ΄ μ»΄ν¨ν°μμ Numba λ²μ μ λ°μ½λ μ΄ν°κ°μλ νμ΄μ¬ λ²μ λ³΄λ€ 1000 λ°° μ΄μ λΉ λ¦ λλ€ (200Γ200 λ§€νΈλ¦μ€ βkβλ° 200 κΈΈμ΄ λ²‘ν° βaβ). λν νΈμΆ λΉ μ½ 10 λ§μ΄ν¬λ‘ μ΄λ₯Ό μΆκ°νλ @autojit λ°μ½λ μ΄ν°λ₯Ό μ¬μ©νμ¬ λμΌν μ½λκ° μ¬λ¬ μ νμμ μλ ν μ μμ΅λλ€.
from numba import jit, autojit
@jit('f8[:](f8[:,:],f8[:])')
#@autojit
def looped_ver(k, a):
x = np.empty_like(a)
for i in range(x.size):
sm = 0.0
for j in range(0, i+1):
sm += k[i-j,j] * a[i-j] * a[j]
x[i] = sm
return x
κ³΅κ° : μ λ Numba κ°λ°μ μ€ ν λͺ μ λλ€.
λ΅λ³
μ¬κΈ°μ μμμ΄ μμ΅λλ€. 첫째, μ€μμ λν΄ μ¬κ³Όλ립λλ€.
λλ λ κ°μ§ λ€λ₯Έ μ κ·Ό λ°©μμΌλ‘ μ€ννμ΅λλ€. λλ ν©κ³μ λν νκ³μ μ½κ° νΌλ μ€λ¬μ λ€. μλλΌ μνμ΄ μ΄μ΄μΌ νλκ°?
λλλλβ1
νΈμ§ : μλμ€, μ§λ¬Έμ μ 곡λ μνμ΄ μ ννμ΅λλ€. λ€λ₯Έ λ΅λ³μ΄ λμΌν μ½λλ₯Ό μ¬μ©νκΈ° λλ¬Έμ μ¬κΈ°μ κ·Έλλ‘ λμμ§λ§ ν΄κ²° λ°©λ²μ κ°λ¨ν©λλ€.
λ¨Όμ λ°λ³΅ λ²μ :
def looped_ver(k, a):
x = np.empty_like(a)
for i in range(x.size):
sm = 0
for j in range(0, i+1):
sm += k[i-j,j] * a[i-j] * a[j]
x[i] = sm
return x
λλ κ·Έκ²μ numpy μ¬λΌμ΄μ€λ‘ λ¨μΌ 루νλ‘ λ§λ€μμ΅λλ€.
def vectorized_ver(k, a):
ktr = zeros_like(k)
ar = zeros_like(k)
sz = len(a)
for i in range(sz):
ktr[i,:i+1] = k[::-1].diagonal(-sz+i+1)
a_ = a[:i+1]
ar[i,:i+1] = a_[::-1] * a_
return np.sum(ktr * ar, 1)
λ λͺ μ μ 루νκ° νλ μΈ numpy λ²μ μ λ΄ μ»΄ν¨ν°μμ μ½ 25 λ°° λΉ λ¦ λλ€ .
μ=5000κ·Έλ° λ€μ (λ μ½κΈ° μ¬μ΄) λ°λ³΅ μ½λμ Cython λ²μ μ μμ±νμ΅λλ€.
import numpy as np
import cython
cimport numpy as np
@cython.boundscheck(False)
@cython.wraparound(False)
def cyth_ver(double [:, ::1] k not None,
double [:] a not None):
cdef double[:] x = np.empty_like(a)
cdef double sm
cdef int i, j
for i in range(len(a)):
sm = 0.0
for j in range(i+1):
sm = sm + k[i-j,j] * a[i-j] * a[j]
x[i] = sm
return x
λ΄ λ ΈνΈλΆμμ μ΄κ²μ 루ν λ²μ λ³΄λ€ μ½ 200 λ°° λΉ λ₯΄λ©° (1 루ν 벑ν°ν λ²μ λ³΄λ€ 8 λ°° λΉ λ¦ λλ€). λ€λ₯Έ μ¬λλ€μ΄ λ μν μ μλ€κ³ νμ ν©λλ€.
λλ Julia λ²μ μ κ°μ§κ³ λμμΌλ©° Cython μ½λμ λΉμ·ν κ²μΌλ‘ 보μμ΅λλ€.
λ΅λ³
λΉμ μ΄ μνλ κ²μ 컨볼 루μ
μΈ κ² κ°μ΅λλ€. κ·Έκ²μ λ¬μ±νλ κ°μ₯ λΉ λ₯Έ λ°©λ²μ numpy.convolve
κΈ°λ₯ μ΄λΌκ³ μκ°ν©λλ€ .
μ νν μꡬμ λ°λΌ μμΈμ μμ ν΄μΌ ν μλ μμ§λ§ λ€μκ³Ό κ°μ΄ μλνκ³ μΆμ΅λλ€.
import numpy as np
a = [1, 2, 3, 4, 5]
k = [2, 4, 6, 8, 10]
result = np.convolve(a, k*a[::-1])