여기에 시작이 있습니다. 첫째, 실수에 대해 사과드립니다.
나는 두 가지 다른 접근 방식으로 실험했습니다. 나는 합계에 대한 한계에 약간 혼란 스러웠다. 아니라 상한이 이어야 하는가?나는난 − 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 배 빠릅니다 .n = 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 코드와 비슷한 것으로 보였습니다.