Numpy и обратные матрицы - метод, чтобы сделать только одно изменение формы - PullRequest
1 голос
/ 13 апреля 2019

Я выполняю пакетное выполнение большого количества матриц 3x3 с помощью CUDA.

Цель состоит в том, чтобы получить большую матрицу матрицы 3x3 (поэтому я использую массив 4D).

Ранее я проделал ту же операцию с функцией numpy.linalg.inv.Таким образом, я могу напрямую получить массив матрицы 3х3: я покажу вам код, который выполняет эту операцию.

Теперь, с версией CUDA, я хотел бы изменить в минимальном количестве инструкций большой одномерный массивпроизвел: поэтому я должен построить (N, N, 3,3) массив из (N * N * 3 * 3) 1D массива.

На данный момент, я могу сделать это изменение в 2 шага(здесь код ниже).

Оригинальная версия с классическим numpy.linalg.inv выполняется:

for r_p in range(N):
  for s_p in range(N):
    # original version (without GPU)
    invCrossMatrix[:,:,r_p,s_p] = np.linalg.inv(arrayFullCross_vec[:,:,r_p,s_p])

invCrossMatrix представляет (3,3, N, N) массиви я получаю его непосредственно из массива (3,3, N, N) arrayFullCross (dimBlocks = 3)

На данный момент, когда я использую пакетное выполнение на GPU, я начинаю с массива 1D:

    # Declaration of inverse cross matrix
    invCrossMatrix_temp = np.zeros((N**2,3,3))

    # Create arrayFullCross_vec array
    arrayFullCross_vec = np.zeros((3,3,N,N))

    # Create arrayFullCross_vec array
    invCrossMatrix_gpu = np.zeros((3*3*(N**2)))

    # Build observables covariance matrix
    arrayFullCross_vec = buildObsCovarianceMatrix3_vec(k_ref, mu_ref, ir)

    ## Performing batch inversion 3x3 :
    invCrossMatrix_gpu = gpuinv3x3(arrayFullCross_vec.flatten('F'),N**2)

    ## First reshape
    invCrossMatrix_temp = invCrossMatrix_gpu.reshape(N**2,3,3)
    # Second reshape : don't forget ".T" transpose operator
    invCrossMatrix = (invCrossMatrix_temp.reshape(N,N,3,3)).T

Вопрос 1): Кстати, зачем нужна опция -F в flatten('F')?

если я это сделаютолько: gpuinv3x3(arrayFullCross_vec.flatten,N**2), код не работает: возможно, Python является главным столбцом, как Fortran?

Вопрос 2) Теперь я хотел бы преобразовать следующий блок:

## First reshape
invCrossMatrix_temp = invCrossMatrix_gpu.reshape(N**2,3,3)
# Second reshape : don't forget ".T" transpose operator
invCrossMatrix = (invCrossMatrix_temp.reshape(N,N,3,3)).T

в одну инструкцию по изменению формы: возможно ли это?

Проблема в том, чтобы преобразовать одномерный массив invCrossMatrix_gpu (N ** 2 * 3 * 3) непосредственно в (3,3,N, N) массив.

Я ожидаю изменить первоначальный 1D массив за один раз, так как я вызываю эти процедуры много раз.

UPDATE 1: Isвправо сказать, что массив inVCrossMatrix, определенный как:

invCrossMatrix = (invCrossMatrix_temp.reshape(N,N,3,3)).T

, имеет размеры (3,3, N, N).

@ hpaulj: эквивалентен ли он:

 invCrossMatrix =(invCrossMatrix_temp.reshape(N,N,3,3)).transpose(2,3,0,1) 

??Привет

...