Цель Моя цель - вычислить тензор, задаваемый формулой, которую вы можете увидеть ниже.Индексы i, j, k, l варьируются от 0 до 40, а p, m, x от 0 до 80.
Тенсордотподход Это суммирование только сжимает 6 индексов огромного тензора.Я попытался сделать это с помощью тензорной точки, которая учитывает такие вычисления, но тогда моя проблема - память, даже если я делаю одну тензорную точку, а затем другую.(Я работаю в Colab, поэтому у меня доступно 12 ГБ ОЗУ)
Подход с использованием вложенных циклов Но есть некоторые дополнительные симметрии, управляющие матрицей B, т.е. единственные ненулевые элементы в B {ijpx} таковычто я + J = P + X.Поэтому я смог написать p и m как функцию от x (p = i + jx, m = k + lx), а затем я сделал 5 циклов именно для i, j, k, l, x, но затем с другой стороныпроблема заключается во времени, так как расчет занимает 136 секунд, и я хочу повторить это много раз.
Цели синхронизации в подходе с вложенными циклами Сокращение времени в десять раз было бы удовлетворительным, но если было бы возможно уменьшить его в 100 раз, этого было бы более чем достаточно.
Есть ли у вас какие-либо идеи по поводу проблемы с памятью или сокращения времени?Как вы обрабатываете такие суммирования с дополнительными ограничениями?
(Примечание. Матрица A является симметричной, и я до сих пор не использовал этот факт. Симметрий больше нет.)
Вот код для вложенного цикла:
for i in range (0,40):
for j in range (0,40):
for k in range (0,40):
for l in range (0,40):
Sum=0
for x in range (0,80):
p=i+j-x
m=k+l-x
if p>=0 and p<80 and m>=0 and m<80:
Sum += A[p,m]*B[i,j,p,x]*B[k,l,m,x]
T[i,j,k,l]= Sum
И код для подхода тензорной точки:
P=np.tensordot(A,B,axes=((0),(2)))
T=np.tensordot(P,B,axes=((0,3),(2,3)))