为了在1D阵列上进行希尔伯特变换,必须:
我使用PyCuLib进行FFT。我的代码到目前为止
def htransforms(data):
N = data.shape[0]
transforms = nb.cuda.device_array_like(data) # Allocates memory on GPU with size/dimensions of signal
transforms.dtype = np.complex64 # Change GPU array type to complex for FFT
pyculib.fft.fft(signal.astype(np.complex64), transforms) # Do FFT on GPU
transforms[1:N/2] *= 2.0 # THIS STEP DOESN'T WORK
transforms[N/2 + 1: N] = 0+0j # NEITHER DOES THIS ONE
pyculib.fft.ifft_inplace(transforms) # Do IFFT on GPU: in place (same memory)
envelope_function = transforms.copy_to_host() # Copy results to host (computer) memory
return abs(envelope_function)
我觉得它可能与Numba的CUDA接口本身有关......它是否允许像这样修改数组(或数组切片)的各个元素?我假设它可能,因为变量transforms
是numba.cuda.cudadrv.devicearray.DeviceNDArray
,所以我想也许它有一些与numpy' s ndarray
相同的操作。
简而言之,使用Numba的device_arrays
,在片上进行简单操作的最简单方法是什么?我得到的错误是
不支持的操作数类型* =:' DeviceNDArray'并且'浮动'
答案 0 :(得分:0)
我会使用 pytorch
您使用 pytorch 的函数(我删除了 abs 以返回复数值)
df1["N"] = [max(df1[i]) for i in df.columns]
A B C D N
0 0.0 10.0 0.0 0 30.0
1 30.0 40.0 0.0 10 40.0
2 0.0 0.0 0.0 35 0.0
3 0.0 9.0 0.0 12 35.0
但你的变换实际上与我在 wikipedia
上发现的不同维基百科版本
def htransforms(data):
N = data.shape[-1]
# Allocates memory on GPU with size/dimensions of signal
transforms = torch.tensor(data).cuda()
torch.fft.fft(transforms, axis=-1)
transforms[:, 1:N//2] *= 2.0 # THIS STEP DOESN'T WORK
transforms[:, N//2 + 1: N] = 0+0j # NEITHER DOES THIS ONE
# Do IFFT on GPU: in place (same memory)
return torch.abs(torch.fft.ifft(transforms)).cpu()
def htransforms_wikipedia(data):
N = data.shape[-1]
# Allocates memory on GPU with size/dimensions of signal
transforms = torch.tensor(data).cuda()
transforms = torch.fft.fft(transforms, axis=-1)
transforms[:, 1:N//2] *= -1j # positive frequency
transforms[:, (N+2)//2 + 1: N] *= +1j # negative frequency
transforms[:,0] = 0; # DC signal
if N % 2 == 0:
transforms[:, N//2] = 0; # the (-1)**n term
# Do IFFT on GPU: in place (same memory)
return torch.fft.ifft(transforms).cpu()
data = torch.zeros((1, 2**10))
data[:, 2**9] = 1;
tdata = htransforms(data).data;
plt.plot(tdata.real.T, '-')
plt.plot(tdata.imag.T, '-')
plt.xlim([500, 525])
plt.legend(['real', 'imaginary'])
plt.title('inpulse response of your version')
您的版本的脉冲响应为 data = torch.zeros((1, 2**10))
data[:, 2**9] = 1;
tdata = htransforms_wikipedia(data).data;
plt.plot(tdata.real.T, '-');
plt.plot(tdata.imag.T, '-');
plt.xlim([500, 525])
plt.legend(['real', 'imaginary'])
plt.title('inpulse response of Wikipedia version')
,其中 1 + 1j * h[k]
是维基百科版本的脉冲响应。如果您正在处理真实数据,维基百科版本很好,因为您可以使用 rfft 和 irfft 生成一个线性版本
h[k]