Применение матричных функций, таких как scipy.linalg.eigh, к многомерным массивам - PullRequest
0 голосов
/ 16 сентября 2018

Я новичок в numpy, но уже довольно давно использую python в качестве инженера. Я пишу программу, которая в настоящее время хранит тензоры напряжений в виде массивов 3x3 в другом массиве NxM, который представляет значения во времени и по толщине стены, поэтому в целом это массив NxMx3x3. Я хочу эффективно рассчитать собственные числа и векторы каждого массива 3х3 в этом большем массиве. До сих пор я пытался использовать «fromiter», но, похоже, это не работает, потому что функции возвращают 2 массива. Я также пробовал apply_along_axis, который также не работает, потому что он говорит, что внутренний 3x3 не квадратная матрица? Я могу сделать это с помощью понимания списков, но это не кажется идеальным, чтобы прибегать к использованию списков.

Пример простого вычисления собственных значений с использованием списка

import numpy as np
from scipy import linalg
a=np.random.random((2,2,3,3))
f=linalg.eigvalsh
ans=np.asarray([f(x) for x in a.reshape((4,3,3))])
ans.shape=(2,2,3)

Я думал, что-то вроде этого будет работать, но я поиграл с этим и не могу заставить его работать:

np.apply_along_axis(f,0,a)

Кстати, бит 2x2 может иметь размер до 5000x100, и этот код повторяется ~ 50x50x200 раз, следовательно, требуется эффективность. Любая помощь будет принята с благодарностью?

1 Ответ

0 голосов
/ 16 сентября 2018

Вы можете использовать numpy.linalg.eigh.Он принимает массив как ваш пример a.

Вот пример.Сначала создайте массив симметричных массивов 3x3:

In [96]: a = np.random.random((2, 2, 3, 3))

In [97]: a = a + np.transpose(a, axes=(0, 1, 3, 2))

In [98]: a[0, 0]
Out[98]: 
array([[0.61145048, 0.85209618, 0.03909677],
       [0.85209618, 1.79309413, 1.61209077],
       [0.03909677, 1.61209077, 1.55432465]])

Вычислите собственные значения и собственные векторы всех массивов 3x3:

In [99]: evals, evecs = np.linalg.eigh(a)

In [100]: evals.shape
Out[100]: (2, 2, 3)

In [101]: evecs.shape
Out[101]: (2, 2, 3, 3)

Посмотрите на результат для a[0, 0]:

In [102]: evals[0, 0]
Out[102]: array([-0.31729364,  0.83148477,  3.44467813])

In [103]: evecs[0, 0]
Out[103]: 
array([[-0.55911658,  0.79634401,  0.23070516],
       [ 0.63392772,  0.23128064,  0.73800062],
       [-0.53434473, -0.55887877,  0.63413738]])

Убедитесь, что это то же самое, что вычисление собственных значений и собственных векторов для a[0, 0] отдельно:

In [104]: np.linalg.eigh(a[0, 0])
Out[104]: 
(array([-0.31729364,  0.83148477,  3.44467813]),
 array([[-0.55911658,  0.79634401,  0.23070516],
        [ 0.63392772,  0.23128064,  0.73800062],
        [-0.53434473, -0.55887877,  0.63413738]]))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...