Pytorch lobpcg 不适用于复杂的稀疏数组?

问题描述 投票:0回答:1

我目前正在尝试使用 Pytorch“lobpcg”使用 GPU 对大型稀疏数组进行对角化。当对角化由实数值组成的数组时,该函数似乎工作得很好,但每当数组包含复数值时,它就会返回一些令人困惑的错误消息。作为参考,我在这里留下了我的代码片段和返回的错误消息

from scipy import sparse
import torch
from torch import lobpcg
import numpy as np
from scipy import sparse 
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
#%%
def Torchfy(arr): # storese sparse arrays in gpu
   arr = arr.tocoo() # Converting to "coordinate format" (type of way to store matrix in the GPU)
   # Here we create sparse pythorch tensor feeding in the indices: device was defined in first cell
   arr = torch.sparse_coo_tensor(indices=torch.tensor([arr.row, arr.col]), values=torch.tensor(arr.data), size=arr.shape).to(device)
   return arr
def H_L(xcoor, ycoor, zcoor, b = 1, g1 = 1, g2 = 1, g3 = 1, e = 1, m = 1, hbar = 1):
########################################### Pre Calculations ###############################################
   h2 = hbar ** 2 # hbar sqrd
   c1 = - h2/(2*m) * (g1 + 2.5 * g2) # setting constant for first term
   c2 = g2 * h2 / m # setting constant for second term
   c3 = g3 * h2/(2*m) # setting constant for third term
   e2 = e ** 2 # e-charge sqrd
   eh = e / hbar
   e2h2 = e2 / h2
   y = 0.5 * b * sparse.spdiags(ycoor.reshape(N3), np.array([0]), N3, N3) # repeated, put in diagonal form (N^3,N^3) 
   x = 0.5 * b * sparse.spdiags(xcoor.reshape(N3), np.array([0]), N3, N3) # repeated, put in diagonal form (N^3,N^3) 
   y2 = y ** 2
   x2 = x ** 2
############################################ First Term ####################################################
   lapl = ddxx + ddyy + ddzz # Laplacian
   a_nabl = -1j * eh * (x * ddy - y * ddx)  # A(r) * Nabla, where A generates B = b * \hat{z}
   a2 = e2h2 * (y2 + x2)
   tmp1 = c1 * (- lapl + a_nabl + a2) # summing the terms relevant to tmp1
   tmp1 = sparse.kron(tmp1, np.eye(4)) # No J_i coupling so we consider kron with identity 
############################################ Second Term ###################################################
   kx2 = - ddxx + 1j * eh * y * ddx + e2h2 * y2
   ky2 = - ddyy - 1j * eh * x * ddy + e2h2 * x2
   tmp2 = sparse.kron(kx2, J_x2) + sparse.kron(ky2, J_y2) + sparse.kron(-ddzz, J_z2)
############################################ Third Term #####################################################
   kxky = 0.5 * (- 2 * ddxy - 2 * e2h2 * x * y - 1j * eh *( x * ddx - y * ddy))
   kxkz = 0.5 * (- 2 * ddxz + 1j * eh * y * ddz)
   kykz = 0.5 * (- 2 * ddyz - 1j * eh * x * ddz)
   tmp3 = sparse.kron(kxky, jxjy) + sparse.kron(kxkz, jxjz) + sparse.kron(kykz, jyjz)
   return tmp1 + tmp2 + tmp3
h = H_L(X, Y, Z)
h = Torchfy(h)
# Using the "Locally optimal block preconditioned conjugate gradient method" to obtain the first 10 eigenvalues
# we focus on the lowest ones (i.e. largest = False)
eigenvalues, eigenvectors = lobpcg(h, k=10, largest=False)

运行上述代码的完整版本后,我收到错误消息:RuntimeError:预期标量类型 ComplexDouble 但发现 Float。有没有办法解决这个问题?
预先感谢

python pytorch gpu complex-numbers eigenvalue
1个回答
0
投票

您遇到的错误消息“RuntimeError:预期标量类型 ComplexDouble 但发现 Float”是由于

lobpcg
函数预期的数据类型与输入张量的数据类型不匹配造成的。 lobpcg 函数期望输入为复数双精度,但似乎您的输入张量为浮点精度。

要解决此问题,您应该确保传递给 lobpcg 的输入张量是复数双精度(即 PyTorch 中的 complex64)。以下是修改代码以处理复杂输入的方法:

您可以使用 torch.complex 创建复杂的张量:

h = torch.complex(h.real, h.imag).to(device)

然后您可以按如下方式更新您的 lobpcg 调用:

eigenvalues, eigenvectors = lobpcg(h, k=10, largest=False, dtype=torch.complex64)
© www.soinside.com 2019 - 2024. All rights reserved.