यहाँ एक शुरुआत है। सबसे पहले, किसी भी गलतियों के लिए मेरी माफी।
मैंने कुछ अलग-अलग तरीकों से प्रयोग किया। ऊपरी सीमा होना चाहिए - मैं थोड़ा योग पर सीमा से उलझन में था , बजाय ?i - 1मैंi−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
मैंने इसे खट्टे स्लाइस के साथ एक एकल लूप बनाया:
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)
एक स्पष्ट लूप के साथ खस्ता संस्करण होने पर मेरे कंप्यूटर पर लगभग 25x तेज होता है ।n=5000
फिर मैंने (अधिक-पठनीय) लूप कोड का साइथन संस्करण लिखा।
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 गुना तेज़ है)। मुझे यकीन है कि दूसरे बेहतर कर सकते हैं।
मैं एक जूलिया संस्करण के साथ खेला था, और यह लग रहा था (अगर मैंने इसे ठीक से समय दिया है) साइथन कोड के बराबर है।