นี่เป็นการเริ่มต้น ก่อนอื่นฉันขอโทษสำหรับข้อผิดพลาดใด ๆ
ผมฉัน- 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)
n = 5,000
จากนั้นฉันเขียนโค้ดวนลูปรุ่น 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
บนแล็ปท็อปของฉันอันนี้เร็วกว่ารุ่นลูปประมาณ 200x (และเร็วกว่าเวอร์ชันเวกเตอร์ 1 ลูป 8 เท่า) ฉันแน่ใจว่าคนอื่นสามารถทำได้ดีกว่า
ฉันเล่นกับรุ่น Julia และดูเหมือนว่า (ถ้าฉันจับเวลาถูกต้อง) เทียบได้กับรหัส Cython