Как быстро нарезать массив в зависимости от условий? - PullRequest
0 голосов
/ 08 ноября 2019

У меня есть гигантское гнездо для цикла .... всего 10, но для иллюстрации здесь я включаю 6. Я делаю суммирование (по нескольким индексам; инциденты не являются независимыми!). Индекс в любом внутреннем цикле for зависит от индекса внешнего цикла (за исключением одного экземпляра). Самый внутренний цикл содержит операцию, в которой я нарезаю массив (с именем 'w') на основе 8 различных условий, все из которых объединяются с использованием '&' и '|'. Существует также функция 'HB', которая принимает в качестве аргумента этот нарезанный массив (с именем 'wrange'), выполняет над ним некоторые операции и возвращает массив того же размера.

Временной масштаб для этого среза и выполняемой функции 'HB' составляет 300-400 микросекунд и 100 микросекунд соответственно. Мне нужно это сильно снизить. В наносекунды. !!

Попробовал использовать словарь вместо массива (где я нарезаю). Это намного медленнее. Попытка хранения нарезанного массива для всех возможных значений. Это очень большое вычисление само по себе, поскольку существует множество возможных комбинаций условий (эти условия косвенно зависят от индексов цикла for)

s изменяется от 1 до 49

t переходит от -s к s

и существует 641 комбинация l, n

Здесь я разместил одно значение s, t и комбинацию l, n для иллюстрации.

s = 7
t = -7 
l = 72
n = 12
Nl = Dictnorm[n,l]
Gamma_l = Dictfwhm[n,l]
Dictc1 = {}
Dictc2 = {}
Dictwrange = {}
DictH = {}
DictG = {}
product = []
startm = max(-l-t,-l)
endm = min(l-t,l)+1
sum5 = 0
for sp in range(s-2,s+3): #s'
    sum4 = 0
    for tp in range(-sp,-sp+1): #t'
        #print(tp)
        sum3 = 0
        integral = 1
        for lp in range(l-2,l+3): #l'
            sum2 = 0
            if (n,lp) in Dictknl2.keys():
                N1 = Dictnorm[n,lp]
                Gamma_1 = Dictfwhm[n,lp]
                for lpp in range(l-2,l+3): #l"
                    sum1 = 0
                    if ((sp+lpp-lp)%2 == 1 and sp>=abs(lpp-lp) and 
                        lp>=abs(sp-lpp) and lpp>=abs(sp-lp) and 
                        (n,lpp) in Dictknl2.keys()):
                        F = f(lpp,lp,sp)
                        N2 = Dictnorm[n,lpp]
                        Gamma_2 = Dictfwhm[n,lpp]
                        for m in range(startm, endm): #m
                            sum0 = 0
                            L1 = LKD(n,l,m,l,m)
                            L2 = LKD(n,l,m+t,l,m+t)
                            for mp in range(max(m+t-tp-5,m-5), 
                                            min(m+5,m+t-tp+5)+1): #m'
                                if (abs(mp)<=lp and abs(mp)<=lpp and 
                                    abs(mp+tp)<=lp and abs(mp+tp)<=lpp 
                                    and LKD(n,l,m,lp,mp)!=0 
                                    and LKD(n,l,m+t,lpp,mp+tp)!=0):
                                    c3 = Dictomega[n,lp,mp+tp]
                                    c4 = Dictomega[n,lpp,mp]
                                    wrange = np.unique(np.concatenate
                                             ((Dictwrange[m],                                  
                                             w[((w>=(c3-Gamma_1))&
                                             ((c3+Gamma_1)>=w))|
                                             ((w>=(c4-Gamma_2))& 
                                             ((c4+Gamma_2)>=w))])))
                                    factor = (sum(
                                             HB(Dictc1[n,l,m+t],
                                                Dictc2[n,l,m],Nl,
                                                Nl,Gamma_l,
                                                Gamma_l,wrange,
                                                Sigma).conjugate()
                                             *HB(c3,c4,N1,N2,Gamma_1, 
                                              Gamma_2,wrange,0)*L1*L2)
                                             *LKD(n,l,m,lp,mp)
                                             *LKD(n,l,m+t,lpp,mp+tp)                    *DictG[m]
                                             *gamma(lpp,sp,lp,tp,mp)
                                             *F)
                                    sum0 = sum0 + factor #sum over m'
                            sum1 = sum1 + sum0 #sum over m
                    sum2 = sum2 + sum1 #sum over l"
                sum3 = sum3 + sum2 #sum over l'
        sum4 = sum4 + sum3*integral #sum over t' 
    sum5 = sum5 + sum4 #sum over s'
z = (1/(sum(product)))*sum5
print(z.real,z.imag,l,n)

TL; DR

def HB(a,...f,array1): #########timesucker
    perform_some_operations_on_array1_using_a_b_c_d
    return operated_on_array1


for i in ():
    for j in ():
       ...
         ...
          for o in ():
              array1 = w[w>some_function1(i,j,..k) & 
                         w<some_function2(i,j,..k) |.....] #########timesucker
              factor = HB(a,....f,array1) * HB(g,...k,array1) * 
                       alpha*beta*gamma....

Требуется около 30 секунд, чтобы запустить весь этот раздел один раз. Мне нужно снизить его как можно ниже. 1 секунда - минимальная цель

...