numpy.einsum_path#

numpy.einsum_path(индексы, *операнды, оптимизировать='greedy')[источник]#

Оценивает порядок сокращения с наименьшей стоимостью для выражения einsum, учитывая создание промежуточных массивов.

Параметры:
индексыstr

Определяет индексы для суммирования.

*operandsсписок array_like

Это массивы для операции.

оптимизировать{bool, list, tuple, ‘greedy’, ‘optimal’}

Выберите тип пути. Если предоставлен кортеж, второй аргумент считается максимальным промежуточным размером. Если предоставлен только один аргумент, используется наибольший размер входного или выходного массива в качестве максимального промежуточного размера.

  • если задан список, который начинается с einsum_pathиспользует это как путь свёртки

  • если False, оптимизация не выполняется

  • если True, по умолчанию используется алгоритм 'жадный'

  • ‘optimal’ Алгоритм, который комбинаторно исследует все возможные способы свертки перечисленных тензоров и выбирает наименее затратный путь. Масштабируется экспоненциально с количеством членов в свертке.

  • 'greedy' Алгоритм, который выбирает наилучшую пару для сокращения на каждом шаге. По сути, этот алгоритм ищет наибольшие внутренние, произведения Адамара, а затем внешние произведения на каждом шаге. Масштабируется кубически с количеством членов в сокращении. Эквивалентен 'optimal' пути для большинства сокращений.

По умолчанию 'greedy'.

Возвращает:
путьсписок кортежей

Списочное представление пути einsum.

string_reprstr

Печатаемое представление пути einsum.

Смотрите также

einsum, linalg.multi_dot

Примечания

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

Примеры

Мы можем начать с примера цепочки точек. В этом случае оптимально сократить b и c тензоры сначала, как представлено первым элементом пути (1, 2). Полученный тензор добавляется в конец сокращения, а оставшееся сокращение (0, 1) затем завершается.

>>> np.random.seed(123)
>>> a = np.random.rand(2, 2)
>>> b = np.random.rand(2, 5)
>>> c = np.random.rand(5, 2)
>>> path_info = np.einsum_path('ij,jk,kl->il', a, b, c, optimize='greedy')
>>> print(path_info[0])
['einsum_path', (1, 2), (0, 1)]
>>> print(path_info[1])
  Complete contraction:  ij,jk,kl->il # may vary
         Naive scaling:  4
     Optimized scaling:  3
      Naive FLOP count:  1.600e+02
  Optimized FLOP count:  5.600e+01
   Theoretical speedup:  2.857
  Largest intermediate:  4.000e+00 elements
-------------------------------------------------------------------------
scaling                  current                                remaining
-------------------------------------------------------------------------
   3                   kl,jk->jl                                ij,jl->il
   3                   jl,ij->il                                   il->il

Более сложный пример преобразования индекса.

>>> I = np.random.rand(10, 10, 10, 10)
>>> C = np.random.rand(10, 10)
>>> path_info = np.einsum_path('ea,fb,abcd,gc,hd->efgh', C, C, I, C, C,
...                            optimize='greedy')
>>> print(path_info[0])
['einsum_path', (0, 2), (0, 3), (0, 2), (0, 1)]
>>> print(path_info[1])
  Complete contraction:  ea,fb,abcd,gc,hd->efgh # may vary
         Naive scaling:  8
     Optimized scaling:  5
      Naive FLOP count:  8.000e+08
  Optimized FLOP count:  8.000e+05
   Theoretical speedup:  1000.000
  Largest intermediate:  1.000e+04 elements
--------------------------------------------------------------------------
scaling                  current                                remaining
--------------------------------------------------------------------------
   5               abcd,ea->bcde                      fb,gc,hd,bcde->efgh
   5               bcde,fb->cdef                         gc,hd,cdef->efgh
   5               cdef,gc->defg                            hd,defg->efgh
   5               defg,hd->efgh                               efgh->efgh