Самый быстрый способ создать симметричную матрицу в python с элементами, как показано ниже

#python #numpy #matrix #jupyter-notebook

Вопрос:

У меня есть коллекция массивов K0,K1,K2....Kn , определенных в 1D массиве z

Мне нужна следующая симметричная матрица самым быстрым возможным способом без использования цикла for.

     [np.trapz(K0*K0,z)  np.trapz(K0*K1,z)  np.trapz(K0*K2,z)  np.trapz(K0*K3,z)...]
    [      .            np.trapz(K1*K1,z)  np.trapz(K1*K2,z)  np.trapz(K1*K3,z)...]
A = [      .                    .          np.trapz(K2*K2,z)  np.trapz(K2*K3,z)...]
    [      .                    .             .               np.trapz(K3*K3,z)...]
    [      .                    .             .                       .           ]
 

Ниже приведен самый быстрый, с которым я мог справиться (все еще недостаточно быстрый для больших n… n>10000 ).

Я храню этот набор K s в объединенном массиве под названием KK

 KK = []
for i in range(n):
    KK.append(Ki)
KK = np.array(KK)
 
 A = np.zeros((n,n))
for i in range(n):
    A[i,i:] = A[i:,i] = np.trapz((KK[i]*KK[i:]),z)
 

Каков более быстрый способ сделать это? Меня не волнует, насколько неэлегантным или непитоническим является решение. Я просто хочу увеличить скорость.

Комментарии:

1. Похоже, вы смешиваете здесь математику и нотацию Python. Лучше использовать только нотацию Python. Как именно создается «KK»?

2. Внесла изменения. Я понимаю, что K0(z) и т. Д. Заставляет вас думать, что K0-это функция. Но я не могу точно представить эти величины без латекса

Ответ №1:

Вы используете свойства симметричной матрицы, что делает ее очень эффективной. Один из способов ускорить процесс-использовать Numba

 import numpy as np
import numba as nb

@nb.njit(cache=True, nogil=True, parallel=True)
def fun(KK,z,n):
    A = np.zeros((n,n))
    for i in nb.prange(n):
        A[i,i:] = A[i:,i] = np.trapz((KK[i]*KK[i:]),z)
    return A
 

Старые ответы

 np.trapz(KK.T[:,:,None]@KK.T[:,None,:],z,axis=0) # using matrix multiplication

np.trapz(np.einsum('ik,jk->ijk',KK,KK),z,axis=2) # Using einsum
 

Комментарии:

1. Спасибо вам за ответы. Однако это занимает гораздо больше времени, чем моя попытка цикла for.

2. @ПрасадМани, насколько велики ваши числа n и числа z ? Это зависит от того, насколько хорошо управляется память. если n x n x len(z) байтов не помещается в вашей памяти, они будут очень медленными. В этом случае зацикливание — лучший способ.

3. Я отредактировал его с помощью Numba, это будет быстрее.

4. Это было фантастически! Большое вам спасибо. Он вычисляет не более чем в два раза быстрее (и в лучшем случае в 5 раз быстрее), а также использует мощность процессора от бездействующих процессоров в узле. Цикл «для» этого не делал, что делало все это медленным

5. @ПрасадМани я добавил их